Код:
#include <amxmodx>
#include <amxmisc>
#include <hamsandwich>
#define SORT_INTERVAL 3.0
enum RankData
{
Data_SteamID[32],
Data_Name[32],
Data_Kills,
Data_Deaths,
Data_Headshots
};
new g_File[64];
new Array:g_SteamID;
new Trie:g_Name, Trie:g_Kills, Trie:g_Deaths, Trie:g_Headshots;
new g_Top[2048];
new bool:g_Sort = true;
new g_Data[33][RankData], bool:g_Authorized[33];
public plugin_init()
{
register_plugin("Rank", "3.0", "hleV & perf");
RegisterHam( Ham_Spawn, "player", "FwdPlayerSpawnPost", 1 );
get_datadir(g_File, 63);
add(g_File, 63, "/ranks.ini");
g_SteamID = ArrayCreate(32, 1);
g_Name = TrieCreate();
g_Kills = TrieCreate();
g_Deaths = TrieCreate();
g_Headshots = TrieCreate();
LoadRanks();
ArraySort(g_SteamID, "SortRanks");
WriteTop();
set_task(SORT_INTERVAL, "SortTask", _, _, _, "b");
register_clcmd("say /rank", "SayRank");
register_clcmd("say /top", "SayTop");
register_event("DeathMsg", "DeathMsg", "a");
}
public plugin_end()
{
ArraySort(g_SteamID, "SortRanks");
SaveRanks();
ArrayDestroy(g_SteamID);
}
public client_putinserver(Client)
{
if(!is_user_steam(Client) || is_user_bot(Client))
return;
get_user_authid(Client, g_Data[Client][Data_SteamID], 31);
get_user_name(Client, g_Data[Client][Data_Name], 31);
if (!TrieKeyExists(g_Name, g_Data[Client][Data_SteamID]))
AddRank(Client);
else
LoadData(Client);
UpdateRank(Client, true);
g_Authorized[Client] = true;
}
public client_disconnect(Client)
g_Authorized[Client] = false;
public client_infochanged(Client)
{
if (!g_Authorized[Client])
return;
static Name[32];
get_user_info(Client, "name", Name, 31);
if (equal(Name, g_Data[Client][Data_Name]))
return;
copy(g_Data[Client][Data_Name], 31, Name);
UpdateRank(Client, true);
}
public FwdPlayerSpawnPost( Client )
{
if(!is_user_steam(Client))
return;
if( is_user_alive( Client ) )
{
set_task(0.1, "SayRank", Client)
}
}
public SayRank(Client)
{
if(!is_user_steam(Client))
{
client_print(Client,print_chat, "Stats only for STEAM players!");
return;
}
new Position = GetPosition(Client);
if (!g_Authorized[Client] || !Position)
{
client_print(Client, print_chat, "* You are not ranked.");
return;
}
new Float:kd, Float:hsp, Float:k = float(g_Data[Client][Data_Kills]), Float:d = float(g_Data[Client][Data_Deaths]), Float:h = float(g_Data[Client][Data_Headshots]);
kd = k / d
hsp = h / k *100
client_print
(
Client,
print_chat,
"* Your rank is %d of %d with Kills: %d | Deaths: %d | HeadShots: %d | K/D: %.2f | HSP: %.2f %",
Position,
ArraySize(g_SteamID),
g_Data[Client][Data_Kills],
g_Data[Client][Data_Deaths],
g_Data[Client][Data_Headshots],
kd,
hsp
);
}
public SayTop(Client)
show_motd(Client, g_Top, "Top");
public DeathMsg()
{
new Killer = read_data(1);
new Victim = read_data(2);
new HS = read_data(3);
if (g_Authorized[Victim])
{
g_Data[Victim][Data_Deaths]++;
g_Sort = true;
UpdateRank(Victim, false);
}
if (g_Authorized[Killer] && Killer != Victim)
{
g_Data[Killer][Data_Kills]++;
if(HS)
{
g_Data[Killer][Data_Headshots]++;
}
g_Sort = true;
UpdateRank(Killer, false);
}
}
public SortTask()
{
if (!g_Sort)
return;
ArraySort(g_SteamID, "SortRanks");
WriteTop();
SaveRanks();
}
public SortRanks(Array:SteamID, Position1, Position2)
{
static SteamID1[32];
ArrayGetString(SteamID, Position1, SteamID1, 31);
static SteamID2[32];
ArrayGetString(SteamID, Position2, SteamID2, 31);
static Kills1;
TrieGetCell(g_Kills, SteamID1, Kills1);
static Kills2;
TrieGetCell(g_Kills, SteamID2, Kills2);
static Deaths1;
TrieGetCell(g_Deaths, SteamID1, Deaths1);
static Deaths2;
TrieGetCell(g_Deaths, SteamID2, Deaths2);
static Headshots1;
TrieGetCell(g_Headshots, SteamID1, Headshots1);
static Headshots2;
TrieGetCell(g_Headshots, SteamID2, Headshots2);
if (Kills1*5 + Headshots1*5 - Deaths1*10 < Kills2*5 + Headshots2*5 - Deaths2*10)
return 1;
else if (Kills1*5 + Headshots1*5 - Deaths1*10 > Kills2*5 + Headshots2*5 - Deaths2*10)
return -1;
return 0;
}
LoadRanks()
{
new File = fopen(g_File, "r");
if (!File)
return;
new Data[112], SteamID[32], Name[32], Kills[16], Deaths[16], Headshots[16];
while (!feof(File))
{
fgets(File, Data, 112);
if (!strlen(Data))
continue;
parse(Data, SteamID, 31, Name, 31, Kills, 15, Deaths, 15, Headshots, 15);
ArrayPushString(g_SteamID, SteamID);
TrieSetString(g_Name, SteamID, Name);
TrieSetCell(g_Kills, SteamID, str_to_num(Kills));
TrieSetCell(g_Deaths, SteamID, str_to_num(Deaths));
TrieSetCell(g_Deaths, SteamID, str_to_num(Deaths));
TrieSetCell(g_Headshots, SteamID, str_to_num(Headshots));
}
fclose(File);
}
SaveRanks()
{
new File = fopen(g_File, "w+");
if (!File)
return;
for (new Position, Size = ArraySize(g_SteamID), SteamID[32], Name[32], Kills, Deaths, Headshots; Position < Size; Position++)
{
ArrayGetString(g_SteamID, Position, SteamID, 31);
TrieGetString(g_Name, SteamID, Name, 31);
TrieGetCell(g_Kills, SteamID, Kills);
TrieGetCell(g_Deaths, SteamID, Deaths);
TrieGetCell(g_Headshots, SteamID, Headshots);
fprintf(File, "%s ^"%s^" %d %d %d^n", SteamID, Name, Kills, Deaths, Headshots);
}
fclose(File);
}
AddRank(Client)
{
g_Data[Client][Data_Kills] = 0;
g_Data[Client][Data_Deaths] = 0;
g_Data[Client][Data_Headshots] = 0;
ArrayPushString(g_SteamID, g_Data[Client][Data_SteamID]);
TrieSetString(g_Name, g_Data[Client][Data_SteamID], g_Data[Client][Data_Name]);
}
LoadData(Client)
{
TrieGetCell(g_Kills, g_Data[Client][Data_SteamID], g_Data[Client][Data_Kills]);
TrieGetCell(g_Deaths, g_Data[Client][Data_SteamID], g_Data[Client][Data_Deaths]);
TrieGetCell(g_Headshots, g_Data[Client][Data_SteamID], g_Data[Client][Data_Headshots]);
}
UpdateRank(Client, bool:Name)
{
if (Name)
TrieSetString(g_Name, g_Data[Client][Data_SteamID], g_Data[Client][Data_Name]);
TrieSetCell(g_Kills, g_Data[Client][Data_SteamID], g_Data[Client][Data_Kills]);
TrieSetCell(g_Deaths, g_Data[Client][Data_SteamID], g_Data[Client][Data_Deaths]);
TrieSetCell(g_Headshots, g_Data[Client][Data_SteamID], g_Data[Client][Data_Headshots]);
}
GetPosition(Client)
{
static Position, Size, SteamID[32];
for (Position = 0, Size = ArraySize(g_SteamID); Position < Size; Position++)
{
ArrayGetString(g_SteamID, Position, SteamID, 31);
if (equal(SteamID, g_Data[Client][Data_SteamID]))
return Position + 1;
}
return 0;
}
WriteTop()
{
static const Header[] = "<body bgcolor=#000000><font color=#87cefa><pre>%5s %35s %5s %5s %5s %5s %5s^n^n";
static const Buffer[] = "%4d %35s %5d %6d %9d %9.2f %10.2f^n";
static Length, Position, Size, SteamID[32], Name[32], Kills, Deaths, Headshots, Float:kd, Float:hsp;
Length = formatex(g_Top[Length], 2047 - Length, Header, "Rank", "Name", "Kills", "Deaths", "HeadShots", "K/D ratio", "HS percent");
for (Position = 0, Size = min(ArraySize(g_SteamID), 15); Position < Size; Position++)
{
new Float:k = float(Kills), Float:d = float(Deaths), Float:h = float(Headshots);
ArrayGetString(g_SteamID, Position, SteamID, 31);
TrieGetString(g_Name, SteamID, Name, 31);
TrieGetCell(g_Kills, SteamID, Kills);
TrieGetCell(g_Deaths, SteamID, Deaths);
TrieGetCell(g_Headshots, SteamID, Headshots);
kd = k / d
hsp = h / k *100
Length += formatex(g_Top[Length], 2047 - Length, Buffer, Position + 1, Name, Kills, Deaths, Headshots, kd, hsp);
}
}
stock bool:is_user_steam(Client)
{
static dp_pointer;
if(dp_pointer || (dp_pointer = get_cvar_pointer("dp_r_id_provider")))
{
server_cmd("dp_clientinfo %d", Client);
server_exec();
return (get_pcvar_num(dp_pointer) == 2) ? true : false;
}
new szAuthid[34];
get_user_authid(Client, szAuthid, charsmax(szAuthid));
return (containi(szAuthid, "LAN") < 0);
}