Compare commits

...

31 Commits

Author SHA1 Message Date
mourningsickness
c04029a469
Merge 2a3907171a into 21a7b58c82 2025-10-08 00:23:14 +00:00
haooy
21a7b58c82 Reset players hp when needed
Some checks failed
Compile / Build SM ${{ matrix.sm-version }} (1.12) (push) Has been cancelled
Compile / Release (push) Has been cancelled
Reset players hp when needed
2025-10-08 00:05:10 +00:00
mourningsickness
133c4e5b12
shavit-hud.sp - add perf% to center hud (#1259)
Co-authored-by: rtldg <rtldg@protonmail.com>
2025-10-07 23:55:27 +00:00
mourningsickness
2a3907171a
shavit-rankings.sp - <3 2025-08-12 09:51:19 -07:00
mourningsickness
068dcff798
shavit-chat.cfg - add new variables to the list in top comments 2025-08-12 09:49:33 -07:00
mourningsickness
dbe8e9a99f
shavit-chat.cfg - mentally disabled. fixed example 2025-08-12 09:46:36 -07:00
mourningsickness
69b13bce5a
shavit-rankings.sp - fix table name in pg/sqlite query 2025-08-12 09:38:15 -07:00
mourningsickness
e7a0e66ec4
shavit-chat.cfg - add style rank examples 2025-08-12 07:38:40 -07:00
mourningsickness
14c3a4a4be
shavit-rankings.sp - fix query 2025-08-11 20:23:46 -07:00
mourningsickness
54ea76ecf9
shavit-rankings.sp - fix rankings by adding 'style' to the select statements 2025-08-11 18:35:22 -07:00
mourningsickness
d140506194
shavit-rankings.sp - remove extra } 2025-08-11 10:02:46 -07:00
mourningsickness
5ca5446354
shavit-rankings.sp - first attempt at optimizing queries using GROUP BY style instead of running a query for each style ID 2025-08-11 09:58:09 -07:00
mourningsickness
5391c32d3d
shavit-chat.sp - remove duplicate '#' 2025-08-01 16:17:39 -07:00
mourningsickness
828ed94857
shavit-chat.sp - fix replace variables 2025-08-01 16:08:53 -07:00
mourningsickness
b0359f02e3
shavit-chat.sp - add dynamic {currentstylerank} variable and prepend '#' to style ranks 2025-08-01 15:51:11 -07:00
mourningsickness
3032818408
shavit-rankings.sp - fix queries 2025-08-01 13:56:30 -07:00
mourningsickness
bd740d8504
shavit-chat.sp - add style rank chatranks support 2025-08-01 11:28:08 -07:00
mourningsickness
832528bc01
shavit-rankings.sp - fix styles < 100 ranked players displaying 0s through to 100 entries in the menu 2025-08-01 10:23:45 -07:00
mourningsickness
8b571296c0
shavit-rankings.sp - change UPDATE to UPDATE IGNORE to prevent null errors when value being set to default 0 2025-07-31 22:10:30 -07:00
mourningsickness
56c6cd35db
shavit-rankings.sp - remove unnecessary translation file 2025-07-31 20:12:33 -07:00
mourningsickness
0b597f1be1
Update shavit-rankings.sp 2025-07-31 20:08:55 -07:00
mourningsickness
62477e4072
shavit-rankings.phrases.txt - last translations 2025-07-31 20:07:06 -07:00
mourningsickness
799f34bfdd
shavit-rankings.phrases.txt - add Overall translation 2025-07-31 13:05:02 -07:00
mourningsickness
aab9f9c271
sql-create-tables-and-migrations.sp - AddStylePoints migration 2025-07-31 11:57:55 -07:00
mourningsickness
88e0a78b08
sql-create-tables-and-migrations.sp - rename table 2025-07-31 08:36:36 -07:00
mourningsickness
858c489a5e
rankings.inc - add forward and natives 2025-07-31 07:44:30 -07:00
mourningsickness
61ee8f5d4b
shavit-rankings.sp - wip 2025-07-30 21:33:17 -07:00
mourningsickness
8b54f4b1ad
shavit-rankings.phrases.txt - add StyleTop100 translation 2025-07-30 21:00:24 -07:00
mourningsickness
025324c3cb
shavit-rankings.phrases.txt - add StyleRank translation 2025-07-30 20:44:43 -07:00
mourningsickness
89b92d4313
shavit-rankings.phrases.txt - add UnrankedOnStyle translation 2025-07-30 20:36:15 -07:00
mourningsickness
139e771386
sql-create-tables-and-migrations.sp - add stylerankings table 2025-07-30 19:25:58 -07:00
10 changed files with 766 additions and 22 deletions

