// Host_Startdemos_f static void Startdemos_f() { if (Client.cls.state == cactive_t.ca_dedicated) { if (!Server.sv.active) { Cbuf.AddText("map start\n"); } return; } int c = Cmd.Argc - 1; if (c > Client.MAX_DEMOS) { Con.Print("Max {0} demos in demoloop\n", Client.MAX_DEMOS); c = Client.MAX_DEMOS; } Con.Print("{0} demo(s) in loop\n", c); for (int i = 1; i < c + 1; i++) { Client.cls.demos[i - 1] = Common.Copy(Cmd.Argv(i), Client.MAX_DEMONAME); } if (!Server.sv.active && Client.cls.demonum != -1 && !Client.cls.demoplayback) { Client.cls.demonum = 0; Client.NextDemo(); } else { Client.cls.demonum = -1; } }
// NET_Port_f static void Port_f() { if (Cmd.Argc != 2) { Con.Print("\"port\" is \"{0}\"\n", HostPort); return; } int n = Common.atoi(Cmd.Argv(1)); if (n < 1 || n > 65534) { Con.Print("Bad value, must be between 1 and 65534\n"); return; } _DefHostPort = n; HostPort = n; if (_IsListening) { // force a change to the new port Cbuf.AddText("listen 0\n"); Cbuf.AddText("listen 1\n"); } }
// Host_GetConsoleCommands // // Add them exactly as if they had been typed at the console static void GetConsoleCommands() { while (true) { string cmd = Sys.ConsoleInput(); if (String.IsNullOrEmpty(cmd)) { break; } Cbuf.AddText(cmd); } }
/* * ============== * PF_changelevel * ============== */ static void PF_changelevel() { // make sure we don't issue two changelevels if (Server.svs.changelevel_issued) { return; } Server.svs.changelevel_issued = true; string s = GetString(OFS.OFS_PARM0); Cbuf.AddText(String.Format("changelevel {0}\n", s)); }
// MaxPlayers_f static void MaxPlayers_f() { if (Cmd.Argc != 2) { Con.Print("\"maxplayers\" is \"%u\"\n", Server.svs.maxclients); return; } if (Server.sv.active) { Con.Print("maxplayers can not be changed while a server is running.\n"); return; } int n = Common.atoi(Cmd.Argv(1)); if (n < 1) { n = 1; } if (n > Server.svs.maxclientslimit) { n = Server.svs.maxclientslimit; Con.Print("\"maxplayers\" set to \"{0}\"\n", n); } if (n == 1 && _IsListening) { Cbuf.AddText("listen 0\n"); } if (n > 1 && !_IsListening) { Cbuf.AddText("listen 1\n"); } Server.svs.maxclients = n; if (n == 1) { Cvar.Set("deathmatch", "0"); } else { Cvar.Set("deathmatch", "1"); } }
// Key_Message (int key) static void KeyMessage(int key) { if (key == K_ENTER) { if (_TeamMessage) { Cbuf.AddText("say_team \""); } else { Cbuf.AddText("say \""); } Cbuf.AddText(_ChatBuffer.ToString()); Cbuf.AddText("\"\n"); Key.Destination = keydest_t.key_game; _ChatBuffer.Length = 0; return; } if (key == K_ESCAPE) { Key.Destination = keydest_t.key_game; _ChatBuffer.Length = 0; return; } if (key < 32 || key > 127) { return; // non printable } if (key == K_BACKSPACE) { if (_ChatBuffer.Length > 0) { _ChatBuffer.Length--; } return; } if (_ChatBuffer.Length == 31) { return; // all full } _ChatBuffer.Append((char)key); }
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> /// PF_localcmd /// Sends text over to the client's execution buffer /// localcmd (string) /// </summary> static void PF_localcmd() { string cmd = GetString(OFS.OFS_PARM0); Cbuf.AddText(cmd); }
/// <summary> /// Key_Console /// Interactive line editing and console scrollback /// </summary> static void KeyConsole(int key) { if (key == K_ENTER) { string line = new String(_Lines[_EditLine]).TrimEnd('\0', ' '); string cmd = line.Substring(1); Cbuf.AddText(cmd); // skip the > Cbuf.AddText("\n"); Con.Print("{0}\n", line); _EditLine = (_EditLine + 1) & 31; _HistoryLine = _EditLine; _Lines[_EditLine][0] = ']'; Key.LinePos = 1; if (Client.cls.state == cactive_t.ca_disconnected) { Scr.UpdateScreen(); // force an update, because the command } // may take some time return; } if (key == K_TAB) { // command completion string txt = new String(_Lines[_EditLine], 1, MAXCMDLINE - 1).TrimEnd('\0', ' '); string[] cmds = Cmd.Complete(txt); string[] vars = Cvar.CompleteName(txt); string match = null; if (cmds != null) { if (cmds.Length > 1 || vars != null) { Con.Print("\nCommands:\n"); foreach (string s in cmds) { Con.Print(" {0}\n", s); } } else { match = cmds[0]; } } if (vars != null) { if (vars.Length > 1 || cmds != null) { Con.Print("\nVariables:\n"); foreach (string s in vars) { Con.Print(" {0}\n", s); } } else if (match == null) { match = vars[0]; } } if (!String.IsNullOrEmpty(match)) { int len = Math.Min(match.Length, MAXCMDLINE - 3); for (int i = 0; i < len; i++) { _Lines[_EditLine][i + 1] = match[i]; } Key.LinePos = len + 1; _Lines[_EditLine][Key.LinePos] = ' '; Key.LinePos++; _Lines[_EditLine][Key.LinePos] = '\0'; return; } } if (key == K_BACKSPACE || key == K_LEFTARROW) { if (Key.LinePos > 1) { Key.LinePos--; } return; } if (key == K_UPARROW) { do { _HistoryLine = (_HistoryLine - 1) & 31; } while (_HistoryLine != _EditLine && (_Lines[_HistoryLine][1] == 0)); if (_HistoryLine == _EditLine) { _HistoryLine = (_EditLine + 1) & 31; } Array.Copy(_Lines[_HistoryLine], _Lines[_EditLine], MAXCMDLINE); Key.LinePos = 0; while (_Lines[_EditLine][Key.LinePos] != '\0' && Key.LinePos < MAXCMDLINE) { Key.LinePos++; } return; } if (key == K_DOWNARROW) { if (_HistoryLine == _EditLine) { return; } do { _HistoryLine = (_HistoryLine + 1) & 31; }while (_HistoryLine != _EditLine && (_Lines[_HistoryLine][1] == '\0')); if (_HistoryLine == _EditLine) { _Lines[_EditLine][0] = ']'; Key.LinePos = 1; } else { Array.Copy(_Lines[_HistoryLine], _Lines[_EditLine], MAXCMDLINE); Key.LinePos = 0; while (_Lines[_EditLine][Key.LinePos] != '\0' && Key.LinePos < MAXCMDLINE) { Key.LinePos++; } } return; } if (key == K_PGUP || key == K_MWHEELUP) { Con.BackScroll += 2; if (Con.BackScroll > Con.TotalLines - (Scr.vid.height >> 3) - 1) { Con.BackScroll = Con.TotalLines - (Scr.vid.height >> 3) - 1; } return; } if (key == K_PGDN || key == K_MWHEELDOWN) { Con.BackScroll -= 2; if (Con.BackScroll < 0) { Con.BackScroll = 0; } return; } if (key == K_HOME) { Con.BackScroll = Con.TotalLines - (Scr.vid.height >> 3) - 1; return; } if (key == K_END) { Con.BackScroll = 0; return; } if (key < 32 || key > 127) { return; // non printable } if (Key.LinePos < MAXCMDLINE - 1) { _Lines[_EditLine][Key.LinePos] = (char)key; Key.LinePos++; _Lines[_EditLine][Key.LinePos] = '\0'; } }
// Key_Event (int key, qboolean down) // // Called by the system between frames for both key up and key down events // Should NOT be called during an interrupt! public static void Event(int key, bool down) { _KeyDown[key] = down; if (!down) { _Repeats[key] = 0; } _LastPress = key; KeyCount++; if (KeyCount <= 0) { return; // just catching keys for Con_NotifyBox } // update auto-repeat status if (down) { _Repeats[key]++; if (key != K_BACKSPACE && key != K_PAUSE && key != K_PGUP && key != K_PGDN && _Repeats[key] > 1) { return; // ignore most autorepeats } if (key >= 200 && String.IsNullOrEmpty(_Bindings[key])) { Con.Print("{0} is unbound, hit F4 to set.\n", KeynumToString(key)); } } if (key == K_SHIFT) { _ShiftDown = down; } // // handle escape specialy, so the user can never unbind it // if (key == K_ESCAPE) { if (!down) { return; } switch (_KeyDest) { case keydest_t.key_message: KeyMessage(key); break; case keydest_t.key_menu: Menu.KeyDown(key); break; case keydest_t.key_game: case keydest_t.key_console: Menu.ToggleMenu_f(); break; default: Sys.Error("Bad key_dest"); break; } return; } // // key up events only generate commands if the game key binding is // a button command (leading + sign). These will occur even in console mode, // to keep the character from continuing an action started before a console // switch. Button commands include the keynum as a parameter, so multiple // downs can be matched with ups // if (!down) { string kb = _Bindings[key]; if (!String.IsNullOrEmpty(kb) && kb.StartsWith("+")) { Cbuf.AddText(String.Format("-{0} {1}\n", kb.Substring(1), key)); } if (_KeyShift[key] != key) { kb = _Bindings[_KeyShift[key]]; if (!String.IsNullOrEmpty(kb) && kb.StartsWith("+")) { Cbuf.AddText(String.Format("-{0} {1}\n", kb.Substring(1), key)); } } return; } // // during demo playback, most keys bring up the main menu // if (Client.cls.demoplayback && down && _ConsoleKeys[key] && _KeyDest == keydest_t.key_game) { Menu.ToggleMenu_f(); return; } // // if not a consolekey, send to the interpreter no matter what mode is // if ((_KeyDest == keydest_t.key_menu && _MenuBound[key]) || (_KeyDest == keydest_t.key_console && !_ConsoleKeys[key]) || (_KeyDest == keydest_t.key_game && (!Con.ForcedUp || !_ConsoleKeys[key]))) { string kb = _Bindings[key]; if (!String.IsNullOrEmpty(kb)) { if (kb.StartsWith("+")) { // button commands add keynum as a parm Cbuf.AddText(String.Format("{0} {1}\n", kb, key)); } else { Cbuf.AddText(kb); Cbuf.AddText("\n"); } } return; } if (!down) { return; // other systems only care about key down events } if (_ShiftDown) { key = _KeyShift[key]; } switch (_KeyDest) { case keydest_t.key_message: KeyMessage(key); break; case keydest_t.key_menu: Menu.KeyDown(key); break; case keydest_t.key_game: case keydest_t.key_console: KeyConsole(key); break; default: Sys.Error("Bad key_dest"); break; } }