Правила форума Гаранты форума
Размещение рекламы AMX-X компилятор

Здравствуйте, гость Вход | Регистрация

Наши новости:

14-дек
24-апр
10-апр
11-апр

> Полезные ссылки

Ищу скриптера оптимизировать плагин + удалить ненужное

, Требуются знания MySQL
Статус пользователя DANDY
сообщение 2.3.2017, 16:53
Сообщение #1
Стаж: 15 лет

Сообщений: 270
Благодарностей: 38
Полезность: 120

Ищу скриптера для оптимизации плагина статистики zp_stats, который работает с базой данных MySQL.
А также нужно удалить таблицы zp_shoots, zp_graph и zp_class_stats.
zp_stats.sma

Код:

#pragma dynamic 16384

#include <amxmodx>
#include <amxmisc>
#include <zombieplague>
#include <sqlx>
#include <hamsandwich>
#include <time>
#include <fakemeta>
#include <mapsmenu>
#include <adminvote>

//natives
native zp_level(id)
native zp_exp(id)
native zp_stats_level(id, iLevel)
native zp_stats_exp(id, iExp)

new map_boss, map_boss2 , map_boss3

#pragma dynamic 16384

#define PLUGIN "[ZP] Web Stats"
#define VERSION "0.3.0"
#define AUTHOR "PomanoB/Maslyak"

#define MOTD_FLAG_ARG 1
#define MOTD_FLAG_END 1

#define FORCE_TEAM_JOIN_TASK 2323
#define FORCE_TEAM_JOIN_DELAY 0.1
#define ADMIN_CHECK_TASK 2373
#define ADMIN_CHECK_DELAY 3.0

#define HOUR 3600

#define column(%1) SQL_FieldNameToNum(query, %1)

// Old Style Menus
stock const FIRST_JOIN_MSG[] = "#Team_Select";
stock const FIRST_JOIN_MSG_SPEC[] = "#Team_Select_Spect";
const iMaxLen = sizeof(FIRST_JOIN_MSG_SPEC);
// New VGUI Menus
stock const VGUI_JOIN_TEAM_NUM = 2;

enum
{
KILLER_ID,
KILLER_HP,
KILLER_ARMOUR,
KILLER_NUM
}

enum
{
ME_DMG,
ME_HIT,
ME_INFECT,
ME_KILLS,
ME_NUM
}

new g_ServerString[25], g_HostName[128]

new Handle:g_SQLTuple

new g_StartTime[33]
new g_UserIP[33][32], g_UserAuthID[33][32], g_UserName[33][32]
new g_UserDBId[33], g_UserTotalAmmo[33], g_TotalDamage[33]

new Handle:g_SQL_Connection

new g_Query[3024]

new g_CvarStartedAmmo
new g_CvarDamageReward
new g_CvarSurvIgnoreRewards
new g_CvarNemIgnoreAmmo
new g_CvarInfetAmmo

new g_CvarAllowHp, g_CvarAllowMe, g_CvarShowHit
new g_CvarMaxInactive, g_CvarMinAmmo
new g_CvarLimitAmmo, g_CvarShowBest

new g_damagedealt[33]

new const g_types[][]={"first_zombie", "infect", "zombiekills", "humankills", "nemkills", "survkills", "suicide"}

new g_Killers[33][KILLER_NUM]
new g_Me[33][ME_NUM]

new g_Hits[33][31][9], g_Kills[33][31]
new g_Weapon[33], g_OldWeapon[33], g_OldAmmo[33]

new bool:g_UserEntered[33], bool:g_UserJoinedTeam[33]

new const g_HitsName[8][] = {"HIT_NONE", "HIT_HEAD", "HIT_CHEST", "HIT_STOMACH", "HIT_LEFTARM", "HIT_RIGHTARM", "HIT_LEFTLEG", "HIT_RIGHTLEG"}

new g_text[5096]

new g_mapname[32]

new g_win_team[3][] = {"tie", "zombie_win", "human_win"}

//native zp_get_user_weapon_pri(id)
//native zp_get_user_weapon_sec(id)

public plugin_init()
{
new szMapName[ 64 ];
get_mapname( szMapName, 63 );

if( contain( szMapName, "zp_boss_city" ) != -1 ) map_boss = 1
else map_boss = 0

if( contain( szMapName, "zp_oberon_arena" ) != -1 ) map_boss2 = 1
else map_boss2 = 0

if( contain( szMapName, "zs_culvert_dione" ) != -1 ) map_boss3 = 1
else map_boss3 = 0

register_plugin(PLUGIN, VERSION, AUTHOR)

register_cvar("zp_stats_host", "127.0.0.1")
register_cvar("zp_stats_db", "zp_stats")
register_cvar("zp_stats_user", "root")
register_cvar("zp_stats_password", "")

register_cvar("zp_stats_version", VERSION, FCVAR_SERVER|FCVAR_SPONLY)

g_CvarAllowHp = register_cvar("zp_stats_allow_hp", "1")
g_CvarAllowMe = register_cvar("zp_stats_allow_me", "1")
g_CvarShowHit = register_cvar("zp_stats_show_hit", "0")

g_CvarMaxInactive = register_cvar("zp_stats_max_inactive_day", "60")
g_CvarMinAmmo = register_cvar("zp_stats_min_ammo", "30")

g_CvarLimitAmmo = register_cvar("zp_stats_limit_ammo", "5000")

g_CvarShowBest = register_cvar("zp_stats_show_best_players", "1")

register_clcmd("say", "handleSay")
register_clcmd("say_team", "handleSay")

register_concmd("zp_ammo", "cmdAmmo", ADMIN_RCON, " <target> <count> - Give Ammo")

RegisterHam(Ham_Killed, "player", "fw_HamKilled")
RegisterHam(Ham_TakeDamage, "player", "fw_TakeDamage", 1)
RegisterHam(Ham_CS_RoundRespawn, "player", "fw_CS_RoundRespawn", 1)
RegisterHam(Ham_TraceAttack, "player", "fw_TraceAttack", 1)

register_message(get_user_msgid("CurWeapon"), "msgCurWeapon")
register_message(get_user_msgid("ShowMenu"), "message_ShowMenu");
register_message(get_user_msgid("VGUIMenu"), "message_VGUIMenu");

register_dictionary("time.txt")
register_dictionary("zp_stats.txt")
}

public plugin_cfg()
{
g_CvarStartedAmmo = get_cvar_pointer("zp_starting_ammo_packs")
g_CvarDamageReward = get_cvar_pointer("zp_human_damage_reward")
g_CvarSurvIgnoreRewards = get_cvar_pointer("zp_surv_ignore_rewards")
g_CvarNemIgnoreAmmo = get_cvar_pointer("zp_nem_ignore_rewards")
g_CvarInfetAmmo = get_cvar_pointer("zp_zombie_infect_reward")

new host[32], db[32], user[32], password[32]
get_cvar_string("zp_stats_host", host, 31)
get_cvar_string("zp_stats_db", db, 31)
get_cvar_string("zp_stats_user", user, 31)
get_cvar_string("zp_stats_password", password, 31)

static menu_msgid
menu_msgid = get_user_msgid("MOTD")
set_msg_block(menu_msgid, BLOCK_SET)

g_SQLTuple = SQL_MakeDbTuple(host,user,password,db)

new err, error[256]
g_SQL_Connection = SQL_Connect(g_SQLTuple, err, error, charsmax(error))

if(g_SQL_Connection == Empty_Handle)
{
log_amx("%L",LANG_SERVER, "CONNECT_ERROR", err, error)
pause("a")
}
//log_amx("%L",LANG_SERVER, "CONNECT_SUCCESSFUL")

get_mapname(g_mapname, 31)

run_sql(SQL_PrepareQuery(g_SQL_Connection, "INSERT INTO `zp_maps` (`map`) VALUES ('%s') ON DUPLICATE KEY UPDATE `games` = `games` + 1", g_mapname))
run_sql(SQL_PrepareQuery(g_SQL_Connection, "SET NAMES utf8"))

new buffer[25], len
get_cvar_string("ip", buffer, charsmax(buffer))
len = format(g_ServerString, charsmax(g_ServerString), buffer)
get_cvar_string("port", buffer, charsmax(buffer))
format(g_ServerString[len], charsmax(g_ServerString) - len, ":%s", buffer)

new escaped_hostname[128]
get_cvar_string("hostname", g_HostName, charsmax(g_HostName))
SQL_QuoteString(g_SQL_Connection, escaped_hostname, charsmax(escaped_hostname), g_HostName)

run_sql(SQL_PrepareQuery(g_SQL_Connection,
"INSERT INTO `zp_servers` (`server`, `hostname`) VALUES ('%s', '%s') ON DUPLICATE KEY UPDATE `hostname` = '%s'",
g_ServerString, escaped_hostname, escaped_hostname))
run_sql(SQL_PrepareQuery(g_SQL_Connection,
"DELETE FROM `zp_server_players` WHERE `server` = '%s'",
g_ServerString))
load_classes_from_file()

set_task(15.0, "showAdv")
}

