namespace XMeGo.Network.Sockets { using System; using System.Collections.Generic; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Threading; using XMeGo; public class ClientWrapper { public bool IsAlive; public byte[] Buffer; public int BufferSize; public Action<byte[], int, ClientWrapper> Callback; public object Owner; public string IP; public Time32 LastReceive; public Time32 LastReceiveCall; public string LocalIp; public string MAC; public bool OverrideTiming; private Queue<byte[]> SendQueue; private object SendSyncRoot; public ServerSocket Server; public System.Net.Sockets.Socket Socket; private IDisposable[] TimerSubscriptions; [DllImport("ws2_32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern int closesocket(IntPtr s); public void Create(System.Net.Sockets.Socket socket, ServerSocket server, Action<byte[], int, ClientWrapper> callBack) { this.Callback = callBack; this.BufferSize = 0x7ff; this.Socket = socket; this.Server = server; this.Buffer = new byte[this.BufferSize]; this.LastReceive = Time32.Now; this.OverrideTiming = false; this.SendQueue = new Queue<byte[]>(); this.SendSyncRoot = new object(); this.TimerSubscriptions = new IDisposable[] { World.Subscribe<ClientWrapper>(Program.World.ConnectionReview, this, World.GenericThreadPool), World.Subscribe<ClientWrapper>(Program.World.ConnectionReceive, this, World.ReceivePool), World.Subscribe<ClientWrapper>(Program.World.ConnectionSend, this, World.SendPool) }; } public void Disconnect() { lock (this.Socket) { int num = 0x3e8; while (((this.SendQueue.Count > 0) && this.IsAlive) && (num-- > 0)) { Thread.Sleep(1); } if (this.IsAlive) { this.IsAlive = false; for (int i = 0; i < this.TimerSubscriptions.Length; i++) { this.TimerSubscriptions[i].Dispose(); } shutdown(this.Socket.Handle, ShutDownFlags.SD_BOTH); closesocket(this.Socket.Handle); this.Socket.Dispose(); } } } private void doReceive(int available) { this.LastReceive = Time32.Now; try { if (available > this.Buffer.Length) { available = this.Buffer.Length; } int num = this.Socket.Receive(this.Buffer, available, SocketFlags.None); if (num != 0) { if (this.Callback != null) { this.Callback(this.Buffer, num, this); } } else { this.Server.InvokeDisconnect(this); } } catch (SocketException) { this.Server.InvokeDisconnect(this); } catch (Exception exception) { XMeGo.Console.WriteLine(exception, ConsoleColor.DarkYellow); } } private static void endSend(IAsyncResult ar) { ClientWrapper asyncState = ar.AsyncState as ClientWrapper; try { asyncState.Socket.EndSend(ar); } catch { asyncState.Server.InvokeDisconnect(asyncState); } } private bool isValid() { if (this.IsAlive || (this.TimerSubscriptions == null)) { return true; } for (int i = 0; i < this.TimerSubscriptions.Length; i++) { this.TimerSubscriptions[i].Dispose(); } return false; } public void Send(byte[] data) { lock (this.SendSyncRoot) { this.SendQueue.Enqueue(data); } } [DllImport("ws2_32.dll", CharSet = CharSet.Unicode, SetLastError = true)] public static extern int shutdown(IntPtr s, ShutDownFlags how); private bool TryDequeueSend(out byte[] buffer) { buffer = null; lock (this.SendSyncRoot) { if (this.SendQueue.Count != 0) { buffer = this.SendQueue.Dequeue(); } } return (buffer != null); } public static void TryReceive(ClientWrapper wrapper) { wrapper.LastReceiveCall = Time32.Now; if (wrapper.isValid()) { try { bool flag = wrapper.Socket.Poll(0, SelectMode.SelectRead); int available = wrapper.Socket.Available; if (available > 0) { wrapper.doReceive(available); } else if (flag) { wrapper.Server.InvokeDisconnect(wrapper); } } catch (SocketException) { wrapper.Server.InvokeDisconnect(wrapper); } } } public static void TryReview(ClientWrapper wrapper) { if (wrapper.IsAlive) { if (wrapper.OverrideTiming) { if (Time32.Now > wrapper.LastReceive.AddMilliseconds(0x2bf20)) { wrapper.Server.InvokeDisconnect(wrapper); } } else if ((Time32.Now < wrapper.LastReceiveCall.AddMilliseconds(0x7d0)) && (Time32.Now > wrapper.LastReceive.AddMilliseconds(0xea60))) { wrapper.Server.InvokeDisconnect(wrapper); } } } public static void TrySend(ClientWrapper wrapper) { if (wrapper.isValid()) { byte[] buffer; while (wrapper.TryDequeueSend(out buffer)) { try { wrapper.Socket.Send(buffer); } catch { wrapper.Server.InvokeDisconnect(wrapper); } } } } public enum ShutDownFlags { SD_RECEIVE, SD_SEND, SD_BOTH } } }
namespace XMeGo.Network.Sockets { using System; using System.Collections.Concurrent; using System.Net; using System.Net.Sockets; using System.Runtime.InteropServices; using System.Threading; using XMeGo; public class ServerSocket { private ConcurrentDictionary<int, int> BruteforceProtection; private Socket Connection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); private bool enabled; private string ipString; private ushort port; public bool PrintoutIPs; private object SyncRoot = new object(); private Thread thread; private const int TimeLimit = 0x3a98; public event Action<ClientWrapper> OnClientConnect; public event Action<ClientWrapper> OnClientDisconnect; public event Action<byte[], int, ClientWrapper> OnClientReceive; public ServerSocket() { this.thread = new Thread(new ThreadStart(this.doSyncAccept)); this.thread.Start(); } public void Disable() { this.enabled = false; this.Connection.Close(1); } private void doSyncAccept() { while (true) { if (this.enabled) { try { this.processSocket(this.Connection.Accept()); } catch { } } Thread.Sleep(1); } } public void Enable() { if (!this.enabled) { this.Connection = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); this.Connection.Bind(new IPEndPoint(IPAddress.Any, this.port)); this.Connection.Listen(100); this.enabled = true; } } public void Enable(ushort port) { this.port = port; this.Connection.Bind(new IPEndPoint(IPAddress.Any, this.port)); this.Connection.Listen(100); this.enabled = true; this.BruteforceProtection = new ConcurrentDictionary<int, int>(); } public void Enable(ushort port, string ip, bool BigSend = false) { this.ipString = ip; this.port = port; this.Connection.Bind(new IPEndPoint(IPAddress.Parse(this.ipString), this.port)); this.Connection.Listen(0x7fffffff); if (BigSend) { this.Connection.ReceiveBufferSize = 0xffff; this.Connection.SendBufferSize = 0xffff; } this.enabled = true; this.BruteforceProtection = new ConcurrentDictionary<int, int>(); } public void InvokeDisconnect(ClientWrapper Client) { if (this.OnClientDisconnect != null) { this.OnClientDisconnect(Client); } } private void processSocket(Socket socket) { try { string str = (socket.RemoteEndPoint as IPEndPoint).Address.ToString(); string str2 = (socket.LocalEndPoint as IPEndPoint).Address.ToString(); int hashCode = str.GetHashCode(); if (!Program.ALEXPC) { int num3; int num2 = Time32.Now.GetHashCode(); if (!this.BruteforceProtection.TryGetValue(hashCode, out num3)) { this.BruteforceProtection[hashCode] = num2; } else { if ((num2 - num3) < 0x3a98) { if (this.PrintoutIPs) { XMeGo.Console.WriteLine("Dropped connection: " + str, ConsoleColor.DarkYellow); } socket.Disconnect(false); socket.Close(); return; } this.BruteforceProtection[hashCode] = num2; if (this.PrintoutIPs) { XMeGo.Console.WriteLine("Allowed connection: " + str, ConsoleColor.DarkYellow); } } } ClientWrapper wrapper = new ClientWrapper(); wrapper.Create(socket, this, this.OnClientReceive); wrapper.IsAlive = true; wrapper.IP = str; wrapper.LocalIp = str2; if (this.OnClientConnect != null) { this.OnClientConnect(wrapper); } } catch (Exception exception) { XMeGo.Console.WriteLine(exception, ConsoleColor.DarkYellow); } } public void Reset() { this.Disable(); this.Enable(); } public void stoptheard() { this.thread = null; } public bool Enabled { get { return this.enabled; } } } }