From bdee526adfc38dc52821f14d1c76544bc6673dcb Mon Sep 17 00:00:00 2001 From: black Date: Mon, 27 Dec 2004 16:54:32 +0000 Subject: [PATCH] -Added support for 10 hostcache masks, which will be at the same time. 5 will be concatenated with AND and the other 5 with OR, so you'll have plenty of possibilities to mask whatever you want. -Changed the mask structure and function to be a bit more generic. -Added 3 new comparison operators (NOTEQUAL, CONTAINS and NOTCONTAIN - the latter two for strings) -Adapted the builtins to work with multiple masks. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@4890 d7cf8633-e32d-0410-b094-e92efae38249 --- netconn.c | 108 ++++++++++++++++++++++++++++++---------------------- netconn.h | 26 ++++++++----- prvm_cmds.c | 102 +++++++++++++++++++++++++++++++++---------------- 3 files changed, 149 insertions(+), 87 deletions(-) diff --git a/netconn.c b/netconn.c index 22a4f130..89f651ad 100755 --- a/netconn.c +++ b/netconn.c @@ -89,7 +89,9 @@ cvar_t net_address = {0, "net_address", "0.0.0.0"}; //cvar_t net_netaddress_ipv6 = {0, "net_address_ipv6", "[0:0:0:0:0:0:0:0]"}; // HostCache interface -hostcache_mask_t hostcache_currentmask; +hostcache_mask_t hostcache_andmasks[HOSTCACHE_ANDMASKCOUNT]; +hostcache_mask_t hostcache_ormasks[HOSTCACHE_ORMASKCOUNT]; + hostcache_infofield_t hostcache_sortbyfield; qboolean hostcache_sortdescending; @@ -151,56 +153,64 @@ static qboolean _HostCache_SortTest( hostcache_t *A, hostcache_t *B ) static qboolean _hc_testint( int A, hostcache_maskop_t op, int B ) { - int diff; - - diff = A - B; - switch( op ) { - case HCMO_GREATER: - if( !diff ) - return false; - case HCMO_GREATEREQUAL: - if( diff < 0 ) - return false; - break; - case HCMO_EQUAL: - if( diff ) - return false; - break; - case HCMO_LESS: - if( !diff ) - return false; - case HCMO_LESSEQUAL: - if( diff > 0 ) - return false; - break; - } - return true; + if( op == HCMO_LESS ) + return A < B; + else if( op == HCMO_LESSEQUAL ) + return A <= B; + else if( op == HCMO_EQUAL ) + return A == B; + else if( op == HCMO_GREATER ) + return A > B; + else if( op == HCMO_NOTEQUAL ) + return A != B; + else // HCMO_GREATEREQUAL + return A >= B; } -static qboolean _HostCache_TestMask( hostcache_info_t *info ) +static qboolean _hc_teststr( const char *A, hostcache_maskop_t op, const char *B ) { - if( !_hc_testint( info->ping, hostcache_currentmask.pingtest, hostcache_currentmask.info.ping ) ) + if( op == HCMO_CONTAINS ) // A info B mask + return *A && !!strstr( B, A ); // we want a real bool + else if( op == HCMO_NOTCONTAIN ) + return !*A || !strstr( B, A ); + else if( op == HCMO_LESS ) + return strcmp( A, B ) < 0; + else if( op == HCMO_LESSEQUAL ) + return strcmp( A, B ) <= 0; + else if( op == HCMO_EQUAL ) + return strcmp( A, B ) == 0; + else if( op == HCMO_GREATER ) + return strcmp( A, B ) > 0; + else if( op == HCMO_NOTEQUAL ) + return strcmp( A, B ) != 0; + else // HCMO_GREATEREQUAL + return strcmp( A, B ) >= 0; +} + +static qboolean _HostCache_TestMask( hostcache_mask_t *mask, hostcache_info_t *info ) +{ + if( !_hc_testint( info->ping, mask->tests[HCIF_PING], mask->info.ping ) ) return false; - if( !_hc_testint( info->maxplayers, hostcache_currentmask.maxplayerstest, hostcache_currentmask.info.maxplayers ) ) + if( !_hc_testint( info->maxplayers, mask->tests[HCIF_MAXPLAYERS], mask->info.maxplayers ) ) return false; - if( !_hc_testint( info->numplayers, hostcache_currentmask.numplayerstest, hostcache_currentmask.info.numplayers ) ) + if( !_hc_testint( info->numplayers, mask->tests[HCIF_NUMPLAYERS], mask->info.numplayers ) ) return false; - if( !_hc_testint( info->protocol, hostcache_currentmask.protocoltest, hostcache_currentmask.info.protocol )) + if( !_hc_testint( info->protocol, mask->tests[HCIF_PROTOCOL], mask->info.protocol )) return false; - if( *hostcache_currentmask.info.cname - && !strstr( info->cname, hostcache_currentmask.info.cname ) ) + if( *mask->info.cname + && !_hc_teststr( info->cname, mask->tests[HCIF_CNAME], mask->info.cname ) ) return false; - if( *hostcache_currentmask.info.game - && !strstr( info->game, hostcache_currentmask.info.game ) ) + if( *mask->info.game + && !_hc_teststr( info->game, mask->tests[HCIF_GAME], mask->info.game ) ) return false; - if( *hostcache_currentmask.info.mod - && !strstr( info->mod, hostcache_currentmask.info.mod ) ) + if( *mask->info.mod + && !_hc_teststr( info->mod, mask->tests[HCIF_MOD], mask->info.mod ) ) return false; - if( *hostcache_currentmask.info.map - && !strstr( info->map, hostcache_currentmask.info.map ) ) + if( *mask->info.map + && !_hc_teststr( info->map, mask->tests[HCIF_MAP], mask->info.map ) ) return false; - if( *hostcache_currentmask.info.name - && !strstr( info->name, hostcache_currentmask.info.name ) ) + if( *mask->info.name + && !_hc_teststr( info->name, mask->tests[HCIF_NAME], mask->info.name ) ) return false; return true; } @@ -210,8 +220,15 @@ static void _HostCache_Insert( hostcache_t *entry ) int start, end, mid; if( hostcache_viewcount == HOSTCACHE_VIEWCACHESIZE ) return; - // now check whether it passes through mask - if( !_HostCache_TestMask( &entry->info ) ) + // now check whether it passes through the masks mask + for( start = 0 ; hostcache_andmasks[start].active && start < HOSTCACHE_ANDMASKCOUNT ; start++ ) + if( !_HostCache_TestMask( &hostcache_andmasks[start], &entry->info ) ) + return; + + for( start = 0 ; hostcache_ormasks[start].active && start < HOSTCACHE_ORMASKCOUNT ; start++ ) + if( _HostCache_TestMask( &hostcache_ormasks[start], &entry->info ) ) + break; + if( start == HOSTCACHE_ORMASKCOUNT || (start > 0 && !hostcache_ormasks[start].active) ) return; if( !hostcache_viewcount ) { @@ -269,9 +286,10 @@ void HostCache_RebuildViewSet(void) _HostCache_Insert( &hostcache_cache[i] ); } -void HostCache_ResetMask(void) +void HostCache_ResetMasks(void) { - memset( &hostcache_currentmask, 0, sizeof( hostcache_mask_t ) ); + memset( &hostcache_andmasks, 0, sizeof( hostcache_andmasks ) ); + memset( &hostcache_andmasks, 0, sizeof( hostcache_andmasks ) ); } @@ -1712,7 +1730,7 @@ void Net_Stats_f(void) void Net_Slist_f(void) { - HostCache_ResetMask(); + HostCache_ResetMasks(); hostcache_sortbyfield = HCIF_PING; hostcache_sortdescending = false; if (m_state != m_slist) { diff --git a/netconn.h b/netconn.h index 7bb3c53c..e5ab5e6e 100755 --- a/netconn.h +++ b/netconn.h @@ -152,14 +152,22 @@ extern int playercolor; #define HOSTCACHE_TOTALSIZE 2048 #define HOSTCACHE_VIEWCACHESIZE 128 +#define HOSTCACHE_ANDMASKCOUNT 5 +#define HOSTCACHE_ORMASKCOUNT 5 typedef enum { - HCMO_GREATEREQUAL, - HCMO_GREATER, - HCMO_EQUAL, + // HCMO_CONTAINS is the default for strings + // HCMO_GREATEREQUAL is the default for numbers (also used when OP == CONTAINS or NOTCONTAINS + HCMO_CONTAINS, + HCMO_NOTCONTAIN, + HCMO_LESSEQUAL, HCMO_LESS, + HCMO_EQUAL, + HCMO_GREATER, + HCMO_GREATEREQUAL, + HCMO_NOTEQUAL } hostcache_maskop_t; // struct with all fields that you can search for or sort by @@ -215,14 +223,14 @@ typedef struct typedef struct { - hostcache_maskop_t pingtest; - hostcache_maskop_t maxplayerstest; - hostcache_maskop_t numplayerstest; - hostcache_maskop_t protocoltest; + qboolean active; + hostcache_maskop_t tests[HCIF_COUNT]; hostcache_info_t info; } hostcache_mask_t; -extern hostcache_mask_t hostcache_currentmask; +extern hostcache_mask_t hostcache_andmasks[HOSTCACHE_ANDMASKCOUNT]; +extern hostcache_mask_t hostcache_ormasks[HOSTCACHE_ORMASKCOUNT]; + extern hostcache_infofield_t hostcache_sortbyfield; extern qboolean hostcache_sortdescending; @@ -295,7 +303,7 @@ void Net_Slist_f(void); // Hostcache interface // manually refresh the view set, do this after having changed the mask or any other flag void HostCache_RebuildViewSet(void); -void HostCache_ResetMask(void); +void HostCache_ResetMasks(void); void HostCache_QueryList(void); #endif diff --git a/prvm_cmds.c b/prvm_cmds.c index ce1bd78a..ba52d121 100644 --- a/prvm_cmds.c +++ b/prvm_cmds.c @@ -159,9 +159,9 @@ string gethostcachestring(float fld, float hostnr) float stringtokeynum(string key) - resethostcachemask() - sethostcachemaskstring(float fld, string str) - sethostcachemasknumber(float fld, float num, float op) + resethostcachemasks() + sethostcachemaskstring(float mask, float fld, string str) + sethostcachemasknumber(float mask, float fld, float num, float op) resorthostcache() sethostcachesort(float field, float descending) refreshhostcache() @@ -3553,14 +3553,14 @@ void VM_M_gethostcachestat( void ) /* ======================== -VM_M_resethostcachemask +VM_M_resethostcachemasks -resethostcachemask() +resethostcachemasks() ======================== */ -void VM_M_resethostcachemask( void ) +void VM_M_resethostcachemasks( void ) { - HostCache_ResetMask(); + HostCache_ResetMasks(); } @@ -3568,75 +3568,111 @@ void VM_M_resethostcachemask( void ) ======================== VM_M_sethostcachemaskstring -sethostcachemaskstring(float field, string str) +sethostcachemaskstring(float mask, float fld, string str, float op) +0-511 and +512 - 1024 or ======================== */ void VM_M_sethostcachemaskstring( void ) { char *str; + int masknr; + hostcache_mask_t *mask; + int field; - VM_SAFEPARMCOUNT( 2, VM_M_sethostcachemask ); + VM_SAFEPARMCOUNT( 4, VM_M_sethostcachemaskstring ); str = PRVM_G_STRING( OFS_PARM1 ); if( !str ) - PRVM_ERROR( "VM_M_sethostcachemask: null string passed!" ); + PRVM_ERROR( "VM_M_sethostcachemaskstring: null string passed!" ); + + masknr = PRVM_G_FLOAT( OFS_PARM0 ); + if( masknr >= 0 && masknr <= HOSTCACHE_ANDMASKCOUNT ) + mask = &hostcache_andmasks[masknr]; + else if( masknr >= 512 && masknr - 512 <= HOSTCACHE_ORMASKCOUNT ) + mask = &hostcache_ormasks[masknr - 512 ]; + else { + Con_Printf( "VM_M_sethostcachemaskstring: invalid mask number %i\n", masknr ); + return; + } - switch( (int) PRVM_G_FLOAT( OFS_PARM0 ) ) { + field = (int) PRVM_G_FLOAT( OFS_PARM1 ); + + switch( field ) { case HCIF_CNAME: - strncpy( hostcache_currentmask.info.cname, PRVM_G_STRING( OFS_PARM1 ), sizeof(hostcache_currentmask.info.cname) ); + strncpy( mask->info.cname, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.cname) ); break; case HCIF_NAME: - strncpy( hostcache_currentmask.info.name, PRVM_G_STRING( OFS_PARM1 ), sizeof(hostcache_currentmask.info.name) ); + strncpy( mask->info.name, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.name) ); break; case HCIF_MAP: - strncpy( hostcache_currentmask.info.map, PRVM_G_STRING( OFS_PARM1 ), sizeof(hostcache_currentmask.info.map) ); + strncpy( mask->info.map, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.map) ); break; case HCIF_MOD: - strncpy( hostcache_currentmask.info.mod, PRVM_G_STRING( OFS_PARM1 ), sizeof(hostcache_currentmask.info.mod) ); + strncpy( mask->info.mod, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.mod) ); break; case HCIF_GAME: - strncpy( hostcache_currentmask.info.game, PRVM_G_STRING( OFS_PARM1 ), sizeof(hostcache_currentmask.info.game) ); + strncpy( mask->info.game, PRVM_G_STRING( OFS_PARM2 ), sizeof(mask->info.game) ); break; default: - Con_Printf( "VM_M_sethostcachemask: Bad field number %i passed!\n", PRVM_G_INT( OFS_PARM0 ) ); + Con_Printf( "VM_M_sethostcachemaskstring: Bad field number %i passed!\n", field ); + return; } + + mask->active = true; + mask->tests[field] = (int) PRVM_G_FLOAT( OFS_PARM3 ); } /* ======================== VM_M_sethostcachemasknumber -sethostcachemasknumber(float field, float num, float op) +sethostcachemasknumber(float mask, float fld, float num, float op) + +0-511 and +512 - 1024 or ======================== */ void VM_M_sethostcachemasknumber( void ) { int number; - hostcache_maskop_t operand; - VM_SAFEPARMCOUNT( 3, VM_M_sethostcachemasknumber ); + hostcache_mask_t *mask; + int masknr; + int field; + VM_SAFEPARMCOUNT( 4, VM_M_sethostcachemasknumber ); + + masknr = PRVM_G_FLOAT( OFS_PARM0 ); + if( masknr >= 0 && masknr <= HOSTCACHE_ANDMASKCOUNT ) + mask = &hostcache_andmasks[masknr]; + else if( masknr >= 512 && masknr - 512 <= HOSTCACHE_ORMASKCOUNT ) + mask = &hostcache_ormasks[masknr - 512 ]; + else { + Con_Printf( "VM_M_sethostcachemasknumber: invalid mask number %i\n", masknr ); + return; + } - number = PRVM_G_FLOAT( OFS_PARM1 ); - operand = (int) PRVM_G_FLOAT( OFS_PARM2 ); + number = PRVM_G_FLOAT( OFS_PARM2 ); + field = (int) PRVM_G_FLOAT( OFS_PARM1 ); - switch( (int) PRVM_G_FLOAT( OFS_PARM0 ) ) { + switch( field ) { case HCIF_MAXPLAYERS: - hostcache_currentmask.info.maxplayers = number; - hostcache_currentmask.maxplayerstest = operand; + mask->info.maxplayers = number; break; case HCIF_NUMPLAYERS: - hostcache_currentmask.info.numplayers = number; - hostcache_currentmask.numplayerstest = operand; + mask->info.numplayers = number; break; case HCIF_PING: - hostcache_currentmask.info.ping = number; - hostcache_currentmask.pingtest = operand; + mask->info.ping = number; break; case HCIF_PROTOCOL: - hostcache_currentmask.info.protocol = number; - hostcache_currentmask.protocoltest = operand; + mask->info.protocol = number; break; default: - Con_Printf( "VM_M_sethostcachemask: Bad field number %i passed!\n", PRVM_G_INT( OFS_PARM0 ) ); + Con_Printf( "VM_M_sethostcachemasknumber: Bad field number %i passed!\n", field ); + return; } + + mask->active = true; + mask->tests[field] = (int) PRVM_G_FLOAT( OFS_PARM3 ); } @@ -3917,7 +3953,7 @@ prvm_builtin_t vm_m_builtins[] = { VM_M_gethostcachestring, VM_M_parseentitydata, VM_M_stringtokeynum, - VM_M_resethostcachemask, + VM_M_resethostcachemasks, VM_M_sethostcachemaskstring, VM_M_sethostcachemasknumber, VM_M_resorthostcache, -- 2.39.2