public showAdv()
{
ChatColor(0, "!g[ZP] !team15000!y - лимит Аммо для !teamБоссов");
ChatColor(0, "!g[ZP] !team10000!y - лимит Аммо для !teamАдминов !yили !teamВипов");
ChatColor(0, "!g[ZP] !team5000!y - лимит Аммо для !teamобычных игроков");

client_print(0, print_chat, "%L", LANG_PLAYER, "ADVERTISEMENT_SAVE")
client_print(0, print_chat, "%L", LANG_PLAYER, "ADVERTISEMENT_DONATE");

set_task(260.0, "showAdv")
}
public cmdAmmo(id, level, cid)
{
if (!cmd_access(id, level, cid, 3))
return PLUGIN_HANDLED

new arg1[24]
read_argv(1, arg1, 23)

new arg2[10]
read_argv(2, arg2, 9)
new count = str_to_num(arg2)

if (!count)
{
console_print(id, "%L", id, "INVALID_AMMO")
return PLUGIN_HANDLED
}

if (arg1[0] == '@')
{
new team = 0

if (arg1[1] == 'Z' || arg1[1] == 'z')
team = 1
else
if (arg1[1] == 'H' || arg1[1] == 'h')
team = 2

new players[32], num
new zombie

get_players(players, num)
new i
for (i=0; i<num; i++)
{
zombie = zp_get_user_zombie(id)
if (!team || (zombie && team == 1)|| (!zombie && team == 2))
{
give_ammo(players[i], count)
}
}
}
else
{
new player = cmd_target(id, arg1, (CMDTARGET_OBEY_IMMUNITY|CMDTARGET_ALLOW_SELF))
if (!player)
{
console_print(id, "%L", id, "CLIENT_NOT_FOUND", arg1)
return PLUGIN_HANDLED
}
else
{
give_ammo(player, count)
}
}

return PLUGIN_HANDLED
}

public give_ammo(id, count)
{
zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + count)
}

public message_ShowMenu(iMsgid, iDest, id)
{
if(!g_UserJoinedTeam[id] && g_UserEntered[id])
{
return PLUGIN_HANDLED
}
static sMenuCode[iMaxLen]
get_msg_arg_string(4, sMenuCode, sizeof(sMenuCode) - 1)
if(equal(sMenuCode, FIRST_JOIN_MSG) || equal(sMenuCode, FIRST_JOIN_MSG_SPEC))
{
enter_the_game(id)
return PLUGIN_HANDLED
}

return PLUGIN_CONTINUE
}

public message_VGUIMenu(iMsgid, iDest, id)
{
if(!g_UserJoinedTeam[id] && g_UserEntered[id])
{
return PLUGIN_HANDLED
}
if(get_msg_arg_int(1) == VGUI_JOIN_TEAM_NUM)
{
enter_the_game(id)
return PLUGIN_HANDLED;
}

return PLUGIN_CONTINUE
}

public enter_the_game(id)
{
g_UserEntered[id] = true

new param[1]
param[0] = id
if(g_UserDBId[id])
{
set_task(FORCE_TEAM_JOIN_DELAY, "force_team_join", FORCE_TEAM_JOIN_TASK + id, param, 1)
set_task(ADMIN_CHECK_DELAY, "admin_check", ADMIN_CHECK_TASK + id, param, 1)
}
}

public force_team_join(args[])
{
new id = args[0]
if(!is_user_connected(id))
return

static jointeam[] = "jointeam"
static joinclass[] = "joinclass"
static menu_msgid_old
static menu_msgid_vgui

menu_msgid_old = get_user_msgid("ShowMenu")
menu_msgid_vgui = get_user_msgid("VGUIMenu")

set_msg_block(menu_msgid_old, BLOCK_SET)
set_msg_block(menu_msgid_vgui, BLOCK_SET)

if(!map_boss && !map_boss2 && !map_boss3)
{
engclient_cmd(id, jointeam, "5") // 5 -> random choise
engclient_cmd(id, joinclass, "5")
}else{
engclient_cmd(id, jointeam, "2") // 5 -> random choise
engclient_cmd(id, joinclass, "2")
}

set_msg_block(menu_msgid_old, BLOCK_NOT)
set_msg_block(menu_msgid_vgui, BLOCK_NOT)

g_UserJoinedTeam[id] = true
}

public client_connect(id)
{
g_UserEntered[id] = false
g_UserJoinedTeam[id] = false
g_UserDBId[id] = 0
g_TotalDamage[id] = 0
g_UserTotalAmmo[id] = 0
reset_me_hp(id)
}

public client_putinserver(id)
{
new unquoted_name[32]
get_user_name(id,unquoted_name,31)
SQL_QuoteString(g_SQL_Connection , g_UserName[id], 31, unquoted_name)

get_user_authid(id,g_UserAuthID[id],31)
get_user_ip(id,g_UserIP[id],31,1)

g_damagedealt[id] = 0

new i
for (i = 0; i < 31; i++)
arrayset(g_Hits[id][i], 0, 9)

g_StartTime[id] = get_systime()

new uniqid[32]
new whereis[10]
new condition[40]

if (equal(g_UserAuthID[id],"STEAM_0:",8))
{
copy(whereis,9,"steam_id")
copy(uniqid,31,g_UserAuthID[id])
}
else
{
copy(whereis,9,"ip")
copy(uniqid,31,g_UserIP[id])
copy(condition, 39, " AND NOT (`steam_id` LIKE 'STEAM_0:%')")
}


format(g_Query,charsmax(g_Query),"SELECT `id`, `ammo`, `level`, `exp`, `class`, `weapon_pri`, `weapon_sec` FROM `zp_players` \
WHERE `%s`='%s' %s", whereis, uniqid, condition)

new data[1]
data[0] = id
SQL_ThreadQuery(g_SQLTuple, "ClientAuthorized_QueryHandler", g_Query, data, 1)
}

public ClientAuthorized_QueryHandler(FailState, Handle:query, error[], err, data[], size, Float:querytime)
{
if(FailState != TQUERY_SUCCESS)
return

new id = data[0]
if(!is_user_connected(id))
return

new ammo = get_pcvar_num(g_CvarStartedAmmo)
new iLevel = 1
new iExp = 0

if(SQL_NumResults(query))
{
ammo = SQL_ReadResult(query, column("ammo"))
g_UserDBId[id] = SQL_ReadResult(query, column("id"))

iLevel = SQL_ReadResult(query, column("level"))
iExp = SQL_ReadResult(query, column("exp"))

zp_set_user_zombie_class(id, SQL_ReadResult(query, column("class")))
}
else
{
format(g_Query,charsmax(g_Query),"INSERT INTO `zp_players` SET\
`ammo`=%d, `total_ammo`=%d, `level` = %d, `exp` = %d,\
`nick`='%s',\
`ip`='%s', `steam_id`='%s';",
ammo, ammo, iLevel, iExp,
g_UserName[id], g_UserIP[id], g_UserAuthID[id])

new Handle:queryyy = SQL_PrepareQuery(g_SQL_Connection, g_Query)
SQL_Execute(queryyy)
g_UserDBId[id] = SQL_GetInsertId(queryyy)
SQL_FreeHandle(queryyy)
}
if(check_player_for_playing(id))
{
zp_set_user_ammo_packs(id, ammo)
zp_stats_level(id, iLevel)
zp_stats_exp(id, iExp)
}
else // multiply users on one IP
{
g_UserDBId[id] = 0
// TODO: set warning message task for this player
}
new param[1]
param[0] = id
if(g_UserEntered[id])
enter_the_game(id)
}
public check_player_for_playing(id)
{
new Handle:query = SQL_PrepareQuery(g_SQL_Connection,
"SELECT `player_id` FROM `zp_server_players` WHERE `player_id` = '%d'",
g_UserDBId[id])
run_sql(query)
if(!SQL_NumResults(query))
{
run_sql(SQL_PrepareQuery(g_SQL_Connection, "INSERT INTO `zp_server_players` (`player_id`, `server`) \
VALUES ('%d', '%s')", g_UserDBId[id], g_ServerString))
return true
}
return false
}
public client_disconnect(id)
{
if(g_UserDBId[id] == 0)
{
return PLUGIN_CONTINUE
}

new unquoted_name[32], name[32]
get_user_name(id,unquoted_name,31)
SQL_QuoteString(g_SQL_Connection , name, 31, unquoted_name)

new current_time = get_systime()
new max_len = charsmax(g_Query)

if(get_pcvar_num(g_CvarLimitAmmo) != 0)
{
if (get_user_flags(id) & ADMIN_LEVEL_D)
{
if (zp_get_user_ammo_packs(id) > 15000)
zp_set_user_ammo_packs(id, 15000)
}
else if ((get_user_flags(id) & ADMIN_LEVEL_H) || (get_user_flags(id) & ADMIN_RESERVATION))
{
if (zp_get_user_ammo_packs(id) > 10000)
zp_set_user_ammo_packs(id, 10000)
}
else
{
if (zp_get_user_ammo_packs(id) > get_pcvar_num(g_CvarLimitAmmo))
zp_set_user_ammo_packs(id, get_pcvar_num(g_CvarLimitAmmo))
}
}

format(g_Query, max_len, "UPDATE `zp_players` SET \
`ammo`=%d, `total_ammo`= `total_ammo` + %d, `nick`='%s', `total_damage`=`total_damage` + %d, \
`last_join`=%d, `last_leave`=%d, `online` = `online` + %d,\
`class` = %d ,`weapon_pri` = %d, `weapon_sec` = %d, `level` = %d, `exp` = %d, \
WHERE `id`=%d",
zp_get_user_ammo_packs(id), g_UserTotalAmmo[id], name,
g_TotalDamage[id], g_StartTime[id], current_time, (current_time - g_StartTime[id]), zp_get_user_next_class(id),
zp_get_user_weapon_pri(id), zp_get_user_weapon_sec(id), zp_level(id), zp_exp(id), g_UserDBId[id])

SQL_QueryAndIgnore(g_SQL_Connection, g_Query)

new i, len

len = format(g_Query, max_len, "INSERT INTO `zp_shoots` VALUES")

for (i = 1; i < 31; i++)
{
if (i != 4 && i != 6 && i!= 9 && i != 25 && i != 29)
{
if (g_Hits[id][i][0])
{
len += format(g_Query[len], max_len - len,
" ('%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d', '%d'),",
i,
g_UserDBId[id],
g_Hits[id][i][0],
g_Hits[id][i][1],
g_Hits[id][i][2],
g_Hits[id][i][3],
g_Hits[id][i][4],
g_Hits[id][i][5],
g_Hits[id][i][6],
g_Hits[id][i][7],
g_Hits[id][i][8],
g_Kills[id][i])
}
}
}


g_Query[--len] = 0

len += format(g_Query[len], max_len - len, " ON DUPLICATE KEY UPDATE \
`shoot` = `shoot` + VALUES(`shoot`), \
`hit_head` = `hit_head` + VALUES(`hit_head`),")

len += format(g_Query[len], max_len - len, "`hit_chest` = `hit_chest` + VALUES(`hit_chest`), \
`hit_stomach` = `hit_stomach` + VALUES(`hit_stomach`), \
`hit_leftarm` = `hit_leftarm` + VALUES(`hit_leftarm`), ")

len += format(g_Query[len], max_len - len,
"`hit_rightarm` = `hit_rightarm` + VALUES(`hit_rightarm`), \
`hit_leftleg` = `hit_leftleg` + VALUES(`hit_leftleg`), \
`hit_rightleg` = `hit_rightleg` + VALUES(`hit_rightleg`), \
`hit_shield` = `hit_shield` + VALUES(`hit_shield`), \
`kills` = `kills` + VALUES(`kills`)")

SQL_QueryAndIgnore(g_SQL_Connection, g_Query)

run_sql(SQL_PrepareQuery(g_SQL_Connection,
"DELETE FROM `zp_server_players` WHERE `player_id` = '%d' AND `server` = '%s'",
g_UserDBId[id], g_ServerString))

return PLUGIN_CONTINUE
}

public zp_user_infected_post(id, infector, nemesis)
{

if (infector)
{
g_UserTotalAmmo[infector] += get_pcvar_num(g_CvarInfetAmmo)
format(g_Query, charsmax(g_Query), "UPDATE `zp_players` SET `infect` = `infect` + 1, `level` = %d, `exp` = %d WHERE `id`=%d", zp_level(id), zp_exp(id), g_UserDBId[infector])
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)

format(g_Query, charsmax(g_Query), "UPDATE `zp_players` SET `infected` = `infected` + 1 WHERE `id`=%d", g_UserDBId[id])
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)

format(g_Query, charsmax(g_Query), "INSERT INTO `zp_class_stats` (`id`, `id_player`, `infect`) VALUES(%d, %d, 1) ON DUPLICATE KEY UPDATE `infect` = `infect` + 1", zp_get_user_zombie_class(infector), g_UserDBId[infector])
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)

g_Me[infector][ME_INFECT]++
}
else if (!nemesis)
{
format(g_Query, charsmax(g_Query), "UPDATE `zp_players` SET `first_zombie` = `first_zombie` + 1 WHERE `id`=%d", g_UserDBId[id])
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)
}
else
{
format(g_Query, charsmax(g_Query), "UPDATE `zp_players` SET `nemesis` = `nemesis` + 1 WHERE `id`=%d", g_UserDBId[id])
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)
}
if (!nemesis)
{
format(g_Query, charsmax(g_Query), "INSERT INTO `zp_class_stats` (`id`, `id_player`, `games`) VALUES(%d, %d, 1) ON DUPLICATE KEY UPDATE `games` = `games` + 1", zp_get_user_zombie_class(id), g_UserDBId[id])
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)
}
}

public zp_user_humanized_post(id, survivor)
{
if (survivor)
{
format(g_Query, charsmax(g_Query), "UPDATE `zp_players` SET `survivor` = `survivor` + 1, `level` = %d, `exp` = %d WHERE `id`=%d", zp_level(id), zp_exp(id), g_UserDBId[id])
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)
}
}

