Beispiel #1
0
    void sendPos()
    {
        bufin = SerializeNetchan(1, 2);
        Netchan net = deserializeNetchan(bufin);

        print("Sending...\nProtocol: " + net.Protocol +
              "\nSequence: " + net.Sequence + "\nAck: " + net.Ack);

        client.Send(bufin, bufin.Length);

        bufout = client.Receive(ref ep);
        net    = deserializeNetchan(bufout);
        Player p = net.Players(0).Value;

        print("Receiving...\nProtocol: " + net.Protocol +
              "\nSequence: " + net.Sequence + "\nAck: " + net.Ack +
              "\n x: " + p.Rot.Value.X +
              "\n y: " + p.Rot.Value.Y +
              "\n z: " + p.Rot.Value.Z);
        print(net.ByteBuffer.Data);

        var i = 0;

        foreach (Transform t in networkedPlayers)
        {
            i++;
            t.position    = new Vector3(p.Pos.Value.X, p.Pos.Value.Y, (float)p.Pos.Value.Z + 2 * i);
            t.eulerAngles = new Vector3(p.Rot.Value.X, p.Rot.Value.Y, p.Rot.Value.Z);
            //t.rotation = new Quaternion(p.Rot.Value.X, p.Rot.Value.Y, p.Rot.Value.Z, 0);
        }
    }
Beispiel #2
0
        public static void SVC_Info( )
        {
            String string_renamed;
            Int32  i, count;
            Int32  version;

            if (SV_MAIN.maxclients.value == 1)
            {
                return;
            }
            version = Lib.Atoi(Cmd.Argv(1));
            if (version != Defines.PROTOCOL_VERSION)
            {
                string_renamed = SV_MAIN.hostname.string_renamed + ": wrong version\\n";
            }
            else
            {
                count = 0;
                for (i = 0; i < SV_MAIN.maxclients.value; i++)
                {
                    if (SV_INIT.svs.clients[i].state >= Defines.cs_connected)
                    {
                        count++;
                    }
                }
                string_renamed = SV_MAIN.hostname.string_renamed + " " + SV_INIT.sv.name + " " + count + "/" + ( Int32 )SV_MAIN.maxclients.value + "\\n";
            }

            Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "info\\n" + string_renamed);
        }
Beispiel #3
0
    public byte[] SerializeNetchan(int seq, int ack)
    {
        var builder = new FlatBufferBuilder(1);

        var plays = new Offset <Player> [1];

        Player.StartPlayer(builder);
        Player.AddId(builder, 1);
        var pos = Vec3.CreateVec3(builder, player.position.x, player.position.y, player.position.z);

        Player.AddPos(builder, pos);
        var rot = Vec3.CreateVec3(builder, player.localEulerAngles.x, player.localEulerAngles.y, player.localEulerAngles.z);

        Player.AddRot(builder, rot);
        var p1 = Player.EndPlayer(builder);

        plays[0] = p1;

        // serialize FlatBuffer data
        var players = Netchan.CreatePlayersVector(builder, plays);

        Netchan.StartNetchan(builder);
        Netchan.AddProtocol(builder, 1234);
        Netchan.AddSequence(builder, seq);
        Netchan.AddAck(builder, ack);
        Netchan.AddPlayers(builder, players);
        var net = Netchan.EndNetchan(builder);

        builder.Finish(net.Value);
        var buf = builder.SizedByteArray();

        return(buf);
    }
Beispiel #4
0
        public static void Gotnewcl(Int32 i, Int32 challenge, String userinfo, netadr_t adr, Int32 qport)
        {
            SV_MAIN.sv_client = SV_INIT.svs.clients[i];
            var     edictnum = i + 1;
            edict_t ent      = GameBase.g_edicts[edictnum];

            SV_INIT.svs.clients[i].edict     = ent;
            SV_INIT.svs.clients[i].challenge = challenge;
            if (!(PlayerClient.ClientConnect(ent, userinfo)))
            {
                if (Info.Info_ValueForKey(userinfo, "rejmsg") != null)
                {
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\n" + Info.Info_ValueForKey(userinfo, "rejmsg") + "\\nConnection refused.\\n");
                }
                else
                {
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nConnection refused.\\n");
                }
                Com.DPrintf("Game rejected a connection.\\n");
                return;
            }

            SV_INIT.svs.clients[i].userinfo = userinfo;
            SV_UserinfoChanged(SV_INIT.svs.clients[i]);
            Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "client_connect");
            Netchan.Setup(Defines.NS_SERVER, SV_INIT.svs.clients[i].netchan, adr, qport);
            SV_INIT.svs.clients[i].state = Defines.cs_connected;
            SZ.Init(SV_INIT.svs.clients[i].datagram, SV_INIT.svs.clients[i].datagram_buf, SV_INIT.svs.clients[i].datagram_buf.Length);
            SV_INIT.svs.clients[i].datagram.allowoverflow = true;
            SV_INIT.svs.clients[i].lastmessage            = SV_INIT.svs.realtime;
            SV_INIT.svs.clients[i].lastconnect            = SV_INIT.svs.realtime;
            Com.DPrintf("new client added.\\n");
        }
Beispiel #5
0
        public static void SVC_GetChallenge( )
        {
            Int32 i;
            Int32 oldest;
            Int32 oldestTime;

            oldest     = 0;
            oldestTime = 0x7fffffff;
            for (i = 0; i < Defines.MAX_CHALLENGES; i++)
            {
                if (NET.CompareBaseAdr(Globals.net_from, SV_INIT.svs.challenges[i].adr))
                {
                    break;
                }
                if (SV_INIT.svs.challenges[i].time < oldestTime)
                {
                    oldestTime = SV_INIT.svs.challenges[i].time;
                    oldest     = i;
                }
            }

            if (i == Defines.MAX_CHALLENGES)
            {
                SV_INIT.svs.challenges[oldest].challenge = Lib.Rand() & 0x7fff;
                SV_INIT.svs.challenges[oldest].adr       = Globals.net_from;
                SV_INIT.svs.challenges[oldest].time      = ( Int32 )Globals.curtime;
                i = oldest;
            }

            Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "challenge " + SV_INIT.svs.challenges[i].challenge);
        }
Beispiel #6
0
        public static void Master_Heartbeat( )
        {
            String string_renamed;
            Int32  i;

            if (Globals.dedicated == null || 0 == Globals.dedicated.value)
            {
                return;
            }
            if (null == SV_MAIN.public_server || 0 == SV_MAIN.public_server.value)
            {
                return;
            }
            if (SV_INIT.svs.last_heartbeat > SV_INIT.svs.realtime)
            {
                SV_INIT.svs.last_heartbeat = SV_INIT.svs.realtime;
            }
            if (SV_INIT.svs.realtime - SV_INIT.svs.last_heartbeat < SV_MAIN.HEARTBEAT_SECONDS * 1000)
            {
                return;
            }
            SV_INIT.svs.last_heartbeat = SV_INIT.svs.realtime;
            string_renamed             = SV_StatusString();
            for (i = 0; i < Defines.MAX_MASTERS; i++)
            {
                if (SV_MAIN.master_adr[i].port != 0)
                {
                    Com.Printf("Sending heartbeat to " + NET.AdrToString(SV_MAIN.master_adr[i]) + "\\n");
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, SV_MAIN.master_adr[i], "heartbeat\\n" + string_renamed);
                }
            }
        }
Beispiel #7
0
        /**
         * SVC_Info, responds with short info for broadcast scans The second parameter should
         * be the current protocol version number.
         */
        public static void SVC_Info()
        {
            string @string;
            int    i, count;
            int    version;

            if (SV_MAIN.maxclients.value == 1)
            {
                return;                 // ignore in single player
            }
            version = Lib.atoi(Cmd.Argv(1));

            if (version != Defines.PROTOCOL_VERSION)
            {
                @string = SV_MAIN.hostname.@string + ": wrong version\n";
            }
            else
            {
                count = 0;

                for (i = 0; i < SV_MAIN.maxclients.value; i++)
                {
                    if (SV_INIT.svs.clients[i].state >= Defines.cs_connected)
                    {
                        count++;
                    }
                }

                @string = SV_MAIN.hostname.@string + " " + SV_INIT.sv.name + " " + count + "/" + (int)SV_MAIN.maxclients.value + "\n";
            }

            Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "info\n" + @string);
        }
Beispiel #8
0
        public static void SV_FinalMessage(String message, Boolean reconnect)
        {
            Int32    i;
            client_t cl;

            SZ.Clear(Globals.net_message);
            MSG.WriteByte(Globals.net_message, Defines.svc_print);
            MSG.WriteByte(Globals.net_message, Defines.PRINT_HIGH);
            MSG.WriteString(Globals.net_message, message);
            if (reconnect)
            {
                MSG.WriteByte(Globals.net_message, Defines.svc_reconnect);
            }
            else
            {
                MSG.WriteByte(Globals.net_message, Defines.svc_disconnect);
            }
            for (i = 0; i < SV_INIT.svs.clients.Length; i++)
            {
                cl = SV_INIT.svs.clients[i];
                if (cl.state >= Defines.cs_connected)
                {
                    Netchan.Transmit(cl.netchan, Globals.net_message.cursize, Globals.net_message.data);
                }
            }

            for (i = 0; i < SV_INIT.svs.clients.Length; i++)
            {
                cl = SV_INIT.svs.clients[i];
                if (cl.state >= Defines.cs_connected)
                {
                    Netchan.Transmit(cl.netchan, Globals.net_message.cursize, Globals.net_message.data);
                }
            }
        }
Beispiel #9
0
        /**
         * Master_Shutdown, Informs all masters that this server is going down.
         */
        public static void Master_Shutdown()
        {
            int i;

            // pgm post3.19 change, cvar pointer not validated before dereferencing
            if (null == Globals.dedicated || 0 == Globals.dedicated.value)
            {
                return;                 // only dedicated servers send heartbeats
            }
            // pgm post3.19 change, cvar pointer not validated before dereferencing
            if (null == SV_MAIN.public_server || 0 == SV_MAIN.public_server.value)
            {
                return;                 // a private dedicated game
            }
            // send to group master
            for (i = 0; i < Defines.MAX_MASTERS; i++)
            {
                if (SV_MAIN.master_adr[i].port != 0)
                {
                    if (i > 0)
                    {
                        Com.Printf("Sending heartbeat to " + NET.AdrToString(SV_MAIN.master_adr[i]) + "\n");
                    }

                    Netchan.OutOfBandPrint(Defines.NS_SERVER, SV_MAIN.master_adr[i], "shutdown");
                }
            }
        }
Beispiel #10
0
        public static Boolean SV_SendClientDatagram(client_t client)
        {
            SV_ENTS.SV_BuildClientFrame(client);
            SZ.Init(msg, msgbuf, msgbuf.Length);
            msg.allowoverflow = true;
            SV_ENTS.SV_WriteFrameToClient(client, msg);
            if (client.datagram.overflowed)
            {
                Com.Printf("WARNING: datagram overflowed for " + client.name + "\\n");
            }
            else
            {
                SZ.Write(msg, client.datagram.data, client.datagram.cursize);
            }
            SZ.Clear(client.datagram);
            if (msg.overflowed)
            {
                Com.Printf("WARNING: msg overflowed for " + client.name + "\\n");
                SZ.Clear(msg);
            }

            Netchan.Transmit(client.netchan, msg.cursize, msg.data);
            client.message_size[SV_INIT.sv.framenum % Defines.RATE_MESSAGES] = msg.cursize;
            return(true);
        }
Beispiel #11
0
        public static void SV_ReadPackets( )
        {
            Int32    i;
            client_t cl;
            var      qport = 0;

            while (NET.GetPacket(Defines.NS_SERVER, Globals.net_from, Globals.net_message))
            {
                if ((Globals.net_message.data[0] == -1) && (Globals.net_message.data[1] == -1) && (Globals.net_message.data[2] == -1) && (Globals.net_message.data[3] == -1))
                {
                    SV_ConnectionlessPacket();
                    continue;
                }

                MSG.BeginReading(Globals.net_message);
                MSG.ReadLong(Globals.net_message);
                MSG.ReadLong(Globals.net_message);
                qport = MSG.ReadShort(Globals.net_message) & 0xffff;
                for (i = 0; i < SV_MAIN.maxclients.value; i++)
                {
                    cl = SV_INIT.svs.clients[i];
                    if (cl.state == Defines.cs_free)
                    {
                        continue;
                    }
                    if (!NET.CompareBaseAdr(Globals.net_from, cl.netchan.remote_address))
                    {
                        continue;
                    }
                    if (cl.netchan.qport != qport)
                    {
                        continue;
                    }
                    if (cl.netchan.remote_address.port != Globals.net_from.port)
                    {
                        Com.Printf("SV_ReadPackets: fixing up a translated port\\n");
                        cl.netchan.remote_address.port = Globals.net_from.port;
                    }

                    if (Netchan.Process(cl.netchan, Globals.net_message))
                    {
                        if (cl.state != Defines.cs_zombie)
                        {
                            cl.lastmessage = SV_INIT.svs.realtime;
                            SV_USER.SV_ExecuteClientMessage(cl);
                        }
                    }

                    break;
                }

                if (i != SV_MAIN.maxclients.value)
                {
                    continue;
                }
            }
        }
