summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIronClawTrem <louie.nutman@gmail.com>2020-02-20 23:21:56 +0000
committerIronClawTrem <louie.nutman@gmail.com>2020-02-20 23:30:29 +0000
commite2082785a7ff537b951b82bba70d364cee8397f1 (patch)
treec70f2cc4a876d1fc28ecc4c6c0ae512a24fcc1b2
parentdc04b10082a4c6994d8730467fc861fdde816c93 (diff)
update client connect code
-rw-r--r--src/game/g_client.c76
-rw-r--r--src/game/g_local.h3
-rw-r--r--src/game/g_main.c4
3 files changed, 41 insertions, 42 deletions
diff --git a/src/game/g_client.c b/src/game/g_client.c
index c77d4f7..db86f70 100644
--- a/src/game/g_client.c
+++ b/src/game/g_client.c
@@ -1428,7 +1428,7 @@ to the server machine, but qfalse on map changes and tournement
restarts.
============
*/
-char *ClientConnect( int clientNum, qboolean firstTime )
+const char *ClientConnect( int clientNum, qboolean firstTime )
{
char *value;
gclient_t *client;
@@ -1441,6 +1441,9 @@ char *ClientConnect( int clientNum, qboolean firstTime )
ent = &g_entities[ clientNum ];
+ if (ent->client && ent->client->pers.connected != CON_DISCONNECTED)
+ ClientDisconnect(clientNum);
+
trap_GetUserinfo( clientNum, userinfo, sizeof( userinfo ) );
value = Info_ValueForKey( userinfo, "cl_guid" );
@@ -1452,13 +1455,14 @@ char *ClientConnect( int clientNum, qboolean firstTime )
return va( "%s", reason );
}
+
// IP filtering
// https://zerowing.idsoftware.com/bugzilla/show_bug.cgi?id=500
// recommanding PB based IP / GUID banning, the builtin system is pretty limited
// check to see if they are on the banned IP list
value = Info_ValueForKey( userinfo, "ip" );
i = 0;
- while( *value && i < sizeof( ip ) - 2 )
+ while( *value && i < sizeof( ip ) - 1 )
{
if( *value != '.' && ( *value < '0' || *value > '9' ) )
break;
@@ -1472,10 +1476,35 @@ char *ClientConnect( int clientNum, qboolean firstTime )
if( strlen( ip ) < 7 && strcmp( Info_ValueForKey( userinfo, "ip" ), "localhost" ) )
{
G_AdminsPrintf( "Connect from client with invalid IP: '%s' NAME: '%s^7'\n",
- ip, Info_ValueForKey( userinfo, "name" ) );
+ ip, Info_ValueForKey( userinfo, "name" ) );
return "Invalid client data";
}
+ // limit max clients per IP
+ if( g_maxGhosts.integer > 1 )
+ {
+ gclient_t *other;
+ int count = 0;
+
+ for( i = 0 ; i < level.maxclients; i++ )
+ {
+ other = &level.clients[ i ];
+ if( other &&
+ ( other->pers.connected == CON_CONNECTED || other->pers.connected == CON_CONNECTING ) &&
+ strcmp( ip, other->pers.ip ) == 0 )
+ {
+ count++;
+ }
+ }
+
+ if( count + 1 > g_maxGhosts.integer )
+ {
+ G_AdminsPrintf( "Connect from client exceeds %d maximum connections per IP: '%s' NAME: '%s^7'\n",
+ g_maxGhosts.integer, ip, Info_ValueForKey( userinfo, "name" ) );
+ return "Maximum simultaneous clients exceeded";
+ }
+ }
+
// check for a password
value = Info_ValueForKey( userinfo, "password" );
@@ -1518,7 +1547,7 @@ char *ClientConnect( int clientNum, qboolean firstTime )
memset( client, 0, sizeof(*client) );
// add guid to session so we don't have to keep parsing userinfo everywhere
- if( !guid[ 0 ] )
+ if( !guid[0] )
{
Q_strncpyz( client->pers.guid, "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
sizeof( client->pers.guid ) );
@@ -1527,23 +1556,9 @@ char *ClientConnect( int clientNum, qboolean firstTime )
{
Q_strncpyz( client->pers.guid, guid, sizeof( client->pers.guid ) );
}
-
Q_strncpyz( client->pers.ip, ip, sizeof( client->pers.ip ) );
client->pers.adminLevel = G_admin_level( ent );
- // do autoghost now so that there won't be any name conflicts later on
- if ( g_autoGhost.integer && client->pers.guid[ 0 ] != 'X' )
- {
- for ( i = 0; i < MAX_CLIENTS; i++ )
- {
- if ( i != ent - g_entities && g_entities[i].client && g_entities[i].client->pers.connected != CON_DISCONNECTED && !Q_stricmp( g_entities[i].client->pers.guid, client->pers.guid ) )
- {
- trap_SendServerCommand( i, "disconnect \"You may not be connected to this server multiple times\"" );
- trap_DropClient( i, "disconnected" );
- }
- }
- }
-
client->pers.connected = CON_CONNECTING;
// read or initialize the session data
@@ -1600,34 +1615,15 @@ char *ClientConnect( int clientNum, qboolean firstTime )
G_admin_namelog_update( client, qfalse );
}
+ if (smj)
+ G_AdminsPrintf( "%s^7 (#%d) has rating %d\n", client->pers.netname, clientNum, smj->rating );
+
// if this is after !restart keepteams or !restart switchteams, apply said selection
if ( client->sess.restartTeam != PTE_NONE ) {
G_ChangeTeam( ent, client->sess.restartTeam );
client->sess.restartTeam = PTE_NONE;
}
- if( !( G_admin_permission( ent, ADMF_NOAUTOBAHN ) ||
- G_admin_permission( ent, ADMF_IMMUNITY ) ) )
- {
- extern g_admin_namelog_t *g_admin_namelog[ 128 ];
- for( i = 0; i < MAX_ADMIN_NAMELOGS && g_admin_namelog[ i ]; i++ )
- {
- if( !Q_stricmp( ip, g_admin_namelog[ i ]->ip ) || !Q_stricmp( guid, g_admin_namelog[ i ]->guid ) )
- {
- schachtmeisterJudgement_t *j = &g_admin_namelog[i]->smj;
- if( j->ratingTime )
- {
- if( j->rating >= g_schachtmeisterClearThreshold.integer )
- break;
- else if( j->rating <= g_schachtmeisterAutobahnThreshold.integer )
- return g_schachtmeisterAutobahnMessage.string;
- G_AdminsPrintf( "%s^7 (#%d) has rating %d\n", ent->client->pers.netname, ent - g_entities, j->rating );
- }
- break;
- }
- }
- }
-
return NULL;
}
diff --git a/src/game/g_local.h b/src/game/g_local.h
index df16a84..a355265 100644
--- a/src/game/g_local.h
+++ b/src/game/g_local.h
@@ -1149,7 +1149,7 @@ qboolean G_Flood_Limited( gentity_t *ent );
//
// g_client.c
//
-char *ClientConnect( int clientNum, qboolean firstTime );
+const char *ClientConnect( int clientNum, qboolean firstTime );
void ClientUserinfoChanged( int clientNum, qboolean forceName );
void ClientDisconnect( int clientNum );
void ClientBegin( int clientNum );
@@ -1494,6 +1494,7 @@ extern vmCvar_t g_schachtmeisterClearThreshold;
extern vmCvar_t g_schachtmeisterAutobahnThreshold;
extern vmCvar_t g_schachtmeisterAutobahnMessage;
extern vmCvar_t g_adminAutobahnNotify;
+extern vmCvar_t g_maxGhosts;
void trap_Printf( const char *fmt );
void trap_Error( const char *fmt );
diff --git a/src/game/g_main.c b/src/game/g_main.c
index 6623959..298b21b 100644
--- a/src/game/g_main.c
+++ b/src/game/g_main.c
@@ -243,6 +243,7 @@ vmCvar_t g_schachtmeisterClearThreshold;
vmCvar_t g_schachtmeisterAutobahnThreshold;
vmCvar_t g_schachtmeisterAutobahnMessage;
vmCvar_t g_adminAutobahnNotify;
+vmCvar_t g_maxGhosts;
static cvarTable_t gameCvarTable[ ] =
{
@@ -464,7 +465,8 @@ static cvarTable_t gameCvarTable[ ] =
{ &g_schachtmeisterClearThreshold, "g_schachtmeisterClearThreshold", "-10", CVAR_ARCHIVE, 0, qfalse },
{ &g_schachtmeisterAutobahnThreshold, "g_schachtmeisterAutobahnThreshold", "-30", CVAR_ARCHIVE, 0, qfalse },
{ &g_schachtmeisterAutobahnMessage, "g_schachtmeisterAutobahnMessage", "Your host is blacklisted.", CVAR_ARCHIVE, 0, qfalse },
- { &g_adminAutobahnNotify, "g_adminAutobahnNotify", "1", CVAR_ARCHIVE, 0, qfalse }
+ { &g_adminAutobahnNotify, "g_adminAutobahnNotify", "1", CVAR_ARCHIVE, 0, qfalse },
+ { &g_maxGhosts, "g_maxGhosts", "0", CVAR_ARCHIVE, 0, qfalse }
};
static int gameCvarTableSize = sizeof( gameCvarTable ) / sizeof( gameCvarTable[ 0 ] );