/// <summary> /// CDAudio_GetAudioDiskInfo /// </summary> public void ReloadDiskInfo() { _IsValidDisc = false; Mci.StatusParams sp = default(Mci.StatusParams); sp.dwItem = Mci.MCI_STATUS_READY; int ret = Mci.Status(_DeviceID, Mci.MCI_STATUS, Mci.MCI_STATUS_ITEM | Mci.MCI_WAIT, ref sp); if (ret != 0) { Con.DPrint("CDAudio: drive ready test - get status failed\n"); return; } if (sp.dwReturn == 0) { Con.DPrint("CDAudio: drive not ready\n"); return; } sp.dwItem = Mci.MCI_STATUS_NUMBER_OF_TRACKS; ret = Mci.Status(_DeviceID, Mci.MCI_STATUS, Mci.MCI_STATUS_ITEM | Mci.MCI_WAIT, ref sp); if (ret != 0) { Con.DPrint("CDAudio: get tracks - status failed\n"); return; } if (sp.dwReturn < 1) { Con.DPrint("CDAudio: no music tracks\n"); return; } _IsValidDisc = true; _MaxTrack = (byte)sp.dwReturn; }
/// <summary> /// CL_SignonReply /// /// An svc_signonnum has been received, perform a client side setup /// </summary> static void SignonReply() { Con.DPrint("CL_SignonReply: {0}\n", Cls.signon); switch (Cls.signon) { case 1: Cls.message.WriteByte(Protocol.clc_stringcmd); Cls.message.WriteString("prespawn"); break; case 2: Cls.message.WriteByte(Protocol.clc_stringcmd); Cls.message.WriteString(String.Format("name \"{0}\"\n", _Name.String)); Cls.message.WriteByte(Protocol.clc_stringcmd); Cls.message.WriteString(String.Format("color {0} {1}\n", ((int)_Color.Value) >> 4, ((int)_Color.Value) & 15)); Cls.message.WriteByte(Protocol.clc_stringcmd); Cls.message.WriteString("spawn " + Cls.spawnparms); break; case 3: Cls.message.WriteByte(Protocol.clc_stringcmd); Cls.message.WriteString("begin"); Cache.Report(); // print remaining memory break; case 4: Scr.EndLoadingPlaque(); // allow normal screen updates break; } }
public void Resume() { if (!_IsEnabled) { return; } if (!_IsValidDisc) { return; } if (!_WasPlaying) { return; } Mci.PlayParams pp; pp.dwFrom = Mci.MCI_MAKE_TMSF(_PlayTrack, 0, 0, 0); pp.dwTo = Mci.MCI_MAKE_TMSF(_PlayTrack + 1, 0, 0, 0); pp.dwCallback = _Form.Handle;// (DWORD)mainwindow; int ret = Mci.Play(_DeviceID, Mci.MCI_PLAY, Mci.MCI_TO | Mci.MCI_NOTIFY, ref pp); if (ret != 0) { Con.DPrint("CDAudio: MCI_PLAY failed ({0})\n", ret); } _IsPlaying = (ret == 0); }
/// <summary> /// CL_EstablishConnection /// </summary> public static void EstablishConnection(string host) { if (Cls.state == ClientActivityState.Dedicated) { return; } if (Cls.demoplayback) { return; } Disconnect(); Cls.netcon = Net.Connect(host); if (Cls.netcon == null) { Host.Error("CL_Connect: connect failed\n"); } Con.DPrint("CL_EstablishConnection: connected to {0}\n", host); Cls.demonum = -1; // not in the demo loop now Cls.state = ClientActivityState.Connected; Cls.signon = 0; // need all the signon messages before playing }
/// <summary> /// CL_EstablishConnection /// </summary> public static void EstablishConnection(string host) { if (cls.state == cactive_t.ca_dedicated) { return; } if (cls.demoplayback) { return; } Disconnect(); cls.netcon = net.Connect(host); if (cls.netcon == null) { SharpQuake.host.Error("CL_Connect: connect failed\n"); } Con.DPrint("CL_EstablishConnection: connected to {0}\n", host); cls.demonum = -1; // not in the demo loop now cls.state = cactive_t.ca_connected; cls.signon = 0; // need all the signon messages before playing }
/// <summary> /// Host_EndGame /// </summary> public static void EndGame(string message, params object[] args) { string str = String.Format(message, args); Con.DPrint("Host_EndGame: {0}\n", str); if (Server.IsActive) { Host.ShutdownServer(false); } if (Client.cls.state == cactive_t.ca_dedicated) { Sys.Error("Host_EndGame: {0}\n", str); // dedicated servers exit } if (Client.cls.demonum != -1) { Client.NextDemo(); } else { Client.Disconnect(); } throw new EndGameException(); //longjmp (host_abortserver, 1); }
public void UnlockBuffer(int bytes) { int processed; AL.GetSource(_Source, ALGetSourcei.BuffersProcessed, out processed); if (processed > 0) { int[] bufs = AL.SourceUnqueueBuffers(_Source, processed); foreach (int buffer in bufs) { if (buffer == 0) { continue; } int idx = Array.IndexOf(_Buffers, buffer); if (idx != -1) { _SamplesSent += _BufferBytes[idx] >> ((Sound.shm.samplebits / 8) - 1); _SamplesSent &= (Sound.shm.samples - 1); _BufferBytes[idx] = 0; } if (!_FreeBuffers.Contains(buffer)) { _FreeBuffers.Enqueue(buffer); } } } if (_FreeBuffers.Count == 0) { Con.DPrint("UnlockBuffer: No free buffers!\n"); return; } int buf = _FreeBuffers.Dequeue(); if (buf != 0) { AL.BufferData(buf, _BufferFormat, Sound.shm.buffer, bytes, Sound.shm.speed); AL.SourceQueueBuffer(_Source, buf); int idx = Array.IndexOf(_Buffers, buf); if (idx != -1) { _BufferBytes[idx] = bytes; } int state; AL.GetSource(_Source, ALGetSourcei.SourceState, out state); if ((ALSourceState)state != ALSourceState.Playing) { AL.SourcePlay(_Source); Con.DPrint("Sound resumed from {0}, free {1} of {2} buffers\n", ((ALSourceState)state).ToString("F"), _FreeBuffers.Count, _Buffers.Length); } } }
public static void Init(quakeparms_t parms) { _Params = parms; Cache.Init(1024 * 1024 * 16); // debug Cbuf.Init(); Cmd.Init(); View.Init(); Chase.Init(); InitVCR(parms); Common.Init(parms.basedir, parms.argv); InitLocal(); Wad.LoadWadFile("gfx.wad"); Key.Init(); Con.Init(); Menu.Init(); Progs.Init(); Mod.Init(); Net.Init(); Server.Init(); //Con.Print("Exe: "__TIME__" "__DATE__"\n"); //Con.Print("%4.1f megabyte heap\n",parms->memsize/ (1024*1024.0)); Render.InitTextures(); // needed even for dedicated servers if (Client.Cls.state != ClientActivityState.Dedicated) { _BasePal = Common.LoadFile("gfx/palette.lmp"); if (_BasePal == null) { Sys.Error("Couldn't load gfx/palette.lmp"); } _ColorMap = Common.LoadFile("gfx/colormap.lmp"); if (_ColorMap == null) { Sys.Error("Couldn't load gfx/colormap.lmp"); } // on non win32, mouse comes before video for security reasons Input.Init(); Vid.Init(_BasePal); Drawer.Init(); Scr.Init(); Render.Init(); Sound.Init(); CDAudio.Init(); Sbar.Init(); Client.Init(); } Cbuf.InsertText("exec quake.rc\n"); _IsInitialized = true; Con.DPrint("========Quake Initialized=========\n"); }
public void Edject() { int ret = Mci.SendCommand(_DeviceID, Mci.MCI_SET, Mci.MCI_SET_DOOR_OPEN, IntPtr.Zero); if (ret != 0) { Con.DPrint("MCI_SET_DOOR_OPEN failed ({0})\n", ret); } }
public void CloseDoor() { int ret = Mci.SendCommand(_DeviceID, Mci.MCI_SET, Mci.MCI_SET_DOOR_CLOSED, IntPtr.Zero); if (ret != 0) { Con.DPrint("MCI_SET_DOOR_CLOSED failed ({0})\n", ret); } }
static int Main(string[] args) { #if !DEBUG try { #endif // select display device _DisplayDevice = DisplayDevice.Default; if (File.Exists(DumpFilePath)) { File.Delete(DumpFilePath); } quakeparms_t parms = new quakeparms_t(); parms.basedir = Application.StartupPath; string[] args2 = new string[args.Length + 1]; args2[0] = String.Empty; args.CopyTo(args2, 1); Common.InitArgv(args2); parms.argv = new string[Common.Argc]; Common.Args.CopyTo(parms.argv, 0); if (Common.HasParam("-dedicated")) { throw new QuakeException("Dedicated server mode not supported!"); } Size size = new Size(640, 480); GraphicsMode mode = new GraphicsMode(); bool fullScreen = false; using (MainForm form = MainForm.CreateInstance(size, mode, fullScreen)) { Con.DPrint("Host.Init\n"); Host.Init(parms); form.Run(); } Host.Shutdown(); #if !DEBUG } catch (QuakeSystemError se) { HandleException(se); } catch (Exception ex) { HandleException(ex); } #endif return(0); // all Ok }
/// <summary> /// SV_DropClient /// Called when the player is getting totally kicked off the host /// if (crash = true), don't bother sending signofs /// </summary> public static void DropClient(bool crash) { client_t client = host.HostClient; if (!crash) { // send any final messages (don't check for errors) if (net.CanSendMessage(client.netconnection)) { MsgWriter msg = client.message; msg.WriteByte(protocol.svc_disconnect); net.SendMessage(client.netconnection, msg); } if (client.edict != null && client.spawned) { // call the prog function for removing a client // this will set the body to a dead frame, among other things int saveSelf = progs.GlobalStruct.self; progs.GlobalStruct.self = EdictToProg(client.edict); progs.Execute(progs.GlobalStruct.ClientDisconnect); progs.GlobalStruct.self = saveSelf; } Con.DPrint("Client {0} removed\n", client.name); } // break the net connection net.Close(client.netconnection); client.netconnection = null; // free the client (the body stays around) client.active = false; client.name = null; client.old_frags = -999999; net.ActiveConnections--; // send notification to all clients for (int i = 0; i < SharpQuake.server.svs.maxclients; i++) { client_t cl = SharpQuake.server.svs.clients[i]; if (!cl.active) { continue; } cl.message.WriteByte(protocol.svc_updatename); cl.message.WriteByte(host.ClientNum); cl.message.WriteString(""); cl.message.WriteByte(protocol.svc_updatefrags); cl.message.WriteByte(host.ClientNum); cl.message.WriteShort(0); cl.message.WriteByte(protocol.svc_updatecolors); cl.message.WriteByte(host.ClientNum); cl.message.WriteByte(0); } }
/// <summary> /// Host_ClearMemory /// </summary> public static void ClearMemory() { Con.DPrint("Clearing memory\n"); Mod.ClearAll(); Client.cls.signon = 0; Server.sv.Clear(); Client.cl.Clear(); }
public static void Init(quakeparms_t parms) { _Params = parms; Cache.Init(1024 * 1024 * 512); // debug Cbuf.Init(); cmd.Init(); view.Init(); chase.Init(); InitVCR(parms); common.Init(parms.basedir, parms.argv); InitLocal(); wad.LoadWadFile("gfx.wad"); Key.Init(); Con.Init(); menu.Init(); progs.Init(); Mod.Init(); net.Init(); server.Init(); //Con.Print("Exe: "__TIME__" "__DATE__"\n"); //Con.Print("%4.1f megabyte heap\n",parms->memsize/ (1024*1024.0)); render.InitTextures(); // needed even for dedicated servers if (client.cls.state != cactive_t.ca_dedicated) { _BasePal = common.LoadFile("gfx/palette.lmp"); if (_BasePal == null) { sys.Error("Couldn't load gfx/palette.lmp"); } _ColorMap = common.LoadFile("gfx/colormap.lmp"); if (_ColorMap == null) { sys.Error("Couldn't load gfx/colormap.lmp"); } // on non win32, mouse comes before video for security reasons input.Init(); vid.Init(_BasePal); Drawer.Init(); Scr.Init(); render.Init(); snd.Init(); cd_audio.Init(); sbar.Init(); client.Init(); } Cbuf.InsertText("exec quake.rc\n"); _IsInitialized = true; Con.DPrint("========Quake Initialized=========\n"); }
// CL_SendCmd public static void SendCmd() { if (Cls.state != ClientActivityState.Connected) { return; } if (Cls.signon == SIGNONS) { UserCommand cmd = new UserCommand(); // get basic movement from keyboard BaseMove(ref cmd); // allow mice or other external controllers to add to the move Input.Move(cmd); // send the unreliable message Client.SendMove(ref cmd); } if (Cls.demoplayback) { Cls.message.Clear();// SZ_Clear (cls.message); return; } // send the reliable message if (Cls.message.IsEmpty) { return; // no message at all } if (!Net.CanSendMessage(Cls.netcon)) { Con.DPrint("CL_WriteToServer: can't send\n"); return; } if (Net.SendMessage(Cls.netcon, Cls.message) == -1) { Host.Error("CL_WriteToServer: lost server connection"); } Cls.message.Clear(); }
// CL_SendCmd public static void SendCmd() { if (cls.state != cactive_t.ca_connected) { return; } if (cls.signon == SIGNONS) { usercmd_t cmd = new usercmd_t(); // get basic movement from keyboard BaseMove(ref cmd); // allow mice or other external controllers to add to the move input.Move(cmd); // send the unreliable message client.SendMove(ref cmd); } if (cls.demoplayback) { cls.message.Clear();// SZ_Clear (cls.message); return; } // send the reliable message if (cls.message.IsEmpty) { return; // no message at all } if (!net.CanSendMessage(cls.netcon)) { Con.DPrint("CL_WriteToServer: can't send\n"); return; } if (net.SendMessage(cls.netcon, cls.message) == -1) { host.Error("CL_WriteToServer: lost server connection"); } cls.message.Clear(); }
private int MapKey(OpenTK.Input.Key srcKey) { int key = (int)srcKey; key &= 255; if (key >= _KeyTable.Length) { return(0); } if (_KeyTable[key] == 0) { Con.DPrint("key 0x{0:X} has no translation\n", key); } return(_KeyTable[key]); }
public void Shutdown() { if (_Form != null) { _Form.Dispose(); _Form = null; } if (!_IsInitialized) { return; } Stop(); if (Mci.SendCommand(_DeviceID, Mci.MCI_CLOSE, Mci.MCI_WAIT, IntPtr.Zero) != 0) { Con.DPrint("CDAudio_Shutdown: MCI_CLOSE failed\n"); } }
/// <summary> /// SV_ConnectClient /// Initializes a client_t for a new net connection. This will only be called /// once for a player each game, not once for each level change. /// </summary> private static void ConnectClient(int clientnum) { client_t client = svs.clients[clientnum]; Con.DPrint("Client {0} connected\n", client.netconnection.address); int edictnum = clientnum + 1; edict_t ent = EdictNum(edictnum); // set up the client_t qsocket_t netconnection = client.netconnection; float[] spawn_parms = new float[NUM_SPAWN_PARMS]; if (sv.loadgame) { Array.Copy(client.spawn_parms, spawn_parms, spawn_parms.Length); } client.Clear(); client.netconnection = netconnection; client.name = "unconnected"; client.active = true; client.spawned = false; client.edict = ent; client.message.AllowOverflow = true; // we can catch it client.privileged = false; if (sv.loadgame) { Array.Copy(spawn_parms, client.spawn_parms, spawn_parms.Length); } else { // call the progs to get default spawn parms for the new client progs.Execute(progs.GlobalStruct.SetNewParms); AssignGlobalSpawnparams(client); } SendServerInfo(client); }
/// <summary> /// SV_CheckStuck /// This is a big hack to try and fix the rare case of getting stuck in the world /// clipping hull. /// </summary> private static void CheckStuck(edict_t ent) { if (TestEntityPosition(ent) == null) { ent.v.oldorigin = ent.v.origin; return; } v3f org = ent.v.origin; ent.v.origin = ent.v.oldorigin; if (TestEntityPosition(ent) == null) { Con.DPrint("Unstuck.\n"); LinkEdict(ent, true); return; } for (int z = 0; z < 18; z++) { for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { ent.v.origin.x = org.x + i; ent.v.origin.y = org.y + j; ent.v.origin.z = org.z + z; if (TestEntityPosition(ent) == null) { Con.DPrint("Unstuck.\n"); LinkEdict(ent, true); return; } } } } ent.v.origin = org; Con.DPrint("player is stuck.\n"); }
public void Stop() { if (!_IsEnabled) { return; } if (!_IsPlaying) { return; } int ret = Mci.SendCommand(_DeviceID, Mci.MCI_STOP, 0, IntPtr.Zero); if (ret != 0) { Con.DPrint("MCI_STOP failed ({0})", ret); } _WasPlaying = false; _IsPlaying = false; }
public void Pause() { if (!_IsEnabled) { return; } if (!_IsPlaying) { return; } Mci.GenericParams gp = default(Mci.GenericParams); int ret = Mci.SendCommand(_DeviceID, Mci.MCI_PAUSE, 0, ref gp); if (ret != 0) { Con.DPrint("MCI_PAUSE failed ({0})", ret); } _WasPlaying = _IsPlaying; _IsPlaying = false; }
/// <summary> /// CL_Disconnect /// /// Sends a disconnect message to the server /// This is also called on Host_Error, so it shouldn't cause any errors /// </summary> public static void Disconnect() { // stop sounds (especially looping!) Sound.StopAllSounds(true); // bring the console down and fade the colors back to normal // SCR_BringDownConsole (); // if running a local server, shut it down if (Cls.demoplayback) { StopPlayback(); } else if (Cls.state == ClientActivityState.Connected) { if (Cls.demorecording) { Stop_f(); } Con.DPrint("Sending clc_disconnect\n"); Cls.message.Clear(); Cls.message.WriteByte(Protocol.clc_disconnect); Net.SendUnreliableMessage(Cls.netcon, Cls.message); Cls.message.Clear(); Net.Close(Cls.netcon); Cls.state = ClientActivityState.Disconnected; if (Server.sv.active) { Host.ShutdownServer(false); } } Cls.demoplayback = Cls.timedemo = false; Cls.signon = 0; }
public void MessageHandler(ref Message m) { if (m.LParam != _DeviceID) { return; } switch (m.WParam.ToInt32()) { case Mci.MCI_NOTIFY_SUCCESSFUL: if (_IsPlaying) { _IsPlaying = false; if (_IsLooping) { Play(_PlayTrack, true); } } break; case Mci.MCI_NOTIFY_ABORTED: case Mci.MCI_NOTIFY_SUPERSEDED: break; case Mci.MCI_NOTIFY_FAILURE: Con.DPrint("MCI_NOTIFY_FAILURE\n"); Stop(); _IsValidDisc = false; break; default: Con.DPrint("Unexpected MM_MCINOTIFY type ({0})\n", m.WParam); m.Result = new IntPtr(1); break; } }
/// <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> /// 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); }
// NET_Init (void) public static void Init() { for (int i2 = 0; i2 < _HostCache.Length; i2++) { _HostCache[i2] = new hostcache_t(); } if (_Drivers == null) { if (Common.HasParam("-playback")) { _Drivers = new INetDriver[] { new NetVcr() }; } else { _Drivers = new INetDriver[] { new NetLoop(), NetDatagram.Instance }; } } if (_LanDrivers == null) { _LanDrivers = new INetLanDriver[] { NetTcpIp.Instance }; } if (Common.HasParam("-record")) { _IsRecording = true; } int i = Common.CheckParm("-port"); if (i == 0) { i = Common.CheckParm("-udpport"); } if (i == 0) { i = Common.CheckParm("-ipxport"); } if (i > 0) { if (i < Common.Argc - 1) { _DefHostPort = Common.atoi(Common.Argv(i + 1)); } else { Sys.Error("Net.Init: you must specify a number after -port!"); } } HostPort = _DefHostPort; if (Common.HasParam("-listen") || Client.cls.state == cactive_t.ca_dedicated) { _IsListening = true; } int numsockets = Server.svs.maxclientslimit; if (Client.cls.state != cactive_t.ca_dedicated) { numsockets++; } _FreeSockets = new List <qsocket_t>(numsockets); _ActiveSockets = new List <qsocket_t>(numsockets); for (i = 0; i < numsockets; i++) { _FreeSockets.Add(new qsocket_t()); } SetNetTime(); // allocate space for network message buffer Message = new MsgWriter(NET_MAXMESSAGE); // SZ_Alloc (&net_message, NET_MAXMESSAGE); Reader = new MsgReader(Net.Message); if (_MessageTimeout == null) { _MessageTimeout = new Cvar("net_messagetimeout", "300"); _HostName = new Cvar("hostname", "UNNAMED"); } Cmd.Add("slist", Slist_f); Cmd.Add("listen", Listen_f); Cmd.Add("maxplayers", MaxPlayers_f); Cmd.Add("port", Port_f); // initialize all the drivers _DriverLevel = 0; foreach (INetDriver driver in _Drivers) { driver.Init(); if (driver.IsInitialized && _IsListening) { driver.Listen(true); } _DriverLevel++; } //if (*my_ipx_address) // Con_DPrintf("IPX address %s\n", my_ipx_address); if (!String.IsNullOrEmpty(_MyTcpIpAddress)) { Con.DPrint("TCP/IP address {0}\n", _MyTcpIpAddress); } }
/// <summary> /// Host_Spawn_f /// </summary> private static void Spawn_f() { if (Cmd.Source == cmd_source_t.src_command) { Con.Print("spawn is not valid from the console\n"); return; } if (Host.HostClient.spawned) { Con.Print("Spawn not valid -- allready spawned\n"); return; } edict_t ent; // run the entrance script if (Server.sv.loadgame) { // loaded games are fully inited allready // if this is the last client to be connected, unpause Server.sv.paused = false; } else { // set up the edict ent = Host.HostClient.edict; ent.Clear(); //memset(&ent.v, 0, progs.entityfields * 4); ent.v.colormap = Server.NumForEdict(ent); ent.v.team = (Host.HostClient.colors & 15) + 1; ent.v.netname = Progs.NewString(Host.HostClient.name); // copy spawn parms out of the client_t Progs.GlobalStruct.SetParams(Host.HostClient.spawn_parms); // call the spawn function Progs.GlobalStruct.time = (float)Server.sv.time; Progs.GlobalStruct.self = Server.EdictToProg(Server.Player); Progs.Execute(Progs.GlobalStruct.ClientConnect); if ((Sys.GetFloatTime() - Host.HostClient.netconnection.connecttime) <= Server.sv.time) { Con.DPrint("{0} entered the game\n", Host.HostClient.name); } Progs.Execute(Progs.GlobalStruct.PutClientInServer); } // send all current names, colors, and frag counts MsgWriter msg = Host.HostClient.message; msg.Clear(); // send time of update msg.WriteByte(Protocol.svc_time); msg.WriteFloat((float)Server.sv.time); for (int i = 0; i < Server.svs.maxclients; i++) { client_t client = Server.svs.clients[i]; msg.WriteByte(Protocol.svc_updatename); msg.WriteByte(i); msg.WriteString(client.name); msg.WriteByte(Protocol.svc_updatefrags); msg.WriteByte(i); msg.WriteShort(client.old_frags); msg.WriteByte(Protocol.svc_updatecolors); msg.WriteByte(i); msg.WriteByte(client.colors); } // send all current light styles for (int i = 0; i < QDef.MAX_LIGHTSTYLES; i++) { msg.WriteByte(Protocol.svc_lightstyle); msg.WriteByte((char)i); msg.WriteString(Server.sv.lightstyles[i]); } // // send some stats // msg.WriteByte(Protocol.svc_updatestat); msg.WriteByte(QStats.STAT_TOTALSECRETS); msg.WriteLong((int)Progs.GlobalStruct.total_secrets); msg.WriteByte(Protocol.svc_updatestat); msg.WriteByte(QStats.STAT_TOTALMONSTERS); msg.WriteLong((int)Progs.GlobalStruct.total_monsters); msg.WriteByte(Protocol.svc_updatestat); msg.WriteByte(QStats.STAT_SECRETS); msg.WriteLong((int)Progs.GlobalStruct.found_secrets); msg.WriteByte(Protocol.svc_updatestat); msg.WriteByte(QStats.STAT_MONSTERS); msg.WriteLong((int)Progs.GlobalStruct.killed_monsters); // // send a fixangle // Never send a roll angle, because savegames can catch the server // in a state where it is expecting the client to correct the angle // and it won't happen if the game was just loaded, so you wind up // with a permanent head tilt ent = Server.EdictNum(1 + Host.ClientNum); msg.WriteByte(Protocol.svc_setangle); msg.WriteAngle(ent.v.angles.x); msg.WriteAngle(ent.v.angles.y); msg.WriteAngle(0); Server.WriteClientDataToMessage(Server.Player, Host.HostClient.message); msg.WriteByte(Protocol.svc_signonnum); msg.WriteByte(3); Host.HostClient.sendsignon = true; }
/// <summary> /// ED_LoadFromFile /// The entities are directly placed in the array, rather than allocated with /// ED_Alloc, because otherwise an error loading the map would have entity /// number references out of order. /// /// Creates a server's entity / program execution context by /// parsing textual entity definitions out of an ent file. /// /// Used for both fresh maps and savegame loads. A fresh map would also need /// to call ED_CallSpawnFunctions () to let the objects initialize themselves. /// </summary> public static void LoadFromFile(string data) { edict_t ent = null; int inhibit = 0; Progs.GlobalStruct.time = (float)Server.sv.time; // parse ents while (true) { // parse the opening brace data = Common.Parse(data); if (data == null) { break; } if (Common.Token != "{") { Sys.Error("ED_LoadFromFile: found {0} when expecting {", Common.Token); } if (ent == null) { ent = Server.EdictNum(0); } else { ent = Server.AllocEdict(); } data = ParseEdict(data, ent); // remove things from different skill levels or deathmatch if (Host.Deathmatch != 0) { if (((int)ent.v.spawnflags & SpawnFlags.SPAWNFLAG_NOT_DEATHMATCH) != 0) { Server.FreeEdict(ent); inhibit++; continue; } } else if ((Host.CurrentSkill == 0 && ((int)ent.v.spawnflags & SpawnFlags.SPAWNFLAG_NOT_EASY) != 0) || (Host.CurrentSkill == 1 && ((int)ent.v.spawnflags & SpawnFlags.SPAWNFLAG_NOT_MEDIUM) != 0) || (Host.CurrentSkill >= 2 && ((int)ent.v.spawnflags & SpawnFlags.SPAWNFLAG_NOT_HARD) != 0)) { Server.FreeEdict(ent); inhibit++; continue; } // // immediately call spawn function // if (ent.v.classname == 0) { Con.Print("No classname for:\n"); Print(ent); Server.FreeEdict(ent); continue; } // look for the spawn function int func = IndexOfFunction(GetString(ent.v.classname)); if (func == -1) { Con.Print("No spawn function for:\n"); Print(ent); Server.FreeEdict(ent); continue; } Progs.GlobalStruct.self = Server.EdictToProg(ent); Execute(func); } Con.DPrint("{0} entities inhibited\n", inhibit); }
/// <summary> /// PR_LoadProgs /// </summary> public static void LoadProgs() { FreeHandles(); QBuiltins.ClearState(); _DynamicStrings.Clear(); // flush the non-C variable lookup cache for (int i = 0; i < GEFV_CACHESIZE; i++) { _gefvCache[i].field = null; } CRC.Init(out _Crc); byte[] buf = Common.LoadFile("progs.dat"); _Progs = Sys.BytesToStructure <dprograms_t>(buf, 0); if (_Progs == null) { Sys.Error("PR_LoadProgs: couldn't load progs.dat"); } Con.DPrint("Programs occupy {0}K.\n", buf.Length / 1024); for (int i = 0; i < buf.Length; i++) { CRC.ProcessByte(ref _Crc, buf[i]); } // byte swap the header _Progs.SwapBytes(); if (_Progs.version != PROG_VERSION) { Sys.Error("progs.dat has wrong version number ({0} should be {1})", _Progs.version, PROG_VERSION); } if (_Progs.crc != PROGHEADER_CRC) { Sys.Error("progs.dat system vars have been modified, progdefs.h is out of date"); } // Functions _Functions = new dfunction_t[_Progs.numfunctions]; int offset = _Progs.ofs_functions; for (int i = 0; i < _Functions.Length; i++, offset += dfunction_t.SizeInBytes) { _Functions[i] = Sys.BytesToStructure <dfunction_t>(buf, offset); _Functions[i].SwapBytes(); } // strings offset = _Progs.ofs_strings; int str0 = offset; for (int i = 0; i < _Progs.numstrings; i++, offset++) { // count string length while (buf[offset] != 0) { offset++; } } int length = offset - str0; _Strings = Encoding.ASCII.GetString(buf, str0, length); // Globaldefs _GlobalDefs = new ddef_t[_Progs.numglobaldefs]; offset = _Progs.ofs_globaldefs; for (int i = 0; i < _GlobalDefs.Length; i++, offset += ddef_t.SizeInBytes) { _GlobalDefs[i] = Sys.BytesToStructure <ddef_t>(buf, offset); _GlobalDefs[i].SwapBytes(); } // Fielddefs _FieldDefs = new ddef_t[_Progs.numfielddefs]; offset = _Progs.ofs_fielddefs; for (int i = 0; i < _FieldDefs.Length; i++, offset += ddef_t.SizeInBytes) { _FieldDefs[i] = Sys.BytesToStructure <ddef_t>(buf, offset); _FieldDefs[i].SwapBytes(); if ((_FieldDefs[i].type & DEF_SAVEGLOBAL) != 0) { Sys.Error("PR_LoadProgs: pr_fielddefs[i].type & DEF_SAVEGLOBAL"); } } // Statements _Statements = new dstatement_t[_Progs.numstatements]; offset = _Progs.ofs_statements; for (int i = 0; i < _Statements.Length; i++, offset += dstatement_t.SizeInBytes) { _Statements[i] = Sys.BytesToStructure <dstatement_t>(buf, offset); _Statements[i].SwapBytes(); } // Swap bytes inplace if needed if (!BitConverter.IsLittleEndian) { offset = _Progs.ofs_globals; for (int i = 0; i < _Progs.numglobals; i++, offset += 4) { SwapHelper.Swap4b(buf, offset); } } GlobalStruct = Sys.BytesToStructure <globalvars_t>(buf, _Progs.ofs_globals); _Globals = new float[_Progs.numglobals - globalvars_t.SizeInBytes / 4]; Buffer.BlockCopy(buf, _Progs.ofs_globals + globalvars_t.SizeInBytes, _Globals, 0, _Globals.Length * 4); _EdictSize = _Progs.entityfields * 4 + dedict_t.SizeInBytes - entvars_t.SizeInBytes; _HGlobals = GCHandle.Alloc(_Globals, GCHandleType.Pinned); _GlobalsAddr = _HGlobals.AddrOfPinnedObject().ToInt64(); _HGlobalStruct = GCHandle.Alloc(Progs.GlobalStruct, GCHandleType.Pinned); _GlobalStructAddr = _HGlobalStruct.AddrOfPinnedObject().ToInt64(); }