Beispiel #12
0
        /**
         * Initializes player structures after successfull connection.
         */
        public static void gotnewcl(int i, int challenge, string userinfo, netadr_t adr, int qport)
        {
            // build a new connection
            // accept the new client
            // this is the only place a client_t is ever initialized

            SV_MAIN.sv_client = SV_INIT.svs.clients[i];

            var edictnum = i + 1;

            var ent = GameBase.g_edicts[edictnum];

            SV_INIT.svs.clients[i].edict = ent;

            // save challenge for checksumming
            SV_INIT.svs.clients[i].challenge = challenge;

            // get the game a chance to reject this connection or modify the
            // userinfo
            if (!PlayerClient.ClientConnect(ent, userinfo))
            {
                if (Info.Info_ValueForKey(userinfo, "rejmsg") != null)
                {
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\n" + Info.Info_ValueForKey(userinfo, "rejmsg") + "\nConnection refused.\n");
                }
                else
                {
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nConnection refused.\n");
                }

                Com.DPrintf("Game rejected a connection.\n");

                return;
            }

            // parse some info from the info strings
            SV_INIT.svs.clients[i].userinfo = userinfo;
            SV_MAIN.SV_UserinfoChanged(SV_INIT.svs.clients[i]);

            // send the connect packet to the client
            Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "client_connect");

            Netchan.Setup(Defines.NS_SERVER, SV_INIT.svs.clients[i].netchan, adr, qport);

            SV_INIT.svs.clients[i].state = Defines.cs_connected;

            SZ.Init(SV_INIT.svs.clients[i].datagram, SV_INIT.svs.clients[i].datagram_buf, SV_INIT.svs.clients[i].datagram_buf.Length);

            SV_INIT.svs.clients[i].datagram.allowoverflow = true;
            SV_INIT.svs.clients[i].lastmessage            = SV_INIT.svs.realtime;  // don't timeout
            SV_INIT.svs.clients[i].lastconnect            = SV_INIT.svs.realtime;
            Com.DPrintf("new client added.\n");
        }
Beispiel #13
0
        /*
         * ===============================================================================
         *
         * OPERATOR CONSOLE ONLY COMMANDS
         *
         * These commands can only be entered from stdin or by a remote operator datagram
         * ===============================================================================
         */

        /*
         * ====================
         * SV_SetMaster_f
         *
         * Specify a list of master servers
         * ====================
         */
        public static void SV_SetMaster_f()
        {
            int i, slot;

            // only dedicated servers send heartbeats
            if (Globals.dedicated.value == 0)
            {
                Com.Printf("Only dedicated servers use masters.\n");

                return;
            }

            // make sure the server is listed public
            Cvar.Set("public", "1");

            for (i = 1; i < Defines.MAX_MASTERS; i++)
            {
                SV_MAIN.master_adr[i] = new();
            }

            slot = 1;             // slot 0 will always contain the id master

            for (i = 1; i < Cmd.Argc(); i++)
            {
                if (slot == Defines.MAX_MASTERS)
                {
                    break;
                }

                if (!NET.StringToAdr(Cmd.Argv(i), SV_MAIN.master_adr[i]))
                {
                    Com.Printf("Bad address: " + Cmd.Argv(i) + "\n");

                    continue;
                }

                if (SV_MAIN.master_adr[slot].port == 0)
                {
                    SV_MAIN.master_adr[slot].port = Defines.PORT_MASTER;
                }

                Com.Printf("Master server at " + NET.AdrToString(SV_MAIN.master_adr[slot]) + "\n");
                Com.Printf("Sending a ping.\n");

                Netchan.OutOfBandPrint(Defines.NS_SERVER, SV_MAIN.master_adr[slot], "ping");

                slot++;
            }

            SV_INIT.svs.last_heartbeat = -9999999;
        }
Beispiel #14
0
 public static void SV_FlushRedirect(Int32 sv_redirected, Byte[] outputbuf)
 {
     if (sv_redirected == Defines.RD_PACKET)
     {
         var s = ("print\\n" + Lib.CtoJava(outputbuf));
         Netchan.Netchan_OutOfBand(Defines.NS_SERVER, Globals.net_from, s.Length, Lib.StringToBytes(s));
     }
     else if (sv_redirected == Defines.RD_CLIENT)
     {
         MSG.WriteByte(SV_MAIN.sv_client.netchan.message, Defines.svc_print);
         MSG.WriteByte(SV_MAIN.sv_client.netchan.message, Defines.PRINT_HIGH);
         MSG.WriteString(SV_MAIN.sv_client.netchan.message, outputbuf);
     }
 }
Beispiel #15
0
        /**
         * Used by SV_Shutdown to send a final message to all connected clients
         * before the server goes down. The messages are sent immediately, not just
         * stuck on the outgoing message list, because the server is going to
         * totally exit after returning from this function.
         */
        public static void SV_FinalMessage(string message, bool reconnect)
        {
            int      i;
            client_t cl;

            SZ.Clear(Globals.net_message);
            MSG.WriteByte(Globals.net_message, Defines.svc_print);
            MSG.WriteByte(Globals.net_message, Defines.PRINT_HIGH);
            MSG.WriteString(Globals.net_message, message);

            if (reconnect)
            {
                MSG.WriteByte(Globals.net_message, Defines.svc_reconnect);
            }
            else
            {
                MSG.WriteByte(Globals.net_message, Defines.svc_disconnect);
            }

            // send it twice
            // stagger the packets to crutch operating system limited buffers

            for (i = 0; i < SV_INIT.svs.clients.Length; i++)
            {
                cl = SV_INIT.svs.clients[i];

                if (cl.state >= Defines.cs_connected)
                {
                    Netchan.Transmit(cl.netchan, Globals.net_message.cursize, Globals.net_message.data);
                }
            }

            for (i = 0; i < SV_INIT.svs.clients.Length; i++)
            {
                cl = SV_INIT.svs.clients[i];

                if (cl.state >= Defines.cs_connected)
                {
                    Netchan.Transmit(cl.netchan, Globals.net_message.cursize, Globals.net_message.data);
                }
            }
        }
Beispiel #16
0
    public Netchan deserializeNetchan(byte[] buf)
    {
        var bb = new ByteBuffer(buf);

        var netchan = Netchan.GetRootAsNetchan(bb);

        //print(netchan.PlayersLength);

        /*var protocol = netchan.Protocol;
         * var sequence = netchan.Sequence;
         * var ack = netchan.Ack;
         * var player = (Player) netchan.Players;
         * var vec3 = (Vec3)player.Pos;
         * var x = vec3.X;
         * var y = vec3.Y;
         * var z = vec3.Z;
         * var n = new netchan(protocol, sequence, ack, x, y, z);
         */
        return(netchan);
    }
Beispiel #17
0
        public static void Master_Heartbeat()
        {
            string @string;
            int    i;

            // pgm post3.19 change, cvar pointer not validated before dereferencing
            if (Globals.dedicated == null || 0 == Globals.dedicated.value)
            {
                return;                 // only dedicated servers send heartbeats
            }
            // pgm post3.19 change, cvar pointer not validated before dereferencing
            if (null == SV_MAIN.public_server || 0 == SV_MAIN.public_server.value)
            {
                return;                 // a private dedicated game
            }
            // check for time wraparound
            if (SV_INIT.svs.last_heartbeat > SV_INIT.svs.realtime)
            {
                SV_INIT.svs.last_heartbeat = SV_INIT.svs.realtime;
            }

            if (SV_INIT.svs.realtime - SV_INIT.svs.last_heartbeat < SV_MAIN.HEARTBEAT_SECONDS * 1000)
            {
                return;                 // not time to send yet
            }
            SV_INIT.svs.last_heartbeat = SV_INIT.svs.realtime;

            // send the same string that we would give for a status OOB command
            @string = SV_MAIN.SV_StatusString();

            // send to group master
            for (i = 0; i < Defines.MAX_MASTERS; i++)
            {
                if (SV_MAIN.master_adr[i].port != 0)
                {
                    Com.Printf("Sending heartbeat to " + NET.AdrToString(SV_MAIN.master_adr[i]) + "\n");
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, SV_MAIN.master_adr[i], "heartbeat\n" + @string);
                }
            }
        }
Beispiel #18
0
        public static void Master_Shutdown( )
        {
            Int32 i;

            if (null == Globals.dedicated || 0 == Globals.dedicated.value)
            {
                return;
            }
            if (null == SV_MAIN.public_server || 0 == SV_MAIN.public_server.value)
            {
                return;
            }
            for (i = 0; i < Defines.MAX_MASTERS; i++)
            {
                if (SV_MAIN.master_adr[i].port != 0)
                {
                    if (i > 0)
                    {
                        Com.Printf("Sending heartbeat to " + NET.AdrToString(SV_MAIN.master_adr[i]) + "\\n");
                    }
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, SV_MAIN.master_adr[i], "shutdown");
                }
            }
        }
Beispiel #19
0
        /**
         * Returns a challenge number that can be used in a subsequent
         * client_connect command. We do this to prevent denial of service attacks
         * that flood the server with invalid connection IPs. With a challenge, they
         * must give a valid IP address.
         */
        public static void SVC_GetChallenge()
        {
            int i;
            int oldest;
            int oldestTime;

            oldest     = 0;
            oldestTime = 0x7fffffff;

            // see if we already have a challenge for this ip
            for (i = 0; i < Defines.MAX_CHALLENGES; i++)
            {
                if (NET.CompareBaseAdr(Globals.net_from, SV_INIT.svs.challenges[i].adr))
                {
                    break;
                }

                if (SV_INIT.svs.challenges[i].time < oldestTime)
                {
                    oldestTime = SV_INIT.svs.challenges[i].time;
                    oldest     = i;
                }
            }

            if (i == Defines.MAX_CHALLENGES)
            {
                // overwrite the oldest
                SV_INIT.svs.challenges[oldest].challenge = Lib.rand() & 0x7fff;
                SV_INIT.svs.challenges[oldest].adr       = Globals.net_from;
                SV_INIT.svs.challenges[oldest].time      = (int)Globals.curtime;
                i = oldest;
            }

            // send it back
            Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "challenge " + SV_INIT.svs.challenges[i].challenge);
        }
