Beispiel #1
0
        public static void SV_UserinfoChanged(client_t cl)
        {
            String val;
            Int32  i;

            PlayerClient.ClientUserinfoChanged(cl.edict, cl.userinfo);
            cl.name = Info.Info_ValueForKey(cl.userinfo, "name");
            val     = Info.Info_ValueForKey(cl.userinfo, "rate");
            if (val.Length > 0)
            {
                i       = Lib.Atoi(val);
                cl.rate = i;
                if (cl.rate < 100)
                {
                    cl.rate = 100;
                }
                if (cl.rate > 15000)
                {
                    cl.rate = 15000;
                }
            }
            else
            {
                cl.rate = 5000;
            }
            val = Info.Info_ValueForKey(cl.userinfo, "msg");
            if (val.Length > 0)
            {
                cl.messagelevel = Lib.Atoi(val);
            }
        }
Beispiel #2
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 #3
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 #4
0
        public static void SV_WriteFrameToClient(client_t client, sizebuf_t msg)
        {
            client_frame_t frame, oldframe;
            Int32          lastframe;

            frame = client.frames[SV_INIT.sv.framenum & Defines.UPDATE_MASK];
            if (client.lastframe <= 0)
            {
                oldframe  = null;
                lastframe = -1;
            }
            else if (SV_INIT.sv.framenum - client.lastframe >= (Defines.UPDATE_BACKUP - 3))
            {
                oldframe  = null;
                lastframe = -1;
            }
            else
            {
                oldframe  = client.frames[client.lastframe & Defines.UPDATE_MASK];
                lastframe = client.lastframe;
            }

            MSG.WriteByte(msg, Defines.svc_frame);
            MSG.WriteLong(msg, SV_INIT.sv.framenum);
            MSG.WriteLong(msg, lastframe);
            MSG.WriteByte(msg, client.surpressCount);
            client.surpressCount = 0;
            MSG.WriteByte(msg, frame.areabytes);
            SZ.Write(msg, frame.areabits, frame.areabytes);
            SV_WritePlayerstateToClient(oldframe, frame, msg);
            SV_EmitPacketEntities(oldframe, frame, msg);
        }
Beispiel #5
0
 public static void SV_ClientPrintf(client_t cl, Int32 level, String s)
 {
     if (level < cl.messagelevel)
     {
         return;
     }
     MSG.WriteByte(cl.netchan.message, Defines.svc_print);
     MSG.WriteByte(cl.netchan.message, level);
     MSG.WriteString(cl.netchan.message, s);
 }
Beispiel #6
0
        public static void SV_ClientThink(client_t cl, usercmd_t cmd)
        {
            cl.commandMsec -= cmd.msec & 0xFF;
            if (cl.commandMsec < 0 && SV_MAIN.sv_enforcetime.value != 0)
            {
                Com.DPrintf("commandMsec underflow from " + cl.name + "\\n");
                return;
            }

            PlayerClient.ClientThink(cl.edict, cmd);
        }
Beispiel #7
0
        public static void SV_DropClient(client_t drop)
        {
            MSG.WriteByte(drop.netchan.message, Defines.svc_disconnect);
            if (drop.state == Defines.cs_spawned)
            {
                PlayerClient.ClientDisconnect(drop.edict);
            }

            if (drop.download != null)
            {
                FS.FreeFile(drop.download);
                drop.download = null;
            }

            drop.state = Defines.cs_zombie;
            drop.name  = "";
        }
Beispiel #8
0
        public static Boolean SV_RateDrop(client_t c)
        {
            Int32 total;
            Int32 i;

            if (c.netchan.remote_address.type == Defines.NA_LOOPBACK)
            {
                return(false);
            }
            total = 0;
            for (i = 0; i < Defines.RATE_MESSAGES; i++)
            {
                total += c.message_size[i];
            }

            if (total > c.rate)
            {
                c.surpressCount++;
                c.message_size[SV_INIT.sv.framenum % Defines.RATE_MESSAGES] = 0;
                return(true);
            }

            return(false);
        }
