예제 #1
0
        private qsocket_t ProcessRequestServerInfo(Socket acceptsock, EndPoint clientaddr)
        {
            var tmp = Host.Network.Reader.ReadString();

            if (tmp != "QUAKE")
            {
                return(null);
            }

            Host.Network.Message.Clear();

            // save space for the header, filled in later
            Host.Network.Message.WriteLong(0);
            Host.Network.Message.WriteByte(CCRep.CCREP_SERVER_INFO);
            var newaddr = acceptsock.LocalEndPoint;               //dfunc.GetSocketAddr(acceptsock, &newaddr);

            Host.Network.Message.WriteString(newaddr.ToString()); // dfunc.AddrToString(&newaddr));
            Host.Network.Message.WriteString(Host.Network.HostName);
            Host.Network.Message.WriteString(Host.Server.sv.name);
            Host.Network.Message.WriteByte(Host.Network.ActiveConnections);
            Host.Network.Message.WriteByte(Host.Server.svs.maxclients);
            Host.Network.Message.WriteByte(NetworkDef.NET_PROTOCOL_VERSION);
            Utilities.WriteInt(Host.Network.Message.Data, 0, EndianHelper.BigLong(NetFlags.NETFLAG_CTL |
                                                                                  (Host.Network.Message.Length & NetFlags.NETFLAG_LENGTH_MASK)));
            Host.Network.LanDriver.Write(acceptsock, Host.Network.Message.Data, Host.Network.Message.Length, clientaddr);
            Host.Network.Message.Clear();
            return(null);
        }
예제 #2
0
        /// <summary>
        /// _Datagram_CheckNewConnections
        /// </summary>
        public qsocket_t InternalCheckNewConnections( )
        {
            var acceptsock = Host.Network.LanDriver.CheckNewConnections( );

            if (acceptsock == null)
            {
                return(null);
            }

            EndPoint clientaddr = new IPEndPoint(IPAddress.Any, 0);

            Host.Network.Message.FillFrom(Host.Network, acceptsock, ref clientaddr);

            if (Host.Network.Message.Length < sizeof(Int32))
            {
                return(null);
            }

            Host.Network.Reader.Reset( );

            var control          = EndianHelper.BigLong(Host.Network.Reader.ReadLong( ));
            var isControlInvalid = (control == -1 ||
                                    ((control & (~NetFlags.NETFLAG_LENGTH_MASK)) != NetFlags.NETFLAG_CTL) ||
                                    (control & NetFlags.NETFLAG_LENGTH_MASK) != Host.Network.Message.Length);

            if (isControlInvalid)
            {
                return(null);
            }

            var command = Host.Network.Reader.ReadByte( );

            switch (command)
            {
            case CCReq.CCREQ_SERVER_INFO:
                return(ProcessRequestServerInfo(acceptsock, clientaddr));

            case CCReq.CCREQ_PLAYER_INFO:
                return(ProcessRequestPlayerInfo(acceptsock, clientaddr));

            case CCReq.CCREQ_RULE_INFO:
                return(ProcessRequestRuleInfo(acceptsock, clientaddr));

            case CCReq.CCREQ_CONNECT:
                if (Host.Network.Reader.ReadString() != "QUAKE")
                {
                    return(null);
                }

                if (Host.Network.Reader.ReadByte() != NetworkDef.NET_PROTOCOL_VERSION)
                {
                    return(ProcessInvalidProtocol(acceptsock, clientaddr));
                }
#if BAN_TEST
                // check for a ban
                if (clientaddr.sa_family == AF_INET)
                {
                    unsigned long testAddr;
                    testAddr = ((struct sockaddr_in *)&clientaddr)->sin_addr.s_addr;
예제 #3
0
        private qsocket_t ProcessRequestRuleInfo(Socket acceptsock, EndPoint clientaddr)
        {
            // find the search start location
            var            prevCvarName = Host.Network.Reader.ReadString();
            ClientVariable var;

            if (!String.IsNullOrEmpty(prevCvarName))
            {
                var = Host.CVars.Get(prevCvarName);

                if (var == null)
                {
                    return(null);
                }

                var index = Host.CVars.IndexOf(var.Name);

                var = Host.CVars.GetByIndex(index + 1);
            }
            else
            {
                var = Host.CVars.GetByIndex(0);
            }

            // search for the next server cvar
            while (var != null)
            {
                if (var.IsServer)
                {
                    break;
                }

                var index = Host.CVars.IndexOf(var.Name);

                var = Host.CVars.GetByIndex(index + 1);
            }

            // send the response
            Host.Network.Message.Clear();

            // save space for the header, filled in later
            Host.Network.Message.WriteLong(0);
            Host.Network.Message.WriteByte(CCRep.CCREP_RULE_INFO);
            if (var != null)
            {
                Host.Network.Message.WriteString(var.Name);
                Host.Network.Message.WriteString(var.Get().ToString());
            }

            Utilities.WriteInt(Host.Network.Message.Data, 0, EndianHelper.BigLong(NetFlags.NETFLAG_CTL |
                                                                                  (Host.Network.Message.Length & NetFlags.NETFLAG_LENGTH_MASK)));

            Host.Network.LanDriver.Write(acceptsock, Host.Network.Message.Data, Host.Network.Message.Length, clientaddr);
            Host.Network.Message.Clear();

            return(null);
        }
예제 #4
0
 private qsocket_t ProcessInvalidProtocol(Socket acceptsock, EndPoint clientaddr)
 {
     Host.Network.Message.Clear();
     // save space for the header, filled in later
     Host.Network.Message.WriteLong(0);
     Host.Network.Message.WriteByte(CCRep.CCREP_REJECT);
     Host.Network.Message.WriteString("Incompatible version.\n");
     Utilities.WriteInt(Host.Network.Message.Data, 0, EndianHelper.BigLong(NetFlags.NETFLAG_CTL |
                                                                           (Host.Network.Message.Length & NetFlags.NETFLAG_LENGTH_MASK)));
     Host.Network.LanDriver.Write(acceptsock, Host.Network.Message.Data, Host.Network.Message.Length, clientaddr);
     Host.Network.Message.Clear();
     return(null);
 }
예제 #5
0
        private void SendHostDetails(Socket acceptsock, Socket newsock, EndPoint clientaddr)
        {
            Host.Network.Message.Clear();
            // save space for the header, filled in later
            Host.Network.Message.WriteLong(0);
            Host.Network.Message.WriteByte(CCRep.CCREP_ACCEPT);
            var newaddr2 = newsock.LocalEndPoint;// dfunc.GetSocketAddr(newsock, &newaddr);

            Host.Network.Message.WriteLong(Host.Network.LanDriver.GetSocketPort(newaddr2));
            Utilities.WriteInt(Host.Network.Message.Data, 0, EndianHelper.BigLong(NetFlags.NETFLAG_CTL |
                                                                                  (Host.Network.Message.Length & NetFlags.NETFLAG_LENGTH_MASK)));
            Host.Network.LanDriver.Write(acceptsock, Host.Network.Message.Data, Host.Network.Message.Length, clientaddr);
            Host.Network.Message.Clear();
        }
예제 #6
0
        private Boolean CheckForExistingConnection(Socket acceptsock, EndPoint clientaddr)
        {
            var exit = false;

            // see if this guy is already connected
            foreach (var s in Host.Network.ActiveSockets)
            {
                if (s.driver != Host.Network.DriverLevel)
                {
                    continue;
                }

                var ret = Host.Network.LanDriver.AddrCompare(clientaddr, s.addr);
                if (ret >= 0)
                {
                    // is this a duplicate connection reqeust?
                    if (ret == 0 && Host.Network.Time - s.connecttime < 2.0)
                    {
                        // yes, so send a duplicate reply
                        Host.Network.Message.Clear();
                        // save space for the header, filled in later
                        Host.Network.Message.WriteLong(0);
                        Host.Network.Message.WriteByte(CCRep.CCREP_ACCEPT);
                        var newaddr = s.socket.LocalEndPoint; //dfunc.GetSocketAddr(s.socket, &newaddr);
                        Host.Network.Message.WriteLong(Host.Network.LanDriver.GetSocketPort(newaddr));
                        Utilities.WriteInt(Host.Network.Message.Data, 0, EndianHelper.BigLong(NetFlags.NETFLAG_CTL |
                                                                                              (Host.Network.Message.Length & NetFlags.NETFLAG_LENGTH_MASK)));
                        Host.Network.LanDriver.Write(acceptsock, Host.Network.Message.Data, Host.Network.Message.Length, clientaddr);
                        Host.Network.Message.Clear();
                        exit = true;
                    }

                    // it's somebody coming back in from a crash/disconnect
                    // so close the old qsocket and let their retry get them back in
                    if (!exit)
                    {
                        Host.Network.Close(s);
                        exit = true;
                    }
                }

                if (exit)
                {
                    break;
                }
            }

            return(exit);
        }
예제 #7
0
        private qsocket_t ProcessRequestPlayerInfo(Socket acceptsock, EndPoint clientaddr)
        {
            var      playerNumber = Host.Network.Reader.ReadByte();
            Int32    clientNumber, activeNumber = -1;
            client_t client = null;

            for (clientNumber = 0; clientNumber < Host.Server.svs.maxclients; clientNumber++)
            {
                client = Host.Server.svs.clients[clientNumber];
                if (client.active)
                {
                    activeNumber++;

                    if (activeNumber == playerNumber)
                    {
                        break;
                    }
                }
            }

            if (clientNumber == Host.Server.svs.maxclients)
            {
                return(null);
            }

            Host.Network.Message.Clear();
            // save space for the header, filled in later
            Host.Network.Message.WriteLong(0);
            Host.Network.Message.WriteByte(CCRep.CCREP_PLAYER_INFO);
            Host.Network.Message.WriteByte(playerNumber);
            Host.Network.Message.WriteString(client.name);
            Host.Network.Message.WriteLong(client.colors);
            Host.Network.Message.WriteLong(( Int32 )client.edict.v.frags);
            Host.Network.Message.WriteLong(( Int32 )(Host.Network.Time - client.netconnection.connecttime));
            Host.Network.Message.WriteString(client.netconnection.address);
            Utilities.WriteInt(Host.Network.Message.Data, 0, EndianHelper.BigLong(NetFlags.NETFLAG_CTL |
                                                                                  (Host.Network.Message.Length & NetFlags.NETFLAG_LENGTH_MASK)));
            Host.Network.LanDriver.Write(acceptsock, Host.Network.Message.Data, Host.Network.Message.Length, clientaddr);
            Host.Network.Message.Clear();

            return(null);
        }
예제 #8
0
        private Boolean AllocateQSocket(Socket acceptsock, EndPoint clientaddr, out qsocket_t sock)
        {
            var success = true;

            // allocate a QSocket
            sock = Host.Network.NewSocket();

            if (sock == null)
            {
                // no room; try to let him know
                Host.Network.Message.Clear();
                // save space for the header, filled in later
                Host.Network.Message.WriteLong(0);
                Host.Network.Message.WriteByte(CCRep.CCREP_REJECT);
                Host.Network.Message.WriteString("Server is full.\n");
                Utilities.WriteInt(Host.Network.Message.Data, 0, EndianHelper.BigLong(NetFlags.NETFLAG_CTL |
                                                                                      (Host.Network.Message.Length & NetFlags.NETFLAG_LENGTH_MASK)));
                Host.Network.LanDriver.Write(acceptsock, Host.Network.Message.Data, Host.Network.Message.Length, clientaddr);
                Host.Network.Message.Clear();
                success = false;
            }

            return(success);
        }
예제 #9
0
        /// <summary>
        /// _Datagram_CheckNewConnections
        /// </summary>
        public qsocket_t InternalCheckNewConnections( )
        {
            var acceptsock = Host.Network.LanDriver.CheckNewConnections( );

            if (acceptsock == null)
            {
                return(null);
            }

            EndPoint clientaddr = new IPEndPoint(IPAddress.Any, 0);

            Host.Network.Message.FillFrom(Host.Network, acceptsock, ref clientaddr);

            if (Host.Network.Message.Length < sizeof(Int32))
            {
                return(null);
            }

            Host.Network.Reader.Reset( );
            var control = EndianHelper.BigLong(Host.Network.Reader.ReadLong( ));

            if (control == -1)
            {
                return(null);
            }
            if ((control & (~NetFlags.NETFLAG_LENGTH_MASK)) != NetFlags.NETFLAG_CTL)
            {
                return(null);
            }
            if ((control & NetFlags.NETFLAG_LENGTH_MASK) != Host.Network.Message.Length)
            {
                return(null);
            }

            var command = Host.Network.Reader.ReadByte( );

            if (command == CCReq.CCREQ_SERVER_INFO)
            {
                var tmp = Host.Network.Reader.ReadString( );
                if (tmp != "QUAKE")
                {
                    return(null);
                }

                Host.Network.Message.Clear( );

                // save space for the header, filled in later
                Host.Network.Message.WriteLong(0);
                Host.Network.Message.WriteByte(CCRep.CCREP_SERVER_INFO);
                var newaddr = acceptsock.LocalEndPoint;                //dfunc.GetSocketAddr(acceptsock, &newaddr);
                Host.Network.Message.WriteString(newaddr.ToString( )); // dfunc.AddrToString(&newaddr));
                Host.Network.Message.WriteString(Host.Network.HostName);
                Host.Network.Message.WriteString(Host.Server.sv.name);
                Host.Network.Message.WriteByte(Host.Network.ActiveConnections);
                Host.Network.Message.WriteByte(Host.Server.svs.maxclients);
                Host.Network.Message.WriteByte(NetworkDef.NET_PROTOCOL_VERSION);
                Utilities.WriteInt(Host.Network.Message.Data, 0, EndianHelper.BigLong(NetFlags.NETFLAG_CTL |
                                                                                      (Host.Network.Message.Length & NetFlags.NETFLAG_LENGTH_MASK)));
                Host.Network.LanDriver.Write(acceptsock, Host.Network.Message.Data, Host.Network.Message.Length, clientaddr);
                Host.Network.Message.Clear( );
                return(null);
            }

            if (command == CCReq.CCREQ_PLAYER_INFO)
            {
                var      playerNumber = Host.Network.Reader.ReadByte( );
                Int32    clientNumber, activeNumber = -1;
                client_t client = null;
                for (clientNumber = 0; clientNumber < Host.Server.svs.maxclients; clientNumber++)
                {
                    client = Host.Server.svs.clients[clientNumber];
                    if (client.active)
                    {
                        activeNumber++;
                        if (activeNumber == playerNumber)
                        {
                            break;
                        }
                    }
                }
                if (clientNumber == Host.Server.svs.maxclients)
                {
                    return(null);
                }

                Host.Network.Message.Clear( );
                // save space for the header, filled in later
                Host.Network.Message.WriteLong(0);
                Host.Network.Message.WriteByte(CCRep.CCREP_PLAYER_INFO);
                Host.Network.Message.WriteByte(playerNumber);
                Host.Network.Message.WriteString(client.name);
                Host.Network.Message.WriteLong(client.colors);
                Host.Network.Message.WriteLong(( Int32 )client.edict.v.frags);
                Host.Network.Message.WriteLong(( Int32 )(Host.Network.Time - client.netconnection.connecttime));
                Host.Network.Message.WriteString(client.netconnection.address);
                Utilities.WriteInt(Host.Network.Message.Data, 0, EndianHelper.BigLong(NetFlags.NETFLAG_CTL |
                                                                                      (Host.Network.Message.Length & NetFlags.NETFLAG_LENGTH_MASK)));
                Host.Network.LanDriver.Write(acceptsock, Host.Network.Message.Data, Host.Network.Message.Length, clientaddr);
                Host.Network.Message.Clear( );

                return(null);
            }

            if (command == CCReq.CCREQ_RULE_INFO)
            {
                // find the search start location
                var            prevCvarName = Host.Network.Reader.ReadString( );
                ClientVariable var;
                if (!String.IsNullOrEmpty(prevCvarName))
                {
                    var = Host.CVars.Get(prevCvarName);

                    if (var == null)
                    {
                        return(null);
                    }

                    var index = Host.CVars.IndexOf(var.Name);

                    var = Host.CVars.GetByIndex(index + 1);
                }
                else
                {
                    var = Host.CVars.GetByIndex(0);
                }

                // search for the next server cvar
                while (var != null)
                {
                    if (var.IsServer)
                    {
                        break;
                    }

                    var index = Host.CVars.IndexOf(var.Name);

                    var = Host.CVars.GetByIndex(index + 1);
                }

                // send the response
                Host.Network.Message.Clear( );

                // save space for the header, filled in later
                Host.Network.Message.WriteLong(0);
                Host.Network.Message.WriteByte(CCRep.CCREP_RULE_INFO);
                if (var != null)
                {
                    Host.Network.Message.WriteString(var.Name);
                    Host.Network.Message.WriteString(var.Get( ).ToString( ));
                }
                Utilities.WriteInt(Host.Network.Message.Data, 0, EndianHelper.BigLong(NetFlags.NETFLAG_CTL |
                                                                                      (Host.Network.Message.Length & NetFlags.NETFLAG_LENGTH_MASK)));
                Host.Network.LanDriver.Write(acceptsock, Host.Network.Message.Data, Host.Network.Message.Length, clientaddr);
                Host.Network.Message.Clear( );

                return(null);
            }

            if (command != CCReq.CCREQ_CONNECT)
            {
                return(null);
            }

            if (Host.Network.Reader.ReadString( ) != "QUAKE")
            {
                return(null);
            }

            if (Host.Network.Reader.ReadByte( ) != NetworkDef.NET_PROTOCOL_VERSION)
            {
                Host.Network.Message.Clear( );
                // save space for the header, filled in later
                Host.Network.Message.WriteLong(0);
                Host.Network.Message.WriteByte(CCRep.CCREP_REJECT);
                Host.Network.Message.WriteString("Incompatible version.\n");
                Utilities.WriteInt(Host.Network.Message.Data, 0, EndianHelper.BigLong(NetFlags.NETFLAG_CTL |
                                                                                      (Host.Network.Message.Length & NetFlags.NETFLAG_LENGTH_MASK)));
                Host.Network.LanDriver.Write(acceptsock, Host.Network.Message.Data, Host.Network.Message.Length, clientaddr);
                Host.Network.Message.Clear( );
                return(null);
            }

#if BAN_TEST
            // check for a ban
            if (clientaddr.sa_family == AF_INET)
            {
                unsigned long testAddr;
                testAddr = ((struct sockaddr_in *)&clientaddr)->sin_addr.s_addr;