public zp_round_ended(winteam)
{
if (!get_playersnum())
return

format(g_Query, charsmax(g_Query), "UPDATE `zp_maps` SET `%s` = `%s` + 1 WHERE `map` = '%s'", g_win_team[winteam], g_win_team[winteam], g_mapname)
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)

if (!get_pcvar_num(g_CvarShowBest))
return

new players[32], playersNum, i, maxInfectId = 0, maxDmgId = 0, maxKillsId = 0
new message[200], len
new maxInfectName[32], maxDmgName[32], maxKillsName[32]
get_players(players, playersNum, "ch")
for (i = 0; i < playersNum; i++)
{
if (g_Me[players[i]][ME_INFECT] > g_Me[players[maxInfectId]][ME_INFECT])
maxInfectId = i
if (g_Me[players[i]][ME_DMG] > g_Me[players[maxDmgId]][ME_DMG])
maxDmgId = i
if (g_Me[players[i]][ME_KILLS] > g_Me[players[maxKillsId]][ME_KILLS])
maxKillsId = i
}
get_user_name(players[maxInfectId], maxInfectName, 31)
get_user_name(players[maxDmgId], maxDmgName, 31)
get_user_name(players[maxKillsId], maxKillsName, 31)

if (!(g_Me[players[maxInfectId]][ME_INFECT] ||
g_Me[players[maxKillsId]][ME_KILLS] ||
g_Me[players[maxDmgId]][ME_DMG]))
{
return // there is no best player on any param
}

for (i = 0; i < playersNum; i++)
{
len = format(message, charsmax(message), "%L", players[i], "BEST_TITLE")
if (g_Me[players[maxInfectId]][ME_INFECT])
len += format(message[len], charsmax(message) - len,
"^n%L", players[i], "BEST_INFECT",
maxInfectName, g_Me[players[maxInfectId]][ME_INFECT])

if (g_Me[players[maxKillsId]][ME_KILLS])
len += format(message[len], charsmax(message) - len,
"^n%L", players[i], "BEST_KILLS",
maxKillsName, g_Me[players[maxKillsId]][ME_KILLS])

if (g_Me[players[maxDmgId]][ME_DMG])
len += format(message[len], charsmax(message) - len,
"^n%L", players[i], "BEST_DMG",
maxDmgName, g_Me[players[maxDmgId]][ME_DMG])

set_hudmessage(100, 200, 0, 0.05, 0.55, 0, 0.02, 6.0, 0.0, 1.0)
show_hudmessage(players[i], message)
}

update_zp_graph()
}

public update_zp_graph()
{
new players[32]
new playersNum = 0
new totalKills = 0
new totalInfects = 0
new totalDamage = 0

get_players(players, playersNum, "ch")
for (new i = 0; i < playersNum; i++)
{
totalInfects += g_Me[players[i]][ME_INFECT]
totalDamage += g_Me[players[i]][ME_DMG]
totalKills += g_Me[players[i]][ME_KILLS]
}
format(g_Query, charsmax(g_Query), "INSERT INTO `zp_graph` (`time`, `server`, `players`, `kills`, `infects`, `damage`) \
VALUES('%d', '%s', '%d', '%d', '%d', '%d')",
get_systime(), g_ServerString, get_playersnum(), totalKills, totalInfects, totalDamage)
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)
}

public fw_HamKilled(id, attacker, shouldgib)
{

if (is_user_connected(attacker) && zp_get_user_zombie(attacker) && (!zp_get_user_nemesis(attacker) || !get_pcvar_num(g_CvarNemIgnoreAmmo)))
g_UserTotalAmmo[attacker] += get_pcvar_num(g_CvarInfetAmmo)

if (is_user_connected(attacker))
{
g_Killers[id][KILLER_ID] = attacker
g_Killers[id][KILLER_HP] = get_user_health(attacker)
g_Killers[id][KILLER_ARMOUR] = get_user_armor(attacker)
g_Me[attacker][ME_KILLS] ++
}

new type, player = attacker

format(g_Query, charsmax(g_Query), "UPDATE `zp_players` SET `death` = `death` + 1, `level` = %d, `exp` = %d WHERE `id`=%d", zp_level(id), zp_exp(id), g_UserDBId[id])
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)

if (id == attacker || !is_user_connected(attacker))
{
type = 6
player = id
}
else if (zp_get_user_zombie(attacker))
{
if (zp_get_user_survivor(id))
type = 5
else
type = 3
if (!zp_get_user_nemesis(attacker))
{
format(g_Query, charsmax(g_Query), "INSERT INTO `zp_class_stats` (`id`, `id_player`, `kills`) VALUES(%d, %d, 1) ON DUPLICATE KEY UPDATE `kills` = `kills` + 1", zp_get_user_zombie_class(attacker), g_UserDBId[attacker])
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)
}
}
else
{
if (zp_get_user_nemesis(id))
type = 4
else
{
type = 2
format(g_Query, charsmax(g_Query), "INSERT INTO `zp_class_stats` (`id`, `id_player`, `death`) VALUES(%d, %d, 1) ON DUPLICATE KEY UPDATE `death` = `death` + 1", zp_get_user_zombie_class(id), g_UserDBId[id])
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)
}
}

if (type == 2 || type == 4)
g_Kills[attacker][g_Weapon[attacker]]++

format(g_Query, charsmax(g_Query), "UPDATE `zp_players` SET `%s` = `%s` + 1 WHERE `id`=%d", g_types[type], g_types[type], g_UserDBId[player])
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)
}

public fw_TakeDamage(victim, inflictor, attacker, Float:damage, damage_type)
{
if (victim == attacker || !is_user_alive(attacker) || !is_user_connected(victim))
return
if (zp_get_user_zombie(attacker) == zp_get_user_zombie(victim))
return

new victim_hp = get_user_health(victim)
if (victim_hp < 0)
victim_hp = 0
if (get_pcvar_num(g_CvarShowHit))
client_print(attacker, print_center, "%L", attacker, "HP_INDICATOR", victim_hp)

if (!zp_get_user_zombie(attacker) || (zp_get_user_survivor(attacker) && !get_pcvar_num(g_CvarSurvIgnoreRewards)))
{

g_damagedealt[attacker] += floatround(damage)
g_TotalDamage[attacker] += floatround(damage)

static ammodamage
ammodamage = get_pcvar_num(g_CvarDamageReward)

while (g_damagedealt[attacker] >= ammodamage)
{
g_UserTotalAmmo[attacker]++
g_damagedealt[attacker] -= ammodamage
}
}
}

public fw_CS_RoundRespawn(id)
{
reset_me_hp(id)
}

public reset_me_hp(id)
{
arrayset(g_Killers[id], 0, KILLER_NUM)
arrayset(g_Me[id], 0, ME_NUM)
}

public fw_TraceAttack(id, idattacker, Float:damage, Float:direction[3], traceresult, damagebits)
{
if (id == idattacker || !is_user_alive(idattacker) || !is_user_connected(id))
return
if (zp_get_user_zombie(idattacker) == zp_get_user_zombie(id))
return
if (is_user_alive(idattacker))
{
new hit = get_tr2(traceresult, TR_iHitgroup)
g_Hits[idattacker][g_Weapon[idattacker]][hit] ++
g_Me[idattacker][ME_DMG] += floatround(damage)
g_Me[idattacker][ME_HIT] = hit
}
}

