Advertisement
Tibers

Speedrun Stats / R3X / Mistrick

Apr 2nd, 2024
485
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Pawn 23.14 KB | Source Code | 0 0
  1. // Credits: R3X
  2. #include <amxmodx>
  3. #include <amxmisc>
  4. #include <engine>
  5. #include <fakemeta>
  6. #include <reapi>
  7. #include <geoip>
  8. #include <sqlx>
  9. #include <box_system>
  10. #include <beams>
  11. #if AMXX_VERSION_NUM < 183
  12. #include <colorchat>
  13. #endif
  14.  
  15. #define PLUGIN "Speedrun: Stats"
  16. #define VERSION "0.3"
  17. #define AUTHOR "Mistrick"
  18.  
  19. #pragma semicolon 1
  20.  
  21. #define FINISH_SPRITENAME "sprites/white.spr"
  22.  
  23. enum _:PlayerData
  24. {
  25.     m_bConnected,
  26.     m_bAuthorized,
  27.     m_bTimerStarted,
  28.     m_bFinished,
  29.     m_iPlayerIndex,
  30.     Float:m_fStartRun
  31. };
  32. enum _:Categories
  33. {
  34.     Cat_100fps,
  35.     Cat_200fps,
  36.     Cat_250fps,
  37.     Cat_333fps,
  38.     Cat_500fps,
  39.     Cat_FastRun,
  40.     Cat_CrazySpeed
  41. };
  42. enum _:Cvars
  43. {
  44.     SQL_HOST,
  45.     SQL_USER,
  46.     SQL_PASSWORD,
  47.     SQL_DATABASE
  48. };
  49.  
  50. new const PREFIX[] = "^4[Speedrun]";
  51.  
  52. new const g_szCategory[][] =
  53. {
  54.     "[100 FPS]", "[200 FPS]", "[250 FPS]", "[333 FPS]", "[500 FPS]", "[Fastrun]", "[Crazy Speed]"
  55. };
  56.  
  57. new g_pCvars[Cvars];
  58. new Handle:g_hTuple, g_szQuery[512];
  59. new g_szMapName[32];
  60. new g_iMapIndex;
  61. new g_ePlayerInfo[33][PlayerData];
  62. new g_iBestTime[33][Categories];
  63. new g_iFinishEnt;
  64. //new g_iSprite;
  65. new g_szMotd[1536];
  66. new g_iBestTimeofMap[Categories];
  67. new g_fwFinished;
  68. new g_iReturn;
  69.  
  70. native get_user_category(id);
  71. forward SR_PlayerOnStart(id);
  72.  
  73. public plugin_init()
  74. {
  75.     register_plugin(PLUGIN, VERSION, AUTHOR);
  76.    
  77.     g_pCvars[SQL_HOST] = register_cvar("speedrun_host", "127.0.0.1");
  78.     g_pCvars[SQL_USER] = register_cvar("speedrun_user", "root");
  79.     g_pCvars[SQL_PASSWORD] = register_cvar("speedrun_password", "root");
  80.     g_pCvars[SQL_DATABASE] = register_cvar("speedrun_database", "speedrun");
  81.    
  82.     register_clcmd("say /rank", "Command_Rank");
  83.     register_clcmd("say /top15", "Command_Top15");
  84.     register_clcmd("say /update", "Command_Update");
  85.    
  86.     RegisterHookChain(RG_CBasePlayer_Jump, "HC_CheckStartTimer", false);
  87.     RegisterHookChain(RG_CBasePlayer_Duck, "HC_CheckStartTimer", false);
  88.     RegisterHookChain(RG_CBasePlayer_Spawn, "HC_CBasePlayer_Spawn_Post", true);
  89.    
  90.     g_fwFinished = CreateMultiForward("SR_PlayerFinishedMap", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL);
  91.    
  92.     CreateTimer();
  93. }
  94. public plugin_cfg()
  95. {
  96.     set_task(0.5, "DB_Init");
  97. }
  98. public plugin_precache()
  99. {
  100.     //g_iSprite = precache_model("sprites/white.spr");
  101. }
  102.  
  103. public Command_Rank(id)
  104. {
  105.     if(!g_ePlayerInfo[id][m_bAuthorized] || is_flooding(id)) return PLUGIN_HANDLED;
  106.    
  107.     new category = get_user_category(id);
  108.    
  109.     if(g_iBestTime[id][category] == 0)
  110.     {
  111.         client_print_color(id, print_team_default, "%s%s^1 You never reach finish.", PREFIX, g_szCategory[category]);
  112.         return PLUGIN_CONTINUE;
  113.     }
  114.    
  115.     ShowRank(id, category);
  116.    
  117.     return PLUGIN_CONTINUE;
  118. }
  119. public Command_Top15(id)
  120. {
  121.     if(!g_ePlayerInfo[id][m_bAuthorized] || is_flooding(id)) return PLUGIN_HANDLED;
  122.    
  123.     ShowTop15(id, get_user_category(id));
  124.    
  125.     return PLUGIN_CONTINUE;
  126. }
  127. public Command_Update(id)
  128. {
  129.     if(!g_ePlayerInfo[id][m_bAuthorized] || is_flooding(id)) return PLUGIN_HANDLED;
  130.    
  131.     new szName[32]; get_user_name(id, szName, charsmax(szName)); SQL_PrepareString(szName, szName, charsmax(szName));
  132.     formatex(g_szQuery, charsmax(g_szQuery), "UPDATE `runners` SET nickname = '%s' WHERE id=%d", szName, g_ePlayerInfo[id][m_iPlayerIndex]);
  133.    
  134.     SQL_ThreadQuery(g_hTuple, "Query_IngnoredHandle", g_szQuery);
  135.    
  136.     return PLUGIN_CONTINUE;
  137. }
  138.  
  139. CreateTimer()
  140. {
  141.     new ent = create_entity("info_target");
  142.     set_entvar(ent, var_classname, "timer_think");
  143.     set_entvar(ent, var_nextthink, get_gametime() + 1.0);  
  144.     register_think("timer_think", "Think_Timer");
  145. }
  146.  
  147. public DB_Init()
  148. {
  149.     state mysql;
  150.    
  151.     new szDB[32]; get_pcvar_string(g_pCvars[SQL_DATABASE], szDB, charsmax(szDB));
  152.    
  153.     if(contain(szDB, ".") > 0)
  154.     {
  155.         state sqlite;
  156.     }
  157.        
  158.     SQL_Init();
  159. }
  160. SQL_Init()<sqlite>
  161. {
  162.     SQL_SetAffinity("sqlite");
  163.    
  164.     new szDir[128]; get_localinfo("amxx_datadir", szDir, charsmax(szDir));
  165.     new szDB[32]; get_pcvar_string(g_pCvars[SQL_DATABASE], szDB, charsmax(szDB));
  166.     new szFile[128]; format(szFile, charsmax(szFile), "%s/%s", szDir, szDB);
  167.    
  168.     if(!file_exists(szFile))
  169.     {
  170.         new file = fopen(szFile, "w");
  171.         if(!file)
  172.         {
  173.             new szMsg[128]; formatex(szMsg, charsmax(szMsg), "%s file not found and cant be created.", szFile);
  174.             set_fail_state(szMsg);
  175.         }
  176.         fclose(file);
  177.     }
  178.    
  179.     g_hTuple = SQL_MakeDbTuple("", "", "", szFile, 0);
  180.    
  181.     formatex(g_szQuery, charsmax(g_szQuery),
  182.             "CREATE TABLE IF NOT EXISTS `runners`( \
  183.             id      INTEGER     PRIMARY KEY,\
  184.             steamid     TEXT    NOT NULL, \
  185.             nickname    TEXT    NOT NULL, \
  186.             ip      TEXT    NOT NULL, \
  187.             nationality TEXT    NULL)");
  188.    
  189.     SQL_ThreadQuery(g_hTuple, "Query_IngnoredHandle", g_szQuery);
  190.    
  191.     formatex(g_szQuery, charsmax(g_szQuery),
  192.             "CREATE TABLE IF NOT EXISTS `maps`( \
  193.             mid         INTEGER     PRIMARY KEY,\
  194.             mapname     TEXT        NOT NULL    UNIQUE, \
  195.             finishX     INTEGER     NOT NULL    DEFAULT 0, \
  196.             finishY     INTEGER     NOT NULL    DEFAULT 0, \
  197.             finishZ     INTEGER     NOT NULL    DEFAULT 0)");
  198.    
  199.     SQL_ThreadQuery(g_hTuple, "Query_IngnoredHandle", g_szQuery);
  200.    
  201.     formatex(g_szQuery, charsmax(g_szQuery),
  202.             "CREATE TABLE IF NOT EXISTS `results`( \
  203.             id          INTEGER     NOT NULL, \
  204.             mid         INTEGER     NOT NULL, \
  205.             category    INTEGER     NOT NULL, \
  206.             besttime    INTEGER     NOT NULL, \
  207.             recorddate  DATETIME    NULL, \
  208.             FOREIGN KEY(id) REFERENCES `runners`(id) ON DELETE CASCADE, \
  209.             FOREIGN KEY(mid) REFERENCES `maps`(mid) ON DELETE CASCADE, \
  210.             PRIMARY KEY(id, mid, category))");
  211.    
  212.     SQL_ThreadQuery(g_hTuple, "Query_IngnoredHandle", g_szQuery);
  213.    
  214.     set_task(1.0, "DelayedLoadMapInfo");
  215. }
  216. SQL_Init()<mysql>
  217. {
  218.     new szHost[32], szUser[32], szPass[32], szDB[32];
  219.     get_pcvar_string(g_pCvars[SQL_HOST], szHost, charsmax(szHost));
  220.     get_pcvar_string(g_pCvars[SQL_USER], szUser, charsmax(szUser));
  221.     get_pcvar_string(g_pCvars[SQL_PASSWORD], szPass, charsmax(szPass));
  222.     get_pcvar_string(g_pCvars[SQL_DATABASE], szDB, charsmax(szDB));
  223.    
  224.     g_hTuple = SQL_MakeDbTuple(szHost, szUser, szPass, szDB);
  225.    
  226.     if(g_hTuple == Empty_Handle)
  227.     {
  228.         set_fail_state("Cant create connection tuple");
  229.     }
  230.    
  231.     formatex(g_szQuery, charsmax(g_szQuery),
  232.             "CREATE TABLE IF NOT EXISTS `runners`(\
  233.             id          INT(11) UNSIGNED    AUTO_INCREMENT,\
  234.             steamid     VARCHAR(32) NOT NULL,\
  235.             nickname    VARCHAR(32) NOT NULL,\
  236.             ip          VARCHAR(32) NOT NULL,\
  237.             nationality VARCHAR(3)  NULL,\
  238.             PRIMARY KEY(id))");
  239.    
  240.     SQL_ThreadQuery(g_hTuple, "Query_IngnoredHandle", g_szQuery);
  241.    
  242.     formatex(g_szQuery, charsmax(g_szQuery),
  243.             "CREATE TABLE IF NOT EXISTS `maps`(\
  244.             mid         INT(11) UNSIGNED    AUTO_INCREMENT,\
  245.             mapname     VARCHAR(64) NOT NULL    UNIQUE,\
  246.             finishX     INT(11)     NOT NULL    DEFAULT 0,\
  247.             finishY     INT(11)     NOT NULL    DEFAULT 0,\
  248.             finishZ     INT(11)     NOT NULL    DEFAULT 0,\
  249.             PRIMARY KEY(mid))");
  250.    
  251.     SQL_ThreadQuery(g_hTuple, "Query_IngnoredHandle", g_szQuery);
  252.    
  253.     formatex(g_szQuery, charsmax(g_szQuery),
  254.             "CREATE TABLE IF NOT EXISTS `results`(\
  255.             id          INT(11)     UNSIGNED,\
  256.             mid         INT(11)     UNSIGNED,\
  257.             category    INT(11)     NOT NULL,\
  258.             besttime    INT(11)     NOT NULL,\
  259.             recorddate  DATETIME    NULL,\
  260.             FOREIGN KEY(id) REFERENCES `runners`(id) ON DELETE CASCADE,\
  261.             FOREIGN KEY(mid) REFERENCES `maps`(mid) ON DELETE CASCADE,\
  262.             PRIMARY KEY(id, mid, category))");
  263.    
  264.     SQL_ThreadQuery(g_hTuple, "Query_IngnoredHandle", g_szQuery);
  265.    
  266.     set_task(1.0, "DelayedLoadMapInfo");
  267. }
  268. public DelayedLoadMapInfo()
  269. {
  270.     get_mapname(g_szMapName, charsmax(g_szMapName));
  271.     formatex(g_szQuery, charsmax(g_szQuery), "SELECT mid, finishX, finishY, finishZ FROM `maps` WHERE mapname='%s'", g_szMapName);
  272.     SQL_ThreadQuery(g_hTuple, "Query_LoadMapHandle", g_szQuery);
  273. }
  274. public Query_LoadMapHandle(failstate, Handle:query, error[], errnum, data[], size)
  275. {
  276.     if(failstate != TQUERY_SUCCESS)
  277.     {
  278.         log_amx("SQL error[LoadMapHandle]: %s", error); return;
  279.     }
  280.    
  281.     if(SQL_MoreResults(query))
  282.     {
  283.         g_iMapIndex = SQL_ReadResult(query, 0);
  284.        
  285.         SQL_ReadResult(query, 1),  SQL_ReadResult(query, 2);
  286.         //CreateFinishI(SQL_ReadResult(query, 1),  SQL_ReadResult(query, 2),  SQL_ReadResult(query, 3));
  287.     }
  288.     else
  289.     {      
  290.         formatex(g_szQuery, charsmax(g_szQuery), "INSERT INTO `maps`(mapname) VALUES ('%s')", g_szMapName);
  291.         SQL_ThreadQuery(g_hTuple, "Query_IngnoredHandle", g_szQuery);
  292.        
  293.         formatex(g_szQuery, charsmax(g_szQuery), "SELECT mid, finishX, finishY, finishZ FROM `maps` WHERE mapname='%s'", g_szMapName);
  294.         SQL_ThreadQuery(g_hTuple, "Query_LoadMapHandle", g_szQuery);
  295.     }
  296.  
  297.     if(g_iMapIndex)
  298.     {
  299.         for(new i = 1; i <= 32; i++)
  300.         {
  301.             if(g_ePlayerInfo[i][m_bConnected]) ClientAuthorization(i);
  302.         }
  303.         for(new i; i < Categories; i++)
  304.         {
  305.             ShowTop15(0, i);
  306.         }
  307.     }
  308. }
  309. public Query_IngnoredHandle(failstate, Handle:query, error[], errnum, data[], size)
  310. {
  311.     if(failstate != TQUERY_SUCCESS)
  312.     {
  313.         log_amx("SQL error[IngnoredHandle]: %s", error); return;
  314.     }
  315. }
  316.  
  317. public client_connected(id)
  318. {
  319.     g_ePlayerInfo[id][m_bAuthorized] = false;
  320.     g_ePlayerInfo[id][m_bTimerStarted] = false;
  321.     g_ePlayerInfo[id][m_bFinished] = false;
  322.     g_ePlayerInfo[id][m_iPlayerIndex] = 0;
  323. }
  324. public client_putinserver(id)
  325. {
  326.     if(!is_user_bot(id) && !is_user_hltv(id))
  327.     {
  328.         g_ePlayerInfo[id][m_bConnected] = true;
  329.         ClientAuthorization(id);
  330.     }
  331. }
  332. ClientAuthorization(id)
  333. {
  334.     if(!g_iMapIndex) return;
  335.    
  336.     new szAuth[32]; get_user_authid(id, szAuth, charsmax(szAuth));
  337.    
  338.     new data[1]; data[0] = id;
  339.     formatex(g_szQuery, charsmax(g_szQuery), "SELECT id, ip, nationality FROM `runners` WHERE steamid='%s'", szAuth);
  340.     SQL_ThreadQuery(g_hTuple, "Query_LoadRunnerInfoHandler", g_szQuery, data, sizeof(data));
  341. }
  342. public Query_LoadRunnerInfoHandler(failstate, Handle:query, error[], errnum, data[], size)
  343. {
  344.     if(failstate != TQUERY_SUCCESS)
  345.     {
  346.         log_amx("SQL error[LoadRunnerInfo]: %s",error); return;
  347.     }
  348.    
  349.     new id = data[0];
  350.     if(!is_user_connected(id)) return;
  351.    
  352.     new szCode[5];
  353.    
  354.     if(SQL_MoreResults(query))
  355.     {
  356.         client_authorized_db(id, SQL_ReadResult(query, 0));
  357.        
  358.         SQL_ReadResult(query, 2, szCode, 1);
  359.        
  360.         if(szCode[0] == 0)
  361.         {
  362.             new szIP[32]; get_user_ip(id, szIP, charsmax(szIP), 1);
  363.            
  364.             get_nationality(id, szIP, szCode);
  365.             formatex(g_szQuery, charsmax(g_szQuery), "UPDATE `runners` SET nationality='%s' WHERE id=%d", szCode, g_ePlayerInfo[id][m_iPlayerIndex]);
  366.             SQL_ThreadQuery(g_hTuple, "Query_IngnoredHandle", g_szQuery);
  367.         }
  368.     }
  369.     else
  370.     {
  371.         new szAuth[32]; get_user_authid(id, szAuth, charsmax(szAuth));
  372.         new szIP[32]; get_user_ip(id, szIP, charsmax(szIP), 1);
  373.         new szName[64]; get_user_name(id, szName, charsmax(szName));
  374.         SQL_PrepareString(szName, szName, 63);
  375.        
  376.         get_nationality(id, szIP, szCode);
  377.        
  378.         formatex(g_szQuery, charsmax(g_szQuery), "INSERT INTO `runners` (steamid, nickname, ip, nationality) VALUES ('%s', '%s', '%s', '%s')", szAuth, szName, szIP, szCode);
  379.         SQL_ThreadQuery(g_hTuple, "Query_InsertRunnerHandle", g_szQuery, data, size);
  380.     }
  381. }
  382. public Query_InsertRunnerHandle(failstate, Handle:query, error[], errnum, data[], size)
  383. {
  384.     if(failstate != TQUERY_SUCCESS)
  385.     {
  386.         log_amx("SQL error[InsertRunner]: %s",error); return;
  387.     }
  388.    
  389.     new id = data[0];
  390.     if(!is_user_connected(id)) return;
  391.    
  392.     client_authorized_db(id , SQL_GetInsertId(query));
  393. }
  394. client_authorized_db(id, pid)
  395. {
  396.     g_ePlayerInfo[id][m_iPlayerIndex] = pid;
  397.     g_ePlayerInfo[id][m_bAuthorized] = true;
  398.    
  399.     arrayset(g_iBestTime[id], 0, sizeof(g_iBestTime[]));
  400.  
  401.     LoadRunnerData(id);
  402. }
  403. LoadRunnerData(id)
  404. {
  405.     if(!g_ePlayerInfo[id][m_bAuthorized]) return;
  406.    
  407.     new data[1]; data[0] = id;
  408.    
  409.     formatex(g_szQuery, charsmax(g_szQuery), "SELECT * FROM `results` WHERE id=%d AND mid=%d", g_ePlayerInfo[id][m_iPlayerIndex], g_iMapIndex);
  410.     SQL_ThreadQuery(g_hTuple, "Query_LoadDataHandle", g_szQuery, data, sizeof(data));
  411. }
  412. public Query_LoadDataHandle(failstate, Handle:query, error[], errnum, data[], size)
  413. {
  414.     if(failstate != TQUERY_SUCCESS)
  415.     {
  416.         log_amx("SQL Insert error: %s",error); return;
  417.     }
  418.    
  419.     new id = data[0];
  420.     if(!is_user_connected(id)) return;
  421.    
  422.     while(SQL_MoreResults(query))
  423.     {
  424.         new category = SQL_ReadResult(query, 2);
  425.         g_iBestTime[id][category] = SQL_ReadResult(query, 3);
  426.        
  427.         SQL_NextRow(query);
  428.     }
  429. }
  430.  
  431. public client_disconnected(id)
  432. {
  433.     g_ePlayerInfo[id][m_bAuthorized] = false;
  434.     g_ePlayerInfo[id][m_bConnected] = false;
  435. }
  436.  
  437. public Think_Timer(ent)
  438. {
  439.     set_entvar(ent, var_nextthink, get_gametime() + 0.009);
  440.    
  441.     for(new id = 1; id <= 32; id++)
  442.     {
  443.         if(g_ePlayerInfo[id][m_bTimerStarted] && !g_ePlayerInfo[id][m_bFinished] && is_user_alive(id))
  444.         {      
  445.             display_time(id, get_running_time(id));
  446.         }
  447.     }
  448. }
  449.  
  450. public SR_PlayerOnStart(id)
  451. {
  452.     HC_CBasePlayer_Spawn_Post(id);
  453. }
  454. public HC_CBasePlayer_Spawn_Post(id)
  455. {
  456.     g_ePlayerInfo[id][m_bTimerStarted] = false;
  457.     hide_timer(id);
  458. }
  459.  
  460. public HC_CheckStartTimer(id)
  461. {
  462.     if(!g_iFinishEnt) return;
  463.  
  464.     if(g_ePlayerInfo[id][m_bAuthorized] && !g_ePlayerInfo[id][m_bTimerStarted])
  465.     {
  466.         StartTimer(id);
  467.     }
  468. }
  469. Create_Box(ent, Float:color[3] = {255.0,255.0,255.0})
  470. {
  471.     new Float:maxs[3]; get_entvar(ent, var_absmax, maxs);
  472.     new Float:mins[3]; get_entvar(ent, var_absmin, mins);
  473.    
  474.     new Float:fOrigin[3]; get_entvar(ent, var_origin, fOrigin);
  475.    
  476.     new Float:z;
  477.  
  478.     z = mins[2];
  479.     DrawLine(ent, maxs[0], maxs[1], z, mins[0], maxs[1], z, color);
  480.     DrawLine(ent, maxs[0], maxs[1], z, maxs[0], mins[1], z, color);
  481.     DrawLine(ent, maxs[0], mins[1], z, mins[0], mins[1], z, color);
  482.     DrawLine(ent, mins[0], mins[1], z, mins[0], maxs[1], z, color);
  483.  
  484. }
  485. DrawLine(ent, Float:x1, Float:y1, Float:z1, Float:x2, Float:y2, Float:z2, Float:color[3] = {255.0,255.0,255.0})
  486. {
  487.     new Float:start[3], Float:stop[3];
  488.     start[0] = x1;
  489.     start[1] = y1;
  490.     start[2] = z1;
  491.    
  492.     stop[0] = x2;
  493.     stop[1] = y2;
  494.     stop[2] = z2;
  495.  
  496.     new beamEnt = Beam_Create(FINISH_SPRITENAME, 10.0);
  497.  
  498.     new class[20];
  499.     pev(ent, FAKEMETA_PEV_TYPE, class, charsmax(class));
  500.     format(class, charsmax(class), "beam_%s", class);
  501.     set_pev(beamEnt, pev_classname, class);
  502.  
  503.     Beam_PointsInit(beamEnt, start, stop);
  504.     Beam_SetBrightness(beamEnt, 200.0);
  505.     Beam_SetColor(beamEnt, color);
  506.     set_pev(beamEnt, pev_owner, ent);
  507.     return beamEnt;
  508. }
  509. public box_created(box, const szClass[])
  510. {
  511.  
  512.     static Float:color_start[3] = {0.0, 255.0, 0.0}, Float:color_finish[3] = {255.0, 0.0, 0.0};
  513.     if(equal("start", szClass))
  514.     {
  515.         Create_Box(box, color_start);
  516.     }
  517.     if(equal("finish", szClass))
  518.     {
  519.         Create_Box(box, color_finish);
  520.         g_iFinishEnt = box;
  521.     }
  522. }
  523. public box_deleted(box, const szClass[])
  524. {
  525.     new a = -1;
  526.     new class[32];
  527.     format(class, charsmax(class), "beam_%s", szClass);
  528.    
  529.     while((a = find_ent_by_owner(a, class, box)))
  530.     {
  531.         remove_entity(a);
  532.     }
  533.     g_iFinishEnt = 0;
  534. }
  535. public box_resized(box, const szClass[])
  536. {
  537.     new beams[4], a = -1, count = 0;
  538.  
  539.     new class[32];
  540.     format(class, charsmax(class), "beam_%s", szClass);
  541.    
  542.     while((a = find_ent_by_owner(a, class, box)))
  543.     {
  544.         beams[count++] = a;
  545.     }
  546.  
  547.     new Float:maxs[3]; get_entvar(box, var_absmax, maxs);
  548.     new Float:mins[3]; get_entvar(box, var_absmin, mins);
  549.    
  550.     new Float:z = mins[2];
  551.  
  552.     ReDrawLine(beams[0], maxs[0], maxs[1], z, mins[0], maxs[1], z);
  553.     ReDrawLine(beams[1], maxs[0], maxs[1], z, maxs[0], mins[1], z);
  554.     ReDrawLine(beams[2], maxs[0], mins[1], z, mins[0], mins[1], z);
  555.     ReDrawLine(beams[3], mins[0], mins[1], z, mins[0], maxs[1], z);
  556.  
  557. }
  558. ReDrawLine(beamEnt, Float:x1, Float:y1, Float:z1, Float:x2, Float:y2, Float:z2)
  559. {
  560.     new Float:start[3], Float:stop[3];
  561.     start[0] = x1;
  562.     start[1] = y1;
  563.     start[2] = z1;
  564.    
  565.     stop[0] = x2;
  566.     stop[1] = y2;
  567.     stop[2] = z2;
  568.  
  569.     Beam_SetStartPos(beamEnt, start);
  570.     Beam_SetEndPos(beamEnt, stop);
  571. }
  572. public box_start_touch(box, id, const szClass[])
  573. {
  574.     if(!is_user_alive(id)) return;
  575.  
  576.     if(equal(szClass, "finish"))
  577.     {
  578.         if(g_ePlayerInfo[id][m_bTimerStarted] && !g_ePlayerInfo[id][m_bFinished])
  579.         {
  580.             Forward_PlayerFinished(id);
  581.         }
  582.     }
  583. }
  584. public box_stop_touch(box, id, const szClass[])
  585. {
  586.     if(!is_user_alive(id)) return;
  587.  
  588.     if(equal(szClass, "start"))
  589.     {
  590.         HC_CheckStartTimer(id);
  591.         StartTimer(id); // if use want to use it for deathrun remove //
  592.         // this make when you come back from square will reset your time back
  593.     }
  594. }
  595.  
  596. StartTimer(id)
  597. {
  598.     g_ePlayerInfo[id][m_bTimerStarted] = true;
  599.     g_ePlayerInfo[id][m_bFinished] = false;
  600.     g_ePlayerInfo[id][m_fStartRun] = _:get_gametime();
  601. }
  602.  
  603. Forward_PlayerFinished(id)
  604. {
  605.     g_ePlayerInfo[id][m_bFinished] = true;
  606.    
  607.     new record = false;
  608.     new iTime = get_running_time(id);
  609.     new category = get_user_category(id);
  610.     new szTime[32]; get_formated_time(iTime, szTime, charsmax(szTime));
  611.    
  612.     console_print(id, "%s Time: %s!", g_szCategory[category], szTime);
  613.    
  614.     if(g_iBestTime[id][category] == 0)
  615.     {
  616.         client_print_color(id, print_team_default, "%s%s^4 First finish.", PREFIX, g_szCategory[category]);
  617.         SaveRunnerData(id, category, iTime);
  618.     }
  619.     else if(g_iBestTime[id][category] > iTime)
  620.     {
  621.         get_formated_time(g_iBestTime[id][category] - iTime, szTime, charsmax(szTime));
  622.         client_print_color(id, print_team_default, "^4%s ^3Own record:^4 -%s!", g_szCategory[category], szTime);
  623.         SaveRunnerData(id, category, iTime);
  624.     }
  625.     else if(g_iBestTime[id][category] < iTime)
  626.     {
  627.         get_formated_time(iTime - g_iBestTime[id][category], szTime, charsmax(szTime));
  628.         client_print_color(id, print_team_default, "^4%s ^3Own record:^4 +%s!", g_szCategory[category], szTime);
  629.     }
  630.     else
  631.     {
  632.         client_print_color(id, print_team_default, "^4%s%s^1 Own record equal!", PREFIX, g_szCategory[category]);
  633.     }
  634.    
  635.     if(g_iBestTimeofMap[category] == 0 || g_iBestTimeofMap[category] > iTime)
  636.     {
  637.         g_iBestTimeofMap[category] = iTime;
  638.        
  639.         new szName[32]; get_user_name(id, szName, charsmax(szName));
  640.         get_formated_time(iTime, szTime, charsmax(szTime));
  641.        
  642.         client_print_color(0, print_team_default, "^4%s%s^3 %s^1 broke map record! Time:^3 %s", PREFIX, g_szCategory[category], szName, szTime);
  643.        
  644.         record = true;
  645.     }
  646.     if(g_iBestTimeofMap[category] != 0 && g_iBestTimeofMap[category] < iTime)
  647.     {
  648.         get_formated_time(iTime - g_iBestTimeofMap[category], szTime, charsmax(szTime));
  649.         client_print_color(id, print_team_default, "^4%s ^3Map record:^4 +%s!", g_szCategory[category], szTime);
  650.     }
  651.    
  652.     ExecuteForward(g_fwFinished, g_iReturn, id, iTime, record);
  653.    
  654.     hide_timer(id);
  655. }
  656. public SaveRunnerData(id, category, iTime)
  657. {
  658.     if(!g_ePlayerInfo[id][m_bAuthorized]) return;
  659.    
  660.     new query_type = g_iBestTime[id][category] ? 1 : 0;
  661.    
  662.     g_iBestTime[id][category] = iTime;
  663.     new szRecordTime[32]; get_time("%Y-%m-%d %H:%M:%S", szRecordTime, charsmax(szRecordTime));
  664.    
  665.     if(query_type)
  666.     {
  667.         formatex(g_szQuery, charsmax(g_szQuery), "UPDATE `results` SET besttime=%d, recorddate='%s' WHERE id=%d AND mid=%d AND category=%d",
  668.             iTime, szRecordTime, g_ePlayerInfo[id][m_iPlayerIndex], g_iMapIndex, category);
  669.     }
  670.     else
  671.     {
  672.         formatex(g_szQuery, charsmax(g_szQuery), "INSERT INTO `results` VALUES (%d, %d, %d, %d, '%s')",
  673.             g_ePlayerInfo[id][m_iPlayerIndex], g_iMapIndex, category, iTime, szRecordTime);
  674.     }
  675.    
  676.     SQL_ThreadQuery(g_hTuple, "Query_IngnoredHandle", g_szQuery);
  677. }
  678.  
  679. ShowRank(id, category)
  680. {
  681.     formatex(g_szQuery, charsmax(g_szQuery), "SELECT COUNT(*) FROM `results` WHERE mid=%d AND category=%d AND besttime > 0 AND besttime < %d",
  682.             g_iMapIndex, category, g_iBestTime[id][category]);
  683.        
  684.     new data[2]; data[0] = id; data[1] = category;
  685.     SQL_ThreadQuery(g_hTuple, "Query_LoadRankHandle", g_szQuery, data, sizeof(data));
  686. }
  687. public Query_LoadRankHandle(failstate, Handle:query, error[], errnum, data[], size)
  688. {
  689.     if(failstate != TQUERY_SUCCESS)
  690.     {
  691.         log_amx("SQL error[LoadRankHandle]: %s", error); return;
  692.     }
  693.    
  694.     new id = data[0];
  695.     new category = data[1];
  696.    
  697.     if(!is_user_connected(id) || !SQL_MoreResults(query)) return;
  698.    
  699.     new rank = SQL_ReadResult(query, 0) + 1;
  700.     client_print_color(id, print_team_default, "%s%s^1 Your rank is %d!", PREFIX, g_szCategory[category], rank);
  701. }
  702.  
  703. ShowTop15(id, category)
  704. {
  705.     formatex(g_szQuery, charsmax(g_szQuery), "SELECT nickname, besttime FROM `results` JOIN `runners` ON `runners`.id=`results`.id WHERE mid=%d AND category=%d AND besttime ORDER BY besttime ASC LIMIT 15",
  706.             g_iMapIndex, category);
  707.        
  708.     new data[2]; data[0] = id; data[1] = category;
  709.     SQL_ThreadQuery(g_hTuple, "Query_LoadTop15Handle", g_szQuery, data, sizeof(data));
  710. }
  711. public Query_LoadTop15Handle(failstate, Handle:query, error[], errnum, data[], size)
  712. {
  713.     if(failstate != TQUERY_SUCCESS)
  714.     {
  715.         log_amx("SQL error[LoadTop15]: %s",error); return;
  716.     }
  717.  
  718.     new id = data[0];
  719.     if(!is_user_connected(id) && id != 0) return;
  720.    
  721.     new category = data[1];
  722.    
  723.     new iLen = 0, iMax = charsmax(g_szMotd);
  724.     iLen = formatex(g_szMotd[iLen], iMax-iLen, "<meta charset=utf-8>");
  725.     iLen += formatex(g_szMotd[iLen], iMax-iLen, "<style>{font:normal 10px} table, th, td{border: 1px solid black;border-collapse:collapse;text-align:center;}");
  726.     iLen += formatex(g_szMotd[iLen], iMax-iLen, "</style><html><table width=100%%><thead><tr><th width=10%%>%s</th> <th width=50%%>%s</th><th width=20%%>%s</th><th width=20%%></th></tr></thead><tbody>", "Pos.", "Player", "Time");
  727.    
  728.    
  729.     new i = 1;
  730.     new iTime, szName[32], szTime[32];
  731.     while(SQL_MoreResults(query))
  732.     {
  733.         SQL_ReadResult(query, 0, szName, 31);
  734.         iTime = SQL_ReadResult(query, 1);
  735.         get_formated_time(iTime, szTime, 31);
  736.        
  737.         iLen += formatex(g_szMotd[iLen], iMax-iLen, "<tr><td>%d</td><td>%s</td>", i, szName);
  738.         if(i == 1)
  739.         {
  740.             g_iBestTimeofMap[category] = iTime;
  741.             iLen += formatex(g_szMotd[iLen], iMax-iLen, "<td>%s</td><td></td>",  szTime);
  742.             if(id == 0) return;
  743.         }
  744.         else
  745.         {
  746.             iLen += formatex(g_szMotd[iLen], iMax-iLen, "<td>%s</td>", szTime);
  747.            
  748.             get_formated_time(iTime-g_iBestTimeofMap[category] , szTime, 31);
  749.             iLen += formatex(g_szMotd[iLen], iMax-iLen, "<td>+%s</td>", szTime);
  750.         }
  751.         iLen += formatex(g_szMotd[iLen], iMax-iLen, "</tr>");
  752.        
  753.         i++;
  754.         SQL_NextRow(query);
  755.     }
  756.     iLen += formatex(g_szMotd[iLen], iMax-iLen, "</pre>");
  757.     show_motd(id, g_szMotd, "Top15");
  758. }
  759.  
  760. hide_timer(id)
  761. {
  762.     show_status(id, "");
  763. }
  764. display_time(id, iTime)
  765. {
  766.     show_status(id, "Time: %d:%02d.%03ds", iTime / 60000, (iTime / 1000) % 60, iTime % 1000);
  767. }
  768. show_status(id, const szMsg[], any:...)
  769. {
  770.     static szStatus[128]; vformat(szStatus, charsmax(szStatus), szMsg, 3);
  771.     static StatusText; if(!StatusText) StatusText = get_user_msgid("StatusText");
  772.    
  773.     message_begin(MSG_ONE_UNRELIABLE, StatusText, _, id);
  774.     write_byte(0);
  775.     write_string(szStatus);
  776.     message_end();
  777. }
  778. get_running_time(id)
  779. {
  780.     return floatround((get_gametime() - g_ePlayerInfo[id][m_fStartRun]) * 1000, floatround_ceil);
  781. }
  782. get_formated_time(iTime, szTime[], size)
  783. {
  784.     formatex(szTime, size, "%d:%02d.%03ds", iTime / 60000, (iTime / 1000) % 60, iTime % 1000);
  785. }
  786. get_nationality(id, const szIP[], szCode[5])
  787. {
  788.     new szTemp[3];
  789.     if(geoip_code2_ex(szIP, szTemp))
  790.     {
  791.         copy(szCode, 4, szTemp);
  792.     }
  793.     else
  794.     {
  795.         get_user_info(id, "lang", szCode, 2);
  796.         SQL_PrepareString(szCode, szCode, 4);
  797.     }
  798. }
  799. bool:is_flooding(id)
  800. {
  801.     static Float:fAntiFlood[33];
  802.     new bool:fl = false;
  803.     new Float:fNow = get_gametime();
  804.    
  805.     if((fNow-fAntiFlood[id]) < 1.0) fl = true;
  806.    
  807.     fAntiFlood[id] = fNow;
  808.     return fl;
  809. }
  810. stock SQL_PrepareString(const szQuery[], szOutPut[], size)
  811. {
  812.     copy(szOutPut, size, szQuery);
  813.     replace_all(szOutPut, size, "'", "\'");
  814.     replace_all(szOutPut,size, "`", "\`");
  815.     replace_all(szOutPut,size, "\\", "\\\\");
  816. }
  817.  
  818.  
  819.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement