Exemple #1
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);
        }
Exemple #2
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);
                }
            }
        }
Exemple #3
0
        public static void PF_Unicast(edict_t ent, bool reliable)
        {
            int      p;
            client_t client;

            if (ent == null)
            {
                return;
            }
            p = ent.index;
            if (p < 1 || p > SV_MAIN.maxclients.value)
            {
                return;
            }
            client = SV_INIT.svs.clients[p - 1];
            if (reliable)
            {
                SZ.Write(client.netchan.message, SV_INIT.sv.multicast.data, SV_INIT.sv.multicast.cursize);
            }
            else
            {
                SZ.Write(client.datagram, SV_INIT.sv.multicast.data, SV_INIT.sv.multicast.cursize);
            }
            SZ.Clear(SV_INIT.sv.multicast);
        }
Exemple #4
0
        public static Int32 SV_FindIndex(String name, Int32 start, Int32 max, Boolean create)
        {
            Int32 i;

            if (name == null || name.Length == 0)
            {
                return(0);
            }
            for (i = 1; i < max && sv.configstrings[start + i] != null; i++)
            {
                if (0 == Lib.Strcmp(sv.configstrings[start + i], name))
                {
                    return(i);
                }
            }
            if (!create)
            {
                return(0);
            }
            if (i == max)
            {
                Com.Error(Defines.ERR_DROP, "*Index: overflow");
            }
            sv.configstrings[start + i] = name;
            if (sv.state != Defines.ss_loading)
            {
                SZ.Clear(sv.multicast);
                MSG.WriteChar(sv.multicast, Defines.svc_configstring);
                MSG.WriteShort(sv.multicast, start + i);
                MSG.WriteString(sv.multicast, name);
                SV_SEND.SV_Multicast(Globals.vec3_origin, Defines.MULTICAST_ALL_R);
            }

            return(i);
        }
Exemple #5
0
        /**
         *  PF_Configstring
         */
        public static void PF_Configstring(int index, string val)
        {
            if (index < 0 || index >= Defines.MAX_CONFIGSTRINGS)
            {
                Com.Error(Defines.ERR_DROP, "configstring: bad index " + index + "\n");
            }

            if (val == null)
            {
                val = "";
            }

            // change the string in sv
            SV_INIT.sv.configstrings[index] = val;

            if (SV_INIT.sv.state != Defines.ss_loading)
            {
                // send the update to
                // everyone
                SZ.Clear(SV_INIT.sv.multicast);
                MSG.WriteChar(SV_INIT.sv.multicast, Defines.svc_configstring);
                MSG.WriteShort(SV_INIT.sv.multicast, index);
                MSG.WriteString(SV_INIT.sv.multicast, val);

                SV_SEND.SV_Multicast(Globals.vec3_origin, Defines.MULTICAST_ALL_R);
            }
        }
Exemple #6
0
        /**
         * Save everything in the world out without deltas. Used for recording
         * footage for merged or assembled demos.
         */
        public static void SV_RecordDemoMessage()
        {
            if (SV_INIT.svs.demofile == null)
            {
                return;
            }

            //memset (nostate, 0, sizeof(nostate));
            entity_state_t nostate = new(null);
            sizebuf_t      buf     = new();

            SZ.Init(buf, SV_ENTS.buf_data, SV_ENTS.buf_data.Length);

            // write a frame message that doesn't contain a player_state_t
            MSG.WriteByte(buf, Defines.svc_frame);
            MSG.WriteLong(buf, SV_INIT.sv.framenum);

            MSG.WriteByte(buf, Defines.svc_packetentities);

            var e   = 1;
            var ent = GameBase.g_edicts[e];

            while (e < GameBase.num_edicts)
            {
                // ignore ents without visible models unless they have an effect
                if (ent.inuse &&
                    ent.s.number != 0 &&
                    (ent.s.modelindex != 0 || ent.s.effects != 0 || ent.s.sound != 0 || ent.s.@event != 0) &&
                    0 == (ent.svflags & Defines.SVF_NOCLIENT))
                {
                    MSG.WriteDeltaEntity(nostate, ent.s, buf, false, true);
                }

                e++;
                ent = GameBase.g_edicts[e];
            }

            MSG.WriteShort(buf, 0);             // end of packetentities

            // now add the accumulated multicast information
            SZ.Write(buf, SV_INIT.svs.demo_multicast.data, SV_INIT.svs.demo_multicast.cursize);
            SZ.Clear(SV_INIT.svs.demo_multicast);

            // now write the entire message to the file, prefixed by the length
            var len = EndianHandler.swapInt(buf.cursize);

            try
            {
                //fwrite (len, 4, 1, svs.demofile);
                SV_INIT.svs.demofile.Write(len);

                //fwrite (buf.data, buf.cursize, 1, svs.demofile);
                SV_INIT.svs.demofile.Write(buf.data, 0, buf.cursize);
            }
            catch (Exception)
            {
                Com.Printf("Error writing demo file:" + e);
            }
        }
Exemple #7
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);
                }
            }
        }