public msgCurWeapon(msgid, dest, id)
{
if (get_msg_arg_int(1))
{
static wId, ammo
wId = get_msg_arg_int(2)
ammo = get_msg_arg_int(3)
g_Weapon[id] = wId
switch(wId)
{
case CSW_KNIFE:
{
g_OldWeapon[id] = wId
return PLUGIN_CONTINUE
}
case CSW_HEGRENADE, CSW_FLASHBANG, CSW_SMOKEGRENADE, CSW_C4:
return PLUGIN_CONTINUE
}
if (wId == g_OldWeapon[id] && g_OldAmmo[id] > ammo)
{
if (wId == CSW_XM1014)
g_Hits[id][wId][0]+=6
else if (wId == CSW_M3)
g_Hits[id][wId][0]+=9
else
g_Hits[id][wId][0]++
}
g_OldWeapon[id] = wId
g_OldAmmo[id] = ammo
}
return PLUGIN_CONTINUE
}

public handleSay(id)
{
new args[64]

read_args(args, charsmax(args))
remove_quotes(args)

new arg1[64]
new arg2[64]

strbreak(args, arg1, charsmax(arg1), arg2, charsmax(arg2))
if (get_pcvar_num(g_CvarAllowHp) && equal(arg1,"/hp"))
show_hp(id)
else if (get_pcvar_num(g_CvarAllowMe) && equal(arg1,"/me"))
show_me(id)
else if (equal(arg1,"/rank"))
show_rank(id,arg2)
else if (equal(arg1, "/rankstats") || equal(arg1, "/stats"))
show_stats(id, arg2)
else if (equal(arg1,"/top", 4))
{
if (arg1[4])
show_top(id, str_to_num(arg1[4]))
else
show_top(id, 15)
}
else if (equal(arg1,"/donate", 7) || equal(arg1,"donate",6))
donate(id, arg2)

if(equali(arg1, "deposit", 7) || equali(arg1, "withdraw", 8) || equali(arg1, "retrieve", 8) || equali(arg1, "bank", 4))
{
client_print(id, print_chat, "%L", id, "ADVERTISEMENT_SAVE");
}
}

public donate(id, arg[])
{
new to[64], count[64]
strbreak(arg, to, 63, count, 63)

if (!to[0] || !count[0])
{
client_print(id, print_chat, "%L", id, "DONATE_USAGE")
return
}
new ammo_sender = zp_get_user_ammo_packs(id)
new ammo
if (equal(count, "all"))
ammo = ammo_sender
else
ammo = str_to_num(count)
if (ammo <= 0)
{
client_print(id, print_chat, "%L", id, "INVALID_AMMO")
return
}
ammo_sender -= ammo
if (ammo_sender < 0)
{
ammo+=ammo_sender
ammo_sender = 0

}
new receiver = cmd_target(id, to, 8)

if (!receiver || receiver == id)
{
client_print(id, print_chat, "%L", id, "CLIENT_NOT_FOUND", to)
return
}

zp_set_user_ammo_packs(receiver, zp_get_user_ammo_packs(receiver) + ammo)
zp_set_user_ammo_packs(id, ammo_sender)

new aName[32], vName[32]
get_user_name(id, aName, 31)
get_user_name(receiver, vName, 31)

format(g_Query, charsmax(g_Query), "INSERT INTO `zp_donations` (`time`, `id_sender`, `id_receiver`, `ammo`) VALUES('%d', '%d', '%d', '%d')", get_systime(), g_UserDBId[id], g_UserDBId[receiver], ammo)
SQL_ThreadQuery(g_SQLTuple, "Error_QueryHandler", g_Query)

set_hudmessage(255, 0, 0, -1.0, 0.3, 0, 6.0, 6.0)
show_hudmessage(receiver, "%L", receiver, "DONATE_RECEIVER", aName, ammo)
show_hudmessage(id, "%L", id, "DONATE_SOURCE", ammo, vName)
}

public show_hp(id)
{
if (g_Killers[id][KILLER_ID])
{
new name[32]
get_user_name(g_Killers[id][KILLER_ID], name, 31)
client_print(id, print_chat, "%L", id, "HP_MESSAGE",
name, g_Killers[id][KILLER_HP],
g_Killers[id][KILLER_ARMOUR])
}
else
client_print(id, print_chat, "%L", id, "HP_NO_KILLER")
return PLUGIN_HANDLED
}

public show_me(id)
{
if (g_Me[id][ME_DMG] || g_Me[id][ME_KILLS] || g_Me[id][ME_INFECT])
{
new hit[32]
format(hit, 31, "%L", id, g_HitsName[g_Me[id][ME_HIT]])
client_print(id, print_chat, "%L", id, "ME_MESSAGE", g_Me[id][ME_INFECT], g_Me[id][ME_KILLS], g_Me[id][ME_DMG], hit)
}
else
client_print(id, print_chat, "%L", id, "HIT_NONE")
return PLUGIN_HANDLED
}

public show_rank(id, unquoted_whois[])
{

new whois[1024]
SQL_QuoteString(g_SQL_Connection , whois, 1023, unquoted_whois)

new total_ammo, infect
new death, rank, total

new name[32]

new activity = get_systime() - get_pcvar_num(g_CvarMaxInactive) * 24 * 60 * 60
new min_ammo = get_pcvar_num(g_CvarMinAmmo)

format(g_Query, charsmax(g_Query), "SET @_c = 0")
SQL_QueryAndIgnore(g_SQL_Connection, g_Query)

new Handle:query

if (!whois[0])
{

query = SQL_PrepareQuery(g_SQL_Connection, "SELECT *,(SELECT COUNT(*) FROM `zp_players` WHERE `last_join` > %d AND `total_ammo` >= %d) AS `total` FROM \
(SELECT *, (@_c := @_c + 1) AS `rank`, \
`total_ammo` AS `skill` \
FROM `zp_players` WHERE `last_join` > %d AND `total_ammo` >= %d \
ORDER BY `skill` DESC) AS `newtable` WHERE `id`='%d';",
activity, min_ammo, activity, min_ammo, g_UserDBId[id])
}
else
{

query = SQL_PrepareQuery(g_SQL_Connection, "SELECT *,(SELECT COUNT(*) FROM `zp_players` WHERE `last_join` > %d AND `total_ammo` >= %d) AS `total` FROM \
(SELECT *, (@_c := @_c + 1) AS `rank`, \
`total_ammo` AS `skill` \
FROM `zp_players` WHERE `last_join` > %d AND `total_ammo` >= %d ORDER BY `skill` DESC) AS `newtable` \
WHERE `nick` LIKE '%%%s%%' OR `ip` LIKE '%%%s%%' \
LIMIT 1",
activity, min_ammo, activity, min_ammo, whois, whois)
}
run_sql(query)

if (SQL_MoreResults(query))
{
total_ammo = SQL_ReadResult(query, column("total_ammo"))
SQL_ReadResult(query, column("nick"), name, 31)
infect = SQL_ReadResult(query, column("infect"))
death = SQL_ReadResult(query, column("death"))
rank = SQL_ReadResult(query, column("rank"))
total = SQL_ReadResult(query, column("total"))

client_print(id, print_chat, "%L", id, "RANK", name, rank, total, infect, death, total_ammo)
}
else
client_print(id, print_chat, "%L", id, "NOT_RANKED", whois)

SQL_FreeHandle(query)
return PLUGIN_HANDLED
}

