// Host_Name_f static void Name_f() { if (Cmd.Argc == 1) { Con.Print("\"name\" is \"{0}\"\n", Client.Name); return; } string newName; if (Cmd.Argc == 2) { newName = Cmd.Argv(1); } else { newName = Cmd.Args; } if (newName.Length > 16) { newName = newName.Remove(15); } if (Cmd.Source == cmd_source_t.src_command) { if (Client.Name == newName) { return; } Cvar.Set("_cl_name", newName); if (Client.Cls.state == ClientActivityState.Connected) { Cmd.ForwardToServer(); } return; } if (!String.IsNullOrEmpty(Host.HostClient.name) && Host.HostClient.name != "unconnected") { if (Host.HostClient.name != newName) { Con.Print("{0} renamed to {1}\n", Host.HostClient.name, newName); } } Host.HostClient.name = newName; Host.HostClient.edict.v.netname = Progs.NewString(newName); // send notification to all clients MessageWriter msg = Server.sv.reliable_datagram; msg.WriteByte(Protocol.svc_updatename); msg.WriteByte(Host.ClientNum); msg.WriteString(newName); }
// Host_Color_f static void Color_f() { if (Cmd.Argc == 1) { Con.Print("\"color\" is \"{0} {1}\"\n", ((int)Client.Color) >> 4, ((int)Client.Color) & 0x0f); Con.Print("color <0-13> [0-13]\n"); return; } int top, bottom; if (Cmd.Argc == 2) { top = bottom = Common.atoi(Cmd.Argv(1)); } else { top = Common.atoi(Cmd.Argv(1)); bottom = Common.atoi(Cmd.Argv(2)); } top &= 15; if (top > 13) { top = 13; } bottom &= 15; if (bottom > 13) { bottom = 13; } int playercolor = top * 16 + bottom; if (Cmd.Source == cmd_source_t.src_command) { Cvar.Set("_cl_color", playercolor); if (Client.Cls.state == ClientActivityState.Connected) { Cmd.ForwardToServer(); } return; } Host.HostClient.colors = playercolor; Host.HostClient.edict.v.team = bottom + 1; // send notification to all clients MessageWriter msg = Server.sv.reliable_datagram; msg.WriteByte(Protocol.svc_updatecolors); msg.WriteByte(Host.ClientNum); msg.WriteByte(Host.HostClient.colors); }
// Cvar_Set() public static void Set(string name, string value) { Cvar var = Find(name); if (var == null) { // there is an error in C code if this happens Con.Print("Cvar.Set: variable {0} not found\n", name); return; } var.Set(value); }
// 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"); } }
// Cvar_Command() // Handles variable inspection and changing from the console public static bool Command() { // check variables Cvar var = Find(Cmd.Argv(0)); if (var == null) { return(false); } // perform a variable print or set if (Cmd.Argc == 1) { Con.Print("\"{0}\" is \"{1}\"\n", var._Name, var._String); } else { var.Set(Cmd.Argv(1)); } return(true); }
public void Update() { if (!_IsEnabled) { return; } if (Sound.BgmVolume != _Volume) { if (_Volume != 0) { Cvar.Set("bgmvolume", 0f); _Volume = Sound.BgmVolume; Pause(); } else { Cvar.Set("bgmvolume", 1f); _Volume = Sound.BgmVolume; Resume(); } } }
// SCR_SizeDown_f // // Keybinding command private static void SizeDown_f() { Cvar.Set("viewsize", _ViewSize.Value - 10); _VidDef.recalc_refdef = true; }
/// <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(); } }
// SCR_SizeUp_f // // Keybinding command static void SizeUp_f() { Cvar.Set("viewsize", _ViewSize.Value + 10); _VidDef.recalc_refdef = true; }
/// <summary> /// Host_FindMaxClients /// </summary> static void FindMaxClients() { server_static_t svs = Server.svs; client_static_t cls = Client.cls; svs.maxclients = 1; int i = Common.CheckParm("-dedicated"); if (i > 0) { cls.state = cactive_t.ca_dedicated; if (i != (Common.Argc - 1)) { svs.maxclients = Common.atoi(Common.Argv(i + 1)); } else { svs.maxclients = 8; } } else { cls.state = cactive_t.ca_disconnected; } i = Common.CheckParm("-listen"); if (i > 0) { if (cls.state == cactive_t.ca_dedicated) { Sys.Error("Only one of -dedicated or -listen can be specified"); } if (i != (Common.Argc - 1)) { svs.maxclients = Common.atoi(Common.Argv(i + 1)); } else { svs.maxclients = 8; } } if (svs.maxclients < 1) { svs.maxclients = 8; } else if (svs.maxclients > QDef.MAX_SCOREBOARD) { svs.maxclients = QDef.MAX_SCOREBOARD; } svs.maxclientslimit = svs.maxclients; if (svs.maxclientslimit < 4) { svs.maxclientslimit = 4; } svs.clients = new client_t[svs.maxclientslimit]; // Hunk_AllocName (svs.maxclientslimit*sizeof(client_t), "clients"); for (i = 0; i < svs.clients.Length; i++) { svs.clients[i] = new client_t(); } if (svs.maxclients > 1) { Cvar.Set("deathmatch", 1.0f); } else { Cvar.Set("deathmatch", 0.0f); } }
// VID_SetMode (int modenum, unsigned char *palette) // sets the mode; only used by the Quake engine for resetting to mode 0 (the // base mode) on memory allocation failures public static void SetMode(int modenum, byte[] palette) { if (modenum < 0 || modenum >= _Modes.Length) { Sys.Error("Bad video mode\n"); } mode_t mode = _Modes[modenum]; // so Con_Printfs don't mess us up by forcing vid and snd updates bool temp = Scr.IsDisabledForLoading; Scr.IsDisabledForLoading = true; CDAudio.Pause(); // Set either the fullscreen or windowed mode DisplayDevice dev = MainForm.DisplayDevice; MainForm form = MainForm.Instance; if (_Windowed) { form.WindowState = WindowState.Normal; form.WindowBorder = WindowBorder.Fixed; form.Location = new Point((mode.width - form.Width) / 2, (mode.height - form.Height) / 2); if (_WindowedMouse.Value != 0 && Key.Destination == keydest_t.key_game) { Input.ActivateMouse(); Input.HideMouse(); } else { Input.DeactivateMouse(); Input.ShowMouse(); } } else { try { dev.ChangeResolution(mode.width, mode.height, mode.bpp, mode.refreshRate); } catch (Exception ex) { Sys.Error("Couldn't set video mode: " + ex.Message); } form.WindowState = WindowState.Fullscreen; form.WindowBorder = WindowBorder.Hidden; } viddef_t vid = Scr.vid; if (vid.conheight > dev.Height) { vid.conheight = dev.Height; } if (vid.conwidth > dev.Width) { vid.conwidth = dev.Width; } vid.width = vid.conwidth; vid.height = vid.conheight; vid.numpages = 2; CDAudio.Resume(); Scr.IsDisabledForLoading = temp; _ModeNum = modenum; Cvar.Set("vid_mode", (float)_ModeNum); // fix the leftover Alt from any Alt-Tab or the like that switched us away ClearAllStates(); Con.SafePrint("Video mode {0} initialized.\n", GetModeDescription(_ModeNum)); SetPalette(palette); vid.recalc_refdef = true; }
/// <summary> /// UDP_Init /// </summary> public bool Init() { _IsInitialized = false; if (Common.HasParam("-noudp")) { return(false); } // determine my name string hostName; try { hostName = Dns.GetHostName(); } catch (SocketException se) { Con.DPrint("Cannot get host name: {0}\n", se.Message); return(false); } // if the quake hostname isn't set, set it to the machine name if (Net.HostName == "UNNAMED") { IPAddress addr; if (!IPAddress.TryParse(hostName, out addr)) { int i = hostName.IndexOf('.'); if (i != -1) { hostName = hostName.Substring(0, i); } } Cvar.Set("hostname", hostName); } int i2 = Common.CheckParm("-ip"); if (i2 > 0) { if (i2 < Common.Argc - 1) { string ipaddr = Common.Argv(i2 + 1); if (!IPAddress.TryParse(ipaddr, out _MyAddress)) { Sys.Error("{0} is not a valid IP address!", ipaddr); } Net.MyTcpIpAddress = ipaddr; } else { Sys.Error("Net.Init: you must specify an IP address after -ip"); } } else { _MyAddress = IPAddress.Any; Net.MyTcpIpAddress = "INADDR_ANY"; } _ControlSocket = OpenSocket(0); if (_ControlSocket == null) { Con.Print("TCP/IP: Unable to open control socket\n"); return(false); } _BroadcastAddress = new IPEndPoint(IPAddress.Broadcast, Net.HostPort); _IsInitialized = true; Con.Print("TCP/IP Initialized\n"); return(true); }
/* * ================= * PF_cvar_set * * float cvar (string) * ================= */ static void PF_cvar_set() { Cvar.Set(GetString(OFS.OFS_PARM0), GetString(OFS.OFS_PARM1)); }
// Draw_Init public static void Init() { for (int i = 0; i < _MenuCachePics.Length; i++) { _MenuCachePics[i] = new cachepic_t(); } if (_glNoBind == null) { _glNoBind = new Cvar("gl_nobind", "0"); _glMaxSize = new Cvar("gl_max_size", "1024"); _glPicMip = new Cvar("gl_picmip", "0"); } // 3dfx can only handle 256 wide textures string renderer = GL.GetString(StringName.Renderer); if (renderer.Contains("3dfx") || renderer.Contains("Glide")) { Cvar.Set("gl_max_size", "256"); } Cmd.Add("gl_texturemode", TextureMode_f); // load the console background and the charset // by hand, because we need to write the version // string into the background before turning // it into a texture int offset = Wad.GetLumpNameOffset("conchars"); byte[] draw_chars = Wad.Data; // draw_chars for (int i = 0; i < 256 * 64; i++) { if (draw_chars[offset + i] == 0) { draw_chars[offset + i] = 255; // proper transparent color } } // now turn them into textures _CharTexture = LoadTexture("charset", 128, 128, new ByteArraySegment(draw_chars, offset), false, true); byte[] buf = Common.LoadFile("gfx/conback.lmp"); if (buf == null) { Sys.Error("Couldn't load gfx/conback.lmp"); } dqpicheader_t cbHeader = Sys.BytesToStructure <dqpicheader_t>(buf, 0); Wad.SwapPic(cbHeader); // hack the version number directly into the pic string ver = String.Format("(c# {0,7:F2}) {1,7:F2}", (float)QDef.CSQUAKE_VERSION, (float)QDef.VERSION); int offset2 = Marshal.SizeOf(typeof(dqpicheader_t)) + 320 * 186 + 320 - 11 - 8 * ver.Length; int y = ver.Length; for (int x = 0; x < y; x++) { CharToConback(ver[x], new ByteArraySegment(buf, offset2 + (x << 3)), new ByteArraySegment(draw_chars, offset)); } _ConBack = new glpic_t(); _ConBack.width = cbHeader.width; _ConBack.height = cbHeader.height; int ncdataIndex = Marshal.SizeOf(typeof(dqpicheader_t)); // cb->data; SetTextureFilters(TextureMinFilter.Nearest, TextureMagFilter.Nearest); _ConBack.texnum = LoadTexture("conback", _ConBack.width, _ConBack.height, new ByteArraySegment(buf, ncdataIndex), false, false); _ConBack.width = Scr.vid.width; _ConBack.height = Scr.vid.height; // save a texture slot for translated picture _TranslateTexture = _TextureExtensionNumber++; // save slots for scraps _ScrapTexNum = _TextureExtensionNumber; _TextureExtensionNumber += MAX_SCRAPS; // // get the other pics we need // _Disc = PicFromWad("disc"); _BackTile = PicFromWad("backtile"); }
// SCR_CalcRefdef // // Must be called whenever vid changes // Internal use only private static void CalcRefdef() { Scr.FullUpdate = 0; // force a background redraw _VidDef.recalc_refdef = false; // force the status bar to redraw Sbar.Changed(); // bound viewsize if (_ViewSize.Value < 30) { Cvar.Set("viewsize", "30"); } if (_ViewSize.Value > 120) { Cvar.Set("viewsize", "120"); } // bound field of view if (_Fov.Value < 10) { Cvar.Set("fov", "10"); } if (_Fov.Value > 170) { Cvar.Set("fov", "170"); } // intermission is always full screen float size; if (Client.cl.intermission > 0) { size = 120; } else { size = _ViewSize.Value; } if (size >= 120) { Sbar.Lines = 0; // no status bar at all } else if (size >= 110) { Sbar.Lines = 24; // no inventory } else { Sbar.Lines = 24 + 16 + 8; } bool full = false; if (_ViewSize.Value >= 100.0) { full = true; size = 100.0f; } else { size = _ViewSize.Value; } if (Client.cl.intermission > 0) { full = true; size = 100; Sbar.Lines = 0; } size /= 100.0f; int h = _VidDef.height - Sbar.Lines; refdef_t rdef = Render.RefDef; rdef.vrect.width = (int)(_VidDef.width * size); if (rdef.vrect.width < 96) { size = 96.0f / rdef.vrect.width; rdef.vrect.width = 96; // min for icons } rdef.vrect.height = (int)(_VidDef.height * size); if (rdef.vrect.height > _VidDef.height - Sbar.Lines) { rdef.vrect.height = _VidDef.height - Sbar.Lines; } if (rdef.vrect.height > _VidDef.height) { rdef.vrect.height = _VidDef.height; } rdef.vrect.x = (_VidDef.width - rdef.vrect.width) / 2; if (full) { rdef.vrect.y = 0; } else { rdef.vrect.y = (h - rdef.vrect.height) / 2; } rdef.fov_x = _Fov.Value; rdef.fov_y = CalcFov(rdef.fov_x, rdef.vrect.width, rdef.vrect.height); _VRect = rdef.vrect; }
/// <summary> /// SV_SpawnServer /// </summary> public static void SpawnServer(string server) { // let's not have any servers with no name if (String.IsNullOrEmpty(Net.HostName)) { Cvar.Set("hostname", "UNNAMED"); } Scr.CenterTimeOff = 0; Con.DPrint("SpawnServer: {0}\n", server); svs.changelevel_issued = false; // now safe to issue another // // tell all connected clients that we are going to a new level // if (sv.active) { SendReconnect(); } // // make cvars consistant // if (Host.IsCoop) { Cvar.Set("deathmatch", 0); } Host.CurrentSkill = (int)(Host.Skill + 0.5); if (Host.CurrentSkill < 0) { Host.CurrentSkill = 0; } if (Host.CurrentSkill > 3) { Host.CurrentSkill = 3; } Cvar.Set("skill", (float)Host.CurrentSkill); // // set up the new server // Host.ClearMemory(); sv.Clear(); sv.name = server; // load progs to get entity field count Progs.LoadProgs(); // allocate server memory sv.max_edicts = QDef.MAX_EDICTS; sv.edicts = new edict_t[sv.max_edicts]; for (int i = 0; i < sv.edicts.Length; i++) { sv.edicts[i] = new edict_t(); } // leave slots at start for clients only sv.num_edicts = svs.maxclients + 1; edict_t ent; for (int i = 0; i < svs.maxclients; i++) { ent = EdictNum(i + 1); svs.clients[i].edict = ent; } sv.state = server_state_t.Loading; sv.paused = false; sv.time = 1.0; sv.modelname = String.Format("maps/{0}.bsp", server); sv.worldmodel = Mod.ForName(sv.modelname, false); if (sv.worldmodel == null) { Con.Print("Couldn't spawn server {0}\n", sv.modelname); sv.active = false; return; } sv.models[1] = sv.worldmodel; // // clear world interaction links // ClearWorld(); sv.sound_precache[0] = String.Empty; sv.model_precache[0] = String.Empty; sv.model_precache[1] = sv.modelname; for (int i = 1; i < sv.worldmodel.numsubmodels; i++) { sv.model_precache[1 + i] = _LocalModels[i]; sv.models[i + 1] = Mod.ForName(_LocalModels[i], false); } // // load the rest of the entities // ent = EdictNum(0); ent.Clear(); ent.v.model = Progs.StringOffset(sv.worldmodel.name); if (ent.v.model == -1) { ent.v.model = Progs.NewString(sv.worldmodel.name); } ent.v.modelindex = 1; // world model ent.v.solid = Solids.SOLID_BSP; ent.v.movetype = Movetypes.MOVETYPE_PUSH; if (Host.IsCoop) { Progs.GlobalStruct.coop = 1; //coop.value; } else { Progs.GlobalStruct.deathmatch = Host.Deathmatch; } int offset = Progs.NewString(sv.name); Progs.GlobalStruct.mapname = offset; // serverflags are for cross level information (sigils) Progs.GlobalStruct.serverflags = svs.serverflags; Progs.LoadFromFile(sv.worldmodel.entities); sv.active = true; // all setup is completed, any further precache statements are errors sv.state = server_state_t.Active; // run two frames to allow everything to settle Host.FrameTime = 0.1; Physics(); Physics(); // create a baseline for more efficient communications CreateBaseline(); // send serverinfo to all connected clients for (int i = 0; i < svs.maxclients; i++) { Host.HostClient = svs.clients[i]; if (Host.HostClient.active) { SendServerInfo(Host.HostClient); } } GC.Collect(); Con.DPrint("Server spawned.\n"); }
/// <summary> /// V_RenderView /// The player's clipping box goes from (-16 -16 -24) to (16 16 32) from /// the entity origin, so any view position inside that will be valid /// </summary> public static void RenderView() { if (Con.ForcedUp) { return; } // don't allow cheats in multiplayer if (Client.cl.maxclients > 1) { Cvar.Set("scr_ofsx", "0"); Cvar.Set("scr_ofsy", "0"); Cvar.Set("scr_ofsz", "0"); } if (Client.cl.intermission > 0) { // intermission / finale rendering CalcIntermissionRefDef(); } else if (!Client.cl.paused) { CalcRefDef(); } Render.PushDlights(); if (_LcdX.Value != 0) { // // render two interleaved views // viddef_t vid = Scr.vid; refdef_t rdef = Render.RefDef; vid.rowbytes <<= 1; vid.aspect *= 0.5f; rdef.viewangles.Y -= _LcdYaw.Value; rdef.vieworg -= _Right * _LcdX.Value; Render.RenderView(); // ???????? vid.buffer += vid.rowbytes>>1; Render.PushDlights(); rdef.viewangles.Y += _LcdYaw.Value * 2; rdef.vieworg += _Right * _LcdX.Value * 2; Render.RenderView(); // ????????? vid.buffer -= vid.rowbytes>>1; rdef.vrect.height <<= 1; vid.rowbytes >>= 1; vid.aspect *= 2; } else { Render.RenderView(); } }