/// <summary> /// Protected constructor, common functionality for this class and subclasses /// </summary> /// <param name="socket">TCP socket for communicating with the remote server</param> /// <param name="connectionLogWriter">Log writer module</param> /// <param name="serverList">Server List object</param> /// <param name="geoIP">GeoIP resolver</param> protected Connection(Socket socket, IConnectionLogWriter logWriter, ServerList serverList, GeoIP geoIP) { this.socket = socket; this.logWriter = logWriter; this.serverList = serverList; this.geoIP = geoIP; // Socket ID for logging SocketID = String.Format("{0}:{1}", (socket.RemoteEndPoint as IPEndPoint).Address, (socket.RemoteEndPoint as IPEndPoint).Port); }
/// <summary> /// Constructor /// </summary> /// <param name="parentConnection">Parent connection which owns this player connection</param> /// <param name="socket">TCP communication socket</param> /// <param name="connectionLogWriter">Log writer module</param> /// <param name="serverList">Server list object</param> /// <param name="geoIP">GeoIP resolver</param> /// <param name="locale">Locale reported by remote host</param> public ClientConnection(Connection parentConnection, Socket socket, IConnectionLogWriter logWriter, ServerList serverList, GeoIP geoIP, OperatingSystem operatingSystem, string locale) : base(socket, logWriter, serverList, geoIP) { this.outerConnection = parentConnection; this.operatingSystem = operatingSystem; this.locale = locale; socket.ReceiveTimeout = 300000; //MasterServer.Log("Accepting player connection from {0}", socket.RemoteEndPoint.ToString()); }
/// <summary> /// Creates a new ServerList /// </summary> /// <param name="masterServer"></param> public ServerList(MasterServer masterServer) { this.masterServer = masterServer; this.geoIP = masterServer.GeoIP; this.connectionLogWriter = ModuleManager.GetModule <IConnectionLogWriter>(); StartService(); // RPC Server UpdateLinks(); // RPC Client scavengeTimer = new Timer(new TimerCallback(this.Scavenge), null, 10000, Timeout.Infinite); ModuleManager.RegisterCommandListener(this); }
/// <summary> /// Process this packet assuming it is a gamestate packet, returns true if parsed with no errors /// </summary> /// <returns>True if no errors were encountered whilst reading the values from the packet</returns> public bool ProcessGameState(Server server, IConnectionLogWriter log) { try { ClientIPs = PopArray(); // Array of player IP/port, for some reason at the start of the packet not the end with the other player data ServerID = PopInt(); // ??? Seems to always be zero ServerIP = PopString(); // ??? Seems to always be empty Port = PopInt(); // Server's listen port QueryPort = PopInt(); // **NOTE** Always zero! Name = PopString(); // Server name Map = PopString(); // Current map GameType = PopString(); // Current game type NumPlayers = PopInt(); // Current players MaxPlayers = PopInt(); // Maximum players Ping = PopInt(); // **NOTE** Always zero! Info = PopKeyValueArray(); // Additional server information as key/value pairs } catch { return(false); } PacketType = ServerInfoPacketType.GameState; try { // This could probably be done using PopStructArray but this works as well int playercount = PopByte(); // Read player info from the packet for (int player = 0; player < playercount; player++) { // Client IP array may be shorter than the player list if this is a listen server string clientIP = (player < ClientIPs.Length) ? ClientIPs[player] : "local"; Players.Add(new Player(server, this, clientIP)); } } catch { if (log != null) { log.Write(String.Format("<{0}> ERROR PARSING GAMESTATE PLAYER DATA", server.Connection.SocketID), this); log.Write(String.Format("<{0}> PACKET={1}", server.Connection.SocketID, Print()), this); } } return(true); }
/// <summary> /// Create a new connection instance to handle an inbound connection /// </summary> /// <param name="socket">TCP socket for communicating with the remote server</param> /// <param name="connectionLogWriter">Log writer module</param> /// <param name="serverList">Server List object</param> /// <param name="geoIP">GeoIP resolver</param> /// <param name="md5Manager">MD5 database manager</param> /// <param name="banManager">IP ban manager</param> /// <param name="cdKeyValidator">CD key validator</param> /// <param name="gameStats">Game stats module</param> public Connection(Socket socket, IConnectionLogWriter logWriter, ServerList serverList, GeoIP geoIP, MD5Manager md5Manager, IPBanManager banManager, ICDKeyValidator cdKeyValidator, IGameStatsLog gameStats) : this(socket, logWriter, serverList, geoIP) { // Raise the NewConnection event for connected packet analysers OnNewConnection(); // Check whether the remote host is banned if (banManager.IsBanned((socket.RemoteEndPoint as IPEndPoint).Address)) { ConnectionLog("BANNED"); socket.Close(); return; } this.md5Manager = md5Manager; this.cdKeyValidator = cdKeyValidator; this.gameStats = gameStats; // Handle this connection in a new thread ConnectionThreadManager.CreateStart(new ThreadStart(Handle)); }
/// <summary> /// Constructor, called by the Connection class when it has established that this connection is to a /// server and has performed the initial authentication handshake. At this point the remote server /// should still be in the waiting for heartbeat State. /// </summary> /// <param name="serverList"></param> /// <param name="socket"></param> /// <param name="banFile"></param> public ServerConnection(Connection parentConnection, Socket socket, IConnectionLogWriter logWriter, ServerList serverList, GeoIP geoip, OperatingSystem operatingSystem, string locale, bool bStatLogging, MD5Manager md5Manager, ICDKeyValidator cdKeyValidator, IGameStatsLog gameStats) : base(socket, logWriter, serverList, geoip) { this.outerConnection = parentConnection; this.operatingSystem = operatingSystem; this.locale = locale; this.md5Manager = md5Manager; this.cdKeyValidator = cdKeyValidator; this.gameStats = gameStats; // Socket ID for logging SocketID = String.Format("{0}:{1}", (socket.RemoteEndPoint as IPEndPoint).Address, (socket.RemoteEndPoint as IPEndPoint).Port); // Set socket timeout socket.ReceiveTimeout = socketTimeoutSeconds * 1000; MasterServer.Log("[{0}] Accepting new server connection. Version={1}", (socket.RemoteEndPoint as IPEndPoint).Address.ToString(), parentConnection.Version); int matchID = serverList.GetMatchID(null); // Create the server object and register it with the server list server = new Server(this, parentConnection.Version, (socket.RemoteEndPoint as IPEndPoint).Address, parentConnection.CDKeyHash, geoip, serverList.GetHeartbeatCode(), bStatLogging, operatingSystem, locale, matchID); serverList.Add(server); }
/// <summary> /// Constructor, create a new query listener at the specified endpoint /// </summary> /// <param name="endpoint">Endpoint for this listener</param> /// <param name="serverList">Server list object to pass to new connections</param> /// <param name="geoIP">GeoIP resolver to pass to new connections</param> /// <param name="md5Manager">MD5 manager to pass to new connections</param> /// <param name="banManager">IP ban manager to pass to new connections</param> /// <param name="cdKeyValidator">CD key validator module to pass to new connections</param> /// <param name="gameStats">Game stats module to pass to new connections</param> public QueryListener(IPEndPoint endpoint, ServerList serverList, GeoIP geoIP, MD5Manager md5Manager, IPBanManager banManager, ICDKeyValidator cdKeyValidator, IGameStatsLog gameStats) { // Endpoint to listen this.endpoint = endpoint; // These objects are passed to new connections this.serverList = serverList; this.geoIP = geoIP; this.md5Manager = md5Manager; this.banManager = banManager; this.cdKeyValidator = cdKeyValidator; this.gameStats = gameStats; // Get configured connection log writer module this.logWriter = ModuleManager.GetModule <IConnectionLogWriter>(); // Bind the listen socket ready to begin listening listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP); listenSocket.Bind(this.Endpoint); // Create and start the listen thread listenThread = new Thread(ListenThreadProc); listenThread.Start(); }