Need help about fast/late indicator in game overlay
C4P741N-TH opened this issue · 0 comments
C4P741N-TH commented
I write some gui program to read hit error from file.txt and it will show fast/late indicator. I want to implement with osu!StreamCompanion plugin to show in game overlay. Can u advise me?
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
namespace osu_judgement_gui
{
public partial class Form1 : Form
{
private string selectedFilePath;
private FileSystemWatcher fileWatcher;
private long lastPosition = 0;
private Timer calculateTimer;
public Form1()
{
InitializeComponent();
calculateTimer = new Timer();
calculateTimer.Interval = 100; // Adjust the interval as needed
calculateTimer.Tick += CalculateAverageTimer_Tick;
this.FormBorderStyle = FormBorderStyle.FixedSingle;
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (fileWatcher != null)
{
fileWatcher.EnableRaisingEvents = false;
fileWatcher.Dispose();
}
}
private void button1_Click(object sender, EventArgs e)
{
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Text files (*.txt)|*.txt|All files (*.*)|*.*";
openFileDialog.Multiselect = false;
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
selectedFilePath = openFileDialog.FileName;
ReadFileAsync(selectedFilePath); // Don't use await here as we don't want to wait for the file read to complete.
StartFileWatcher(selectedFilePath);
calculateTimer.Start(); // Start the timer when a new file is selected
}
}
private async void ReadFileAsync(string filePath)
{
try
{
using (var fileStream = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
using (var streamReader = new StreamReader(fileStream))
{
// Set the position to the last read line
if (lastPosition > 0)
fileStream.Position = lastPosition;
while (!streamReader.EndOfStream)
{
string line = await streamReader.ReadLineAsync();
UpdateTextBoxes(line);
lastPosition = fileStream.Position; // Update the last position after each read.
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error reading the file: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void StartFileWatcher(string filePath)
{
fileWatcher = new FileSystemWatcher();
fileWatcher.Path = Path.GetDirectoryName(filePath);
fileWatcher.Filter = Path.GetFileName(filePath);
fileWatcher.NotifyFilter = NotifyFilters.LastWrite;
fileWatcher.Changed += OnFileChanged;
fileWatcher.EnableRaisingEvents = true;
}
private void OnFileChanged(object sender, FileSystemEventArgs e)
{
// Avoid cross-thread issues by invoking on the UI thread.
Invoke(new Action(() =>
{
ReadFileAsync(selectedFilePath);
}));
}
private void UpdateTextBoxes(string line)
{
if (!string.IsNullOrEmpty(selectedFilePath))
{
try
{
string[] numbers = line.Split(',');
if (numbers.Length > 0 && int.TryParse(numbers[numbers.Length - 1], out int lastValue))
{
if (lastValue > 11)
{
textBox2.Text = "Late";
textBox3.Text = lastValue.ToString();
}
else if (lastValue < -11)
{
textBox2.Text = "Fast";
textBox3.Text = lastValue.ToString();
}
else if (lastValue > -11 && lastValue < 11)
{
textBox2.Text = "Perfect";
textBox3.Text = lastValue.ToString();
}
else
{
textBox2.Text = "";
textBox3.Text = lastValue.ToString();
}
}
}
catch (Exception ex)
{
MessageBox.Show("Error display indicator: " + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
private void CalculateAverageTimer_Tick(object sender, EventArgs e)
{
calculateTimer.Stop(); // Stop the timer during the calculation
CalculateAverage();
calculateTimer.Start(); // Start the timer again after the calculation is done
}
private void CalculateAverage()
{
if (!string.IsNullOrEmpty(selectedFilePath))
{
try
{
// Read all lines in the file
string[] lines = File.ReadAllLines(selectedFilePath);
if (lines.Length > 0)
{
// Parse the values and calculate the average
double sum = 0;
int count = 0;
foreach (string line in lines)
{
string[] numbers = line.Split(',');
foreach (string number in numbers)
{
if (double.TryParse(number, out double value))
{
sum += value;
count++;
}
}
}
if (count > 0)
{
double average = sum / count;
textBox4.Text = Math.Round(average,2).ToString();
}
}
}
catch (Exception ex)
{
}
}
}
}
}```