-Added support for 10 hostcache masks, which will be at the same time.
authorblack <black@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 27 Dec 2004 16:54:32 +0000 (16:54 +0000)
committerblack <black@d7cf8633-e32d-0410-b094-e92efae38249>
Mon, 27 Dec 2004 16:54:32 +0000 (16:54 +0000)
 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
netconn.h
prvm_cmds.c

index 22a4f13..89f651a 100755 (executable)
--- 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) {
index 7bb3c53..e5ab5e6 100755 (executable)
--- 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
index ce1bd78..ba52d12 100644 (file)
@@ -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,