public static Int32 SV_FindIndex(String name, Int32 start, Int32 max, Boolean create) { Int32 i; if (name == null || name.Length == 0) { return(0); } for (i = 1; i < max && sv.configstrings[start + i] != null; i++) { if (0 == Lib.Strcmp(sv.configstrings[start + i], name)) { return(i); } } if (!create) { return(0); } if (i == max) { Com.Error(Defines.ERR_DROP, "*Index: overflow"); } sv.configstrings[start + i] = name; if (sv.state != Defines.ss_loading) { SZ.Clear(sv.multicast); MSG.WriteChar(sv.multicast, Defines.svc_configstring); MSG.WriteShort(sv.multicast, start + i); MSG.WriteString(sv.multicast, name); SV_SEND.SV_Multicast(Globals.vec3_origin, Defines.MULTICAST_ALL_R); } return(i); }
public static void SV_NextDownload_f( ) { Int32 r; Int32 percent; Int32 size; if (SV_MAIN.sv_client.download == null) { return; } r = SV_MAIN.sv_client.downloadsize - SV_MAIN.sv_client.downloadcount; if (r > 1024) { r = 1024; } MSG.WriteByte(SV_MAIN.sv_client.netchan.message, Defines.svc_download); MSG.WriteShort(SV_MAIN.sv_client.netchan.message, r); SV_MAIN.sv_client.downloadcount += r; size = SV_MAIN.sv_client.downloadsize; if (size == 0) { size = 1; } percent = SV_MAIN.sv_client.downloadcount * 100 / size; MSG.WriteByte(SV_MAIN.sv_client.netchan.message, percent); SZ.Write(SV_MAIN.sv_client.netchan.message, SV_MAIN.sv_client.download, SV_MAIN.sv_client.downloadcount - r, r); if (SV_MAIN.sv_client.downloadcount != SV_MAIN.sv_client.downloadsize) { return; } FS.FreeFile(SV_MAIN.sv_client.download); SV_MAIN.sv_client.download = null; }
/** * PF_Configstring */ public static void PF_Configstring(int index, string val) { if (index < 0 || index >= Defines.MAX_CONFIGSTRINGS) { Com.Error(Defines.ERR_DROP, "configstring: bad index " + index + "\n"); } if (val == null) { val = ""; } // change the string in sv SV_INIT.sv.configstrings[index] = val; if (SV_INIT.sv.state != Defines.ss_loading) { // send the update to // everyone SZ.Clear(SV_INIT.sv.multicast); MSG.WriteChar(SV_INIT.sv.multicast, Defines.svc_configstring); MSG.WriteShort(SV_INIT.sv.multicast, index); MSG.WriteString(SV_INIT.sv.multicast, val); SV_SEND.SV_Multicast(Globals.vec3_origin, Defines.MULTICAST_ALL_R); } }
/** * Save everything in the world out without deltas. Used for recording * footage for merged or assembled demos. */ public static void SV_RecordDemoMessage() { if (SV_INIT.svs.demofile == null) { return; } //memset (nostate, 0, sizeof(nostate)); entity_state_t nostate = new(null); sizebuf_t buf = new(); SZ.Init(buf, SV_ENTS.buf_data, SV_ENTS.buf_data.Length); // write a frame message that doesn't contain a player_state_t MSG.WriteByte(buf, Defines.svc_frame); MSG.WriteLong(buf, SV_INIT.sv.framenum); MSG.WriteByte(buf, Defines.svc_packetentities); var e = 1; var ent = GameBase.g_edicts[e]; while (e < GameBase.num_edicts) { // ignore ents without visible models unless they have an effect if (ent.inuse && ent.s.number != 0 && (ent.s.modelindex != 0 || ent.s.effects != 0 || ent.s.sound != 0 || ent.s.@event != 0) && 0 == (ent.svflags & Defines.SVF_NOCLIENT)) { MSG.WriteDeltaEntity(nostate, ent.s, buf, false, true); } e++; ent = GameBase.g_edicts[e]; } MSG.WriteShort(buf, 0); // end of packetentities // now add the accumulated multicast information SZ.Write(buf, SV_INIT.svs.demo_multicast.data, SV_INIT.svs.demo_multicast.cursize); SZ.Clear(SV_INIT.svs.demo_multicast); // now write the entire message to the file, prefixed by the length var len = EndianHandler.swapInt(buf.cursize); try { //fwrite (len, 4, 1, svs.demofile); SV_INIT.svs.demofile.Write(len); //fwrite (buf.data, buf.cursize, 1, svs.demofile); SV_INIT.svs.demofile.Write(buf.data, 0, buf.cursize); } catch (Exception) { Com.Printf("Error writing demo file:" + e); } }
public static void SV_BeginDownload_f( ) { String name; var offset = 0; name = Cmd.Argv(1); if (Cmd.Argc() > 2) { offset = Lib.Atoi(Cmd.Argv(2)); } if (name.IndexOf("..") != -1 || SV_MAIN.allow_download.value == 0 || name[0] == '.' || name[0] == '/' || (name.StartsWith("players/") && 0 == SV_MAIN.allow_download_players.value) || (name.StartsWith("models/") && 0 == SV_MAIN.allow_download_models.value) || (name.StartsWith("sound/") && 0 == SV_MAIN.allow_download_sounds.value) || (name.StartsWith("maps/") && 0 == SV_MAIN.allow_download_maps.value) || name.IndexOf('/') == -1) { MSG.WriteByte(SV_MAIN.sv_client.netchan.message, Defines.svc_download); MSG.WriteShort(SV_MAIN.sv_client.netchan.message, -1); MSG.WriteByte(SV_MAIN.sv_client.netchan.message, 0); return; } if (SV_MAIN.sv_client.download != null) { FS.FreeFile(SV_MAIN.sv_client.download); } SV_MAIN.sv_client.download = FS.LoadFile(name); if (SV_MAIN.sv_client.download == null) { return; } SV_MAIN.sv_client.downloadsize = SV_MAIN.sv_client.download.Length; SV_MAIN.sv_client.downloadcount = offset; if (offset > SV_MAIN.sv_client.downloadsize) { SV_MAIN.sv_client.downloadcount = SV_MAIN.sv_client.downloadsize; } if (SV_MAIN.sv_client.download == null || (name.StartsWith("maps/") && FS.file_from_pak != 0)) { Com.DPrintf("Couldn't download " + name + " to " + SV_MAIN.sv_client.name + "\\n"); if (SV_MAIN.sv_client.download != null) { FS.FreeFile(SV_MAIN.sv_client.download); SV_MAIN.sv_client.download = null; } MSG.WriteByte(SV_MAIN.sv_client.netchan.message, Defines.svc_download); MSG.WriteShort(SV_MAIN.sv_client.netchan.message, -1); MSG.WriteByte(SV_MAIN.sv_client.netchan.message, 0); return; } SV_NextDownload_f(); Com.DPrintf("Downloading " + name + " to " + SV_MAIN.sv_client.name + "\\n"); }
public static void SV_New_f( ) { String gamedir; Int32 playernum; edict_t ent; Com.DPrintf("New() from " + SV_MAIN.sv_client.name + "\\n"); if (SV_MAIN.sv_client.state != Defines.cs_connected) { Com.Printf("New not valid -- already spawned\\n"); return; } if (SV_INIT.sv.state == Defines.ss_demo) { SV_BeginDemoserver(); return; } gamedir = Cvar.VariableString("gamedir"); MSG.WriteByte(SV_MAIN.sv_client.netchan.message, Defines.svc_serverdata); MSG.WriteInt(SV_MAIN.sv_client.netchan.message, Defines.PROTOCOL_VERSION); MSG.WriteLong(SV_MAIN.sv_client.netchan.message, SV_INIT.svs.spawncount); MSG.WriteByte(SV_MAIN.sv_client.netchan.message, SV_INIT.sv.attractloop ? 1 : 0); MSG.WriteString(SV_MAIN.sv_client.netchan.message, gamedir); if (SV_INIT.sv.state == Defines.ss_cinematic || SV_INIT.sv.state == Defines.ss_pic) { playernum = -1; } else { playernum = SV_MAIN.sv_client.serverindex; } MSG.WriteShort(SV_MAIN.sv_client.netchan.message, playernum); MSG.WriteString(SV_MAIN.sv_client.netchan.message, SV_INIT.sv.configstrings[Defines.CS_NAME]); if (SV_INIT.sv.state == Defines.ss_game) { ent = GameBase.g_edicts[playernum + 1]; ent.s.number = playernum + 1; SV_MAIN.sv_client.edict = ent; SV_MAIN.sv_client.lastcmd = new usercmd_t(); MSG.WriteByte(SV_MAIN.sv_client.netchan.message, Defines.svc_stufftext); MSG.WriteString(SV_MAIN.sv_client.netchan.message, "cmd configstrings " + SV_INIT.svs.spawncount + " 0\\n"); } }
public static void SV_Configstrings_f( ) { Int32 start; Com.DPrintf("Configstrings() from " + SV_MAIN.sv_client.name + "\\n"); if (SV_MAIN.sv_client.state != Defines.cs_connected) { Com.Printf("configstrings not valid -- already spawned\\n"); return; } if (Lib.Atoi(Cmd.Argv(1)) != SV_INIT.svs.spawncount) { Com.Printf("SV_Configstrings_f from different level\\n"); SV_New_f(); return; } start = Lib.Atoi(Cmd.Argv(2)); while (SV_MAIN.sv_client.netchan.message.cursize < Defines.MAX_MSGLEN / 2 && start < Defines.MAX_CONFIGSTRINGS) { if (SV_INIT.sv.configstrings[start] != null && SV_INIT.sv.configstrings[start].Length != 0) { MSG.WriteByte(SV_MAIN.sv_client.netchan.message, Defines.svc_configstring); MSG.WriteShort(SV_MAIN.sv_client.netchan.message, start); MSG.WriteString(SV_MAIN.sv_client.netchan.message, SV_INIT.sv.configstrings[start]); } start++; } if (start == Defines.MAX_CONFIGSTRINGS) { MSG.WriteByte(SV_MAIN.sv_client.netchan.message, Defines.svc_stufftext); MSG.WriteString(SV_MAIN.sv_client.netchan.message, "cmd baselines " + SV_INIT.svs.spawncount + " 0\\n"); } else { MSG.WriteByte(SV_MAIN.sv_client.netchan.message, Defines.svc_stufftext); MSG.WriteString(SV_MAIN.sv_client.netchan.message, "cmd configstrings " + SV_INIT.svs.spawncount + " " + start + "\\n"); } }
/** * SV_FindIndex. */ public static int SV_FindIndex(string name, int start, int max, bool create) { int i; if (name == null || name.Length == 0) { return(0); } for (i = 1; i < max && SV_INIT.sv.configstrings[start + i] != null; i++) { if (0 == Lib.strcmp(SV_INIT.sv.configstrings[start + i], name)) { return(i); } } if (!create) { return(0); } if (i == max) { Com.Error(Defines.ERR_DROP, "*Index: overflow"); } SV_INIT.sv.configstrings[start + i] = name; if (SV_INIT.sv.state != Defines.ss_loading) { // send the update to everyone SZ.Clear(SV_INIT.sv.multicast); MSG.WriteChar(SV_INIT.sv.multicast, Defines.svc_configstring); MSG.WriteShort(SV_INIT.sv.multicast, start + i); MSG.WriteString(SV_INIT.sv.multicast, name); SV_SEND.SV_Multicast(Globals.vec3_origin, Defines.MULTICAST_ALL_R); } return(i); }
public static void SV_RecordDemoMessage( ) { if (SV_INIT.svs.demofile == null) { return; } entity_state_t nostate = new entity_state_t(null); sizebuf_t buf = new sizebuf_t(); SZ.Init(buf, buf_data, buf_data.Length); MSG.WriteByte(buf, Defines.svc_frame); MSG.WriteLong(buf, SV_INIT.sv.framenum); MSG.WriteByte(buf, Defines.svc_packetentities); var e = 1; edict_t ent = GameBase.g_edicts[e]; while (e < GameBase.num_edicts) { if (ent.inuse && ent.s.number != 0 && (ent.s.modelindex != 0 || ent.s.effects != 0 || ent.s.sound != 0 || ent.s.event_renamed != 0) && 0 == (ent.svflags & Defines.SVF_NOCLIENT)) { MSG.WriteDeltaEntity(nostate, ent.s, buf, false, true); } e++; ent = GameBase.g_edicts[e]; } MSG.WriteShort(buf, 0); SZ.Write(buf, SV_INIT.svs.demo_multicast.data, SV_INIT.svs.demo_multicast.cursize); SZ.Clear(SV_INIT.svs.demo_multicast); var len = EndianHandler.SwapInt(buf.cursize); try { SV_INIT.svs.demofile.Write(len); SV_INIT.svs.demofile.Write(buf.data, 0, buf.cursize); } catch (Exception e1) { Com.Printf("Error writing demo file:" + e); } }
public static void SV_ServerRecord_f( ) { String name; Byte[] buf_data = new Byte[32768]; sizebuf_t buf = new sizebuf_t(); Int32 len; Int32 i; if (Cmd.Argc() != 2) { Com.Printf("serverrecord <demoname>\\n"); return; } if (SV_INIT.svs.demofile != null) { Com.Printf("Already recording.\\n"); return; } if (SV_INIT.sv.state != Defines.ss_game) { Com.Printf("You must be in a level to record.\\n"); return; } name = FS.Gamedir() + "/demos/" + Cmd.Argv(1) + ".dm2"; Com.Printf("recording to " + name + ".\\n"); FS.CreatePath(name); try { SV_INIT.svs.demofile = new QuakeFile(name, FileAccess.ReadWrite); } catch (Exception e) { Com.Printf("ERROR: couldn't open.\\n"); return; } SZ.Init(SV_INIT.svs.demo_multicast, SV_INIT.svs.demo_multicast_buf, SV_INIT.svs.demo_multicast_buf.Length); SZ.Init(buf, buf_data, buf_data.Length); MSG.WriteByte(buf, Defines.svc_serverdata); MSG.WriteLong(buf, Defines.PROTOCOL_VERSION); MSG.WriteLong(buf, SV_INIT.svs.spawncount); MSG.WriteByte(buf, 2); MSG.WriteString(buf, Cvar.VariableString("gamedir")); MSG.WriteShort(buf, -1); MSG.WriteString(buf, SV_INIT.sv.configstrings[Defines.CS_NAME]); for (i = 0; i < Defines.MAX_CONFIGSTRINGS; i++) { if (SV_INIT.sv.configstrings[i].Length == 0) { MSG.WriteByte(buf, Defines.svc_configstring); MSG.WriteShort(buf, i); MSG.WriteString(buf, SV_INIT.sv.configstrings[i]); } } Com.DPrintf("signon message length: " + buf.cursize + "\\n"); len = EndianHandler.SwapInt(buf.cursize); try { SV_INIT.svs.demofile.Write(len); SV_INIT.svs.demofile.Write(buf.data, 0, buf.cursize); } catch (IOException e1) { e1.PrintStackTrace(); } }
public static void SV_StartSound(Single[] origin, edict_t entity, Int32 channel, Int32 soundindex, Single volume, Single attenuation, Single timeofs) { Int32 sendchan; Int32 flags; Int32 i; Int32 ent; Boolean use_phs; if (volume < 0 || volume > 1) { Com.Error(Defines.ERR_FATAL, "SV_StartSound: volume = " + volume); } if (attenuation < 0 || attenuation > 4) { Com.Error(Defines.ERR_FATAL, "SV_StartSound: attenuation = " + attenuation); } if (timeofs < 0 || timeofs > 0.255) { Com.Error(Defines.ERR_FATAL, "SV_StartSound: timeofs = " + timeofs); } ent = entity.index; if ((channel & 8) != 0) { use_phs = false; channel &= 7; } else { use_phs = true; } sendchan = (ent << 3) | (channel & 7); flags = 0; if (volume != Defines.DEFAULT_SOUND_PACKET_VOLUME) { flags |= Defines.SND_VOLUME; } if (attenuation != Defines.DEFAULT_SOUND_PACKET_ATTENUATION) { flags |= Defines.SND_ATTENUATION; } if ((entity.svflags & Defines.SVF_NOCLIENT) != 0 || (entity.solid == Defines.SOLID_BSP) || origin != null) { flags |= Defines.SND_POS; } flags |= Defines.SND_ENT; if (timeofs != 0) { flags |= Defines.SND_OFFSET; } if (origin == null) { origin = origin_v; if (entity.solid == Defines.SOLID_BSP) { for (i = 0; i < 3; i++) { origin_v[i] = entity.s.origin[i] + 0.5F * (entity.mins[i] + entity.maxs[i]); } } else { Math3D.VectorCopy(entity.s.origin, origin_v); } } MSG.WriteByte(SV_INIT.sv.multicast, Defines.svc_sound); MSG.WriteByte(SV_INIT.sv.multicast, flags); MSG.WriteByte(SV_INIT.sv.multicast, soundindex); if ((flags & Defines.SND_VOLUME) != 0) { MSG.WriteByte(SV_INIT.sv.multicast, volume * 255); } if ((flags & Defines.SND_ATTENUATION) != 0) { MSG.WriteByte(SV_INIT.sv.multicast, attenuation * 64); } if ((flags & Defines.SND_OFFSET) != 0) { MSG.WriteByte(SV_INIT.sv.multicast, timeofs * 1000); } if ((flags & Defines.SND_ENT) != 0) { MSG.WriteShort(SV_INIT.sv.multicast, sendchan); } if ((flags & Defines.SND_POS) != 0) { MSG.WritePos(SV_INIT.sv.multicast, origin); } if (attenuation == Defines.ATTN_NONE) { use_phs = false; } if ((channel & Defines.CHAN_RELIABLE) != 0) { if (use_phs) { SV_Multicast(origin, Defines.MULTICAST_PHS_R); } else { SV_Multicast(origin, Defines.MULTICAST_ALL_R); } } else { if (use_phs) { SV_Multicast(origin, Defines.MULTICAST_PHS); } else { SV_Multicast(origin, Defines.MULTICAST_ALL); } } }
public static void PF_WriteShort(int c) { MSG.WriteShort(SV_INIT.sv.multicast, c); }
static void SV_WritePlayerstateToClient(client_frame_t from, client_frame_t to, sizebuf_t msg) { player_state_t ps, ops; player_state_t dummy; ps = to.ps; if (from == null) { dummy = new player_state_t(); ops = dummy; } else { ops = from.ps; } var pflags = 0; if (ps.pmove.pm_type != ops.pmove.pm_type) { pflags |= Defines.PS_M_TYPE; } if (ps.pmove.origin[0] != ops.pmove.origin[0] || ps.pmove.origin[1] != ops.pmove.origin[1] || ps.pmove.origin[2] != ops.pmove.origin[2]) { pflags |= Defines.PS_M_ORIGIN; } if (ps.pmove.velocity[0] != ops.pmove.velocity[0] || ps.pmove.velocity[1] != ops.pmove.velocity[1] || ps.pmove.velocity[2] != ops.pmove.velocity[2]) { pflags |= Defines.PS_M_VELOCITY; } if (ps.pmove.pm_time != ops.pmove.pm_time) { pflags |= Defines.PS_M_TIME; } if (ps.pmove.pm_flags != ops.pmove.pm_flags) { pflags |= Defines.PS_M_FLAGS; } if (ps.pmove.gravity != ops.pmove.gravity) { pflags |= Defines.PS_M_GRAVITY; } if (ps.pmove.delta_angles[0] != ops.pmove.delta_angles[0] || ps.pmove.delta_angles[1] != ops.pmove.delta_angles[1] || ps.pmove.delta_angles[2] != ops.pmove.delta_angles[2]) { pflags |= Defines.PS_M_DELTA_ANGLES; } if (ps.viewoffset[0] != ops.viewoffset[0] || ps.viewoffset[1] != ops.viewoffset[1] || ps.viewoffset[2] != ops.viewoffset[2]) { pflags |= Defines.PS_VIEWOFFSET; } if (ps.viewangles[0] != ops.viewangles[0] || ps.viewangles[1] != ops.viewangles[1] || ps.viewangles[2] != ops.viewangles[2]) { pflags |= Defines.PS_VIEWANGLES; } if (ps.kick_angles[0] != ops.kick_angles[0] || ps.kick_angles[1] != ops.kick_angles[1] || ps.kick_angles[2] != ops.kick_angles[2]) { pflags |= Defines.PS_KICKANGLES; } if (ps.blend[0] != ops.blend[0] || ps.blend[1] != ops.blend[1] || ps.blend[2] != ops.blend[2] || ps.blend[3] != ops.blend[3]) { pflags |= Defines.PS_BLEND; } if (ps.fov != ops.fov) { pflags |= Defines.PS_FOV; } if (ps.rdflags != ops.rdflags) { pflags |= Defines.PS_RDFLAGS; } if (ps.gunframe != ops.gunframe) { pflags |= Defines.PS_WEAPONFRAME; } pflags |= Defines.PS_WEAPONINDEX; MSG.WriteByte(msg, Defines.svc_playerinfo); MSG.WriteShort(msg, pflags); if ((pflags & Defines.PS_M_TYPE) != 0) { MSG.WriteByte(msg, ps.pmove.pm_type); } if ((pflags & Defines.PS_M_ORIGIN) != 0) { MSG.WriteShort(msg, ps.pmove.origin[0]); MSG.WriteShort(msg, ps.pmove.origin[1]); MSG.WriteShort(msg, ps.pmove.origin[2]); } if ((pflags & Defines.PS_M_VELOCITY) != 0) { MSG.WriteShort(msg, ps.pmove.velocity[0]); MSG.WriteShort(msg, ps.pmove.velocity[1]); MSG.WriteShort(msg, ps.pmove.velocity[2]); } if ((pflags & Defines.PS_M_TIME) != 0) { MSG.WriteByte(msg, ps.pmove.pm_time); } if ((pflags & Defines.PS_M_FLAGS) != 0) { MSG.WriteByte(msg, ps.pmove.pm_flags); } if ((pflags & Defines.PS_M_GRAVITY) != 0) { MSG.WriteShort(msg, ps.pmove.gravity); } if ((pflags & Defines.PS_M_DELTA_ANGLES) != 0) { MSG.WriteShort(msg, ps.pmove.delta_angles[0]); MSG.WriteShort(msg, ps.pmove.delta_angles[1]); MSG.WriteShort(msg, ps.pmove.delta_angles[2]); } if ((pflags & Defines.PS_VIEWOFFSET) != 0) { MSG.WriteChar(msg, ps.viewoffset[0] * 4); MSG.WriteChar(msg, ps.viewoffset[1] * 4); MSG.WriteChar(msg, ps.viewoffset[2] * 4); } if ((pflags & Defines.PS_VIEWANGLES) != 0) { MSG.WriteAngle16(msg, ps.viewangles[0]); MSG.WriteAngle16(msg, ps.viewangles[1]); MSG.WriteAngle16(msg, ps.viewangles[2]); } if ((pflags & Defines.PS_KICKANGLES) != 0) { MSG.WriteChar(msg, ps.kick_angles[0] * 4); MSG.WriteChar(msg, ps.kick_angles[1] * 4); MSG.WriteChar(msg, ps.kick_angles[2] * 4); } if ((pflags & Defines.PS_WEAPONINDEX) != 0) { MSG.WriteByte(msg, ps.gunindex); } if ((pflags & Defines.PS_WEAPONFRAME) != 0) { MSG.WriteByte(msg, ps.gunframe); MSG.WriteChar(msg, ps.gunoffset[0] * 4); MSG.WriteChar(msg, ps.gunoffset[1] * 4); MSG.WriteChar(msg, ps.gunoffset[2] * 4); MSG.WriteChar(msg, ps.gunangles[0] * 4); MSG.WriteChar(msg, ps.gunangles[1] * 4); MSG.WriteChar(msg, ps.gunangles[2] * 4); } if ((pflags & Defines.PS_BLEND) != 0) { MSG.WriteByte(msg, ps.blend[0] * 255); MSG.WriteByte(msg, ps.blend[1] * 255); MSG.WriteByte(msg, ps.blend[2] * 255); MSG.WriteByte(msg, ps.blend[3] * 255); } if ((pflags & Defines.PS_FOV) != 0) { MSG.WriteByte(msg, ps.fov); } if ((pflags & Defines.PS_RDFLAGS) != 0) { MSG.WriteByte(msg, ps.rdflags); } var statbits = 0; for (var i = 0; i < Defines.MAX_STATS; i++) { if (ps.stats[i] != ops.stats[i]) { statbits |= 1 << i; } } MSG.WriteLong(msg, statbits); for (var i = 0; i < Defines.MAX_STATS; i++) { if ((statbits & (1 << i)) != 0) { MSG.WriteShort(msg, ps.stats[i]); } } }
static void SV_EmitPacketEntities(client_frame_t from, client_frame_t to, sizebuf_t msg) { entity_state_t oldent = null, newent = null; Int32 oldindex, newindex; Int32 oldnum, newnum; Int32 from_num_entities; Int32 bits; MSG.WriteByte(msg, Defines.svc_packetentities); if (from == null) { from_num_entities = 0; } else { from_num_entities = from.num_entities; } newindex = 0; oldindex = 0; while (newindex < to.num_entities || oldindex < from_num_entities) { if (newindex >= to.num_entities) { newnum = 9999; } else { newent = SV_INIT.svs.client_entities[(to.first_entity + newindex) % SV_INIT.svs.num_client_entities]; newnum = newent.number; } if (oldindex >= from_num_entities) { oldnum = 9999; } else { oldent = SV_INIT.svs.client_entities[(from.first_entity + oldindex) % SV_INIT.svs.num_client_entities]; oldnum = oldent.number; } if (newnum == oldnum) { MSG.WriteDeltaEntity(oldent, newent, msg, false, newent.number <= SV_MAIN.maxclients.value); oldindex++; newindex++; continue; } if (newnum < oldnum) { MSG.WriteDeltaEntity(SV_INIT.sv.baselines[newnum], newent, msg, true, true); newindex++; continue; } if (newnum > oldnum) { bits = Defines.U_REMOVE; if (oldnum >= 256) { bits |= Defines.U_NUMBER16 | Defines.U_MOREBITS1; } MSG.WriteByte(msg, bits & 255); if ((bits & 0x0000ff00) != 0) { MSG.WriteByte(msg, (bits >> 8) & 255); } if ((bits & Defines.U_NUMBER16) != 0) { MSG.WriteShort(msg, oldnum); } else { MSG.WriteByte(msg, oldnum); } oldindex++; continue; } } MSG.WriteShort(msg, 0); }
public static byte[] fatpvs = new byte[65536 / 8]; // 32767 is MAX_MAP_LEAFS /* * ============================================================================= * * Encode a client frame onto the network channel * * ============================================================================= */ /** * Writes a delta update of an entity_state_t list to the message. */ private static void SV_EmitPacketEntities(client_frame_t from, client_frame_t to, sizebuf_t msg) { entity_state_t oldent = null, newent = null; int oldindex, newindex; int oldnum, newnum; int from_num_entities; int bits; MSG.WriteByte(msg, Defines.svc_packetentities); if (from == null) { from_num_entities = 0; } else { from_num_entities = from.num_entities; } newindex = 0; oldindex = 0; while (newindex < to.num_entities || oldindex < from_num_entities) { if (newindex >= to.num_entities) { newnum = 9999; } else { newent = SV_INIT.svs.client_entities[(to.first_entity + newindex) % SV_INIT.svs.num_client_entities]; newnum = newent.number; } if (oldindex >= from_num_entities) { oldnum = 9999; } else { oldent = SV_INIT.svs.client_entities[(from.first_entity + oldindex) % SV_INIT.svs.num_client_entities]; oldnum = oldent.number; } if (newnum == oldnum) { // delta update from old position // because the force parm is false, this will not result // in any bytes being emited if the entity has not changed at // all note that players are always 'newentities', this updates // their oldorigin always // and prevents warping MSG.WriteDeltaEntity(oldent, newent, msg, false, newent.number <= SV_MAIN.maxclients.value); oldindex++; newindex++; continue; } if (newnum < oldnum) { // this is a new entity, send it from the baseline MSG.WriteDeltaEntity(SV_INIT.sv.baselines[newnum], newent, msg, true, true); newindex++; continue; } if (newnum > oldnum) { // the old entity isn't present in the new message bits = Defines.U_REMOVE; if (oldnum >= 256) { bits |= Defines.U_NUMBER16 | Defines.U_MOREBITS1; } MSG.WriteByte(msg, bits & 255); if ((bits & 0x0000ff00) != 0) { MSG.WriteByte(msg, (bits >> 8) & 255); } if ((bits & Defines.U_NUMBER16) != 0) { MSG.WriteShort(msg, oldnum); } else { MSG.WriteByte(msg, oldnum); } oldindex++; continue; } } MSG.WriteShort(msg, 0); // end of packetentities }