-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
568 additions
and
576 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | ||
} | ||
} |
Oops, something went wrong.