Skip to content

Commit

Permalink
File scoped namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
kwsch authored and Koi-3088 committed Jun 27, 2022
1 parent 6f95bb1 commit 5d10a5c
Show file tree
Hide file tree
Showing 7 changed files with 568 additions and 576 deletions.
321 changes: 160 additions & 161 deletions EtumrepMMO.Server.WinForms/Main.cs
Original file line number Diff line number Diff line change
@@ -1,204 +1,203 @@
using Newtonsoft.Json;

namespace EtumrepMMO.Server.WinForms
namespace EtumrepMMO.Server.WinForms;

public sealed partial class Main : Form
{
public sealed partial class Main : Form
private readonly ServerConnection Connection;
private readonly string ConfigPath = GetConfigPath();
private readonly object _logLock = new();
private readonly object _queueLock = new();
private readonly object _concurrentLock = new();

private static CancellationTokenSource Source { get; set; } = new();
private ServerSettings Settings { get; set; }
private static bool WasStarted { get; set; }

private const string _waiting = "Waiting for users...";
private const string _noQueue = "No users in queue...";
private const string _connectionsText = "Connections accepted: ";
private const string _authText = "Users authenticated: ";
private const string _etumrepText = "EtumrepMMOs run: ";

public Main()
{
private readonly ServerConnection Connection;
private readonly string ConfigPath = GetConfigPath();
private readonly object _logLock = new();
private readonly object _queueLock = new();
private readonly object _concurrentLock = new();

private static CancellationTokenSource Source { get; set; } = new();
private ServerSettings Settings { get; set; }
private static bool WasStarted { get; set; }

private const string _waiting = "Waiting for users...";
private const string _noQueue = "No users in queue...";
private const string _connectionsText = "Connections accepted: ";
private const string _authText = "Users authenticated: ";
private const string _etumrepText = "EtumrepMMOs run: ";

public Main()
InitializeComponent();
if (File.Exists(ConfigPath))
{
InitializeComponent();
if (File.Exists(ConfigPath))
{
var text = File.ReadAllText(ConfigPath);
Settings = JsonConvert.DeserializeObject<ServerSettings>(text, GetSettings()) ?? new ServerSettings();
UpdateLabels(Settings.ConnectionsAccepted, Settings.UsersAuthenticated, Settings.EtumrepsRun);
}
else Settings = new();

var status = new Progress<ConnectionStatus>(x =>
{
UpdateStatusLamp(x);
});
var text = File.ReadAllText(ConfigPath);
Settings = JsonConvert.DeserializeObject<ServerSettings>(text, GetSettings()) ?? new ServerSettings();
UpdateLabels(Settings.ConnectionsAccepted, Settings.UsersAuthenticated, Settings.EtumrepsRun);
}
else Settings = new();

var concurrent = new Progress<(string, bool)>(x =>
{
UpdateCurrentlyProcessed(x.Item1, x.Item2);
});
var status = new Progress<ConnectionStatus>(x =>
{
UpdateStatusLamp(x);
});

var labels = new Progress<(int, int, int)>(x =>
{
UpdateLabels(x.Item1, x.Item2, x.Item3);
});
var concurrent = new Progress<(string, bool)>(x =>
{
UpdateCurrentlyProcessed(x.Item1, x.Item2);
});

var queue = new Progress<(string, bool)>(x =>
{
UpdateQueue(x.Item1, x.Item2);
});
var labels = new Progress<(int, int, int)>(x =>
{
UpdateLabels(x.Item1, x.Item2, x.Item3);
});

UpdateCurrentlyProcessed(_waiting, false);
UpdateQueue(_noQueue, false);
var queue = new Progress<(string, bool)>(x =>
{
UpdateQueue(x.Item1, x.Item2);
});

RTB_Logs.MaxLength = 32_767;
Connection = new(Settings, status, concurrent, labels, queue);
Grid_Settings.SelectedObject = Settings;
LogUtil.Forwarders.Add(PostLog);
}
UpdateCurrentlyProcessed(_waiting, false);
UpdateQueue(_noQueue, false);

private void Main_FormClosing(object sender, FormClosingEventArgs e)
{
WindowState = FormWindowState.Minimized;
Stop();
}
RTB_Logs.MaxLength = 32_767;
Connection = new(Settings, status, concurrent, labels, queue);
Grid_Settings.SelectedObject = Settings;
LogUtil.Forwarders.Add(PostLog);
}

private void Button_Start_Click(object sender, EventArgs e)
{
if (WasStarted)
return;
private void Main_FormClosing(object sender, FormClosingEventArgs e)
{
WindowState = FormWindowState.Minimized;
Stop();
}

WasStarted = true;
Tab_Logs.Select();
RunServer();
}
private void Button_Start_Click(object sender, EventArgs e)
{
if (WasStarted)
return;

private void Button_Stop_Click(object sender, EventArgs e)
{
if (WasStarted)
Stop();
}
WasStarted = true;
Tab_Logs.Select();
RunServer();
}

private void Stop()
{
SaveSettings();
Source.Cancel();
private void Button_Stop_Click(object sender, EventArgs e)
{
if (WasStarted)
Stop();
}

async Task WaitUntilDone()
{
await Connection.Stop().ConfigureAwait(false);
Source = new();
WasStarted = false;
LV_Concurrent.Items.Clear();
LV_Concurrent.Items.Add("Waiting for users...");
LV_QueueList.Items.Clear();
}
Task.WhenAny(WaitUntilDone(), Task.Delay(1_000)).ConfigureAwait(true).GetAwaiter().GetResult();
LogUtil.Log("Server has been shut down.", "[Stop Button Event]");
}
private void Stop()
{
SaveSettings();
Source.Cancel();

private void PostLog(string message, string identity)
async Task WaitUntilDone()
{
var line = $"[{DateTime.Now:HH:mm:ss}] - {identity}: {message}{Environment.NewLine}";
if (InvokeRequired)
Invoke((MethodInvoker)(() => UpdateLog(line)));
else UpdateLog(line);
await Connection.Stop().ConfigureAwait(false);
Source = new();
WasStarted = false;
LV_Concurrent.Items.Clear();
LV_Concurrent.Items.Add("Waiting for users...");
LV_QueueList.Items.Clear();
}
Task.WhenAny(WaitUntilDone(), Task.Delay(1_000)).ConfigureAwait(true).GetAwaiter().GetResult();
LogUtil.Log("Server has been shut down.", "[Stop Button Event]");
}

// Taken from kwsch's SysBot
// https://github.com/kwsch/SysBot.NET/commit/27455c4d88f1f9df7dc94dd0e76f3a9bb44b6242
private void UpdateLog(string line)
{
lock (_logLock)
{
// ghetto truncate
var rtb = RTB_Logs;
var text = rtb.Text;
var max = rtb.MaxLength;
if (text.Length + line.Length + 2 >= max)
rtb.Text = text[(max / 4)..];

rtb.AppendText(line);
rtb.ScrollToCaret();
}
}
private void PostLog(string message, string identity)
{
var line = $"[{DateTime.Now:HH:mm:ss}] - {identity}: {message}{Environment.NewLine}";
if (InvokeRequired)
Invoke((MethodInvoker)(() => UpdateLog(line)));
else UpdateLog(line);
}

private void RunServer()
// Taken from kwsch's SysBot
// https://github.com/kwsch/SysBot.NET/commit/27455c4d88f1f9df7dc94dd0e76f3a9bb44b6242
private void UpdateLog(string line)
{
lock (_logLock)
{
var token = Source.Token;
_ = Task.Run(async () => await Connection.MainAsync(token), token);
// ghetto truncate
var rtb = RTB_Logs;
var text = rtb.Text;
var max = rtb.MaxLength;
if (text.Length + line.Length + 2 >= max)
rtb.Text = text[(max / 4)..];

rtb.AppendText(line);
rtb.ScrollToCaret();
}
}

private static string GetConfigPath() => "config.json";
private void RunServer()
{
var token = Source.Token;
_ = Task.Run(async () => await Connection.MainAsync(token), token);
}

