/// <summary> /// CL_Record_f /// record <demoname> <map> [cd track] /// </summary> static void Record_f() { if (Cmd.Source != cmd_source_t.src_command) { return; } int c = Cmd.Argc; if (c != 2 && c != 3 && c != 4) { Con.Print("record <demoname> [<map> [cd track]]\n"); return; } if (Cmd.Argv(1).Contains("..")) { Con.Print("Relative pathnames are not allowed.\n"); return; } if (c == 2 && Cls.state == ClientActivityState.Connected) { Con.Print("Can not record - already connected to server\nClient demo recording must be started before connecting\n"); return; } // write the forced cd track number, or -1 int track; if (c == 4) { track = Common.atoi(Cmd.Argv(3)); Con.Print("Forcing CD track to {0}\n", track); } else { track = -1; } string name = Path.Combine(Common.GameDir, Cmd.Argv(1)); // // start the map up // if (c > 2) { Cmd.ExecuteString(String.Format("map {0}", Cmd.Argv(2)), cmd_source_t.src_command); } // // open the demo file // name = Path.ChangeExtension(name, ".dem"); Con.Print("recording to {0}.\n", name); FileStream fs = Sys.FileOpenWrite(name, true); if (fs == null) { Con.Print("ERROR: couldn't open.\n"); return; } BinaryWriter writer = new BinaryWriter(fs, Encoding.ASCII); Cls.demofile = new DisposableWrapper <BinaryWriter>(writer, true); Cls.forcetrack = track; byte[] tmp = Encoding.ASCII.GetBytes(Cls.forcetrack.ToString()); writer.Write(tmp); writer.Write('\n'); Cls.demorecording = true; }
// hostcache // hostCacheCount /// <summary> /// NET_Connect /// called by client to connect to a host. Returns -1 if not able to connect /// </summary> public static qsocket_t Connect(string host) { int numdrivers = _Drivers.Length;// net_numdrivers; SetNetTime(); if (String.IsNullOrEmpty(host)) { host = null; } if (host != null) { if (Common.SameText(host, "local")) { numdrivers = 1; goto JustDoIt; } if (HostCacheCount > 0) { foreach (hostcache_t hc in _HostCache) { if (Common.SameText(hc.name, host)) { host = hc.cname; goto JustDoIt; } } } } SlistSilent = (host != null); Slist_f(); while (_SlistInProgress) { Poll(); } if (host == null) { if (HostCacheCount != 1) { return(null); } host = _HostCache[0].cname; Con.Print("Connecting to...\n{0} @ {1}\n\n", _HostCache[0].name, host); } _DriverLevel = 0; foreach (hostcache_t hc in _HostCache) { if (Common.SameText(host, hc.name)) { host = hc.cname; break; } _DriverLevel++; } JustDoIt: _DriverLevel = 0; foreach (INetDriver drv in _Drivers) { if (!drv.IsInitialized) { continue; } qsocket_t ret = drv.Connect(host); if (ret != null) { return(ret); } _DriverLevel++; } if (host != null) { Con.Print("\n"); PrintSlistHeader(); PrintSlist(); PrintSlistTrailer(); } return(null); }
/// <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> /// BuildTris /// Generate a list of trifans or strips for the model, which holds for all frames /// </summary> private static void BuildTris() { int[] bestverts = new int[1024]; int[] besttris = new int[1024]; // Uze // All references to pheader from model.c changed to _AliasHdr (former paliashdr) // // build tristrips // stvert_t[] stverts = Mod.STVerts; dtriangle_t[] triangles = Mod.Triangles; _NumOrder = 0; _NumCommands = 0; Array.Clear(_Used, 0, _Used.Length); // memset (used, 0, sizeof(used)); int besttype = 0, len; for (int i = 0; i < _AliasHdr.numtris; i++) { // pick an unused triangle and start the trifan if (_Used[i] != 0) { continue; } int bestlen = 0; for (int type = 0; type < 2; type++) { for (int startv = 0; startv < 3; startv++) { if (type == 1) { len = StripLength(i, startv); } else { len = FanLength(i, startv); } if (len > bestlen) { besttype = type; bestlen = len; for (int j = 0; j < bestlen + 2; j++) { bestverts[j] = _StripVerts[j]; } for (int j = 0; j < bestlen; j++) { besttris[j] = _StripTris[j]; } } } } // mark the tris on the best strip as used for (int j = 0; j < bestlen; j++) { _Used[besttris[j]] = 1; } if (besttype == 1) { _Commands[_NumCommands++] = (bestlen + 2); } else { _Commands[_NumCommands++] = -(bestlen + 2); } Union4b uval = Union4b.Empty; for (int j = 0; j < bestlen + 2; j++) { // emit a vertex into the reorder buffer int k = bestverts[j]; _VertexOrder[_NumOrder++] = k; // emit s/t coords into the commands stream float s = stverts[k].s; float t = stverts[k].t; if (triangles[besttris[0]].facesfront == 0 && stverts[k].onseam != 0) { s += _AliasHdr.skinwidth / 2; // on back side } s = (s + 0.5f) / _AliasHdr.skinwidth; t = (t + 0.5f) / _AliasHdr.skinheight; uval.f0 = s; _Commands[_NumCommands++] = uval.i0; uval.f0 = t; _Commands[_NumCommands++] = uval.i0; } } _Commands[_NumCommands++] = 0; // end of list marker Con.DPrint("{0,3} tri {1,3} vert {2,3} cmd\n", _AliasHdr.numtris, _NumOrder, _NumCommands); _AllVerts += _NumOrder; _AllTris += _AliasHdr.numtris; }
// pollProcedureList private static void PrintSlistHeader() { Con.Print("Server Map Users\n"); Con.Print("--------------- --------------- -----\n"); _SlistLastShown = 0; }
/// <summary> /// Host_Savegame_f /// </summary> private static void Savegame_f() { if (cmd.Source != cmd_source_t.src_command) { return; } if (!server.sv.active) { Con.Print("Not playing a local game.\n"); return; } if (client.cl.intermission != 0) { Con.Print("Can't save in intermission.\n"); return; } if (server.svs.maxclients != 1) { Con.Print("Can't save multiplayer games.\n"); return; } if (cmd.Argc != 2) { Con.Print("save <savename> : save a game\n"); return; } if (cmd.Argv(1).Contains("..")) { Con.Print("Relative pathnames are not allowed.\n"); return; } for (int i = 0; i < server.svs.maxclients; i++) { if (server.svs.clients[i].active && (server.svs.clients[i].edict.v.health <= 0)) { Con.Print("Can't savegame with a dead player\n"); return; } } string name = Path.ChangeExtension(Path.Combine(common.GameDir, cmd.Argv(1)), ".sav"); Con.Print("Saving game to {0}...\n", name); FileStream fs = sys.FileOpenWrite(name, true); if (fs == null) { Con.Print("ERROR: couldn't open.\n"); return; } using (StreamWriter writer = new StreamWriter(fs, Encoding.ASCII)) { writer.WriteLine(SAVEGAME_VERSION); writer.WriteLine(SavegameComment()); for (int i = 0; i < server.NUM_SPAWN_PARMS; i++) { writer.WriteLine(server.svs.clients[0].spawn_parms[i].ToString("F6", CultureInfo.InvariantCulture.NumberFormat)); } writer.WriteLine(host.CurrentSkill); writer.WriteLine(server.sv.name); writer.WriteLine(server.sv.time.ToString("F6", CultureInfo.InvariantCulture.NumberFormat)); // write the light styles for (int i = 0; i < QDef.MAX_LIGHTSTYLES; i++) { if (!String.IsNullOrEmpty(server.sv.lightstyles[i])) { writer.WriteLine(server.sv.lightstyles[i]); } else { writer.WriteLine("m"); } } progs.WriteGlobals(writer); for (int i = 0; i < server.sv.num_edicts; i++) { progs.WriteEdict(writer, server.EdictNum(i)); writer.Flush(); } } Con.Print("done.\n"); }
// Host_Version_f private static void Version_f() { Con.Print("Version {0}\n", QDef.VERSION); Con.Print("Exe hash code: {0}\n", System.Reflection.Assembly.GetExecutingAssembly().GetHashCode()); }
/* * ========= * PF_dprint * ========= */ static void PF_dprint() { Con.DPrint(PF_VarString(0)); }
/* * ================= * PF_break * * break() * ================= */ static void PF_break() { Con.Print("break statement\n"); //*(int *)-4 = 0; // dump to debugger }
static void CD_f() { if (Cmd.Argc < 2) { return; } string command = Cmd.Argv(1); if (Common.SameText(command, "on")) { _Controller.IsEnabled = true; return; } if (Common.SameText(command, "off")) { if (_Controller.IsPlaying) { _Controller.Stop(); } _Controller.IsEnabled = false; return; } if (Common.SameText(command, "reset")) { _Controller.IsEnabled = true; if (_Controller.IsPlaying) { _Controller.Stop(); } _Controller.ReloadDiskInfo(); return; } if (Common.SameText(command, "remap")) { int ret = Cmd.Argc - 2; byte[] remap = _Controller.Remap; if (ret <= 0) { for (int n = 1; n < 100; n++) { if (remap[n] != n) { Con.Print(" {0} -> {1}\n", n, remap[n]); } } return; } for (int n = 1; n <= ret; n++) { remap[n] = (byte)Common.atoi(Cmd.Argv(n + 1)); } return; } if (Common.SameText(command, "close")) { _Controller.CloseDoor(); return; } if (!_Controller.IsValidCD) { _Controller.ReloadDiskInfo(); if (!_Controller.IsValidCD) { Con.Print("No CD in player.\n"); return; } } if (Common.SameText(command, "play")) { _Controller.Play((byte)Common.atoi(Cmd.Argv(2)), false); return; } if (Common.SameText(command, "loop")) { _Controller.Play((byte)Common.atoi(Cmd.Argv(2)), true); return; } if (Common.SameText(command, "stop")) { _Controller.Stop(); return; } if (Common.SameText(command, "pause")) { _Controller.Pause(); return; } if (Common.SameText(command, "resume")) { _Controller.Resume(); return; } if (Common.SameText(command, "eject")) { if (_Controller.IsPlaying) { _Controller.Stop(); } _Controller.Edject(); return; } if (Common.SameText(command, "info")) { Con.Print("%u tracks\n", _Controller.MaxTrack); if (_Controller.IsPlaying) { Con.Print("Currently {0} track {1}\n", _Controller.IsLooping ? "looping" : "playing", _Controller.CurrentTrack); } else if (_Controller.IsPaused) { Con.Print("Paused {0} track {1}\n", _Controller.IsLooping ? "looping" : "playing", _Controller.CurrentTrack); } Con.Print("Volume is {0}\n", _Controller.Volume); return; } }
/// <summary> /// SV_ReadClientMessage /// Returns false if the client should be killed /// </summary> private static bool ReadClientMessage() { while (true) { int ret = net.GetMessage(host.HostClient.netconnection); if (ret == -1) { Con.DPrint("SV_ReadClientMessage: NET_GetMessage failed\n"); return(false); } if (ret == 0) { return(true); } net.Reader.Reset(); bool flag = true; while (flag) { if (!host.HostClient.active) { return(false); // a command caused an error } if (net.Reader.IsBadRead) { Con.DPrint("SV_ReadClientMessage: badread\n"); return(false); } int cmd = net.Reader.ReadChar(); switch (cmd) { case -1: flag = false; // end of message ret = 1; break; case protocol.clc_nop: break; case protocol.clc_stringcmd: string s = net.Reader.ReadString(); if (host.HostClient.privileged) { ret = 2; } else { ret = 0; } if (common.SameText(s, "status", 6)) { ret = 1; } else if (common.SameText(s, "god", 3)) { ret = 1; } else if (common.SameText(s, "notarget", 8)) { ret = 1; } else if (common.SameText(s, "fly", 3)) { ret = 1; } else if (common.SameText(s, "name", 4)) { ret = 1; } else if (common.SameText(s, "noclip", 6)) { ret = 1; } else if (common.SameText(s, "say", 3)) { ret = 1; } else if (common.SameText(s, "say_team", 8)) { ret = 1; } else if (common.SameText(s, "tell", 4)) { ret = 1; } else if (common.SameText(s, "color", 5)) { ret = 1; } else if (common.SameText(s, "kill", 4)) { ret = 1; } else if (common.SameText(s, "pause", 5)) { ret = 1; } else if (common.SameText(s, "spawn", 5)) { ret = 1; } else if (common.SameText(s, "begin", 5)) { ret = 1; } else if (common.SameText(s, "prespawn", 8)) { ret = 1; } else if (common.SameText(s, "kick", 4)) { ret = 1; } else if (common.SameText(s, "ping", 4)) { ret = 1; } else if (common.SameText(s, "give", 4)) { ret = 1; } else if (common.SameText(s, "ban", 3)) { ret = 1; } if (ret == 2) { Cbuf.InsertText(s); } else if (ret == 1) { SharpQuake.cmd.ExecuteString(s, cmd_source_t.src_client); } else { Con.DPrint("{0} tried to {1}\n", host.HostClient.name, s); } break; case protocol.clc_disconnect: return(false); case protocol.clc_move: ReadClientMove(ref host.HostClient.cmd); break; default: Con.DPrint("SV_ReadClientMessage: unknown command char\n"); return(false); } } if (ret != 1) { break; } } return(true); }
// GetWavinfo static wavinfo_t GetWavInfo(string name, byte[] wav) { wavinfo_t info = new wavinfo_t(); if (wav == null) { return(info); } // debug //using (FileStream fs = new FileStream(Path.GetFileName(name), FileMode.Create, FileAccess.Write, FileShare.Read)) //{ // fs.Write(wav, 0, wav.Length); //} WavHelper helper = new WavHelper(wav); int offset = 0; // find "RIFF" chunk int riff = helper.FindChunk("RIFF", offset); if (riff == -1) { Con.Print("Missing RIFF chunk\n"); return(info); } string wave = Encoding.ASCII.GetString(wav, offset + 8, 4); if (wave != "WAVE") { Con.Print("RIFF chunk is not WAVE\n"); return(info); } // get "fmt " chunk offset += 12; //iff_data = data_p + 12; int fmt = helper.FindChunk("fmt ", offset); if (fmt == -1) { Con.Print("Missing fmt chunk\n"); return(info); } int format = helper.GetLittleShort(fmt + 8); if (format != 1) { Con.Print("Microsoft PCM format only\n"); return(info); } info.channels = helper.GetLittleShort(fmt + 10); info.rate = helper.GetLittleLong(fmt + 12); info.width = helper.GetLittleShort(fmt + 16 + 4 + 2) / 8; // get cue chunk int cue = helper.FindChunk("cue ", offset); if (cue != -1) { info.loopstart = helper.GetLittleLong(cue + 32); // if the next chunk is a LIST chunk, look for a cue length marker int list = helper.FindChunk("LIST", cue); if (list != -1) { string mark = Encoding.ASCII.GetString(wav, list + 28, 4); if (mark == "mark") { // this is not a proper parse, but it works with cooledit... int i = helper.GetLittleLong(list + 24); // samples in loop info.samples = info.loopstart + i; } } } else { info.loopstart = -1; } // find data chunk int data = helper.FindChunk("data", offset); if (data == -1) { Con.Print("Missing data chunk\n"); return(info); } int samples = helper.GetLittleLong(data + 4) / info.width; if (info.samples > 0) { if (samples < info.samples) { Sys.Error("Sound {0} has a bad loop length", name); } } else { info.samples = samples; } info.dataofs = data + 8; return(info); }
// void S_Update (vec3_t origin, vec3_t v_forward, vec3_t v_right, vec3_t v_up) // // Called once each time through the main loop public static void Update(ref Vector3 origin, ref Vector3 forward, ref Vector3 right, ref Vector3 up) { if (!_IsInitialized || (_SoundBlocked > 0)) { return; } _ListenerOrigin = origin; _ListenerForward = forward; _ListenerRight = right; _ListenerUp = up; // update general area ambient sound sources UpdateAmbientSounds(); channel_t combine = null; // update spatialization for static and dynamic sounds //channel_t ch = channels + NUM_AMBIENTS; for (int i = Ambients.NUM_AMBIENTS; i < _TotalChannels; i++) { channel_t ch = _Channels[i];// channels + NUM_AMBIENTS; if (ch.sfx == null) { continue; } Spatialize(ch); // respatialize channel if (ch.leftvol == 0 && ch.rightvol == 0) { continue; } // try to combine static sounds with a previous channel of the same // sound effect so we don't mix five torches every frame if (i >= MAX_DYNAMIC_CHANNELS + Ambients.NUM_AMBIENTS) { // see if it can just use the last one if (combine != null && combine.sfx == ch.sfx) { combine.leftvol += ch.leftvol; combine.rightvol += ch.rightvol; ch.leftvol = ch.rightvol = 0; continue; } // search for one combine = _Channels[MAX_DYNAMIC_CHANNELS + Ambients.NUM_AMBIENTS];// channels + MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS; int j; for (j = MAX_DYNAMIC_CHANNELS + Ambients.NUM_AMBIENTS; j < i; j++) { combine = _Channels[j]; if (combine.sfx == ch.sfx) { break; } } if (j == _TotalChannels) { combine = null; } else { if (combine != ch) { combine.leftvol += ch.leftvol; combine.rightvol += ch.rightvol; ch.leftvol = ch.rightvol = 0; } continue; } } } // // debugging output // if (_Show.Value != 0) { int total = 0; for (int i = 0; i < _TotalChannels; i++) { channel_t ch = _Channels[i]; if (ch.sfx != null && (ch.leftvol > 0 || ch.rightvol > 0)) { total++; } } Con.Print("----({0})----\n", total); } // mix some sound Update(); }
/// <summary> /// SV_WriteEntitiesToClient /// </summary> static void WriteEntitiesToClient(edict_t clent, MessageWriter msg) { // find the client's PVS Vector3 org = Common.ToVector(ref clent.v.origin) + Common.ToVector(ref clent.v.view_ofs); byte[] pvs = FatPVS(ref org); // send over all entities (except the client) that touch the pvs for (int e = 1; e < sv.num_edicts; e++) { edict_t ent = sv.edicts[e]; // ignore if not touching a PV leaf if (ent != clent) // clent is ALLWAYS sent { // ignore ents without visible models string mname = Progs.GetString(ent.v.model); if (String.IsNullOrEmpty(mname)) { continue; } int i; for (i = 0; i < ent.num_leafs; i++) { if ((pvs[ent.leafnums[i] >> 3] & (1 << (ent.leafnums[i] & 7))) != 0) { break; } } if (i == ent.num_leafs) { continue; // not visible } } if (msg.Capacity - msg.Length < 16) { Con.Print("packet overflow\n"); return; } // send an update int bits = 0; v3f miss; Mathlib.VectorSubtract(ref ent.v.origin, ref ent.baseline.origin, out miss); if (miss.x < -0.1f || miss.x > 0.1f) { bits |= Protocol.U_ORIGIN1; } if (miss.y < -0.1f || miss.y > 0.1f) { bits |= Protocol.U_ORIGIN2; } if (miss.z < -0.1f || miss.z > 0.1f) { bits |= Protocol.U_ORIGIN3; } if (ent.v.angles.x != ent.baseline.angles.x) { bits |= Protocol.U_ANGLE1; } if (ent.v.angles.y != ent.baseline.angles.y) { bits |= Protocol.U_ANGLE2; } if (ent.v.angles.z != ent.baseline.angles.z) { bits |= Protocol.U_ANGLE3; } if (ent.v.movetype == Movetypes.MOVETYPE_STEP) { bits |= Protocol.U_NOLERP; // don't mess up the step animation } if (ent.baseline.colormap != ent.v.colormap) { bits |= Protocol.U_COLORMAP; } if (ent.baseline.skin != ent.v.skin) { bits |= Protocol.U_SKIN; } if (ent.baseline.frame != ent.v.frame) { bits |= Protocol.U_FRAME; } if (ent.baseline.effects != ent.v.effects) { bits |= Protocol.U_EFFECTS; } if (ent.baseline.modelindex != ent.v.modelindex) { bits |= Protocol.U_MODEL; } if (e >= 256) { bits |= Protocol.U_LONGENTITY; } if (bits >= 256) { bits |= Protocol.U_MOREBITS; } // // write the message // msg.WriteByte(bits | Protocol.U_SIGNAL); if ((bits & Protocol.U_MOREBITS) != 0) { msg.WriteByte(bits >> 8); } if ((bits & Protocol.U_LONGENTITY) != 0) { msg.WriteShort(e); } else { msg.WriteByte(e); } if ((bits & Protocol.U_MODEL) != 0) { msg.WriteByte((int)ent.v.modelindex); } if ((bits & Protocol.U_FRAME) != 0) { msg.WriteByte((int)ent.v.frame); } if ((bits & Protocol.U_COLORMAP) != 0) { msg.WriteByte((int)ent.v.colormap); } if ((bits & Protocol.U_SKIN) != 0) { msg.WriteByte((int)ent.v.skin); } if ((bits & Protocol.U_EFFECTS) != 0) { msg.WriteByte((int)ent.v.effects); } if ((bits & Protocol.U_ORIGIN1) != 0) { msg.WriteCoord(ent.v.origin.x); } if ((bits & Protocol.U_ANGLE1) != 0) { msg.WriteAngle(ent.v.angles.x); } if ((bits & Protocol.U_ORIGIN2) != 0) { msg.WriteCoord(ent.v.origin.y); } if ((bits & Protocol.U_ANGLE2) != 0) { msg.WriteAngle(ent.v.angles.y); } if ((bits & Protocol.U_ORIGIN3) != 0) { msg.WriteCoord(ent.v.origin.z); } if ((bits & Protocol.U_ANGLE3) != 0) { msg.WriteAngle(ent.v.angles.z); } } }
public void Play(byte track, bool looping) { if (!_IsEnabled) { return; } if (!_IsValidDisc) { ReloadDiskInfo(); if (!_IsValidDisc) { return; } } track = _Remap[track]; if (track < 1 || track > _MaxTrack) { Con.DPrint("CDAudio: Bad track number {0}.\n", track); return; } // don't try to play a non-audio track Mci.StatusParams sp = default(Mci.StatusParams); sp.dwItem = Mci.MCI_CDA_STATUS_TYPE_TRACK; sp.dwTrack = track; int ret = Mci.Status(_DeviceID, Mci.MCI_STATUS, Mci.MCI_STATUS_ITEM | Mci.MCI_TRACK | Mci.MCI_WAIT, ref sp); if (ret != 0) { Con.DPrint("MCI_STATUS failed ({0})\n", ret); return; } if (sp.dwReturn != Mci.MCI_CDA_TRACK_AUDIO) { Con.Print("CDAudio: track {0} is not audio\n", track); return; } // get the length of the track to be played sp.dwItem = Mci.MCI_STATUS_LENGTH; sp.dwTrack = track; ret = Mci.Status(_DeviceID, Mci.MCI_STATUS, Mci.MCI_STATUS_ITEM | Mci.MCI_TRACK | Mci.MCI_WAIT, ref sp); if (ret != 0) { Con.DPrint("MCI_STATUS failed ({0})\n", ret); return; } if (_IsPlaying) { if (_PlayTrack == track) { return; } Stop(); } Mci.PlayParams pp; pp.dwFrom = Mci.MCI_MAKE_TMSF(track, 0, 0, 0); pp.dwTo = (sp.dwReturn << 8) | track; pp.dwCallback = _Form.Handle; ret = Mci.Play(_DeviceID, Mci.MCI_PLAY, Mci.MCI_NOTIFY | Mci.MCI_FROM | Mci.MCI_TO, ref pp); if (ret != 0) { Con.DPrint("CDAudio: MCI_PLAY failed ({0})\n", ret); return; } _IsLooping = looping; _PlayTrack = track; _IsPlaying = true; if (_Volume == 0) { Pause(); } }
/// <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); }
/// <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> /// CL_ParseServerInfo /// </summary> private static void ParseServerInfo() { Con.DPrint("Serverinfo packet received.\n"); // // wipe the client_state_t struct // ClearState(); // parse protocol version number int i = net.Reader.ReadLong(); if (i != protocol.PROTOCOL_VERSION) { Con.Print("Server returned version {0}, not {1}", i, protocol.PROTOCOL_VERSION); return; } // parse maxclients cl.maxclients = net.Reader.ReadByte(); if (cl.maxclients < 1 || cl.maxclients > QDef.MAX_SCOREBOARD) { Con.Print("Bad maxclients ({0}) from server\n", cl.maxclients); return; } cl.scores = new scoreboard_t[cl.maxclients];// Hunk_AllocName (cl.maxclients*sizeof(*cl.scores), "scores"); for (i = 0; i < cl.scores.Length; i++) { cl.scores[i] = new scoreboard_t(); } // parse gametype cl.gametype = net.Reader.ReadByte(); // parse signon message string str = net.Reader.ReadString(); cl.levelname = common.Copy(str, 40); // seperate the printfs so the server message can have a color Con.Print(ConsoleBar); Con.Print("{0}{1}\n", (char)2, str); // // first we go through and touch all of the precache data that still // happens to be in the cache, so precaching something else doesn't // needlessly purge it // // precache models Array.Clear(cl.model_precache, 0, cl.model_precache.Length); int nummodels; string[] model_precache = new string[QDef.MAX_MODELS]; for (nummodels = 1; ; nummodels++) { str = net.Reader.ReadString(); if (String.IsNullOrEmpty(str)) { break; } if (nummodels == QDef.MAX_MODELS) { Con.Print("Server sent too many model precaches\n"); return; } model_precache[nummodels] = str; Mod.TouchModel(str); } // precache sounds Array.Clear(cl.sound_precache, 0, cl.sound_precache.Length); int numsounds; string[] sound_precache = new string[QDef.MAX_SOUNDS]; for (numsounds = 1; ; numsounds++) { str = net.Reader.ReadString(); if (String.IsNullOrEmpty(str)) { break; } if (numsounds == QDef.MAX_SOUNDS) { Con.Print("Server sent too many sound precaches\n"); return; } sound_precache[numsounds] = str; snd.TouchSound(str); } // // now we try to load everything else until a cache allocation fails // for (i = 1; i < nummodels; i++) { cl.model_precache[i] = Mod.ForName(model_precache[i], false); if (cl.model_precache[i] == null) { Con.Print("Model {0} not found\n", model_precache[i]); return; } KeepaliveMessage(); } snd.BeginPrecaching(); for (i = 1; i < numsounds; i++) { cl.sound_precache[i] = snd.PrecacheSound(sound_precache[i]); KeepaliveMessage(); } snd.EndPrecaching(); // local state _Entities[0].model = cl.worldmodel = cl.model_precache[1]; render.NewMap(); host.NoClipAngleHack = false; // noclip is turned off at start GC.Collect(); }
/// <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(); } }
private static float _LastMsg; // static float lastmsg from CL_KeepaliveMessage /// <summary> /// CL_ParseServerMessage /// </summary> private 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(); snd.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) { cd_audio.Pause(); } else { cd_audio.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)) { cd_audio.Play((byte)cls.forcetrack, true); } else { cd_audio.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: SharpQuake.cmd.ExecuteString("help", cmd_source_t.src_command); break; } } }
/// <summary> /// Host_Status_f /// </summary> private static void Status_f() { bool flag = true; if (cmd.Source == cmd_source_t.src_command) { if (!server.sv.active) { cmd.ForwardToServer(); return; } } else { flag = false; } StringBuilder sb = new StringBuilder(256); sb.Append(String.Format("host: {0}\n", cvar.GetString("hostname"))); sb.Append(String.Format("version: {0:F2}\n", QDef.VERSION)); if (net.TcpIpAvailable) { sb.Append("tcp/ip: "); sb.Append(net.MyTcpIpAddress); sb.Append('\n'); } sb.Append("map: "); sb.Append(server.sv.name); sb.Append('\n'); sb.Append(String.Format("players: {0} active ({1} max)\n\n", net.ActiveConnections, server.svs.maxclients)); for (int j = 0; j < server.svs.maxclients; j++) { client_t client = server.svs.clients[j]; if (!client.active) { continue; } int seconds = (int)(net.Time - client.netconnection.connecttime); int hours, minutes = seconds / 60; if (minutes > 0) { seconds -= (minutes * 60); hours = minutes / 60; if (hours > 0) { minutes -= (hours * 60); } } else { hours = 0; } sb.Append(String.Format("#{0,-2} {1,-16} {2} {2}:{4,2}:{5,2}", j + 1, client.name, (int)client.edict.v.frags, hours, minutes, seconds)); sb.Append(" "); sb.Append(client.netconnection.address); sb.Append('\n'); } if (flag) { Con.Print(sb.ToString()); } else { server.ClientPrint(sb.ToString()); } }
/// <summary> /// R_SplitEntityOnNode /// </summary> private static void SplitEntityOnNode(mnodebase_t node) { if (node.contents == Contents.CONTENTS_SOLID) { return; } // add an efrag if the node is a leaf if (node.contents < 0) { if (_EfragTopNode == null) { _EfragTopNode = node as mnode_t; } mleaf_t leaf = (mleaf_t)(object)node; // grab an efrag off the free list efrag_t ef = client.cl.free_efrags; if (ef == null) { Con.Print("Too many efrags!\n"); return; // no free fragments... } client.cl.free_efrags = client.cl.free_efrags.entnext; ef.entity = _AddEnt; // add the entity link // *lastlink = ef; if (_LastObj is entity_t) { ((entity_t)_LastObj).efrag = ef; } else { ((efrag_t)_LastObj).entnext = ef; } _LastObj = ef; // lastlink = &ef->entnext; ef.entnext = null; // set the leaf links ef.leaf = leaf; ef.leafnext = leaf.efrags; leaf.efrags = ef; return; } // NODE_MIXED mnode_t n = node as mnode_t; if (n == null) { return; } mplane_t splitplane = n.plane; int sides = mathlib.BoxOnPlaneSide(ref _EMins, ref _EMaxs, splitplane); if (sides == 3) { // split on this plane // if this is the first splitter of this bmodel, remember it if (_EfragTopNode == null) { _EfragTopNode = n; } } // recurse down the contacted sides if ((sides & 1) != 0) { SplitEntityOnNode(n.children[0]); } if ((sides & 2) != 0) { SplitEntityOnNode(n.children[1]); } }
private static int _StripCount; // stripcount /// <summary> /// GL_MakeAliasModelDisplayLists /// </summary> public static void MakeAliasModelDisplayLists(model_t m, aliashdr_t hdr) { _AliasModel = m; _AliasHdr = hdr; // // look for a cached version // string path = Path.ChangeExtension("glquake/" + Path.GetFileNameWithoutExtension(m.name), ".ms2"); DisposableWrapper <BinaryReader> file; Common.FOpenFile(path, out file); if (file != null) { using ( file ) { BinaryReader reader = file.Object; _NumCommands = reader.ReadInt32(); _NumOrder = reader.ReadInt32(); for (int i = 0; i < _NumCommands; i++) { _Commands[i] = reader.ReadInt32(); } for (int i = 0; i < _NumOrder; i++) { _VertexOrder[i] = reader.ReadInt32(); } } } else { // // build it from scratch // Con.Print("meshing {0}...\n", m.name); BuildTris(); // trifans or lists // // save out the cached version // string fullpath = Path.Combine(Common.GameDir, path); Stream fs = Sys.FileOpenWrite(fullpath, true); if (fs != null) { using (BinaryWriter writer = new BinaryWriter(fs, Encoding.ASCII)) { writer.Write(_NumCommands); writer.Write(_NumOrder); for (int i = 0; i < _NumCommands; i++) { writer.Write(_Commands[i]); } for (int i = 0; i < _NumOrder; i++) { writer.Write(_VertexOrder[i]); } } } } // // save the data out // _AliasHdr.poseverts = _NumOrder; int[] cmds = new int[_NumCommands]; //Hunk_Alloc (numcommands * 4); _AliasHdr.commands = cmds; // in bytes??? // (byte*)cmds - (byte*)paliashdr; Buffer.BlockCopy(_Commands, 0, cmds, 0, _NumCommands * 4); //memcpy (cmds, commands, numcommands * 4); trivertx_t[][] poseverts = Mod.PoseVerts; trivertx_t[] verts = new trivertx_t[_AliasHdr.numposes * _AliasHdr.poseverts]; // Hunk_Alloc (paliashdr->numposes * paliashdr->poseverts * sizeof(trivertx_t) ); _AliasHdr.posedata = verts; // (byte*)verts - (byte*)paliashdr; int offset = 0; for (int i = 0; i < _AliasHdr.numposes; i++) { for (int j = 0; j < _NumOrder; j++) { verts[offset++] = poseverts[i][_VertexOrder[j]]; // *verts++ = poseverts[i][vertexorder[j]]; } } }
// CL_PlayDemo_f // // play [demoname] static void PlayDemo_f() { if (Cmd.Source != cmd_source_t.src_command) { return; } if (Cmd.Argc != 2) { Con.Print("play <demoname> : plays a demo\n"); return; } // // disconnect from server // Client.Disconnect(); // // open the demo file // string name = Path.ChangeExtension(Cmd.Argv(1), ".dem"); Con.Print("Playing demo from {0}.\n", name); if (Cls.demofile != null) { Cls.demofile.Dispose(); } DisposableWrapper <BinaryReader> reader; Common.FOpenFile(name, out reader); Cls.demofile = reader; if (Cls.demofile == null) { Con.Print("ERROR: couldn't open.\n"); Cls.demonum = -1; // stop demo loop return; } Cls.demoplayback = true; Cls.state = ClientActivityState.Connected; Cls.forcetrack = 0; BinaryReader s = reader.Object; int c; bool neg = false; while (true) { c = s.ReadByte(); if (c == '\n') { break; } if (c == '-') { neg = true; } else { Cls.forcetrack = Cls.forcetrack * 10 + (c - '0'); } } if (neg) { Cls.forcetrack = -Cls.forcetrack; } // ZOID, fscanf is evil // fscanf (cls.demofile, "%i\n", &cls.forcetrack); }
// vcrSendMessage // 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> /// CL_GetMessage /// Handles recording and playback of demos, on top of NET_ code /// </summary> /// <returns></returns> static int GetMessage() { if (Cls.demoplayback) { // decide if it is time to grab the next message if (Cls.signon == SIGNONS) // allways grab until fully connected { if (Cls.timedemo) { if (Host.FrameCount == Cls.td_lastframe) { return(0); // allready read this frame's message } Cls.td_lastframe = Host.FrameCount; // if this is the second frame, grab the real td_starttime // so the bogus time on the first frame doesn't count if (Host.FrameCount == Cls.td_startframe + 1) { Cls.td_starttime = (float)Host.RealTime; } } else if (Cl.time <= Cl.mtime[0]) { return(0); // don't need another message yet } } // get the next message BinaryReader reader = ((DisposableWrapper <BinaryReader>)Cls.demofile).Object; int size = Common.LittleLong(reader.ReadInt32()); if (size > QDef.MAX_MSGLEN) { Sys.Error("Demo message > MAX_MSGLEN"); } Cl.mviewangles[1] = Cl.mviewangles[0]; Cl.mviewangles[0].X = Common.LittleFloat(reader.ReadSingle()); Cl.mviewangles[0].Y = Common.LittleFloat(reader.ReadSingle()); Cl.mviewangles[0].Z = Common.LittleFloat(reader.ReadSingle()); Net.Message.FillFrom(reader.BaseStream, size); if (Net.Message.Length < size) { StopPlayback(); return(0); } return(1); } int r; while (true) { r = Net.GetMessage(Cls.netcon); if (r != 1 && r != 2) { return(r); } // discard nop keepalive message if (Net.Message.Length == 1 && Net.Message.Data[0] == Protocol.svc_nop) { Con.Print("<-- server to client keepalive\n"); } else { break; } } if (Cls.demorecording) { WriteDemoMessage(); } return(r); }
/// <summary> /// NET_GetMessage /// returns data in net_message sizebuf /// returns 0 if no data is waiting /// returns 1 if a message was received /// returns 2 if an unreliable message was received /// returns -1 if the connection died /// </summary> public static int GetMessage(qsocket_t sock) { //int ret; if (sock == null) { return(-1); } if (sock.disconnected) { Con.Print("NET_GetMessage: disconnected socket\n"); return(-1); } SetNetTime(); int ret = _Drivers[sock.driver].GetMessage(sock); // see if this connection has timed out if (ret == 0 && sock.driver != 0) { if (_Time - sock.lastMessageTime > _MessageTimeout.Value) { Close(sock); return(-1); } } if (ret > 0) { if (sock.driver != 0) { sock.lastMessageTime = _Time; if (ret == 1) { _MessagesReceived++; } else if (ret == 2) { _UnreliableMessagesReceived++; } } if (_IsRecording) { _VcrGetMessage.time = Host.Time; _VcrGetMessage.op = VcrOp.VCR_OP_GETMESSAGE; _VcrGetMessage.session = 1;// (long)sock; Uze todo: write somethisng meaningful _VcrGetMessage.ret = ret; byte[] buf = Sys.StructureToBytes(ref _VcrGetMessage); Host.VcrWriter.Write(buf, 0, buf.Length); Host.VcrWriter.Write(Net.Message.Length); Host.VcrWriter.Write(Net.Message.Data, 0, Net.Message.Length); } } else { if (_IsRecording) { _VcrGetMessage.time = Host.Time; _VcrGetMessage.op = VcrOp.VCR_OP_GETMESSAGE; _VcrGetMessage.session = 1; // (long)sock; Uze todo: fix this _VcrGetMessage.ret = ret; byte[] buf = Sys.StructureToBytes(ref _VcrGetMessage); Host.VcrWriter.Write(buf, 0, buf.Length); } } return(ret); }
/// <summary> /// SV_StartSound /// Each entity can have eight independant sound sources, like voice, /// weapon, feet, etc. /// /// Channel 0 is an auto-allocate channel, the others override anything /// allready running on that entity/channel pair. /// /// An attenuation of 0 will play full volume everywhere in the level. /// Larger attenuations will drop off. (max 4 attenuation) /// </summary> public static void StartSound(edict_t entity, int channel, string sample, int volume, float attenuation) { if (volume < 0 || volume > 255) { Sys.Error("SV_StartSound: volume = {0}", volume); } if (attenuation < 0 || attenuation > 4) { Sys.Error("SV_StartSound: attenuation = {0}", attenuation); } if (channel < 0 || channel > 7) { Sys.Error("SV_StartSound: channel = {0}", channel); } if (sv.datagram.Length > QDef.MAX_DATAGRAM - 16) { return; } // find precache number for sound int sound_num; for (sound_num = 1; sound_num < QDef.MAX_SOUNDS && sv.sound_precache[sound_num] != null; sound_num++) { if (sample == sv.sound_precache[sound_num]) { break; } } if (sound_num == QDef.MAX_SOUNDS || String.IsNullOrEmpty(sv.sound_precache[sound_num])) { Con.Print("SV_StartSound: {0} not precacheed\n", sample); return; } int ent = NumForEdict(entity); channel = (ent << 3) | channel; int field_mask = 0; if (volume != Sound.DEFAULT_SOUND_PACKET_VOLUME) { field_mask |= Protocol.SND_VOLUME; } if (attenuation != Sound.DEFAULT_SOUND_PACKET_ATTENUATION) { field_mask |= Protocol.SND_ATTENUATION; } // directed messages go only to the entity the are targeted on sv.datagram.WriteByte(Protocol.svc_sound); sv.datagram.WriteByte(field_mask); if ((field_mask & Protocol.SND_VOLUME) != 0) { sv.datagram.WriteByte(volume); } if ((field_mask & Protocol.SND_ATTENUATION) != 0) { sv.datagram.WriteByte((int)(attenuation * 64)); } sv.datagram.WriteShort(channel); sv.datagram.WriteByte(sound_num); v3f v; Mathlib.VectorAdd(ref entity.v.mins, ref entity.v.maxs, out v); Mathlib.VectorMA(ref entity.v.origin, 0.5f, ref v, out v); sv.datagram.WriteCoord(v.x); sv.datagram.WriteCoord(v.y); sv.datagram.WriteCoord(v.z); }