View File

@ -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!"
}
}

View File

@ -42,6 +42,7 @@
#define HUD_GLOCK (1 << 14) // makes you spawn with a Glock
#define HUD_DEBUGTARGETNAME (1 << 15) // admin option to show current targetname & classname
#define HUD_SPECTATORSDEAD (1 << 16) // for only showing spectators list when you're dead/spectating.
#define HUD_PERFS_CENTER (1 << 17) // for the perf percentage in the center hud. e.g. "Jumps: 20 (66.6%)"
// HUD2 - these settings will *disable* elements for the main hud
#define HUD2_TIME (1 << 0)

View File

@ -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");

View File

@ -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);

View File

@ -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)

View File

@ -209,6 +209,7 @@ public void OnPluginStart()
..."HUD_USP 8192\n"
..."HUD_GLOCK 16384\n"
..."HUD_SPECTATORSDEAD 65536\n"
..."HUD_PERFS_CENTER 131072\n"
);
IntToString(HUD_DEFAULT2, defaultHUD, 8);
@ -776,6 +777,10 @@ Action ShowHUDMenu(int client, int item)
FormatEx(sHudItem, 64, "%T", "HudPerfs", client);
menu.AddItem(sInfo, sHudItem);
FormatEx(sInfo, 16, "!%d", HUD_PERFS_CENTER);
FormatEx(sHudItem, 64, "%T", "HudPerfsCenter", client);
menu.AddItem(sInfo, sHudItem);
FormatEx(sInfo, 16, "@%d", HUD2_STYLE);
FormatEx(sHudItem, 64, "%T", "HudStyleText", client);
menu.AddItem(sInfo, sHudItem);
@ -1369,7 +1374,15 @@ int AddHUDToBuffer_Source2013(int client, huddata_t data, char[] buffer, int max
if((gI_HUD2Settings[client] & HUD2_JUMPS) == 0)
{
FormatEx(sLine, 128, "%T: %d", "HudJumpsText", client, data.iJumps);
if (!Shavit_GetStyleSettingBool(data.iStyle, "autobhop") && (gI_HUDSettings[client] & HUD_PERFS_CENTER))
{
FormatEx(sLine, 128, "%T: %d (%.1f)", "HudJumpsText", client, data.iJumps, Shavit_GetPerfectJumps(data.iTarget));
}
else
{
FormatEx(sLine, 128, "%T: %d", "HudJumpsText", client, data.iJumps);
}
AddHUDLine(buffer, maxlen, sLine, iLines);
}

View File

@ -2454,7 +2454,7 @@ public void Shavit_OnRestart(int client, int track)
{
SetEntPropFloat(client, Prop_Send, "m_flStamina", 0.0);
if (gCV_RestartWithFullHP.BoolValue)
if (gCV_RestartWithFullHP.BoolValue && GetClientHealth(client) <= 100)
{
SetEntityHealth(client, 100);
SetEntProp(client, Prop_Send, "m_ArmorValue", 100);

View File

@ -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;
}
@ -877,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++)
{
@ -903,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);
}
@ -1015,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)
{
@ -1045,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));
@ -1062,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)
@ -1086,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
{
@ -1093,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)
@ -1126,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)
{
@ -1150,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
{
@ -1162,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);
@ -1187,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;
@ -1204,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);
}
}
}
@ -1244,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];
@ -1254,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)
@ -1301,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];
@ -1645,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];

View File

@ -85,6 +85,10 @@
{
"en" "Perfect jumps"
}
"HudPerfsCenter"
{
"en" "Perfect jumps (center hud)"
}
"HudDefaultPistol"
{
"en" "Default Pistol: 1=USP 2=Glock"

View File

@ -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."
}
}
}