// Host_Map_f // // handle a // map <servername> // command from the console. Active clients are kicked off. static void Map_f() { if (Cmd.Source != cmd_source_t.src_command) { return; } Client.cls.demonum = -1; // stop demo loop in case this fails Client.Disconnect(); ShutdownServer(false); Key.Destination = keydest_t.key_game; // remove console or menu Scr.BeginLoadingPlaque(); Client.cls.mapstring = Cmd.JoinArgv() + "\n"; Server.svs.serverflags = 0; // haven't completed an episode yet string name = Cmd.Argv(1); Server.SpawnServer(name); if (!Server.IsActive) { return; } if (Client.cls.state != cactive_t.ca_dedicated) { Client.cls.spawnparms = Cmd.JoinArgv(); Cmd.ExecuteString("connect local", cmd_source_t.src_command); } }
// Cbuf_Execute() // Pulls off \n terminated lines of text from the command buffer and sends // them through Cmd_ExecuteString. Stops when the buffer is empty. // Normally called once per frame, but may be explicitly invoked. // Do not call inside a command function! public static void Execute() { while (_Buf.Length > 0) { string text = _Buf.ToString(); // find a \n or ; line break int quotes = 0, i; for (i = 0; i < text.Length; i++) { if (text[i] == '"') { quotes++; } if (((quotes & 1) == 0) && (text[i] == ';')) { break; // don't break if inside a quoted string } if (text[i] == '\n') { break; } } string line = text.Substring(0, i).TrimEnd('\n', ';'); // delete the text from the command buffer and move remaining commands down // this is necessary because commands (exec, alias) can insert data at the // beginning of the text buffer if (i == _Buf.Length) { _Buf.Length = 0; } else { _Buf.Remove(0, i + 1); } // execute the command line if (!String.IsNullOrEmpty(line)) { Cmd.ExecuteString(line, cmd_source_t.src_command); if (_Wait) { // skip out while text still remains in buffer, leaving it // for next frame _Wait = false; break; } } } }
/// <summary> /// SV_SendReconnect /// Tell all the clients that the server is changing levels /// </summary> private static void SendReconnect() { MsgWriter msg = new MsgWriter(128); msg.WriteChar(Protocol.svc_stufftext); msg.WriteString("reconnect\n"); Net.SendToAll(msg, 5); if (Client.cls.state != cactive_t.ca_dedicated) { Cmd.ExecuteString("reconnect\n", cmd_source_t.src_command); } }
/// <summary> /// CL_Record_f /// record <demoname> <map> [cd track] /// </summary> static void Record_f() { if (Cmd.Source != cmd_source_t.src_command) { return; } int c = Cmd.Argc; if (c != 2 && c != 3 && c != 4) { Con.Print("record <demoname> [<map> [cd track]]\n"); return; } if (Cmd.Argv(1).Contains("..")) { Con.Print("Relative pathnames are not allowed.\n"); return; } if (c == 2 && cls.state == cactive_t.ca_connected) { Con.Print("Can not record - already connected to server\nClient demo recording must be started before connecting\n"); return; } // write the forced cd track number, or -1 int track; if (c == 4) { track = Common.atoi(Cmd.Argv(3)); Con.Print("Forcing CD track to {0}\n", track); } else { track = -1; } string name = Path.Combine(Common.GameDir, Cmd.Argv(1)); // // start the map up // if (c > 2) { Cmd.ExecuteString(String.Format("map {0}", Cmd.Argv(2)), cmd_source_t.src_command); } // // open the demo file // name = Path.ChangeExtension(name, ".dem"); Con.Print("recording to {0}.\n", name); FileStream fs = Sys.FileOpenWrite(name, true); if (fs == null) { Con.Print("ERROR: couldn't open.\n"); return; } BinaryWriter writer = new BinaryWriter(fs, Encoding.ASCII); cls.demofile = new DisposableWrapper <BinaryWriter>(writer, true); cls.forcetrack = track; byte[] tmp = Encoding.ASCII.GetBytes(cls.forcetrack.ToString()); writer.Write(tmp); writer.Write('\n'); cls.demorecording = true; }
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; } } }
/// <summary> /// SV_ReadClientMessage /// Returns false if the client should be killed /// </summary> static bool ReadClientMessage() { while (true) { int ret = Net.GetMessage(Host.HostClient.netconnection); if (ret == -1) { Con.DPrint("SV_ReadClientMessage: NET_GetMessage failed\n"); return(false); } if (ret == 0) { return(true); } Net.Reader.Reset(); bool flag = true; while (flag) { if (!Host.HostClient.active) { return(false); // a command caused an error } if (Net.Reader.IsBadRead) { Con.DPrint("SV_ReadClientMessage: badread\n"); return(false); } int cmd = Net.Reader.ReadChar(); switch (cmd) { case -1: flag = false; // end of message ret = 1; break; case Protocol.clc_nop: break; case Protocol.clc_stringcmd: string s = Net.Reader.ReadString(); if (Host.HostClient.privileged) { ret = 2; } else { ret = 0; } if (Common.SameText(s, "status", 6)) { ret = 1; } else if (Common.SameText(s, "god", 3)) { ret = 1; } else if (Common.SameText(s, "notarget", 8)) { ret = 1; } else if (Common.SameText(s, "fly", 3)) { ret = 1; } else if (Common.SameText(s, "name", 4)) { ret = 1; } else if (Common.SameText(s, "noclip", 6)) { ret = 1; } else if (Common.SameText(s, "say", 3)) { ret = 1; } else if (Common.SameText(s, "say_team", 8)) { ret = 1; } else if (Common.SameText(s, "tell", 4)) { ret = 1; } else if (Common.SameText(s, "color", 5)) { ret = 1; } else if (Common.SameText(s, "kill", 4)) { ret = 1; } else if (Common.SameText(s, "pause", 5)) { ret = 1; } else if (Common.SameText(s, "spawn", 5)) { ret = 1; } else if (Common.SameText(s, "begin", 5)) { ret = 1; } else if (Common.SameText(s, "prespawn", 8)) { ret = 1; } else if (Common.SameText(s, "kick", 4)) { ret = 1; } else if (Common.SameText(s, "ping", 4)) { ret = 1; } else if (Common.SameText(s, "give", 4)) { ret = 1; } else if (Common.SameText(s, "ban", 3)) { ret = 1; } if (ret == 2) { Cbuf.InsertText(s); } else if (ret == 1) { Cmd.ExecuteString(s, cmd_source_t.src_client); } else { Con.DPrint("{0} tried to {1}\n", Host.HostClient.name, s); } break; case Protocol.clc_disconnect: return(false); case Protocol.clc_move: ReadClientMove(ref Host.HostClient.cmd); break; default: Con.DPrint("SV_ReadClientMessage: unknown command char\n"); return(false); } } if (ret != 1) { break; } } return(true); }