static float _LastMsg; // static float lastmsg from CL_KeepaliveMessage /// <summary> /// CL_ParseServerMessage /// </summary> static void ParseServerMessage() { // // if recording demos, copy the message out // if (_ShowNet.Value == 1) { Con.Print("{0} ", Net.Message.Length); } else if (_ShowNet.Value == 2) { Con.Print("------------------\n"); } cl.onground = false; // unless the server says otherwise // // parse the message // Net.Reader.Reset(); int i; while (true) { if (Net.Reader.IsBadRead) { Host.Error("CL_ParseServerMessage: Bad server message"); } int cmd = Net.Reader.ReadByte(); if (cmd == -1) { ShowNet("END OF MESSAGE"); return; // end of message } // if the high bit of the command byte is set, it is a fast update if ((cmd & 128) != 0) { ShowNet("fast update"); ParseUpdate(cmd & 127); continue; } ShowNet(_SvcStrings[cmd]); // other commands switch (cmd) { default: Host.Error("CL_ParseServerMessage: Illegible server message\n"); break; case Protocol.svc_nop: break; case Protocol.svc_time: cl.mtime[1] = cl.mtime[0]; cl.mtime[0] = Net.Reader.ReadFloat(); break; case Protocol.svc_clientdata: i = Net.Reader.ReadShort(); ParseClientData(i); break; case Protocol.svc_version: i = Net.Reader.ReadLong(); if (i != Protocol.PROTOCOL_VERSION) { Host.Error("CL_ParseServerMessage: Server is protocol {0} instead of {1}\n", i, Protocol.PROTOCOL_VERSION); } break; case Protocol.svc_disconnect: Host.EndGame("Server disconnected\n"); break; case Protocol.svc_print: Con.Print(Net.Reader.ReadString()); break; case Protocol.svc_centerprint: Scr.CenterPrint(Net.Reader.ReadString()); break; case Protocol.svc_stufftext: Cbuf.AddText(Net.Reader.ReadString()); break; case Protocol.svc_damage: View.ParseDamage(); break; case Protocol.svc_serverinfo: ParseServerInfo(); Scr.vid.recalc_refdef = true; // leave intermission full screen break; case Protocol.svc_setangle: cl.viewangles.X = Net.Reader.ReadAngle(); cl.viewangles.Y = Net.Reader.ReadAngle(); cl.viewangles.Z = Net.Reader.ReadAngle(); break; case Protocol.svc_setview: cl.viewentity = Net.Reader.ReadShort(); break; case Protocol.svc_lightstyle: i = Net.Reader.ReadByte(); if (i >= QDef.MAX_LIGHTSTYLES) { Sys.Error("svc_lightstyle > MAX_LIGHTSTYLES"); } _LightStyle[i].map = Net.Reader.ReadString(); break; case Protocol.svc_sound: ParseStartSoundPacket(); break; case Protocol.svc_stopsound: i = Net.Reader.ReadShort(); Sound.StopSound(i >> 3, i & 7); break; case Protocol.svc_updatename: Sbar.Changed(); i = Net.Reader.ReadByte(); if (i >= cl.maxclients) { Host.Error("CL_ParseServerMessage: svc_updatename > MAX_SCOREBOARD"); } cl.scores[i].name = Net.Reader.ReadString(); break; case Protocol.svc_updatefrags: Sbar.Changed(); i = Net.Reader.ReadByte(); if (i >= cl.maxclients) { Host.Error("CL_ParseServerMessage: svc_updatefrags > MAX_SCOREBOARD"); } cl.scores[i].frags = Net.Reader.ReadShort(); break; case Protocol.svc_updatecolors: Sbar.Changed(); i = Net.Reader.ReadByte(); if (i >= cl.maxclients) { Host.Error("CL_ParseServerMessage: svc_updatecolors > MAX_SCOREBOARD"); } cl.scores[i].colors = Net.Reader.ReadByte(); NewTranslation(i); break; case Protocol.svc_particle: Render.ParseParticleEffect(); break; case Protocol.svc_spawnbaseline: i = Net.Reader.ReadShort(); // must use CL_EntityNum() to force cl.num_entities up ParseBaseline(EntityNum(i)); break; case Protocol.svc_spawnstatic: ParseStatic(); break; case Protocol.svc_temp_entity: ParseTempEntity(); break; case Protocol.svc_setpause: { cl.paused = Net.Reader.ReadByte() != 0; if (cl.paused) { CDAudio.Pause(); } else { CDAudio.Resume(); } } break; case Protocol.svc_signonnum: i = Net.Reader.ReadByte(); if (i <= cls.signon) { Host.Error("Received signon {0} when at {1}", i, cls.signon); } cls.signon = i; SignonReply(); break; case Protocol.svc_killedmonster: cl.stats[QStats.STAT_MONSTERS]++; break; case Protocol.svc_foundsecret: cl.stats[QStats.STAT_SECRETS]++; break; case Protocol.svc_updatestat: i = Net.Reader.ReadByte(); if (i < 0 || i >= QStats.MAX_CL_STATS) { Sys.Error("svc_updatestat: {0} is invalid", i); } cl.stats[i] = Net.Reader.ReadLong(); break; case Protocol.svc_spawnstaticsound: ParseStaticSound(); break; case Protocol.svc_cdtrack: cl.cdtrack = Net.Reader.ReadByte(); cl.looptrack = Net.Reader.ReadByte(); if ((cls.demoplayback || cls.demorecording) && (cls.forcetrack != -1)) { CDAudio.Play((byte)cls.forcetrack, true); } else { CDAudio.Play((byte)cl.cdtrack, true); } break; case Protocol.svc_intermission: cl.intermission = 1; cl.completed_time = (int)cl.time; Scr.vid.recalc_refdef = true; // go to full screen break; case Protocol.svc_finale: cl.intermission = 2; cl.completed_time = (int)cl.time; Scr.vid.recalc_refdef = true; // go to full screen Scr.CenterPrint(Net.Reader.ReadString()); break; case Protocol.svc_cutscene: cl.intermission = 3; cl.completed_time = (int)cl.time; Scr.vid.recalc_refdef = true; // go to full screen Scr.CenterPrint(Net.Reader.ReadString()); break; case Protocol.svc_sellscreen: Cmd.ExecuteString("help", cmd_source_t.src_command); break; } } }
// _Host_Frame // //Runs all active servers static void InternalFrame(double time) { // keep the random time dependent Sys.Random(); // decide the simulation time if (!FilterTime(time)) { return; // don't run too fast, or packets will flood out } // get new key events Sys.SendKeyEvents(); // allow mice or other external controllers to add commands Input.Commands(); // process console commands Cbuf.Execute(); Net.Poll(); // if running the server locally, make intentions now if (Server.sv.active) { Client.SendCmd(); } //------------------- // // server operations // //------------------- // check for commands typed to the host GetConsoleCommands(); if (Server.sv.active) { ServerFrame(); } //------------------- // // client operations // //------------------- // if running the server remotely, send intentions now after // the incoming messages have been read if (!Server.sv.active) { Client.SendCmd(); } _Time += FrameTime; // fetch results from server if (Client.cls.state == cactive_t.ca_connected) { Client.ReadFromServer(); } // update video if (_Speeds.Value != 0) { _Time1 = Sys.GetFloatTime(); } Scr.UpdateScreen(); if (_Speeds.Value != 0) { _Time2 = Sys.GetFloatTime(); } // update audio if (Client.cls.signon == Client.SIGNONS) { Sound.Update(ref Render.Origin, ref Render.ViewPn, ref Render.ViewRight, ref Render.ViewUp); Client.DecayLights(); } else { Sound.Update(ref Common.ZeroVector, ref Common.ZeroVector, ref Common.ZeroVector, ref Common.ZeroVector); } CDAudio.Update(); if (_Speeds.Value != 0) { int pass1 = (int)((_Time1 - _Time3) * 1000); _Time3 = Sys.GetFloatTime(); int pass2 = (int)((_Time2 - _Time1) * 1000); int pass3 = (int)((_Time3 - _Time2) * 1000); Con.Print("{0,3} tot {1,3} server {2,3} gfx {3,3} snd\n", pass1 + pass2 + pass3, pass1, pass2, pass3); } _FrameCount++; }