private static JsonSerializerSettings GetSettings() => new()
{
Formatting = Formatting.Indented,
DefaultValueHandling = DefaultValueHandling.Include,
NullValueHandling = NullValueHandling.Ignore,
};
private static string GetConfigPath() => "config.json";

private void SaveSettings()
{
var lines = JsonConvert.SerializeObject(Settings, GetSettings());
File.WriteAllText(ConfigPath, lines);
}
private static JsonSerializerSettings GetSettings() => new()
{
Formatting = Formatting.Indented,
DefaultValueHandling = DefaultValueHandling.Include,
NullValueHandling = NullValueHandling.Ignore,
};

private void UpdateStatusLamp(ConnectionStatus status) => PB_Ready.BackColor = status switch
{
ConnectionStatus.Connecting => Color.Wheat,
ConnectionStatus.Connected => Color.LawnGreen,
_ => Color.WhiteSmoke
};
private void SaveSettings()
{
var lines = JsonConvert.SerializeObject(Settings, GetSettings());
File.WriteAllText(ConfigPath, lines);
}

private void UpdateLabels(int connections, int authentications, int etumreps)
{
Label_Connections.Text = _connectionsText + connections;
Label_Authenticated.Text = _authText + authentications;
Label_Etumreps.Text = _etumrepText + etumreps;
}
private void UpdateStatusLamp(ConnectionStatus status) => PB_Ready.BackColor = status switch
{
ConnectionStatus.Connecting => Color.Wheat,
ConnectionStatus.Connected => Color.LawnGreen,
_ => Color.WhiteSmoke
};

private void UpdateLabels(int connections, int authentications, int etumreps)
{
Label_Connections.Text = _connectionsText + connections;
Label_Authenticated.Text = _authText + authentications;
Label_Etumreps.Text = _etumrepText + etumreps;
}

private void UpdateQueue(string text, bool insert)
private void UpdateQueue(string text, bool insert)
{
lock (_queueLock)
{
lock (_queueLock)
var item = LV_QueueList.FindItemWithText(_noQueue);
LV_QueueList.Items.Remove(item);

if (insert)
LV_QueueList.Items.Add(text);
else
{
var item = LV_QueueList.FindItemWithText(_noQueue);
item = LV_QueueList.FindItemWithText(text);
LV_QueueList.Items.Remove(item);

if (insert)
LV_QueueList.Items.Add(text);
else
{
item = LV_QueueList.FindItemWithText(text);
LV_QueueList.Items.Remove(item);

if (LV_QueueList.Items.Count is 0)
LV_QueueList.Items.Add(_noQueue);
}
if (LV_QueueList.Items.Count is 0)
LV_QueueList.Items.Add(_noQueue);
}
}
}

private void UpdateCurrentlyProcessed(string text, bool insert)
private void UpdateCurrentlyProcessed(string text, bool insert)
{
lock (_concurrentLock)
{
lock (_concurrentLock)
var item = LV_Concurrent.FindItemWithText(_waiting);
LV_Concurrent.Items.Remove(item);

if (insert)
LV_Concurrent.Items.Add(text);
else
{
var item = LV_Concurrent.FindItemWithText(_waiting);
item = LV_Concurrent.FindItemWithText(text);
LV_Concurrent.Items.Remove(item);

if (insert)
LV_Concurrent.Items.Add(text);
else
{
item = LV_Concurrent.FindItemWithText(text);
LV_Concurrent.Items.Remove(item);

if (LV_Concurrent.Items.Count is 0)
LV_Concurrent.Items.Add(_waiting);
}
if (LV_Concurrent.Items.Count is 0)
LV_Concurrent.Items.Add(_waiting);
}
}
}
}
}
23 changes: 11 additions & 12 deletions EtumrepMMO.Server.WinForms/Program.cs
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
namespace EtumrepMMO.Server.WinForms
namespace EtumrepMMO.Server.WinForms;

internal static class Program
{
internal static class Program
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Main());
}
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Main());
}
}
Loading

0 comments on commit 5d10a5c

Please sign in to comment.