using System; using System.Net; using Holo.Virtual.Users; using System.Linq; using Holo.Source.Socket_servers.ClientSocket; using System.Net.Sockets; using System.Diagnostics; namespace Holo.GameConnectionSystem { public static class gameSocketServer { #region Fields private static Socket mSocketListner; private static int mMaxConnections; private static int mSystraProcessID; private static AsyncCallback mConnectionReqCallback; private static string[] mConnectionCounter; #endregion #region Methods internal static void SetupSocket(int pPort, int pMaxConnections) { Out.WriteLine("Setting up socket on port " + pPort); mConnectionReqCallback = new AsyncCallback(ConnectionRequest); mMaxConnections = pMaxConnections; mSystraProcessID = Process.GetCurrentProcess().Id; mConnectionCounter = new string[pMaxConnections]; StartListening(pPort, pMaxConnections); } internal static void StartListening(int pPort, int pMaxConnections) { try { Out.WriteLine("Setting up sockets"); mSocketListner = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint Endpoint = new IPEndPoint(IPAddress.Any, pPort); mSocketListner.Bind(Endpoint); mSocketListner.Listen(1000); mSocketListner.BeginAccept(mConnectionReqCallback, mSocketListner); Out.WriteLine("Ready to accept connections!"); } catch (Exception e) { Out.WriteError("Could not set up socket:\r" + e.ToString()); Holo.Eucalypt.Shutdown(); } } private static void ConnectionRequest(IAsyncResult iAr) { try { Socket ClientSock = ((Socket)iAr.AsyncState).EndAccept(iAr); string IP = ClientSock.RemoteEndPoint.ToString().Split(':')[0]; AddConnection(ClientSock, IP, iAr); } catch (SocketException sck) //Nothing interresting { } catch (Exception e) { Out.WriteError(e.ToString()); } mSocketListner.BeginAccept(mConnectionReqCallback, mSocketListner); } private static void AddConnection(Socket pSock, string pIP, IAsyncResult pConnInfo) { uint SocketID = NewSocketID; if (!ConnectionAllowed(pIP, (int)SocketID)) { pSock.Close(); return; } Out.WriteLine("[" + pIP + "] --> Connection accepted as [" + SocketID + "]"); virtualUser User = new virtualUser(); SocketInformation Socketinfo = pSock.DuplicateAndClose(mSystraProcessID); User.Bind(new SocketExtension(User, Socketinfo, SocketID, pIP)); } private static uint NewSocketID { get { int ID = Array.IndexOf(mConnectionCounter, null); if (ID != -1) return (uint)ID; else return (uint)acceptedConnections + 1; } } internal static void DisposeConnection(uint mSocketID) { mConnectionCounter[(int)mSocketID] = null; Out.WriteLine("[" + mSocketID + "] --> Connection disposed."); } #endregion #region Properties internal static int acceptedConnections { get { return mConnectionCounter.Count(a => (a != null)); } } #endregion #region Anti-ddos internal static bool ConnectionAllowed(string IP, int ID) { int conncout = mConnectionCounter.Count(a => (a == IP)); if (conncout >= 10 || ID > mMaxConnections) //Reached connection limit return false; mConnectionCounter[ID] = IP; return true; } #endregion } }