using System; using System.Net; using System.Net.Sockets; using System.Collections.Generic; using System.Threading; using Holo.Virtual.Users; using System.Collections; using Holo.Source.Managers; using Holo.Source.GameConnectionSystem; using Holo.Managers; namespace Holo.GameConnectionSystem { /// /// Asynchronous socket server for the game connections. /// public static class gameSocketServer { #region Declares private static Socket socketHandler; private static int _Port = int.Parse(Config.getTableEntry("server_game_port")); private static int _maxConnections = int.Parse(Config.getTableEntry("server_game_maxconnections")); private static int _acceptedConnections; private static HashSet _activeConnections; private static Hashtable connections = new Hashtable(2); private static bool AcceptConnections = true; #endregion #region Methods internal static void SetupSocket() { connectionHelper.Init(); AcceptConnections = true; if (_activeConnections != null) _activeConnections.Clear(); _activeConnections = new HashSet(); StartListening(); } internal static void Destroy() { AcceptConnections = false; HashSet Data = _activeConnections; foreach (int ConnectionID in Data) { freeConnection(ConnectionID); } } internal static void StartListening() { bool SomethingWentWrong = false; try { if (_Port == 0 || _maxConnections == 0) throw new NullReferenceException(); else { socketHandler = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint Endpoint = new IPEndPoint(IPAddress.Any, _Port); socketHandler.Bind(Endpoint); socketHandler.Listen(1000); while (!AcceptConnections) { socketHandler.BeginAccept(new AsyncCallback(InncommingDataRequest), socketHandler); } } } catch (Exception e) { Out.WriteError("Fatal error during socket setup:\r" + e.ToString()); SomethingWentWrong = true; Holo.Eucalypt.Shutdown(); } finally { if (!SomethingWentWrong) { socketHandler.BeginAccept(new AsyncCallback(InncommingDataRequest), socketHandler); } } } internal static void InncommingDataRequest(IAsyncResult iAr) { //Out.WriteLine("New connectionRequest"); try { Socket ReplyFromComputer = ((Socket)iAr.AsyncState).EndAccept(iAr); string IP = ReplyFromComputer.RemoteEndPoint.ToString().Split(':')[0]; int amount = GetConnectionAmount(IP); if (acceptedConnections >= maxConnections || AcceptConnections == false) { ReplyFromComputer.Shutdown(SocketShutdown.Both); ReplyFromComputer.Close(); } //else if (amount > 10) //{ // { // ReplyFromComputer.Shutdown(SocketShutdown.Both); // ReplyFromComputer.Close(); // connectionHelper.BanIP(IP); // } //} else if (connectionHelper.IpIsBanned(IP) == true) { ReplyFromComputer.Shutdown(SocketShutdown.Both); ReplyFromComputer.Close(); } else { int ConnectionRequestID = NewConnectionRequestID(); if (ConnectionRequestID > 0) { //Out.WriteLine("Accepted connection: [" + ConnectionRequestID + "] from [" + IP + "]"); AddConnection(IP); new gameConnection(ReplyFromComputer, ConnectionRequestID); } } } catch { } socketHandler.BeginAccept(new AsyncCallback(InncommingDataRequest), socketHandler); } internal static int NewConnectionRequestID() { _acceptedConnections++; _activeConnections.Add(_acceptedConnections); return _acceptedConnections; } /// /// Flags a connection as free. /// /// The ID of the connection. internal static void freeConnection(int connectionID) { if (_activeConnections.Contains(connectionID)) { _activeConnections.Remove(connectionID); //Out.WriteLine("Flagged connection [" + connectionID + "] as free."); _acceptedConnections--; } } internal static void AddConnection(string IP) { int Amount = 0; if (connections.ContainsKey(IP) == true) { Amount = (int)connections[IP]; connections.Remove(IP); } else { Amount = 0; } int newamount = Amount + 1; connections.Add(IP, newamount); } internal static void RemoveConnection(string IP) { int IpConnected = 0; if (connections.ContainsKey(IP) == true) { IpConnected = (int)connections[IP]; } else { connections.Remove(IP); } if (IpConnected > 1) //More than one connected { int NewAmount = IpConnected - 1; connections.Remove(IP); connections.Add(IP, NewAmount); } else //Only one connected { connections.Remove(IP); } } #endregion #region Properities internal static int GetConnectionAmount(string IP) { if (connections.ContainsKey(IP) == true) { return ((int)connections[IP]); } else { return 0; } } internal static int maxConnections { /// /// Gets or set an Integer for the maximum amount of connections at the same time. /// set { _maxConnections = value; } get { return _maxConnections; } } internal static int acceptedConnections { /// /// Returns as integer of the accepted connections count since init. /// get { return _acceptedConnections; } } #endregion } }