Exemple #1
0
        /// <summary>
        /// Called when the connection receives a hello packet during initial handshake
        /// </summary>
        /// <param name="hello"></param>
        public void HandleHello(ServerInfoPacket hello)
        {
            ServerBehindNAT = hello.ServerBehindNAT;
            UplinkToGamespy = hello.UplinkToGamespy;

            this.LastUpdate = DateTime.Now;
        }
Exemple #2
0
        /// <summary>
        /// Handle a server greeting "HELLO"
        /// </summary>
        /// <param name="serverInfo"></param>
        protected virtual void HandleHello(ServerInfoPacket serverInfo)
        {
            if (serverInfo.ProcessHello())
            {
                ConnectionLog("HELLO SERVERBEHINDNAT={0} UPLINKTOGAMESPY={1}", serverInfo.ServerBehindNAT, serverInfo.UplinkToGamespy);
                MasterServer.Log("[{0}] sent greeting. ServerBehindNAT={1}", server.Address, serverInfo.ServerBehindNAT);

                server.HandleHello(serverInfo);

                SendHeartbeatRequest(HeartbeatType.QueryInterface, server.HeartbeatCode);
                SendHeartbeatRequest(HeartbeatType.GamePort, server.HeartbeatCode);

                if (server.UplinkToGamespy)
                {
                    SendHeartbeatRequest(HeartbeatType.GamespyQueryPort, server.HeartbeatCode);
                }

                waitingHeartbeatTime = DateTime.Now;
                State = ConnectionState.WaitingHeartbeat;
            }
            else
            {
                ConnectionLog("HELLO INVALID");
                MasterServer.Log("[{0}] Invalid greeting received, closing connection", server.Address);
                Abort();
            }
        }
Exemple #3
0
        /// <summary>
        /// Update information for a local server using the supplied gamestate packet
        /// </summary>
        /// <param name="server">Server to update</param>
        /// <param name="serverInfo">Gamestate packet</param>
        public void UpdateServer(Server server, ServerInfoPacket serverInfo)
        {
            // Update the server
            server.Update(serverInfo);

            // Remove duplicate servers
            List <Server> pendingRemoval = new List <Server>();

            lock (serverListLock)
            {
                foreach (Server otherServer in servers)
                {
                    if (otherServer != server && otherServer.IsDuplicateOf(server))
                    {
                        // Can't modify the collection here
                        pendingRemoval.Add(otherServer);
                    }
                }
            }

            foreach (Server removeServer in pendingRemoval)
            {
                MasterServer.Log("[{0}] Removing duplicate server record.", removeServer);
                Remove(removeServer);
            }

#if !WCF
#warning "WCF functionality disabled - ServerList RPC will not function"
#else
            // Propogate server information to remote master servers
            foreach (RemoteMasterServer remoteMaster in remoteMasters)
            {
                try
                {
                    remoteMaster.Update(
                        server.Active,
                        server.Address,
                        server.CDKey,
                        server.Name,
                        server.Country,
                        server.Locale,
                        server.Port,
                        server.QueryPort,
                        server.Map,
                        server.GameType,
                        server.MaxPlayers,
                        server.CurrentPlayers,
                        server.Properties,
                        server.Players
                        );
                }
                catch (MessageSecurityException)
                {
                    MasterServer.Log("[RPC] Credentials rejected by remote server at {0}", remoteMaster.InnerChannel.RemoteAddress.Uri.Host);
                }
                catch (CommunicationException) { }
            }
#endif
        }
Exemple #4
0
        /// <summary>
        /// Handle a player disconnect failed response
        /// </summary>
        /// <param name="serverInfo"></param>
        protected virtual void HandleClientDisconnectFailed(ServerInfoPacket serverInfo)
        {
            ConnectionLog("STM_CLIENTDISCONNECTFAILED");

            if (serverInfo.ProcessClientDisconnectFailed())
            {
                MasterServer.Log("[{0}] Disconnect client {1} failed", server, serverInfo.ClientIP);
            }
        }
Exemple #5
0
        /// <summary>
        /// Handle stats information from a server
        /// </summary>
        /// <param name="serverInfo"></param>
        protected virtual void HandleStats(ServerInfoPacket serverInfo)
        {
            ConnectionLog("STM_STATS BTSTATLOGGING={0}", server.EnableStatLogging);

            if (server.EnableStatLogging && serverInfo.ProcessGameStats() && gameStats != null)
            {
                gameStats.Log(DateTime.Now, server, serverInfo.StatLine);
            }
        }
Exemple #6
0
        /// <summary>
        /// Update this server instance with information from the supplied packet
        /// </summary>
        /// <param name="data"></param>
        public void Update(ServerInfoPacket data)
        {
            this.Active         = true;
            this.Name           = data.Name;
            this.Port           = data.Port;
            this.Map            = data.Map;
            this.GameType       = data.GameType;
            this.MaxPlayers     = data.MaxPlayers;
            this.CurrentPlayers = data.NumPlayers;
            this.Properties     = data.Info;
            this.Players        = data.Players;

            this.LastUpdate = DateTime.Now;
            this.listEntry  = new ServerListEntry(Address, (ushort)Port, (ushort)QueryPort, Name, Map, GameType, (byte)CurrentPlayers, (byte)MaxPlayers, Flags);
        }
Exemple #7
0
        /// <summary>
        /// Handle a player challenge response
        /// </summary>
        /// <param name="serverInfo"></param>
        protected virtual void HandleClientChallengeResponse(ServerInfoPacket serverInfo)
        {
            MasterServer.Log("[{0}] Received STM_ClientResponse", server);

            if (serverInfo.ProcessClientResponse())
            {
                ConnectionLog("STM_CLIENTRESPONSE MD5={0} MD5={1}", serverInfo.ClientCDKey, serverInfo.ClientCDKeySalted);

                MasterServer.Log("{0} MD5={1}", serverInfo.ClientIP, serverInfo.ClientCDKey);
                MasterServer.Log("{0} MD5={1}", serverInfo.ClientIP, serverInfo.ClientCDKeySalted);

                if (validationContexts.ContainsKey(serverInfo.ClientIP))
                {
                    ValidationContext clientValidationContext = validationContexts[serverInfo.ClientIP];
                    validationContexts.Remove(serverInfo.ClientIP);

                    clientValidationContext.SetClientInfo(serverInfo.ClientCDKey, serverInfo.ClientCDKeySalted, outerConnection.Type, outerConnection.Version);

                    // Check player CD key is valid?
                    if (!cdKeyValidator.ValidateKey(clientValidationContext))
                    {
                        MasterServer.Log("Client {0} CD key invalid. Disconnecting client.", serverInfo.ClientIP);
                        DisconnectClient(serverInfo.ClientIP);
                    }
                    else if (!cdKeyValidator.ValidateSaltedKey(clientValidationContext))
                    {
                        MasterServer.Log("Client {0} failed challenge. Disconnecting client.", serverInfo.ClientIP);
                        DisconnectClient(serverInfo.ClientIP);
                    }
                    else
                    {
                        MasterServer.Log("Client {0} challenge succeeded.", serverInfo.ClientIP);
                    }

                    cdKeyValidator.EndValidation(clientValidationContext);
                }
                else
                {
                    MasterServer.Log("Client {0} challenge unverified. No matching context found!");
                }
            }
            else
            {
                ConnectionLog("STM_CLIENTRESPONSE BAD: {0}", serverInfo.Print());
            }
        }
Exemple #8
0
        public void GetServerInfo()
        {
            if (_client.Connected)
            {
                using (ServerInfoPacket _serverInfoP = new ServerInfoPacket(_stream))
                {
                    _serverInfoP.ReceivePacket(_aes);

                    serverHeader  = Encoding.Unicode.GetString(_serverInfoP.serverHeader);
                    serverVersion = Encoding.Unicode.GetString(_serverInfoP.serverVersion);
                }
            }
            else
            {
                throw new Exception("Not connected!");
            }
        }
Exemple #9
0
        /// <summary>
        /// Handle an MD5 version packet
        /// </summary>
        /// <param name="serverInfo"></param>
        protected virtual void HandleMD5Version(ServerInfoPacket serverInfo)
        {
            if (serverInfo.ProcessMD5Version())
            {
                ConnectionLog("STM_MD5VERSION VERSION={0}", serverInfo.MD5Version);
                MasterServer.Log("[{0}] STM_MD5Version with: {1}", server, serverInfo.MD5Version);

                List <MD5Entry> updates = md5Manager.Get(serverInfo.MD5Version);

                if (updates.Count > 0)
                {
                    SendMD5Updates(updates);
                }
            }
            else
            {
                ConnectionLog("STM_MD5VERSION BAD: {0}", serverInfo.Print());
            }
        }
Exemple #10
0
        protected override object HandleClient(object clientObject)
        {
            IPEndPoint _clientEndPoint = null;

            try
            {
                TcpClient     _client = (TcpClient)clientObject;
                NetworkStream _stream = _client.GetStream();
                _clientEndPoint = (IPEndPoint)_client.Client.RemoteEndPoint;

                Console.WriteLine("[" + MadNetHelper.GetTimeStamp() + "] Client (" + _clientEndPoint.Address + ") connected.");
                Logger.Log("Client (" + _clientEndPoint.Address + ") connected.", Logger.MessageType.INFORM);

                using (ServerInfoPacket _serverInfoP = new ServerInfoPacket(_stream))
                {
                    _serverInfoP.serverHeader  = Encoding.Unicode.GetBytes(_serverHeader);
                    _serverInfoP.serverVersion = Encoding.Unicode.GetBytes(_serverVer);
                    _serverInfoP.SendPacket(_aes);
                }

                CLISession _session = new CLISession(_stream, _aes, _js, _dhcpReader, _db);
                _session.InitCommands();
                _session.Start();
            }
            catch (Exception e)
            {
                if (_listenThreadRunning)
                {
                    Console.WriteLine("[" + MadNetHelper.GetTimeStamp() + "] Execption: " + e.Message);
                    Logger.Log(" Execption: " + e.Message, Logger.MessageType.ERROR);
                }
            }
            finally
            {
                if (_listenThreadRunning)
                {
                    Console.WriteLine("[" + MadNetHelper.GetTimeStamp() + "] Client (" + _clientEndPoint.Address + ") disconnected.");
                    Logger.Log("Client (" + _clientEndPoint.Address + ") disconnected.", Logger.MessageType.INFORM);
                }
            }

            return(null);
        }
Exemple #11
0
        /// <summary>
        /// Handle a CheckOption reply packet. Displays the value on screen
        /// </summary>
        /// <param name="serverInfo"></param>
        protected virtual void HandleCheckOptionReply(ServerInfoPacket serverInfo)
        {
            if (serverInfo.ProcessCheckOptionResponse())
            {
                ConnectionLog("STM_CHECKOPTIONREPLY PKG={0} VAR={1} VALUE=\"{2}\"", serverInfo.OptionPackageName, serverInfo.OptionVariableName, serverInfo.OptionVariableValue);

                MasterServer.LogMessage("[{0}] {1} {2}=\"{3}\"", server, serverInfo.OptionPackageName, serverInfo.OptionVariableName, serverInfo.OptionVariableValue);

                CheckOptionReplyEventHandler checkOptionReply = this.CheckOptionReply;

                if (checkOptionReply != null)
                {
                    checkOptionReply(serverInfo.OptionPackageName, serverInfo.OptionVariableName, serverInfo.OptionVariableValue);
                }
            }
            else
            {
                ConnectionLog("STM_CHECKOPTIONREPLY BAD: {0}", serverInfo.Print());
            }
        }
Exemple #12
0
        /// <summary>
        /// Handle a gamestate packet from a server
        /// </summary>
        /// <param name="serverInfo"></param>
        protected virtual void HandleGameState(ServerInfoPacket serverInfo)
        {
            // MasterServer.Log("[{0}] STM_GameState", server);
            if (serverInfo.ProcessGameState(server, logWriter))
            {
                ConnectionLog("STM_GAMESTATE OK");
                serverList.UpdateServer(server, serverInfo);
                SendMatchID();
            }
            else
            {
                ConnectionLog("STM_GAMESTATE BAD: {0}", serverInfo.Print());
                gameStateParseFailureCount++;
            }

            if (gameStateParseFailureCount > 5)
            {
                MasterServer.Log("[{0}] WARN: Invalid STM_GameState", server);
                gameStateParseFailureCount = 0;
            }
        }
        void ServerConnection_OnPacket(ServerInfoPacket packet)
        {
            ServerInfoPacket data = (ServerInfoPacket)packet;
            ServerInfo       info = new ServerInfo()
            {
                Active          = packet.Active,
                Banned          = packet.Banned,
                Clients         = packet.Clients,
                Firewalled      = packet.Firewalled,
                Items           = packet.Items,
                ItemScripts     = packet.ItemScripts,
                Memory          = packet.Memory,
                Mobiles         = packet.Mobiles,
                MobileScripts   = packet.MobileScripts,
                DotNetVersion   = packet.DotNetVersion,
                OperatingSystem = packet.OperatingSystem,
                UpSecs          = packet.UpSecs,
            };

            InvokeOnServerInfo(info);
        }
Exemple #14
0
        /// <summary>
        /// Handle the server connection
        /// </summary>
        protected override void Handle()
        {
            // Loop until connection is closed or forcibly aborted
            while (socket.Connected && !aborted)
            {
                try
                {
                    // Read data from the socket
                    InboundPacket packet = Receive();

                    if (!packet.Empty && packet.Valid)
                    {
                        ServerInfoPacket serverInfo = (ServerInfoPacket)packet;

                        // Connection is considered "established" once the heartbeat has been established
                        switch (State)
                        {
                        // Waiting for initial greeting from the server
                        case ConnectionState.WaitingHello:
                            HandleHello(serverInfo);
                            break;

                        // Waiting to receive heartbeat from the server
                        case ConnectionState.WaitingHeartbeat:
                            if ((DateTime.Now - waitingHeartbeatTime).TotalSeconds > waitForHeartbeatSeconds)
                            {
                                ConnectionLog("TIMEOUT WAITING HEARTBEAT IN STATE {0}", State);
                                MasterServer.Log("[{0}] Timeout waiting for heartbeat response.");
                                outerConnection.Abort();
                            }
                            else
                            {
                                ConnectionLog("UNSOLICITED MESSAGE IN STATE {0}", State);
                            }
                            break;

                        // Connection is established, process inbound packets as normal server conversation
                        case ConnectionState.Established:
                            switch (serverInfo.PacketCode)
                            {
                            case ServerToMaster.ClientResponse:         HandleClientChallengeResponse(serverInfo);  break;

                            case ServerToMaster.GameState:              HandleGameState(serverInfo);                break;

                            case ServerToMaster.Stats:                  HandleStats(serverInfo);                    break;

                            case ServerToMaster.ClientDisconnectFailed: HandleClientDisconnectFailed(serverInfo);   break;

                            case ServerToMaster.MD5Version:             HandleMD5Version(serverInfo);               break;

                            case ServerToMaster.CheckOptionReply:       HandleCheckOptionReply(serverInfo);         break;

                            default:
                                packet.Rewind();
                                ConnectionLog("INVALID MESSAGE STATE={0} CODE={1}", State, packet.PopByte());
                                break;
                            }

                            break;
                        }
                    }
                    else if (socket.Connected)
                    {
                        ConnectionLog("INVALID PACKET STATE={0} DATA={1}", State, packet.PrintBytes(true));
                        Debug.WriteLine(String.Format("Invalid packet from server at {0} in state {1}", server.Address, State));
                        Debug.WriteLine(packet.Print());

                        if (State == ConnectionState.WaitingHeartbeat && (DateTime.Now - waitingHeartbeatTime).TotalSeconds > waitForHeartbeatSeconds)
                        {
                            MasterServer.Log("[{0}] Timeout waiting for heartbeat response.", server);
                            ConnectionLog("TIMEOUT WAITING HEARTBEAT IN STATE {0}", State);
                            outerConnection.Abort();
                        }
                    }
                }
                catch (ThreadAbortException)
                {
                    aborted = true;
                }
                catch (Exception ex)
                {
                    if (!aborted)
                    {
                        ConnectionLog("ERROR: {0}", ex.Message);
                    }

                    break;
                }
            }

            if (!socket.Connected)
            {
                MasterServer.Log("[{0}] Connection closed", server);
            }

            serverList.Remove(server);
            server = null;
        }