Beispiel #20
0
 public static void SVC_Status( )
 {
     Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "print\\n" + SV_StatusString());
 }
Beispiel #21
0
        /**
         * A connection request that did not come from the master.
         */
        public static void SVC_DirectConnect()
        {
            string   userinfo;
            netadr_t adr;
            int      i;
            client_t cl;

            int version;
            int qport;

            adr = Globals.net_from;

            Com.DPrintf("SVC_DirectConnect ()\n");

            version = Lib.atoi(Cmd.Argv(1));

            if (version != Defines.PROTOCOL_VERSION)
            {
                Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nServer is version " + Globals.VERSION + "\n");
                Com.DPrintf("    rejected connect from version " + version + "\n");

                return;
            }

            qport = Lib.atoi(Cmd.Argv(2));
            var challenge = Lib.atoi(Cmd.Argv(3));

            userinfo = Cmd.Argv(4);

            // force the IP key/value pair so the game can filter based on ip
            userinfo = Info.Info_SetValueForKey(userinfo, "ip", NET.AdrToString(Globals.net_from));

            // attractloop servers are ONLY for local clients
            if (SV_INIT.sv.attractloop)
            {
                if (!NET.IsLocalAddress(adr))
                {
                    Com.Printf("Remote connect in attract loop.  Ignored.\n");
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nConnection refused.\n");

                    return;
                }
            }

            // see if the challenge is valid
            if (!NET.IsLocalAddress(adr))
            {
                for (i = 0; i < Defines.MAX_CHALLENGES; i++)
                {
                    if (NET.CompareBaseAdr(Globals.net_from, SV_INIT.svs.challenges[i].adr))
                    {
                        if (challenge == SV_INIT.svs.challenges[i].challenge)
                        {
                            break;                             // good
                        }
                        Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nBad challenge.\n");

                        return;
                    }
                }

                if (i == Defines.MAX_CHALLENGES)
                {
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nNo challenge for address.\n");

                    return;
                }
            }

            // if there is already a slot for this ip, reuse it
            for (i = 0; i < SV_MAIN.maxclients.value; i++)
            {
                cl = SV_INIT.svs.clients[i];

                if (cl.state == Defines.cs_free)
                {
                    continue;
                }

                if (NET.CompareBaseAdr(adr, cl.netchan.remote_address) && (cl.netchan.qport == qport || adr.port == cl.netchan.remote_address.port))
                {
                    if (!NET.IsLocalAddress(adr) && SV_INIT.svs.realtime - cl.lastconnect < (int)SV_MAIN.sv_reconnect_limit.value * 1000)
                    {
                        Com.DPrintf(NET.AdrToString(adr) + ":reconnect rejected : too soon\n");

                        return;
                    }

                    Com.Printf(NET.AdrToString(adr) + ":reconnect\n");

                    SV_MAIN.gotnewcl(i, challenge, userinfo, adr, qport);

                    return;
                }
            }

            // find a client slot
            //newcl = null;
            var index = -1;

            for (i = 0; i < SV_MAIN.maxclients.value; i++)
            {
                cl = SV_INIT.svs.clients[i];

                if (cl.state == Defines.cs_free)
                {
                    index = i;

                    break;
                }
            }

            if (index == -1)
            {
                Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nServer is full.\n");
                Com.DPrintf("Rejected a connection.\n");

                return;
            }

            SV_MAIN.gotnewcl(index, challenge, userinfo, adr, qport);
        }
Beispiel #22
0
        /**
         * Reads packets from the network or loopback.
         */
        public static void SV_ReadPackets()
        {
            int      i;
            client_t cl;
            var      qport = 0;

            while (NET.GetPacket(Defines.NS_SERVER, Globals.net_from, Globals.net_message))
            {
                // check for connectionless packet (0xffffffff) first
                if (Globals.net_message.data[0] == 255 &&
                    Globals.net_message.data[1] == 255 &&
                    Globals.net_message.data[2] == 255 &&
                    Globals.net_message.data[3] == 255)
                {
                    SV_MAIN.SV_ConnectionlessPacket();

                    continue;
                }

                // read the qport out of the message so we can fix up
                // stupid address translating routers
                MSG.BeginReading(Globals.net_message);
                MSG.ReadLong(Globals.net_message);                 // sequence number
                MSG.ReadLong(Globals.net_message);                 // sequence number
                qport = MSG.ReadShort(Globals.net_message) & 0xffff;

                // check for packets from connected clients
                for (i = 0; i < SV_MAIN.maxclients.value; i++)
                {
                    cl = SV_INIT.svs.clients[i];

                    if (cl.state == Defines.cs_free)
                    {
                        continue;
                    }

                    if (!NET.CompareBaseAdr(Globals.net_from, cl.netchan.remote_address))
                    {
                        continue;
                    }

                    if (cl.netchan.qport != qport)
                    {
                        continue;
                    }

                    if (cl.netchan.remote_address.port != Globals.net_from.port)
                    {
                        Com.Printf("SV_ReadPackets: fixing up a translated port\n");
                        cl.netchan.remote_address.port = Globals.net_from.port;
                    }

                    if (Netchan.Process(cl.netchan, Globals.net_message))
                    {
                        // this is a valid, sequenced packet, so process it
                        if (cl.state != Defines.cs_zombie)
                        {
                            cl.lastmessage = SV_INIT.svs.realtime;                             // don't timeout
                            SV_USER.SV_ExecuteClientMessage(cl);
                        }
                    }

                    break;
                }

                if (i != SV_MAIN.maxclients.value)
                {
                    continue;
                }
            }
        }
Beispiel #23
0
        public static void SVC_DirectConnect( )
        {
            String   userinfo;
            netadr_t adr;
            Int32    i;
            client_t cl;
            Int32    version;
            Int32    qport;

            adr = Globals.net_from;
            Com.DPrintf("SVC_DirectConnect ()\\n");
            version = Lib.Atoi(Cmd.Argv(1));
            if (version != Defines.PROTOCOL_VERSION)
            {
                Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nServer is version " + Globals.VERSION + "\\n");
                Com.DPrintf("    rejected connect from version " + version + "\\n");
                return;
            }

            qport = Lib.Atoi(Cmd.Argv(2));
            var challenge = Lib.Atoi(Cmd.Argv(3));

            userinfo = Cmd.Argv(4);
            userinfo = Info.Info_SetValueForKey(userinfo, "ip", NET.AdrToString(Globals.net_from));
            if (SV_INIT.sv.attractloop)
            {
                if (!NET.IsLocalAddress(adr))
                {
                    Com.Printf("Remote connect in attract loop.  Ignored.\\n");
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nConnection refused.\\n");
                    return;
                }
            }

            if (!NET.IsLocalAddress(adr))
            {
                for (i = 0; i < Defines.MAX_CHALLENGES; i++)
                {
                    if (NET.CompareBaseAdr(Globals.net_from, SV_INIT.svs.challenges[i].adr))
                    {
                        if (challenge == SV_INIT.svs.challenges[i].challenge)
                        {
                            break;
                        }
                        Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nBad challenge.\\n");
                        return;
                    }
                }

                if (i == Defines.MAX_CHALLENGES)
                {
                    Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nNo challenge for address.\\n");
                    return;
                }
            }

            for (i = 0; i < SV_MAIN.maxclients.value; i++)
            {
                cl = SV_INIT.svs.clients[i];
                if (cl.state == Defines.cs_free)
                {
                    continue;
                }
                if (NET.CompareBaseAdr(adr, cl.netchan.remote_address) && (cl.netchan.qport == qport || adr.port == cl.netchan.remote_address.port))
                {
                    if (!NET.IsLocalAddress(adr) && (SV_INIT.svs.realtime - cl.lastconnect) < (( Int32 )SV_MAIN.sv_reconnect_limit.value * 1000))
                    {
                        Com.DPrintf(NET.AdrToString(adr) + ":reconnect rejected : too soon\\n");
                        return;
                    }

                    Com.Printf(NET.AdrToString(adr) + ":reconnect\\n");
                    Gotnewcl(i, challenge, userinfo, adr, qport);
                    return;
                }
            }

            var index = -1;

            for (i = 0; i < SV_MAIN.maxclients.value; i++)
            {
                cl = SV_INIT.svs.clients[i];
                if (cl.state == Defines.cs_free)
                {
                    index = i;
                    break;
                }
            }

            if (index == -1)
            {
                Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nServer is full.\\n");
                Com.DPrintf("Rejected a connection.\\n");
                return;
            }

            Gotnewcl(index, challenge, userinfo, adr, qport);
        }
Beispiel #24
0
 public static void SVC_Ping( )
 {
     Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "ack");
 }
