mirror of
https://github.com/shavitush/bhoptimer.git
synced 2025-12-06 18:08:26 +00:00
Compare commits
33 Commits
ae6b12f1ae
...
d8009d9b9c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d8009d9b9c | ||
|
|
7cbb250541 | ||
|
|
a350d7982c | ||
|
|
a5bec0403b | ||
|
|
2a3907171a | ||
|
|
068dcff798 | ||
|
|
dbe8e9a99f | ||
|
|
69b13bce5a | ||
|
|
e7a0e66ec4 | ||
|
|
14c3a4a4be | ||
|
|
54ea76ecf9 | ||
|
|
d140506194 | ||
|
|
5ca5446354 | ||
|
|
71c674663f | ||
|
|
5391c32d3d | ||
|
|
828ed94857 | ||
|
|
b0359f02e3 | ||
|
|
3032818408 | ||
|
|
bd740d8504 | ||
|
|
832528bc01 | ||
|
|
8b571296c0 | ||
|
|
56c6cd35db | ||
|
|
0b597f1be1 | ||
|
|
62477e4072 | ||
|
|
799f34bfdd | ||
|
|
aab9f9c271 | ||
|
|
88e0a78b08 | ||
|
|
858c489a5e | ||
|
|
61ee8f5d4b | ||
|
|
8b54f4b1ad | ||
|
|
025324c3cb | ||
|
|
89b92d4313 | ||
|
|
139e771386 |
@ -20,6 +20,8 @@
|
||||
// {rank1} - player rank in percentage (1 decimal point)
|
||||
// {rank2} - player rank in percentage (2 decimal points)
|
||||
// {rank3} - player rank in percentage (3 decimal points)
|
||||
// {styleXrank} - player rank on style X (X replaced with style ID) ie. "{style0rank}"
|
||||
// {currentstylerank} - player rank on the style they are currently on, includes style name at the end ie. "#2 Normal"
|
||||
// {pts} - how many points a player has
|
||||
// {wrs} - how many wrs a player has
|
||||
// {wrrank} - player rank out of wrs held
|
||||
@ -106,4 +108,20 @@
|
||||
"name" "{rand}WRTOP10% {name}"
|
||||
"display" "WRTOP10%<n>Top 10% of players by WRs held."
|
||||
}
|
||||
|
||||
"11"
|
||||
{
|
||||
"free" "1"
|
||||
"name" "{rand}[{currentstylerank}] {name}"
|
||||
"message" "{default}"
|
||||
"display" "[#Rank Current Style]<n>Show your rank on your current style!"
|
||||
}
|
||||
|
||||
"12"
|
||||
{
|
||||
"free" "1"
|
||||
"name" "{rand}[{style0rank} Normal] {name}"
|
||||
"message" "{default}"
|
||||
"display" "[#Rank Normal]<n>Display your normal rank!"
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,6 +47,19 @@ forward void Shavit_OnTierAssigned(const char[] map, int tier);
|
||||
*/
|
||||
forward void Shavit_OnRankAssigned(int client, int rank, float points, bool first);
|
||||
|
||||
/**
|
||||
* Gets called when the server acknowledges the client's ranking status for a style.
|
||||
* It is called after OnClientPostAdminCheck and at forced rank recalculations.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param style Style index.
|
||||
* @param rank Client's rank. (0 if unranked or unassigned)
|
||||
* @param points Client's points. (0.0 if unranked or unassigned)
|
||||
* @param first True if the forward is called after the initial connection, false if it is caused by recalculation.
|
||||
* @noreturn
|
||||
*/
|
||||
forward void Shavit_OnStyleRankAssigned(int client, int style, int rank, float points, bool first);
|
||||
|
||||
/**
|
||||
* Gets the map tier for a specified map.
|
||||
* Use the map's display name.
|
||||
@ -72,6 +85,15 @@ native StringMap Shavit_GetMapTiers();
|
||||
*/
|
||||
native float Shavit_GetPoints(int client);
|
||||
|
||||
/**
|
||||
* Gets player points on a style.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param style Style index.
|
||||
* @return Points. 0.0 if unranked.
|
||||
*/
|
||||
native float Shavit_GetStylePoints(int client, int style);
|
||||
|
||||
/**
|
||||
* Gets player rank.
|
||||
*
|
||||
@ -80,6 +102,15 @@ native float Shavit_GetPoints(int client);
|
||||
*/
|
||||
native int Shavit_GetRank(int client);
|
||||
|
||||
/**
|
||||
* Gets player rank on a style.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param style Style index.
|
||||
* @return Rank. 0 if unranked.
|
||||
*/
|
||||
native int Shavit_GetStyleRank(int client, int style);
|
||||
|
||||
/**
|
||||
* Gets the amount of players with over 0 points.
|
||||
*
|
||||
@ -87,6 +118,14 @@ native int Shavit_GetRank(int client);
|
||||
*/
|
||||
native int Shavit_GetRankedPlayers();
|
||||
|
||||
/**
|
||||
* Gets the amount of players with over 0 points on a style.
|
||||
*
|
||||
* @param style Style index.
|
||||
* @return Amount of ranked players.
|
||||
*/
|
||||
native int Shavit_GetStyleRankedPlayers(int style);
|
||||
|
||||
/**
|
||||
* Deletes tier setting for the specified map.
|
||||
* Points recalculation will run right after this is finished.
|
||||
@ -164,8 +203,11 @@ public void __pl_shavit_rankings_SetNTVOptional()
|
||||
MarkNativeAsOptional("Shavit_GetMapTier");
|
||||
MarkNativeAsOptional("Shavit_GetMapTiers");
|
||||
MarkNativeAsOptional("Shavit_GetPoints");
|
||||
MarkNativeAsOptional("Shavit_GetStylePoints");
|
||||
MarkNativeAsOptional("Shavit_GetRank");
|
||||
MarkNativeAsOptional("Shavit_GetStyleRank");
|
||||
MarkNativeAsOptional("Shavit_GetRankedPlayers");
|
||||
MarkNativeAsOptional("Shavit_GetStyleRankedPlayers");
|
||||
MarkNativeAsOptional("Shavit_Rankings_DeleteMap");
|
||||
MarkNativeAsOptional("Shavit_GetWRCount");
|
||||
MarkNativeAsOptional("Shavit_GetWRHolders");
|
||||
|
||||
@ -55,6 +55,7 @@ enum
|
||||
Migration_FixSQLiteMapzonesROWID,
|
||||
Migration_AddUsersFirstLogin, // 30
|
||||
Migration_MoreFirstLoginStuff,
|
||||
Migration_AddStylePoints,
|
||||
MIGRATIONS_END
|
||||
};
|
||||
|
||||
@ -91,6 +92,7 @@ char gS_MigrationNames[][] = {
|
||||
"FixSQLiteMapzonesROWID",
|
||||
"AddUsersFirstLogin",
|
||||
"MoreFirstLoginStuff",
|
||||
"AddStylePoints",
|
||||
};
|
||||
|
||||
static Database gH_SQL;
|
||||
@ -182,6 +184,11 @@ public void SQL_CreateTables(Database hSQL, const char[] prefix, int driver)
|
||||
gS_SQLPrefix, sOptionalINNODB);
|
||||
AddQueryLog(trans, sQuery);
|
||||
|
||||
FormatEx(sQuery, sizeof(sQuery),
|
||||
"CREATE TABLE IF NOT EXISTS `%sstylepoints` (`auth` INT NOT NULL, `style` TINYINT NOT NULL, `points` FLOAT NOT NULL DEFAULT 0, PRIMARY KEY (`auth`, `style`));",
|
||||
gS_SQLPrefix);
|
||||
AddQueryLog(trans, sQuery);
|
||||
|
||||
//
|
||||
//// shavit-stats
|
||||
//
|
||||
@ -375,6 +382,7 @@ void ApplyMigration(int migration)
|
||||
case Migration_FixSQLiteMapzonesROWID: ApplyMigration_FixSQLiteMapzonesROWID();
|
||||
case Migration_AddUsersFirstLogin: ApplyMigration_AddUsersFirstLogin();
|
||||
case Migration_MoreFirstLoginStuff: ApplyMigration_MoreFirstLoginStuff();
|
||||
case Migration_AddStylePoints: ApplyMigration_AddStylePoints();
|
||||
}
|
||||
}
|
||||
|
||||
@ -768,6 +776,13 @@ public void ApplyMigration_MoreFirstLoginStuff()
|
||||
gH_SQL.Execute(trans, Trans_MigrationSimple, TransMigrationSimple_Error, Migration_MoreFirstLoginStuff);
|
||||
}
|
||||
|
||||
void ApplyMigration_AddStylePoints()
|
||||
{
|
||||
char sQuery[256];
|
||||
FormatEx(sQuery, sizeof(sQuery), "INSERT INTO %sstylepoints (auth, style) SELECT UNIQUE auth, style FROM %splayertimes;", gS_SQLPrefix, gS_SQLPrefix);
|
||||
QueryLog(gH_SQL, SQL_TableMigrationSingleQuery_Callback, sQuery, Migration_AddStylePoints, DBPrio_High);
|
||||
}
|
||||
|
||||
public void SQL_TableMigrationSingleQuery_Callback(Database db, DBResultSet results, const char[] error, any data)
|
||||
{
|
||||
InsertMigration(data);
|
||||
|
||||
@ -108,12 +108,16 @@ char gS_CustomName[MAXPLAYERS+1][128];
|
||||
char gS_CustomMessage[MAXPLAYERS+1][16];
|
||||
|
||||
chatstrings_t gS_ChatStrings;
|
||||
stylestrings_t gS_StyleStrings[STYLE_LIMIT];
|
||||
|
||||
// chat procesor
|
||||
bool gB_Protobuf = false;
|
||||
bool gB_NewMessage[MAXPLAYERS+1];
|
||||
StringMap gSM_Messages = null;
|
||||
|
||||
//style ranks
|
||||
int gI_Styles = 0;
|
||||
|
||||
char gS_ControlCharacters[][] = {"\x01", "\x02", "\x03", "\x04", "\x05", "\x06", "\x07", "\x08", "\x09",
|
||||
"\x0A", "\x0B", "\x0C", "\x0D", "\x0E", "\x0F", "\x10" };
|
||||
|
||||
@ -215,6 +219,19 @@ public void Shavit_OnChatConfigLoaded()
|
||||
Shavit_GetChatStringsStruct(gS_ChatStrings);
|
||||
}
|
||||
|
||||
public void Shavit_OnStyleConfigLoaded(int styles)
|
||||
{
|
||||
gI_Styles = styles;
|
||||
|
||||
for (int i = 0; i < STYLE_LIMIT; i++)
|
||||
{
|
||||
if (i < styles)
|
||||
{
|
||||
Shavit_GetStyleStringsStruct(i, gS_StyleStrings[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnMapStart()
|
||||
{
|
||||
if(!LoadChatConfig())
|
||||
@ -1319,6 +1336,31 @@ void FormatChat(int client, char[] buffer, int size)
|
||||
IntToString(iRank, temp, 32);
|
||||
ReplaceString(buffer, size, "{rank}", temp);
|
||||
|
||||
int iStyleRank;
|
||||
char sStyleRank[16];
|
||||
char sStyleBuf[32];
|
||||
for (int i = 0; i < gI_Styles; i++)
|
||||
{
|
||||
iStyleRank = Shavit_GetStyleRank(client, i);
|
||||
if(iStyleRank == 0)
|
||||
{
|
||||
strcopy(sStyleRank, 16, "Unranked");
|
||||
}
|
||||
else
|
||||
{
|
||||
IntToString(iStyleRank, sStyleRank, 16);
|
||||
Format(sStyleRank, 16, "#%s", sStyleRank);
|
||||
}
|
||||
FormatEx(sStyleBuf, 32, "{style%drank}", i);
|
||||
ReplaceString(buffer, size, sStyleBuf, sStyleRank);
|
||||
|
||||
if(i == Shavit_GetBhopStyle(client))
|
||||
{
|
||||
FormatEx(sStyleBuf, 32, "%s %s", sStyleRank, gS_StyleStrings[i].sStyleName);
|
||||
ReplaceString(buffer, size, "{currentstylerank}", sStyleBuf);
|
||||
}
|
||||
}
|
||||
|
||||
int iRanked = Shavit_GetRankedPlayers();
|
||||
|
||||
if(iRanked == 0)
|
||||
@ -1558,6 +1600,31 @@ public int Native_GetPlainChatrank(Handle handler, int numParams)
|
||||
IntToString(iRank, sRank, 16);
|
||||
ReplaceString(buf, sizeof(buf), "{rank}", sRank);
|
||||
|
||||
int iStyleRank;
|
||||
char sStyleRank[16];
|
||||
char sStyleBuf[32];
|
||||
for (int i = 0; i < gI_Styles; i++)
|
||||
{
|
||||
iStyleRank = Shavit_GetStyleRank(client, i);
|
||||
if(iStyleRank == 0)
|
||||
{
|
||||
strcopy(sStyleRank, 16, "Unranked");
|
||||
}
|
||||
else
|
||||
{
|
||||
IntToString(iStyleRank, sStyleRank, 16);
|
||||
Format(sStyleRank, 16, "#%s", sStyleRank);
|
||||
}
|
||||
FormatEx(sStyleBuf, 32, "{style%drank}", i);
|
||||
ReplaceString(buf, sizeof(buf), sStyleBuf, sStyleRank);
|
||||
|
||||
if(i == Shavit_GetBhopStyle(client))
|
||||
{
|
||||
FormatEx(sStyleBuf, 32, "%s %s", sStyleRank, gS_StyleStrings[i].sStyleName);
|
||||
ReplaceString(buf, sizeof(buf), "{currentstylerank}", sStyleBuf);
|
||||
}
|
||||
}
|
||||
|
||||
int iRanked = Shavit_GetRankedPlayers();
|
||||
|
||||
if (iRanked == 0)
|
||||
|
||||
@ -2301,7 +2301,7 @@ public int Native_SetPracticeMode(Handle handler, int numParams)
|
||||
bool practice = view_as<bool>(GetNativeCell(2));
|
||||
bool alert = view_as<bool>(GetNativeCell(3));
|
||||
|
||||
if(alert && practice && !gA_Timers[client].bPracticeMode && (!gB_HUD || (Shavit_GetHUDSettings(client) & HUD_NOPRACALERT) == 0))
|
||||
if(alert && practice && !gA_Timers[client].bPracticeMode && (!gB_HUD || (Shavit_GetHUDSettings(client) & HUD_NOPRACALERT) == 0) && !Shavit_InsideZone(client, Zone_Start, -1))
|
||||
{
|
||||
Shavit_PrintToChat(client, "%T", "PracticeModeAlert", client, gS_ChatStrings.sWarning, gS_ChatStrings.sText);
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
/*
|
||||
* shavit's Timer - Rankings
|
||||
* by: shavit, rtldg
|
||||
* by: shavit, rtldg, olivia
|
||||
*
|
||||
* This file is part of shavit's Timer (https://github.com/shavitush/bhoptimer)
|
||||
*
|
||||
@ -59,7 +59,9 @@
|
||||
enum struct ranking_t
|
||||
{
|
||||
int iRank;
|
||||
int iStyleRank[STYLE_LIMIT];
|
||||
float fPoints;
|
||||
float fStylePoints[STYLE_LIMIT];
|
||||
int iWRAmountAll;
|
||||
int iWRAmountCvar;
|
||||
int iWRHolderRankAll;
|
||||
@ -68,6 +70,35 @@ enum struct ranking_t
|
||||
int iWRHolderRank[STYLE_LIMIT*2];
|
||||
}
|
||||
|
||||
enum struct stylerankcache_t
|
||||
{
|
||||
int iMenuPosition;
|
||||
int iStyle;
|
||||
int iTarget;
|
||||
}
|
||||
|
||||
enum struct styletop_t
|
||||
{
|
||||
ArrayList sName;
|
||||
int iSteamID[100];
|
||||
float fPoints[100];
|
||||
|
||||
void Init()
|
||||
{
|
||||
if(this.sName != null)
|
||||
{
|
||||
delete this.sName;
|
||||
}
|
||||
|
||||
this.sName = new ArrayList(ByteCountToCells(33), 100);
|
||||
|
||||
for(int x = 0; x < this.sName.Length; x++)
|
||||
{
|
||||
this.sName.SetString(x, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char gS_MySQLPrefix[32];
|
||||
Database gH_SQL = null;
|
||||
bool gB_SQLWindowFunctions = false;
|
||||
@ -99,15 +130,23 @@ Convar gCV_DefaultTier = null;
|
||||
ranking_t gA_Rankings[MAXPLAYERS+1];
|
||||
|
||||
int gI_RankedPlayers = 0;
|
||||
int gI_StyleRankedPlayers[STYLE_LIMIT] = {0, ...};
|
||||
|
||||
Menu gH_Top100Menu = null;
|
||||
styletop_t gA_StyleTop[STYLE_LIMIT];
|
||||
|
||||
Handle gH_Forwards_OnTierAssigned = null;
|
||||
Handle gH_Forwards_OnRankAssigned = null;
|
||||
Handle gH_Forwards_OnStyleRankAssigned = null;
|
||||
|
||||
// Timer settings.
|
||||
chatstrings_t gS_ChatStrings;
|
||||
stylestrings_t gS_StyleStrings[STYLE_LIMIT];
|
||||
int gI_Styles = 0;
|
||||
|
||||
// Cache
|
||||
stylerankcache_t gA_StyleRankCache[MAXPLAYERS+1];
|
||||
|
||||
bool gB_WorldRecordsCached = false;
|
||||
bool gB_WRHolderTablesMade = false;
|
||||
bool gB_WRHoldersRefreshed = false;
|
||||
@ -119,7 +158,7 @@ int gI_WRHoldersCvar;
|
||||
public Plugin myinfo =
|
||||
{
|
||||
name = "[shavit] Rankings",
|
||||
author = "shavit, rtldg",
|
||||
author = "shavit, rtldg, olivia",
|
||||
description = "A fair and competitive ranking system for shavit's bhoptimer.",
|
||||
version = SHAVIT_VERSION,
|
||||
url = "https://github.com/shavitush/bhoptimer"
|
||||
@ -130,8 +169,11 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
|
||||
CreateNative("Shavit_GetMapTier", Native_GetMapTier);
|
||||
CreateNative("Shavit_GetMapTiers", Native_GetMapTiers);
|
||||
CreateNative("Shavit_GetPoints", Native_GetPoints);
|
||||
CreateNative("Shavit_GetStylePoints", Native_GetStylePoints);
|
||||
CreateNative("Shavit_GetRank", Native_GetRank);
|
||||
CreateNative("Shavit_GetStyleRank", Native_GetStyleRank);
|
||||
CreateNative("Shavit_GetRankedPlayers", Native_GetRankedPlayers);
|
||||
CreateNative("Shavit_GetStyleRankedPlayers", Native_GetStyleRankedPlayers);
|
||||
CreateNative("Shavit_Rankings_DeleteMap", Native_Rankings_DeleteMap);
|
||||
CreateNative("Shavit_GetWRCount", Native_GetWRCount);
|
||||
CreateNative("Shavit_GetWRHolders", Native_GetWRHolders);
|
||||
@ -147,16 +189,24 @@ public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max
|
||||
|
||||
public void OnPluginStart()
|
||||
{
|
||||
for (int i = 0; i < sizeof(gA_StyleTop); i++)
|
||||
{
|
||||
gA_StyleTop[i].Init();
|
||||
}
|
||||
|
||||
gEV_Type = GetEngineVersion();
|
||||
|
||||
gH_Forwards_OnTierAssigned = CreateGlobalForward("Shavit_OnTierAssigned", ET_Event, Param_String, Param_Cell);
|
||||
gH_Forwards_OnRankAssigned = CreateGlobalForward("Shavit_OnRankAssigned", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
|
||||
gH_Forwards_OnStyleRankAssigned = CreateGlobalForward("Shavit_OnStyleRankAssigned", ET_Event, Param_Cell, Param_Cell, Param_Cell, Param_Cell, Param_Cell);
|
||||
|
||||
RegConsoleCmd("sm_tier", Command_Tier, "Prints the map's tier to chat.");
|
||||
RegConsoleCmd("sm_maptier", Command_Tier, "Prints the map's tier to chat. (sm_tier alias)");
|
||||
|
||||
RegConsoleCmd("sm_rank", Command_Rank, "Show your or someone else's rank. Usage: sm_rank [name]");
|
||||
RegConsoleCmd("sm_top", Command_Top, "Show the top 100 players.");
|
||||
RegConsoleCmd("sm_stylerank", Command_Rank, "Show your or someone else's rank on a style. Usage: sm_stylerank [name]");
|
||||
RegConsoleCmd("sm_styletop", Command_Top, "Show the top 100 players for a style.");
|
||||
|
||||
RegAdminCmd("sm_settier", Command_SetTier, ADMFLAG_RCON, "Change the map's tier. Usage: sm_settier <tier> [map]");
|
||||
RegAdminCmd("sm_setmaptier", Command_SetTier, ADMFLAG_RCON, "Change the map's tier. Usage: sm_setmaptier <tier> [map] (sm_settier alias)");
|
||||
@ -204,6 +254,14 @@ public void Shavit_OnChatConfigLoaded()
|
||||
public void Shavit_OnStyleConfigLoaded(int styles)
|
||||
{
|
||||
gI_Styles = styles;
|
||||
|
||||
for (int i = 0; i < STYLE_LIMIT; i++)
|
||||
{
|
||||
if (i < styles)
|
||||
{
|
||||
Shavit_GetStyleStringsStruct(i, gS_StyleStrings[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void OnLibraryAdded(const char[] name)
|
||||
@ -288,6 +346,31 @@ void CreateGetWeightedPointsFunction()
|
||||
"RETURN total; " ...
|
||||
"END;;", gS_MySQLPrefix, sWeightingLimit, gCV_WeightingMultiplier.FloatValue);
|
||||
|
||||
AddQueryLog(trans, sQuery);
|
||||
|
||||
FormatEx(sQuery, sizeof(sQuery),
|
||||
"CREATE FUNCTION GetStyleWeightedPoints(steamid INT, istyle INT) " ...
|
||||
"RETURNS FLOAT " ...
|
||||
"READS SQL DATA " ...
|
||||
"BEGIN " ...
|
||||
"DECLARE p FLOAT; " ...
|
||||
"DECLARE total FLOAT DEFAULT 0.0; " ...
|
||||
"DECLARE mult FLOAT DEFAULT 1.0; " ...
|
||||
"DECLARE done INT DEFAULT 0; " ...
|
||||
"DECLARE cur CURSOR FOR SELECT points FROM %splayertimes WHERE auth = steamid AND style = istyle AND points > 0.0 ORDER BY points DESC %s; " ...
|
||||
"DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1; " ...
|
||||
"OPEN cur; " ...
|
||||
"iter: LOOP " ...
|
||||
"FETCH cur INTO p; " ...
|
||||
"IF done THEN " ...
|
||||
"LEAVE iter; " ...
|
||||
"END IF; " ...
|
||||
"SET total = total + (p * mult); " ...
|
||||
"SET mult = mult * %f; " ...
|
||||
"END LOOP; " ...
|
||||
"CLOSE cur; " ...
|
||||
"RETURN total; " ...
|
||||
"END;;", gS_MySQLPrefix, sWeightingLimit, gCV_WeightingMultiplier.FloatValue);
|
||||
|
||||
AddQueryLog(trans, sQuery);
|
||||
|
||||
@ -310,12 +393,42 @@ public void OnClientConnected(int client)
|
||||
{
|
||||
ranking_t empty_ranking;
|
||||
gA_Rankings[client] = empty_ranking;
|
||||
|
||||
stylerankcache_t empty_cache;
|
||||
gA_StyleRankCache[client] = empty_cache;
|
||||
}
|
||||
|
||||
public void OnClientAuthorized(int client, const char[] auth)
|
||||
{
|
||||
if (gH_SQL && !IsFakeClient(client))
|
||||
{
|
||||
int iSteamID = GetSteamAccountID(client);
|
||||
|
||||
if(iSteamID == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char sQuery[512];
|
||||
|
||||
for (int i = 0; i < gI_Styles; i++)
|
||||
{
|
||||
if (gI_Driver == Driver_mysql)
|
||||
{
|
||||
FormatEx(sQuery, 512,
|
||||
"INSERT IGNORE INTO %sstylepoints (auth, style, points) VALUES (%d, %d, 0);",
|
||||
gS_MySQLPrefix, iSteamID, i);
|
||||
}
|
||||
else // postgresql & sqlite
|
||||
{
|
||||
FormatEx(sQuery, 512,
|
||||
"INSERT INTO %sstylepoints (auth, style, points) VALUES (%d, %d, 0) ON CONFLICT DO NOTHING;",
|
||||
gS_MySQLPrefix, iSteamID, i);
|
||||
}
|
||||
|
||||
QueryLog(gH_SQL, SQL_InsertUser_Callback, sQuery, GetClientSerial(client));
|
||||
}
|
||||
|
||||
if (gB_WRHolderTablesMade)
|
||||
{
|
||||
UpdateWRs(client);
|
||||
@ -325,6 +438,25 @@ public void OnClientAuthorized(int client, const char[] auth)
|
||||
}
|
||||
}
|
||||
|
||||
public void SQL_InsertUser_Callback(Database db, DBResultSet results, const char[] error, any data)
|
||||
{
|
||||
if(results == null)
|
||||
{
|
||||
int client = GetClientFromSerial(data);
|
||||
|
||||
if(client == 0)
|
||||
{
|
||||
LogError("Timer error! (rankings) Failed to insert a disconnected player's data to the table. Reason: %s", error);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogError("Timer error! (rankings) Failed to insert \"%N\"'s data to the table. Reason: %s", client, error);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public void OnMapStart()
|
||||
{
|
||||
GetLowercaseMapName(gS_Map);
|
||||
@ -569,45 +701,224 @@ public Action Command_Rank(int client, int args)
|
||||
{
|
||||
int target = client;
|
||||
|
||||
if(args > 0)
|
||||
if (args > 0)
|
||||
{
|
||||
char sArgs[MAX_TARGET_LENGTH];
|
||||
GetCmdArgString(sArgs, MAX_TARGET_LENGTH);
|
||||
|
||||
target = FindTarget(client, sArgs, true, false);
|
||||
|
||||
if(target == -1)
|
||||
if (target == -1)
|
||||
{
|
||||
return Plugin_Handled;
|
||||
}
|
||||
}
|
||||
|
||||
if(gA_Rankings[target].fPoints == 0.0)
|
||||
if(IsValidClient(client))
|
||||
{
|
||||
Shavit_PrintToChat(client, "%T", "Unranked", client, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText);
|
||||
|
||||
return Plugin_Handled;
|
||||
gA_StyleRankCache[client].iTarget = target;
|
||||
OpenRankMenu(client, 0);
|
||||
}
|
||||
|
||||
Shavit_PrintToChat(client, "%T", "Rank", client, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText,
|
||||
gS_ChatStrings.sVariable, (gA_Rankings[target].iRank > gI_RankedPlayers)? gI_RankedPlayers:gA_Rankings[target].iRank, gS_ChatStrings.sText,
|
||||
gI_RankedPlayers,
|
||||
gS_ChatStrings.sVariable, gA_Rankings[target].fPoints, gS_ChatStrings.sText);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
void OpenRankMenu(int client, int position = 0)
|
||||
{
|
||||
if(!IsValidClient(gA_StyleRankCache[client].iTarget))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Menu menu = new Menu(MenuHandler_Rank);
|
||||
|
||||
char sDisplay[32];
|
||||
GetClientName(gA_StyleRankCache[client].iTarget, sDisplay, sizeof(sDisplay));
|
||||
|
||||
SetMenuTitle(menu, "%T\n ", "StyleRankTitle", client, sDisplay);
|
||||
|
||||
FormatEx(sDisplay, 32, "%T\n ", "Overall", client);
|
||||
menu.AddItem("-1", sDisplay);
|
||||
|
||||
int[] iOrderedStyles = new int[gI_Styles];
|
||||
Shavit_GetOrderedStyles(iOrderedStyles, gI_Styles);
|
||||
|
||||
for(int i = 0; i < gI_Styles; i++)
|
||||
{
|
||||
int iStyle = iOrderedStyles[i];
|
||||
|
||||
if(Shavit_GetStyleSettingInt(iStyle, "enabled") == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
char sStyle[8];
|
||||
IntToString(iStyle, sStyle, sizeof(sStyle));
|
||||
menu.AddItem(sStyle, gS_StyleStrings[iStyle].sStyleName);
|
||||
}
|
||||
|
||||
menu.ExitButton = true;
|
||||
DisplayMenuAtItem(menu, client, position, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public void MenuHandler_Rank(Menu menu, MenuAction action, int param1, int param2)
|
||||
{
|
||||
if(action == MenuAction_Select)
|
||||
{
|
||||
if(!IsValidClient(gA_StyleRankCache[param1].iTarget))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
char sStyle[8];
|
||||
menu.GetItem(param2, sStyle, sizeof(sStyle));
|
||||
int iStyle = StringToInt(sStyle);
|
||||
int target = gA_StyleRankCache[param1].iTarget;
|
||||
|
||||
if (iStyle < 0 || iStyle >= gI_Styles)
|
||||
{
|
||||
iStyle = -1;
|
||||
}
|
||||
|
||||
if (gA_Rankings[target].fPoints == 0.0)
|
||||
{
|
||||
Shavit_PrintToChat(param1, "%T", "Unranked", param1, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText);
|
||||
}
|
||||
else if (iStyle > -1 && gA_Rankings[target].fStylePoints[iStyle] == 0.0)
|
||||
{
|
||||
Shavit_PrintToChat(param1, "%T", "UnrankedOnStyle", param1, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText, gS_ChatStrings.sStyle, gS_StyleStrings[iStyle].sStyleName, gS_ChatStrings.sText);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (iStyle == -1)
|
||||
{
|
||||
Shavit_PrintToChat(param1, "%T", "Rank", param1, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText,
|
||||
gS_ChatStrings.sVariable, (gA_Rankings[target].iRank > gI_RankedPlayers)? gI_RankedPlayers:gA_Rankings[target].iRank, gS_ChatStrings.sText,
|
||||
gI_RankedPlayers,
|
||||
gS_ChatStrings.sVariable, gA_Rankings[target].fPoints, gS_ChatStrings.sText);
|
||||
}
|
||||
else
|
||||
{
|
||||
Shavit_PrintToChat(param1, "%T", "StyleRank", param1, gS_ChatStrings.sVariable2, target, gS_ChatStrings.sText,
|
||||
gS_ChatStrings.sVariable, (gA_Rankings[target].iStyleRank[iStyle] > gI_StyleRankedPlayers[iStyle])? gI_StyleRankedPlayers[iStyle]:gA_Rankings[target].iStyleRank[iStyle], gS_ChatStrings.sText,
|
||||
gI_StyleRankedPlayers[iStyle],
|
||||
gS_ChatStrings.sVariable, gA_Rankings[target].fStylePoints[iStyle], gS_ChatStrings.sText,
|
||||
gS_ChatStrings.sStyle, gS_StyleStrings[iStyle].sStyleName, gS_ChatStrings.sText);
|
||||
}
|
||||
}
|
||||
|
||||
OpenRankMenu(param1, GetMenuSelectionPosition());
|
||||
}
|
||||
else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
public Action Command_Top(int client, int args)
|
||||
{
|
||||
if(gH_Top100Menu != null)
|
||||
if(IsValidClient(client))
|
||||
{
|
||||
gH_Top100Menu.SetTitle("%T (%d)\n ", "Top100", client, gI_RankedPlayers);
|
||||
gH_Top100Menu.Display(client, MENU_TIME_FOREVER);
|
||||
OpenTopMainMenu(client, 0);
|
||||
}
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
|
||||
void OpenTopMainMenu(int client, int position = 0)
|
||||
{
|
||||
Menu menu = new Menu(MenuHandler_TopMain);
|
||||
|
||||
char sDisplay[32];
|
||||
|
||||
SetMenuTitle(menu, "%T\n ", "StyleTopTitle", client);
|
||||
|
||||
FormatEx(sDisplay, 32, "%T\n ", "Overall", client);
|
||||
menu.AddItem("-1", sDisplay);
|
||||
|
||||
int[] iOrderedStyles = new int[gI_Styles];
|
||||
Shavit_GetOrderedStyles(iOrderedStyles, gI_Styles);
|
||||
|
||||
for(int i = 0; i < gI_Styles; i++)
|
||||
{
|
||||
int iStyle = iOrderedStyles[i];
|
||||
|
||||
if(Shavit_GetStyleSettingInt(iStyle, "enabled") == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
char sStyle[8];
|
||||
IntToString(iStyle, sStyle, sizeof(sStyle));
|
||||
menu.AddItem(sStyle, gS_StyleStrings[iStyle].sStyleName);
|
||||
}
|
||||
|
||||
menu.ExitButton = true;
|
||||
DisplayMenuAtItem(menu, client, position, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public void MenuHandler_TopMain(Menu menu, MenuAction action, int param1, int param2)
|
||||
{
|
||||
if(action == MenuAction_Select)
|
||||
{
|
||||
gA_StyleRankCache[param1].iMenuPosition = GetMenuSelectionPosition();
|
||||
char sStyle[8];
|
||||
menu.GetItem(param2, sStyle, sizeof(sStyle));
|
||||
int iStyle = StringToInt(sStyle);
|
||||
|
||||
if (iStyle < 0 || iStyle >= gI_Styles)
|
||||
{
|
||||
iStyle = -1;
|
||||
}
|
||||
|
||||
if(iStyle == -1)
|
||||
{
|
||||
if(gH_Top100Menu != null)
|
||||
{
|
||||
gH_Top100Menu.SetTitle("%T (%d)\n ", "Top100", param1, gI_RankedPlayers);
|
||||
gH_Top100Menu.Display(param1, MENU_TIME_FOREVER);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
gA_StyleRankCache[param1].iStyle = iStyle;
|
||||
OpenStyleTopMenu(param1);
|
||||
}
|
||||
}
|
||||
else if (action == MenuAction_End)
|
||||
delete menu;
|
||||
}
|
||||
|
||||
void OpenStyleTopMenu(int client)
|
||||
{
|
||||
int iStyle = gA_StyleRankCache[client].iStyle;
|
||||
char sDisplay[96];
|
||||
|
||||
Menu menu = new Menu(MenuHandler_Top);
|
||||
|
||||
menu.SetTitle("%T (%d)\n ", "StyleTop100", client, gS_StyleStrings[iStyle].sStyleName, gI_StyleRankedPlayers[iStyle]);
|
||||
|
||||
if (gI_StyleRankedPlayers[iStyle] == 0)
|
||||
{
|
||||
FormatEx(sDisplay, 64, "%T", "NoRankedPlayers", client);
|
||||
menu.AddItem("-1", sDisplay, ITEMDRAW_DISABLED);
|
||||
}
|
||||
else
|
||||
{
|
||||
char sName[33];
|
||||
char sSteamID[33];
|
||||
for (int i = 0; i < (gI_StyleRankedPlayers[iStyle] < 100 ? gI_StyleRankedPlayers[iStyle] : 100); i++)
|
||||
{
|
||||
gA_StyleTop[iStyle].sName.GetString(i, sName, sizeof(sName));
|
||||
IntToString(gA_StyleTop[iStyle].iSteamID[i], sSteamID, sizeof(sSteamID));
|
||||
FormatEx(sDisplay, 96, "#%d - %s (%.2f)", i+1, sName, gA_StyleTop[iStyle].fPoints[i]);
|
||||
menu.AddItem(sSteamID, sDisplay);
|
||||
}
|
||||
}
|
||||
|
||||
menu.ExitBackButton = true;
|
||||
menu.ExitButton = true;
|
||||
DisplayMenu(menu, client, MENU_TIME_FOREVER);
|
||||
}
|
||||
|
||||
public int MenuHandler_Top(Menu menu, MenuAction action, int param1, int param2)
|
||||
{
|
||||
if(action == MenuAction_Select)
|
||||
@ -620,6 +931,11 @@ public int MenuHandler_Top(Menu menu, MenuAction action, int param1, int param2)
|
||||
FakeClientCommand(param1, "sm_profile [U:1:%s]", sInfo);
|
||||
}
|
||||
}
|
||||
else if(action == MenuAction_Cancel)
|
||||
{
|
||||
if(param2 == MenuCancel_ExitBack)
|
||||
OpenTopMainMenu(param1, gA_StyleRankCache[param1].iMenuPosition);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -631,9 +947,11 @@ public Action Command_SetTier(int client, int args)
|
||||
|
||||
int tier = StringToInt(sArg);
|
||||
|
||||
if(args == 0 || tier < 1 || tier > 10)
|
||||
int maxtier = GetMaxTier();
|
||||
|
||||
if(args == 0 || tier < 1 || tier > maxtier)
|
||||
{
|
||||
ReplyToCommand(client, "%T", "ArgumentsMissing", client, "sm_settier <tier> (1-10) [map]");
|
||||
ReplyToCommand(client, "%T", "ArgumentsMissing", client, "sm_settier <tier> (1-%d) [map]", maxtier);
|
||||
|
||||
return Plugin_Handled;
|
||||
}
|
||||
@ -875,6 +1193,8 @@ public Action Command_RecalcAll(int client, int args)
|
||||
AddQueryLog(trans, sQuery);
|
||||
FormatEx(sQuery, sizeof(sQuery), "UPDATE %susers SET points = 0;", gS_MySQLPrefix);
|
||||
AddQueryLog(trans, sQuery);
|
||||
FormatEx(sQuery, sizeof(sQuery), "UPDATE %sstylepoints SET points = 0;", gS_MySQLPrefix);
|
||||
AddQueryLog(trans, sQuery);
|
||||
|
||||
for(int i = 0; i < gI_Styles; i++)
|
||||
{
|
||||
@ -901,7 +1221,7 @@ public void Trans_OnRecalcSuccess(Database db, any data, int numQueries, DBResul
|
||||
SetCmdReplySource(SM_REPLY_TO_CONSOLE);
|
||||
}
|
||||
|
||||
ReplyToCommand(client, "- Finished recalculating all points. Recalculating user points, top 100 and user cache.");
|
||||
ReplyToCommand(client, "- Finished recalculating all points. Recalculating user points, top 100 and user cache for all styles.");
|
||||
|
||||
UpdateAllPoints(true);
|
||||
}
|
||||
@ -1013,13 +1333,19 @@ void UpdatePointsForSinglePlayer(int client)
|
||||
{
|
||||
int auth = GetSteamAccountID(client);
|
||||
|
||||
char sQuery[1024];
|
||||
char sQuery[1024], sStyleQuery[1024];
|
||||
|
||||
if (gCV_WeightingMultiplier.FloatValue == 1.0 || gB_SqliteHatesPOW)
|
||||
{
|
||||
FormatEx(sQuery, sizeof(sQuery),
|
||||
"UPDATE %susers SET points = (SELECT SUM(points) FROM %splayertimes WHERE auth = %d) WHERE auth = %d;",
|
||||
gS_MySQLPrefix, gS_MySQLPrefix, auth, auth);
|
||||
|
||||
FormatEx(sStyleQuery, sizeof(sStyleQuery),
|
||||
"UPDATE IGNORE %sstylepoints AS S INNER JOIN (SELECT auth, style, SUM(points) AS total FROM %splayertimes WHERE auth = %d GROUP BY style) P ON S.auth = P.auth SET S.points = P.total WHERE S.style = P.style;",
|
||||
gS_MySQLPrefix, gS_MySQLPrefix, auth);
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery);
|
||||
}
|
||||
else if (gB_SQLWindowFunctions)
|
||||
{
|
||||
@ -1043,12 +1369,40 @@ void UpdatePointsForSinglePlayer(int client)
|
||||
sLimit,
|
||||
auth
|
||||
);
|
||||
|
||||
FormatEx(sStyleQuery, sizeof(sStyleQuery),
|
||||
"UPDATE IGNORE %sstylepoints AS S SET points = (\n"
|
||||
... " SELECT SUM(points2) FROM (\n"
|
||||
... " SELECT style, (points * POW(%f, ROW_NUMBER() OVER (ORDER BY points DESC) - 1)) as points2\n"
|
||||
... " FROM %splayertimes\n"
|
||||
... " WHERE auth = %d AND points > 0 GROUP BY style\n"
|
||||
... " ORDER BY points DESC %s\n"
|
||||
... " ) as t\n"
|
||||
... ") P WHERE auth = %d AND S.style = t.style;",
|
||||
gS_MySQLPrefix,
|
||||
gCV_WeightingMultiplier.FloatValue,
|
||||
gS_MySQLPrefix,
|
||||
auth,
|
||||
sLimit,
|
||||
auth
|
||||
);
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery);
|
||||
}
|
||||
else // We should only be here if mysql :)
|
||||
{
|
||||
FormatEx(sQuery, sizeof(sQuery),
|
||||
"UPDATE %susers SET points = GetWeightedPoints(auth) WHERE auth = %d;",
|
||||
gS_MySQLPrefix, auth);
|
||||
|
||||
for (int i = 0; i < gI_Styles; i++)
|
||||
{
|
||||
FormatEx(sStyleQuery, sizeof(sStyleQuery),
|
||||
"UPDATE IGNORE %sstylepoints SET points = GetStyleWeightedPoints(auth, %d) WHERE auth = %d and style = %d;",
|
||||
gS_MySQLPrefix, i, auth, i);
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery);
|
||||
}
|
||||
}
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdateAllPoints_Callback, sQuery, GetClientSerial(client));
|
||||
@ -1060,7 +1414,7 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1)
|
||||
LogError("DEBUG: 6 (UpdateAllPoints)");
|
||||
#endif
|
||||
|
||||
char sQuery[1024];
|
||||
char sQuery[1024], sStyleQuery[1024];
|
||||
char sLastLogin[69], sLimit[30], sMapWhere[512], sTrackWhere[64];
|
||||
|
||||
if (track != -1)
|
||||
@ -1084,6 +1438,13 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1)
|
||||
"UPDATE %susers AS U SET points = P.total FROM (SELECT auth, SUM(points) AS total FROM %splayertimes GROUP BY auth) P WHERE U.auth = P.auth %s %s;",
|
||||
gS_MySQLPrefix, gS_MySQLPrefix,
|
||||
(sLastLogin[0] != 0) ? "AND " : "", sLastLogin);
|
||||
|
||||
FormatEx(sStyleQuery, sizeof(sStyleQuery),
|
||||
"UPDATE IGNORE %sstylepoints AS S SET points = P.total FROM (SELECT auth, style, SUM(points) AS total FROM %splayertimes GROUP BY auth, style) P WHERE S.auth = P.auth AND S.style = P.style %s %s;",
|
||||
gS_MySQLPrefix, gS_MySQLPrefix,
|
||||
(sLastLogin[0] != 0) ? "AND " : "", sLastLogin);
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1091,6 +1452,13 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1)
|
||||
"UPDATE %susers AS U INNER JOIN (SELECT auth, SUM(points) AS total FROM %splayertimes GROUP BY auth) P ON U.auth = P.auth SET U.points = P.total %s %s;",
|
||||
gS_MySQLPrefix, gS_MySQLPrefix,
|
||||
(sLastLogin[0] != 0) ? "WHERE" : "", sLastLogin);
|
||||
|
||||
FormatEx(sStyleQuery, sizeof(sStyleQuery),
|
||||
"UPDATE IGNORE %sstylepoints AS S INNER JOIN (SELECT auth, style, SUM(points) AS total FROM %splayertimes GROUP BY auth, style) P ON S.auth = P.auth SET S.points = P.total WHERE S.style = P.style %s %s;",
|
||||
gS_MySQLPrefix, gS_MySQLPrefix,
|
||||
(sLastLogin[0] != 0) ? "WHERE" : "", sLastLogin);
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery);
|
||||
}
|
||||
}
|
||||
else if (gB_SQLWindowFunctions && gI_Driver == Driver_mysql)
|
||||
@ -1124,6 +1492,34 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1)
|
||||
(sMapWhere[0] && sTrackWhere[0]) ? "AND" : "",
|
||||
sTrackWhere,
|
||||
sLimit); // TODO: Remove/move sLimit?
|
||||
|
||||
FormatEx(sStyleQuery, sizeof(sStyleQuery),
|
||||
"UPDATE IGNORE %sstylepoints AS s, (\n"
|
||||
... " SELECT auth, SUM(t.points2) as pp FROM (\n"
|
||||
... " SELECT p.auth, (p.points * POW(%f, ROW_NUMBER() OVER (PARTITION BY p.auth ORDER BY p.points DESC) - 1)) as points2\n"
|
||||
... " FROM %splayertimes AS p\n"
|
||||
... " JOIN %sstylepoints AS s2\n"
|
||||
... " ON s2.auth = p.auth %s %s\n"
|
||||
... " WHERE p.points > 0 AND p.auth IN (SELECT DISTINCT auth FROM %splayertimes %s %s %s %s)\n"
|
||||
... " ORDER BY p.points DESC GROUP BY style %s\n"
|
||||
... " ) AS t\n"
|
||||
... " GROUP by auth, style\n"
|
||||
... ") AS a\n"
|
||||
... "SET s.points = a.pp\n"
|
||||
... "WHERE s.auth = a.auth and s.style = a.style;",
|
||||
gS_MySQLPrefix,
|
||||
gCV_WeightingMultiplier.FloatValue,
|
||||
gS_MySQLPrefix,
|
||||
gS_MySQLPrefix,
|
||||
sLastLogin[0] ? "AND" : "", sLastLogin,
|
||||
gS_MySQLPrefix,
|
||||
sMapWhere[0] ? "AND" : "",
|
||||
sMapWhere,
|
||||
sTrackWhere[0] ? "AND" : "",
|
||||
sTrackWhere,
|
||||
sLimit); // TODO: Remove/move sLimit?
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery);
|
||||
}
|
||||
else if (gB_SQLWindowFunctions)
|
||||
{
|
||||
@ -1148,6 +1544,30 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1)
|
||||
sMapWhere,
|
||||
(sMapWhere[0] && sTrackWhere[0]) ? "AND" : "",
|
||||
sTrackWhere);
|
||||
|
||||
FormatEx(sStyleQuery, sizeof(sStyleQuery),
|
||||
"UPDATE IGNORE %sstylepoints AS s\n"
|
||||
... "SET points = (\n"
|
||||
... " SELECT SUM(points2) FROM (\n"
|
||||
... " SELECT (points * POW(%f, ROW_NUMBER() OVER (ORDER BY points DESC) - 1)) AS points2\n"
|
||||
... " FROM %splayertimes\n"
|
||||
... " WHERE auth = s.auth AND points > 0\n"
|
||||
... " ORDER BY points DESC GROUP BY style %s\n"
|
||||
... " ) AS t\n"
|
||||
... ") p WHERE %s %s auth IN\n"
|
||||
... " (SELECT DISTINCT auth FROM %splayertimes WHERE style = t.style %s %s %s %s);",
|
||||
gS_MySQLPrefix,
|
||||
gCV_WeightingMultiplier.FloatValue,
|
||||
gS_MySQLPrefix,
|
||||
sLimit, // TODO: Remove/move sLimit?
|
||||
sLastLogin, sLastLogin[0] ? "AND" : "",
|
||||
gS_MySQLPrefix,
|
||||
sMapWhere[0] ? "AND" : "",
|
||||
sMapWhere,
|
||||
sTrackWhere[0] ? "AND" : "",
|
||||
sTrackWhere);
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery);
|
||||
}
|
||||
else // !gB_SQLWindowFunctions && gI_Driver == Driver_mysql
|
||||
{
|
||||
@ -1160,6 +1580,21 @@ void UpdateAllPoints(bool recalcall=false, char[] map="", int track=-1)
|
||||
sMapWhere,
|
||||
(sMapWhere[0] && sTrackWhere[0]) ? "AND" : "",
|
||||
sTrackWhere);
|
||||
|
||||
for (int i = 0; i < gI_Styles; i++)
|
||||
{
|
||||
FormatEx(sQuery, sizeof(sQuery),
|
||||
"UPDATE IGNORE %sstylepoints SET points = GetWeightedStylePoints(auth, %d) WHERE %s %s auth IN (SELECT DISTINCT auth FROM %splayertimes WHERE style = %d %s %s %s %s);",
|
||||
gS_MySQLPrefix, i,
|
||||
sLastLogin, (sLastLogin[0] != 0) ? "AND" : "",
|
||||
gS_MySQLPrefix, i,
|
||||
sMapWhere[0] ? "AND" : "",
|
||||
sMapWhere,
|
||||
sTrackWhere[0] ? "AND" : "",
|
||||
sTrackWhere);
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdateAllStylePoints_Callback, sStyleQuery);
|
||||
}
|
||||
}
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdateAllPoints_Callback, sQuery);
|
||||
@ -1185,6 +1620,14 @@ public void SQL_UpdateAllPoints_Callback(Database db, DBResultSet results, const
|
||||
}
|
||||
}
|
||||
|
||||
public void SQL_UpdateAllStylePoints_Callback(Database db, DBResultSet results, const char[] error, any data)
|
||||
{
|
||||
if(results == null)
|
||||
{
|
||||
LogError("Timer (rankings, update all style points) error! Reason: %s", error);
|
||||
}
|
||||
}
|
||||
|
||||
void UpdatePlayerRank(int client, bool first)
|
||||
{
|
||||
int iSteamID = 0;
|
||||
@ -1202,6 +1645,19 @@ void UpdatePlayerRank(int client, bool first)
|
||||
hPack.WriteCell(first);
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdatePlayerRank_Callback, sQuery, hPack, DBPrio_Low);
|
||||
|
||||
for (int i = 0; i < gI_Styles; i++)
|
||||
{
|
||||
FormatEx(sQuery, 512, "SELECT s2.points, COUNT(*) FROM %sstylepoints s1 JOIN (SELECT points FROM %sstylepoints WHERE auth = %d AND style = %d) s2 WHERE style = %d AND s1.points >= s2.points;",
|
||||
gS_MySQLPrefix, gS_MySQLPrefix, iSteamID, i, i);
|
||||
|
||||
DataPack hStylePack = new DataPack();
|
||||
hStylePack.WriteCell(GetClientSerial(client));
|
||||
hStylePack.WriteCell(first);
|
||||
hStylePack.WriteCell(i);
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdatePlayerStyleRank_Callback, sQuery, hStylePack, DBPrio_Low);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1242,6 +1698,45 @@ public void SQL_UpdatePlayerRank_Callback(Database db, DBResultSet results, cons
|
||||
}
|
||||
}
|
||||
|
||||
public void SQL_UpdatePlayerStyleRank_Callback(Database db, DBResultSet results, const char[] error, any data)
|
||||
{
|
||||
DataPack hPack = view_as<DataPack>(data);
|
||||
hPack.Reset();
|
||||
|
||||
int iSerial = hPack.ReadCell();
|
||||
bool bFirst = view_as<bool>(hPack.ReadCell());
|
||||
int iStyle = hPack.ReadCell();
|
||||
delete hPack;
|
||||
|
||||
if(results == null)
|
||||
{
|
||||
LogError("Timer (rankings, update player style rank) error! Reason: %s", error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
int client = GetClientFromSerial(iSerial);
|
||||
|
||||
if(client == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if(results.FetchRow())
|
||||
{
|
||||
gA_Rankings[client].fStylePoints[iStyle] = results.FetchFloat(0);
|
||||
gA_Rankings[client].iStyleRank[iStyle] = (gA_Rankings[client].fStylePoints[iStyle] > 0.0)? results.FetchInt(1):0;
|
||||
|
||||
Call_StartForward(gH_Forwards_OnStyleRankAssigned);
|
||||
Call_PushCell(client);
|
||||
Call_PushCell(iStyle);
|
||||
Call_PushCell(gA_Rankings[client].iStyleRank[iStyle]);
|
||||
Call_PushCell(gA_Rankings[client].fStylePoints[iStyle]);
|
||||
Call_PushCell(bFirst);
|
||||
Call_Finish();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateTop100()
|
||||
{
|
||||
char sQuery[512];
|
||||
@ -1252,6 +1747,21 @@ void UpdateTop100()
|
||||
gS_MySQLPrefix, gS_MySQLPrefix);
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdateTop100_Callback, sQuery, 0, DBPrio_High);
|
||||
|
||||
for (int i = 0; i < gI_Styles; i++)
|
||||
{
|
||||
FormatEx(sQuery, sizeof(sQuery),
|
||||
"SELECT COUNT(*) as c, '' as auth, '' as name, '' as points FROM %sstylepoints as s WHERE style = %d AND points > 0.0 \
|
||||
UNION ALL \
|
||||
SELECT '' as c, %sstylepoints.auth, %susers.name, %sstylepoints.points \
|
||||
FROM %sstylepoints \
|
||||
INNER JOIN %susers \
|
||||
ON %sstylepoints.auth = %susers.auth \
|
||||
WHERE %sstylepoints.points > 0 AND %sstylepoints.style = %d ORDER BY c DESC, CAST(points AS FLOAT) DESC LIMIT 101;",
|
||||
gS_MySQLPrefix, i, gS_MySQLPrefix, gS_MySQLPrefix,gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, i);
|
||||
|
||||
QueryLog(gH_SQL, SQL_UpdateStyleTop100_Callback, sQuery, i, DBPrio_High);
|
||||
}
|
||||
}
|
||||
|
||||
public void SQL_UpdateTop100_Callback(Database db, DBResultSet results, const char[] error, any data)
|
||||
@ -1299,9 +1809,42 @@ public void SQL_UpdateTop100_Callback(Database db, DBResultSet results, const ch
|
||||
gH_Top100Menu.AddItem("-1", sDisplay);
|
||||
}
|
||||
|
||||
gH_Top100Menu.ExitBackButton = true;
|
||||
gH_Top100Menu.ExitButton = true;
|
||||
}
|
||||
|
||||
public void SQL_UpdateStyleTop100_Callback(Database db, DBResultSet results, const char[] error, any data)
|
||||
{
|
||||
if (results == null)
|
||||
{
|
||||
LogError("Timer (rankings, update style top 100) error! Reason: %s", error);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (!results.FetchRow())
|
||||
{
|
||||
LogError("Timer (rankings, update style top 100 b) error! Reason: failed to fetch first row");
|
||||
return;
|
||||
}
|
||||
|
||||
int iStyle = data;
|
||||
gI_StyleRankedPlayers[iStyle] = results.FetchInt(0);
|
||||
|
||||
int row = 0;
|
||||
char sName[33];
|
||||
while (results.FetchRow())
|
||||
{
|
||||
gA_StyleTop[iStyle].iSteamID[row] = results.FetchInt(1);
|
||||
|
||||
results.FetchString(2, sName, 33);
|
||||
gA_StyleTop[iStyle].sName.SetString(row, sName);
|
||||
|
||||
gA_StyleTop[iStyle].fPoints[row] = results.FetchFloat(3);
|
||||
row++;
|
||||
}
|
||||
}
|
||||
|
||||
bool DoWeHaveWindowFunctions(const char[] sVersion)
|
||||
{
|
||||
char buf[100][2];
|
||||
@ -1643,16 +2186,31 @@ public int Native_GetPoints(Handle handler, int numParams)
|
||||
return view_as<int>(gA_Rankings[GetNativeCell(1)].fPoints);
|
||||
}
|
||||
|
||||
public int Native_GetStylePoints(Handle handler, int numParams)
|
||||
{
|
||||
return view_as<int>(gA_Rankings[GetNativeCell(1)].fStylePoints[GetNativeCell(2)]);
|
||||
}
|
||||
|
||||
public int Native_GetRank(Handle handler, int numParams)
|
||||
{
|
||||
return gA_Rankings[GetNativeCell(1)].iRank;
|
||||
}
|
||||
|
||||
public int Native_GetStyleRank(Handle handler, int numParams)
|
||||
{
|
||||
return gA_Rankings[GetNativeCell(1)].iStyleRank[GetNativeCell(2)];
|
||||
}
|
||||
|
||||
public int Native_GetRankedPlayers(Handle handler, int numParams)
|
||||
{
|
||||
return gI_RankedPlayers;
|
||||
}
|
||||
|
||||
public int Native_GetStyleRankedPlayers(Handle handler, int numParams)
|
||||
{
|
||||
return gI_StyleRankedPlayers[GetNativeCell(1)];
|
||||
}
|
||||
|
||||
public int Native_Rankings_DeleteMap(Handle handler, int numParams)
|
||||
{
|
||||
char sMap[PLATFORM_MAX_PATH];
|
||||
@ -1722,3 +2280,10 @@ public void SQL_DeleteMap_Callback(Database db, DBResultSet results, const char[
|
||||
UpdateAllPoints(true);
|
||||
}
|
||||
}
|
||||
|
||||
int GetMaxTier()
|
||||
{
|
||||
float val = 10.0;
|
||||
gCV_DefaultTier.GetBounds(ConVarBound_Upper, val);
|
||||
return RoundToFloor(val);
|
||||
}
|
||||
|
||||
@ -56,6 +56,7 @@ int gI_MapType[MAXPLAYERS+1];
|
||||
int gI_Style[MAXPLAYERS+1];
|
||||
int gI_MenuPos[MAXPLAYERS+1];
|
||||
int gI_Track[MAXPLAYERS+1];
|
||||
int gI_Tier[MAXPLAYERS+1];
|
||||
int gI_TargetSteamID[MAXPLAYERS+1];
|
||||
char gS_TargetName[MAXPLAYERS+1][MAX_NAME_LENGTH];
|
||||
|
||||
@ -753,10 +754,47 @@ public int MenuHandler_MapsDoneLeft_Track(Menu menu, MenuAction action, int para
|
||||
{
|
||||
if(action == MenuAction_Select)
|
||||
{
|
||||
char sInfo[8];
|
||||
char sInfo[8], sTier[16];
|
||||
menu.GetItem(param2, sInfo, 8);
|
||||
gI_Track[param1] = StringToInt(sInfo);
|
||||
|
||||
if(gB_Rankings)
|
||||
{
|
||||
Menu submenu = new Menu(MenuHandler_MapsDoneLeft_Tier);
|
||||
submenu.SetTitle("%T\n ", "SelectTier", param1);
|
||||
|
||||
submenu.AddItem("0", "All");
|
||||
|
||||
for(int i = 1; i <= 10; ++i)
|
||||
{
|
||||
IntToString(i, sInfo, 8);
|
||||
FormatEx(sTier, 16, "Tier %d", i);
|
||||
submenu.AddItem(sInfo, sTier);
|
||||
}
|
||||
|
||||
submenu.Display(param1, MENU_TIME_FOREVER);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowMaps(param1);
|
||||
}
|
||||
}
|
||||
else if(action == MenuAction_End)
|
||||
{
|
||||
delete menu;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public int MenuHandler_MapsDoneLeft_Tier(Menu menu, MenuAction action, int param1, int param2)
|
||||
{
|
||||
if(action == MenuAction_Select)
|
||||
{
|
||||
char sInfo[8];
|
||||
menu.GetItem(param2, sInfo, 8);
|
||||
gI_Tier[param1] = StringToInt(sInfo);
|
||||
|
||||
ShowMaps(param1);
|
||||
}
|
||||
else if(action == MenuAction_End)
|
||||
@ -1180,7 +1218,7 @@ public int MenuHandler_TypeHandler(Menu menu, MenuAction action, int param1, int
|
||||
{
|
||||
if(action == MenuAction_Select)
|
||||
{
|
||||
char sInfo[32];
|
||||
char sInfo[32], sTier[16];
|
||||
menu.GetItem(param2, sInfo, 32);
|
||||
|
||||
char sExploded[2][4];
|
||||
@ -1189,7 +1227,26 @@ public int MenuHandler_TypeHandler(Menu menu, MenuAction action, int param1, int
|
||||
gI_Track[param1] = StringToInt(sExploded[0]);
|
||||
gI_MapType[param1] = StringToInt(sExploded[1]);
|
||||
|
||||
ShowMaps(param1);
|
||||
if(gB_Rankings)
|
||||
{
|
||||
Menu submenu = new Menu(MenuHandler_MapsDoneLeft_Tier);
|
||||
submenu.SetTitle("%T\n ", "SelectTier", param1);
|
||||
|
||||
submenu.AddItem("0", "All");
|
||||
|
||||
for(int i = 1; i <= 10; ++i)
|
||||
{
|
||||
IntToString(i, sInfo, 8);
|
||||
FormatEx(sTier, 16, "Tier %d", i);
|
||||
submenu.AddItem(sInfo, sTier);
|
||||
}
|
||||
|
||||
submenu.Display(param1, MENU_TIME_FOREVER);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowMaps(param1);
|
||||
}
|
||||
}
|
||||
else if(action == MenuAction_Cancel && param2 == MenuCancel_ExitBack)
|
||||
{
|
||||
@ -1210,21 +1267,39 @@ void ShowMaps(int client)
|
||||
return;
|
||||
}
|
||||
|
||||
char sQuery[512];
|
||||
char sQuery[512], tierStr[32];
|
||||
|
||||
if(gI_Tier[client] > 0)
|
||||
{
|
||||
FormatEx(tierStr, 32, " AND t.tier = %d", gI_Tier[client]);
|
||||
}
|
||||
else
|
||||
{
|
||||
gI_Tier[client] = 0;
|
||||
}
|
||||
|
||||
if(gI_MapType[client] == MAPSDONE)
|
||||
{
|
||||
FormatEx(sQuery, 512,
|
||||
"SELECT a.map, a.time, a.jumps, a.id, COUNT(b.map) + 1 as 'rank', a.points FROM %splayertimes a LEFT JOIN %splayertimes b ON a.time > b.time AND a.map = b.map AND a.style = b.style AND a.track = b.track WHERE a.auth = %d AND a.style = %d AND a.track = %d GROUP BY a.map, a.time, a.jumps, a.id, a.points ORDER BY a.%s;",
|
||||
gS_MySQLPrefix, gS_MySQLPrefix, gI_TargetSteamID[client], gI_Style[client], gI_Track[client], (gB_Rankings)? "points DESC":"map");
|
||||
if(gB_Rankings)
|
||||
{
|
||||
FormatEx(sQuery, 512,
|
||||
"SELECT a.map, a.time, a.jumps, a.id, COUNT(b.map) + 1 as 'rank', a.points FROM %splayertimes a LEFT JOIN %splayertimes b ON a.time > b.time AND a.map = b.map AND a.style = b.style AND a.track = b.track LEFT JOIN %smaptiers t ON a.map = t.map WHERE a.auth = %d AND a.style = %d AND a.track = %d%s GROUP BY a.map, a.time, a.jumps, a.id, a.points ORDER BY a.points DESC;",
|
||||
gS_MySQLPrefix, gS_MySQLPrefix, gS_MySQLPrefix, gI_TargetSteamID[client], gI_Style[client], gI_Track[client], tierStr);
|
||||
}
|
||||
else
|
||||
{
|
||||
FormatEx(sQuery, 512,
|
||||
"SELECT a.map, a.time, a.jumps, a.id, COUNT(b.map) + 1 as 'rank', a.points FROM %splayertimes a LEFT JOIN %splayertimes b ON a.time > b.time AND a.map = b.map AND a.style = b.style AND a.track = b.track WHERE a.auth = %d AND a.style = %d AND a.track = %d GROUP BY a.map, a.time, a.jumps, a.id, a.points ORDER BY a.map;",
|
||||
gS_MySQLPrefix, gS_MySQLPrefix, gI_TargetSteamID[client], gI_Style[client], gI_Track[client]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(gB_Rankings)
|
||||
{
|
||||
FormatEx(sQuery, 512,
|
||||
"SELECT DISTINCT m.map, t.tier FROM %smapzones m LEFT JOIN %smaptiers t ON m.map = t.map WHERE m.type = 0 AND m.track = %d AND m.map NOT IN (SELECT DISTINCT map FROM %splayertimes WHERE auth = %d AND style = %d AND track = %d) ORDER BY m.map;",
|
||||
gS_MySQLPrefix, gS_MySQLPrefix, gI_Track[client], gS_MySQLPrefix, gI_TargetSteamID[client], gI_Style[client], gI_Track[client]);
|
||||
"SELECT DISTINCT m.map, t.tier FROM %smapzones m LEFT JOIN %smaptiers t ON m.map = t.map WHERE m.type = 0 AND m.track = %d%s AND m.map NOT IN (SELECT DISTINCT map FROM %splayertimes WHERE auth = %d AND style = %d AND track = %d) ORDER BY m.map;",
|
||||
gS_MySQLPrefix, gS_MySQLPrefix, gI_Track[client], tierStr, gS_MySQLPrefix, gI_TargetSteamID[client], gI_Style[client], gI_Track[client]);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -1328,13 +1403,19 @@ public void ShowMapsCallback(Database db, DBResultSet results, const char[] erro
|
||||
menu.AddItem(sRecordID, sDisplay);
|
||||
}
|
||||
|
||||
char sTier[8];
|
||||
if(gI_Tier[client] > 0)
|
||||
{
|
||||
FormatEx(sTier, 8, "T%d ", gI_Tier[client]);
|
||||
}
|
||||
|
||||
if(gI_MapType[client] == MAPSDONE)
|
||||
{
|
||||
menu.SetTitle("%T (%s)", "MapsDoneFor", client, gS_StyleStrings[gI_Style[client]].sShortName, gS_TargetName[client], rows, sTrack);
|
||||
menu.SetTitle("%s%T (%s)", sTier, "MapsDoneFor", client, gS_StyleStrings[gI_Style[client]].sShortName, gS_TargetName[client], rows, sTrack);
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.SetTitle("%T (%s)", "MapsLeftFor", client, gS_StyleStrings[gI_Style[client]].sShortName, gS_TargetName[client], rows, sTrack);
|
||||
menu.SetTitle("%s%T (%s)", sTier, "MapsLeftFor", client, gS_StyleStrings[gI_Style[client]].sShortName, gS_TargetName[client], rows, sTrack);
|
||||
}
|
||||
|
||||
if(menu.ItemCount == 0)
|
||||
|
||||
@ -16,18 +16,46 @@
|
||||
"#format" "{1:s},{2:N},{3:s},{4:s},{5:d},{6:s},{7:d},{8:s},{9:.1f},{10:s}"
|
||||
"en" "{1}{2}{3} is ranked {4}{5}{6} out of {7} with {8}{9}{10} points."
|
||||
}
|
||||
"StyleRank"
|
||||
{
|
||||
"#format" "{1:s},{2:N},{3:s},{4:s},{5:d},{6:s},{7:d},{8:s},{9:.1f},{10:s},{11:s},{12:s},{13:s}"
|
||||
"en" "{1}{2}{3} is ranked {4}{5}{6} out of {7} with {8}{9}{10} points. ({11}{12}{13})"
|
||||
}
|
||||
"Unranked"
|
||||
{
|
||||
"#format" "{1:s},{2:N},{3:s}"
|
||||
"en" "{1}{2}{3} is unranked."
|
||||
}
|
||||
"UnrankedOnStyle"
|
||||
{
|
||||
"#format" "{1:s},{2:N},{3:s},{4:s},{5:s},{6:s}"
|
||||
"en" "{1}{2}{3} is unranked on {4}{5}{6}."
|
||||
}
|
||||
// ---------- Menus ---------- //
|
||||
"Top100"
|
||||
{
|
||||
"en" "Top 100 ranked players:"
|
||||
}
|
||||
"StyleTop100"
|
||||
{
|
||||
"#format" "{1:s}"
|
||||
"en" "Top 100 ranked players ({1}):"
|
||||
}
|
||||
"StyleRankTitle"
|
||||
{
|
||||
"#format" "{1:s}"
|
||||
"en" "{1}'s rank:"
|
||||
}
|
||||
"StyleTopTitle"
|
||||
{
|
||||
"en" "Top Players Menu:"
|
||||
}
|
||||
"Overall"
|
||||
{
|
||||
"en" "Overall"
|
||||
}
|
||||
"NoRankedPlayers"
|
||||
{
|
||||
"en" "No ranked players found."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,10 @@
|
||||
{
|
||||
"en" "Select timer track:"
|
||||
}
|
||||
"SelectTier"
|
||||
{
|
||||
"en" "Select map tier:"
|
||||
}
|
||||
"MapsDone"
|
||||
{
|
||||
"en" "Maps done"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user