Beispiel #9
0
        public static void SV_BuildClientFrame(client_t client)
        {
            Int32 e, i;

            Single[]       org = new Single[] { 0, 0, 0 };
            edict_t        ent;
            edict_t        clent;
            client_frame_t frame;
            entity_state_t state;
            Int32          l;
            Int32          clientarea, clientcluster;
            Int32          leafnum;
            Int32          c_fullsend;

            Byte[] clientphs;
            Byte[] bitvector;
            clent = client.edict;
            if (clent.client == null)
            {
                return;
            }
            frame          = client.frames[SV_INIT.sv.framenum & Defines.UPDATE_MASK];
            frame.senttime = SV_INIT.svs.realtime;
            for (i = 0; i < 3; i++)
            {
                org[i] = clent.client.ps.pmove.origin[i] * 0.125F + clent.client.ps.viewoffset[i];
            }
            leafnum         = CM.CM_PointLeafnum(org);
            clientarea      = CM.CM_LeafArea(leafnum);
            clientcluster   = CM.CM_LeafCluster(leafnum);
            frame.areabytes = CM.CM_WriteAreaBits(frame.areabits, clientarea);
            frame.ps.Set(clent.client.ps);
            SV_FatPVS(org);
            clientphs          = CM.CM_ClusterPHS(clientcluster);
            frame.num_entities = 0;
            frame.first_entity = SV_INIT.svs.next_client_entities;
            c_fullsend         = 0;
            for (e = 1; e < GameBase.num_edicts; e++)
            {
                ent = GameBase.g_edicts[e];
                if ((ent.svflags & Defines.SVF_NOCLIENT) != 0)
                {
                    continue;
                }
                if (0 == ent.s.modelindex && 0 == ent.s.effects && 0 == ent.s.sound && 0 == ent.s.event_renamed)
                {
                    continue;
                }
                if (ent != clent)
                {
                    if (!CM.CM_AreasConnected(clientarea, ent.areanum))
                    {
                        if (0 == ent.areanum2 || !CM.CM_AreasConnected(clientarea, ent.areanum2))
                        {
                            continue;
                        }
                    }

                    if ((ent.s.renderfx & Defines.RF_BEAM) != 0)
                    {
                        l = ent.clusternums[0];
                        if (0 == (clientphs[l >> 3] & (1 << (l & 7))))
                        {
                            continue;
                        }
                    }
                    else
                    {
                        if (ent.s.sound == 0)
                        {
                            bitvector = SV_ENTS.fatpvs;
                        }
                        else
                        {
                            bitvector = SV_ENTS.fatpvs;
                        }
                        if (ent.num_clusters == -1)
                        {
                            if (!CM.CM_HeadnodeVisible(ent.headnode, bitvector))
                            {
                                continue;
                            }
                            c_fullsend++;
                        }
                        else
                        {
                            for (i = 0; i < ent.num_clusters; i++)
                            {
                                l = ent.clusternums[i];
                                if ((bitvector[l >> 3] & (1 << (l & 7))) != 0)
                                {
                                    break;
                                }
                            }

                            if (i == ent.num_clusters)
                            {
                                continue;
                            }
                        }

                        if (ent.s.modelindex == 0)
                        {
                            Single[] delta = new Single[] { 0, 0, 0 };
                            Single   len;
                            Math3D.VectorSubtract(org, ent.s.origin, delta);
                            len = Math3D.VectorLength(delta);
                            if (len > 400)
                            {
                                continue;
                            }
                        }
                    }
                }

                var ix = SV_INIT.svs.next_client_entities % SV_INIT.svs.num_client_entities;
                state = SV_INIT.svs.client_entities[ix];
                if (ent.s.number != e)
                {
                    Com.DPrintf("FIXING ENT.S.NUMBER!!!\\n");
                    ent.s.number = e;
                }

                SV_INIT.svs.client_entities[ix].Set(ent.s);
                if (ent.owner == client.edict)
                {
                    state.solid = 0;
                }
                SV_INIT.svs.next_client_entities++;
                frame.num_entities++;
            }
        }
Beispiel #10
0
        public static void SV_ExecuteClientMessage(client_t cl)
        {
            Int32     c;
            String    s;
            usercmd_t nullcmd = new usercmd_t();
            usercmd_t oldest = new usercmd_t(), oldcmd = new usercmd_t(), newcmd = new usercmd_t();
            Int32     net_drop;
            Int32     stringCmdCount;
            Int32     checksum, calculatedChecksum;
            Int32     checksumIndex;
            Boolean   move_issued;
            Int32     lastframe;

            SV_MAIN.sv_client = cl;
            SV_USER.sv_player = SV_MAIN.sv_client.edict;
            move_issued       = false;
            stringCmdCount    = 0;
            while (true)
            {
                if (Globals.net_message.readcount > Globals.net_message.cursize)
                {
                    Com.Printf("SV_ReadClientMessage: bad read:\\n");
                    Com.Printf(Lib.HexDump(Globals.net_message.data, 32, false));
                    SV_MAIN.SV_DropClient(cl);
                    return;
                }

                c = MSG.ReadByte(Globals.net_message);
                if (c == -1)
                {
                    break;
                }
                switch (c)

                {
                default:
                    Com.Printf("SV_ReadClientMessage: unknown command char\\n");
                    SV_MAIN.SV_DropClient(cl);
                    return;

                case Defines.clc_nop:
                    break;

                case Defines.clc_userinfo:
                    cl.userinfo = MSG.ReadString(Globals.net_message);
                    SV_MAIN.SV_UserinfoChanged(cl);
                    break;

                case Defines.clc_move:
                    if (move_issued)
                    {
                        return;
                    }
                    move_issued   = true;
                    checksumIndex = Globals.net_message.readcount;
                    checksum      = MSG.ReadByte(Globals.net_message);
                    lastframe     = MSG.ReadLong(Globals.net_message);
                    if (lastframe != cl.lastframe)
                    {
                        cl.lastframe = lastframe;
                        if (cl.lastframe > 0)
                        {
                            cl.frame_latency[cl.lastframe & (Defines.LATENCY_COUNTS - 1)] = SV_INIT.svs.realtime - cl.frames[cl.lastframe & Defines.UPDATE_MASK].senttime;
                        }
                    }

                    nullcmd = new usercmd_t();
                    MSG.ReadDeltaUsercmd(Globals.net_message, nullcmd, oldest);
                    MSG.ReadDeltaUsercmd(Globals.net_message, oldest, oldcmd);
                    MSG.ReadDeltaUsercmd(Globals.net_message, oldcmd, newcmd);
                    if (cl.state != Defines.cs_spawned)
                    {
                        cl.lastframe = -1;
                        break;
                    }

                    calculatedChecksum = Com.BlockSequenceCRCByte(Globals.net_message.data, checksumIndex + 1, Globals.net_message.readcount - checksumIndex - 1, cl.netchan.incoming_sequence);
                    if ((calculatedChecksum & 0xff) != checksum)
                    {
                        Com.DPrintf("Failed command checksum for " + cl.name + " (" + calculatedChecksum + " != " + checksum + ")/" + cl.netchan.incoming_sequence + "\\n");
                        return;
                    }

                    if (0 == SV_MAIN.sv_paused.value)
                    {
                        net_drop = cl.netchan.dropped;
                        if (net_drop < 20)
                        {
                            while (net_drop > 2)
                            {
                                SV_ClientThink(cl, cl.lastcmd);
                                net_drop--;
                            }

                            if (net_drop > 1)
                            {
                                SV_ClientThink(cl, oldest);
                            }
                            if (net_drop > 0)
                            {
                                SV_ClientThink(cl, oldcmd);
                            }
                        }

                        SV_ClientThink(cl, newcmd);
                    }

                    cl.lastcmd.Set(newcmd);
                    break;

                case Defines.clc_stringcmd:
                    s = MSG.ReadString(Globals.net_message);
                    if (++stringCmdCount < SV_USER.MAX_STRINGCMDS)
                    {
                        SV_ExecuteUserCommand(s);
                    }
                    if (cl.state == Defines.cs_zombie)
                    {
                        return;
                    }
                    break;
                }
            }
        }