public show_stats(id, unquoted_whois[])
{

new total_ammo, infect, zombiekills, nemkills, humankills, damage, online
new survkills, death, infected, rank, total, Float:skill, first_zombie, join, leave, suicide
new survivor, nemesis


new whois[1024]
SQL_QuoteString(g_SQL_Connection , whois, 1023, unquoted_whois)

new name[96], ip[32], steam_id[32]

new len

new join_str[32], leave_str[32], time_str[64]

new activity = get_systime() - get_pcvar_num(g_CvarMaxInactive) * 24 * 60 * 60
new min_ammo = get_pcvar_num(g_CvarMinAmmo)

new Handle:query = SQL_PrepareQuery(g_SQL_Connection, "SET @_c = 0")
run_sql(query)

if (!whois[0])
{

query = SQL_PrepareQuery(g_SQL_Connection, "SELECT *,(SELECT COUNT(*) FROM `zp_players` WHERE `last_join` > %d AND `total_ammo` >= %d) AS `total` FROM \
(SELECT *, (@_c := @_c + 1) AS `rank`, \
`total_ammo` AS `skill` \
FROM `zp_players` WHERE `last_join` > %d AND `total_ammo` >= %d \
ORDER BY `skill` DESC) AS `newtable` WHERE `id`='%d';",
activity, min_ammo, activity, min_ammo, g_UserDBId[id])
}
else
{

query = SQL_PrepareQuery(g_SQL_Connection, "SELECT *,(SELECT COUNT(*) FROM `zp_players` WHERE `last_join` > %d AND `total_ammo` >= %d) AS `total` FROM \
(SELECT *, (@_c := @_c + 1) AS `rank`, \
`total_ammo` AS `skill` \
FROM `zp_players` WHERE `last_join` > %d AND `total_ammo` >= %d ORDER BY `skill` DESC) AS `newtable` \
WHERE `nick` LIKE '%%%s%%' OR `ip` LIKE '%%%s%%' \
LIMIT 1",
activity, min_ammo, activity, min_ammo, whois, whois)
}
run_sql(query)

if (SQL_MoreResults(query))
{

total_ammo = SQL_ReadResult(query, column("total_ammo"))
SQL_ReadResult(query, column("nick"), name, 31)
SQL_ReadResult(query, column("ip"), ip, 31)
SQL_ReadResult(query, column("steam_id"), steam_id, 31)
damage = SQL_ReadResult(query, column("total_damage"))
join = SQL_ReadResult(query, column("last_join"))
leave = SQL_ReadResult(query, column("last_leave"))
first_zombie = SQL_ReadResult(query, column("first_zombie"))
infect = SQL_ReadResult(query, column("infect"))
zombiekills = SQL_ReadResult(query, column("zombiekills"))
humankills = SQL_ReadResult(query, column("humankills"))
nemkills = SQL_ReadResult(query, column("nemkills"))
survkills = SQL_ReadResult(query, column("survkills"))
suicide = SQL_ReadResult(query, column("suicide"))
death = SQL_ReadResult(query, column("death"))
infected = SQL_ReadResult(query, column("infected"))
online = SQL_ReadResult(query, column("online"))
survivor = SQL_ReadResult(query, column("survivor"))
nemesis = SQL_ReadResult(query, column("nemesis"))
rank = SQL_ReadResult(query, column("rank"))
SQL_ReadResult(query, column("skill"), skill)
total = SQL_ReadResult(query, column("total"))

replace_all(name, charsmax(name), ">", "gt;")
replace_all(name, charsmax(name), "<", "lt;")

new lStats[32]
format(lStats, 31, "%L", id, "STATS")
new lRank[32]
format(lRank, 31, "%L", id, "RANK_STATS")
new lInfect[32]
format(lInfect, 31, "%L", id, "INFECT_STATS")
new lZKills[32]
format(lZKills, 31, "%L", id, "ZKILLS_STATS")
new lHKills[32]
format(lHKills, 31, "%L", id, "HKILLS_STATS")
new lNKills[32]
format(lNKills, 31, "%L", id, "NKILLS_STATS")
new lSKills[32]
format(lSKills, 31, "%L", id, "SKILLS_STATS")
new lDeath[32]
format(lDeath, 31, "%L", id, "DEATH")
new lInfected[32]
format(lInfected, 31, "%L", id, "INFECTED")
new lTotalAmmo[32]
format(lTotalAmmo, 31, "%L", id, "TOTALAMMO")
new lTotalDamage[32]
format(lTotalDamage, 31, "%L", id, "TOTALDAMAGE")
new lFirstZombie[32]
format(lFirstZombie, 31, "%L", id, "FIRST_ZOMBIE")
new lSuicide[32]
format(lSuicide, 31, "%L", id, "SUICIDE")
new lLastGame[32]
format(lLastGame, 31, "%L", id, "LAST_GAME")
new lOnline[32]
format(lOnline, 31, "%L", id, "ONLINE")
new lSurvivor[32]
format(lSurvivor, 31, "%L", id, "SURVIVOR")
new lNemesis[32]
format(lNemesis, 31, "%L", id, "NEMESIS")

new max_len = charsmax(g_text)
len = format(g_text, max_len, "<html><head><meta http-equiv=^"Content-Type^" content=^"text/html; charset=utf-8^" /></head><body bgcolor=#000000>")
len += format(g_text[len], max_len - len, "%s %s:<table style=^"color: #FFB000^"><tr><td>%s</td><td>%d/%d</td></tr><tr><td>%s</td><td>%d</td>",
lStats, name, lRank, rank, total, lInfect, infect)
len += format(g_text[len], max_len - len, "<tr><td>%s</td><td>%d</td></tr><tr><td>%s</td><td>%d</td></tr>",
lZKills, zombiekills, lHKills, humankills)
len += format(g_text[len], max_len - len, "<tr><td>%s</td><td>%d</td></tr><tr><td>%s</td><td>%d</td></tr>",
lNKills, nemkills, lSKills, survkills)
len += format(g_text[len], max_len - len, "<tr><td>%s</td><td>%d</td></tr><tr><td>%s</td><td>%d</td></tr>",
lDeath, death, lInfected, infected)
len += format(g_text[len], max_len - len, "<tr><td>%s</td><td>%d</td></tr><tr><td>%s</td><td>%d</td></tr>",
lTotalAmmo, total_ammo, lTotalDamage, damage)
len += format(g_text[len], max_len - len, "<tr><td>%s</td><td>%d</td></tr><tr><td>%s</td><td>%d</td></tr>",
lFirstZombie, first_zombie, lSuicide, suicide)

format_time(join_str, 32, "%c", join)
format_time(leave_str, 32, "%c", leave)
len += format(g_text[len], max_len - len, "<tr><td>%s</td><td>%s - %s</td></tr>",
lLastGame, join_str, leave_str)


get_time_length(0, online, timeunit_seconds, time_str, 63)
len += format(g_text[len], max_len - len, "<tr><td>%s</td><td>%s</td></tr>",
lOnline, time_str)

len += format(g_text[len], max_len - len, "<tr><td>%s</td><td>%s</td></tr><tr><td>%s</td><td>%s</td></tr>",
"IP", ip, "Steam ID", steam_id)

len += format(g_text[len], max_len - len, "<tr><td>%s</td><td>%d</td></tr><tr><td>%s</td><td>%d</td></tr>",
lSurvivor, survivor, lNemesis, nemesis)

len += format(g_text[len], max_len - len, "</table></body></html>")

show_motd(id, g_text, "Stats")

setc(g_text, max_len, 0)
}
else
client_print(id, print_chat, "%L", id, "NOT_RANKED", whois)

SQL_FreeHandle(query)
return PLUGIN_HANDLED
}

public show_top(id, top)
{
new count, Handle:query
new len

new zombiekills, humankills, death, infected, infect, total_ammo, name[32], rank

new activity = get_systime() - get_pcvar_num(g_CvarMaxInactive) * 24 * 60 * 60
new min_ammo = get_pcvar_num(g_CvarMinAmmo)

new max_len = charsmax(g_text)

query = SQL_PrepareQuery(g_SQL_Connection, "SELECT COUNT(*) FROM `zp_players` WHERE `last_join` > %d", activity)
run_sql(query)
if(SQL_MoreResults(query))
count = SQL_ReadResult(query, 0)
else
{
client_print(id, print_chat, "%L", id, "STATS_NULL")
return PLUGIN_HANDLED
}

new lTop[32]
format(lTop, 31, "%L", id, "TOP")

new lLooserTop[32]
format(lLooserTop, 31, "%L", id, "TOP_LOOSERS")

new title[32]
if (top <= 15)
format(title, 31, "%s %d", lTop, top)
else if (top < count)
format(title, 31, "%s %d - %d", lTop, top - 14, top)
else
{
top = count
format(title, 31, "%s", lLooserTop)
}

query = SQL_PrepareQuery(g_SQL_Connection, "SET @_c = 0")
run_sql(query)

query = SQL_PrepareQuery(g_SQL_Connection, "SELECT `nick`, `zombiekills`, `humankills`, \
`infect`, `death`, `infected`, `total_ammo`, `rank` FROM \
(SELECT *, (@_c := @_c + 1) AS `rank`, \
`total_ammo` AS `skill` \
FROM `zp_players` WHERE `last_join` > %d AND `total_ammo` >= %d \
ORDER BY `skill` DESC) AS `newtable` WHERE `rank` <= '%d' ORDER BY `rank` DESC LIMIT 15",
activity, min_ammo, top)
run_sql(query)

while (SQL_MoreResults(query))
{
SQL_ReadResult(query, column("nick"), name, 31)
zombiekills = SQL_ReadResult(query, column("zombiekills"))
humankills = SQL_ReadResult(query, column("humankills"))
infect = SQL_ReadResult(query, column("infect"))
death = SQL_ReadResult(query, column("death"))
infected = SQL_ReadResult(query, column("infected"))
total_ammo = SQL_ReadResult(query, column("total_ammo"))
rank = SQL_ReadResult(query, column("rank"))

format(g_text, max_len, "<tr><td>%d<td>%s<td>%d<td>%d<td>%d<td>%d<td>%d<td>%d%s",
rank, name, zombiekills, humankills, infect, death, infected, total_ammo, g_text)

SQL_NextRow(query)
}

SQL_FreeHandle(query)

new lInfect[32]
format(lInfect, 31, "%L", id, "INFECT_STATS")
new lZKills[32]
format(lZKills, 31, "%L", id, "ZKILLS_STATS")
new lHKills[32]
format(lHKills, 31, "%L", id, "HKILLS_STATS")
new lDeath[32]
format(lDeath, 31, "%L", id, "DEATH")
new lInfected[32]
format(lInfected, 31, "%L", id, "INFECTED")
new lTotalAmmo[32]
format(lTotalAmmo, 31, "%L", id, "TOTALAMMO")
new lNick[32]
format(lNick, 31, "%L", id, "NICK")

len = format(g_text, max_len, "<html><head><meta http-equiv=^"Content-Type^" content=^"text/html; charset=utf-8^" /></head><body bgcolor=#000000><table style=^"color: #FFB000^"><tr><td>%s<td>%s<td>%s<td>%s<td>%s<td>%s<td>%s<td>%s%s","#", lNick, lZKills, lHKills, lInfect, lDeath, lInfected, lTotalAmmo, g_text)
format(g_text[len], max_len - len, "</table></body></html>")

show_motd(id, g_text, title)

setc(g_text, max_len, 0)
return PLUGIN_HANDLED
}

/* Zombie Plague */
public load_classes_from_file()
{
new Array:g_zclass2_realname = ArrayCreate(64, 1)
new Array:g_zclass2_name = ArrayCreate(64, 1)
new Array:g_zclass2_info = ArrayCreate(64, 1)
new Array:g_zclass2_hp = ArrayCreate(1, 1)
new Array:g_zclass2_spd = ArrayCreate(1, 1)
new Array:g_zclass2_grav = ArrayCreate(1, 1)
new Array:g_zclass2_kb = ArrayCreate(1, 1)

new const ZP_ZOMBIECLASSES_FILE[] = "zp_zombieclasses.ini"

new path[64]
new linedata[2024], key[64], value[960]
new file

// Build zombie classes file path
get_configsdir(path, charsmax(path))
format(path, charsmax(path), "%s/%s", path, ZP_ZOMBIECLASSES_FILE)

// Parse if present
if (! file_exists(path))
{
log_amx("%L",LANG_SERVER, "ZP_ZOMBIECLASSES_FILE_NOT_FOUND", ZP_ZOMBIECLASSES_FILE)
return
}
// Open zombie classes file for reading
file = fopen(path, "rt")

while (file && !feof(file))
{
// Read one line at a time
fgets(file, linedata, charsmax(linedata))

// Replace newlines with a null character to prevent headaches
replace(linedata, charsmax(linedata), "^n", "")

// Blank line or comment
if (!linedata[0] || linedata[0] == ';') continue;

// New class starting
if (linedata[0] == '[')
{
// Remove first and last characters (braces)
linedata[strlen(linedata) - 1] = 0
copy(linedata, charsmax(linedata), linedata[1])

// Store its real name for future reference
ArrayPushString(g_zclass2_realname, linedata)
continue;
}

// Get key and value(s)
strtok(linedata, key, charsmax(key), value, charsmax(value), '=')

// Trim spaces
trim(key)
trim(value)
new quoted_value[1024]
SQL_QuoteString(g_SQL_Connection , quoted_value, charsmax(quoted_value), value)
if (equal(key, "NAME"))
ArrayPushString(g_zclass2_name, quoted_value)
else if (equal(key, "INFO"))
ArrayPushString(g_zclass2_info, quoted_value)
else if (equal(key, "HEALTH"))
ArrayPushCell(g_zclass2_hp, str_to_num(quoted_value))
else if (equal(key, "SPEED"))
ArrayPushCell(g_zclass2_spd, str_to_num(quoted_value))
else if (equal(key, "GRAVITY"))
ArrayPushCell(g_zclass2_grav, str_to_float(quoted_value))
else if (equal(key, "KNOCKBACK"))
ArrayPushCell(g_zclass2_kb, str_to_float(quoted_value))
}
if (file) fclose(file)
new sql[4096]
new len
len = format(sql, charsmax(sql), "INSERT INTO `zp_classes` VALUES")
new i, size = ArraySize(g_zclass2_realname)
for (i = 0; i < size; i++)
{
len+=format(sql[len], charsmax(sql) - len, " (%d, '%a', '%a', %d, %d, '%2.2f', '%2.2f'),",
i, ArrayGetStringHandle(g_zclass2_name, i),
ArrayGetStringHandle(g_zclass2_info, i),
ArrayGetCell(g_zclass2_hp, i), ArrayGetCell(g_zclass2_spd, i),
Float:ArrayGetCell(g_zclass2_grav, i),
Float:ArrayGetCell(g_zclass2_kb, i))
}
sql[--len] = 0
SQL_QueryAndIgnore(g_SQL_Connection, "DELETE FROM `zp_classes`")

new Handle:query = SQL_PrepareQuery(g_SQL_Connection, sql)
run_sql(query)

SQL_FreeHandle(query)
}

public run_sql(Handle:query)
{
//log_query(query)
if(!SQL_Execute(query))
{
new error[3096]
new errnum = SQL_QueryError(query, error, charsmax(error))
log_to_file("sql-error.log", "Error code: %d Sql: %s", errnum, error)
}
}

public log_query(Handle:query)
{
new log[3096]
SQL_GetQueryString(query, log, 3095)
log_to_file("sql.log", log)
}

/**
* Handler for when a threaded query is resolved. Only checks for errors and log it
*/
public Error_QueryHandler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime)
{
if (!failstate)
return

log_to_file("sql-error.log", "Error code: %d Sql: %s", errnum, error)

new querystring[3096]
SQL_GetQueryString(query, querystring, charsmax(querystring))
log_to_file("sql-error.log"," --> Original query was: %s", querystring)
}