Beispiel #25
0
        public static void SV_SendClientMessages( )
        {
            Int32    i;
            client_t c;
            Int32    msglen;
            Int32    r;

            msglen = 0;
            if (SV_INIT.sv.state == Defines.ss_demo && SV_INIT.sv.demofile != null)
            {
                if (SV_MAIN.sv_paused.value != 0)
                {
                    msglen = 0;
                }
                else
                {
                    try
                    {
                        msglen = EndianHandler.SwapInt(SV_INIT.sv.demofile.ReadInt32());
                    }
                    catch (Exception e)
                    {
                        SV_DemoCompleted();
                        return;
                    }

                    if (msglen == -1)
                    {
                        SV_DemoCompleted();
                        return;
                    }

                    if (msglen > Defines.MAX_MSGLEN)
                    {
                        Com.Error(Defines.ERR_DROP, "SV_SendClientMessages: msglen > MAX_MSGLEN");
                    }
                    r = 0;
                    try
                    {
                        r = SV_INIT.sv.demofile.Read(msgbuf, 0, msglen);
                    }
                    catch (Exception e1)
                    {
                        Com.Printf("IOError: reading demo file, " + e1);
                    }

                    if (r != msglen)
                    {
                        SV_DemoCompleted();
                        return;
                    }
                }
            }

            for (i = 0; i < SV_MAIN.maxclients.value; i++)
            {
                c = SV_INIT.svs.clients[i];
                if (c.state == 0)
                {
                    continue;
                }
                if (c.netchan.message.overflowed)
                {
                    SZ.Clear(c.netchan.message);
                    SZ.Clear(c.datagram);
                    SV_BroadcastPrintf(Defines.PRINT_HIGH, c.name + " overflowed\\n");
                    SV_MAIN.SV_DropClient(c);
                }

                if (SV_INIT.sv.state == Defines.ss_cinematic || SV_INIT.sv.state == Defines.ss_demo || SV_INIT.sv.state == Defines.ss_pic)
                {
                    Netchan.Transmit(c.netchan, msglen, msgbuf);
                }
                else if (c.state == Defines.cs_spawned)
                {
                    if (SV_RateDrop(c))
                    {
                        continue;
                    }
                    SV_SendClientDatagram(c);
                }
                else
                {
                    if (c.netchan.message.cursize != 0 || Globals.curtime - c.netchan.last_sent > 1000)
                    {
                        Netchan.Transmit(c.netchan, 0, NULLBYTE);
                    }
                }
            }
        }
Beispiel #26
0
        public static void SendCmd()
        {
            int       i;
            usercmd_t cmd, oldcmd;
            int       checksumIndex;

            i   = Globals.cls.netchan.outgoing_sequence & (Defines.CMD_BACKUP - 1);
            cmd = Globals.cl.cmds[i];
            Globals.cl.cmd_time[i] = (int)Globals.cls.realtime;
            CreateCmd(cmd);
            Globals.cl.cmd.Set(cmd);
            if (Globals.cls.state == Defines.ca_disconnected || Globals.cls.state == Defines.ca_connecting)
            {
                return;
            }
            if (Globals.cls.state == Defines.ca_connected)
            {
                if (Globals.cls.netchan.message.cursize != 0 || Globals.curtime - Globals.cls.netchan.last_sent > 1000)
                {
                    Netchan.Transmit(Globals.cls.netchan, 0, new byte[0]);
                }
                return;
            }

            if (Globals.userinfo_modified)
            {
                CL.FixUpGender();
                Globals.userinfo_modified = false;
                MSG.WriteByte(Globals.cls.netchan.message, Defines.clc_userinfo);
                MSG.WriteString(Globals.cls.netchan.message, Cvar.Userinfo());
            }

            SZ.Init(buf, data, data.Length);
            if (cmd.buttons != 0 && Globals.cl.cinematictime > 0 && !Globals.cl.attractloop && Globals.cls.realtime - Globals.cl.cinematictime > 1000)
            {
                SCR.FinishCinematic();
            }

            MSG.WriteByte(buf, Defines.clc_move);
            checksumIndex = buf.cursize;
            MSG.WriteByte(buf, 0);
            if (cl_nodelta.value != 0F || !Globals.cl.frame.valid || Globals.cls.demowaiting)
            {
                MSG.WriteLong(buf, -1);
            }
            else
            {
                MSG.WriteLong(buf, Globals.cl.frame.serverframe);
            }
            i   = (Globals.cls.netchan.outgoing_sequence - 2) & (Defines.CMD_BACKUP - 1);
            cmd = Globals.cl.cmds[i];
            nullcmd.Clear();
            MSG.WriteDeltaUsercmd(buf, nullcmd, cmd);
            oldcmd = cmd;
            i      = (Globals.cls.netchan.outgoing_sequence - 1) & (Defines.CMD_BACKUP - 1);
            cmd    = Globals.cl.cmds[i];
            MSG.WriteDeltaUsercmd(buf, oldcmd, cmd);
            oldcmd = cmd;
            i      = (Globals.cls.netchan.outgoing_sequence) & (Defines.CMD_BACKUP - 1);
            cmd    = Globals.cl.cmds[i];
            MSG.WriteDeltaUsercmd(buf, oldcmd, cmd);
            buf.data[checksumIndex] = Com.BlockSequenceCRCByte(buf.data, checksumIndex + 1, buf.cursize - checksumIndex - 1, Globals.cls.netchan.outgoing_sequence);
            Netchan.Transmit(Globals.cls.netchan, buf.cursize, buf.data);
        }