Advertisement
Guest User

vip_manager.sma

a guest
Mar 28th, 2020
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 28.53 KB | None | 0 0
  1. #include <amxmodx>
  2. #include <amxmisc>
  3. #include <regex>
  4. #include <sqlx>
  5.  
  6. #define MAX_PLAYERS 32
  7.  
  8. //#define BACKWARDS_COMPAT
  9.  
  10. enum _:Auths {
  11.     Auth_Name,
  12.     Auth_SteamID,
  13.     Auth_IP,
  14.     Auth_Tag
  15. };
  16.  
  17. enum _:AuthData {
  18.     Auth_Type,
  19.     Auth_Key[35],
  20.     Auth_Password[32],
  21.     Auth_RemoveTime,
  22.     Auth_Flags
  23. };
  24.  
  25. enum _:AddData {
  26.     Data_Type,
  27.     Data_Auth[35],
  28.     Data_Password[32],
  29.     Data_Flags[27],
  30.     Data_RemoveDate[32]
  31. };
  32.  
  33. #define getBit(%1,%2) (%1 &   (1 << (%2 & 31)))
  34. #define setBit(%1,%2)  %1 |=  (1 << (%2 & 31))
  35. #define delBit(%1,%2)  %1 &= ~(1 << (%2 & 31))
  36.  
  37. new gVIP;
  38. #define is_vip(%1) getBit(gVIP, %1)
  39. #define set_vip(%1) setBit(gVIP, %1)
  40. #define remove_vip(%1) delBit(gVIP, %1)
  41.  
  42. new gFlags[MAX_PLAYERS + 1];
  43.  
  44. new Handle:gSqlTuple = Empty_Handle;
  45. new gUsersFile[64];
  46.  
  47. new gCvarSql;
  48. new gCvarHost;
  49. new gCvarUser;
  50. new gCvarPass;
  51. new gCvarDb;
  52. new gCvarAuthFlags;
  53. new gCvarDefaultFlags;
  54. new gCvarDeleteExpired;
  55. new gCvarPasswordField;
  56.  
  57. new gForwardAuth;
  58. new gForwardPutinserver;
  59. new gForwardDisconnect;
  60. new gReturnFromForward;
  61.  
  62. new Trie:gAuthKeys;
  63.  
  64. new Array:gAuthData;
  65. new Trie:gAuthToIndex[Auths];
  66. new gNumAuths;
  67.  
  68. new Regex:gDatePattern;
  69.  
  70. public plugin_init() {
  71.     register_plugin("VIP Manager", "0.0.6", "Exolent");
  72.    
  73.     register_concmd("vip_adduser", "CmdAddUser", ADMIN_RCON, "<name, #userid, authid> <type> [password] [flags] [days] -- <type> can be 'name', 'steamid', or 'ip'");
  74.     register_concmd("vip_addauth", "CmdAddAuth", ADMIN_RCON, "<type> <auth> [password] [flags] [days] -- <type> can be 'name', 'steamid', 'ip', or 'tag'");
  75.     register_concmd("vip_reload", "CmdReload", ADMIN_RCON, "-- reloads the VIP users list for the vip_users.ini");
  76.    
  77.     gCvarSql = register_cvar("vip_sql", "0");
  78.     gCvarHost = register_cvar("vip_sql_host", "");
  79.     gCvarUser = register_cvar("vip_sql_user", "");
  80.     gCvarPass = register_cvar("vip_sql_pass", "");
  81.     gCvarDb = register_cvar("vip_sql_db", "");
  82.     gCvarAuthFlags = register_cvar("vip_auth_flags", "b");
  83.     gCvarDefaultFlags = register_cvar("vip_default_flags", "");
  84.     gCvarDeleteExpired = register_cvar("vip_delete_expired", "0");
  85.     gCvarPasswordField = register_cvar("vip_password_field", "_vip_pw");
  86.    
  87.     gForwardAuth = CreateMultiForward("vip_authorized", ET_IGNORE, FP_CELL);
  88.     gForwardPutinserver = CreateMultiForward("vip_putinserver", ET_IGNORE, FP_CELL);
  89.     gForwardDisconnect = CreateMultiForward("vip_disconnect", ET_IGNORE, FP_CELL);
  90.    
  91.     gAuthKeys = TrieCreate();
  92.     TrieSetCell(gAuthKeys, "name", Auth_Name);
  93.     TrieSetCell(gAuthKeys, "steam", Auth_SteamID);
  94.     TrieSetCell(gAuthKeys, "steamid", Auth_SteamID);
  95.     TrieSetCell(gAuthKeys, "authid", Auth_SteamID);
  96.     TrieSetCell(gAuthKeys, "ip", Auth_IP);
  97.     TrieSetCell(gAuthKeys, "tag", Auth_Tag);
  98.    
  99.     gAuthData = ArrayCreate(AuthData);
  100.    
  101.     for(new i = 0; i < Auths; i++) {
  102.         gAuthToIndex[i] = TrieCreate();
  103.     }
  104.    
  105.     gDatePattern = regex_compile("\d{4}-\d{1,2}-\d{1,2}", gReturnFromForward, "", 0);
  106.    
  107.     get_configsdir(gUsersFile, charsmax(gUsersFile));
  108.     add(gUsersFile, charsmax(gUsersFile), "/vip_users.ini");
  109.    
  110.     LoadConfig();
  111. }
  112.  
  113. public plugin_end() {
  114.     TrieDestroy(gAuthKeys);
  115.    
  116.     ArrayDestroy(gAuthData);
  117.    
  118.     for(new i = 0; i < Auths; i++) {
  119.         TrieDestroy(gAuthToIndex[i]);
  120.     }
  121.    
  122.     regex_free(gDatePattern);
  123. }
  124.  
  125. public plugin_natives() {
  126.     register_library("vip");
  127.    
  128.     register_native("is_user_vip", "_is_user_vip");
  129.     register_native("get_vip_flags", "_get_vip_flags");
  130. }
  131.  
  132. public _is_user_vip(plugin, params) {
  133.     return is_vip(get_param(1)) ? 1 : 0;
  134. }
  135.  
  136. public _get_vip_flags(plugin, params) {
  137.     new id = get_param(1);
  138.    
  139.     return is_vip(id) ? gFlags[id] : 0;
  140. }
  141.  
  142. public client_authorized(id) {
  143.     CheckAuth(id, gForwardAuth);
  144. }
  145.  
  146. public client_putinserver(id) {
  147.     CheckAuth(id, gForwardPutinserver);
  148. }
  149.  
  150. public client_infochanged(id) {
  151.     if(!is_user_connected(id)) return;
  152.    
  153.     new oldName[32], newName[32];
  154.     get_user_name(id, oldName, charsmax(oldName));
  155.     get_user_info(id, "name", newName, charsmax(newName));
  156.    
  157.     if(!equal(oldName, newName)) {
  158.         CheckAuth(id, gForwardAuth, newName);
  159.     }
  160. }
  161.  
  162. public client_disconnect(id) {
  163.     if(is_vip(id)) {
  164.         ExecuteForward(gForwardDisconnect, gReturnFromForward, id);
  165.        
  166.         remove_vip(id);
  167.         gFlags[id] = 0;
  168.        
  169.         remove_task(id);
  170.     }
  171. }
  172.  
  173. public CmdAddUser(id, level, cid) {
  174.     if(!cmd_access(id, level, cid, 3)) {
  175.         return PLUGIN_HANDLED;
  176.     }
  177.    
  178.     new auth[35];
  179.     read_argv(1, auth, charsmax(auth));
  180.    
  181.     new target = cmd_target(id, auth, CMDTARGET_NO_BOTS);
  182.     if(!target) {
  183.         return PLUGIN_HANDLED;
  184.     }
  185.    
  186.     new type[16];
  187.     read_argv(2, type, charsmax(type));
  188.     strtolower(type);
  189.    
  190.     new typeNum;
  191.     if(!TrieGetCell(gAuthKeys, type, typeNum) || typeNum == Auth_Tag) {
  192.         console_print(id, "Invalid type! Only 'name', 'steamid', and 'ip' are valid types!");
  193.         return PLUGIN_HANDLED;
  194.     }
  195.    
  196.     switch(typeNum) {
  197.         case Auth_SteamID: {
  198.             get_user_authid(target, auth, charsmax(auth));
  199.         }
  200.         case Auth_IP: {
  201.             get_user_ip(target, auth, charsmax(auth), 1);
  202.         }
  203.         default: {
  204.             get_user_name(target, auth, charsmax(auth));
  205.         }
  206.     }
  207.    
  208.     new password[32];
  209.     new flagString[27], flags;
  210.     new remove, removeDate[32];
  211.    
  212.     new argCount = read_argc();
  213.     if(argCount > 3) {
  214.         read_argv(3, password, charsmax(password));
  215.        
  216.         if(argCount > 4) {
  217.             read_argv(4, flagString, charsmax(flagString));
  218.            
  219.             flags = read_flags(flagString);
  220.            
  221.             // fix flagString in case it wasn't 100% proper
  222.             get_flags(flags, flagString, charsmax(flagString));
  223.            
  224.             if(argCount > 5) {
  225.                 new days[12];
  226.                 read_argv(5, days, charsmax(days));
  227.                
  228.                 if(!is_str_num(days) || (remove = str_to_num(days)) < 0) {
  229.                     console_print(id, "Days must be a positive integer, or 0 for no expiring!");
  230.                     return PLUGIN_HANDLED;
  231.                 }
  232.                
  233.                 if(remove) {
  234.                     remove = get_systime() + (remove * 86400);
  235.                    
  236.                     format_time(removeDate, charsmax(removeDate), "%Y-%m-%d", remove);
  237.                 }
  238.             }
  239.         }
  240.     }
  241.    
  242.     new f = fopen(gUsersFile, "a+");
  243.    
  244.     if(f) {
  245.         fprintf(f, "^n^"%s^" ^"%s^" ^"%s^" ^"%s^" ^"%s^"", type, auth, password, flagString, removeDate);
  246.         fclose(f);
  247.     }
  248.    
  249.     if(gSqlTuple != Empty_Handle) {
  250.         new data[AddData];
  251.         data[Data_Type] = typeNum;
  252.         copy(data[Data_Auth], charsmax(data[Data_Auth]), auth);
  253.         copy(data[Data_Password], charsmax(data[Data_Password]), password);
  254.         copy(data[Data_Flags], charsmax(data[Data_Flags]), flagString);
  255.         copy(data[Data_RemoveDate], charsmax(data[Data_RemoveDate]), remove ? removeDate : "0000-00-00");
  256.        
  257.         new query[128];
  258.         formatex(query, charsmax(query), "SELECT COUNT(*) FROM `vip_users` WHERE `auth_type` = %d AND `auth` = ^"%s^";", typeNum, auth);
  259.        
  260.         SQL_ThreadQuery(gSqlTuple, "QueryCheckAddUser", query, data, AddData);
  261.     }
  262.    
  263.     if(typeNum != Auth_Name) {
  264.         get_user_name(target, auth, charsmax(auth));
  265.     }
  266.    
  267.    
  268.     console_print(id, "Added user to VIP: <%s> <%s>", type, auth);
  269.    
  270.     return PLUGIN_HANDLED;
  271. }
  272.  
  273. public QueryCheckAddUser(failstate, Handle:query, error[], errcode, data[], size, Float:queueTime) {
  274.     if(failstate == TQUERY_CONNECT_FAILED) {
  275.         log_amx("Failed connecting to check add user (%d): %s", errcode, error);
  276.     }
  277.     else if(failstate == TQUERY_QUERY_FAILED) {
  278.         log_amx("Failed query on check add user (%d): %s", errcode, error);
  279.     }
  280.     else if(!SQL_ReadResult(query, 0)) {
  281.         new queryString[256];
  282.         formatex(queryString, charsmax(queryString), "INSERT INTO `vip_users` (`auth_type`, `auth`, `password`, `flags`, `date_remove`) VALUES (%d, ^"%s^", ^"%s^", ^"%s^", ^"%s^");",
  283.             data[Data_Type], data[Data_Auth], data[Data_Password], data[Data_Flags], data[Data_RemoveDate]);
  284.        
  285.         SQL_ThreadQuery(gSqlTuple, "QueryAddUser", queryString);
  286.     }
  287. }
  288.  
  289. public QueryAddUser(failstate, Handle:query, error[], errcode, data[], size, Float:queueTime) {
  290.     if(failstate == TQUERY_CONNECT_FAILED) {
  291.         log_amx("Failed connecting to add user (%d): %s", errcode, error);
  292.     }
  293.     else if(failstate == TQUERY_QUERY_FAILED) {
  294.         log_amx("Failed query on add user (%d): %s", errcode, error);
  295.     }
  296. }
  297.  
  298. public CmdAddAuth(id, level, cid) {
  299.     if(!cmd_access(id, level, cid, 3)) {
  300.         return PLUGIN_HANDLED;
  301.     }
  302.    
  303.     new type[16], auth[35];
  304.     read_argv(1, type, charsmax(type));
  305.     read_argv(2, auth, charsmax(auth));
  306.    
  307.     strtolower(type);
  308.    
  309.     new typeNum;
  310.     if(!TrieGetCell(gAuthKeys, type, typeNum)) {
  311.         console_print(id, "Invalid type! Only 'name', 'steamid', 'ip', and 'tag' are valid types!");
  312.         return PLUGIN_HANDLED;
  313.     }
  314.    
  315.     new password[32];
  316.     new flagString[27], flags;
  317.     new remove, removeDate[32];
  318.    
  319.     new argCount = read_argc();
  320.     if(argCount > 3) {
  321.         read_argv(3, password, charsmax(password));
  322.        
  323.         if(argCount > 4) {
  324.             read_argv(4, flagString, charsmax(flagString));
  325.            
  326.             flags = read_flags(flagString);
  327.            
  328.             // fix flagString in case it wasn't 100% proper
  329.             get_flags(flags, flagString, charsmax(flagString));
  330.            
  331.             if(argCount > 5) {
  332.                 new days[12];
  333.                 read_argv(5, days, charsmax(days));
  334.                
  335.                 if(!is_str_num(days) || (remove = str_to_num(days)) < 0) {
  336.                     console_print(id, "Days must be a positive integer, or 0 for no expiring!");
  337.                     return PLUGIN_HANDLED;
  338.                 }
  339.                
  340.                 if(remove) {
  341.                     remove = get_systime() + (remove * 86400);
  342.                    
  343.                     format_time(removeDate, charsmax(removeDate), "%Y-%m-%d", remove);
  344.                 }
  345.             }
  346.         }
  347.     }
  348.    
  349.     new f = fopen(gUsersFile, "a+");
  350.    
  351.     if(f) {
  352.         fprintf(f, "^n^"%s^" ^"%s^" ^"%s^" ^"%s^" ^"%s^"", type, auth, password, flagString, removeDate);
  353.         fclose(f);
  354.     }
  355.    
  356.     if(gSqlTuple != Empty_Handle) {
  357.         new data[AddData];
  358.         data[Data_Type] = typeNum;
  359.         copy(data[Data_Auth], charsmax(data[Data_Auth]), auth);
  360.         copy(data[Data_Password], charsmax(data[Data_Password]), password);
  361.         copy(data[Data_Flags], charsmax(data[Data_Flags]), flagString);
  362.         copy(data[Data_RemoveDate], charsmax(data[Data_RemoveDate]), remove ? removeDate : "0000-00-00");
  363.        
  364.         new query[128];
  365.         formatex(query, charsmax(query), "SELECT COUNT(*) FROM `vip_users` WHERE `auth_type` = %d AND `auth` = ^"%s^";", typeNum, auth);
  366.        
  367.         SQL_ThreadQuery(gSqlTuple, "QueryCheckAddAuth", query, data, AddData);
  368.     }
  369.    
  370.     console_print(id, "Added user to VIP: <%s> <%s>", type, auth);
  371.    
  372.     return PLUGIN_HANDLED;
  373. }
  374.  
  375. public QueryCheckAddAuth(failstate, Handle:query, error[], errcode, data[], size, Float:queueTime) {
  376.     if(failstate == TQUERY_CONNECT_FAILED) {
  377.         log_amx("Failed connecting to check add auth (%d): %s", errcode, error);
  378.     }
  379.     else if(failstate == TQUERY_QUERY_FAILED) {
  380.         log_amx("Failed query on check add auth (%d): %s", errcode, error);
  381.     }
  382.     else if(!SQL_ReadResult(query, 0)) {
  383.         new queryString[256];
  384.         formatex(queryString, charsmax(queryString), "INSERT INTO `vip_users` (`auth_type`, `auth`, `password`, `flags`, `date_remove`) VALUES (%d, ^"%s^", ^"%s^", ^"%s^", ^"%s^");",
  385.             data[Data_Type], data[Data_Auth], data[Data_Password], data[Data_Flags], data[Data_RemoveDate]);
  386.        
  387.         SQL_ThreadQuery(gSqlTuple, "QueryAddAuth", queryString);
  388.     }
  389. }
  390.  
  391. public QueryAddAuth(failstate, Handle:query, error[], errcode, data[], size, Float:queueTime) {
  392.     if(failstate == TQUERY_CONNECT_FAILED) {
  393.         log_amx("Failed connecting to add auth (%d): %s", errcode, error);
  394.     }
  395.     else if(failstate == TQUERY_QUERY_FAILED) {
  396.         log_amx("Failed query on add auth (%d): %s", errcode, error);
  397.     }
  398. }
  399.  
  400. public CmdReload(id, level, cid) {
  401.     if(!cmd_access(id, level, cid, 1)) {
  402.         return PLUGIN_HANDLED;
  403.     }
  404.    
  405.     LoadConfig();
  406.    
  407.     new players[32], num;
  408.     get_players(players, num, "ch");
  409.    
  410.     while(num) {
  411.         CheckAuth(players[--num], gForwardAuth);
  412.     }
  413.    
  414.     console_print(id, "Reloaded VIP users list");
  415.    
  416.     return PLUGIN_HANDLED;
  417. }
  418.  
  419. LoadConfig() {
  420.     static bool:alreadyLoaded;
  421.    
  422.     if(alreadyLoaded) {
  423.         gSqlTuple = Empty_Handle;
  424.        
  425.         ArrayClear(gAuthData);
  426.         gNumAuths = 0;
  427.     }
  428.    
  429.     new config[64];
  430.     get_configsdir(config, charsmax(config));
  431.     add(config, charsmax(config), "/vip.cfg");
  432.    
  433.     if(file_exists(config)) {
  434.         server_cmd("exec %s", config);
  435.         server_exec();
  436.     }
  437.    
  438.     if(!get_pcvar_num(gCvarSql) || !LoadSql(alreadyLoaded)) {
  439.         LoadFile();
  440.     }
  441.    
  442.     alreadyLoaded = true;
  443. }
  444.  
  445. LoadFile() {
  446.    
  447.     new f = fopen(gUsersFile, "rt");
  448.    
  449.     if(!f) return;
  450.    
  451.     new data[64];
  452.     new type[16];
  453.     new typeNum;
  454.     new auth[32];
  455.     new flagString[32];
  456.     new removeDate[32];
  457.     new remove, curTime = get_systime();
  458.     new authData[AuthData];
  459.     new deleteExpired = get_pcvar_num(gCvarDeleteExpired);
  460.     new Trie:linesExpired, line;
  461.    
  462. #if defined BACKWARDS_COMPAT
  463.     new Trie:linesToFix = TrieCreate(), bool:fixLines = false;
  464. #endif
  465.    
  466.     new tmpFile[64];
  467.     formatex(tmpFile, charsmax(tmpFile), "%s.tmp", gUsersFile);
  468.    
  469.     if(deleteExpired) {
  470.         linesExpired = TrieCreate();
  471.     }
  472.    
  473.     while(!feof(f)) {
  474.         fgets(f, data, charsmax(data));
  475.         trim(data);
  476.         line++;
  477.        
  478.         if(!data[0] || data[0] == ';' || data[0] == '/' && data[1] == '/') continue;
  479.        
  480.         if(parse(data, type, charsmax(type), auth, charsmax(auth), flagString, charsmax(flagString), removeDate, charsmax(removeDate)) < 2) continue;
  481.        
  482.         strtolower(type);
  483.        
  484.         if(!TrieGetCell(gAuthKeys, type, typeNum) || TrieKeyExists(gAuthToIndex[typeNum], auth)) continue;
  485.        
  486. #if defined BACKWARDS_COMPAT
  487.         if(!removeDate[0]) {
  488.             // there are only 3 params
  489.             // check if the 3rd is a date instead of flags
  490.             // this is for backwards compatibility for older versions without flags
  491.             if(flagString[0] && regex_match_c(flagString, gDatePattern, gReturnFromForward) > 0) {
  492.                 // this flag string is really a date string
  493.                 // switch the strings
  494.                 copy(data, charsmax(data), removeDate);
  495.                 copy(removeDate, charsmax(removeDate), flagString);
  496.                 copy(flagString, charsmax(flagString), data);
  497.                
  498.                 // say we want to fix lines later
  499.                 fixLines = true;
  500.                
  501.                 // add specific line to be fixed
  502.                 num_to_str(line, data, charsmax(data));
  503.                 TrieSetCell(linesToFix, data, line);
  504.             }
  505.         }
  506. #endif
  507.        
  508.         remove = DateToUnix(removeDate);
  509.        
  510.         if(remove && remove <= curTime) {
  511.             if(deleteExpired) {
  512.                 num_to_str(line, type, charsmax(type));
  513.                 TrieSetCell(linesExpired, type, line);
  514.             }
  515.             continue;
  516.         }
  517.        
  518.         authData[Auth_Type] = typeNum;
  519.         copy(authData[Auth_Key], charsmax(authData[Auth_Key]), auth);
  520.         authData[Auth_Flags] = read_flags(flagString);
  521.         authData[Auth_RemoveTime] = remove;
  522.        
  523.         ArrayPushArray(gAuthData, authData);
  524.         TrieSetCell(gAuthToIndex[typeNum], auth, gNumAuths);
  525.         gNumAuths++;
  526.     }
  527.    
  528. #if defined BACKWARDS_COMPAT
  529.     if(deleteExpired || fixLines) {
  530. #else
  531.     if(deleteExpired) {
  532. #endif
  533.         fseek(f, 0, SEEK_SET);
  534.        
  535.         new t = fopen(tmpFile, "wt");
  536.         line = 0;
  537.        
  538.         while(!feof(f)) {
  539.             num_to_str(++line, type, charsmax(type));
  540.             fgets(f, data, charsmax(data));
  541.            
  542.             if(deleteExpired && TrieKeyExists(linesExpired, type)) continue;
  543.            
  544. #if defined BACKWARDS_COMPAT
  545.             if(TrieKeyExists(linesToFix, type)) {
  546.                 parse(data, type, charsmax(type), auth, charsmax(auth), flagString, charsmax(flagString), removeDate, charsmax(removeDate));
  547.                
  548.                 // switch date and flag string since they are backwards
  549.                 formatex(data, charsmax(data), "^"%s^" ^"%s^" ^"%s^" ^"%s^"^n", type, auth, removeDate, flagString);
  550.             }
  551. #endif
  552.            
  553.             fputs(t, data);
  554.         }
  555.        
  556.         fclose(t);
  557.        
  558.         TrieDestroy(linesExpired);
  559.     }
  560.    
  561. #if defined BACKWARDS_COMPAT
  562.     TrieDestroy(linesToFix);
  563. #endif
  564.    
  565.     fclose(f);
  566.    
  567. #if defined BACKWARDS_COMPAT
  568.     if(deleteExpired || fixLines) {
  569. #else
  570.     if(deleteExpired) {
  571. #endif
  572.         rename_file(tmpFile, gUsersFile, 1);
  573.     }
  574. }
  575.  
  576. DateToUnix(const dateString[]) {
  577.     if(!dateString[0] || regex_match_c(dateString, gDatePattern, gReturnFromForward) <= 0 || equal(dateString, "0000-00-00")) {
  578.         return 0;
  579.     }
  580.    
  581.     new year[5], month[3], rest[32];
  582.     strtok(dateString, year, charsmax(year), rest, charsmax(rest), '-');
  583.     strtok(rest, month, charsmax(month), rest, charsmax(rest), '-');
  584.    
  585.     return TimeToUnix(str_to_num(year), str_to_num(month), str_to_num(rest), 0, 0, 0);
  586. }
  587.  
  588. LoadSql(bool:threadQueries) {
  589.     new host[32], user[32], pass[32], db[32];
  590.     get_pcvar_string(gCvarHost, host, charsmax(host));
  591.     get_pcvar_string(gCvarUser, user, charsmax(user));
  592.     get_pcvar_string(gCvarPass, pass, charsmax(pass));
  593.     get_pcvar_string(gCvarDb, db, charsmax(db));
  594.    
  595.     gSqlTuple = SQL_MakeDbTuple(host, user, pass, db);
  596.    
  597.     if(gSqlTuple == Empty_Handle) {
  598.         log_amx("Failed to create SQL tuple.");
  599.         return 0;
  600.     }
  601.    
  602.     new const queryString[] = "CREATE TABLE IF NOT EXISTS `vip_users` (\
  603.            `id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,\
  604.            `auth_type` INT NOT NULL DEFAULT '0',\
  605.            `auth` VARCHAR(32) NOT NULL,\
  606.            `password` VARCHAR(32) NOT NULL,\
  607.            `flags` VARCHAR(26) NOT NULL,\
  608.            `date_remove` DATE NOT NULL DEFAULT '0000-00-00');";
  609.    
  610.     if(threadQueries) {
  611.         SQL_ThreadQuery(gSqlTuple, "QueryCreateTable", queryString);
  612.     } else {
  613.         new errcode, error[128];
  614.         new Handle:link = SQL_Connect(gSqlTuple, errcode, error, charsmax(error));
  615.        
  616.         if(link == Empty_Handle) {
  617.             gSqlTuple = Empty_Handle;
  618.            
  619.             log_amx("Failed to connect to database (%d): %s", errcode, error);
  620.             return 0;
  621.         }
  622.        
  623.         new Handle:query = SQL_PrepareQuery(link, "%s", queryString);
  624.        
  625.         // Added `date_remove` field to table
  626.         //
  627.         // Fix for v0.0.1 to v0.0.2
  628.         // ALTER TABLE `vip_users` ADD `date_remove` DATE NOT NULL DEFAULT '0000-00-00';
  629.        
  630.         // Added `flags` field to table
  631.         //
  632.         // Fix for v0.0.1 to v0.0.4
  633.         // ALTER TABLE `vip_users` ADD `date_remove` DATE NOT NULL DEFAULT '0000-00-00', ADD `flags` VARCHAR(26) NOT NULL DEFAULT '';
  634.         //
  635.         // Fix for v0.0.2 to v0.0.4
  636.         // ALTER TABLE `vip_users` ADD `flags` VARCHAR(26) NOT NULL DEFAULT '';
  637.        
  638.         // Added `password` field to table
  639.         //
  640.         // Fix for v0.0.1 to v0.0.5
  641.         // ALTER TABLE `vip_users` ADD `date_remove` DATE NOT NULL DEFAULT '0000-00-00', ADD `flags` VARCHAR(26) NOT NULL DEFAULT '', ADD `password` VARCHAR(32) NOT NULL DEFAULT '';
  642.         //
  643.         // Fix for v0.0.2 to v0.0.5
  644.         // ALTER TABLE `vip_users` ADD `flags` VARCHAR(26) NOT NULL DEFAULT '', ADD `password` VARCHAR(32) NOT NULL DEFAULT '';
  645.         //
  646.         // Fix for v0.0.4 to v0.0.5
  647.         // ALTER TABLE `vip_users` ADD `password` VARCHAR(32) NOT NULL DEFAULT '';
  648.        
  649.         if(!SQL_Execute(query)) {
  650.             gSqlTuple = Empty_Handle;
  651.            
  652.             SQL_QueryError(query, error, charsmax(error));
  653.             log_amx("Error creating table: %s", error);
  654.         }
  655.        
  656.         SQL_FreeHandle(query);
  657.         SQL_FreeHandle(link);
  658.        
  659.         if(gSqlTuple != Empty_Handle) {
  660.             LoadFromSql();
  661.         } else {
  662.             return 0;
  663.         }
  664.     }
  665.    
  666.     return 1;
  667. }
  668.  
  669. public QueryCreateTable(failstate, Handle:query, error[], errcode, data[], size, Float:queueTime) {
  670.     if(failstate == TQUERY_CONNECT_FAILED) {
  671.         log_amx("Failed connecting to create table (%d): %s", errcode, error);
  672.        
  673.         LoadFile();
  674.     }
  675.     else if(failstate == TQUERY_QUERY_FAILED) {
  676.         log_amx("Failed query on create table (%d): %s", errcode, error);
  677.        
  678.         LoadFile();
  679.     }
  680.     else {
  681.         LoadFromSql();
  682.     }
  683. }
  684.  
  685. LoadFromSql() {
  686.     new curDate[11];
  687.     get_time("%Y-%m-%d", curDate, charsmax(curDate));
  688.    
  689.     new queryString[94];
  690.     // SELECT * FROM `vip_users` WHERE `date_remove` = '0000-00-00' OR `date_remove` > '2012-02-09';
  691.     // 0123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789
  692.    
  693.     if(get_pcvar_num(gCvarDeleteExpired)) {
  694.         formatex(queryString, charsmax(queryString), "DELETE FROM `vip_users` WHERE `date_remove` > '%s';", curDate);
  695.        
  696.         SQL_ThreadQuery(gSqlTuple, "QueryDeleteExpired", queryString);
  697.     }
  698.    
  699.     formatex(queryString, charsmax(queryString), "SELECT * FROM `vip_users` WHERE `date_remove` = '0000-00-00' OR `date_remove` > '%s';", curDate);
  700.    
  701.     SQL_ThreadQuery(gSqlTuple, "QueryLoadUsers", queryString);
  702. }
  703.  
  704. public QueryDeleteExpired(failstate, Handle:query, error[], errcode, data[], size, Float:queueTime) {
  705.     if(failstate == TQUERY_CONNECT_FAILED) {
  706.         log_amx("Failed connecting to delete expired (%d): %s", errcode, error);
  707.     }
  708.     else if(failstate == TQUERY_QUERY_FAILED) {
  709.         log_amx("Failed query on delete expired (%d): %s", errcode, error);
  710.     }
  711. }
  712.  
  713. public QueryLoadUsers(failstate, Handle:query, error[], errcode, data[], size, Float:queueTime) {
  714.     if(failstate == TQUERY_CONNECT_FAILED) {
  715.         log_amx("Failed connecting to load users (%d): %s", errcode, error);
  716.        
  717.         LoadFile();
  718.     }
  719.     else if(failstate == TQUERY_QUERY_FAILED) {
  720.         log_amx("Failed query on load users (%d): %s", errcode, error);
  721.        
  722.         LoadFile();
  723.     }
  724.     else if(SQL_NumResults(query)) {
  725.         new fieldAuth = SQL_FieldNameToNum(query, "auth");
  726.         new fieldType = SQL_FieldNameToNum(query, "auth_type");
  727.         new fieldPassword = SQL_FieldNameToNum(query, "password");
  728.         new fieldFlags = SQL_FieldNameToNum(query, "flags");
  729.         new fieldRemove = SQL_FieldNameToNum(query, "date_remove");
  730.        
  731.         new flagString[27];
  732.         new removeDate[11];
  733.         new curTime = get_systime();
  734.         new authData[AuthData];
  735.        
  736.         do {
  737.             SQL_ReadResult(query, fieldRemove, removeDate, charsmax(removeDate));
  738.            
  739.             authData[Auth_RemoveTime] = DateToUnix(removeDate);
  740.            
  741.             if(!authData[Auth_RemoveTime] || authData[Auth_RemoveTime] > curTime) {
  742.                 SQL_ReadResult(query, fieldAuth, authData[Auth_Key], charsmax(authData[Auth_Key]));
  743.                 authData[Auth_Type] = SQL_ReadResult(query, fieldType);
  744.                
  745.                 SQL_ReadResult(query, fieldPassword, authData[Auth_Password], charsmax(authData[Auth_Password]));
  746.                
  747.                 SQL_ReadResult(query, fieldFlags, flagString, charsmax(flagString));
  748.                 authData[Auth_Flags] = read_flags(flagString);
  749.                
  750.                 ArrayPushArray(gAuthData, authData);
  751.                 TrieSetCell(gAuthToIndex[authData[Auth_Type]], authData[Auth_Key], gNumAuths);
  752.                 gNumAuths++;
  753.             }
  754.            
  755.             SQL_NextRow(query);
  756.         }
  757.         while(SQL_MoreResults(query));
  758.     }
  759. }
  760.  
  761. CheckAuth(id, forwardHandle, forceName[] = "") {
  762.     new wasVip = is_vip(id);
  763.     remove_vip(id);
  764.     gFlags[id] = 0;
  765.    
  766.     remove_task(id);
  767.    
  768.     new flags[27];
  769.     get_pcvar_string(gCvarAuthFlags, flags, charsmax(flags));
  770.    
  771.     if(flags[0] && has_all_flags(id, flags)) {
  772.         gFlags[id] = read_flags(flags) | read_pcvar_flags(gCvarDefaultFlags);
  773.         AuthUser(id, wasVip, forwardHandle);
  774.         return;
  775.     }
  776.    
  777.     new name[32], steamid[32], ip[32];
  778.     if(forceName[0]) {
  779.         copy(name, charsmax(name), forceName);
  780.     } else {
  781.         get_user_name(id, name, charsmax(name));
  782.     }
  783.     get_user_authid(id, steamid, charsmax(steamid));
  784.     get_user_ip(id, ip, charsmax(ip), 1);
  785.    
  786.     new curTime = get_systime();
  787.    
  788.     new authData[AuthData], index;
  789.    
  790.     if(!TrieGetCell(Trie:gAuthToIndex[Auth_Name], name, index)
  791.     && !TrieGetCell(Trie:gAuthToIndex[Auth_SteamID], steamid, index)
  792.     && !TrieGetCell(Trie:gAuthToIndex[Auth_IP], ip, index)) {
  793.         index = -1;
  794.        
  795.         for(new i = 0; i < gNumAuths; i++) {
  796.             ArrayGetArray(gAuthData, i, authData);
  797.            
  798.             if(authData[Auth_Type] == Auth_Tag
  799.             && (0 < authData[Auth_RemoveTime] <= curTime)
  800.             && containi(name, authData[Auth_Key]) != -1) {
  801.                 index = i;
  802.                 break;
  803.             }
  804.         }
  805.        
  806.         if(index == -1) return;
  807.     }
  808.    
  809.     if(authData[Auth_Password][0]) {
  810.         new field[32], password[32];
  811.         get_pcvar_string(gCvarPasswordField, field, charsmax(field));
  812.         get_user_info(id, field, password, charsmax(password));
  813.        
  814.         if(!equal(authData[Auth_Password], password)) return;
  815.     }
  816.    
  817.     gFlags[id] = authData[Auth_Flags] | read_pcvar_flags(gCvarDefaultFlags);
  818.     AuthUser(id, wasVip, forwardHandle, authData[Auth_RemoveTime] - curTime);
  819. }
  820.  
  821. AuthUser(id, wasVip, forwardHandle, remove = 0) {
  822.     set_vip(id);
  823.    
  824.     if(!wasVip) {
  825.         ExecuteForward(forwardHandle, wasVip, id);
  826.     }
  827.    
  828.     if(remove > 0) {
  829.         set_task(float(remove), "TaskCheckAuth", id);
  830.     }
  831. }
  832.  
  833. public TaskCheckAuth(id) {
  834.     CheckAuth(id, gForwardAuth);
  835. }
  836.  
  837. read_pcvar_flags(cvar) {
  838.     new flags[27];
  839.     get_pcvar_string(cvar, flags, charsmax(flags));
  840.     return read_flags(flags);
  841. }
  842.  
  843. // CODE BELOW IS FROM BUGSY'S UNIX TO TIME CONVERSION INCLUDE
  844. // https://forums.alliedmods.net/showthread.php?t=91915
  845.  
  846. stock const YearSeconds[2] =
  847. {
  848.     31536000,    //Normal year
  849.     31622400     //Leap year
  850. };
  851.  
  852. stock const MonthSeconds[12] =
  853. {
  854.     2678400, //January    31
  855.     2419200, //February    28
  856.     2678400, //March    31
  857.     2592000, //April    30
  858.     2678400, //May        31
  859.     2592000, //June        30
  860.     2678400, //July        31
  861.     2678400, //August    31
  862.     2592000, //September    30
  863.     2678400, //October    31
  864.     2592000, //November    30
  865.     2678400  //December    31
  866. };
  867.  
  868. stock const DaySeconds = 86400;
  869. stock const HourSeconds = 3600;
  870. stock const MinuteSeconds = 60;
  871.  
  872. stock TimeToUnix( const iYear , const iMonth , const iDay , const iHour , const iMinute , const iSecond /*, TimeZones:tzTimeZone=UT_TIMEZONE_UTC*/)
  873. {
  874.     new i , iTimeStamp;
  875.  
  876.     for ( i = 1970 ; i < iYear ; i++ )
  877.         iTimeStamp += YearSeconds[ IsLeapYear(i) ];
  878.  
  879.     for ( i = 1 ; i < iMonth ; i++ )
  880.         iTimeStamp += SecondsInMonth( iYear , i );
  881.  
  882.     iTimeStamp += ( ( iDay - 1 ) * DaySeconds );
  883.     iTimeStamp += ( iHour * HourSeconds );
  884.     iTimeStamp += ( iMinute * MinuteSeconds );
  885.     iTimeStamp += iSecond;
  886.  
  887.     /*if ( tzTimeZone == UT_TIMEZONE_SERVER )
  888.         tzTimeZone = GetTimeZone();
  889.        
  890.     return ( iTimeStamp + TimeZoneOffset[ tzTimeZone ] );*/
  891.    
  892.     return iTimeStamp;
  893. }
  894.  
  895. stock SecondsInMonth( const iYear , const iMonth )
  896. {
  897.     return ( ( IsLeapYear( iYear ) && ( iMonth == 2 ) ) ? ( MonthSeconds[iMonth - 1] + DaySeconds ) : MonthSeconds[iMonth - 1] );
  898. }
  899.  
  900. stock IsLeapYear( const iYear )
  901. {
  902.     return ( ( (iYear % 4) == 0) && ( ( (iYear % 100) != 0) || ( (iYear % 400) == 0 ) ) );
  903. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement