📄 sv_ccmds.java
字号:
savedInuse = new boolean[(int) SV_MAIN.maxclients.value]; for (i = 0; i < SV_MAIN.maxclients.value; i++) { cl = SV_INIT.svs.clients[i]; savedInuse[i] = cl.edict.inuse; cl.edict.inuse = false; } SV_WriteLevelFile(); // we must restore these for clients to transfer over correctly for (i = 0; i < SV_MAIN.maxclients.value; i++) { cl = SV_INIT.svs.clients[i]; cl.edict.inuse = savedInuse[i]; } savedInuse = null; } } // start up the next map SV_INIT.SV_Map(false, Cmd.Argv(1), false); // archive server state SV_INIT.svs.mapcmd = Cmd.Argv(1); // copy off the level to the autosave slot if (0 == Globals.dedicated.value) { SV_WriteServerFile(true); SV_CopySaveGame("current", "save0"); } } /* ================== SV_Map_f Goes directly to a given map without any savegame archiving. For development work ================== */ public static void SV_Map_f() { String map; //char expanded[MAX_QPATH]; String expanded; // if not a pcx, demo, or cinematic, check to make sure the level exists map = Cmd.Argv(1); if (map.indexOf(".") < 0) { expanded = "maps/" + map + ".bsp"; if (FS.LoadFile(expanded) == null) { Com.Printf("Can't find " + expanded + "\n"); return; } } SV_INIT.sv.state = Defines.ss_dead; // don't save current level when changing SV_WipeSavegame("current"); SV_GameMap_f(); } /* ===================================================================== SAVEGAMES ===================================================================== */ /* ============== SV_Loadgame_f ============== */ public static void SV_Loadgame_f() { String name; RandomAccessFile f; String dir; if (Cmd.Argc() != 2) { Com.Printf("USAGE: loadgame <directory>\n"); return; } Com.Printf("Loading game...\n"); dir = Cmd.Argv(1); if ( (dir.indexOf("..") > -1) || (dir.indexOf("/") > -1) || (dir.indexOf("\\") > -1)) { Com.Printf("Bad savedir.\n"); } // make sure the server.ssv file exists name = FS.Gamedir() + "/save/" + Cmd.Argv(1) + "/server.ssv"; try { f = new RandomAccessFile(name, "r"); } catch (FileNotFoundException e) { Com.Printf("No such savegame: " + name + "\n"); return; } try { f.close(); } catch (IOException e1) { e1.printStackTrace(); } SV_CopySaveGame(Cmd.Argv(1), "current"); SV_ReadServerFile(); // go to the map SV_INIT.sv.state = Defines.ss_dead; // don't save current level when changing SV_INIT.SV_Map(false, SV_INIT.svs.mapcmd, true); } /* ============== SV_Savegame_f ============== */ public static void SV_Savegame_f() { String dir; if (SV_INIT.sv.state != Defines.ss_game) { Com.Printf("You must be in a game to save.\n"); return; } if (Cmd.Argc() != 2) { Com.Printf("USAGE: savegame <directory>\n"); return; } if (Cvar.VariableValue("deathmatch") != 0) { Com.Printf("Can't savegame in a deathmatch\n"); return; } if (0 == Lib.strcmp(Cmd.Argv(1), "current")) { Com.Printf("Can't save to 'current'\n"); return; } if (SV_MAIN.maxclients.value == 1 && SV_INIT.svs.clients[0].edict.client.ps.stats[Defines.STAT_HEALTH] <= 0) { Com.Printf("\nCan't savegame while dead!\n"); return; } dir = Cmd.Argv(1); if ( (dir.indexOf("..") > -1) || (dir.indexOf("/") > -1) || (dir.indexOf("\\") > -1)) { Com.Printf("Bad savedir.\n"); } Com.Printf("Saving game...\n"); // archive current level, including all client edicts. // when the level is reloaded, they will be shells awaiting // a connecting client SV_WriteLevelFile(); // save server state try { SV_WriteServerFile(false); } catch (Exception e) { Com.Printf("IOError in SV_WriteServerFile: " + e); } // copy it off SV_CopySaveGame("current", dir); Com.Printf("Done.\n"); } //=============================================================== /* ================== SV_Kick_f Kick a user off of the server ================== */ public static void SV_Kick_f() { if (!SV_INIT.svs.initialized) { Com.Printf("No server running.\n"); return; } if (Cmd.Argc() != 2) { Com.Printf("Usage: kick <userid>\n"); return; } if (!SV_SetPlayer()) return; SV_SEND.SV_BroadcastPrintf(Defines.PRINT_HIGH, SV_MAIN.sv_client.name + " was kicked\n"); // print directly, because the dropped client won't get the // SV_BroadcastPrintf message SV_SEND.SV_ClientPrintf(SV_MAIN.sv_client, Defines.PRINT_HIGH, "You were kicked from the game\n"); SV_MAIN.SV_DropClient(SV_MAIN.sv_client); SV_MAIN.sv_client.lastmessage = SV_INIT.svs.realtime; // min case there is a funny zombie } /* ================ SV_Status_f ================ */ public static void SV_Status_f() { int i, j, l; client_t cl; String s; int ping; if (SV_INIT.svs.clients == null) { Com.Printf("No server running.\n"); return; } Com.Printf("map : " + SV_INIT.sv.name + "\n"); Com.Printf("num score ping name lastmsg address qport \n"); Com.Printf("--- ----- ---- --------------- ------- --------------------- ------\n"); for (i = 0; i < SV_MAIN.maxclients.value; i++) { cl = SV_INIT.svs.clients[i]; if (0 == cl.state) continue; Com.Printf("%3i ", new Vargs().add(i)); Com.Printf("%5i ", new Vargs().add(cl.edict.client.ps.stats[Defines.STAT_FRAGS])); if (cl.state == Defines.cs_connected) Com.Printf("CNCT "); else if (cl.state == Defines.cs_zombie) Com.Printf("ZMBI "); else { ping = cl.ping < 9999 ? cl.ping : 9999; Com.Printf("%4i ", new Vargs().add(ping)); } Com.Printf("%s", new Vargs().add(cl.name)); l = 16 - cl.name.length(); for (j = 0; j < l; j++) Com.Printf(" "); Com.Printf("%7i ", new Vargs().add(SV_INIT.svs.realtime - cl.lastmessage)); s = NET.AdrToString(cl.netchan.remote_address); Com.Printf(s); l = 22 - s.length(); for (j = 0; j < l; j++) Com.Printf(" "); Com.Printf("%5i", new Vargs().add(cl.netchan.qport)); Com.Printf("\n"); } Com.Printf("\n"); } /* ================== SV_ConSay_f ================== */ public static void SV_ConSay_f() { client_t client; int j; String p; String text; // char[1024]; if (Cmd.Argc() < 2) return; text = "console: "; p = Cmd.Args(); if (p.charAt(0) == '"') { p = p.substring(1, p.length() - 1); } text += p; for (j = 0; j < SV_MAIN.maxclients.value; j++) { client = SV_INIT.svs.clients[j]; if (client.state != Defines.cs_spawned) continue; SV_SEND.SV_ClientPrintf(client, Defines.PRINT_CHAT, text + "\n"); } } /* ================== SV_Heartbeat_f ================== */ public static void SV_Heartbeat_f() { SV_INIT.svs.last_heartbeat = -9999999; } /* =========== SV_Serverinfo_f Examine or change the serverinfo string =========== */ public static void SV_Serverinfo_f() { Com.Printf("Server info settings:\n"); Info.Print(Cvar.Serverinfo()); } /* =========== SV_DumpUser_f Examine all a users info strings =========== */ public static void SV_DumpUser_f() { if (Cmd.Argc() != 2) { Com.Printf("Usage: info <userid>\n"); return; } if (!SV_SetPlayer()) return; Com.Printf("userinfo\n"); Com.Printf("--------\n"); Info.Print(SV_MAIN.sv_client.userinfo); } /* ============== SV_ServerRecord_f Begins server demo recording. Every entity and every message will be recorded, but no playerinfo will be stored. Primarily for demo merging. ============== */ public static void SV_ServerRecord_f() { //char name[MAX_OSPATH]; String name; byte buf_data[] = new byte[32768]; sizebuf_t buf = new sizebuf_t(); int len; int i; if (Cmd.Argc() != 2) { Com.Printf("serverrecord <demoname>\n"); return; } if (SV_INIT.svs.demofile != null) { Com.Printf("Already recording.\n"); return; } if (SV_INIT.sv.state != Defines.ss_game) { Com.Printf("You must be in a level to record.\n"); return; } // // open the demo file // name = FS.Gamedir() + "/demos/" + Cmd.Argv(1) + ".dm2"; Com.Printf("recording to " + name + ".\n"); FS.CreatePath(name); try { SV_INIT.svs.demofile = new RandomAccessFile(name, "rw"); } catch (Exception e) { Com.Printf("ERROR: couldn't open.\n"); return; } // setup a buffer to catch all multicasts SZ.Init(SV_INIT.svs.demo_multicast, SV_INIT.svs.demo_multicast_buf, SV_INIT.svs.demo_multicast_buf.length); // // write a single giant fake message with all the startup info // SZ.Init(buf, buf_data, buf_data.length); // // serverdata needs to go over for all types of servers // to make sure the protocol is right, and to set the gamedir // // send the serverdata MSG.WriteByte(buf, Defines.svc_serverdata); MSG.WriteLong(buf, Defines.PROTOCOL_VERSION); MSG.WriteLong(buf, SV_INIT.svs.spawncount); // 2 means server demo MSG.WriteByte(buf, 2); // demos are always attract loops MSG.WriteString(buf, Cvar.VariableString("gamedir")); MSG.WriteShort(buf, -1); // send full levelname MSG.WriteString(buf, SV_INIT.sv.configstrings[Defines.CS_NAME]); for (i = 0; i < Defines.MAX_CONFIGSTRINGS; i++) if (SV_INIT.sv.configstrings[i].length() == 0) { MSG.WriteByte(buf, Defines.svc_configstring); MSG.WriteShort(buf, i); MSG.WriteString(buf, SV_INIT.sv.configstrings[i]); } // write it to the demo file Com.DPrintf("signon message length: " + buf.cursize + "\n"); len = EndianHandler.swapInt(buf.cursize); //fwrite(len, 4, 1, svs.demofile); //fwrite(buf.data, buf.cursize, 1, svs.demofile); try { SV_INIT.svs.demofile.writeInt(len); SV_INIT.svs.demofile.write(buf.data, 0, buf.cursize); } catch (IOException e1) { // TODO: do quake2 error handling! e1.printStackTrace(); } // the rest of the demo file will be individual frames } /* ============== SV_ServerStop_f Ends server demo recording ============== */ public static void SV_ServerStop_f() { if (SV_INIT.svs.demofile == null) { Com.Printf("Not doing a serverrecord.\n"); return; } try { SV_INIT.svs.demofile.close(); } catch (IOException e) { e.printStackTrace(); } SV_INIT.svs.demofile = null; Com.Printf("Recording completed.\n"); } /* =============== SV_KillServer_f Kick everyone off, possibly in preparation for a new game =============== */ public static void SV_KillServer_f() { if (!SV_INIT.svs.initialized) return; SV_MAIN.SV_Shutdown("Server was killed.\n", false); NET.Config(false); // close network sockets } /* =============== SV_ServerCommand_f Let the game dll handle a command =============== */ public static void SV_ServerCommand_f() { GameSVCmds.ServerCommand(); } //=========================================================== /* ================== SV_InitOperatorCommands ================== */ public static void SV_InitOperatorCommands() { Cmd.AddCommand("heartbeat", new xcommand_t() { public void execute() { SV_Heartbeat_f(); } }); Cmd.AddCommand("kick", new xcommand_t() { public void execute() { SV_Kick_f(); } }); Cmd.AddCommand("status", new xcommand_t() { public void execute() { SV_Status_f(); } }); Cmd.AddCommand("serverinfo", new xcommand_t() { public void execute() { SV_Serverinfo_f(); } }); Cmd.AddCommand("dumpuser", new xcommand_t() { public void execute() { SV_DumpUser_f(); } }); Cmd.AddCommand("map", new xcommand_t() { public void execute() { SV_Map_f(); } }); Cmd.AddCommand("demomap", new xcommand_t() { public void execute() { SV_DemoMap_f(); } }); Cmd.AddCommand("gamemap", new xcommand_t() { public void execute() { SV_GameMap_f(); } }); Cmd.AddCommand("setmaster", new xcommand_t() { public void execute() { SV_SetMaster_f(); } }); if (Globals.dedicated.value != 0) Cmd.AddCommand("say", new xcommand_t() { public void execute() { SV_ConSay_f(); } }); Cmd.AddCommand("serverrecord", new xcommand_t() { public void execute() { SV_ServerRecord_f(); } }); Cmd.AddCommand("serverstop", new xcommand_t() { public void execute() { SV_ServerStop_f(); } }); Cmd.AddCommand("save", new xcommand_t() { public void execute() { SV_Savegame_f(); } }); Cmd.AddCommand("load", new xcommand_t() { public void execute() { SV_Loadgame_f(); } }); Cmd.AddCommand("killserver", new xcommand_t() { public void execute() { SV_KillServer_f(); } }); Cmd.AddCommand("sv", new xcommand_t() { public void execute() { SV_ServerCommand_f(); } }); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -