set g_ban_default_bantime 5400 "90 minutes"
set g_ban_default_masksize 3 "whole 255.255.255.0 networks (set to 4 for single IPs); when UID support is compiled in, masksize 0 means banning by UID"
set g_banned_list "" "format: IP remainingtime IP remainingtime ..."
+set g_banned_list_idmode "1" "when set, the IP banning system always uses the ID over the IP address (so a user in a banned IP range can connect if they have a valid signed ID)"
alias bans "sv_cmd bans"
alias ban "sv_cmd ban $*" // usage: ban address(maybe incomplete, like 1.2.3) bantime(seconds)
alias kickban "sv_cmd kickban $*" // usage: kickban # playerno bantime(seconds) masksize(bytes)
}
Tuba_Precache();
-#ifdef UID
- {
- // find the user ID
- string uid;
- registercvar("_cl_userid", "", CVAR_SAVE);
- uid = cvar_string("_cl_userid");
- if(strlen(uid) < 16)
- {
- uid = "";
- for(i = 0; i < 4; ++i)
- uid = strcat(uid, substring(ftos(floor(10000 + random() * 10000)), 1, -1));
- }
- cvar_set("_cl_userid", uid);
- localcmd(strcat("\ncmd uid ", uid, "\n"));
- }
-#endif
-
get_mi_min_max_texcoords(1); // try the CLEVER way first
minimapname = strcat("gfx/", mi_shortname, "_radar.tga");
shortmapname = mi_shortname;
string ColoredTeamName(float t);
void DecodeLevelParms (void);
//void dom_player_join_team(entity pl);
-#ifdef UID
-.float uid_kicktime;
-.string uid;
-#endif
void ClientConnect (void)
{
float t;
else
self.hitplotfh = -1;
-#ifdef UID
- if(clienttype(self) == CLIENTTYPE_REAL)
- if not(self.uid)
- self.uid_kicktime = time + 60;
-#endif
-
if(g_race || g_cts) {
string rr;
if(g_cts)
self.stat_count -= 1;
}
-#ifdef UID
- if(self.uid_kicktime)
- if(time > self.uid_kicktime)
- {
- bprint("^3", self.netname, "^3 was kicked for missing UID.\n");
- dropclient(self);
- return;
- }
-#endif
-
if(sv_maxidle && frametime)
{
// WORKAROUND: only use dropclient in server frames (frametime set). Never use it in cl_movement frames (frametime zero).
tokens = tokenize_console(s);
}
GetCvars(1);
-#ifdef UID
- } else if(cmd == "uid") {
- if not(self.uid)
- {
- self.uid = strzone(argv(1));
- self.uid_kicktime = 0;
- print("Client ", etos(self), " has UID ", self.uid, "\n");
- Ban_MaybeEnforceBan(self);
- }
-#endif
} else if(cmd == "sentcvar") { // new system
if(tokens == 2) // undefined cvar: use the default value on the server then
{
-//DarkPlaces supported extension list, draft version 1.04
-
-//things that don't have extensions yet:
-.float disableclientprediction;
-
-//definitions that id Software left out:
-//these are passed as the 'nomonsters' parameter to traceline/tracebox (yes really this was supported in all quake engines, nomonsters is misnamed)
-float MOVE_NORMAL = 0; // same as FALSE
-float MOVE_NOMONSTERS = 1; // same as TRUE
-float MOVE_MISSILE = 2; // save as movement with .movetype == MOVETYPE_FLYMISSILE
-
-//checkextension function
-//idea: expected by almost everyone
-//darkplaces implementation: LordHavoc
-float(string s) checkextension = #99;
-//description:
-//check if (cvar("pr_checkextension")) before calling this, this is the only
-//guaranteed extension to be present in the extension system, it allows you
-//to check if an extension is available, by name, to check for an extension
-//use code like this:
-//// (it is recommended this code be placed in worldspawn or a worldspawn called function somewhere)
-//if (cvar("pr_checkextension"))
-//if (checkextension("DP_SV_SETCOLOR"))
-// ext_setcolor = TRUE;
-//from then on you can check ext_setcolor to know if that extension is available
-
-//BX_WAL_SUPPORT
-//idea: id Software
-//darkplaces implementation: LordHavoc
-//description:
-//indicates the engine supports .wal textures for filenames in the textures/ directory
-//(note: DarkPlaces has supported this since 2001 or 2002, but did not advertise it as an extension, then I noticed Betwix was advertising it and added the extension accordingly)
-
-//DP_BUTTONCHAT
-//idea: Vermeulen
-//darkplaces implementation: LordHavoc
-//field definitions:
-.float buttonchat;
-//description:
-//true if the player is currently chatting (in messagemode, menus or console)
-
-//DP_BUTTONUSE
-//idea: id Software
-//darkplaces implementation: LordHavoc
-//field definitions:
-.float buttonuse;
-//client console commands:
-//+use
-//-use
-//description:
-//made +use and -use commands work, they now control the .buttonuse field (.button1 was used by many mods for other purposes).
-
-//DP_CL_LOADSKY
-//idea: Nehahra, LordHavoc
-//darkplaces implementation: LordHavoc
-//client console commands:
+ //DarkPlaces supported extension list, draft version 1.04
+
+ //things that don't have extensions yet:
+ .float disableclientprediction;
+
+ //definitions that id Software left out:
+ //these are passed as the 'nomonsters' parameter to traceline/tracebox (yes really this was supported in all quake engines, nomonsters is misnamed)
+ float MOVE_NORMAL = 0; // same as FALSE
+ float MOVE_NOMONSTERS = 1; // same as TRUE
+ float MOVE_MISSILE = 2; // save as movement with .movetype == MOVETYPE_FLYMISSILE
+
+ //checkextension function
+ //idea: expected by almost everyone
+ //darkplaces implementation: LordHavoc
+ float(string s) checkextension = #99;
+ //description:
+ //check if (cvar("pr_checkextension")) before calling this, this is the only
+ //guaranteed extension to be present in the extension system, it allows you
+ //to check if an extension is available, by name, to check for an extension
+ //use code like this:
+ //// (it is recommended this code be placed in worldspawn or a worldspawn called function somewhere)
+ //if (cvar("pr_checkextension"))
+ //if (checkextension("DP_SV_SETCOLOR"))
+ // ext_setcolor = TRUE;
+ //from then on you can check ext_setcolor to know if that extension is available
+
+ //BX_WAL_SUPPORT
+ //idea: id Software
+ //darkplaces implementation: LordHavoc
+ //description:
+ //indicates the engine supports .wal textures for filenames in the textures/ directory
+ //(note: DarkPlaces has supported this since 2001 or 2002, but did not advertise it as an extension, then I noticed Betwix was advertising it and added the extension accordingly)
+
+ //DP_BUTTONCHAT
+ //idea: Vermeulen
+ //darkplaces implementation: LordHavoc
+ //field definitions:
+ .float buttonchat;
+ //description:
+ //true if the player is currently chatting (in messagemode, menus or console)
+
+ //DP_BUTTONUSE
+ //idea: id Software
+ //darkplaces implementation: LordHavoc
+ //field definitions:
+ .float buttonuse;
+ //client console commands:
+ //+use
+ //-use
+ //description:
+ //made +use and -use commands work, they now control the .buttonuse field (.button1 was used by many mods for other purposes).
+
+ //DP_CL_LOADSKY
+ //idea: Nehahra, LordHavoc
+ //darkplaces implementation: LordHavoc
+ //client console commands:
//"loadsky" (parameters: "basename", example: "mtnsun_" would load "mtnsun_up.tga" and "mtnsun_rt.tga" and similar names, use "" to revert to quake sky, note: this is the same as Quake2 skybox naming)
//description:
//sets global skybox for the map for this client (can be stuffed to a client by QC), does not hurt much to repeatedly execute this command, please don't use this in mods if it can be avoided (only if changing skybox is REALLY needed, otherwise please use DP_GFX_SKYBOX).
//description:
//various physics properties can be defined in an entity and are executed via
//ODE
+
+//DP_CRYPTO
+//idea: divVerent
+//darkplaces implementation: divVerent
+//field definitions: (SVQC)
+.string crypto_keyfp; // fingerprint of CA key the player used to authenticate, or string_null if not verified
+.string crypto_mykeyfp; // fingerprint of CA key the server used to authenticate to the player, or string_null if not verified
+.string crypto_idfp; // fingerprint of ID used by the player entity, or string_null if not identified
+.string crypto_encryptmethod; // the string "AES128" if encrypting, and string_null if plaintext
+.string crypto_signmethod; // the string "HMAC-SHA256" if signing, and string_null if plaintext
+// there is no field crypto_myidfp, as that info contains no additional information the QC may have a use for
+//description:
continue;
l = strlen(ip);
- for(j = 0; j < l; ++j)
- if(strstrofs("0123456789.", substring(ip, j, 1), 0) == -1)
- {
- print("Invalid character ", substring(ip, j, 1), " in IP address ", ip, ". Skipping this ban.\n");
- goto skip;
- }
+ if(l != 44) // length 44 is a cryptographic ID
+ {
+ for(j = 0; j < l; ++j)
+ if(strstrofs("0123456789.", substring(ip, j, 1), 0) == -1)
+ {
+ print("Invalid character ", substring(ip, j, 1), " in IP address ", ip, ". Skipping this ban.\n");
+ goto skip;
+ }
+ }
if(cvar("g_ban_sync_trusted_servers_verify"))
if((strstrofs(strcat(";", OnlineBanList_Servers, ";"), strcat(";", serverip, ";"), 0) == -1))
string ban_ip2;
string ban_ip3;
string ban_ip4;
-#ifdef UID
-string ban_uid;
-#endif
+string ban_idfp;
void Ban_SaveBans()
{
float i1, i2, i3, i4;
string s;
- s = client.netaddress;
-
- i1 = strstrofs(s, ".", 0);
- if(i1 < 0)
- return FALSE;
- i2 = strstrofs(s, ".", i1 + 1);
- if(i2 < 0)
- return FALSE;
- i3 = strstrofs(s, ".", i2 + 1);
- if(i3 < 0)
- return FALSE;
- i4 = strstrofs(s, ".", i3 + 1);
- if(i4 >= 0)
- return FALSE;
-
- ban_ip1 = substring(s, 0, i1);
- ban_ip2 = substring(s, 0, i2);
- ban_ip3 = substring(s, 0, i3);
- ban_ip4 = strcat1(s);
-#ifdef UID
- ban_uid = client.uid;
-#endif
+ if(client.crypto_keyfp)
+ ban_idfp = client.crypto_idfp;
+ else
+ ban_idfp = string_null;
+
+ if(cvar("g_banned_list_idmode") && ban_idfp)
+ {
+ ban_ip1 = ban_ip2 = ban_ip3 = ban_ip4 = ban_idfp;
+ }
+ else
+ {
+ s = client.netaddress;
+
+ i1 = strstrofs(s, ".", 0);
+ if(i1 < 0)
+ return FALSE;
+ i2 = strstrofs(s, ".", i1 + 1);
+ if(i2 < 0)
+ return FALSE;
+ i3 = strstrofs(s, ".", i2 + 1);
+ if(i3 < 0)
+ return FALSE;
+ i4 = strstrofs(s, ".", i3 + 1);
+ if(i4 >= 0)
+ return FALSE;
+
+ ban_ip1 = substring(s, 0, i1);
+ ban_ip2 = substring(s, 0, i2);
+ ban_ip3 = substring(s, 0, i3);
+ ban_ip4 = strcat1(s);
+ }
return TRUE;
}
if(ban_ip2 == s) return TRUE;
if(ban_ip3 == s) return TRUE;
if(ban_ip4 == s) return TRUE;
-#ifdef UID
- if(ban_uid == s) return TRUE;
-#endif
+ if(ban_idfp == s) return TRUE;
}
return FALSE;
}
default:
Ban_Insert(ban_ip4, bantime, reason, 1);
break;
-#ifdef UID
case 0:
- Ban_Insert(ban_uid, bantime, reason, 1);
+ Ban_Insert(ban_idfp, bantime, reason, 1);
break;
-#endif
}
/*
* not needed, as we enforce the ban in Ban_Insert anyway
string rr;
float grecordtime[RANKINGS_CNT];
string grecordholder[RANKINGS_CNT];
-#ifdef UID
string grecorduid[RANKINGS_CNT];
-#endif
float worst_time; // last ranked time
float have_recs; // have we already read the records from the database before?
float race_GetTime(float pos) {
for(i=0;i<RANKINGS_CNT;++i) {
grecordtime[i] = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i))));
grecordholder[i] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i))));
-#ifdef UID
- grecorduid[i] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i))));
-#endif
+ grecorduid[i] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i))));
}
grecordtime[0] = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, "time")));
grecordholder[0] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "netname")));
-#ifdef UID
- grecorduid[0] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "uid")));
-#endif
+ grecorduid[0] = strzone(db_get(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp")));
worst_time = stof(db_get(ServerProgsDB, strcat(GetMapname(), rr, strcat("time", ftos(RANKINGS_CNT-1)))));
have_recs = 1;
}
return grecordholder[pos-1];
}
-#ifdef UID
float race_CheckUID(string myuid, string net_name) { // return existing UID or player name ranking pos, else 0
float i;
- for (i=RANKINGS_CNT-1;i>=0;--i)
- if(grecorduid[i] == myuid)
- return i+1;
+ if(myuid)
+ {
+ for (i=RANKINGS_CNT-1;i>=0;--i)
+ if(grecorduid[i] == myuid)
+ return i+1;
+ }
for (i=RANKINGS_CNT-1;i>=0;--i)
if(grecordholder[i] == net_name)
return i+1;
void race_SetTime(entity e, float t, float match_rec) {
float pos, prevpos;
pos = race_GetPos(t);
-#ifdef UID
- prevpos = race_CheckUID(e.uid, e.netname);
-#else
- prevpos = race_CheckName(e.netname);
-#endif
+ prevpos = race_CheckUID(e.crypto_idfp, e.netname);
float oldrec;
string recorddifference;
for (i=prevpos-1;i>pos-1;--i) {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), ftos(grecordtime[i-1]));
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), grecordholder[i-1]);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i)), grecorduid[i-1]);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), grecorduid[i-1]);
grecordtime[i] = grecordtime[i-1];
if (grecordholder[i])
strunzone(grecordholder[i]);
grecordholder[i] = strzone(grecordholder[i-1]);
-#ifdef UID
if (grecorduid[i])
strunzone(grecorduid[i]);
grecorduid[i] = strzone(grecorduid[i-1]);
-#endif
}
} else { // player has no ranked record yet
for (i=RANKINGS_CNT-1;i>pos-1;--i) {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), ftos(grecordtime[i-1]));
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), grecordholder[i-1]);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i)), grecorduid[i-1]);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), grecorduid[i-1]);
grecordtime[i] = grecordtime[i-1];
if (grecordholder[i])
strunzone(grecordholder[i]);
grecordholder[i] = strzone(grecordholder[i-1]);
-#ifdef UID
if (grecorduid[i])
strunzone(grecorduid[i]);
grecorduid[i] = strzone(grecorduid[i-1]);
-#endif
}
}
if (pos == 1) {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time"), ftos(t));
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname"), e.netname);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid"), e.uid);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp"), e.crypto_idfp);
grecordtime[0] = t;
if (grecordholder[0])
strunzone(grecordholder[0]);
grecordholder[0] = strzone(e.netname);
-#ifdef UID
if (grecorduid[0])
strunzone(grecorduid[0]);
- grecorduid[0] = strzone(e.uid);
-#endif
+ grecorduid[0] = strzone(e.crypto_idfp);
write_recordmarker(e, time - TIME_DECODE(t), TIME_DECODE(t));
race_send_recordtime(MSG_ALL);
} else {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(pos-1)), ftos(t));
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(pos-1)), e.netname);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(pos-1)), e.uid);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(pos-1)), e.crypto_idfp);
grecordtime[pos-1] = t;
if (grecordholder[pos-1])
strunzone(grecordholder[pos-1]);
grecordholder[pos-1] = strzone(e.netname);
-#ifdef UID
if (grecorduid[pos-1])
strunzone(grecorduid[pos-1]);
- grecorduid[pos-1] = strzone(e.uid);
-#endif
+ grecorduid[pos-1] = strzone(e.crypto_idfp);
}
if (pos == RANKINGS_CNT)
if (i == 0) {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time"), ftos(grecordtime[1]));
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname"), grecordholder[1]);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid"), grecorduid[1]);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp"), grecorduid[1]);
grecordtime[0] = grecordtime[1];
if (grecordholder[i])
strunzone(grecordholder[0]);
grecordholder[0] = strzone(grecordholder[1]);
-#ifdef UID
if (grecorduid[i])
strunzone(grecorduid[0]);
grecorduid[0] = strzone(grecorduid[1]);
-#endif
}
else if (i == RANKINGS_CNT-1) {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), string_null);
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), string_null);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i)), string_null);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), string_null);
grecordtime[i] = 0;
if (grecordholder[i])
strunzone(grecordholder[i]);
grecordholder[i] = string_null;
-#ifdef UID
if (grecorduid[i])
strunzone(grecorduid[i]);
grecorduid[i] = string_null;
-#endif
}
else {
db_put(ServerProgsDB, strcat(GetMapname(), rr, "time", ftos(i)), ftos(grecordtime[i+1]));
db_put(ServerProgsDB, strcat(GetMapname(), rr, "netname", ftos(i)), grecordholder[i+1]);
-#ifdef UID
- db_put(ServerProgsDB, strcat(GetMapname(), rr, "uid", ftos(i)), grecorduid[i+1]);
-#endif
+ db_put(ServerProgsDB, strcat(GetMapname(), rr, "crypto_idfp", ftos(i)), grecorduid[i+1]);
grecordtime[i] = grecordtime[i+1];
if (grecordholder[i])
strunzone(grecordholder[i]);
grecordholder[i] = strzone(grecordholder[i+1]);
-#ifdef UID
if (grecorduid[i])
strunzone(grecorduid[i]);
grecorduid[i] = strzone(grecorduid[i+1]);
-#endif
}
}