public static void SV_UserinfoChanged(client_t cl) { String val; Int32 i; PlayerClient.ClientUserinfoChanged(cl.edict, cl.userinfo); cl.name = Info.Info_ValueForKey(cl.userinfo, "name"); val = Info.Info_ValueForKey(cl.userinfo, "rate"); if (val.Length > 0) { i = Lib.Atoi(val); cl.rate = i; if (cl.rate < 100) { cl.rate = 100; } if (cl.rate > 15000) { cl.rate = 15000; } } else { cl.rate = 5000; } val = Info.Info_ValueForKey(cl.userinfo, "msg"); if (val.Length > 0) { cl.messagelevel = Lib.Atoi(val); } }
public static void Gotnewcl(Int32 i, Int32 challenge, String userinfo, netadr_t adr, Int32 qport) { SV_MAIN.sv_client = SV_INIT.svs.clients[i]; var edictnum = i + 1; edict_t ent = GameBase.g_edicts[edictnum]; SV_INIT.svs.clients[i].edict = ent; SV_INIT.svs.clients[i].challenge = challenge; if (!(PlayerClient.ClientConnect(ent, userinfo))) { if (Info.Info_ValueForKey(userinfo, "rejmsg") != null) { Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\n" + Info.Info_ValueForKey(userinfo, "rejmsg") + "\\nConnection refused.\\n"); } else { Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nConnection refused.\\n"); } Com.DPrintf("Game rejected a connection.\\n"); return; } SV_INIT.svs.clients[i].userinfo = userinfo; SV_UserinfoChanged(SV_INIT.svs.clients[i]); Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "client_connect"); Netchan.Setup(Defines.NS_SERVER, SV_INIT.svs.clients[i].netchan, adr, qport); SV_INIT.svs.clients[i].state = Defines.cs_connected; SZ.Init(SV_INIT.svs.clients[i].datagram, SV_INIT.svs.clients[i].datagram_buf, SV_INIT.svs.clients[i].datagram_buf.Length); SV_INIT.svs.clients[i].datagram.allowoverflow = true; SV_INIT.svs.clients[i].lastmessage = SV_INIT.svs.realtime; SV_INIT.svs.clients[i].lastconnect = SV_INIT.svs.realtime; Com.DPrintf("new client added.\\n"); }
public static Boolean SV_SendClientDatagram(client_t client) { SV_ENTS.SV_BuildClientFrame(client); SZ.Init(msg, msgbuf, msgbuf.Length); msg.allowoverflow = true; SV_ENTS.SV_WriteFrameToClient(client, msg); if (client.datagram.overflowed) { Com.Printf("WARNING: datagram overflowed for " + client.name + "\\n"); } else { SZ.Write(msg, client.datagram.data, client.datagram.cursize); } SZ.Clear(client.datagram); if (msg.overflowed) { Com.Printf("WARNING: msg overflowed for " + client.name + "\\n"); SZ.Clear(msg); } Netchan.Transmit(client.netchan, msg.cursize, msg.data); client.message_size[SV_INIT.sv.framenum % Defines.RATE_MESSAGES] = msg.cursize; return(true); }
public static void SV_WriteFrameToClient(client_t client, sizebuf_t msg) { client_frame_t frame, oldframe; Int32 lastframe; frame = client.frames[SV_INIT.sv.framenum & Defines.UPDATE_MASK]; if (client.lastframe <= 0) { oldframe = null; lastframe = -1; } else if (SV_INIT.sv.framenum - client.lastframe >= (Defines.UPDATE_BACKUP - 3)) { oldframe = null; lastframe = -1; } else { oldframe = client.frames[client.lastframe & Defines.UPDATE_MASK]; lastframe = client.lastframe; } MSG.WriteByte(msg, Defines.svc_frame); MSG.WriteLong(msg, SV_INIT.sv.framenum); MSG.WriteLong(msg, lastframe); MSG.WriteByte(msg, client.surpressCount); client.surpressCount = 0; MSG.WriteByte(msg, frame.areabytes); SZ.Write(msg, frame.areabits, frame.areabytes); SV_WritePlayerstateToClient(oldframe, frame, msg); SV_EmitPacketEntities(oldframe, frame, msg); }
public static void SV_ClientPrintf(client_t cl, Int32 level, String s) { if (level < cl.messagelevel) { return; } MSG.WriteByte(cl.netchan.message, Defines.svc_print); MSG.WriteByte(cl.netchan.message, level); MSG.WriteString(cl.netchan.message, s); }
public static void SV_ClientThink(client_t cl, usercmd_t cmd) { cl.commandMsec -= cmd.msec & 0xFF; if (cl.commandMsec < 0 && SV_MAIN.sv_enforcetime.value != 0) { Com.DPrintf("commandMsec underflow from " + cl.name + "\\n"); return; } PlayerClient.ClientThink(cl.edict, cmd); }
public static void SV_DropClient(client_t drop) { MSG.WriteByte(drop.netchan.message, Defines.svc_disconnect); if (drop.state == Defines.cs_spawned) { PlayerClient.ClientDisconnect(drop.edict); } if (drop.download != null) { FS.FreeFile(drop.download); drop.download = null; } drop.state = Defines.cs_zombie; drop.name = ""; }
public static Boolean SV_RateDrop(client_t c) { Int32 total; Int32 i; if (c.netchan.remote_address.type == Defines.NA_LOOPBACK) { return(false); } total = 0; for (i = 0; i < Defines.RATE_MESSAGES; i++) { total += c.message_size[i]; } if (total > c.rate) { c.surpressCount++; c.message_size[SV_INIT.sv.framenum % Defines.RATE_MESSAGES] = 0; return(true); } return(false); }
public static void SV_BuildClientFrame(client_t client) { Int32 e, i; Single[] org = new Single[] { 0, 0, 0 }; edict_t ent; edict_t clent; client_frame_t frame; entity_state_t state; Int32 l; Int32 clientarea, clientcluster; Int32 leafnum; Int32 c_fullsend; Byte[] clientphs; Byte[] bitvector; clent = client.edict; if (clent.client == null) { return; } frame = client.frames[SV_INIT.sv.framenum & Defines.UPDATE_MASK]; frame.senttime = SV_INIT.svs.realtime; for (i = 0; i < 3; i++) { org[i] = clent.client.ps.pmove.origin[i] * 0.125F + clent.client.ps.viewoffset[i]; } leafnum = CM.CM_PointLeafnum(org); clientarea = CM.CM_LeafArea(leafnum); clientcluster = CM.CM_LeafCluster(leafnum); frame.areabytes = CM.CM_WriteAreaBits(frame.areabits, clientarea); frame.ps.Set(clent.client.ps); SV_FatPVS(org); clientphs = CM.CM_ClusterPHS(clientcluster); frame.num_entities = 0; frame.first_entity = SV_INIT.svs.next_client_entities; c_fullsend = 0; for (e = 1; e < GameBase.num_edicts; e++) { ent = GameBase.g_edicts[e]; if ((ent.svflags & Defines.SVF_NOCLIENT) != 0) { continue; } if (0 == ent.s.modelindex && 0 == ent.s.effects && 0 == ent.s.sound && 0 == ent.s.event_renamed) { continue; } if (ent != clent) { if (!CM.CM_AreasConnected(clientarea, ent.areanum)) { if (0 == ent.areanum2 || !CM.CM_AreasConnected(clientarea, ent.areanum2)) { continue; } } if ((ent.s.renderfx & Defines.RF_BEAM) != 0) { l = ent.clusternums[0]; if (0 == (clientphs[l >> 3] & (1 << (l & 7)))) { continue; } } else { if (ent.s.sound == 0) { bitvector = SV_ENTS.fatpvs; } else { bitvector = SV_ENTS.fatpvs; } if (ent.num_clusters == -1) { if (!CM.CM_HeadnodeVisible(ent.headnode, bitvector)) { continue; } c_fullsend++; } else { for (i = 0; i < ent.num_clusters; i++) { l = ent.clusternums[i]; if ((bitvector[l >> 3] & (1 << (l & 7))) != 0) { break; } } if (i == ent.num_clusters) { continue; } } if (ent.s.modelindex == 0) { Single[] delta = new Single[] { 0, 0, 0 }; Single len; Math3D.VectorSubtract(org, ent.s.origin, delta); len = Math3D.VectorLength(delta); if (len > 400) { continue; } } } } var ix = SV_INIT.svs.next_client_entities % SV_INIT.svs.num_client_entities; state = SV_INIT.svs.client_entities[ix]; if (ent.s.number != e) { Com.DPrintf("FIXING ENT.S.NUMBER!!!\\n"); ent.s.number = e; } SV_INIT.svs.client_entities[ix].Set(ent.s); if (ent.owner == client.edict) { state.solid = 0; } SV_INIT.svs.next_client_entities++; frame.num_entities++; } }
public static void SV_ExecuteClientMessage(client_t cl) { Int32 c; String s; usercmd_t nullcmd = new usercmd_t(); usercmd_t oldest = new usercmd_t(), oldcmd = new usercmd_t(), newcmd = new usercmd_t(); Int32 net_drop; Int32 stringCmdCount; Int32 checksum, calculatedChecksum; Int32 checksumIndex; Boolean move_issued; Int32 lastframe; SV_MAIN.sv_client = cl; SV_USER.sv_player = SV_MAIN.sv_client.edict; move_issued = false; stringCmdCount = 0; while (true) { if (Globals.net_message.readcount > Globals.net_message.cursize) { Com.Printf("SV_ReadClientMessage: bad read:\\n"); Com.Printf(Lib.HexDump(Globals.net_message.data, 32, false)); SV_MAIN.SV_DropClient(cl); return; } c = MSG.ReadByte(Globals.net_message); if (c == -1) { break; } switch (c) { default: Com.Printf("SV_ReadClientMessage: unknown command char\\n"); SV_MAIN.SV_DropClient(cl); return; case Defines.clc_nop: break; case Defines.clc_userinfo: cl.userinfo = MSG.ReadString(Globals.net_message); SV_MAIN.SV_UserinfoChanged(cl); break; case Defines.clc_move: if (move_issued) { return; } move_issued = true; checksumIndex = Globals.net_message.readcount; checksum = MSG.ReadByte(Globals.net_message); lastframe = MSG.ReadLong(Globals.net_message); if (lastframe != cl.lastframe) { cl.lastframe = lastframe; if (cl.lastframe > 0) { cl.frame_latency[cl.lastframe & (Defines.LATENCY_COUNTS - 1)] = SV_INIT.svs.realtime - cl.frames[cl.lastframe & Defines.UPDATE_MASK].senttime; } } nullcmd = new usercmd_t(); MSG.ReadDeltaUsercmd(Globals.net_message, nullcmd, oldest); MSG.ReadDeltaUsercmd(Globals.net_message, oldest, oldcmd); MSG.ReadDeltaUsercmd(Globals.net_message, oldcmd, newcmd); if (cl.state != Defines.cs_spawned) { cl.lastframe = -1; break; } calculatedChecksum = Com.BlockSequenceCRCByte(Globals.net_message.data, checksumIndex + 1, Globals.net_message.readcount - checksumIndex - 1, cl.netchan.incoming_sequence); if ((calculatedChecksum & 0xff) != checksum) { Com.DPrintf("Failed command checksum for " + cl.name + " (" + calculatedChecksum + " != " + checksum + ")/" + cl.netchan.incoming_sequence + "\\n"); return; } if (0 == SV_MAIN.sv_paused.value) { net_drop = cl.netchan.dropped; if (net_drop < 20) { while (net_drop > 2) { SV_ClientThink(cl, cl.lastcmd); net_drop--; } if (net_drop > 1) { SV_ClientThink(cl, oldest); } if (net_drop > 0) { SV_ClientThink(cl, oldcmd); } } SV_ClientThink(cl, newcmd); } cl.lastcmd.Set(newcmd); break; case Defines.clc_stringcmd: s = MSG.ReadString(Globals.net_message); if (++stringCmdCount < SV_USER.MAX_STRINGCMDS) { SV_ExecuteUserCommand(s); } if (cl.state == Defines.cs_zombie) { return; } break; } } }