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); }
/** * 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); }