void sendPos() { bufin = SerializeNetchan(1, 2); Netchan net = deserializeNetchan(bufin); print("Sending...\nProtocol: " + net.Protocol + "\nSequence: " + net.Sequence + "\nAck: " + net.Ack); client.Send(bufin, bufin.Length); bufout = client.Receive(ref ep); net = deserializeNetchan(bufout); Player p = net.Players(0).Value; print("Receiving...\nProtocol: " + net.Protocol + "\nSequence: " + net.Sequence + "\nAck: " + net.Ack + "\n x: " + p.Rot.Value.X + "\n y: " + p.Rot.Value.Y + "\n z: " + p.Rot.Value.Z); print(net.ByteBuffer.Data); var i = 0; foreach (Transform t in networkedPlayers) { i++; t.position = new Vector3(p.Pos.Value.X, p.Pos.Value.Y, (float)p.Pos.Value.Z + 2 * i); t.eulerAngles = new Vector3(p.Rot.Value.X, p.Rot.Value.Y, p.Rot.Value.Z); //t.rotation = new Quaternion(p.Rot.Value.X, p.Rot.Value.Y, p.Rot.Value.Z, 0); } }
public static void SVC_Info( ) { String string_renamed; Int32 i, count; Int32 version; if (SV_MAIN.maxclients.value == 1) { return; } version = Lib.Atoi(Cmd.Argv(1)); if (version != Defines.PROTOCOL_VERSION) { string_renamed = SV_MAIN.hostname.string_renamed + ": wrong version\\n"; } else { count = 0; for (i = 0; i < SV_MAIN.maxclients.value; i++) { if (SV_INIT.svs.clients[i].state >= Defines.cs_connected) { count++; } } string_renamed = SV_MAIN.hostname.string_renamed + " " + SV_INIT.sv.name + " " + count + "/" + ( Int32 )SV_MAIN.maxclients.value + "\\n"; } Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "info\\n" + string_renamed); }
public byte[] SerializeNetchan(int seq, int ack) { var builder = new FlatBufferBuilder(1); var plays = new Offset <Player> [1]; Player.StartPlayer(builder); Player.AddId(builder, 1); var pos = Vec3.CreateVec3(builder, player.position.x, player.position.y, player.position.z); Player.AddPos(builder, pos); var rot = Vec3.CreateVec3(builder, player.localEulerAngles.x, player.localEulerAngles.y, player.localEulerAngles.z); Player.AddRot(builder, rot); var p1 = Player.EndPlayer(builder); plays[0] = p1; // serialize FlatBuffer data var players = Netchan.CreatePlayersVector(builder, plays); Netchan.StartNetchan(builder); Netchan.AddProtocol(builder, 1234); Netchan.AddSequence(builder, seq); Netchan.AddAck(builder, ack); Netchan.AddPlayers(builder, players); var net = Netchan.EndNetchan(builder); builder.Finish(net.Value); var buf = builder.SizedByteArray(); return(buf); }
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 void SVC_GetChallenge( ) { Int32 i; Int32 oldest; Int32 oldestTime; oldest = 0; oldestTime = 0x7fffffff; for (i = 0; i < Defines.MAX_CHALLENGES; i++) { if (NET.CompareBaseAdr(Globals.net_from, SV_INIT.svs.challenges[i].adr)) { break; } if (SV_INIT.svs.challenges[i].time < oldestTime) { oldestTime = SV_INIT.svs.challenges[i].time; oldest = i; } } if (i == Defines.MAX_CHALLENGES) { SV_INIT.svs.challenges[oldest].challenge = Lib.Rand() & 0x7fff; SV_INIT.svs.challenges[oldest].adr = Globals.net_from; SV_INIT.svs.challenges[oldest].time = ( Int32 )Globals.curtime; i = oldest; } Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "challenge " + SV_INIT.svs.challenges[i].challenge); }
public static void Master_Heartbeat( ) { String string_renamed; Int32 i; if (Globals.dedicated == null || 0 == Globals.dedicated.value) { return; } if (null == SV_MAIN.public_server || 0 == SV_MAIN.public_server.value) { return; } if (SV_INIT.svs.last_heartbeat > SV_INIT.svs.realtime) { SV_INIT.svs.last_heartbeat = SV_INIT.svs.realtime; } if (SV_INIT.svs.realtime - SV_INIT.svs.last_heartbeat < SV_MAIN.HEARTBEAT_SECONDS * 1000) { return; } SV_INIT.svs.last_heartbeat = SV_INIT.svs.realtime; string_renamed = SV_StatusString(); for (i = 0; i < Defines.MAX_MASTERS; i++) { if (SV_MAIN.master_adr[i].port != 0) { Com.Printf("Sending heartbeat to " + NET.AdrToString(SV_MAIN.master_adr[i]) + "\\n"); Netchan.OutOfBandPrint(Defines.NS_SERVER, SV_MAIN.master_adr[i], "heartbeat\\n" + string_renamed); } } }
/** * SVC_Info, responds with short info for broadcast scans The second parameter should * be the current protocol version number. */ public static void SVC_Info() { string @string; int i, count; int version; if (SV_MAIN.maxclients.value == 1) { return; // ignore in single player } version = Lib.atoi(Cmd.Argv(1)); if (version != Defines.PROTOCOL_VERSION) { @string = SV_MAIN.hostname.@string + ": wrong version\n"; } else { count = 0; for (i = 0; i < SV_MAIN.maxclients.value; i++) { if (SV_INIT.svs.clients[i].state >= Defines.cs_connected) { count++; } } @string = SV_MAIN.hostname.@string + " " + SV_INIT.sv.name + " " + count + "/" + (int)SV_MAIN.maxclients.value + "\n"; } Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "info\n" + @string); }
public static void SV_FinalMessage(String message, Boolean reconnect) { Int32 i; client_t cl; SZ.Clear(Globals.net_message); MSG.WriteByte(Globals.net_message, Defines.svc_print); MSG.WriteByte(Globals.net_message, Defines.PRINT_HIGH); MSG.WriteString(Globals.net_message, message); if (reconnect) { MSG.WriteByte(Globals.net_message, Defines.svc_reconnect); } else { MSG.WriteByte(Globals.net_message, Defines.svc_disconnect); } for (i = 0; i < SV_INIT.svs.clients.Length; i++) { cl = SV_INIT.svs.clients[i]; if (cl.state >= Defines.cs_connected) { Netchan.Transmit(cl.netchan, Globals.net_message.cursize, Globals.net_message.data); } } for (i = 0; i < SV_INIT.svs.clients.Length; i++) { cl = SV_INIT.svs.clients[i]; if (cl.state >= Defines.cs_connected) { Netchan.Transmit(cl.netchan, Globals.net_message.cursize, Globals.net_message.data); } } }
/** * Master_Shutdown, Informs all masters that this server is going down. */ public static void Master_Shutdown() { int i; // pgm post3.19 change, cvar pointer not validated before dereferencing if (null == Globals.dedicated || 0 == Globals.dedicated.value) { return; // only dedicated servers send heartbeats } // pgm post3.19 change, cvar pointer not validated before dereferencing if (null == SV_MAIN.public_server || 0 == SV_MAIN.public_server.value) { return; // a private dedicated game } // send to group master for (i = 0; i < Defines.MAX_MASTERS; i++) { if (SV_MAIN.master_adr[i].port != 0) { if (i > 0) { Com.Printf("Sending heartbeat to " + NET.AdrToString(SV_MAIN.master_adr[i]) + "\n"); } Netchan.OutOfBandPrint(Defines.NS_SERVER, SV_MAIN.master_adr[i], "shutdown"); } } }
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_ReadPackets( ) { Int32 i; client_t cl; var qport = 0; while (NET.GetPacket(Defines.NS_SERVER, Globals.net_from, Globals.net_message)) { if ((Globals.net_message.data[0] == -1) && (Globals.net_message.data[1] == -1) && (Globals.net_message.data[2] == -1) && (Globals.net_message.data[3] == -1)) { SV_ConnectionlessPacket(); continue; } MSG.BeginReading(Globals.net_message); MSG.ReadLong(Globals.net_message); MSG.ReadLong(Globals.net_message); qport = MSG.ReadShort(Globals.net_message) & 0xffff; for (i = 0; i < SV_MAIN.maxclients.value; i++) { cl = SV_INIT.svs.clients[i]; if (cl.state == Defines.cs_free) { continue; } if (!NET.CompareBaseAdr(Globals.net_from, cl.netchan.remote_address)) { continue; } if (cl.netchan.qport != qport) { continue; } if (cl.netchan.remote_address.port != Globals.net_from.port) { Com.Printf("SV_ReadPackets: fixing up a translated port\\n"); cl.netchan.remote_address.port = Globals.net_from.port; } if (Netchan.Process(cl.netchan, Globals.net_message)) { if (cl.state != Defines.cs_zombie) { cl.lastmessage = SV_INIT.svs.realtime; SV_USER.SV_ExecuteClientMessage(cl); } } break; } if (i != SV_MAIN.maxclients.value) { continue; } } }
/** * Initializes player structures after successfull connection. */ public static void gotnewcl(int i, int challenge, string userinfo, netadr_t adr, int qport) { // build a new connection // accept the new client // this is the only place a client_t is ever initialized SV_MAIN.sv_client = SV_INIT.svs.clients[i]; var edictnum = i + 1; var ent = GameBase.g_edicts[edictnum]; SV_INIT.svs.clients[i].edict = ent; // save challenge for checksumming SV_INIT.svs.clients[i].challenge = challenge; // get the game a chance to reject this connection or modify the // userinfo 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; } // parse some info from the info strings SV_INIT.svs.clients[i].userinfo = userinfo; SV_MAIN.SV_UserinfoChanged(SV_INIT.svs.clients[i]); // send the connect packet to the client 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; // don't timeout SV_INIT.svs.clients[i].lastconnect = SV_INIT.svs.realtime; Com.DPrintf("new client added.\n"); }
/* * =============================================================================== * * OPERATOR CONSOLE ONLY COMMANDS * * These commands can only be entered from stdin or by a remote operator datagram * =============================================================================== */ /* * ==================== * SV_SetMaster_f * * Specify a list of master servers * ==================== */ public static void SV_SetMaster_f() { int i, slot; // only dedicated servers send heartbeats if (Globals.dedicated.value == 0) { Com.Printf("Only dedicated servers use masters.\n"); return; } // make sure the server is listed public Cvar.Set("public", "1"); for (i = 1; i < Defines.MAX_MASTERS; i++) { SV_MAIN.master_adr[i] = new(); } slot = 1; // slot 0 will always contain the id master for (i = 1; i < Cmd.Argc(); i++) { if (slot == Defines.MAX_MASTERS) { break; } if (!NET.StringToAdr(Cmd.Argv(i), SV_MAIN.master_adr[i])) { Com.Printf("Bad address: " + Cmd.Argv(i) + "\n"); continue; } if (SV_MAIN.master_adr[slot].port == 0) { SV_MAIN.master_adr[slot].port = Defines.PORT_MASTER; } Com.Printf("Master server at " + NET.AdrToString(SV_MAIN.master_adr[slot]) + "\n"); Com.Printf("Sending a ping.\n"); Netchan.OutOfBandPrint(Defines.NS_SERVER, SV_MAIN.master_adr[slot], "ping"); slot++; } SV_INIT.svs.last_heartbeat = -9999999; }
public static void SV_FlushRedirect(Int32 sv_redirected, Byte[] outputbuf) { if (sv_redirected == Defines.RD_PACKET) { var s = ("print\\n" + Lib.CtoJava(outputbuf)); Netchan.Netchan_OutOfBand(Defines.NS_SERVER, Globals.net_from, s.Length, Lib.StringToBytes(s)); } else if (sv_redirected == Defines.RD_CLIENT) { MSG.WriteByte(SV_MAIN.sv_client.netchan.message, Defines.svc_print); MSG.WriteByte(SV_MAIN.sv_client.netchan.message, Defines.PRINT_HIGH); MSG.WriteString(SV_MAIN.sv_client.netchan.message, outputbuf); } }
/** * Used by SV_Shutdown to send a final message to all connected clients * before the server goes down. The messages are sent immediately, not just * stuck on the outgoing message list, because the server is going to * totally exit after returning from this function. */ public static void SV_FinalMessage(string message, bool reconnect) { int i; client_t cl; SZ.Clear(Globals.net_message); MSG.WriteByte(Globals.net_message, Defines.svc_print); MSG.WriteByte(Globals.net_message, Defines.PRINT_HIGH); MSG.WriteString(Globals.net_message, message); if (reconnect) { MSG.WriteByte(Globals.net_message, Defines.svc_reconnect); } else { MSG.WriteByte(Globals.net_message, Defines.svc_disconnect); } // send it twice // stagger the packets to crutch operating system limited buffers for (i = 0; i < SV_INIT.svs.clients.Length; i++) { cl = SV_INIT.svs.clients[i]; if (cl.state >= Defines.cs_connected) { Netchan.Transmit(cl.netchan, Globals.net_message.cursize, Globals.net_message.data); } } for (i = 0; i < SV_INIT.svs.clients.Length; i++) { cl = SV_INIT.svs.clients[i]; if (cl.state >= Defines.cs_connected) { Netchan.Transmit(cl.netchan, Globals.net_message.cursize, Globals.net_message.data); } } }
public Netchan deserializeNetchan(byte[] buf) { var bb = new ByteBuffer(buf); var netchan = Netchan.GetRootAsNetchan(bb); //print(netchan.PlayersLength); /*var protocol = netchan.Protocol; * var sequence = netchan.Sequence; * var ack = netchan.Ack; * var player = (Player) netchan.Players; * var vec3 = (Vec3)player.Pos; * var x = vec3.X; * var y = vec3.Y; * var z = vec3.Z; * var n = new netchan(protocol, sequence, ack, x, y, z); */ return(netchan); }
public static void Master_Heartbeat() { string @string; int i; // pgm post3.19 change, cvar pointer not validated before dereferencing if (Globals.dedicated == null || 0 == Globals.dedicated.value) { return; // only dedicated servers send heartbeats } // pgm post3.19 change, cvar pointer not validated before dereferencing if (null == SV_MAIN.public_server || 0 == SV_MAIN.public_server.value) { return; // a private dedicated game } // check for time wraparound if (SV_INIT.svs.last_heartbeat > SV_INIT.svs.realtime) { SV_INIT.svs.last_heartbeat = SV_INIT.svs.realtime; } if (SV_INIT.svs.realtime - SV_INIT.svs.last_heartbeat < SV_MAIN.HEARTBEAT_SECONDS * 1000) { return; // not time to send yet } SV_INIT.svs.last_heartbeat = SV_INIT.svs.realtime; // send the same string that we would give for a status OOB command @string = SV_MAIN.SV_StatusString(); // send to group master for (i = 0; i < Defines.MAX_MASTERS; i++) { if (SV_MAIN.master_adr[i].port != 0) { Com.Printf("Sending heartbeat to " + NET.AdrToString(SV_MAIN.master_adr[i]) + "\n"); Netchan.OutOfBandPrint(Defines.NS_SERVER, SV_MAIN.master_adr[i], "heartbeat\n" + @string); } } }
public static void Master_Shutdown( ) { Int32 i; if (null == Globals.dedicated || 0 == Globals.dedicated.value) { return; } if (null == SV_MAIN.public_server || 0 == SV_MAIN.public_server.value) { return; } for (i = 0; i < Defines.MAX_MASTERS; i++) { if (SV_MAIN.master_adr[i].port != 0) { if (i > 0) { Com.Printf("Sending heartbeat to " + NET.AdrToString(SV_MAIN.master_adr[i]) + "\\n"); } Netchan.OutOfBandPrint(Defines.NS_SERVER, SV_MAIN.master_adr[i], "shutdown"); } } }
/** * Returns a challenge number that can be used in a subsequent * client_connect command. We do this to prevent denial of service attacks * that flood the server with invalid connection IPs. With a challenge, they * must give a valid IP address. */ public static void SVC_GetChallenge() { int i; int oldest; int oldestTime; oldest = 0; oldestTime = 0x7fffffff; // see if we already have a challenge for this ip for (i = 0; i < Defines.MAX_CHALLENGES; i++) { if (NET.CompareBaseAdr(Globals.net_from, SV_INIT.svs.challenges[i].adr)) { break; } if (SV_INIT.svs.challenges[i].time < oldestTime) { oldestTime = SV_INIT.svs.challenges[i].time; oldest = i; } } if (i == Defines.MAX_CHALLENGES) { // overwrite the oldest SV_INIT.svs.challenges[oldest].challenge = Lib.rand() & 0x7fff; SV_INIT.svs.challenges[oldest].adr = Globals.net_from; SV_INIT.svs.challenges[oldest].time = (int)Globals.curtime; i = oldest; } // send it back Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "challenge " + SV_INIT.svs.challenges[i].challenge); }
public static void SVC_Status( ) { Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "print\\n" + SV_StatusString()); }
/** * A connection request that did not come from the master. */ public static void SVC_DirectConnect() { string userinfo; netadr_t adr; int i; client_t cl; int version; int qport; adr = Globals.net_from; Com.DPrintf("SVC_DirectConnect ()\n"); version = Lib.atoi(Cmd.Argv(1)); if (version != Defines.PROTOCOL_VERSION) { Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nServer is version " + Globals.VERSION + "\n"); Com.DPrintf(" rejected connect from version " + version + "\n"); return; } qport = Lib.atoi(Cmd.Argv(2)); var challenge = Lib.atoi(Cmd.Argv(3)); userinfo = Cmd.Argv(4); // force the IP key/value pair so the game can filter based on ip userinfo = Info.Info_SetValueForKey(userinfo, "ip", NET.AdrToString(Globals.net_from)); // attractloop servers are ONLY for local clients if (SV_INIT.sv.attractloop) { if (!NET.IsLocalAddress(adr)) { Com.Printf("Remote connect in attract loop. Ignored.\n"); Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nConnection refused.\n"); return; } } // see if the challenge is valid if (!NET.IsLocalAddress(adr)) { for (i = 0; i < Defines.MAX_CHALLENGES; i++) { if (NET.CompareBaseAdr(Globals.net_from, SV_INIT.svs.challenges[i].adr)) { if (challenge == SV_INIT.svs.challenges[i].challenge) { break; // good } Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nBad challenge.\n"); return; } } if (i == Defines.MAX_CHALLENGES) { Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nNo challenge for address.\n"); return; } } // if there is already a slot for this ip, reuse it for (i = 0; i < SV_MAIN.maxclients.value; i++) { cl = SV_INIT.svs.clients[i]; if (cl.state == Defines.cs_free) { continue; } if (NET.CompareBaseAdr(adr, cl.netchan.remote_address) && (cl.netchan.qport == qport || adr.port == cl.netchan.remote_address.port)) { if (!NET.IsLocalAddress(adr) && SV_INIT.svs.realtime - cl.lastconnect < (int)SV_MAIN.sv_reconnect_limit.value * 1000) { Com.DPrintf(NET.AdrToString(adr) + ":reconnect rejected : too soon\n"); return; } Com.Printf(NET.AdrToString(adr) + ":reconnect\n"); SV_MAIN.gotnewcl(i, challenge, userinfo, adr, qport); return; } } // find a client slot //newcl = null; var index = -1; for (i = 0; i < SV_MAIN.maxclients.value; i++) { cl = SV_INIT.svs.clients[i]; if (cl.state == Defines.cs_free) { index = i; break; } } if (index == -1) { Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\nServer is full.\n"); Com.DPrintf("Rejected a connection.\n"); return; } SV_MAIN.gotnewcl(index, challenge, userinfo, adr, qport); }
/** * Reads packets from the network or loopback. */ public static void SV_ReadPackets() { int i; client_t cl; var qport = 0; while (NET.GetPacket(Defines.NS_SERVER, Globals.net_from, Globals.net_message)) { // check for connectionless packet (0xffffffff) first if (Globals.net_message.data[0] == 255 && Globals.net_message.data[1] == 255 && Globals.net_message.data[2] == 255 && Globals.net_message.data[3] == 255) { SV_MAIN.SV_ConnectionlessPacket(); continue; } // read the qport out of the message so we can fix up // stupid address translating routers MSG.BeginReading(Globals.net_message); MSG.ReadLong(Globals.net_message); // sequence number MSG.ReadLong(Globals.net_message); // sequence number qport = MSG.ReadShort(Globals.net_message) & 0xffff; // check for packets from connected clients for (i = 0; i < SV_MAIN.maxclients.value; i++) { cl = SV_INIT.svs.clients[i]; if (cl.state == Defines.cs_free) { continue; } if (!NET.CompareBaseAdr(Globals.net_from, cl.netchan.remote_address)) { continue; } if (cl.netchan.qport != qport) { continue; } if (cl.netchan.remote_address.port != Globals.net_from.port) { Com.Printf("SV_ReadPackets: fixing up a translated port\n"); cl.netchan.remote_address.port = Globals.net_from.port; } if (Netchan.Process(cl.netchan, Globals.net_message)) { // this is a valid, sequenced packet, so process it if (cl.state != Defines.cs_zombie) { cl.lastmessage = SV_INIT.svs.realtime; // don't timeout SV_USER.SV_ExecuteClientMessage(cl); } } break; } if (i != SV_MAIN.maxclients.value) { continue; } } }
public static void SVC_DirectConnect( ) { String userinfo; netadr_t adr; Int32 i; client_t cl; Int32 version; Int32 qport; adr = Globals.net_from; Com.DPrintf("SVC_DirectConnect ()\\n"); version = Lib.Atoi(Cmd.Argv(1)); if (version != Defines.PROTOCOL_VERSION) { Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nServer is version " + Globals.VERSION + "\\n"); Com.DPrintf(" rejected connect from version " + version + "\\n"); return; } qport = Lib.Atoi(Cmd.Argv(2)); var challenge = Lib.Atoi(Cmd.Argv(3)); userinfo = Cmd.Argv(4); userinfo = Info.Info_SetValueForKey(userinfo, "ip", NET.AdrToString(Globals.net_from)); if (SV_INIT.sv.attractloop) { if (!NET.IsLocalAddress(adr)) { Com.Printf("Remote connect in attract loop. Ignored.\\n"); Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nConnection refused.\\n"); return; } } if (!NET.IsLocalAddress(adr)) { for (i = 0; i < Defines.MAX_CHALLENGES; i++) { if (NET.CompareBaseAdr(Globals.net_from, SV_INIT.svs.challenges[i].adr)) { if (challenge == SV_INIT.svs.challenges[i].challenge) { break; } Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nBad challenge.\\n"); return; } } if (i == Defines.MAX_CHALLENGES) { Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nNo challenge for address.\\n"); return; } } for (i = 0; i < SV_MAIN.maxclients.value; i++) { cl = SV_INIT.svs.clients[i]; if (cl.state == Defines.cs_free) { continue; } if (NET.CompareBaseAdr(adr, cl.netchan.remote_address) && (cl.netchan.qport == qport || adr.port == cl.netchan.remote_address.port)) { if (!NET.IsLocalAddress(adr) && (SV_INIT.svs.realtime - cl.lastconnect) < (( Int32 )SV_MAIN.sv_reconnect_limit.value * 1000)) { Com.DPrintf(NET.AdrToString(adr) + ":reconnect rejected : too soon\\n"); return; } Com.Printf(NET.AdrToString(adr) + ":reconnect\\n"); Gotnewcl(i, challenge, userinfo, adr, qport); return; } } var index = -1; for (i = 0; i < SV_MAIN.maxclients.value; i++) { cl = SV_INIT.svs.clients[i]; if (cl.state == Defines.cs_free) { index = i; break; } } if (index == -1) { Netchan.OutOfBandPrint(Defines.NS_SERVER, adr, "print\\nServer is full.\\n"); Com.DPrintf("Rejected a connection.\\n"); return; } Gotnewcl(index, challenge, userinfo, adr, qport); }
public static void SVC_Ping( ) { Netchan.OutOfBandPrint(Defines.NS_SERVER, Globals.net_from, "ack"); }
public static void SV_SendClientMessages( ) { Int32 i; client_t c; Int32 msglen; Int32 r; msglen = 0; if (SV_INIT.sv.state == Defines.ss_demo && SV_INIT.sv.demofile != null) { if (SV_MAIN.sv_paused.value != 0) { msglen = 0; } else { try { msglen = EndianHandler.SwapInt(SV_INIT.sv.demofile.ReadInt32()); } catch (Exception e) { SV_DemoCompleted(); return; } if (msglen == -1) { SV_DemoCompleted(); return; } if (msglen > Defines.MAX_MSGLEN) { Com.Error(Defines.ERR_DROP, "SV_SendClientMessages: msglen > MAX_MSGLEN"); } r = 0; try { r = SV_INIT.sv.demofile.Read(msgbuf, 0, msglen); } catch (Exception e1) { Com.Printf("IOError: reading demo file, " + e1); } if (r != msglen) { SV_DemoCompleted(); return; } } } for (i = 0; i < SV_MAIN.maxclients.value; i++) { c = SV_INIT.svs.clients[i]; if (c.state == 0) { continue; } if (c.netchan.message.overflowed) { SZ.Clear(c.netchan.message); SZ.Clear(c.datagram); SV_BroadcastPrintf(Defines.PRINT_HIGH, c.name + " overflowed\\n"); SV_MAIN.SV_DropClient(c); } if (SV_INIT.sv.state == Defines.ss_cinematic || SV_INIT.sv.state == Defines.ss_demo || SV_INIT.sv.state == Defines.ss_pic) { Netchan.Transmit(c.netchan, msglen, msgbuf); } else if (c.state == Defines.cs_spawned) { if (SV_RateDrop(c)) { continue; } SV_SendClientDatagram(c); } else { if (c.netchan.message.cursize != 0 || Globals.curtime - c.netchan.last_sent > 1000) { Netchan.Transmit(c.netchan, 0, NULLBYTE); } } } }
public static void SendCmd() { int i; usercmd_t cmd, oldcmd; int checksumIndex; i = Globals.cls.netchan.outgoing_sequence & (Defines.CMD_BACKUP - 1); cmd = Globals.cl.cmds[i]; Globals.cl.cmd_time[i] = (int)Globals.cls.realtime; CreateCmd(cmd); Globals.cl.cmd.Set(cmd); if (Globals.cls.state == Defines.ca_disconnected || Globals.cls.state == Defines.ca_connecting) { return; } if (Globals.cls.state == Defines.ca_connected) { if (Globals.cls.netchan.message.cursize != 0 || Globals.curtime - Globals.cls.netchan.last_sent > 1000) { Netchan.Transmit(Globals.cls.netchan, 0, new byte[0]); } return; } if (Globals.userinfo_modified) { CL.FixUpGender(); Globals.userinfo_modified = false; MSG.WriteByte(Globals.cls.netchan.message, Defines.clc_userinfo); MSG.WriteString(Globals.cls.netchan.message, Cvar.Userinfo()); } SZ.Init(buf, data, data.Length); if (cmd.buttons != 0 && Globals.cl.cinematictime > 0 && !Globals.cl.attractloop && Globals.cls.realtime - Globals.cl.cinematictime > 1000) { SCR.FinishCinematic(); } MSG.WriteByte(buf, Defines.clc_move); checksumIndex = buf.cursize; MSG.WriteByte(buf, 0); if (cl_nodelta.value != 0F || !Globals.cl.frame.valid || Globals.cls.demowaiting) { MSG.WriteLong(buf, -1); } else { MSG.WriteLong(buf, Globals.cl.frame.serverframe); } i = (Globals.cls.netchan.outgoing_sequence - 2) & (Defines.CMD_BACKUP - 1); cmd = Globals.cl.cmds[i]; nullcmd.Clear(); MSG.WriteDeltaUsercmd(buf, nullcmd, cmd); oldcmd = cmd; i = (Globals.cls.netchan.outgoing_sequence - 1) & (Defines.CMD_BACKUP - 1); cmd = Globals.cl.cmds[i]; MSG.WriteDeltaUsercmd(buf, oldcmd, cmd); oldcmd = cmd; i = (Globals.cls.netchan.outgoing_sequence) & (Defines.CMD_BACKUP - 1); cmd = Globals.cl.cmds[i]; MSG.WriteDeltaUsercmd(buf, oldcmd, cmd); buf.data[checksumIndex] = Com.BlockSequenceCRCByte(buf.data, checksumIndex + 1, buf.cursize - checksumIndex - 1, Globals.cls.netchan.outgoing_sequence); Netchan.Transmit(Globals.cls.netchan, buf.cursize, buf.data); }