// Host_Map_f // // handle a // map <servername> // command from the console. Active clients are kicked off. private 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); } }
// Host_Restart_f // // Restarts the current server for a dead player private static void Restart_f() { if (Client.cls.demoplayback || !Server.IsActive) { return; } if (Cmd.Source != cmd_source_t.src_command) { return; } string mapname = Server.sv.name; // must copy out, because it gets cleared // in sv_spawnserver Server.SpawnServer(mapname); }
/// <summary> /// Host_Changelevel_f /// Goes to a new map, taking all clients along /// </summary> private static void Changelevel_f() { if (Cmd.Argc != 2) { Con.Print("changelevel <levelname> : continue game on a new level\n"); return; } if (!Server.sv.active || Client.cls.demoplayback) { Con.Print("Only the server may changelevel\n"); return; } Server.SaveSpawnparms(); string level = Cmd.Argv(1); Server.SpawnServer(level); }
/// <summary> /// Host_Loadgame_f /// </summary> private static void Loadgame_f() { if (Cmd.Source != cmd_source_t.src_command) { return; } if (Cmd.Argc != 2) { Con.Print("load <savename> : load a game\n"); return; } Client.cls.demonum = -1; // stop demo loop in case this fails string name = Path.ChangeExtension(Path.Combine(Common.GameDir, Cmd.Argv(1)), ".sav"); // we can't call SCR_BeginLoadingPlaque, because too much stack space has // been used. The menu calls it before stuffing loadgame command // SCR_BeginLoadingPlaque (); Con.Print("Loading game from {0}...\n", name); FileStream fs = Sys.FileOpenRead(name); if (fs == null) { Con.Print("ERROR: couldn't open.\n"); return; } using (StreamReader reader = new StreamReader(fs, Encoding.ASCII)) { string line = reader.ReadLine(); int version = Common.atoi(line); if (version != SAVEGAME_VERSION) { Con.Print("Savegame is version {0}, not {1}\n", version, SAVEGAME_VERSION); return; } line = reader.ReadLine(); float[] spawn_parms = new float[Server.NUM_SPAWN_PARMS]; for (int i = 0; i < spawn_parms.Length; i++) { line = reader.ReadLine(); spawn_parms[i] = Common.atof(line); } // this silliness is so we can load 1.06 save files, which have float skill values line = reader.ReadLine(); float tfloat = Common.atof(line); Host.CurrentSkill = (int)(tfloat + 0.1); Cvar.Set("skill", (float)Host.CurrentSkill); string mapname = reader.ReadLine(); line = reader.ReadLine(); float time = Common.atof(line); Client.Disconnect_f(); Server.SpawnServer(mapname); if (!Server.sv.active) { Con.Print("Couldn't load map\n"); return; } Server.sv.paused = true; // pause until all clients connect Server.sv.loadgame = true; // load the light styles for (int i = 0; i < QDef.MAX_LIGHTSTYLES; i++) { line = reader.ReadLine(); Server.sv.lightstyles[i] = line; } // load the edicts out of the savegame file int entnum = -1; // -1 is the globals StringBuilder sb = new StringBuilder(32768); while (!reader.EndOfStream) { line = reader.ReadLine(); if (line == null) { Sys.Error("EOF without closing brace"); } sb.AppendLine(line); int idx = line.IndexOf('}'); if (idx != -1) { int length = 1 + sb.Length - (line.Length - idx); string data = Common.Parse(sb.ToString(0, length)); if (String.IsNullOrEmpty(Common.Token)) { break; // end of file } if (Common.Token != "{") { Sys.Error("First token isn't a brace"); } if (entnum == -1) { // parse the global vars Progs.ParseGlobals(data); } else { // parse an edict edict_t ent = Server.EdictNum(entnum); ent.Clear(); Progs.ParseEdict(data, ent); // link it into the bsp tree if (!ent.free) { Server.LinkEdict(ent, false); } } entnum++; sb.Remove(0, length); } } Server.sv.num_edicts = entnum; Server.sv.time = time; for (int i = 0; i < Server.NUM_SPAWN_PARMS; i++) { Server.svs.clients[0].spawn_parms[i] = spawn_parms[i]; } } if (Client.cls.state != cactive_t.ca_dedicated) { Client.EstablishConnection("local"); Reconnect_f(); } }