Kquery 4.0: Using Filters
Kquery 4 FAQ - The Filter System
    Quick Links : Find some pre-made filters and the Web-based 'build your own filter' system.
    Scroll down to Advanced Filering Techniques.

  • Kquery 4 offers a brand new and powerful way to filter servers, with it's own pascal based language system.
    In the following screenshot, we've created a filter which only shows us servers with a ping under 100 :



  • Lets create a new filter by clicking on the following menus :



  • Next you'll need to name it - best to use a short descriptive name, such as 'Ping below 50'.



  • Presuming everything's gone well, the main Filter Builder interface should appear.



    This is where things get slightly more tricky.
    If you haven't done any sort of coding before, I suggest you use the Web based Filter Builder which will write the code for you.

    Some Brief Pascal Notes :
    • Single program statements are terminated with a semi-colon ;
    • Strings are quoted with single quotes only '
    • The := symbol is the variable assignment operator. It is not just an equals sign.
    • Comments start with // or are between { and }
    • AND and OR statements must be FULLY NESTED in bracket ( ) characters -
      e.g. if ((a or b) and c) do something;
    • Variables must be pre-declared
    • A variable may be given a value through a calculation like this:
      • sum := number1 + number2;
      • division := number1 / number2;
      • complex := (number1 + number2) * 3;
    The following 'introduction to pascal' links may be useful :

    Ok. From now on i assume you can program in pascal/delphi :)

  • Supplied Variables :
    Kquery 4 supplies the following variables to the parser that you can use :
     
    
       hostname:     string[100]; // contains the name of the server
       ip:           string[15];  // is the IP of the server
       port:         integer;     // is the query port of the server
       gameport:     integer;     // is the game port of the server
       ping :        integer;     // holds an integer ping value (no higher than 9999)
       country:      string[2];   // holds a two letter country code, e.g. UK
       map:          string[20];  // holds the current map
       servertype:   char;        // holds D for dedicated, L for listen, or P for proxy/hltv servers
                                  // * HL engine only
       ostype:       char;        // holds W for win32, L for linux
                                  // * HL engine only
       gametype:     string[20];  // Current Gametype - normally two letters (Q3, UT, HL, UT2, BFIELD1942)
       modtype:      string[20];  // Current mod type (cstrike,dod,xDoubleDom,baseq3) 
       modname:      string[50];  // Current mod full name (counterstrike) *HL only
       serverver:    string[50];  // Server Protocol Version
       passworded:   integer;     // 0 if not passworded, 1 if passworded, -1 if password status is unknown
       actplayers:   integer;     // Current number of active playres
       maxplayers:   integer;     // Current maximum players allowed
       resplayers:   integer;     // Current number of reserved slots
       botplayers:   integer;     // Current number of bot players *where supported
       anticheat:    string[40];  // Anticheat name (PunkBuster / Cheating Death)
       anticheatver: string[20];  // Anticheat version number 
    

  • Lets look at some example code :


    This simple bit of code does the following :
    result:=true;
    * By default, all servers are put in the filtered category
    if pos('bygames.com',hostname)<>0 then result:=false;
    * If the hostname contains the string 'bygames.com' (i.e. it's position is not equal <> to 0), put it in the defiltered category (result=false)


    The code doesn't need to be advanced at all, the following line will filter all servers below 100 ping (as shown in the top example) :

    if ping<100 then result:=true else result:=false;

    This code filters using a bit more logic :
        result:=true;  // by default allow all servers to be filtered
        if pos('game2xs',hostname)<>0 then result:=true else // allow all game2xs servers through unchecked
         begin
          if (actplayers>6) and (actplayers<>maxplayers-resplayers) then result:=true;
           // if the server has over 6 players and isn't full then let it through
          if pos('Cheating Death',anticheat)<>0 then result:=false;
           // if the server runs cheating death then move it to de-filtered
          if ping>100 then result:=false; // if ping is more than 100 then move to de-filtered
         end;
    
  • Once you've typed in your code, you should test it before saving. Clicking the test button will do this.


    In our above example, we've mis-typed 'pos' as 'pes'
    The compiler has spotted this, tried to highlight the problem (it kinda missed, but it got the line number right).

  • That's about it. Hit "OK" to save the filter, and your new filter should be active.
    The following section is for advanced filtering methods.

    Advanced Filtering : Rule Information

    Kquery versions from 1.8.9 build 103 now support advanced filtering by server rule information.

     
    
       // Use the following functions to filter rule information : 
    
       function getRuleString([rulename]:string) : String;
       // returns the string value of the specified rule name 
       // Default Value : '' 
    
       function getRuleInteger([rulename]:string) : Integer;
       // returns the integer value of the specified rule name 
       // Default Value : 0 
       // Note - trying to return a non-integer number will cause the function to fail. 
    
       function getRuleExist([rulename]:string) : Boolean;
       // returns true if the rule is found on the server 
       // Default Value : false 
    
       // Example : BattleField 1942, v1.61 with over 15 mins remaining 
    
       if (
          (ping<150)
          and (getRuleString('gamever')='v1.61')
          and (getRuleString('gameid')='bf1942')
          and (getRuleInteger('roundtimeremain')>900)
          and (gametype='BFIELD1942')
          )
         then
          result:=true
         else
          result:=false;
    
    

    Filtering by rules does slow the filtering process down (but not much), and you may notice that on some gametypes (such as half-life) that you will receive the server information first before the server gets filtered.
    You can use any rule value for this filter - you can check out what types of rules each server has by turning on the rules display within kquery (file->interfaces->show rules)

  • Advanced Filtering : Supported Function Reference
    Kquery versions from 1.6.6 build 059 now support the following pascal / delphi based functions :

     
    
       JvInterpreter_System and JvInterpreter_SysUtils are used in this interpreter.
       Their usage (and source code) can be found on google, just do a search for the procedure / function name.
       The main functions (taken from the source code) are described as : 
    
        // ( JvInterpreter_System)
        AddFun(cSystem, 'Move', JvInterpreter_Move, 3, [varEmpty, varByRef, varEmpty], varEmpty);
        AddFun(cSystem, 'ParamCount', JvInterpreter_ParamCount, 0, [0], varEmpty);
        AddFun(cSystem, 'ParamStr', JvInterpreter_ParamStr, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'Randomize', JvInterpreter_Randomize, 0, [0], varEmpty);
        AddFun(cSystem, 'Random', JvInterpreter_Random, 1, [varInteger], varEmpty);
        AddFun(cSystem, 'UpCase', JvInterpreter_UpCase, 1, [varEmpty], varEmpty);
    
        AddFun(cSystem, 'VarType', JvInterpreter_VarType, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'VarAsType', JvInterpreter_VarAsType, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSystem, 'VarIsEmpty', JvInterpreter_VarIsEmpty, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'VarIsNull', JvInterpreter_VarIsNull, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'VarToStr', JvInterpreter_VarToStr, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'VarFromDateTime', JvInterpreter_VarFromDateTime, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'VarToDateTime', JvInterpreter_VarToDateTime, 1, [varEmpty], varEmpty);
    
        AddFun(cSystem, 'ord', JvInterpreter_Ord, 1, [varEmpty], varEmpty);
    
        AddFun(cSystem, 'Chr', JvInterpreter_Chr, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'Abs', JvInterpreter_Abs, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'Length', JvInterpreter_Length, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'Copy', JvInterpreter_Copy, 3, [varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSystem, 'Round', JvInterpreter_Round, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'Trunc', JvInterpreter_Trunc, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'Pos', JvInterpreter_Pos, 2, [varEmpty, varEmpty], varEmpty);
    
        // some Stringfunctions
        AddFun(cSystem, 'Delete', JvInterpreter_Delete, 3, [varByRef, varEmpty, varEmpty], varEmpty);
        AddFun(cSystem, 'Insert', JvInterpreter_Insert, 3, [varEmpty, varByRef, varEmpty], varEmpty);
        // some mathfunctions
        AddFun(cSystem, 'Sqr', JvInterpreter_Sqr, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'Sqrt', JvInterpreter_Sqrt, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'Exp', JvInterpreter_Exp, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'Ln', JvInterpreter_Ln, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'Sin', JvInterpreter_Sin, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'Cos', JvInterpreter_Cos, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'Tan', JvInterpreter_Tan, 1, [varEmpty], varEmpty);
        AddFun(cSystem, 'ArcTan', JvInterpreter_ArcTan, 1, [varEmpty], varEmpty);
        //---pfh
        AddFun(cSystem, 'SetLength', JvInterpreter_SetLength, 2, [varByRef or varString, varInteger], varEmpty);
    
    
        // ( JvInterpreter_SysUtils)
        AddFun(cSysUtils, 'NewStr', JvInterpreter_NewStr, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'DisposeStr', JvInterpreter_DisposeStr, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'AssignStr', JvInterpreter_AssignStr, 2, [varByRef, varEmpty], varEmpty);
        AddFun(cSysUtils, 'AppendStr', JvInterpreter_AppendStr, 2, [varByRef, varEmpty], varEmpty);
    
        AddFun(cSysUtils, 'UpperCase', JvInterpreter_UpperCase, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'LowerCase', JvInterpreter_LowerCase, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'CompareStr', JvInterpreter_CompareStr, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'CompareText', JvInterpreter_CompareText, 2, [varEmpty, varEmpty], varEmpty);
    
        AddFun(cSysUtils, 'AnsiUpperCase', JvInterpreter_AnsiUpperCase, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiLowerCase', JvInterpreter_AnsiLowerCase, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiCompareStr', JvInterpreter_AnsiCompareStr, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiCompareText', JvInterpreter_AnsiCompareText, 2, [varEmpty, varEmpty], varEmpty);
    
        AddFun(cSysUtils, 'AnsiStrComp', JvInterpreter_AnsiStrComp, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiStrIComp', JvInterpreter_AnsiStrIComp, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiStrLComp', JvInterpreter_AnsiStrLComp, 3, [varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiStrLIComp', JvInterpreter_AnsiStrLIComp, 3, [varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiStrLower', JvInterpreter_AnsiStrLower, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiStrUpper', JvInterpreter_AnsiStrUpper, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiLastChar', JvInterpreter_AnsiLastChar, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiStrLastChar', JvInterpreter_AnsiStrLastChar, 1, [varEmpty], varEmpty);
    
        AddFun(cSysUtils, 'Trim', JvInterpreter_Trim, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'TrimLeft', JvInterpreter_TrimLeft, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'TrimRight', JvInterpreter_TrimRight, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'QuotedStr', JvInterpreter_QuotedStr, 1, [varEmpty], varEmpty);
    
        AddFun(cSysUtils, 'AnsiQuotedStr', JvInterpreter_AnsiQuotedStr, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiExtractQuotedStr', JvInterpreter_AnsiExtractQuotedStr, 2, [varByRef, varEmpty], varEmpty);
    
        AddFun(cSysUtils, 'AdjustLineBreaks', JvInterpreter_AdjustLineBreaks, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'IsValidIdent', JvInterpreter_IsValidIdent, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'IntToStr', JvInterpreter_IntToStr, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'IntToHex', JvInterpreter_IntToHex, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrToInt', JvInterpreter_StrToInt, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrToIntDef', JvInterpreter_StrToIntDef, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'LoadStr', JvInterpreter_LoadStr, 1, [varEmpty], varEmpty);
    
        AddFun(cSysUtils, 'StrLen', JvInterpreter_StrLen, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrEnd', JvInterpreter_StrEnd, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrMove', JvInterpreter_StrMove, 3, [varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrCopy', JvInterpreter_StrCopy, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrECopy', JvInterpreter_StrECopy, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrLCopy', JvInterpreter_StrLCopy, 3, [varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrPCopy', JvInterpreter_StrPCopy, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrPLCopy', JvInterpreter_StrPLCopy, 3, [varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrCat', JvInterpreter_StrCat, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrLCat', JvInterpreter_StrLCat, 3, [varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrComp', JvInterpreter_StrComp, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrIComp', JvInterpreter_StrIComp, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrLComp', JvInterpreter_StrLComp, 3, [varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrLIComp', JvInterpreter_StrLIComp, 3, [varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrScan', JvInterpreter_StrScan, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrRScan', JvInterpreter_StrRScan, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrPos', JvInterpreter_StrPos, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrUpper', JvInterpreter_StrUpper, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrLower', JvInterpreter_StrLower, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrPas', JvInterpreter_StrPas, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrAlloc', JvInterpreter_StrAlloc, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrBufSize', JvInterpreter_StrBufSize, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrNew', JvInterpreter_StrNew, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrDispose', JvInterpreter_StrDispose, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'Format', JvInterpreter_Format, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'FmtStr', JvInterpreter_FmtStr, 3, [varByRef, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrFmt', JvInterpreter_StrFmt, 3, [varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrLFmt', JvInterpreter_StrLFmt, 4, [varEmpty, varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'FormatBuf', JvInterpreter_FormatBuf, 5, [varByRef, varEmpty, varEmpty, varEmpty, varEmpty],
          varEmpty);
        AddFun(cSysUtils, 'FloatToStr', JvInterpreter_FloatToStr, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'CurrToStr', JvInterpreter_CurrToStr, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'FloatToStrF', JvInterpreter_FloatToStrF, 4, [varEmpty, varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'CurrToStrF', JvInterpreter_CurrToStrF, 3, [varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'FormatFloat', JvInterpreter_FormatFloat, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'FormatCurr', JvInterpreter_FormatCurr, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrToFloat', JvInterpreter_StrToFloat, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrToCurr', JvInterpreter_StrToCurr, 1, [varEmpty], varEmpty);
    
        AddFun(cSysUtils, 'ByteType', JvInterpreter_ByteType, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'StrByteType', JvInterpreter_StrByteType, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'ByteToCharLen', JvInterpreter_ByteToCharLen, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'CharToByteLen', JvInterpreter_CharToByteLen, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'ByteToCharIndex', JvInterpreter_ByteToCharIndex, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'CharToByteIndex', JvInterpreter_CharToByteIndex, 2, [varEmpty, varEmpty], varEmpty);
    
        AddFun(cSysUtils, 'IsDelimiter', JvInterpreter_IsDelimiter, 3, [varEmpty, varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'LastDelimiter', JvInterpreter_LastDelimiter, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiCompareFileName', JvInterpreter_AnsiCompareFileName, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiLowerCaseFileName', JvInterpreter_AnsiLowerCaseFileName, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiUpperCaseFileName', JvInterpreter_AnsiUpperCaseFileName, 1, [varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiPos', JvInterpreter_AnsiPos, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiStrPos', JvInterpreter_AnsiStrPos, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiStrRScan', JvInterpreter_AnsiStrRScan, 2, [varEmpty, varEmpty], varEmpty);
        AddFun(cSysUtils, 'AnsiStrScan', JvInterpreter_AnsiStrScan, 2, [varEmpty, varEmpty], varEmpty);
    
Support :

Please see the Kquery Technical Support Forums.