Exemple #8
0
        /**
         * SV_FindIndex.
         */
        public static int SV_FindIndex(string name, int start, int max, bool create)
        {
            int i;

            if (name == null || name.Length == 0)
            {
                return(0);
            }

            for (i = 1; i < max && SV_INIT.sv.configstrings[start + i] != null; i++)
            {
                if (0 == Lib.strcmp(SV_INIT.sv.configstrings[start + i], name))
                {
                    return(i);
                }
            }

            if (!create)
            {
                return(0);
            }

            if (i == max)
            {
                Com.Error(Defines.ERR_DROP, "*Index: overflow");
            }

            SV_INIT.sv.configstrings[start + i] = name;

            if (SV_INIT.sv.state != Defines.ss_loading)
            {
                // send the update to everyone
                SZ.Clear(SV_INIT.sv.multicast);
                MSG.WriteChar(SV_INIT.sv.multicast, Defines.svc_configstring);
                MSG.WriteShort(SV_INIT.sv.multicast, start + i);
                MSG.WriteString(SV_INIT.sv.multicast, name);
                SV_SEND.SV_Multicast(Globals.vec3_origin, Defines.MULTICAST_ALL_R);
            }

            return(i);
        }
Exemple #9
0
        public static void SV_RecordDemoMessage( )
        {
            if (SV_INIT.svs.demofile == null)
            {
                return;
            }
            entity_state_t nostate = new entity_state_t(null);
            sizebuf_t      buf     = new sizebuf_t();

            SZ.Init(buf, buf_data, buf_data.Length);
            MSG.WriteByte(buf, Defines.svc_frame);
            MSG.WriteLong(buf, SV_INIT.sv.framenum);
            MSG.WriteByte(buf, Defines.svc_packetentities);
            var     e   = 1;
            edict_t ent = GameBase.g_edicts[e];

            while (e < GameBase.num_edicts)
            {
                if (ent.inuse && ent.s.number != 0 && (ent.s.modelindex != 0 || ent.s.effects != 0 || ent.s.sound != 0 || ent.s.event_renamed != 0) && 0 == (ent.svflags & Defines.SVF_NOCLIENT))
                {
                    MSG.WriteDeltaEntity(nostate, ent.s, buf, false, true);
                }
                e++;
                ent = GameBase.g_edicts[e];
            }

            MSG.WriteShort(buf, 0);
            SZ.Write(buf, SV_INIT.svs.demo_multicast.data, SV_INIT.svs.demo_multicast.cursize);
            SZ.Clear(SV_INIT.svs.demo_multicast);
            var len = EndianHandler.SwapInt(buf.cursize);

            try
            {
                SV_INIT.svs.demofile.Write(len);
                SV_INIT.svs.demofile.Write(buf.data, 0, buf.cursize);
            }
            catch (Exception e1)
            {
                Com.Printf("Error writing demo file:" + e);
            }
        }
Exemple #10
0
        public static void SV_Multicast(Single[] origin, Int32 to)
        {
            client_t client;

            Byte[]  mask = null;
            Int32   leafnum, cluster;
            Int32   j;
            Boolean reliable;
            Int32   area1, area2;

            reliable = false;
            if (to != Defines.MULTICAST_ALL_R && to != Defines.MULTICAST_ALL)
            {
                leafnum = CM.CM_PointLeafnum(origin);
                area1   = CM.CM_LeafArea(leafnum);
            }
            else
            {
                leafnum = 0;
                area1   = 0;
            }

            if (SV_INIT.svs.demofile != null)
            {
                SZ.Write(SV_INIT.svs.demo_multicast, SV_INIT.sv.multicast.data, SV_INIT.sv.multicast.cursize);
            }
            switch (to)

            {
            case Defines.MULTICAST_ALL_R:
                reliable = true;
                break;

            case Defines.MULTICAST_ALL:
                leafnum = 0;
                mask    = null;
                break;

            case Defines.MULTICAST_PHS_R:
                reliable = true;
                break;

            case Defines.MULTICAST_PHS:
                leafnum = CM.CM_PointLeafnum(origin);
                cluster = CM.CM_LeafCluster(leafnum);
                mask    = CM.CM_ClusterPHS(cluster);
                break;

            case Defines.MULTICAST_PVS_R:
                reliable = true;
                break;

            case Defines.MULTICAST_PVS:
                leafnum = CM.CM_PointLeafnum(origin);
                cluster = CM.CM_LeafCluster(leafnum);
                mask    = CM.CM_ClusterPVS(cluster);
                break;

            default:
                mask = null;
                Com.Error(Defines.ERR_FATAL, "SV_Multicast: bad to:" + to + "\\n");
                break;
            }

            for (j = 0; j < SV_MAIN.maxclients.value; j++)
            {
                client = SV_INIT.svs.clients[j];
                if (client.state == Defines.cs_free || client.state == Defines.cs_zombie)
                {
                    continue;
                }
                if (client.state != Defines.cs_spawned && !reliable)
                {
                    continue;
                }
                if (mask != null)
                {
                    leafnum = CM.CM_PointLeafnum(client.edict.s.origin);
                    cluster = CM.CM_LeafCluster(leafnum);
                    area2   = CM.CM_LeafArea(leafnum);
                    if (!CM.CM_AreasConnected(area1, area2))
                    {
                        continue;
                    }
                    if (cluster == -1)
                    {
                        continue;
                    }
                    if (mask != null && (0 == (mask[cluster >> 3] & (1 << (cluster & 7)))))
                    {
                        continue;
                    }
                }

                if (reliable)
                {
                    SZ.Write(client.netchan.message, SV_INIT.sv.multicast.data, SV_INIT.sv.multicast.cursize);
                }
                else
                {
                    SZ.Write(client.datagram, SV_INIT.sv.multicast.data, SV_INIT.sv.multicast.cursize);
                }
            }

            SZ.Clear(SV_INIT.sv.multicast);
        }
Exemple #11
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);
                    }
                }
            }
        }