// ================ For Admins ================

public admin_check(args[])
{
new id = args[0]
if(!is_user_connected(id))
return

format(g_Query, charsmax(g_Query), "SELECT is_admin('%d') as permissions", g_UserDBId[id])
SQL_ThreadQuery(g_SQLTuple, "AdminCheck_QueryHandler", g_Query, args, 1)
}

public AdminCheck_QueryHandler(FailState, Handle:query, error[], errnum, data[], size, Float:queuetime)
{
if(FailState != TQUERY_SUCCESS)
return

new permissions[40]
SQL_ReadResult(query, column("permissions"), permissions, charsmax(permissions))
if(!strcmp(permissions, "Not Admin"))
return

new id = data[0]
if(!is_user_connected(id))
return
new flags = read_flags(permissions)
remove_user_flags(id)
set_user_flags(id,flags)
log_to_file("admin_enter.log", "%d granted with %s", g_UserDBId[id], permissions)
}

stock ChatColor(const id, const input[], any:...)
{
new count = 1, players[32], msg[191], i;
vformat(msg, 190, input, 3)
replace_all(msg, 190, "!g", "^4")
replace_all(msg, 190, "!y", "^1")
replace_all(msg, 190, "!team", "^3")
if (id) players[0] = id; else get_players(players, count, "ch")
{
for (i = 0; i < count; i++)
{
if (is_user_connected(players[i]))
{
message_begin(MSG_ONE_UNRELIABLE, get_user_msgid("SayText"), _, players[i]);
write_byte(players[i]);
write_string(msg);
message_end();
}
}
}
}




Контакты:
VK: Дмитрий Лазарев (приоритетнее)
Skype: dandyzp
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   Цитировать сообщение
Статус пользователя SISA
сообщение 2.3.2017, 17:13
Сообщение #2
Стаж: 15 лет

Сообщений: 2774
Благодарностей: 2956
Полезность: 994

Цитата(x1DD @ 2.3.2017, 1:46) *
SISA,
Has users playing
[attachment=43671:1.jpg]
[attachment=43672:2.jpg]


Её не оптимизировать. Там надо половину кода переписывать, на асинхронные запросы в первую очередь.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя DANDY
сообщение 2.3.2017, 17:14
Сообщение #3
Стаж: 15 лет

Сообщений: 270
Благодарностей: 38
Полезность: 120

SISA,
А чем плохи асинхронные запросы?
Вы этим заняться можете?
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя SISA
сообщение 2.3.2017, 17:25
Сообщение #4
Стаж: 15 лет

Сообщений: 2774
Благодарностей: 2956
Полезность: 994

Цитата(DANDY @ 2.3.2017, 19:14) *
SISA,
А чем плохи асинхронные запросы?
Вы этим заняться можете?


Я не говорил, что они плохи. Как раз на них там и надо всё переписать.

Где-то была тема по написанию плагинов под заказа, там как раз статистику писали заказчику. Вот там и спросите, сколько такая работа стоит и возможна ли она.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя DANDY
сообщение 2.3.2017, 17:30
Сообщение #5
Стаж: 15 лет

Сообщений: 270
Благодарностей: 38
Полезность: 120

SISA, Понял, спасибо за информацию.
Но все же, не мог бы ты объяснить, раз они не так плохи, и всё на них там, почему переписать все надо? После переписывания плагина может увеличиться быстродействие серверов?
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя ssx
сообщение 2.3.2017, 17:35
Сообщение #6


Стаж: 12 лет

Сообщений: 2237
Благодарностей: 1343
Полезность: 836

Цитата(DANDY @ 2.3.2017, 17:30) *
SISA, Понял, спасибо за информацию.
Но все же, не мог бы ты объяснить, раз они не так плохи, и всё на них там, почему переписать все надо? После переписывания плагина может увеличиться быстродействие серверов?

Обычные запросы = сервер ждет ответа , как придет ответ - продолжит работу. Если БД далеко или тупит, будут лаги.
Асинхронные запросы = сервер не ждет ответа.


[Half-Life DM FFA] 78.152.169.100:27016
[CS 1.6 GunGame] 78.152.169.100:27018
[CS 1.6 DM AIM] 78.152.169.100:27017
[CS 1.6 DM FFA] 78.152.169.100:27015
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя SISA
сообщение 2.3.2017, 17:51
Сообщение #7
Стаж: 15 лет

Сообщений: 2774
Благодарностей: 2956
Полезность: 994

Цитата
Если БД далеко или тупит, будут лаги.


Не совсем так. БД может быть на одной машине с сервером, но при большом количестве записей в таблице, всё равно фриз получишь. На HDD большой, на SSD поменьше. Надо вообще убрать эти бестолковые синхронные запросы их АМХ, а то многие лентяги, при написании плагинов, любят их пихать в код, а потом ещё и продают его crazy.gif

Эта стата от Романова фризит абсолютно все сервера, когда БД разрастается.

Отредактировал: SISA, - 2.3.2017, 17:53
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя [WPMG]PRoSToTeM@
сообщение 2.3.2017, 20:10
Сообщение #8
Стаж: 13 лет

Сообщений: 1514
Благодарностей: 1025
Полезность: 725

Асинхрон сложнее в реализации, необходимо запоминать контекст, вызываться с задержкой, что порой довольно сложно и неприятно может быть на павне. Также надо продумывать ситуации в случае, если данных нет к какому-то моменту или они вовсе не идут, что в свою очередь может создать различные побочные эффекты, потери данных. С синхронным кодом всё красиво и на месте. На HLDS и тем более на павне нельзя писать асинхронный код в синхронном виде, что очень печально. Да и на C++ без корутин особо не попишешь такой код.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
Поблагодарили 1 раз
   + Цитировать сообщение
Статус пользователя GetA
сообщение 2.3.2017, 20:28
Сообщение #9
Стаж: 9 лет 8 месяцев

Сообщений: 812
Благодарностей: 189
Полезность: 123

bigdata.ckcorp.ru
Цитата(SISA @ 2.3.2017, 17:51) *
БД может быть на одной машине с сервером, но при большом количестве записей в таблице, всё равно фриз получишь. На HDD большой, на SSD поменьше.

Не совсем прозрачно.
Всё упирается в IOPS?

Отредактировал: GetA, - 2.3.2017, 20:29
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
Статус пользователя SISA
сообщение 2.3.2017, 20:33
Сообщение #10
Стаж: 15 лет

Сообщений: 2774
Благодарностей: 2956
Полезность: 994

GetA,

Сложно сказать, во что оно упирается. Оно может упираться в сам мьюскул модуль, который на амх реализован крайне посредственно.

Цитата([WPMG]PRoSToTeM@ @ 2.3.2017, 22:10) *

Асинхрон сложнее в реализации, необходимо запоминать контекст, вызываться с задержкой, что порой довольно сложно и неприятно может быть на павне. Также надо продумывать ситуации в случае, если данных нет к какому-то моменту или они вовсе не идут, что в свою очередь может создать различные побочные эффекты, потери данных. С синхронным кодом всё красиво и на месте. На HLDS и тем более на павне нельзя писать асинхронный код в синхронном виде, что очень печально. Да и на C++ без корутин особо не попишешь такой код.


Нормально всё там. У асинхронного есть массив для передачи. С тасками же работают и ничего сложного. Асинхронный запрос, тот же таск.
Перейти в начало страницы         Просмотр профиля    Отправить личное сообщение
   + Цитировать сообщение
  Ответить в данную темуНачать новую тему
 
0 пользователей и 1 гостей читают эту тему: