diff --git a/MelonVPNClient/MainWindow.cs b/MelonVPNClient/MainWindow.cs index 188b4a4..5abf644 100644 --- a/MelonVPNClient/MainWindow.cs +++ b/MelonVPNClient/MainWindow.cs @@ -197,7 +197,7 @@ public partial class MainWindow : Window void StartupCheckMethod() { - ClientResponseState s = Client.SendDataMessage(DataMessage.Status); + ClientResponseState s = GUISocketServer.SendDataMessage(DataMessage.Status); Console.WriteLine(s); Application.Invoke(delegate { @@ -207,7 +207,7 @@ public partial class MainWindow : Window void Refresh() { - ClientResponseState s = Client.SendDataMessage(DataMessage.Status); + ClientResponseState s = GUISocketServer.SendDataMessage(DataMessage.Status); switch (s) { case ClientResponseState.Error: @@ -364,7 +364,7 @@ public partial class MainWindow : Window void OnStartClicked(object sender, EventArgs e) { - ClientResponseState s = Client.SendDataMessage(DataMessage.Start); + ClientResponseState s = GUISocketServer.SendDataMessage(DataMessage.Start); switch (s) { case ClientResponseState.Error: @@ -382,7 +382,7 @@ public partial class MainWindow : Window void OnStopClicked(object sender, EventArgs e) { - ClientResponseState s = Client.SendDataMessage(DataMessage.Stop); + ClientResponseState s = GUISocketServer.SendDataMessage(DataMessage.Stop); switch (s) { case ClientResponseState.Error: @@ -417,7 +417,7 @@ public partial class MainWindow : Window void RestartToggleBtn_Clicked(object sender, EventArgs e) { - ClientResponseState s = (RestartMode) ? Client.SendDataMessage(DataMessage.RestartOff) : Client.SendDataMessage(DataMessage.RestartOn); + ClientResponseState s = (RestartMode) ? GUISocketServer.SendDataMessage(DataMessage.RestartOff) : GUISocketServer.SendDataMessage(DataMessage.RestartOn); switch (s) { case ClientResponseState.Error: diff --git a/MelonVPNConnectedClientUpdate/Program.cs b/MelonVPNConnectedClientUpdate/Program.cs index 749fbf5..6ae3761 100644 --- a/MelonVPNConnectedClientUpdate/Program.cs +++ b/MelonVPNConnectedClientUpdate/Program.cs @@ -6,8 +6,10 @@ namespace MelonVPNConnectedClientUpdate class MainClass { public static void Main(string[] args) - { - Client.SendCustomMessage(Messages.GetClientListMessage(Console.ReadLine())); + { + GUISocketServer.oneConnect(); + GUISocketServer.SendCustomMessage(Messages.GetClientListMessage(Console.ReadLine())); + GUISocketServer.oneDispose(); } } } diff --git a/MelonVPNCore/Client.cs b/MelonVPNCore/Client.cs deleted file mode 100644 index 9dd9cd1..0000000 --- a/MelonVPNCore/Client.cs +++ /dev/null @@ -1,41 +0,0 @@ -using System; -using System.Net; -using System.Net.Sockets; -using System.Text; - -namespace MelonVPNCore -{ - public static class Client - { - public static ClientResponseState SendDataMessage(DataMessage msg) => SendDataMessage(msg, false); - public static ClientResponseState SendDataMessage(DataMessage msg, bool IsSendingFromDaemon) => SendCustomMessage(Messages.GetMessage(msg), IsSendingFromDaemon); - public static ClientResponseState SendCustomMessage(string msg) => SendCustomMessage(msg, false); - public static ClientResponseState SendCustomMessage(string msg, bool IsSendingFromDaemon) - { - IPHostEntry host = Dns.GetHostEntry("localhost"); - IPAddress ipAddress = host.AddressList[0]; - IPEndPoint remoteEndPoint = new IPEndPoint(ipAddress, IsSendingFromDaemon ? 22036 : 22035); - - try - { - if (msg == Messages.EOF || msg == "") return ClientResponseState.Blank; - - Socket client = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - client.Connect(remoteEndPoint); - client.ReceiveTimeout = 5000; - client.SendTimeout = 5000; - - byte[] bytes = Encoding.ASCII.GetBytes(msg); - - client.Send(bytes); - client.Close(); - return ClientResponseState.Sent; - } - catch (Exception e) - { - Console.WriteLine(e); - return ClientResponseState.Error; - } - } - } -} \ No newline at end of file diff --git a/MelonVPNCore/DaemonMessaging.cs b/MelonVPNCore/DaemonMessaging.cs index 0ab3b31..1f2b58d 100644 --- a/MelonVPNCore/DaemonMessaging.cs +++ b/MelonVPNCore/DaemonMessaging.cs @@ -3,30 +3,44 @@ using System.Net; using System.Net.Sockets; using System.Text; using System.Threading; +using System.Collections.Generic; namespace MelonVPNCore { public class DaemonClient : IDisposable { - public ClientResponseState SendDataMessage(DataMessage msg) => SendCustomMessage(msg); - public ClientResponseState SendCustomMessage(DataMessage msg) => SendCustomMessage(Messages.GetMessage(msg))); + public ClientResponseState SendDataMessage(DataMessage msg) => SendCustomMessage(Messages.GetMessage(msg)); private Socket _sock; public static int timeout = 5000; private Thread _recvThread; private bool _stayConnected = false; public event EventHandler messageReceived; + public event EventHandler connectionError; - public DaemonClient() + public DaemonClient() { } + public DaemonClient(Socket sockIn) + { + if (sockIn is null) throw new ArgumentNullException(nameof(sockIn)); + } + + public void start() { try { - IPHostEntry host = Dns.GetHostEntry("localhost"); - IPAddress ipAddress = host.AddressList[0]; - IPEndPoint remoteEndPoint = new IPEndPoint(ipAddress, DaemonServer.port); - _sock = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - _stayConnected = true; - _sock.Connect(remoteEndPoint); + if (_sock is null) + { + IPHostEntry host = Dns.GetHostEntry("localhost"); + IPAddress ipAddress = host.AddressList[0]; + IPEndPoint remoteEndPoint = new IPEndPoint(ipAddress, DaemonServer.port); + _sock = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); + _stayConnected = true; + _sock.Connect(remoteEndPoint); + } + else + { + _stayConnected = true; + } _sock.ReceiveTimeout = timeout; _sock.SendTimeout = timeout; _recvThread = new Thread(recvThreader) @@ -34,23 +48,19 @@ namespace MelonVPNCore IsBackground = true }; _recvThread.Start(); - } catch (Exception e) + } + catch (Exception e) { _stayConnected = false; Console.WriteLine(e); _sock = null; - if (! (_recvThread is null)) + if (!(_recvThread is null)) { if (_recvThread.IsAlive) _recvThread.Abort(); _recvThread = null; } throw new InvalidOperationException("Daemon Client Init Failed."); - } - } - - public DaemonClient(Socket sockIn) - { - if (sockIn is null) throw new InvalidOperationException("Passed Socket is Null."); + } } public ClientResponseState SendCustomMessage(string msg) @@ -65,6 +75,7 @@ namespace MelonVPNCore catch (Exception e) { Console.WriteLine(e); + connectionError?.Invoke(this, e); return ClientResponseState.Error; } } @@ -85,8 +96,11 @@ namespace MelonVPNCore data += Encoding.ASCII.GetString(bytes, 0, bytesRec); if (data.IndexOf(Messages.EOF, StringComparison.CurrentCulture) > -1) break; } - - messageReceived?.Invoke(null, data); + messageReceived?.Invoke(this, data); + } catch (SocketException e) + { + Console.WriteLine(e); + connectionError?.Invoke(this, e); } catch (Exception e) { Console.WriteLine(e); @@ -104,7 +118,13 @@ namespace MelonVPNCore if (disposing) { _stayConnected = false; - _sock.Shutdown(SocketShutdown.Both); + try + { + _sock.Shutdown(SocketShutdown.Both); + } catch (SocketException e) + { + Console.WriteLine(e); + } if (!(_recvThread is null)) { if (_recvThread.IsAlive) _recvThread.Abort(); @@ -135,7 +155,7 @@ namespace MelonVPNCore private bool _stayListening = false; public event EventHandler clientConnected; - public DaemonServer() + public void start() { try { @@ -151,7 +171,8 @@ namespace MelonVPNCore IsBackground = true }; _lThread.Start(); - } catch (Exception e) + } + catch (Exception e) { _stayListening = false; Console.WriteLine(e); @@ -171,9 +192,8 @@ namespace MelonVPNCore { try { - Socket handled = _sock.Accept(); - DaemonClient dc = new DaemonClient(handled); - clientConnected?.Invoke(null,dc); + DaemonClient dc = new DaemonClient(_sock.Accept()); + clientConnected?.Invoke(this,dc); } catch (Exception e) { @@ -214,4 +234,96 @@ namespace MelonVPNCore #endregion } + + public class DaemonClientMultiplexor : IDisposable + { + public ClientResponseState SendDataMessage(DataMessage msg) => SendCustomMessage(Messages.GetMessage(msg)); + private List plexed = new List(); + private object slockplexed = new object(); + private object slockcon = new object(); + private object slockrecv = new object(); + public event EventHandler clientMessageReceived; + public event EventHandler clientConnectComplete; + public bool startClients = true; + public bool disconnectErroredClients = true; + + public DaemonClientMultiplexor(DaemonServer dsIn) + { + if (dsIn is null) throw new ArgumentNullException(nameof(dsIn)); + dsIn.clientConnected += DsIn_ClientConnected; + } + + void DsIn_ClientConnected(object sender, DaemonClient e) + { + lock (slockplexed) plexed.Add(e); + e.messageReceived += E_MessageReceived; + e.connectionError += E_ConnectionError; + if (startClients) e.start(); + lock(slockcon) clientConnectComplete?.Invoke(this, e); + } + + void E_MessageReceived(object sender, string e) + { + lock(slockrecv) clientMessageReceived?.Invoke(this, e); + } + + void E_ConnectionError(object sender, Exception e) + { + if(disconnectErroredClients) ((DaemonClient)sender).Dispose(); + } + + public ClientResponseState SendCustomMessage(string msg) + { + var toret = ClientResponseState.Sent; + lock (slockplexed) { + foreach (DaemonClient c in plexed) + { + try + { + if (c.SendCustomMessage(msg) != ClientResponseState.Sent) toret = ClientResponseState.Error; + } catch (Exception e) + { + Console.WriteLine(e); + } + } + } + return toret; + } + + public void disconnectAllClients() + { + lock (slockplexed) foreach (DaemonClient c in plexed) c.Dispose(); + lock (slockplexed) plexed.Clear(); + } + + #region IDisposable Support + private bool disposedValue = false; // To detect redundant calls + + protected virtual void Dispose(bool disposing) + { + if (!disposedValue) + { + if (disposing) + { + lock(slockplexed) foreach (DaemonClient c in plexed) c.Dispose(); + lock (slockplexed) plexed.Clear(); + } + + plexed = null; + slockcon = null; + slockrecv = null; + slockplexed = null; + disposedValue = true; + } + } + + // This code added to correctly implement the disposable pattern. + public void Dispose() + { + // Do not change this code. Put cleanup code in Dispose(bool disposing) above. + Dispose(true); + } + #endregion + + } } diff --git a/MelonVPNCore/DaemonSocketServer.cs b/MelonVPNCore/DaemonSocketServer.cs index 54ef645..1707bc6 100644 --- a/MelonVPNCore/DaemonSocketServer.cs +++ b/MelonVPNCore/DaemonSocketServer.cs @@ -15,158 +15,16 @@ namespace MelonVPNCore private static bool isRestarting = false; private static int startingTime = 3000; private static int restartDelay = 250; + private static DaemonServer _srv; + private static DaemonClientMultiplexor _mlt; + private static string lastClientUpdate = Messages.EOF; public static void StartServer() { - IPHostEntry host = Dns.GetHostEntry("localhost"); - IPAddress ipAddress = host.AddressList[0]; - IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 22035); - - try - { - Socket listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - listener.Bind(localEndPoint); - listener.Listen(32); - - string lastClientUpdate = Messages.EOF; - - while (true) - { - Socket handler = listener.Accept(); - - string data = null; - byte[] bytes = null; - - while (true) - { - bytes = new byte[1024]; - int bytesRec = handler.Receive(bytes); - data += Encoding.ASCII.GetString(bytes, 0, bytesRec); - if (data.IndexOf(Messages.EOF, StringComparison.CurrentCulture) > -1) break; - } - - if (data.StartsWith(Messages.ClientListStartMsg, StringComparison.CurrentCulture) && shouldBeRunning) - { - lastClientUpdate = data; - Client.SendCustomMessage(lastClientUpdate, true); - } - else if (data == Messages.RestartOnMsg) - { - shouldRestart = true; - Client.SendDataMessage(DataMessage.RestartOn, true); - } - else if (data == Messages.RestartOffMsg) - { - shouldRestart = false; - Client.SendDataMessage(DataMessage.RestartOff, true); - } - else if (data == Messages.StatusMsg) - { - Console.WriteLine("Status requested"); - if (isProcessOnline(currentVpnProcess) || shouldBeRunning) - { - if (isRestarting) - { - Console.WriteLine("Sending response: restarting"); - Client.SendDataMessage(DataMessage.Restarting, true); - Client.SendCustomMessage(lastClientUpdate, true); - } - else - { - Console.WriteLine("Sending response: online"); - Client.SendDataMessage(DataMessage.Online, true); - Client.SendCustomMessage(lastClientUpdate, true); - } - } - else - { - Console.WriteLine("Sending response: offline"); - Client.SendDataMessage(DataMessage.Offline, true); - Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); - } - Client.SendDataMessage((shouldRestart) ? DataMessage.RestartOn : DataMessage.RestartOff); - } - else if (data == Messages.StartMsg) - { - if (! isProcessOnline(currentVpnProcess)) - { - shouldBeRunning = true; - Console.WriteLine("Starting VPN"); - try - { - Console.WriteLine("Starting embedded process"); - Console.WriteLine("Sending starting reply"); - Client.SendDataMessage(DataMessage.Starting, true); - if (StartEProcess(true)) - { - Console.WriteLine("Sending online reply"); - Client.SendDataMessage(DataMessage.Online, true); - currentVpnProcess.EnableRaisingEvents = true; - } - else { throw new InvalidOperationException("Client crashed!"); } - } - catch (Exception e) - { - shouldBeRunning = false; - Console.WriteLine("There was an error. But I fixed it."); - Console.WriteLine("It looked like this: " + e); - currentVpnProcess.Dispose(); - currentVpnProcess = null; - Client.SendDataMessage(DataMessage.Error, true); - Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); - } - } - else - { - Console.WriteLine("VPN already started"); - } - } - else if (data == Messages.StopMsg) - { - shouldBeRunning = false; - bool haderr = false; - if (isProcessOnline(currentVpnProcess)) - { - Console.WriteLine("Stopping VPN"); - try - { - currentVpnProcess.EnableRaisingEvents = false; - Console.WriteLine("Stopping embedded process"); - currentVpnProcess.Kill(); - currentVpnProcess = null; - } - catch (Exception e) - { - Console.WriteLine("There was an error. But I fixed it."); - Console.WriteLine("It looked like this: " + e); - currentVpnProcess = null; - Client.SendDataMessage(DataMessage.Error, true); - Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); - haderr = true; - } - } - else - { - Console.WriteLine("VPN already stopped"); - } - if (!haderr) - { - Console.WriteLine("Sending offline reply"); - Client.SendDataMessage(DataMessage.Offline, true); - Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); - } - } - - Client.SendDataMessage(DataMessage.Blank, true); - - handler.Shutdown(SocketShutdown.Both); - handler.Close(); - } - } - catch (Exception e) - { - Console.WriteLine(e); - } + _srv = new DaemonServer(); + _mlt = new DaemonClientMultiplexor(_srv); + _mlt.clientMessageReceived += clientMessageReceived; + _srv.start(); } public static bool isProcessOnline(Process p) @@ -188,6 +46,132 @@ namespace MelonVPNCore } } + static void clientMessageReceived(object sender, string data) + { + try + { + if (data.StartsWith(Messages.ClientListStartMsg, StringComparison.CurrentCulture) && shouldBeRunning) + { + lastClientUpdate = data; + _mlt.SendCustomMessage(lastClientUpdate); + } + else if (data == Messages.RestartOnMsg) + { + shouldRestart = true; + _mlt.SendDataMessage(DataMessage.RestartOn); + } + else if (data == Messages.RestartOffMsg) + { + shouldRestart = false; + _mlt.SendDataMessage(DataMessage.RestartOff); + } + else if (data == Messages.StatusMsg) + { + Console.WriteLine("Status requested"); + if (isProcessOnline(currentVpnProcess) || shouldBeRunning) + { + if (isRestarting) + { + Console.WriteLine("Sending response: restarting"); + _mlt.SendDataMessage(DataMessage.Restarting); + _mlt.SendCustomMessage(lastClientUpdate); + } + else + { + Console.WriteLine("Sending response: online"); + _mlt.SendDataMessage(DataMessage.Online); + _mlt.SendCustomMessage(lastClientUpdate); + } + } + else + { + Console.WriteLine("Sending response: offline"); + _mlt.SendDataMessage(DataMessage.Offline); + _mlt.SendCustomMessage(Messages.ClientListEmptyMsg); + } + _mlt.SendDataMessage((shouldRestart) ? DataMessage.RestartOn : DataMessage.RestartOff); + } + else if (data == Messages.StartMsg) + { + if (!isProcessOnline(currentVpnProcess)) + { + shouldBeRunning = true; + Console.WriteLine("Starting VPN"); + try + { + Console.WriteLine("Starting embedded process"); + Console.WriteLine("Sending starting reply"); + _mlt.SendDataMessage(DataMessage.Starting); + if (StartEProcess(true)) + { + Console.WriteLine("Sending online reply"); + _mlt.SendDataMessage(DataMessage.Online); + currentVpnProcess.EnableRaisingEvents = true; + } + else { throw new InvalidOperationException("Client crashed!"); } + } + catch (Exception e) + { + shouldBeRunning = false; + Console.WriteLine("There was an error. But I fixed it."); + Console.WriteLine("It looked like this: " + e); + currentVpnProcess.Dispose(); + currentVpnProcess = null; + _mlt.SendDataMessage(DataMessage.Error); + _mlt.SendCustomMessage(Messages.ClientListEmptyMsg); + } + } + else + { + Console.WriteLine("VPN already started"); + } + } + else if (data == Messages.StopMsg) + { + shouldBeRunning = false; + bool haderr = false; + if (isProcessOnline(currentVpnProcess)) + { + Console.WriteLine("Stopping VPN"); + try + { + currentVpnProcess.EnableRaisingEvents = false; + Console.WriteLine("Stopping embedded process"); + currentVpnProcess.Kill(); + currentVpnProcess = null; + } + catch (Exception e) + { + Console.WriteLine("There was an error. But I fixed it."); + Console.WriteLine("It looked like this: " + e); + currentVpnProcess = null; + _mlt.SendDataMessage(DataMessage.Error); + _mlt.SendCustomMessage(Messages.ClientListEmptyMsg); + haderr = true; + } + } + else + { + Console.WriteLine("VPN already stopped"); + } + if (!haderr) + { + Console.WriteLine("Sending offline reply"); + _mlt.SendDataMessage(DataMessage.Offline); + _mlt.SendCustomMessage(Messages.ClientListEmptyMsg); + } + } + + _mlt.SendDataMessage(DataMessage.Blank); + + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + + static void CurrentVpnProcess_Exited(object sender, EventArgs e) { Console.WriteLine("Restarting embedded process"); @@ -199,11 +183,11 @@ namespace MelonVPNCore while (shouldRestart && shouldBeRunning) { Console.WriteLine("Sending restarting reply"); - Client.SendDataMessage(DataMessage.Restarting, true); + _mlt.SendDataMessage(DataMessage.Restarting); if (StartEProcess(false)) { Console.WriteLine("Sending online reply"); - Client.SendDataMessage(DataMessage.Online, true); + _mlt.SendDataMessage(DataMessage.Online); currentVpnProcess.EnableRaisingEvents = true; imonline = true; break; @@ -220,8 +204,8 @@ namespace MelonVPNCore { shouldBeRunning = false; Console.WriteLine("Sending offline reply"); - Client.SendDataMessage(DataMessage.Offline, true); - Client.SendCustomMessage(Messages.ClientListEmptyMsg, true); + _mlt.SendDataMessage(DataMessage.Offline); + _mlt.SendCustomMessage(Messages.ClientListEmptyMsg); } } diff --git a/MelonVPNCore/GUISocketServer.cs b/MelonVPNCore/GUISocketServer.cs index 20a4d6b..3e45287 100644 --- a/MelonVPNCore/GUISocketServer.cs +++ b/MelonVPNCore/GUISocketServer.cs @@ -2,70 +2,105 @@ using System.Net; using System.Net.Sockets; using System.Text; +using System.Threading; namespace MelonVPNCore { public static class GUISocketServer { + public static ClientResponseState SendDataMessage(DataMessage msg) => SendCustomMessage(Messages.GetMessage(msg)); + public static int reconnectTimeout = 2000; + public static DaemonClient client; public static event EventHandler Receive; public static event EventHandler ClientListUpdate; + private static bool waitfcl = false; + private static bool exec = true; public static void StartServer() { - IPHostEntry host = Dns.GetHostEntry("localhost"); - IPAddress ipAddress = host.AddressList[0]; - IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 22036); + while (exec) + { + try + { + client = new DaemonClient(); + client.connectionError += Client_ConnectionError; + client.messageReceived += Client_MessageReceived; + waitfcl = true; + client.start(); + while (waitfcl) Thread.Sleep(reconnectTimeout); + client.connectionError -= Client_ConnectionError; + client.messageReceived -= Client_MessageReceived; + client.Dispose(); + } + catch (InvalidOperationException e) + { + Console.WriteLine(e); + } + Thread.Sleep(reconnectTimeout); + } + Console.WriteLine("GUISocketServer has reached the end."); + } + + public static void oneConnect() + { try { - Socket listener = new Socket(ipAddress.AddressFamily, SocketType.Stream, ProtocolType.Tcp); - listener.Bind(localEndPoint); - listener.Listen(32); + client = new DaemonClient(); + client.messageReceived += Client_MessageReceived; + waitfcl = true; + client.start(); + } + catch (InvalidOperationException e) + { + Console.WriteLine(e); + } + } - while (true) + public static void oneDispose() + { + client.messageReceived -= Client_MessageReceived; + client.Dispose(); + } + + static void Client_ConnectionError(object sender, Exception e) + { + waitfcl = false; + } + + static void Client_MessageReceived(object sender, string data) + { + try + { + ClientResponseState ret = ClientResponseState.None; + if (data == Messages.OnlineMsg) ret = ClientResponseState.Online; + if (data == Messages.OfflineMsg) ret = ClientResponseState.Offline; + if (data == Messages.ErrorMsg) ret = ClientResponseState.ServerError; + if (data == Messages.StartingMsg) ret = ClientResponseState.Starting; + if (data == Messages.RestartingMsg) ret = ClientResponseState.Restarting; + if (data == Messages.RestartOnMsg) ret = ClientResponseState.RestartOn; + if (data == Messages.RestartOffMsg) ret = ClientResponseState.RestartOff; + Console.WriteLine(data); + if (data.StartsWith(Messages.ClientListStartMsg, StringComparison.CurrentCulture)) { - Socket handler = listener.Accept(); - - string data = ""; - byte[] bytes = null; - - while (true) - { - bytes = new byte[1024]; - int bytesRec = handler.Receive(bytes); - data += Encoding.ASCII.GetString(bytes, 0, bytesRec); - if (data.IndexOf(Messages.EOF, StringComparison.CurrentCulture) > -1) break; - } - - ClientResponseState ret = ClientResponseState.None; - if (data == Messages.OnlineMsg) ret = ClientResponseState.Online; - if (data == Messages.OfflineMsg) ret = ClientResponseState.Offline; - if (data == Messages.ErrorMsg) ret = ClientResponseState.ServerError; - if (data == Messages.StartingMsg) ret = ClientResponseState.Starting; - if (data == Messages.RestartingMsg) ret = ClientResponseState.Restarting; - if (data == Messages.RestartOnMsg) ret = ClientResponseState.RestartOn; - if (data == Messages.RestartOffMsg) ret = ClientResponseState.RestartOff; - Console.WriteLine(data); - if (data.StartsWith(Messages.ClientListStartMsg, StringComparison.CurrentCulture)) - { - string jsonWithEof = data.Substring(Messages.ClientListStartMsg.Length); - string jsonData = jsonWithEof.Substring(0, jsonWithEof.Length - Messages.EOF.Length); - Console.WriteLine("clients: " + jsonData); - ConnectedClient[] clients = ClientListParser.Parse(jsonData); - ClientListUpdate?.Invoke(null, clients); - } - - handler.Shutdown(SocketShutdown.Both); - handler.Close(); - - Receive?.Invoke(null, ret); + string jsonWithEof = data.Substring(Messages.ClientListStartMsg.Length); + string jsonData = jsonWithEof.Substring(0, jsonWithEof.Length - Messages.EOF.Length); + Console.WriteLine("clients: " + jsonData); + ConnectedClient[] clients = ClientListParser.Parse(jsonData); + ClientListUpdate?.Invoke(null, clients); } + Receive?.Invoke(null, ret); } catch (Exception e) { Console.WriteLine(e); } - Console.WriteLine("GUI socket server reached the end"); + } + + public static ClientResponseState SendCustomMessage(string msg) + { + var toret = client?.SendCustomMessage(msg); + return (toret.HasValue) ? toret.Value : ClientResponseState.Error; } } } diff --git a/MelonVPNCore/MelonVPNCore.csproj b/MelonVPNCore/MelonVPNCore.csproj index 82c59fb..b74fae8 100644 --- a/MelonVPNCore/MelonVPNCore.csproj +++ b/MelonVPNCore/MelonVPNCore.csproj @@ -29,7 +29,6 @@ -