nVault; Премахване на проверка за парола

В този раздел можете да подавате всякакви заявки за намиране, изработка или преработка на плъгини/модове.
Отговори
Потребителски аватар

Автор на темата
LayerFort DJBosma
Потребител
Потребител
Мнения: 50
Регистриран: 25 дек 2018, 04:14
Местоположение: Alkmaar
Се отблагодари: 2 пъти
Получена благодарност: 2 пъти
Години: 24
Контакти:

nVault; Премахване на проверка за парола

Мнение от LayerFort DJBosma » 12 фев 2019, 15:03

Здравейте,

1. Това което желая е да се премахне проверката за паролата, да няма регистрация, нито командата /login; от плъгин 1.
2. При възможнност, начина по който CHANGE_NAME от плъгин 2, прехвърля статистиките на новия ник, да се интегрира в плъгин 1.
3. Да се създадът natives за ранковете в плъгин 1; от примерният CUSTOM_CHAT в плъгин 2



Плъгин 1;

Код: Избери всички

#include <amxmodx>
#include <hamsandwich>
#include <nvault_util>
#include <fakemeta>
#include <engine>
#include <geoip>
#include <zombieplague>


new const szRanks[][] = 
{
    "Guardsman",
    "Healer",
    "Protector",
    "Warrior",
    "High Warrior",
    "Alpha Warrior",
    "Archwarrior",
    "High Archwarrior",
    "Alpha Archwarrior",
    "Destroyer",
    "High Destroyer",
    "Alpha Destroyer",
    "Commander",
    "High Commander",
    "Alpha Commander",
    "Baron",
    "High Baron",
    "Alpha Baron",
    "King",
    "Alpha King",
    "Overlord",
    "Hacker"
}

new const iEXP[] = 
{
    0,
    50,
    100,
    200,
    250,
    300,
    350,
    400,
    450,
    500,
    600,
    700,
    700,
    800,
    900,
    1100,
    1250,
    1500,
    2000,
    2500,
    3000,
    999999999
}

enum _:Player_Data
{
	Data_Steamid[35],
	Data_Name[32],
	Data_Exp,
	Data_Kills,
	Data_Deaths,
	Data_HeadShot,
	Data_Knife,
	Data_Nade,
	Data_NemKills,
	Data_SurKills,
	Data_PlayTime,
	Data_Level,
	Data_Country[46],
	Data_Rank,
	Data_Password[20],
	MAX_PLAYER_DATA
}

enum _:Forward_Data
{
	Forward_Login,
	Forward_Levelup,
	Forward_Exp_Add,
	Forward_Exp_Set,
	Forward_Result,
	MAX_FORWARD_DATA
}

new iVaultHandle, gData[33][MAX_PLAYER_DATA], iHudStats, Float:fLastHud[33], szMotd[1536], gForward[MAX_FORWARD_DATA], Float:fLastCmd, iTotalEntries, iMsgSayText
const iExpKill = 1
const iExpHeadShot = 3
const iExpKnife = 4
const iExpGrenade = 4
const iExpNemKill = 5
const iExpSurKill = 5
const Float:HUD_STATS_X = 0.77//-1.0
const Float:HUD_STATS_Y = 0.6//0.8
new const szVaultName[] = "uservault_fterzp31231"

#define is_user_valid(%0) (0<%0<33)
new cvar_ammopacks
new g_maxplayers

new Ammopacks[22] = {
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9,
    10,
    11,
    12,
    13,
    14,
    15,
    16,
    17,
    18,
    19,
    20,
    21,
    0
}

//Uncomment this to update motd.txt on map loaded to show global top-10 players.
#define UPDATE_MOTD

//Uncomment this to enable nvault prune.
#define PRUNE_DATABASE

#if defined UPDATE_MOTD
new const szFileMotd[] = "motd.txt"
#endif

#if defined PRUNE_DATABASE
const iExpiredDays = 30
#endif

////////////////////Register System Here/////////////////////
const RG_MAX_PASS_LENGTH = 9
const RG_MIN_PASS_LENGTH = 3
const RG_MAX_LOGIN_TIME = 240
const TASK_HUD_REGISTER = 45037
const PData_Safe = 2
const m_iMenu = 205
new const Team_Select[] = "#Team_Select"
new const szInfoName[] = "name"
new iHudLogin, iHudLogin2, bool:bIsRegistered[33], bool:bIsLogin[33], iCountdown[33]
/////////////////////////////////////////////////////////////

public plugin_natives()
{
	register_native("xp_get_user_exp","_get_user_exp",1)
	register_native("xp_set_user_exp","_set_user_exp",1)
	
	register_native("xp_get_user_playtime","_get_user_playtime",1)
	register_native("xp_set_user_playtime","_set_user_playtime",1)
	
	register_native("xp_get_user_level","_get_user_level",1)
	register_native("xp_set_user_level","_set_user_level",1)
	
	register_native("xp_get_user_deaths","_get_user_deaths",1)
	register_native("xp_set_user_deaths","_set_user_deaths",1)
	
	register_native("xp_get_user_frags","_get_user_frags",1)
	register_native("xp_set_user_frags","_set_user_frags",1)
	
	register_native("xp_get_user_headshot","_get_user_headshot",1)
	register_native("xp_set_user_headshot","_set_user_headshot",1)
	
	register_native("xp_get_user_knife","_get_user_knife",1)
	register_native("xp_set_user_knife","_set_user_knife",1)
	
	register_native("xp_get_user_nade","_get_user_nade",1)
	register_native("xp_set_user_nade","_set_user_nade",1)
	
	register_native("xp_get_user_nemesis","_get_user_nemesis",1)
	register_native("xp_set_user_nemesis","_set_user_nemesis",1)
	
	register_native("xp_get_user_survivor","_get_user_survivor",1)
	register_native("xp_set_user_survivor","_set_user_survivor",1)
	
	register_native("xp_reset_user_data","_reset_user_data",1)
	register_native("xp_get_user_rank","_get_user_rank",1)
	register_native("xp_check_user_level","CheckPlayerLevel",1)
	
	register_native("xp_is_user_registered","_is_user_registered",1)
	register_native("xp_is_user_login","_is_user_login",1)
}

public plugin_init()
{
	new const PLUGIN_VERSION[] = "0.0.5"
	new const CVAR_EXP_VERSION[] = "n4d_zpstats"
	register_plugin("[ZP] Addon: UserVault", PLUGIN_VERSION, "PLUGIN_AUTHOR") //last update: 28.April.2015 12:14PM - wbyokomo
	
	iHudStats = CreateHudSyncObj()
	iHudLogin = CreateHudSyncObj()
	iHudLogin2 = CreateHudSyncObj()
	iMsgSayText = get_user_msgid("SayText")
	
	register_event("HLTV", "event_newround", "a", "1=0", "2=0")
	register_event("DeathMsg", "OnDeathMsg", "a") //use deathmsg easy to trace weapon and hitplace
	
	register_message(get_user_msgid("ShowMenu"), "OnShowMenu") //register system
	register_message(get_user_msgid("VGUIMenu"), "OnVGUIMenu") //register system
	
	register_forward(FM_ClientUserInfoChanged, "OnClientUserInfoChanged") //register system
	
	RegisterHam(Ham_Player_PreThink, "player", "OnPlayerPreThink") //no need for csbot
	
	register_clcmd("say", "CmdLogin") //register system
	register_clcmd("say /showpass", "CmdMyPassword")
	register_clcmd("say /stats" , "CmdStats")
	register_clcmd("say /rank", "CmdShowRank")
	register_clcmd("say /top15", "CmdTopExpGlobal")
	register_clcmd("say /top10", "CmdTopExpGlobal")
	register_clcmd("say /toponline", "CmdTopExpOnline")
	
	register_clcmd("say_team", "CmdLogin") //register system
	register_clcmd("say_team /showpass", "CmdMyPassword")
	register_clcmd("say_team /stats" , "CmdStats")
	register_clcmd("say_team /rank", "CmdShowRank")
	register_clcmd("say_team /top15", "CmdTopExpGlobal")
	register_clcmd("say_team /top10", "CmdTopExpGlobal")
	register_clcmd("say_team /toponline", "CmdTopExpOnline")
	
	//register_clcmd("chooseteam", "CmdJoinTeam") //block join team
	//register_clcmd("jointeam", "CmdJoinTeam") //block join team
	cvar_ammopacks = register_cvar("xp_ammopacks_reward", "1")
	g_maxplayers = get_maxplayers()
	
	gForward[Forward_Login] = CreateMultiForward("xp_user_login", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL) //xp_user_login(player, level, exp)
	gForward[Forward_Levelup] = CreateMultiForward("xp_user_levelup", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL) //xp_user_levelup(player, level, exp)
	gForward[Forward_Exp_Add] = CreateMultiForward("xp_user_expadd", ET_CONTINUE, FP_CELL, FP_CELL) //xp_user_expadd(player, expadd)
	gForward[Forward_Exp_Set] = CreateMultiForward("xp_user_expset", ET_CONTINUE, FP_CELL, FP_CELL) //xp_user_expset(player, exptotal)
	
	register_cvar(CVAR_EXP_VERSION, PLUGIN_VERSION, FCVAR_SERVER|FCVAR_SPONLY)
	set_cvar_string(CVAR_EXP_VERSION, PLUGIN_VERSION)
}

public event_newround()
{
	new id;
	for(id = 1; id<= g_maxplayers; id++)
		if(is_user_valid(id) && is_user_alive(id) && is_user_connected(id) && !zp_get_user_zombie(id)
		&& !zp_get_user_nemesis(id) && !zp_get_user_survivor(id))
			reward_user(id, 1)
}

public fw_spawn_post(id)
{
	if(zp_get_user_zombie(id) || zp_get_user_survivor(id) || zp_get_user_nemesis(id)
	|| !is_user_alive(id) || !is_user_connected(id) || !is_user_valid(id)) {return;}
	else
		reward_user(id, 0)
}

public zp_user_humanized_post(id)
	fw_spawn_post(id)

reward_user(id, roundstart)
{
	if(get_pcvar_num(cvar_ammopacks) == 1 && roundstart == 1){ reward_with_ammopacks(id);}
}

reward_with_ammopacks(id)
{
	new ap = Ammopacks[gData[id][Data_Level]]
	zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + ap)
	//client_print(id, print_chat, "You received %d ammmopacks from the server", ap)
	UTIL_ColorChat(id, "^x04[User Vault]^x01 You received:^x04 %d^x01 ammmopacks from the server", ap)
}

public plugin_cfg()
{
	iVaultHandle = nvault_open(szVaultName)
	
	if(iVaultHandle == INVALID_HANDLE)
	{
		new szText[128]; formatex(szText, 127, "Error opening nVault file [%s]", szVaultName);
		set_fail_state(szText)
	}
	else
	{
		server_print("Database [%s] successfully loaded...", szVaultName)
		
		#if defined PRUNE_DATABASE
		nvault_prune(iVaultHandle, 0, get_systime() - (86400 * iExpiredDays))
		#endif
		
		FormatGlobalTopTen()
		
		#if defined UPDATE_MOTD
		if(file_exists(szFileMotd))
		{
			if(delete_file(szFileMotd))
			{
				if(write_file(szFileMotd, szMotd, -1)) server_print("File [%s] has been updated...", szFileMotd);
			}
		}
		#endif
	}
	
}

public plugin_end()
{
	nvault_close(iVaultHandle)
}

public client_putinserver(id)
{
	if(is_user_hltv(id)) return;
	
	get_user_name(id, gData[id][Data_Name], 31)
	get_user_authid(id, gData[id][Data_Steamid], 34)
	
	if(is_user_bot(id))
	{
		//auto load data for bot
		LoadPlayerData(id)
		new szIp[32]; get_user_ip(id, szIp, 31, 1);
		geoip_country_ex(szIp, gData[id][Data_Country], 45)
		if(equali(gData[id][Data_Country],"error") || equali(gData[id][Data_Country],"")) copy(gData[id][Data_Country], 45, "Unknown");
		gData[id][Data_Rank] = -1
		//UTIL_ColorChat(0, "^x04%s^x01 Stage:^x04 %d^x01 Points:^x04 %d^x01 Country:^x04 %s^x01 CONNECTED.", gData[id][Data_Name], gData[id][Data_Level], gData[id][Data_Exp], gData[id][Data_Country])
		ExecuteForward(gForward[Forward_Login], gForward[Forward_Result], id, gData[id][Data_Level], gData[id][Data_Exp])
		bIsLogin[id] = true
	}
	else
	{
		//humans & force login
		iCountdown[id] = RG_MAX_LOGIN_TIME
		new szName[32], szKey[50], szData[164]
		copy(szName, 31, gData[id][Data_Name])
		replace_all(szName, 31, " ", "#")
		formatex(szKey, 49, "%s#Points", szName)
		
		//key was found, mean NAME already registered
		if(nvault_get(iVaultHandle, szKey, szData, 163))
		{
			new szExp[8], szKills[8], szDeaths[8], szHeadShot[8], szKnife[8], szNade[8], szNemKill[8], szSurKill[8], szPlayTime[8], szLevel[8], szName2[32], szPassword[20]
			parse(szData, szExp, 7, szKills, 7, szDeaths, 7, szHeadShot, 7, szKnife, 7, szNade, 7, szNemKill, 7, szSurKill, 7, szPlayTime, 7, szLevel, 7, szName2, 31, szPassword, 19)
			
			gData[id][Data_Exp] = str_to_num(szExp)
			gData[id][Data_Kills] = str_to_num(szKills)
			gData[id][Data_Deaths] = str_to_num(szDeaths)
			gData[id][Data_HeadShot] = str_to_num(szHeadShot)
			gData[id][Data_Knife] = str_to_num(szKnife)
			gData[id][Data_Nade] = str_to_num(szNade)
			gData[id][Data_NemKills] = str_to_num(szNemKill)
			gData[id][Data_SurKills] = str_to_num(szSurKill)
			gData[id][Data_PlayTime] = str_to_num(szPlayTime)
			gData[id][Data_Level] = str_to_num(szLevel)
			copy(gData[id][Data_Password], 19, szPassword)
			
			

			
			
			bIsRegistered[id] = true
		}
		else
		{
			bIsRegistered[id] = false
		}
		
		remove_task(id+TASK_HUD_REGISTER)
		set_task(1.0, "TaskLoopShowHudLogin", id+TASK_HUD_REGISTER, _, _, "b")
	}
}

public client_disconnected(id)
{
	if(bIsLogin[id])
	{
		gData[id][Data_PlayTime] += get_user_time(id)
		SavePlayerData(id)
		//UTIL_ColorChat(0, "^x04%s^x01 Stage:^x04 %d^x01 Points:^x04 %d^x01 Country:^x04 %s^x01 DISCONNECTED.", gData[id][Data_Name], gData[id][Data_Level], gData[id][Data_Exp], gData[id][Data_Country])
	}
	
	bIsRegistered[id] = false
	remove_task(id+TASK_HUD_REGISTER)
}

public OnClientUserInfoChanged(id)
{
	static szOldName[32], szNewName[32]
	pev(id, pev_netname, szOldName, charsmax(szOldName))
	if(szOldName[0])
	{
		get_user_info(id, szInfoName, szNewName, charsmax(szNewName))
		if(!equal(szOldName, szNewName))
		{
			copy(gData[id][Data_Name], 31, szOldName)
			set_user_info(id, szInfoName, gData[id][Data_Name])
			return FMRES_HANDLED;
		}
	}
	
	return FMRES_IGNORED;
}

public OnShowMenu(iMsgID, iDest, id)
{
	new szMenu[sizeof(Team_Select)]
	get_msg_arg_string(4, szMenu, charsmax(szMenu))
	if(!equal(szMenu, Team_Select)) return PLUGIN_CONTINUE;
	if(bIsLogin[id]) return PLUGIN_CONTINUE;
	
	if(pev_valid(id) == PData_Safe) set_pdata_int(id, m_iMenu, 0);
	
	return PLUGIN_HANDLED;
}

public OnVGUIMenu(iMsgID, iDest, id)
{
	if(get_msg_arg_int(1) != 2) return PLUGIN_CONTINUE;
	if(bIsLogin[id]) return PLUGIN_CONTINUE;
	
	return PLUGIN_HANDLED;
}

public CmdLogin(id, menu_msgid)
{
	if(!is_user_connected(id)) return PLUGIN_CONTINUE;
	
	if(!bIsLogin[id])
	{
		new text[81], arg1[12], arg2[32], arg3[5]
		read_args(text, charsmax(text))
		remove_quotes(text)
		arg1[0] = '^0' // /login
		arg2[0] = '^0' // PASSWORD
		arg3[0] = '^0'
		parse(text, arg1, charsmax(arg1), arg2, charsmax(arg2), arg3, charsmax(arg3))
		
		if(arg3[0] == 0)
		{
			if(equali(arg1,"/login"))
			{
				new iPassLen = strlen(arg2)
				if(iPassLen < RG_MIN_PASS_LENGTH)
				{
					UTIL_ColorChat(id, "^x04[UserVault]^x01 PASSWORD must contain MIN (^x04%d^x01) characters!", RG_MIN_PASS_LENGTH)
					return PLUGIN_HANDLED;
				}
				
				if(iPassLen > RG_MAX_PASS_LENGTH)
				{
					UTIL_ColorChat(id, "^x04[UserVault]^x01 PASSWORD must contain MAX (^x04%d^x01) characters!", RG_MAX_PASS_LENGTH)
					return PLUGIN_HANDLED;
				}
				
				//1st time login?
				if(!bIsRegistered[id])
				{
					copy(gData[id][Data_Password], 19, arg2)
					bIsLogin[id] = true
					remove_task(id+TASK_HUD_REGISTER)
					engclient_cmd(id, "chooseteam")
					new szIp[32]; get_user_ip(id, szIp, 31, 1);
					geoip_country_ex(szIp, gData[id][Data_Country], 45)
					if(equali(gData[id][Data_Country],"error") || equali(gData[id][Data_Country],"")) copy(gData[id][Data_Country], 45, "Unknown");
					gData[id][Data_Rank] = -1
					//UTIL_ColorChat(0, "^x04%s^x01 Stage:^x04 %d^x01 Points:^x04 %d^x01 Country:^x04 %s^x01 CONNECTED.", gData[id][Data_Name], gData[id][Data_Level], gData[id][Data_Exp], gData[id][Data_Country])
					log_to_file("uservault_password.log", "[UserVault REGISTRATION] USERNAME: %s | PASSWORD: %s", gData[id][Data_Name], gData[id][Data_Password]) //just in case if player forgot their own password.
					ExecuteForward(gForward[Forward_Login], gForward[Forward_Result], id, gData[id][Data_Level], gData[id][Data_Exp])
					set_task(random_float(8.0,16.0), "TaskShowInfoPassword", id+TASK_HUD_REGISTER)
					return PLUGIN_HANDLED;
				}
				
				//account registered & check password
				if(!equal(arg2, gData[id][Data_Password]))
				{
					UTIL_ColorChat(id, "^x04[UserVault]^x01 Your PASSWORD did not match, please try again.")
					return PLUGIN_HANDLED;
				}
				
				//ok login successful
				bIsLogin[id] = true
				remove_task(id+TASK_HUD_REGISTER)
				
				//static msg_block
				//msg_block = get_msg_block(menu_msgid)
				//set_msg_block(menu_msgid, BLOCK_SET)
					engclient_cmd(id, "jointeam", "5" );
					engclient_cmd(id, "joinclass", "5" );
					client_cmd_ex(id, "jointeam", "5" );
					client_cmd_ex(id, "joinclass", "5" );
					//set_msg_block(menu_msgid, msg_block)
					
				new szIp[32]; get_user_ip(id, szIp, 31, 1);
				geoip_country_ex(szIp, gData[id][Data_Country], 45)
				if(equali(gData[id][Data_Country],"error") || equali(gData[id][Data_Country],"")) copy(gData[id][Data_Country], 45, "Unknown");
				gData[id][Data_Rank] = -1
				//UTIL_ColorChat(0, "^x04%s^x01 Stage:^x04 %d^x01 Points:^x04 %d^x01 Country:^x04 %s^x01 CONNECTED.", gData[id][Data_Name], gData[id][Data_Level], gData[id][Data_Exp], gData[id][Data_Country])
				ExecuteForward(gForward[Forward_Login], gForward[Forward_Result], id, gData[id][Data_Level], gData[id][Data_Exp])
				set_task(random_float(8.0,16.0), "TaskShowInfoPassword", id+TASK_HUD_REGISTER)
				
				return PLUGIN_HANDLED;
			}
		}
		else
		{
			UTIL_ColorChat(id, "^x04[UserVault]^x01 Login/Register failed! PASSWORD must not contain any SPACE. Please try again.. E.g: /login PASSWORD")
		}
		
		return PLUGIN_HANDLED;
	}
	
	return PLUGIN_CONTINUE;
}

public CmdJoinTeam(id)
{
	if(is_user_connected(id) && !bIsLogin[id]) return PLUGIN_HANDLED;
	
	return PLUGIN_CONTINUE;
}

public CmdMyPassword(id)
{
	if(!is_user_connected(id)) return PLUGIN_HANDLED;
	
	if(!bIsLogin[id])
	{
		//client_print(id, print_chat, "Sorry! This command is not available at this time.")
		UTIL_ColorChat(id, "^x04[UserVault]^x01 Sorry! This command is not available at this time.")
		return PLUGIN_HANDLED;
	}
	
	UTIL_ColorChat(id, "^x04[UserVault]^x01 USERNAME:^x04 %s^x01 | PASSWORD:^x04 %s", gData[id][Data_Name], gData[id][Data_Password])
	
	return PLUGIN_HANDLED;
}

public CmdStats(id)
{
	if(!is_user_connected(id)) return PLUGIN_HANDLED;
	
	if(!bIsLogin[id])
	{
		//client_print(id, print_chat, "Sorry! failed to load your stats. Please rejoin the server :)")
		UTIL_ColorChat(id, "^x04[UserVault]^x01 Sorry! failed to load your stats. Please rejoin the server!")
		return PLUGIN_HANDLED;
	}
	
	new menu = menu_create("\yPlayer Stats:", "PlayerStatsMenuHandler")
	new szUserId[32], iPlayers[32], iNum, j, id2, szName[32]
	get_players(iPlayers, iNum, "h")
	for(j=0;j<iNum;j++)
	{
		id2 = iPlayers[j]
		get_user_name(id2, szName, 31)
		formatex(szUserId, 31, "%d", get_user_userid(id2))
		menu_additem(menu, szName, szUserId, 0)
	}
	
	menu_display(id, menu, 0)
	
	return PLUGIN_HANDLED;
}

public PlayerStatsMenuHandler(id, menu, item)
{
	if(!is_user_connected(id))
	{
		menu_destroy(menu)
		return PLUGIN_HANDLED;
	}
	
	if(item == MENU_EXIT)
	{
		menu_destroy(menu)
		return PLUGIN_HANDLED;
	}
	
	new szData[6], szName[64]
	new _access, item_callback
	menu_item_getinfo(menu, item, _access, szData, 5, szName, 63, item_callback)
	
	new userid = str_to_num(szData)
	new player = find_player("k", userid)
	
	if(player && is_user_connected(player))
	{
		GetPlayerStats(player, id)
	}
	
	menu_destroy(menu)
	return PLUGIN_HANDLED;
}

public CmdShowRank(id)
{
	if(!is_user_connected(id)) return PLUGIN_HANDLED;
	
	if(!bIsLogin[id])
	{
		//client_print(id, print_chat, "Sorry! failed to load your stats. Please rejoin the server :)")
		UTIL_ColorChat(id, "^x04[UserVault]^x01 Sorry! failed to load your stats. Please rejoin the server!")
		return PLUGIN_HANDLED;
	}
	
	static Float:ctime; ctime = get_gametime();
	if(fLastCmd > ctime)
	{
		//client_print(id, print_chat, "System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		UTIL_ColorChat(id, "^x04[UserVault]^x01 System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		return PLUGIN_HANDLED;
	}
	
	fLastCmd = ctime+2.0
	new iRank = SortPlayerRank(id)
	if(iRank == -1) UTIL_ColorChat(id, "^x04[UserVault]^x01 Your rank is not been saved yet, please rejoin the server.") //client_print(id, print_chat, "Your rank is not been saved yet, please rejoin the server.");
	else UTIL_ColorChat(id, "^x04%s^x01 rank is^x04 %d^x01/^x04%d^x01 -- Kills:^x04 %d^x01 Deaths:^x04 %d^x01 Stage:^x04 %d^x01 Points:^x04 %d^x01/^x04%d", gData[id][Data_Name], iRank, iTotalEntries, gData[id][Data_Kills], gData[id][Data_Deaths], gData[id][Data_Level], gData[id][Data_Exp], iEXP[gData[id][Data_Level]+1])
	
	return PLUGIN_HANDLED;
}

public CmdTopExpGlobal(id)
{
	if(!is_user_connected(id)) return PLUGIN_HANDLED;
	
	if(!bIsLogin[id])
	{
		//client_print(id, print_chat, "Sorry! failed to load your stats. Please rejoin the server :)")
		UTIL_ColorChat(id, "^x04[UserVault]^x01 Sorry! failed to load your stats. Please rejoin the server!")
		return PLUGIN_HANDLED;
	}
	
	static Float:ctime; ctime = get_gametime();
	if(fLastCmd > ctime)
	{
		//client_print(id, print_chat, "System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		UTIL_ColorChat(id, "^x04[UserVault]^x01 System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		return PLUGIN_HANDLED;
	}
	
	fLastCmd = ctime+2.0
	show_motd(id, szMotd, "TOP-10 Players (GLOBAL)")
	
	return PLUGIN_HANDLED;
}

public CmdTopExpOnline(id)
{
	if(!is_user_connected(id)) return PLUGIN_HANDLED;
	
	if(!bIsLogin[id])
	{
		UTIL_ColorChat(id, "^x04[UserVault]^x01 Sorry! failed to load your stats. Please rejoin the server!")
		return PLUGIN_HANDLED;
	}
	
	static Float:ctime; ctime = get_gametime();
	if(fLastCmd > ctime)
	{
		UTIL_ColorChat(id, "^x04[UserVault]^x01 System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		return PLUGIN_HANDLED;
	}
	
	fLastCmd = ctime+2.0
	static Sort[33][2]
	new players[32], num, count, index
	get_players(players, num)
	
	for(new i = 0; i < num; i++)
	{
		index = players[i]
		Sort[count][0] = index
		Sort[count][1] = gData[index][Data_Exp]
		count++
	}
	
	SortCustom2D(Sort, count, "CompareEXP")
	
	new y = clamp(count, 0, 10)
	new kindex, szMotd2[1536], len
	szMotd2[0] = 0
	
	add(szMotd2, charsmax(szMotd2),
	"<html><style>\
	body{background:url('https://static.brusheezy.com/system/resources/previews/000/013/939/non_2x/grunge-texture-by-krist-photoshop-textures.jpg') repeat;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
	.t{color:#afafaf;text-align:left; }\
	#h{background: #333;border-style: solid;border-width: 1px;border-color: #999;color:#E0E0E0;font-weight:bold;}\
	#p{color:#D41313;}\
	#n{color:#fff;}\
	</style><body>\
	<table cellspacing=0 width=100% class=t>")
	
	add(szMotd2, charsmax(szMotd2),
	"<tr><td id=h width=7%>#</td>\
	<td id=h>Name</td>\
	<td id=h>Points</td>\
	<td id=h>Kills</td>\
	<td id=h>Deaths</td>\
	<td id=h>Online</td></tr>")
	
	len = strlen(szMotd2)
	
	for(new x = 0; x < y; x++)
	{
		kindex = Sort[x][0]
		new iSec, szTimeFormat[32], szName[32]
		iSec = get_user_time(kindex)+gData[kindex][Data_PlayTime]
		GetTimeFormat(iSec, szTimeFormat, 31)
		get_user_name(kindex, szName, 31)
		replace_all(szName, 31, "#", " ")
		replace_all(szName, 31, "<", "&lt")
		replace_all(szName, 31, ">", "&gt")
		
		len += formatex(szMotd2[len], charsmax(szMotd2)-len,
		"<tr><td id=p>%d</td>\
		<td id=n>%s</td>\
		<td>%d</td>\
		<td>%d</td>\
		<td>%d</td>\
		<td>%s</td>", (x+1), szName, gData[kindex][Data_Exp], gData[kindex][Data_Kills], gData[kindex][Data_Deaths], szTimeFormat)
	}
	
	add(szMotd2, charsmax(szMotd2), "</table></body></html>")
	show_motd(id, szMotd2, "TOP Players (Now Online)")
	
	return PLUGIN_HANDLED;
}

public CompareEXP(elem1[], elem2[])
{
	if(elem1[1] > elem2[1]) return -1;
	else if(elem1[1] < elem2[1]) return 1;
	
	return 0;
}

public OnDeathMsg()
{
	new atk, vic, hs, szWpn[4]
	atk = read_data(1)
	vic = read_data(2)
	hs = read_data(3)
	read_data(4, szWpn, 3)
	
	if(is_user_connected(vic))
	{
		gData[vic][Data_Deaths]++
	}
	
	if((atk != vic) && is_user_connected(atk))
	{
		gData[atk][Data_Kills]++
		ExpAdd(atk, iExpKill)
		
		if(hs)
		{
			gData[atk][Data_HeadShot]++
			ExpAdd(atk, iExpHeadShot)
		}
		{
			gData[atk][Data_NemKills]++
			ExpAdd(atk, iExpNemKill)
		}
		{
			gData[atk][Data_SurKills]++
			ExpAdd(atk, iExpSurKill)
		}
		
		if(szWpn[0]=='k' && szWpn[1]=='n')
		{
			gData[atk][Data_Knife]++
			ExpAdd(atk, iExpKnife)
			CheckPlayerLevel(atk)
			return;
		}
		
		if(szWpn[0]=='g' && szWpn[1]=='r')
		{
			gData[atk][Data_Nade]++
			ExpAdd(atk, iExpGrenade)
			CheckPlayerLevel(atk)
			return;
		}
		
		CheckPlayerLevel(atk)
	}
}

public zp_user_infected_post(vic, atk)
{
	if(atk && is_user_connected(vic))
	{
		gData[vic][Data_Deaths]++
	}
	
	if((atk != vic) && is_user_connected(atk))
	{
		gData[atk][Data_Kills]++
		ExpAdd(atk, iExpKill)
		CheckPlayerLevel(atk)
	}
}

public OnPlayerPreThink(id)
{
	static Float:ctime; ctime = get_gametime();
	if(fLastHud[id] > ctime) return;
	
	fLastHud[id] = ctime+1.0
	
	if(!is_user_alive(id))
	{
		static iSpec; iSpec = entity_get_int(id, EV_INT_iuser2);
		if(!is_user_alive(iSpec)) return;
		
		set_hudmessage(128, 128, 128, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.6, 0.5, -1)
		ShowSyncHudMsg(id, iHudStats, "        SPECTATING^n%s ^n[ Country: %s ]^n[ HP: %.0f | Ammo: %d ]^n[ %s: %d/%d ]", gData[iSpec][Data_Name], gData[iSpec][Data_Country], entity_get_float(iSpec, EV_FL_health), zp_get_user_ammo_packs(iSpec),szRanks[gData[iSpec][Data_Level]], gData[iSpec][Data_Exp], iEXP[gData[iSpec][Data_Level]+1]) //entity_get_float(iSpec, EV_FL_armorvalue)
		return;
	}
	new iRank
	iRank = SortPlayerRank(id)
	set_hudmessage(4, 128, 4, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.6, 0.5, -1)
	ShowSyncHudMsg(id, iHudStats, "[ %s: %d/%d ]^n[ Rank: %d of %d ]^n              Alive ^n[ Humans:%d|%d:Zombies ]",szRanks[gData[id][Data_Level]], gData[id][Data_Exp], iEXP[gData[id][Data_Level]+1], iRank, iTotalEntries, zp_get_human_count(), zp_get_zombie_count() )
}

public _get_user_exp(id)
{
	return gData[id][Data_Exp];
}

public _set_user_exp(id, amount)
{
	ExecuteForward(gForward[Forward_Exp_Set], gForward[Forward_Result], id, amount)
	if(gForward[Forward_Result] >= PLUGIN_HANDLED) return;
	
	gData[id][Data_Exp] = amount
}

public _get_user_playtime(id)
{
	return gData[id][Data_PlayTime];
}

public _set_user_playtime(id, amount)
{
	gData[id][Data_PlayTime] = amount
}

public _get_user_level(id)
{
	return gData[id][Data_Level];
}

public _set_user_level(id, amount)
{
	gData[id][Data_Level] = amount
}

public _get_user_deaths(id)
{
	return gData[id][Data_Deaths];
}

public _set_user_deaths(id, amount)
{
	gData[id][Data_Deaths] = amount
}

public _get_user_frags(id)
{
	return gData[id][Data_Kills];
}

public _set_user_frags(id, amount)
{
	gData[id][Data_Kills] = amount
}

public _get_user_headshot(id)
{
	return gData[id][Data_HeadShot];
}

public _set_user_headshot(id, amount)
{
	gData[id][Data_HeadShot] = amount
}

public _get_user_knife(id)
{
	return gData[id][Data_Knife];
}

public _set_user_knife(id, amount)
{
	gData[id][Data_Knife] = amount
}

public _get_user_nade(id)
{
	return gData[id][Data_Nade];
}

public _set_user_nade(id, amount)
{
	gData[id][Data_Nade] = amount
}

public _get_user_nemesis(id)
{
	return gData[id][Data_NemKills];
}

public _set_user_nemesis(id, amount)
{
	gData[id][Data_NemKills] = amount
}

public _get_user_survivor(id)
{
	return gData[id][Data_SurKills];
}

public _set_user_survivor(id, amount)
{
	gData[id][Data_SurKills] = amount
}

public _reset_user_data(id)
{
	gData[id][Data_Exp] = 0
	gData[id][Data_Kills] = 0
	gData[id][Data_Deaths] = 0
	gData[id][Data_HeadShot] = 0
	gData[id][Data_Knife] = 0
	gData[id][Data_Nade] = 0
	gData[id][Data_NemKills] = 0
	gData[id][Data_SurKills] = 0
	gData[id][Data_PlayTime] = 0
	gData[id][Data_Level] = 0
}

public _get_user_rank(id)
{
	return SortPlayerRank(id);
}

public _is_user_registered(id)
{
	return bIsRegistered[id];
}

public _is_user_login(id)
{
	return bIsLogin[id];
}

public TaskLoopShowHudLogin(id)
{
	id-=TASK_HUD_REGISTER
	if(!is_user_connected(id))
	{
		remove_task(id+TASK_HUD_REGISTER)
		return;
	}
	
	if(!iCountdown[id])
	{
		new szReason[64]
		if(bIsRegistered[id]) formatex(szReason, 63, "You had only %d seconds to login, please reconnect.", RG_MAX_LOGIN_TIME);
		else formatex(szReason, 63, "You had only %d seconds to register, please reconnect.", RG_MAX_LOGIN_TIME);
		emessage_begin(MSG_ONE, SVC_DISCONNECT, _, id)
		ewrite_string(szReason)
		emessage_end()
		return;
	}
	
	if(bIsRegistered[id])
	{
		set_hudmessage(128, 0, 0, -1.0, 0.2, 0, 6.0, 1.1, 0.6, 0.5, -1)
		ShowSyncHudMsg(id, iHudLogin, "You have %d second(s) to login..", iCountdown[id])
		
		set_hudmessage(0, 128, 0, -1.0, -1.0, 0, 6.0, 1.1, 0.6, 0.5, -1)
		ShowSyncHudMsg(id, iHudLogin2, "Nick: %s (Login)^nType in chat:^n^n/login ^"mypass^"", gData[id][Data_Name])
	}
	else
	{
		set_hudmessage(128, 0, 0, -1.0, 0.2, 0, 6.0, 1.1, 0.6, 0.5, -1)
		ShowSyncHudMsg(id, iHudLogin, "You have %d second(s) to login!", iCountdown[id]) //to register
		
		set_hudmessage(0, 128, 0, -1.0, -1.0, 0, 6.0, 1.1, 0.6, 0.5, -1)
		ShowSyncHudMsg(id, iHudLogin2, "Nick: %s (Register)^n^nType in chat:^n^n/login ^"mypass^"", gData[id][Data_Name])
	}
	
	iCountdown[id]--
}

public TaskShowInfoPassword(id)
{
	id-=TASK_HUD_REGISTER
	if(!is_user_connected(id)) return;
	
	set_hudmessage(0, 255, 0, -1.0, -1.0, 0, 10.0, 10.0, 0.5, 3.0, -1)
	client_print(id, print_console, "[UserVault] LOGIN DETAILS^n-----------------------------^nUSERNAME : %s ^nPASSWORD: %s ^n-----------------------------", gData[id][Data_Name], gData[id][Data_Password])
	ShowSyncHudMsg(id, iHudLogin2, "Registration completed!^n-----------------------------^nUSERNAME: %s ^nPASSWORD: %s ^n-----------------------------^n Details in console!", gData[id][Data_Name], gData[id][Data_Password])
	UTIL_ColorChat(id, "^x04[UserVault]^x01 You can use chat command^x04 /showpass^x01 to show your password.")
	UTIL_ColorChat(id, "^x04[UserVault]^x01 Commands: ^x04/showpass ^x01, ^x04/stats ^x01, ^x04/rank ^x01, ^x04/top15 ^x01, ^x04/top10 ^x01, ^x04/toponline")
}

ExpAdd(id, exp)
{
	ExecuteForward(gForward[Forward_Exp_Add], gForward[Forward_Result], id, exp)
	if(gForward[Forward_Result] >= PLUGIN_HANDLED) return;
	
	gData[id][Data_Exp] += exp
}

GetTimeFormat(seconds, szTime[], len)
{
	new days, hours, minutes
	days = seconds / 86400;
	hours = ( seconds / 3600 ) % 24;
	minutes = ( seconds / 60 ) % 60;
	seconds = seconds % 60;
	
	if(days)
	{
		formatex(szTime, len, "%dD %dH %dM %dS", days, hours, minutes, seconds)
		return;
	}
	
	if(hours)
	{
		formatex(szTime, len, "%dH %dM %dS", hours, minutes, seconds)
		return;
	}
	
	if(minutes)
	{
		formatex(szTime, len, "%dM %dS", minutes, seconds)
		return;
	}
	
	if(seconds)
	{
		formatex(szTime, len, "%dS", seconds)
	}
}

GetPlayerStats(id, caller)
{
	new szMotd2[1536], len
	szMotd2[0] = 0
	
	add(szMotd2, charsmax(szMotd2),
	"<html><style>\
	body{background: url('https://static.brusheezy.com/system/resources/previews/000/013/939/non_2x/grunge-texture-by-krist-photoshop-textures.jpg') repeat;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
	.t{color:#afafaf;text-align:left;  }\
	#h{background: #333;border-style: solid;border-width: 1px;border-color: #999;color:#E0E0E0;font-weight:bold;}\
	#p{color:#e6e6e6;}\
	#n{color:#fff;}\
	</style><body>\
	<table cellspacing=0 width=100% class=t>")
	
	add(szMotd2, charsmax(szMotd2),
	"<tr><td id=h width=30%>Statistics</td>\
	<td id=h>Amount</td></tr>")
	
	len = strlen(szMotd2)

	new iSec, szTimeFormat[32], iRank, iPacks, szName[32]
	iSec = get_user_time(id)+gData[id][Data_PlayTime]
	GetTimeFormat(iSec, szTimeFormat, 31)
	iRank = SortPlayerRank(id)
	iPacks = zp_get_user_ammo_packs(id)
	get_user_name(id, szName, 31)
	replace_all(szName, 31, "#", " ")
	replace_all(szName, 31, "<", "&lt")
	replace_all(szName, 31, ">", "&gt")
	
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Nickname</td>\<td>%s</td>", szName)
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>SteamID</td>\<td>%s</td>", gData[id][Data_Steamid])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Country</td>\<td>%s</td>", gData[id][Data_Country])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Rank</td>\<td>%d of %d</td>", iRank, iTotalEntries)
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Ammo</td>\<td>%d</td>", iPacks)
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Points</td>\<td>%d</td>", gData[id][Data_Exp])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Stage</td>\<td>%s</td>", szRanks[gData[id][Data_Level]])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Kills</td>\<td>%d</td>", gData[id][Data_Kills])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Deaths</td>\<td>%d</td>", gData[id][Data_Deaths])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Headshot kills</td>\<td>%d</td>", gData[id][Data_HeadShot])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Knife kills</td>\<td>%d</td>", gData[id][Data_Knife])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Grenade kills</td>\<td>%d</td>", gData[id][Data_Nade])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Nemesis kills</td>\<td>%d</td>", gData[id][Data_NemKills])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Survivor kills</td>\<td>%d</td>", gData[id][Data_SurKills])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Online time</td>\<td>%s</td>", szTimeFormat)
	
	add(szMotd2, charsmax(szMotd2), "</table></body></html>")
	show_motd(caller, szMotd2, "Player Statistics")
}

public CheckPlayerLevel(id)
{
	while((gData[id][Data_Exp] >= iEXP[gData[id][Data_Level]+1]))
	{
		gData[id][Data_Level]++
		UTIL_ColorChat(id, "^x04%s^x01 has been promoted to the Stage of^x04 %s^x01 with^x04 %d^x01 Points.", gData[id][Data_Name], szRanks[gData[id][Data_Level]], gData[id][Data_Exp])
		ExecuteForward(gForward[Forward_Levelup], gForward[Forward_Result], id, gData[id][Data_Level], gData[id][Data_Exp])
	}
}

LoadPlayerData(id)
{
	new szName[32], szKey[50], szData[164]
	copy(szName, 31, gData[id][Data_Name])
	replace_all(szName, 31, " ", "#")
	formatex(szKey, 49, "%s#Points", szName)

	if(nvault_get(iVaultHandle, szKey, szData, 163))
	{
		new szExp[8], szKills[8], szDeaths[8], szHeadShot[8], szKnife[8], szNade[8], szNemKill[8], szSurKill[8], szPlayTime[8], szLevel[8]
		parse(szData, szExp, 7, szKills, 7, szDeaths, 7, szHeadShot, 7, szKnife, 7, szNade, 7, szNemKill, 7, szSurKill, 7, szPlayTime, 7, szLevel, 7)
		
		gData[id][Data_Exp] = str_to_num(szExp)
		gData[id][Data_Kills] = str_to_num(szKills)
		gData[id][Data_Deaths] = str_to_num(szDeaths)
		gData[id][Data_HeadShot] = str_to_num(szHeadShot)
		gData[id][Data_Knife] = str_to_num(szKnife)
		gData[id][Data_Nade] = str_to_num(szNade)
		gData[id][Data_NemKills] = str_to_num(szNemKill)
		gData[id][Data_SurKills] = str_to_num(szSurKill)
		gData[id][Data_PlayTime] = str_to_num(szPlayTime)
		gData[id][Data_Level] = str_to_num(szLevel)
	}
}

SavePlayerData(id)
{
    new szKey[50], szData[164]
    replace_all(gData[id][Data_Name], 31, " ", "#")
    formatex(szKey, 49, "%s#Points", gData[id][Data_Name])
    formatex(szData, 163, "%d %d %d %d %d %d %d %d %d %d %s %s", gData[id][Data_Exp], gData[id][Data_Kills], gData[id][Data_Deaths], gData[id][Data_HeadShot], gData[id][Data_Knife], gData[id][Data_Nade], gData[id][Data_NemKills], gData[id][Data_SurKills], gData[id][Data_PlayTime], gData[id][Data_Level], gData[id][Data_Name], gData[id][Data_Password])
    nvault_set(iVaultHandle, szKey, szData)
    bIsLogin[id] = false
}

FormatGlobalTopTen()
{
	enum _:VaultData
	{
		VD_Key[64],
		VD_Value
	}
	
	const MAX_ENTRIES = 10
	new vault = nvault_util_open(szVaultName)
	new Array:entries = ArrayCreate(VaultData)
	new sizeEntries
	new numEntries = nvault_util_count(vault)
	new data[VaultData], value[128], data2[VaultData]
	
	for(new i = 0, pos, timestamp; i < numEntries; i++)
	{
		pos = nvault_util_read(vault, pos, data[VD_Key], charsmax(data[VD_Key]), value, charsmax(value), timestamp)
		data[VD_Value] = str_to_num(value)
		
		if(sizeEntries == 0)
		{
			ArrayPushArray(entries, data)
			sizeEntries++;
		}
		else
		{
			for(timestamp = 0; timestamp <= sizeEntries; timestamp++)
			{
				if(timestamp == sizeEntries)
				{
					if(sizeEntries < MAX_ENTRIES)
					{
						ArrayPushArray(entries, data)
						sizeEntries++;
					}
					
					break;
				}
				
				ArrayGetArray(entries, timestamp, data2)
				
				if(data[VD_Value] >= data2[VD_Value])
				{
					ArrayInsertArrayBefore(entries, timestamp, data)
					
					if(sizeEntries < MAX_ENTRIES)
					{
						sizeEntries++;
					}
					else
					{
						ArrayDeleteItem(entries, sizeEntries)
					}
					
					break;
				}
			}
		}
	}
	
	nvault_util_close(vault)

	new len
	szMotd[0] = 0
	
	add(szMotd, charsmax(szMotd),
	"<html><style>\
	body{background:url('https://static.brusheezy.com/system/resources/previews/000/013/939/non_2x/grunge-texture-by-krist-photoshop-textures.jpg') repeat;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
	.t{color:#afafaf;text-align:left; }\
	#h{background: #333;border-style: solid;border-width: 1px;border-color: #999;color:#E0E0E0;font-weight:bold;}\
	#p{color:#D41313;}\
	#n{color:#fff;}\
	</style><body>\
	<table cellspacing=0 width=100% class=t>")
	
	add(szMotd, charsmax(szMotd),
	"<tr><td id=h width=7%>#</td>\
	<td id=h>Name</td>\
	<td id=h>Points</td>\
	<td id=h>Kills</td>\
	<td id=h>Deaths</td>\
	<td id=h>Online</td></tr>")
	
	len = strlen(szMotd)
	
	for(new i = 0; i < sizeEntries; i++)
	{
		ArrayGetArray(entries, i, data)
		
		new szDataNew[164]
		nvault_get(iVaultHandle, data[VD_Key], szDataNew, charsmax(szDataNew))
		
		new szExp[8], szKills[8], szDeaths[8], szHeadShot[8], szKnife[8], szNade[8], szNemKill[8], szSurKill[8], szPlayTime[8], szLevel[8], szName3[32]
		parse(szDataNew, szExp, 7, szKills, 7, szDeaths, 7, szHeadShot, 7, szKnife, 7, szNade, 7, szNemKill, 7, szSurKill, 7, szPlayTime, 7, szLevel, 7, szName3, 31)
		
		new iSec, szOnline[32]
		iSec = str_to_num(szPlayTime)
		GetTimeFormat(iSec, szOnline, 31)
		replace_all(szName3, 31, "#", " ")
		replace_all(szName3, 31, "<", "&lt")
		replace_all(szName3, 31, ">", "&gt")
		
		len += formatex(szMotd[len], charsmax(szMotd)-len,
		"<tr><td id=p>%d</td>\
		<td id=n>%s</td>\
		<td>%s</td>\
		<td>%s</td>\
		<td>%s</td>\
		<td>%s</td>", (i+1), szName3, szExp, szKills, szDeaths, szOnline)
	}
	
	add(szMotd, charsmax(szMotd), "</table></body></html>")
	ArrayDestroy(entries)
}

SortPlayerRank(id)
{
	new szName[32], szKey[50]
	copy(szName, 31, gData[id][Data_Name])
	replace_all(szName, 31, " ", "#")
	formatex(szKey, 49, "%s#Points", szName)
	
	enum _:VaultData
	{
		VD_Key[64],
		VD_Value
	}
	
	new vault = nvault_util_open(szVaultName)
	new Array:entries = ArrayCreate(VaultData)
	new sizeEntries
	new numEntries = nvault_util_count(vault)
	new data[VaultData], value[128], data2[VaultData]
	
	for(new i = 0, pos, timestamp; i < numEntries; i++)
	{
		pos = nvault_util_read(vault, pos, data[VD_Key], charsmax(data[VD_Key]), value, charsmax(value), timestamp)
		data[VD_Value] = str_to_num(value)
		
		if(sizeEntries == 0)
		{
			ArrayPushArray(entries, data)
			sizeEntries++;
		}
		else
		{
			for(timestamp = 0; timestamp <= sizeEntries; timestamp++)
			{
				if(timestamp == sizeEntries)
				{
					if(sizeEntries < numEntries)
					{
						ArrayPushArray(entries, data)
						sizeEntries++;
					}
					
					break;
				}
				
				ArrayGetArray(entries, timestamp, data2)
				
				if(data[VD_Value] >= data2[VD_Value])
				{
					ArrayInsertArrayBefore(entries, timestamp, data)
					
					if(sizeEntries < numEntries)
					{
						sizeEntries++;
					}
					else
					{
						ArrayDeleteItem(entries, sizeEntries)
					}
					
					break;
				}
			}
		}
	}
	
	nvault_util_close(vault)
	iTotalEntries = sizeEntries
	
	for(new i = 0; i < sizeEntries; i++)
	{
		ArrayGetArray(entries, i, data)
		if(equal(data[VD_Key],szKey))
		{
			gData[id][Data_Rank] = i+1
			break;
		}
	}
	
	ArrayDestroy(entries)
	return gData[id][Data_Rank];
}

UTIL_ColorChat(id, const szText[], any:...)
{
	new szBuffer[512]
	
	if(!id)
	{
		new iPlayers[32], iNum, y, id2
		get_players(iPlayers, iNum, "ch")
		for(y=0;y<iNum;y++)
		{
			id2 = iPlayers[y]
			if(!is_user_connected(id2)) continue;
			
			vformat(szBuffer, charsmax(szBuffer), szText, 3)
			message_begin(MSG_ONE_UNRELIABLE, iMsgSayText, _, id2)
			write_byte(id2)
			write_string(szBuffer)
			message_end()
		}
	}
	else
	{
		vformat(szBuffer, charsmax(szBuffer), szText, 3)
		message_begin(MSG_ONE, iMsgSayText, _, id)
		write_byte(id)
		write_string(szBuffer)
		message_end()
	}
}

stock client_cmd_ex(id, const command[], any:...)
{
	#pragma unused command
	
	if (id == 0 || is_user_connected(id))
	{
		new szMessage[256]
		
		format_args(szMessage, charsmax(szMessage), 1)
		
		message_begin(id == 0 ? MSG_ALL : MSG_ONE, 51, _, id)
		write_byte(strlen(szMessage) + 2)
		write_byte(10)
		write_string(szMessage)
		message_end()
	}
}

Плъгин 2;

Код: Избери всички

/*

	Copyright(C). 2014. zmd94 ;)
	
	This program is free software: you can redistribute it and/or modify
	it under the terms of the GNU General Public License as published by
	the Free Software Foundation, either version 3 of the License, or
	(at your option) any later version.
	
	This program is distributed in the hope that it will be useful,
	but WITHOUT ANY WARRANTY; without even the implied warranty of
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
	GNU General Public License for more details.
	
	You should have received a copy of the GNU General Public License
	along with this program.  If not, see <http://www.gnu.org/licenses/>.

*/


//Uncomment 'CUSTOM_CHAT' if your want to use custom chat
//#define CUSTOM_CHAT

//Uncomment 'DATA_EXPIRED' if your want to enable data expired function
#define DATA_EXPIRED

//Uncomment 'CHANGE_NAME' if your want to enable player to change their name
#define CHANGE_NAME

#include <amxmodx>
#include <fakemeta>
#include <hamsandwich>
#include <nvault_util>
#include <nvault>
#include <engine>
#include <fun>
#include <zombieplague> 

new const VERSION[] = "3.2"
new const VAULTNAME[] = "fterzp-uservault312551"
new const RANKS[][]=
{
    "Guardsman",
    "Healer",
    "Protector",
    "Warrior",
    "High Warrior",
    "Alpha Warrior",
    "Archwarrior",
    "High Archwarrior",
    "Alpha Archwarrior",
    "Destroyer",
    "High Destroyer",
    "Alpha Destroyer",
    "Commander",
    "High Commander",
    "Alpha Commander",
    "Baron",
    "High Baron",
    "Alpha Baron",
    "King",
    "Alpha King",
    "Overlord",
    "Hacker"
}

new const EXP[] =
{
    0,
    50,
    100,
    200,
    250,
    300,
    350,
    400,
    450,
    500,
    600,
    700,
    700,
    800,
    900,
    1100,
    1250,
    1500,
    2000,
    2500,
    3000,
    999999999
}

#define ADMIN_FLAG	ADMIN_IMMUNITY
#define MAXPLAYERS 32
#define TOPLEVEL 15
#define TASK_INFO 2399

// Bool
new bool:g_bKilledZombie[MAXPLAYERS+1][33]

// String
new g_szMotd[1536]
new g_sName[MAXPLAYERS+1][32]

// Variables
new g_iLevel[MAXPLAYERS+1], g_iXP[MAXPLAYERS+1] 
new g_iDamage[MAXPLAYERS+1][33], g_iSprite[MAXPLAYERS+1]
new g_iSteamID[MAXPLAYERS+1][32]

new g_iZombieScore, g_iHumanScore
new g_iVault, g_msgSayText

new g_iELevelBonus, g_iEAPRewards, g_iEHitRecieved, g_iEHitDealt, g_iEShowScore, g_iEHumanWin, g_iEHumanWinBonus
, g_iEZombieWinBonus, g_iEZombieInfectBonus, g_iESurvKillBonus, g_iENemKillBonus, g_iEDamageEXP
, g_iEHPBonus, g_iEArmorBonus

new g_iSaveType, g_iConnectMessage, g_iELevelIcon, g_iLevelIconTime, g_iEInformHud, g_iHudLocation
, g_iHudColors, g_iScoreColors, g_iHumanEXP, g_iZombieEXP, g_iHeadShotEXP, g_iLevelEXPBonus, g_iLevelHPBonus
, g_iLevelArBonus, g_iLevelAPBonus, g_iHumanWinEXP, g_iZombieWinEXP, g_iInfectEXP, g_iSurKillEXP
, g_iNemKillEXP, g_iDamageAmount, g_iDamageEXP

#if defined DATA_EXPIRED
new g_iDataExpired
#endif

public plugin_init()
{
	// Original plugin is by Excalibur007. ;)
	register_plugin("[ZP] UserVault", VERSION, "PLUGIN_AUTHOR") //Custom Level by zmd94
	
	//register_dictionary("custom_level.txt")
	
	#if defined CUSTOM_CHAT
	register_clcmd("say", "custom_say")
	register_clcmd("say_team", "custom_say_team")
	#endif
	
	register_clcmd("say /vault", "custom_menu")
	register_clcmd("say_team /vault", "custom_menu")
	register_clcmd("say /stats", "show_stats")
	register_clcmd("say_team /stats", "show_stats")
	register_clcmd("say /top15", "show_global_top")
	register_clcmd("say_team /top15", "show_global_top")
	register_clcmd("say /top10", "show_global_top")
	register_clcmd("say_team /top10", "show_global_top")
	register_clcmd("say /onlinetop", "show_online_top")
	register_clcmd("say_team /onlinetop", "show_online_top")
	register_clcmd("say /save", "save_data")
	register_clcmd("say_team /save", "save_data")
	
	register_clcmd("free_give","cl_give", ADMIN_FLAG, "Enable to give free EXP")

	register_event("HLTV", "event_new_round", "a", "1=0", "2=0")
	register_event("Damage", "event_Damage", "be", "2!0", "3=0", "4!0")
	register_event("DeathMsg", "event_DeathMsg", "a", "1>0")
	register_event("StatusValue", "event_StatusValue", "be", "1=2", "2!0")
	register_event("TextMsg", "event_Restart", "a", "2&#Game_C", "2&#Game_w")
	
	RegisterHam(Ham_Spawn, "player", "fw_PlayerRespawn", 1)
	
	#if defined CHANGE_NAME
	register_forward( FM_ClientUserInfoChanged, "FwdClientUserInfoChanged" )
	#endif
	
	g_iSaveType = register_cvar("cl_save_type", "2") // 1; Save the EXP via player steamID | 2; Save the EXP via player name 
	#if defined DATA_EXPIRED
	g_iDataExpired = register_cvar("cl_data_expired", "30") // This will remove all entries in the vault that are X days old 
	#endif
	g_iConnectMessage = register_cvar("uv_connect_message", "0") // Enable connect message
	g_iHumanEXP = register_cvar("uv_human_EXP", "1") // Amount of EXP gain from killing a zombie without headshot
	g_iZombieEXP = register_cvar("uv_zombie_EXP", "1") // Amount of EXP gain from killing a human
	g_iHeadShotEXP = register_cvar("uv_level_head_EXP", "2") //  Amount of EXP gain from killing a zombie with headshot
	g_iELevelIcon = register_cvar("uv_level_icon", "1") // Enable level icon
	g_iLevelIconTime = register_cvar("uv_level_icon_time", "1.5") // The time for the icon to stay displaying
	g_iELevelBonus = register_cvar("uv_level_bonus", "1") // Enable level bonus
	g_iLevelEXPBonus = register_cvar("uv_EXP_bonus", "2") // Amount of EXP gain when level up 
	g_iEHPBonus = register_cvar("uv_enable_health_bonus", "0") // Enable HP bonus
	g_iLevelHPBonus = register_cvar("uv_health_bonus", "0")  // The values of health reward 
	g_iEArmorBonus = register_cvar("uv_enable_armor_bonus", "0") // Enable armor bonus
	g_iLevelArBonus = register_cvar("uv_armor_bonus", "0") // The values of armor reward 
	g_iEAPRewards = register_cvar("uv_enable_AP_bonus", "1") // Enable ammo packs reward when level up
	g_iLevelAPBonus = register_cvar("uv_AP_amount", "1") // The values of ammo packs reward 
	g_iEInformHud = register_cvar("uv_level_hud", "1") // Enable level hud information
	g_iHudColors = register_cvar("uv_hud_colors", "255 0 0")
	g_iHudLocation = register_cvar("uv_hud_position", "2") // 1; The position of hud information is in the left | 2; The position of hud information is in the right
	g_iEDamageEXP = register_cvar("uv_level_damage", "1") // Enable human to recieve EXP from dealing a damage 
	g_iDamageAmount = register_cvar("uv_damage_amount", "50") // Amount of damage need to recieve EXP for human
	g_iDamageEXP = register_cvar("uv_damage_EXP_amount", "1") // Amount of EXP gain from dealing a damage
	g_iEHitRecieved = register_cvar("uv_show_hit_recieved", "1") // Enable showing recieved damage 
	g_iEHitDealt = register_cvar("uv_show_hit_dealt", "1") // Enable showing dealt damage
	g_iEShowScore = register_cvar("uv_show_score", "1") // Enable showing score for zombie and human
	g_iScoreColors = register_cvar("uv_score_colors", "0 255 0")
	g_iEHumanWin = register_cvar("uv_human_win", "1") // Enable human to be a winner if nobody win
	g_iEHumanWinBonus = register_cvar("uv_human_win_bonus", "1") // Enable win bonus for human
	g_iHumanWinEXP = register_cvar("uv_human_win_amount", "1") // EXP given to human for winning
	g_iEZombieWinBonus = register_cvar("uv_zombie_win_bonus", "1") // Enable win bonus for zombie
	g_iZombieWinEXP = register_cvar("uv_zombie_win_amount", "1") // EXP given to zombie for winning
	g_iEZombieInfectBonus = register_cvar("uv_zombie_infect_bonus", "1") // Enable EXP bonus for zombie when infecting human
	g_iInfectEXP = register_cvar("uv_zombie_infect_amount", "1") // EXP given to zombie for infecting human
	g_iESurvKillBonus = register_cvar("uv_survivor_kill_bonus", "1") // Enable kill bonus when killing survivor
	g_iSurKillEXP = register_cvar("uv_survivor_bonus_amount", "5") // Then amount of EXP bonus by killing survivor
	g_iENemKillBonus = register_cvar("uv_nemesis_kill_bonus", "1") // Enable kill bonus when killing nemesis
	g_iNemKillEXP = register_cvar("uv_nemesis_bonus_amount", "5") // Then amount of EXP bonus by killing nemesis
	
	g_msgSayText = get_user_msgid("SayText")
	
	#if defined CUSTOM_CHAT
	register_message(g_msgSayText, "message_SayText")
	#endif
	
	// Score Inform. ;)
	if(get_pcvar_num(g_iEShowScore))
	{
		set_task(1.0, "ShowScore", 0, _, _, "b")
	}
}

public plugin_precache()
{
	if(get_pcvar_num(g_iELevelIcon))
	{
		new szFile[35]
		for(new i = 0; i < sizeof(RANKS); i++)
		{
			formatex(szFile, charsmax(szFile), "sprites/fter/uv_level/%i.spr", i)
			g_iSprite[i] = precache_model(szFile)
		}
	}
}

public plugin_cfg()
{
	//new sCFGdir[32]
	//get_configsdir(sCFGdir, charsmax(sCFGdir))
	//server_cmd("exec %s/cl_system.cfg", sCFGdir)
	
	g_iVault = nvault_open(VAULTNAME)
	if(g_iVault == INVALID_HANDLE)
	{
		new szText[128]; formatex(szText, 127, "Error opening UserVault database [%s]", VAULTNAME);
		set_fail_state(szText)
	}
	
	server_print("UserVault database [%s] successfully loaded!", VAULTNAME)
	
	#if defined DATA_EXPIRED
	nvault_prune(g_iVault, 0, get_systime() - (86400 * get_pcvar_num(g_iDataExpired)))
	#endif
	
	FormatTop(TOPLEVEL)
}

public plugin_end()
{
	nvault_close(g_iVault)
}

public zp_round_ended(iTeam)
{
	new iPlayers[MAXPLAYERS], iPlayerCount, i, player
	
	switch(iTeam)
	{
		case WIN_ZOMBIES: 
		{
			if(get_pcvar_num(g_iEShowScore))
			{
				g_iZombieScore ++ 
			}
			
			if(get_pcvar_num(g_iEZombieWinBonus))
			{
				get_players(iPlayers, iPlayerCount, "ac") 
				for(i = 0; i < iPlayerCount; i++)
				{
					player = iPlayers[i]
					if(zp_get_user_zombie(player))
					{
						g_iXP[player] += get_pcvar_num(g_iZombieWinEXP)
						sChatColor(player, "^x04[UserVault]^x03 Zombies have recieved!g %d Points!y for infecting all humans", get_pcvar_num(g_iZombieWinEXP))
						
						ReviewLevel(player)
					}
				}
			}
		}
		case WIN_HUMANS: 
		{
			if(get_pcvar_num(g_iEShowScore))
			{
				g_iHumanScore ++ 
			}
			
			if(get_pcvar_num(g_iEHumanWinBonus))
			{
				get_players(iPlayers, iPlayerCount, "ac") 
				for(i = 0; i < iPlayerCount; i++)
				{	
					player = iPlayers[i]
					if(!zp_get_user_zombie(player))
					{
						g_iXP[player] += get_pcvar_num(g_iHumanWinEXP)
						sChatColor(player, "^x04[UserVault]^x03 Humans have recieved!g %d Points!y for defeating the plague", get_pcvar_num(g_iHumanWinEXP))
						
						ReviewLevel(player)
					}
				}
			}
		}
		case WIN_NO_ONE: 
		{
			if(get_pcvar_num(g_iEHumanWin))
			{
				g_iHumanScore ++
				
				if(get_pcvar_num(g_iEHumanWinBonus))
				{
					get_players(iPlayers, iPlayerCount, "ac") 
					for(i = 0; i < iPlayerCount; i++)
					{
						player = iPlayers[i]
						if(!zp_get_user_zombie(player))
						{
							g_iXP[player] += get_pcvar_num(g_iHumanWinEXP)
							sChatColor(player, "^x04[UserVault]^x03 Humans have recieved!g %d Points!y for survive in this round", get_pcvar_num(g_iHumanWinEXP))
							
							ReviewLevel(player)
						}
					}
				}
			}
		}
	}
}

public client_authorized(id)
{
	switch(get_pcvar_num(g_iSaveType))
	{
		case 1:
		{
			get_user_authid(id, g_iSteamID[id], charsmax(g_iSteamID))
		}
		case 2:
		{
			get_user_name(id, g_sName[id], charsmax(g_sName))
		}
	}
}

public client_putinserver(id)
{
	if(is_user_connected(id))
	{
		LoadData(id)
		
		if(get_pcvar_num(g_iConnectMessage))
		{
			new szName[32]
			get_user_name(id, szName, charsmax(szName))
			sChatColor(0, "^x04[UserVault]^x01 %s !tis connected !y| Stage:!g %s!y | Points :!g %d |", szName, RANKS[g_iLevel[id]], g_iXP[id])
		}
		
		if(get_pcvar_num(g_iEInformHud))
		{
			set_task(1.0, "InfoHud", id+TASK_INFO, _, _, "b")
		}
	}
}

public client_disconnected(id)
{
	SaveData(id)
	
	remove_task(id+TASK_INFO)
	
	g_iLevel[id] = 0
	g_iXP[id] = 0
}

public InfoHud(id)
{
	id -= TASK_INFO
	
	new PlayerInfoHud = CreateHudSyncObj()
	new iHudLocation = get_pcvar_num(g_iHudLocation)
	
	new szColors[16]
	new szRed[4], szGreen[4], szBlue[4]
	new iRed, iGreen, iBlue
	
	get_pcvar_string(g_iHudColors, szColors, charsmax(szColors))
	parse(szColors, szRed, charsmax(szRed), szGreen, charsmax(szGreen), szBlue, charsmax(szBlue))
	iRed = str_to_num(szRed); iGreen = str_to_num(szGreen); iBlue = str_to_num(szBlue); 
	
	if(!is_user_alive(id))
	{
		static iSpec; iSpec = entity_get_int(id, EV_INT_iuser2)
		
		if(!is_user_alive(iSpec)) 
			return
		
		new iSpecName[32]
		get_user_name(iSpec, iSpecName, charsmax(iSpecName))
		
		switch(iHudLocation)
		{
			case 1:
			{
				if(g_iLevel[iSpec] == 21)
				{
					set_hudmessage(iRed, iGreen, iBlue, 0.01, 0.28, 0, 6.0, 12.0, 0.0, 0.0, -1) 
					ShowSyncHudMsg(id, PlayerInfoHud,"[Spectating: %s] ^n[Stage: Hacker] ^n[Points: Complete]", iSpecName) 
				}
				else
				{
					set_hudmessage(iRed, iGreen, iBlue, 0.01, 0.28, 0, 6.0, 12.0, 0.0, 0.0, -1) 
					ShowSyncHudMsg(id, PlayerInfoHud,"[Spectating: %s] ^n[Stage: %s] ^n[Points: %d/ %d]", iSpecName, RANKS[g_iLevel[iSpec]], g_iXP[iSpec], EXP[g_iLevel[iSpec] + 1]) 
				}
			}
			case 2:
			{
				if(g_iLevel[iSpec] == 21)
				{
					set_hudmessage(iRed, iGreen, iBlue, 0.75, 0.28, 0, 6.0, 12.0, 0.0, 0.0, -1) 
					ShowSyncHudMsg(id, PlayerInfoHud,"[Spectating: %s] ^n[Stage: Hacker] ^n[Points: Complete]", iSpecName) 
				}
				else
				{
					set_hudmessage(iRed, iGreen, iBlue, 0.75, 0.28, 0, 6.0, 12.0, 0.0, 0.0, -1) 
					ShowSyncHudMsg(id, PlayerInfoHud,"[Spectating: %s] ^n[Stage: %s] ^n[Points: %d/ %d]", iSpecName, RANKS[g_iLevel[iSpec]], g_iXP[iSpec], EXP[g_iLevel[iSpec] + 1]) 
				}
			}
		}
	}
	else
	{
		switch(iHudLocation)
		{
			case 1:
			{
				if(g_iLevel[id] == 21)
				{
					set_hudmessage(iRed, iGreen, iBlue, 0.01, 0.28, 0, 6.0, 12.0, 0.0, 0.0, -1) 
					ShowSyncHudMsg(id, PlayerInfoHud,"[Stage: Hacker] ^n[Points: Complete]") 
				}
				else
				{
					set_hudmessage(iRed, iGreen, iBlue, 0.01, 0.28, 0, 6.0, 12.0, 0.0, 0.0, -1) 
					ShowSyncHudMsg(id, PlayerInfoHud,"[Stage: %s] ^n[Points: %d/ %d]",RANKS[g_iLevel[id]], g_iXP[id], EXP[g_iLevel[id] + 1]) 
				}
			}
			case 2:
			{
				if(g_iLevel[id] == 21)
				{
					set_hudmessage(iRed, iGreen, iBlue, 0.75, 0.28, 0, 6.0, 12.0, 0.0, 0.0, -1) 
					ShowSyncHudMsg(id, PlayerInfoHud,"[Stage: Hacker] ^n[Points: Complete]") 
				}
				else
				{
					set_hudmessage(iRed, iGreen, iBlue, 0.75, 0.28, 0, 6.0, 12.0, 0.0, 0.0, -1) 
					ShowSyncHudMsg(id, PlayerInfoHud,"[Stage: %s] ^n[Points: %d/ %d]",RANKS[g_iLevel[id]], g_iXP[id], EXP[g_iLevel[id] + 1]) 
				}
			}
		}
	}
} 

public ShowScore()
{
	new ScoreHud = CreateHudSyncObj()
	
	new szColors[16]
	new szRed[4], szGreen[4], szBlue[4]
	new iRed, iGreen, iBlue
	
	get_pcvar_string(g_iScoreColors, szColors, charsmax(szColors))
	parse(szColors, szRed, charsmax(szRed), szGreen, charsmax(szGreen), szBlue, charsmax(szBlue))
	iRed = str_to_num(szRed); iGreen = str_to_num(szGreen); iBlue = str_to_num(szBlue);  
	
	set_hudmessage(iRed, iGreen, iBlue, -1.0, 0.02, 0, 12.0, 12.0, 0.0, 0.0, -1)
	ShowSyncHudMsg(0, ScoreHud, "[Zombie] - [Human]^n[%s%d] ----- [%s%d]",g_iZombieScore >= 10 ? "" : "0", g_iZombieScore, g_iHumanScore >= 10 ? "" : "0", g_iHumanScore)
}

public custom_menu(id)
{
	new sMenu = menu_create("\yMenu \rUserVault", "custom_handler")
	
	menu_additem(sMenu, "\wShow global top players!", "1", 0)
	menu_additem(sMenu, "\wShow online top players!", "2", 0)
	menu_additem(sMenu, "\wPoints for next level", "3", 0)
	menu_additem(sMenu, "\wSave your Points!", "4", 0)
	
	menu_display(id, sMenu, 0)
}

public custom_handler(id, menu, item)
{
	if(item == MENU_EXIT) 
	{
		menu_destroy(menu)
		return PLUGIN_HANDLED
	}
	
	switch(item)
	{
		case 0: show_global_top(id)
		case 1: show_online_top(id)
		case 2: show_stats(id)
		case 3: save_data(id)
	}
	
	menu_destroy(menu)
	return PLUGIN_HANDLED
}

#if defined CUSTOM_CHAT
public custom_say(id)
{
	new szMessage[192], szName[32]
	
	read_args(szMessage, charsmax(szMessage))
	remove_quotes(szMessage)
	get_user_name(id, szName, charsmax(szName))
	
	if(equali(szMessage[0], " ") || equali(szMessage[0], "") || !is_valid_msg(szMessage))
		return PLUGIN_HANDLED_MAIN
	
	if(is_user_alive(id))
	{
		format(szMessage, charsmax(szMessage), "^4[%s] ^3%s : ^1%s", RANKS[g_iLevel[id]], szName, szMessage)
	}
	else
	{
		format(szMessage, charsmax(szMessage), "^1*DEAD* ^4[%s] ^3%s : ^1%s", RANKS[g_iLevel[id]], szName, szMessage)
	}
	
	new iPlayers[MAXPLAYERS], iPlayerCount, i, player
	get_players(iPlayers, iPlayerCount, "ch") 
	for(i = 0; i < iPlayerCount; i++)
	{
		player = iPlayers[i]
		if(is_user_alive(id) && is_user_alive(player) || !is_user_alive(id) && !is_user_alive(player))
		{
			message_begin(MSG_ONE, g_msgSayText, {0, 0, 0}, player)
			write_byte(id)
			write_string(szMessage)
			message_end()
		}
	}
	
	return PLUGIN_CONTINUE
}

public custom_say_team(id)
{
	new szMessage[192], szName[32]
	
	read_args(szMessage, charsmax(szMessage))
	remove_quotes(szMessage)
	get_user_name(id, szName, charsmax(szName))
	
	if(equali(szMessage[0], " ") || equali(szMessage[0], "") || !is_valid_msg(szMessage))
		return PLUGIN_HANDLED_MAIN
	
	if(is_user_alive(id))
	{
		format(szMessage, charsmax(szMessage), "^4[%s] ^3%s : ^1%s", RANKS[g_iLevel[id]], szName, szMessage)
	}
	else
	{
		format(szMessage, charsmax(szMessage), "^1*DEAD* ^4[%s] ^3%s : ^1%s", RANKS[g_iLevel[id]], szName, szMessage)
	}
	
	new iPlayers[MAXPLAYERS], iPlayerCount, i, player
	get_players(iPlayers, iPlayerCount, "ch") 
	for(i = 0; i < iPlayerCount; i++)
	{
		player = iPlayers[i]
		if(is_user_alive(id) && is_user_alive(player) && get_user_team(id) == get_user_team(player) || !is_user_alive(id) && !is_user_alive(player) && get_user_team(id) == get_user_team(player))
		{
			message_begin(MSG_ONE, g_msgSayText, {0, 0, 0}, player)
			write_byte(id)
			write_string(szMessage)
			message_end()
		}
	}
	
	return PLUGIN_CONTINUE
}
#endif

public cl_give(id, level, cid)
{
	if (!cmd_access(id, level, cid, 2))
	{				
		return PLUGIN_HANDLED
	}
	
	new iTarget[32], iCount[32]	
	read_argv(1, iTarget, charsmax(iTarget))
	read_argv(2, iCount, charsmax(iCount))
	
	new target_id, iName[32], iNameID[32]
	target_id = find_player("bl", iTarget)
	
	get_user_name(target_id, iName, charsmax(iName)) 
	get_user_name(id, iNameID, charsmax(iNameID))
	
	if(!target_id) 
	{
		console_print(id, "Can't find that player")
		return PLUGIN_HANDLED
	}
	
	if(read_argc() != 3)
	{
		return PLUGIN_HANDLED	
	}
	
	if(str_to_num(iCount) < (EXP[g_iLevel[target_id] + 1] - g_iXP[target_id]))
	{
		if(str_to_num(iCount) == 0)
		{
			console_print(id, "Points for %s is %i / %i", iName, g_iXP[target_id], EXP[g_iLevel[target_id] + 1])
		}
		else
		{
			console_print(id, "%s has been given %i Points", iName, str_to_num(iCount))
			g_iXP[target_id] += str_to_num(iCount)
		}
	}
	else
	{
		console_print(id, "Maximum Points allowed for %s: %i", iName, (EXP[g_iLevel[target_id] + 1] - g_iXP[target_id]))
	}
	
	return PLUGIN_HANDLED;
}

public show_stats(id)
{
	if(is_user_connected(id))
	{
		sChatColor(id, "^x04[UserVault]^x03 Stage:!g %s!y | Points for next level:!g %d", id, RANKS[g_iLevel[id]], (EXP[g_iLevel[id] + 1] - g_iXP[id]))
	}
}

public show_online_top(id)
{
	static Sort[33][2]
	new szName[MAXPLAYERS+1][32]
	new players[32], num, count, index
	
	get_players(players, num)
	for(new i = 0; i < num; i++)
	{
		index = players[i]
		get_user_name(index, szName[index], charsmax(szName))
		
		Sort[count][0] = index
		Sort[count][1] = g_iXP[index]
		count++
	}
	
	SortCustom2D(Sort, count, "CompareEXP")
	
	new y = clamp(count, 0, 10)
	new kindex, szMotd2[1536], len
	szMotd2[0] = 0
	
	add(szMotd2, charsmax(szMotd2),
	"<html><style>\
	body{background:#040404;font-family:Verdana, Arial, Sans-Serif;font-size:19pt;}\
	.t{color:#808080;text-align:left; }\
	#h{background: #0066CC url('http://onlyarg.com/foro/images/Amiral/thead.png') repeat-x;color:#E0E0E0;font-weight:bold;}\
	#p{color:#D41313;}\
	#n{color:#fff;}\
	</style><body>\
	<table cellspacing=0 width=100% class=t>")
	
	add(szMotd2, charsmax(szMotd2),
	"<tr><td id=h width=7%>#</td>\
	<td id=h>Name</td>\
	<td id=h>Stage</td>\
	<td id=h>Points</td></tr>")
	
	len = strlen(szMotd2)
	for(new x = 0; x < y; x++)
	{
		kindex = Sort[x][0]
		
		replace_all(szName[kindex], charsmax(szName), "<", "&lt")
		replace_all(szName[kindex], charsmax(szName), ">", "&gt")
		
		len += formatex(szMotd2[len], charsmax(szMotd2)-len,
		"<tr><td id=p>%d</td>\
		<td id=n>%s</td>\
		<td>%d</td>\
		<td>%d</td>", (x+1), szName[kindex], RANKS[g_iLevel[kindex]], g_iXP[kindex])
	}
	
	add(szMotd2, charsmax(szMotd2), "</table></body></html>")
	show_motd(id, szMotd2, "Top Online Players (now)")
}

public CompareEXP(elem1[], elem2[])
{
	if(elem1[1] > elem2[1]) return -1;
	else if(elem1[1] < elem2[1]) return 1;
	
	return 0;
}

public show_global_top(id)
{
	show_motd(id, g_szMotd, "Top Players (30 days)")
}

FormatTop(iNum)
{
    enum _:sVaultData
	{
		VD_Key[64],
		VD_Value
	}
	
    new sVault = nvault_util_open(VAULTNAME)
    new Array:entries = ArrayCreate(sVaultData)
	
    new sizeEntries;
    new numEntries = nvault_util_count(sVault)
    new data[sVaultData], value[128], data2[sVaultData]
    
    for(new i = 0, pos, timestamp; i < numEntries; i++) 
	{
        pos = nvault_util_read(sVault, pos, data[VD_Key], charsmax(data[VD_Key]), value, charsmax(value), timestamp);
        data[VD_Value] = str_to_num(value)
        
        if(sizeEntries == 0) 
		{
            ArrayPushArray(entries, data)
            sizeEntries++
        } 
		else 
		{
            for(timestamp = 0; timestamp <= sizeEntries; timestamp++) 
			{
                if(timestamp == sizeEntries) 
				{
                    if(sizeEntries < iNum) 
					{
                        ArrayPushArray(entries, data)
                        sizeEntries++
                    }
					
                    break
                }
                
                ArrayGetArray(entries, timestamp, data2)
                if(data[VD_Value] >= data2[VD_Value]) 
				{
                    ArrayInsertArrayBefore(entries, timestamp, data)
                    if(sizeEntries < iNum) 
					{
                        sizeEntries++
                    } 
					else 
					{
                        ArrayDeleteItem(entries, sizeEntries);
                    }
                    
                    break
                }
            }
        }
    }
	
    nvault_util_close(sVault)
	
    new iLen
    new len = charsmax(g_szMotd)
	
    iLen = formatex(g_szMotd, len, "<STYLE>body{background:#212121;color:#d1d1d1;font-family:Arial}table{width:100%%;font-size:19px}</STYLE><table cellpadding=1 cellspacing=1 border=0>")
    iLen += formatex(g_szMotd[iLen], len - iLen, "<tr bgcolor=#333333><th width=1%%><align=left font color=white> %s <th width=5%%> %-22.22s <th width=5%%> %s", "#", "NAME", "Stage")

    new i
    for(i = 0; i < sizeEntries; i++)
    {
        ArrayGetArray(entries, i, data); 
        data[VD_Key][20] = 0;
		
        replace_all(data[VD_Key], charsmax(data[VD_Key]), "<", "&lt;")
        replace_all(data[VD_Key], charsmax(data[VD_Key]), ">", "&gt;")
        
        iLen += formatex(g_szMotd[iLen], len - iLen, "<tr align=left%s><td align=left><font color=white> %d. <td> %-22.22s <td> %d", " bgcolor=#2b5b95",(i+1), data[VD_Key], RANKS[data[VD_Value]])
    }
    
    ArrayDestroy(entries);
    iLen += formatex(g_szMotd[iLen], len - iLen, "</table></body>")
}

public save_data(id)
{
	if(is_user_alive(id))
	{
		SaveData(id)
		sChatColor(id, "^x04[UserVault]^x03 Saving completed!")
	}
}

public event_new_round()
{
	new iPlayers[MAXPLAYERS], iPlayerCount, i, player
	get_players(iPlayers, iPlayerCount, "a") 
	for(i = 0; i < iPlayerCount; i++)
	{
		player = iPlayers[i]
		g_iDamage[player][player] = 0
	}
}

public event_Restart()
{
	if(get_pcvar_num(g_iEShowScore))
	{
		g_iZombieScore = 0
		g_iHumanScore = 0
	}
}

public event_Damage(iVictim)
{
	static iAttacker; iAttacker = get_user_attacker(iVictim)
	static iHit; iHit = read_data(2)
	
	new AttackerHud = CreateHudSyncObj()
	new VictimHud = CreateHudSyncObj()
	
	if(iAttacker == iVictim || !is_user_alive(iAttacker) || !is_user_alive(iVictim))
		return
		
	if(get_pcvar_num(g_iEHitRecieved))
	{
		set_hudmessage(255, 0, 0, 0.45, 0.50, 2, 0.1, 4.0, 0.1, 0.1, -1)
		ShowSyncHudMsg(iVictim, VictimHud, "%i^n", iHit)	
	}
	
	if(get_pcvar_num(g_iEHitDealt))
	{
		set_hudmessage(0, 100, 200, -1.0, 0.55, 2, 0.1, 4.0, 0.02, 0.02, -1)
		ShowSyncHudMsg(iAttacker, AttackerHud, "%i^n", iHit)
	}
	
	Show_spectate(iVictim, iAttacker, iHit)
	
	if(zp_get_user_zombie(iVictim) && !zp_get_user_survivor(iAttacker))
	{
		g_iDamage[iAttacker][iVictim] += read_data(2)
		if (get_pcvar_num(g_iEDamageEXP))
		{
			if(g_iDamage[iAttacker][iVictim] >= get_pcvar_num(g_iDamageAmount))
			{	
				g_iXP[iAttacker] += get_pcvar_num(g_iDamageEXP)
				
				sChatColor(iAttacker, "^x04[UserVault]^x01 You've gained!t %d Poins!y for dealing a damage of!t %d", get_pcvar_num(g_iDamageEXP), get_pcvar_num(g_iDamageAmount))
				g_iDamage[iAttacker][iVictim] = 0
				
				ReviewLevel(iAttacker)
			}
		}
	}
}

public Show_spectate(iVictim, iAttacker, iHit)
{
	new AttackerSpecHud = CreateHudSyncObj()
	new VictimSpecHud = CreateHudSyncObj()
	
	new Players[MAXPLAYERS], iPlayerCount, i, id
	get_players(Players, iPlayerCount, "bc") 
	for (i = 0; i < iPlayerCount; i++) 
	{
		id = Players[i]
		if (id != iVictim && entity_get_int(id, EV_INT_iuser2) == iVictim)
		{
			set_hudmessage(255, 0, 0, 0.45, 0.50, 2, 0.1, 4.0, 0.1, 0.1, -1)
			ShowSyncHudMsg(id, VictimSpecHud, "%i^n", iHit)
		}
		
		if (id != iAttacker && entity_get_int(id, EV_INT_iuser2) == iAttacker)
		{
			set_hudmessage(0, 100, 200, -1.0, 0.55, 2, 0.1, 4.0, 0.02, 0.02, -1)
			ShowSyncHudMsg(id, AttackerSpecHud, "%i^n", iHit)			
		}
	}
}

public event_DeathMsg()
{
	new iKiller; iKiller = read_data(1)
	new iVictim; iVictim = read_data(2)
	new iIsHeadshot; iIsHeadshot = read_data(3)
	
	if(iVictim == iKiller || !is_user_alive(iKiller))
		return
	
	if(!zp_get_user_zombie(iKiller) || zp_get_user_survivor(iKiller))
	{
		if(zp_get_user_nemesis(iVictim))
		{
			if (get_pcvar_num(g_iESurvKillBonus))
			{
				g_iXP[iKiller] += get_pcvar_num(g_iNemKillEXP)
				sChatColor(iKiller, "^x04[UserVault]^x03 You've gained!g %d Points!y for killing a nemesis", get_pcvar_num(g_iNemKillEXP))
				
				ReviewLevel(iKiller)
			}
		}
		else
		{
			if(iIsHeadshot)
			{
				g_bKilledZombie[iKiller][iVictim] = true
				
				g_iXP[iKiller] += get_pcvar_num(g_iHeadShotEXP)
				sChatColor(iKiller, "^x04[UserVault]^x03 You've gained!g %d Points!y for killing a zombie with a headshot", get_pcvar_num(g_iHeadShotEXP))
			}
			else
			{
				g_bKilledZombie[iKiller][iVictim] = true
				
				g_iXP[iKiller] += get_pcvar_num(g_iHumanEXP)
				sChatColor(iKiller, "^x04[UserVault]^x03 You've gained!g %d Points!y for killing a zombie", get_pcvar_num(g_iHumanEXP))
			}
			
			ReviewLevel(iKiller)
		}
	}
	else if(zp_get_user_zombie(iKiller) || zp_get_user_nemesis(iKiller))
	{
		if(zp_get_user_survivor(iVictim))
		{
			if(get_pcvar_num(g_iENemKillBonus))
			{
				g_iXP[iKiller] += get_pcvar_num(g_iSurKillEXP)
				sChatColor(iKiller, "^x04[UserVault]^x03 You've gained!g %d Points!y for killing a survivor", get_pcvar_num(g_iSurKillEXP))
				
				ReviewLevel(iKiller)
			}
		}
		else
		{
			g_iXP[iKiller] += get_pcvar_num(g_iZombieEXP)
			sChatColor(iKiller, "^x04[UserVault]^x03 You've gained!g %d Points!y for killing a human", get_pcvar_num(g_iZombieEXP))
			
			ReviewLevel(iKiller)
		}
	}
}

public ReviewLevel(id)
{
	while((g_iLevel[id] < 18 && g_iXP[id] >= EXP[g_iLevel[id] + 1]))
	{
		g_iLevel[id] += 1
		sChatColor(id, "^x04[UserVault]^x03 Congratulations, your stage now is!g %s", RANKS[g_iLevel[id]])
		
		if(get_pcvar_num(g_iELevelBonus))
		{
			g_iXP[id] += get_pcvar_num(g_iLevelEXPBonus)
			sChatColor(id, "^x04[UserVault]^x03 Bonus Points:!g %d", get_pcvar_num(g_iLevelEXPBonus))
		
			iBonus(id)
		}
		
		if(get_pcvar_num(g_iEAPRewards))
		{
			zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + get_pcvar_num(g_iLevelAPBonus))
			sChatColor(id, "^x04[UserVault]^x03 Bonus AmmoPacks:!g %d", get_pcvar_num(g_iLevelAPBonus))
		}
	}
}

public event_StatusValue(id)
{
	if(!get_pcvar_num(g_iELevelIcon))
		return
	
	new pid = read_data(2)
	new pidlevel = g_iLevel[pid]
	
	if(!pev_valid(pid) || !is_user_alive(pid) || zp_get_user_zombie(pid))
		return
	
	new flTime = floatround(get_pcvar_float(g_iLevelIconTime) * 10)
	if (flTime > 0)
	{
		Create_TE_PLAYERATTACHMENT(id, pid, 55, g_iSprite[pidlevel], flTime)
	}
}

public fw_PlayerRespawn(id)
{
	if(is_user_alive(id))
	{
		if(get_pcvar_num(g_iELevelBonus))
		{
			set_task(5.0, "iBonus", id)
		}
		
		set_task(50.0, "iInform", id)
		set_task(120.0, "iSave", id)
	}
}

public iBonus(id)
{
	if(is_user_alive(id) && !zp_get_user_zombie(id))
	{
		new iHealth = g_iLevel[id]* get_pcvar_num(g_iLevelHPBonus)
		new iArmor = g_iLevel[id]* get_pcvar_num(g_iLevelArBonus)
		
		if(get_pcvar_num(g_iEHPBonus))
		{
			set_user_health(id, get_user_health(id) + iHealth)
		}
		
		if(get_pcvar_num(g_iEArmorBonus))
		{
			set_user_armor(id, get_user_armor(id) + iArmor)
		}
		
		if(get_pcvar_num(g_iEHPBonus) && get_pcvar_num(g_iEArmorBonus))
		{
			sChatColor(id, "^x04[UserVault]^x03 Stage:!g %s !t| Bonus Health:!y %d !t| Bonus Armor:!g %d", RANKS[g_iLevel[id]], iHealth, iArmor)
		}
	}
}

public iInform(id)
{
	if(is_user_alive(id))
	{
		sChatColor(id, "^x04[UserVault]^x03 Just !ysay /vault !tto open the !gUserVault !tmenu")
	}
}

public iSave(id)
{
	if(is_user_alive(id))
	{
		sChatColor(id, "^x04[UserVault]^x03 Just !ysay /save !tto save your current Points!")
	}
}

#if defined CUSTOM_CHAT
public message_SayText(id)
{
	return PLUGIN_HANDLED
}
#endif

public zp_user_infected_post(id, infector)
{
	if(get_pcvar_num(g_iEZombieInfectBonus))
	{
		if(is_user_alive(infector) && infector != id)
		{
			g_iXP[infector] += get_pcvar_num(g_iInfectEXP)
			sChatColor(infector, "^x04[UserVault]^x03 You've gained!g %d Points!y for infecting a human", get_pcvar_num(g_iInfectEXP))
			
			ReviewLevel(id)
		}
	}
}

#if defined CHANGE_NAME
public FwdClientUserInfoChanged( id, szBuffer )
{
	if ( !is_user_connected( id ) )
		return FMRES_IGNORED;
		
	static szNewName[32];
 
	engfunc( EngFunc_InfoKeyValue, szBuffer, "name", szNewName, charsmax(szNewName));
	
	if(equal(szNewName, g_sName[id]))
		return FMRES_IGNORED;
	
	SaveData(id)
	
	sChatColor(id, "^x04[UserVault]^x03 %s, !gyour name has been changed into !y%s!", g_sName[id], szNewName)
	sChatColor(id, "^x04[UserVault]^x03 %s, !gyour level and Points will be transferred to your new name!", szNewName)
	
	copy(g_sName[id], charsmax(g_sName[]), szNewName)
	LoadData(id)
	
	sChatColor(id, "^x04[UserVault]^x03 Transferring is completed!")
	
	return FMRES_IGNORED;
} 
#endif

SaveData(id)
{
	new szData[32], szKey[40]
	switch(get_pcvar_num(g_iSaveType))
	{
		case 1:
		{
			formatex(szKey, charsmax(szKey), "%s", g_iSteamID[id])
		}
		case 2:
		{
			formatex(szKey, charsmax(szKey), "%s", g_sName[id])
		}
	}
	
	formatex(szData, charsmax(szData), "%d %d", g_iLevel[id], g_iXP[id])
	nvault_set(g_iVault, szKey, szData)
}

LoadData(id)
{
	new szData[32], szKey[40]
	switch(get_pcvar_num(g_iSaveType))
	{
		case 1:
		{
			formatex(szKey, charsmax(szKey), "%s" , g_iSteamID[id])
		}
		case 2:
		{
			formatex(szKey, charsmax(szKey), "%s", g_sName[id])
		}
	}
	
	if(nvault_get(g_iVault, szKey, szData, charsmax(szData)))
	{
		new iSpacePos = contain(szData, " ")
		if(iSpacePos > -1)
		{
			new szLevel[8], szXP[32]
			
			parse(szData, szLevel, charsmax(szLevel), szXP, charsmax(szXP))
			
			g_iLevel[id] = str_to_num(szLevel)
			g_iXP[id] = str_to_num(szXP)
		}
	}
}

#if defined CUSTOM_CHAT
bool:is_valid_msg(const szMessage[])
{
	if(szMessage[0] == '@' || szMessage[0] == '/' || szMessage[0] == '!' || !strlen(szMessage))
		return false
		
	return true
}
#endif

stock Create_TE_PLAYERATTACHMENT(id, entity, vOffset, iSprite, life)
{
	message_begin(MSG_ONE_UNRELIABLE, SVC_TEMPENTITY, _, id)
	write_byte(TE_PLAYERATTACHMENT)
	write_byte(entity)
	write_coord(vOffset)
	write_short(iSprite)
	write_short(life)
	message_end()
}

stock sChatColor(const id, const input[], any:...)
{
    new count = 1, players[32], i, player
    static msg[191]

    if(numargs() == 2)
        copy(msg, 190, input)
    else
        vformat(msg, 190, input, 3)

    replace_all(msg, 190, "!g", "^4")
    replace_all(msg, 190, "!y", "^1")
    replace_all(msg, 190, "!t", "^3")
    
    if(id) {
        if(!is_user_connected(id)) return
        players[0] = id
    }
    else get_players(players, count, "ch")

    for(i = 0; i < count; i++)
    {
		player = players[i]
		
		message_begin(MSG_ONE_UNRELIABLE, g_msgSayText, _, player)
		write_byte(player)
		write_string(msg)
		message_end()
	}
} 
Благодаря ви предварително.
Пиша от избата, защото горе имаме течове..

Потребителски аватар

Автор на темата
LayerFort DJBosma
Потребител
Потребител
Мнения: 50
Регистриран: 25 дек 2018, 04:14
Местоположение: Alkmaar
Се отблагодари: 2 пъти
Получена благодарност: 2 пъти
Години: 24
Контакти:

nVault; Премахване на проверка за парола

Мнение от LayerFort DJBosma » 15 фев 2019, 23:10

Здравейте, оправих се с повечето неща.

Само където сега като напишеш /rank показва 0 от 2, (0/2) вместо (1/2) но в топ15 го показва правилно.

Другото което е OnPlayerPreThink, не показва.

Код: Избери всички

#include <amxmodx>
#include <amxmisc>
#include <hamsandwich>
#include <nvault_util>
#include <fakemeta>
#include <engine>
#include <geoip>
#include <zombieplague>

new const szRanks[][] = 
{
    "Guardsman",
    "Healer",
    "Protector",
    "Warrior",
    "High Warrior",
    "Alpha Warrior",
    "Archwarrior",
    "High Archwarrior",
    "Alpha Archwarrior",
    "Destroyer",
    "High Destroyer",
    "Alpha Destroyer",
    "Commander",
    "High Commander",
    "Alpha Commander",
    "Baron",
    "High Baron",
    "Alpha Baron",
    "King",
    "Alpha King",
    "Overlord",
    "Hacker"
}

new const iEXP[] = 
{
    0,
    50,
    100,
    200,
    250,
    300,
    350,
    400,
    450,
    500,
    600,
    700,
    700,
    800,
    900,
    1100,
    1250,
    1500,
    2000,
    2500,
    3000,
    999999999
}

enum _:Player_Data
{
	Data_Steamid[35],
	//Data_Ip[16],
	Data_Name[32],
	Data_Exp,
	Data_Kills,
	Data_Deaths,
	Data_HeadShot,
	Data_Knife,
	Data_Nade,
	Data_NemKills,
	Data_SurKills,
	Data_PlayTime,
	Data_Level,
	Data_Country[46],
	Data_Rank,
	Data_Connected,
	MAX_PLAYER_DATA
}

enum _:Forward_Data
{
	Forward_Levelup,
	Forward_Exp_Add,
	Forward_Exp_Set,
	Forward_Result,
	MAX_FORWARD_DATA
}

new iVaultHandle, gData[33][MAX_PLAYER_DATA], iHudStats, Float:fLastHud[33], szMotd[1536], gForward[MAX_FORWARD_DATA], Float:fLastCmd, iTotalEntries, iMsgSayText
const iExpKill = 1
const iExpHeadShot = 3
const iExpKnife = 4
const iExpGrenade = 4
const iExpNemKill = 5
const iExpSurKill = 5
const Float:HUD_STATS_X = 0.77//-1.0
const Float:HUD_STATS_Y = 0.6//0.8
new const szVaultName[] = "vault201915feb-5"

#define is_user_valid(%0) (0<%0<33)
new cvar_ammopacks
//new g_maxplayers

new Ammopacks[22] = {
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9,
    10,
    11,
    12,
    13,
    14,
    15,
    16,
    17,
    18,
    19,
    20,
    21,
    0
}

//Uncomment this to update motd.txt on map loaded to show global top-10 players.
#define UPDATE_MOTD

//Uncomment this to enable nvault prune.
#define PRUNE_DATABASE


#if defined UPDATE_MOTD
new const szFileMotd[] = "motd.txt"
#endif

#if defined PRUNE_DATABASE
const iExpiredDays = 30
#endif

public plugin_natives()
{
	register_native("xp_get_user_exp","_get_user_exp",1)
	register_native("xp_set_user_exp","_set_user_exp",1)
	
	register_native("xp_get_user_playtime","_get_user_playtime",1)
	register_native("xp_set_user_playtime","_set_user_playtime",1)
	
	register_native("xp_get_user_level","_get_user_level",1)
	register_native("xp_set_user_level","_set_user_level",1)
	
	register_native("xp_get_user_deaths","_get_user_deaths",1)
	register_native("xp_set_user_deaths","_set_user_deaths",1)
	
	register_native("xp_get_user_frags","_get_user_frags",1)
	register_native("xp_set_user_frags","_set_user_frags",1)
	
	register_native("xp_get_user_headshot","_get_user_headshot",1)
	register_native("xp_set_user_headshot","_set_user_headshot",1)
	
	register_native("xp_get_user_knife","_get_user_knife",1)
	register_native("xp_set_user_knife","_set_user_knife",1)
	
	register_native("xp_get_user_nade","_get_user_nade",1)
	register_native("xp_set_user_nade","_set_user_nade",1)
	
	register_native("xp_get_user_nemesis","_get_user_nemesis",1)
	register_native("xp_set_user_nemesis","_set_user_nemesis",1)
	
	register_native("xp_get_user_survivor","_get_user_survivor",1)
	register_native("xp_set_user_survivor","_set_user_survivor",1)
	
	register_native("xp_reset_user_data","_reset_user_data",1)
	register_native("xp_get_user_rank","_get_user_rank",1)
	register_native("xp_check_user_level","CheckPlayerLevel",1)
}

public plugin_init()
{
	new const PLUGIN_VERSION[] = "1.0"//0.0.5
	new const CVAR_EXP_VERSION[] = "n4d_zpstats"
	register_plugin("[ZP] UserVault", PLUGIN_VERSION, "wbyokomo, huehue, djbosma")
	
	iHudStats = CreateHudSyncObj()
	iMsgSayText = get_user_msgid("SayText")
	
	//register_event("HLTV", "event_newround", "a", "1=0", "2=0")
	register_event("DeathMsg", "OnDeathMsg", "a") //use deathmsg easy to trace weapon and hitplace
	register_event_ex("30", "Event_Intermission", RegisterEvent_Global)
	
	register_clcmd("say /stats" , "CmdStats")
	register_clcmd("say /rank", "CmdShowRank")
	register_clcmd("say /top15", "CmdTopExpGlobal")
	register_clcmd("say /top10", "CmdTopExpGlobal")
	register_clcmd("say /toponline", "CmdTopExpOnline")
	
	register_clcmd("say_team /stats" , "CmdStats")
	register_clcmd("say_team /rank", "CmdShowRank")
	register_clcmd("say_team /top15", "CmdTopExpGlobal")
	register_clcmd("say_team /top10", "CmdTopExpGlobal")
	register_clcmd("say_team /toponline", "CmdTopExpOnline")
	
	cvar_ammopacks = register_cvar("xp_ammopacks_reward", "1")
	//g_maxplayers = get_maxplayers()
	

	gForward[Forward_Levelup] = CreateMultiForward("xp_user_levelup", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL) //xp_user_levelup(player, level, exp)
	gForward[Forward_Exp_Add] = CreateMultiForward("xp_user_expadd", ET_CONTINUE, FP_CELL, FP_CELL) //xp_user_expadd(player, expadd)
	gForward[Forward_Exp_Set] = CreateMultiForward("xp_user_expset", ET_CONTINUE, FP_CELL, FP_CELL) //xp_user_expset(player, exptotal)
	
	register_cvar(CVAR_EXP_VERSION, PLUGIN_VERSION, FCVAR_SERVER|FCVAR_SPONLY)
	set_cvar_string(CVAR_EXP_VERSION, PLUGIN_VERSION)
}

/*
public event_newround()
{
	new id;
	for(id = 1; id<= g_maxplayers; id++)
		if(is_user_valid(id) && is_user_alive(id) && is_user_connected(id) && !zp_get_user_zombie(id)
		&& !zp_get_user_nemesis(id) && !zp_get_user_survivor(id))
			reward_user(id, 1)
}
*/

public Event_Intermission()
{
	set_task_ex(0.1, "Delayed_Intermission")
}
public Delayed_Intermission()
{
	new iPlayers[MAX_PLAYERS], iNum, id
	get_players_ex(iPlayers, iNum, GetPlayers_ExcludeHLTV|GetPlayers_ExcludeBots)

	for (--iNum; iNum >= 0; iNum--)
	{
		id = iPlayers[iNum]

		if (!is_user_connected(id))
			return

		reward_with_ammopacks(id)
	}
}
public fw_spawn_post(id)
{
	if(zp_get_user_zombie(id) || zp_get_user_survivor(id) || zp_get_user_nemesis(id)
	|| !is_user_alive(id) || !is_user_connected(id) || !is_user_valid(id)) {return;}
	else
		reward_user(id, 0)
}

public zp_user_humanized_post(id)
	fw_spawn_post(id)

reward_user(id, roundstart)
{
	if(get_pcvar_num(cvar_ammopacks) == 1 && roundstart == 1){ reward_with_ammopacks(id);}
}

reward_with_ammopacks(id)
{
	new ap = Ammopacks[gData[id][Data_Level]]
	zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + ap)
	//client_print(id, print_chat, "You received %d ammmopacks from the server", ap)
	UTIL_ColorChat(id, "^x04[User Vault]^x01 You received:^x04 %d^x01 ammmopacks from the server", ap)
}

public plugin_cfg()
{
	iVaultHandle = nvault_open(szVaultName)
	
	if(iVaultHandle == INVALID_HANDLE)
	{
		new szText[128]; formatex(szText, 127, "[UserVault] Error opening nVault file [%s]", szVaultName);
		set_fail_state(szText)
	}
	else
	{
		server_print("[UserVault] Database [%s] successfully loaded...", szVaultName)
		
		#if defined PRUNE_DATABASE
		nvault_prune(iVaultHandle, 0, get_systime() - (86400 * iExpiredDays))
		#endif
		
		FormatGlobalTopTen()
		
		#if defined UPDATE_MOTD
		if(file_exists(szFileMotd))
		{
			if(delete_file(szFileMotd))
			{
				if(write_file(szFileMotd, szMotd, -1)) server_print("[UserVault] File [%s] has been updated...", szFileMotd);
			}
		}
		#endif
	}
}

public plugin_end()
{
	nvault_close(iVaultHandle)
}

public client_putinserver(id)
{

	if (is_user_hltv(id))
		return;

	arrayset(gData[id], 0, sizeof(gData[]))
	
	get_user_name(id, gData[id][Data_Name], charsmax(gData[][Data_Name]))
	get_user_authid(id, gData[id][Data_Steamid], charsmax(gData[][Data_Steamid]))
	//get_user_ip(id, gData[id][Data_Ip], charsmax(gData[][Data_Ip]))
	set_task(0.1, "Load_Data", id, gData[id][Data_Name], sizeof(gData[][Data_Name]))
}

public client_disconnected(id)
{
	if (gData[id][Data_Connected])
	{
		gData[id][Data_PlayTime] += get_user_time(id)
		Save_Data(id, gData[id][Data_Name])
		gData[id][Data_Connected] = false
	}
}

public client_infochanged(id)
{
	if (!is_user_connected(id))
		return PLUGIN_HANDLED
	
	static szNames[2][32]
	get_user_name(id, szNames[0], charsmax(szNames[]))
	get_user_info(id, "name", szNames[1], charsmax(szNames[]))

	if (!equali(szNames[1], szNames[0]))
	{
		Save_Data(id, szNames[0])
		set_task(0.1, "Load_Data", id, szNames[1], sizeof(szNames[]))
		gData[id][Data_Name] = szNames[1]
		return PLUGIN_HANDLED
	}
	return PLUGIN_HANDLED
}

public CmdStats(id)
{
	if(!is_user_connected(id)) return PLUGIN_HANDLED;
	
	new menu = menu_create("\yPlayer Stats:", "PlayerStatsMenuHandler")
	new szUserId[32], iPlayers[32], iNum, j, id2, szName[32]
	get_players(iPlayers, iNum, "h")
	for(j=0;j<iNum;j++)
	{
		id2 = iPlayers[j]
		get_user_name(id2, szName, 31)
		formatex(szUserId, 31, "%d", get_user_userid(id2))
		menu_additem(menu, szName, szUserId, 0)
	}
	
	menu_display(id, menu, 0)
	
	return PLUGIN_HANDLED;
}

public PlayerStatsMenuHandler(id, menu, item)
{
	if(!is_user_connected(id))
	{
		menu_destroy(menu)
		return PLUGIN_HANDLED;
	}
	
	if(item == MENU_EXIT)
	{
		menu_destroy(menu)
		return PLUGIN_HANDLED;
	}
	
	new szData[6], szName[64]
	new _access, item_callback
	menu_item_getinfo(menu, item, _access, szData, 5, szName, 63, item_callback)
	
	new userid = str_to_num(szData)
	new player = find_player("k", userid)
	
	if(player && is_user_connected(player))
	{
		GetPlayerStats(player, id)
	}
	
	menu_destroy(menu)
	return PLUGIN_HANDLED;
}

public CmdShowRank(id)
{
	if(!is_user_connected(id)) return PLUGIN_HANDLED;
	
	static Float:ctime; ctime = get_gametime();
	if(fLastCmd > ctime)
	{
		//client_print(id, print_chat, "System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		UTIL_ColorChat(id, "^x04[UserVault]^x01 System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		return PLUGIN_HANDLED;
	}
	
	fLastCmd = ctime+2.0
	new iRank = SortPlayerRank(id)
	if(iRank == -1) UTIL_ColorChat(id, "^x04[UserVault]^x01 Your rank is not been saved yet, please rejoin the server.") //client_print(id, print_chat, "Your rank is not been saved yet, please rejoin the server.");
	else UTIL_ColorChat(id, "^x04%s^x01 rank is^x04 %d^x01/^x04%d^x01 -- Kills:^x04 %d^x01 Deaths:^x04 %d^x01 Stage:^x04 %d^x01 Points:^x04 %d^x01/^x04%d", gData[id][Data_Name], iRank, iTotalEntries, gData[id][Data_Kills], gData[id][Data_Deaths], szRanks[gData[id][Data_Level]], gData[id][Data_Exp], iEXP[gData[id][Data_Level]+1])
	
	return PLUGIN_HANDLED;
}

public CmdTopExpGlobal(id)
{
	if(!is_user_connected(id)) return PLUGIN_HANDLED;
	
	static Float:ctime; ctime = get_gametime();
	if(fLastCmd > ctime)
	{
		//client_print(id, print_chat, "System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		UTIL_ColorChat(id, "^x04[UserVault]^x01 System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		return PLUGIN_HANDLED;
	}
	
	fLastCmd = ctime+2.0
	show_motd(id, szMotd, "TOP-10 Players (GLOBAL)")
	
	return PLUGIN_HANDLED;
}

public CmdTopExpOnline(id)
{
	if(!is_user_connected(id)) return PLUGIN_HANDLED;
	
	static Float:ctime; ctime = get_gametime();
	if(fLastCmd > ctime)
	{
		client_print(id, print_chat, "System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		return PLUGIN_HANDLED;
	}
	
	fLastCmd = ctime+2.0
	static Sort[33][2]
	new players[32], num, count, index
	get_players(players, num)
	
	for(new i = 0; i < num; i++)
	{
		index = players[i]
		Sort[count][0] = index
		Sort[count][1] = gData[index][Data_Exp]
		count++
	}
	
	SortCustom2D(Sort, count, "CompareEXP")
	
	new y = clamp(count, 0, 10)
	new kindex, szMotd2[1536], len
	szMotd2[0] = 0
	
	add(szMotd2, charsmax(szMotd2),
	"<html><style>\
	body{background:url('https://static.brusheezy.com/system/resources/previews/000/013/939/non_2x/grunge-texture-by-krist-photoshop-textures.jpg') repeat;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
	.t{color:#afafaf;text-align:left; }\
	#h{background: #333;border-style: solid;border-width: 1px;border-color: #999;color:#E0E0E0;font-weight:bold;}\
	#p{color:#D41313;}\
	#n{color:#fff;}\
	</style><body>\
	<table cellspacing=0 width=100% class=t>")
	
	add(szMotd2, charsmax(szMotd2),
	"<tr><td id=h width=7%>#</td>\
	<td id=h>Name</td>\
	<td id=h>Points</td>\
	<td id=h>Kills</td>\
	<td id=h>Deaths</td>\
	<td id=h>Online</td></tr>")
	
	len = strlen(szMotd2)
	
	for(new x = 0; x < y; x++)
	{
		kindex = Sort[x][0]
		new iSec, szTimeFormat[32], szName[32]
		iSec = get_user_time(kindex)+gData[kindex][Data_PlayTime]
		GetTimeFormat(iSec, szTimeFormat, 31)
		get_user_name(kindex, szName, 31)
		replace_all(szName, 31, "#", " ")
		replace_all(szName, 31, "<", "&lt")
		replace_all(szName, 31, ">", "&gt")
		
		len += formatex(szMotd2[len], charsmax(szMotd2)-len,
		"<tr><td id=p>%d</td>\
		<td id=n>%s</td>\
		<td>%d</td>\
		<td>%d</td>\
		<td>%d</td>\
		<td>%s</td>", (x+1), szName, gData[kindex][Data_Exp], gData[kindex][Data_Kills], gData[kindex][Data_Deaths], szTimeFormat)
	}
	
	add(szMotd2, charsmax(szMotd2), "</table></body></html>")
	show_motd(id, szMotd2, "TOP Players (Now Online)")
	
	return PLUGIN_HANDLED;
}

public CompareEXP(elem1[], elem2[])
{
	if(elem1[1] > elem2[1]) return -1;
	else if(elem1[1] < elem2[1]) return 1;
	
	return 0;
}

public OnDeathMsg()
{
	new atk, vic, hs, szWpn[4]
	atk = read_data(1)
	vic = read_data(2)
	hs = read_data(3)
	read_data(4, szWpn, 3)
	
	if(is_user_connected(vic))
	{
		gData[vic][Data_Deaths]++
	}
	
	if((atk != vic) && is_user_connected(atk))
	{
		gData[atk][Data_Kills]++
		gData[atk][Data_Exp] += iExpKill
		
		if(hs)
		{
			gData[atk][Data_HeadShot]++
			gData[atk][Data_Exp] += iExpHeadShot
		}
		if(zp_get_user_nemesis(vic))
		{
			gData[atk][Data_NemKills]++
			gData[atk][Data_Exp] += iExpNemKill
		}
		else if(zp_get_user_survivor(vic))
		{
			gData[atk][Data_SurKills]++
			gData[atk][Data_Exp] += iExpSurKill
		}
		
		if(szWpn[0]=='k' && szWpn[1]=='n')
		{
			gData[atk][Data_Knife]++
			gData[atk][Data_Exp] += iExpKnife
			CheckPlayerLevel(atk)
			return;
		}
		
		if(szWpn[0]=='g' && szWpn[1]=='r')
		{
			gData[atk][Data_Nade]++
			gData[atk][Data_Exp] += iExpGrenade
			CheckPlayerLevel(atk)
			return;
		}
		
		CheckPlayerLevel(atk)
	}
}

public zp_user_infected_post(vic, atk)
{
	if(is_user_connected(vic))
	{
		gData[vic][Data_Deaths]++
	}
	
	if((atk != vic) && is_user_connected(atk))
	{
		gData[atk][Data_Kills]++
		gData[atk][Data_Exp] += iExpKill
		CheckPlayerLevel(atk)
	}
}

/*public OnPlayerPreThink(id)
{
	static Float:ctime; ctime = get_gametime();
	if(fLastHud[id] > ctime) return;
	
	fLastHud[id] = ctime+1.0
	
	if(!is_user_alive(id))
	{
		static iSpec; iSpec = entity_get_int(id, EV_INT_iuser2);
		if(!is_user_alive(iSpec)) return;
		
		set_hudmessage(128, 128, 128, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.6, 0.5, -1)
		ShowSyncHudMsg(id, iHudStats, "        SPECTATING^n%s ^n[ Country: %s ]^n[ HP: %.0f | Ammo: %d ]^n[ %s: %d/%d ]", gData[iSpec][Data_Name], gData[iSpec][Data_Country], entity_get_float(iSpec, EV_FL_health), zp_get_user_ammo_packs(iSpec),szRanks[gData[iSpec][Data_Level]], gData[iSpec][Data_Exp], iEXP[gData[iSpec][Data_Level]+1]) //entity_get_float(iSpec, EV_FL_armorvalue)
		return;
	}
	new iRank
	iRank = SortPlayerRank(id)
	set_hudmessage(4, 128, 4, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.6, 0.5, -1)
	ShowSyncHudMsg(id, iHudStats, "[ %s: %d/%d ]^n[ Rank: %d of %d ]^n              Alive ^n[ Humans:%d|%d:Zombies ]",szRanks[gData[id][Data_Level]], gData[id][Data_Exp], iEXP[gData[id][Data_Level]+1], iRank, iTotalEntries, zp_get_human_count(), zp_get_zombie_count() )
}
*/

public OnPlayerPreThink(id)
{
	static Float:ctime; ctime = get_gametime();
	if(fLastHud[id] > ctime) return;
	
	fLastHud[id] = ctime+1.0
	
	if(!is_user_alive(id))
	{
		static iSpec; iSpec = entity_get_int(id, EV_INT_iuser2);
		if(!is_user_alive(iSpec)) return;
		
		set_hudmessage(128, 128, 128, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.6, 0.5, -1)
		ShowSyncHudMsg(id, iHudStats, "SPECTATING: %s | COUNTRY: %s^nHP: %.0f | ARMOR: %.0f | PACKS: %d^nEXP: %d/%d | LEVEL: %s", gData[iSpec][Data_Name], gData[iSpec][Data_Country], entity_get_float(iSpec, EV_FL_health), entity_get_float(iSpec, EV_FL_armorvalue), zp_get_user_ammo_packs(iSpec), gData[iSpec][Data_Exp], iEXP[gData[iSpec][Data_Level]+1], szRanks[gData[iSpec][Data_Level]])
		return;
	}
	
	set_hudmessage(4, 128, 4, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.6, 0.5, -1)
	ShowSyncHudMsg(id, iHudStats, "HP: %.0f | ARMOR: %.0f | PACKS: %d^nEXP: %d/%d | LEVEL: %s^nCOUNTRY: %s", entity_get_float(id, EV_FL_health), entity_get_float(id, EV_FL_armorvalue), zp_get_user_ammo_packs(id), gData[id][Data_Exp], iEXP[gData[id][Data_Level]+1], szRanks[gData[id][Data_Level]], gData[id][Data_Country])
}

public _get_user_exp(id)
{
	return gData[id][Data_Exp];
}

public _set_user_exp(id, amount)
{
	gData[id][Data_Exp] = amount
}

public _get_user_playtime(id)
{
	return gData[id][Data_PlayTime];
}

public _set_user_playtime(id, amount)
{
	gData[id][Data_PlayTime] = amount
}

public _get_user_level(id)
{
	return gData[id][Data_Level];
}

public _set_user_level(id, amount)
{
	gData[id][Data_Level] = amount
}

public _get_user_deaths(id)
{
	return gData[id][Data_Deaths];
}

public _set_user_deaths(id, amount)
{
	gData[id][Data_Deaths] = amount
}

public _get_user_frags(id)
{
	return gData[id][Data_Kills];
}

public _set_user_frags(id, amount)
{
	gData[id][Data_Kills] = amount
}

public _get_user_headshot(id)
{
	return gData[id][Data_HeadShot];
}

public _set_user_headshot(id, amount)
{
	gData[id][Data_HeadShot] = amount
}

public _get_user_knife(id)
{
	return gData[id][Data_Knife];
}

public _set_user_knife(id, amount)
{
	gData[id][Data_Knife] = amount
}

public _get_user_nade(id)
{
	return gData[id][Data_Nade];
}

public _set_user_nade(id, amount)
{
	gData[id][Data_Nade] = amount
}

public _get_user_nemesis(id)
{
	return gData[id][Data_NemKills];
}

public _set_user_nemesis(id, amount)
{
	gData[id][Data_NemKills] = amount
}

public _get_user_survivor(id)
{
	return gData[id][Data_SurKills];
}

public _set_user_survivor(id, amount)
{
	gData[id][Data_SurKills] = amount
}

public _reset_user_data(id)
{
	gData[id][Data_Exp] = 0
	gData[id][Data_Kills] = 0
	gData[id][Data_Deaths] = 0
	gData[id][Data_HeadShot] = 0
	gData[id][Data_Knife] = 0
	gData[id][Data_Nade] = 0
	gData[id][Data_NemKills] = 0
	gData[id][Data_SurKills] = 0
	gData[id][Data_PlayTime] = 0
	gData[id][Data_Level] = 0
}

public _get_user_rank(id)
{
	return SortPlayerRank(id);
}

GetTimeFormat(seconds, szTime[], len)
{
	new days, hours, minutes
	days = seconds / 86400;
	hours = ( seconds / 3600 ) % 24;
	minutes = ( seconds / 60 ) % 60;
	seconds = seconds % 60;
	
	if(days)
	{
		formatex(szTime, len, "%dD %dH %dM %dS", days, hours, minutes, seconds)
		return;
	}
	
	if(hours)
	{
		formatex(szTime, len, "%dH %dM %dS", hours, minutes, seconds)
		return;
	}
	
	if(minutes)
	{
		formatex(szTime, len, "%dM %dS", minutes, seconds)
		return;
	}
	
	if(seconds)
	{
		formatex(szTime, len, "%dS", seconds)
	}
}

GetPlayerStats(id, caller)
{
	new szMotd2[1536], len
	szMotd2[0] = 0
	
	add(szMotd2, charsmax(szMotd2),
	"<html><style>\
	body{background: url('https://static.brusheezy.com/system/resources/previews/000/013/939/non_2x/grunge-texture-by-krist-photoshop-textures.jpg') repeat;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
	.t{color:#afafaf;text-align:left;  }\
	#h{background: #333;border-style: solid;border-width: 1px;border-color: #999;color:#E0E0E0;font-weight:bold;}\
	#p{color:#e6e6e6;}\
	#n{color:#fff;}\
	</style><body>\
	<table cellspacing=0 width=100% class=t>")
	
	add(szMotd2, charsmax(szMotd2),
	"<tr><td id=h width=30%>Statistics</td>\
	<td id=h>Ammount</td></tr>")
	
	len = strlen(szMotd2)

	new iSec, szTimeFormat[32], iRank, iPacks, szName[32]
	iSec = get_user_time(id)+gData[id][Data_PlayTime]
	GetTimeFormat(iSec, szTimeFormat, 31)
	iRank = SortPlayerRank(id)
	iPacks = zp_get_user_ammo_packs(id)
	get_user_name(id, szName, 31)
	replace_all(szName, 31, "#", " ")
	replace_all(szName, 31, "<", "&lt")
	replace_all(szName, 31, ">", "&gt")
	
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Nickname</td><td>%s</td>", szName)
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>SteamID</td><td>%s</td>", gData[id][Data_Steamid])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Country</td><td>%s</td>", gData[id][Data_Country])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Rank</td><td>%d of %d</td>", iRank, iTotalEntries)
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Ammo</td><td>%d</td>", iPacks)
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Points</td><td>%d</td>", gData[id][Data_Exp])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Stage</td><td>%s</td>", szRanks[gData[id][Data_Level]])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Kills</td><td>%d</td>", gData[id][Data_Kills])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Deaths</td><td>%d</td>", gData[id][Data_Deaths])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Headshot kills</td><td>%d</td>", gData[id][Data_HeadShot])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Knife kills</td><td>%d</td>", gData[id][Data_Knife])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Grenade kills</td><td>%d</td>", gData[id][Data_Nade])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Nemesis kills</td><td>%d</td>", gData[id][Data_NemKills])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Survivor kills</td><td>%d</td>", gData[id][Data_SurKills])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Online time</td><td>%s</td>", szTimeFormat)
	
	add(szMotd2, charsmax(szMotd2), "</table></body></html>")
	show_motd(caller, szMotd2, "Player Statistics")
}

public CheckPlayerLevel(id)
{
	while((gData[id][Data_Exp] >= iEXP[gData[id][Data_Level]+1]))
	{
		gData[id][Data_Level]++
		UTIL_ColorChat(id, "^x04%s^x01 has been promoted to the Stage of^x04 %s^x01 with^x04 %d^x01 Points.", gData[id][Data_Name], szRanks[gData[id][Data_Level]], gData[id][Data_Exp])
		ExecuteForward(gForward[Forward_Levelup], gForward[Forward_Result], id, gData[id][Data_Level], gData[id][Data_Exp])
	}
}


public Load_Data(szName[], id)
{
	if(!is_user_connected(id))
		return
	
	new szName[32], szKey[50], szData[164]
	copy(szName, 31, gData[id][Data_Name])
	replace_all(szName, 31, " ", "#")
	formatex(szKey, 49, "%s#EXP", szName)
	//formatex(szKey, 49, "%s#EXP", gData[id][Data_Name])
	//formatex(szKey, 49, "%s#EXP", gData[id][Data_Ip])
	

	if (nvault_get(iVaultHandle, szName, szData, charsmax(szData)))
	{
		//replace_all(szData, charsmax(szData), "#", " ")
	
		new szExp[8], szKills[8], szDeaths[8], szHeadShot[8], szKnife[8], szNade[8], szNemKill[8], szSurKill[8], szPlayTime[8], szLevel[8]
		parse(szData, szExp, charsmax(szExp), szKills, charsmax(szKills), szDeaths, charsmax(szDeaths), szHeadShot, charsmax(szHeadShot), szKnife, charsmax(szKnife),
			szNade, charsmax(szNade), szNemKill, charsmax(szNemKill), szSurKill, charsmax(szSurKill), szPlayTime, charsmax(szPlayTime), szLevel, charsmax(szLevel))

		gData[id][Data_Exp] = str_to_num(szExp)
		gData[id][Data_Kills] = str_to_num(szKills)
		gData[id][Data_Deaths] = str_to_num(szDeaths)
		gData[id][Data_HeadShot] = str_to_num(szHeadShot)
		gData[id][Data_Knife] = str_to_num(szKnife)
		gData[id][Data_Nade] = str_to_num(szNade)
		gData[id][Data_NemKills] = str_to_num(szNemKill)
		gData[id][Data_SurKills] = str_to_num(szSurKill)
		gData[id][Data_PlayTime] = str_to_num(szPlayTime)
		gData[id][Data_Level] = str_to_num(szLevel)
	}
	else
	{
		_reset_user_data(id)
	}
	gData[id][Data_Connected] = true
}

public Save_Data(id, szName[])
{
	new szData[MAX_FMT_LENGTH]
	formatex(szData, charsmax(szData), "%d %d %d %d %d %d %d %d %d %d %s", gData[id][Data_Exp], gData[id][Data_Kills], gData[id][Data_Deaths], gData[id][Data_HeadShot], gData[id][Data_Knife], gData[id][Data_Nade], gData[id][Data_NemKills], gData[id][Data_SurKills], gData[id][Data_PlayTime], gData[id][Data_Level], gData[id][Data_Name])
	nvault_set(iVaultHandle, szName, szData)
}

FormatGlobalTopTen()
{
	enum _:VaultData
	{
		VD_Key[64],
		VD_Value
	}
	
	const MAX_ENTRIES = 10
	new vault = nvault_util_open(szVaultName)
	new Array:entries = ArrayCreate(VaultData)
	new sizeEntries
	new numEntries = nvault_util_count(vault)
	new data[VaultData], value[128], data2[VaultData]
	
	for(new i = 0, pos, timestamp; i < numEntries; i++)
	{
		pos = nvault_util_read(vault, pos, data[VD_Key], charsmax(data[VD_Key]), value, charsmax(value), timestamp)
		data[VD_Value] = str_to_num(value)
		
		if(sizeEntries == 0)
		{
			ArrayPushArray(entries, data)
			sizeEntries++;
		}
		else
		{
			for(timestamp = 0; timestamp <= sizeEntries; timestamp++)
			{
				if(timestamp == sizeEntries)
				{
					if(sizeEntries < MAX_ENTRIES)
					{
						ArrayPushArray(entries, data)
						sizeEntries++;
					}
					
					break;
				}
				
				ArrayGetArray(entries, timestamp, data2)
				
				if(data[VD_Value] >= data2[VD_Value])
				{
					ArrayInsertArrayBefore(entries, timestamp, data)
					
					if(sizeEntries < MAX_ENTRIES)
					{
						sizeEntries++;
					}
					else
					{
						ArrayDeleteItem(entries, sizeEntries)
					}
					
					break;
				}
			}
		}
	}
	
	nvault_util_close(vault)

	new len
	szMotd[0] = 0
	
	add(szMotd, charsmax(szMotd),
	"<html><style>\
	body{background:url('https://static.brusheezy.com/system/resources/previews/000/013/939/non_2x/grunge-texture-by-krist-photoshop-textures.jpg') repeat;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
	.t{color:#afafaf;text-align:left; }\
	#h{background: #333;border-style: solid;border-width: 1px;border-color: #999;color:#E0E0E0;font-weight:bold;}\
	#p{color:#D41313;}\
	#n{color:#fff;}\
	</style><body>\
	<table cellspacing=0 width=100% class=t>")
	
	add(szMotd, charsmax(szMotd),
	"<tr><td id=h width=7%>#</td>\
	<td id=h>Name</td>\
	<td id=h>Points</td>\
	<td id=h>Kills</td>\
	<td id=h>Deaths</td>\
	<td id=h>Online</td></tr>")
	
	len = strlen(szMotd)
	
	for(new i = 0; i < sizeEntries; i++)
	{
		ArrayGetArray(entries, i, data)
		//data[VD_Key][20] = 0
		
		new szDataNew[164]
		nvault_get(iVaultHandle, data[VD_Key], szDataNew, charsmax(szDataNew))
		
		new szExp[8], szKills[8], szDeaths[8], szHeadShot[8], szKnife[8], szNade[8], szNemKill[8], szSurKill[8], szPlayTime[8], szLevel[8], szName3[32]
		parse(szDataNew, szExp, 7, szKills, 7, szDeaths, 7, szHeadShot, 7, szKnife, 7, szNade, 7, szNemKill, 7, szSurKill, 7, szPlayTime, 7, szLevel, 7, szName3, 31)
		
		new iSec, szOnline[32]
		iSec = str_to_num(szPlayTime)
		GetTimeFormat(iSec, szOnline, 31)
		replace_all(szName3, 31, "#", " ")
		//replace_all(szName3, 31, " ", "#")
		replace_all(szName3, 31, "<", "&lt")
		replace_all(szName3, 31, ">", "&gt")
		
		len += formatex(szMotd[len], charsmax(szMotd)-len,
		"<tr><td id=p>%d</td>\
		<td id=n>%s</td>\
		<td>%s</td>\
		<td>%s</td>\
		<td>%s</td>\
		<td>%s</td>", (i+1), szName3, szExp, szKills, szDeaths, szOnline)
	}
	
	add(szMotd, charsmax(szMotd), "</table></body></html>")
	ArrayDestroy(entries)
}

SortPlayerRank(id)
{
	new szName[32], szKey[50]
	copy(szName, 31, gData[id][Data_Name])
	replace_all(szName, 31, "#", " ")
	formatex(szKey, 49, "%s#EXP", szName)
	//formatex(szKey, 49, "%s#EXP", gData[id][Data_Name])
	//formatex(szKey, 49, "%s#EXP", gData[id][Data_Ip])
	
	enum _:VaultData
	{
		VD_Key[64],
		VD_Value
	}
	
	new vault = nvault_util_open(szVaultName)
	new Array:entries = ArrayCreate(VaultData)
	new sizeEntries
	new numEntries = nvault_util_count(vault)
	new data[VaultData], value[128], data2[VaultData]
	
	for(new i = 0, pos, timestamp; i < numEntries; i++)
	{
		pos = nvault_util_read(vault, pos, data[VD_Key], charsmax(data[VD_Key]), value, charsmax(value), timestamp)
		data[VD_Value] = str_to_num(value)
		
		if(sizeEntries == 0)
		{
			ArrayPushArray(entries, data)
			sizeEntries++;
		}
		else
		{
			for(timestamp = 0; timestamp <= sizeEntries; timestamp++)
			{
				if(timestamp == sizeEntries)
				{
					if(sizeEntries < numEntries)
					{
						ArrayPushArray(entries, data)
						sizeEntries++;
					}
					
					break;
				}
				
				ArrayGetArray(entries, timestamp, data2)
				
				if(data[VD_Value] >= data2[VD_Value])
				{
					ArrayInsertArrayBefore(entries, timestamp, data)
					
					if(sizeEntries < numEntries)
					{
						sizeEntries++;
					}
					else
					{
						ArrayDeleteItem(entries, sizeEntries)
					}
					
					break;
				}
			}
		}
	}
	
	nvault_util_close(vault)
	iTotalEntries = sizeEntries
	
	for(new i = 0; i < sizeEntries; i++)
	{
		ArrayGetArray(entries, i, data)
		if(equal(data[VD_Key],szKey))
		{
			gData[id][Data_Rank] = i+1
			break;
		}
	}
	
	ArrayDestroy(entries)
	return gData[id][Data_Rank];
}

UTIL_ColorChat(id, const szText[], any:...)
{
	new szBuffer[512]
	
	if(!id)
	{
		new iPlayers[32], iNum, y, id2
		get_players(iPlayers, iNum, "ch")
		for(y=0;y<iNum;y++)
		{
			id2 = iPlayers[y]
			if(!is_user_connected(id2)) continue;
			
			vformat(szBuffer, charsmax(szBuffer), szText, 3)
			message_begin(MSG_ONE_UNRELIABLE, iMsgSayText, _, id2)
			write_byte(id2)
			write_string(szBuffer)
			message_end()
		}
	}
	else
	{
		vformat(szBuffer, charsmax(szBuffer), szText, 3)
		message_begin(MSG_ONE, iMsgSayText, _, id)
		write_byte(id)
		write_string(szBuffer)
		message_end()
	}
}

stock client_cmd_ex(id, const command[], any:...)
{
	#pragma unused command
	
	if (id == 0 || is_user_connected(id))
	{
		new szMessage[256]
		
		format_args(szMessage, charsmax(szMessage), 1)
		
		message_begin(id == 0 ? MSG_ALL : MSG_ONE, 51, _, id)
		write_byte(strlen(szMessage) + 2)
		write_byte(10)
		write_string(szMessage)
		message_end()
	}
}
Пиша от избата, защото горе имаме течове..

Потребителски аватар

OciXCrom TM
Администратор
Администратор
Мнения: 4972
Регистриран: 06 окт 2016, 19:20
Местоположение: /resetscore
Се отблагодари: 53 пъти
Получена благодарност: 445 пъти
Години: 21
Контакти:

nVault; Премахване на проверка за парола

Мнение от OciXCrom TM » 16 фев 2019, 14:52

И в двата случая се ползва същата функция за да се вземе ранкът - SortPlayerRank(id). Не виждам логика да показва различна стойност на две места. В краен случай направи го в командата да бъде new iRank = SortPlayerRank(id) + 1 за да не започва от 0. Сигурен ли си, че си компилирал кода след последните промени, понеже такова нещо не ми звучи нормално?

Относно OnPlayerPreThink:

Код: Избери всички

static Float:ctime; ctime = get_gametime();
	if(fLastHud[id] > ctime) return;
	
	fLastHud[id] = ctime+1.0
Според написаното, fLastHud[id] винаги е по-голямо от ctime, съответно условието fLastHud[id] > ctime винаги ще се изпълнява и ще връща return. Трябва да направиш fLastHud[id] = ctime, без + 1.0.

Потребителски аватар

Автор на темата
LayerFort DJBosma
Потребител
Потребител
Мнения: 50
Регистриран: 25 дек 2018, 04:14
Местоположение: Alkmaar
Се отблагодари: 2 пъти
Получена благодарност: 2 пъти
Години: 24
Контакти:

nVault; Премахване на проверка за парола

Мнение от LayerFort DJBosma » 16 фев 2019, 16:17

Код: Избери всички

RegisterHam(Ham_Player_PreThink, "player", "OnPlayerPreThink")
Бях забравил

С добавените от теб предложени промени сега всеки в топа има ранк 1/X. Последно това съм променял, но без успех, навсякъде ранка е 0/X

Код: Избери всички

public client_putinserver(id)
{

	if (is_user_hltv(id))
		return;

	arrayset(gData[id], 0, sizeof(gData[]))
	
	get_user_name(id, gData[id][Data_Name], charsmax(gData[][Data_Name]))
	get_user_authid(id, gData[id][Data_Steamid], charsmax(gData[][Data_Steamid]))
	//get_user_ip(id, gData[id][Data_Ip], charsmax(gData[][Data_Ip]))
	set_task(0.1, "Load_Data", id, gData[id][Data_Name], sizeof(gData[][Data_Name]))
}

Код: Избери всички

public client_infochanged(id)
{
	if (!is_user_connected(id))
		return PLUGIN_HANDLED
	
	static szNames[2][32]
	get_user_name(id, szNames[0], charsmax(szNames[]))
	get_user_info(id, "name", szNames[1], charsmax(szNames[]))

	if (!equali(szNames[1], szNames[0]))
	{
		Save_Data(id, szNames[0])
		set_task(0.1, "Load_Data", id, szNames[1], sizeof(szNames[]))
		gData[id][Data_Name] = szNames[1]
		return PLUGIN_HANDLED
	}
	return PLUGIN_HANDLED
}

Код: Избери всички

public Load_Data(szName[], id)
{
	if(!is_user_connected(id))
		return
	
	new szName[32], szKey[50], szData[164]
	copy(szName, 31, gData[id][Data_Name])
	replace_all(szName, 31, " ", "#")
	formatex(szKey, 49, "%s#EXP", szName)
	//formatex(szKey, 49, "%s#EXP", gData[id][Data_Name])
	//formatex(szKey, 49, "%s#EXP", gData[id][Data_Ip])	

	if (nvault_get(iVaultHandle, szName, szData, charsmax(szData)))
	{
		//replace_all(szData, charsmax(szData), "#", " ")
	
		new szExp[8], szKills[8], szDeaths[8], szHeadShot[8], szKnife[8], szNade[8], szNemKill[8], szSurKill[8], szPlayTime[8], szLevel[8]
		parse(szData, szExp, charsmax(szExp), szKills, charsmax(szKills), szDeaths, charsmax(szDeaths), szHeadShot, charsmax(szHeadShot), szKnife, charsmax(szKnife),
			szNade, charsmax(szNade), szNemKill, charsmax(szNemKill), szSurKill, charsmax(szSurKill), szPlayTime, charsmax(szPlayTime), szLevel, charsmax(szLevel))

		gData[id][Data_Exp] = str_to_num(szExp)
		gData[id][Data_Kills] = str_to_num(szKills)
		gData[id][Data_Deaths] = str_to_num(szDeaths)
		gData[id][Data_HeadShot] = str_to_num(szHeadShot)
		gData[id][Data_Knife] = str_to_num(szKnife)
		gData[id][Data_Nade] = str_to_num(szNade)
		gData[id][Data_NemKills] = str_to_num(szNemKill)
		gData[id][Data_SurKills] = str_to_num(szSurKill)
		gData[id][Data_PlayTime] = str_to_num(szPlayTime)
		gData[id][Data_Level] = str_to_num(szLevel)
	}
	else
	{
		_reset_user_data(id)
	}
	gData[id][Data_Connected] = true
}

Код: Избери всички

public Save_Data(id, szName[])
{
	new szKey[50], szData[MAX_FMT_LENGTH]
	replace_all(gData[id][Data_Name], 31, " ", "#")
	formatex(szKey, 49, "%s#EXP", gData[id][Data_Name])
	formatex(szData, charsmax(szData), "%d %d %d %d %d %d %d %d %d %d %s", gData[id][Data_Exp], gData[id][Data_Kills], gData[id][Data_Deaths], gData[id][Data_HeadShot], gData[id][Data_Knife], gData[id][Data_Nade], gData[id][Data_NemKills], gData[id][Data_SurKills], gData[id][Data_PlayTime], gData[id][Data_Level], gData[id][Data_Name])
	nvault_set(iVaultHandle, szName, szData)
}
Пиша от избата, защото горе имаме течове..

Потребителски аватар

Автор на темата
LayerFort DJBosma
Потребител
Потребител
Мнения: 50
Регистриран: 25 дек 2018, 04:14
Местоположение: Alkmaar
Се отблагодари: 2 пъти
Получена благодарност: 2 пъти
Години: 24
Контакти:

nVault; Премахване на проверка за парола

Мнение от LayerFort DJBosma » 18 фев 2019, 17:48

*бут*

Пробвах

replace_all(szName, 31, " ", "#")
С
replace_all(szName, 31, "#", " ")

Безуспешно.

В топа ранка се показва правилно но все пак..
Пиша от избата, защото горе имаме течове..

Потребителски аватар

Автор на темата
LayerFort DJBosma
Потребител
Потребител
Мнения: 50
Регистриран: 25 дек 2018, 04:14
Местоположение: Alkmaar
Се отблагодари: 2 пъти
Получена благодарност: 2 пъти
Години: 24
Контакти:

nVault; Премахване на проверка за парола

Мнение от LayerFort DJBosma » 20 фев 2019, 12:56

Ето и отново целия плъгин.

Код: Избери всички

#include <amxmodx>
#include <amxmisc>
#include <hamsandwich>
#include <nvault_util>
#include <fakemeta>
#include <engine>
#include <zombieplague>

new const szRanks[][] = 
{
    "Guardsman",
    "Healer",
    "Protector",
    "Warrior",
    "High Warrior",
    "Alpha Warrior",
    "Archwarrior",
    "High Archwarrior",
    "Alpha Archwarrior",
    "Destroyer",
    "High Destroyer",
    "Alpha Destroyer",
    "Commander",
    "High Commander",
    "Alpha Commander",
    "Baron",
    "High Baron",
    "Alpha Baron",
    "King",
    "Alpha King",
    "Overlord",
    "Hacker"
}

new const iEXP[] = 
{
    0,
    50,
    100,
    200,
    250,
    300,
    350,
    400,
    450,
    500,
    600,
    700,
    700,
    800,
    900,
    1100,
    1250,
    1500,
    2000,
    2500,
    3000,
    999999999
}

enum _:Player_Data
{
	Data_Steamid[35],
	//Data_Ip[16],
	Data_Name[32],
	Data_Exp,
	Data_Kills,
	Data_Deaths,
	Data_HeadShot,
	Data_Knife,
	Data_Nade,
	Data_NemKills,
	Data_SurKills,
	Data_PlayTime,
	Data_Level,
	Data_Country[46],
	Data_Rank,
	Data_Connected,
	MAX_PLAYER_DATA
}

enum _:Forward_Data
{
	Forward_Levelup,
	Forward_Exp_Add,
	Forward_Exp_Set,
	Forward_Result,
	MAX_FORWARD_DATA
}

new iVaultHandle, gData[33][MAX_PLAYER_DATA], iHudStats, Float:fLastHud[33], szMotd[1536], gForward[MAX_FORWARD_DATA], Float:fLastCmd, iTotalEntries, iMsgSayText
const iExpKill = 1
const iExpHeadShot = 3
const iExpKnife = 4
const iExpGrenade = 4
const iExpNemKill = 5
const iExpSurKill = 5
const Float:HUD_STATS_X = 0.77//-1.0
const Float:HUD_STATS_Y = 0.6//0.8
new const szVaultName[] = "fter-zpuservault"

#define is_user_valid(%0) (0<%0<33)
new cvar_ammopacks
//new g_maxplayers

new Ammopacks[22] = {
    1,
    2,
    3,
    4,
    5,
    6,
    7,
    8,
    9,
    10,
    11,
    12,
    13,
    14,
    15,
    16,
    17,
    18,
    19,
    20,
    21,
    0
}

//Uncomment this to update motd.txt on map loaded to show global top-10 players.
#define UPDATE_MOTD

//Uncomment this to enable nvault prune.
#define PRUNE_DATABASE


#if defined UPDATE_MOTD
new const szFileMotd[] = "motd.txt"
#endif

#if defined PRUNE_DATABASE
const iExpiredDays = 30
#endif

public plugin_natives()
{
	register_native("xp_get_user_exp","_get_user_exp",1)
	register_native("xp_set_user_exp","_set_user_exp",1)
	
	register_native("xp_get_user_playtime","_get_user_playtime",1)
	register_native("xp_set_user_playtime","_set_user_playtime",1)
	
	register_native("xp_get_user_level","_get_user_level",1)
	register_native("xp_set_user_level","_set_user_level",1)
	
	register_native("xp_get_user_deaths","_get_user_deaths",1)
	register_native("xp_set_user_deaths","_set_user_deaths",1)
	
	register_native("xp_get_user_frags","_get_user_frags",1)
	register_native("xp_set_user_frags","_set_user_frags",1)
	
	register_native("xp_get_user_headshot","_get_user_headshot",1)
	register_native("xp_set_user_headshot","_set_user_headshot",1)
	
	register_native("xp_get_user_knife","_get_user_knife",1)
	register_native("xp_set_user_knife","_set_user_knife",1)
	
	register_native("xp_get_user_nade","_get_user_nade",1)
	register_native("xp_set_user_nade","_set_user_nade",1)
	
	register_native("xp_get_user_nemesis","_get_user_nemesis",1)
	register_native("xp_set_user_nemesis","_set_user_nemesis",1)
	
	register_native("xp_get_user_survivor","_get_user_survivor",1)
	register_native("xp_set_user_survivor","_set_user_survivor",1)
	
	register_native("xp_reset_user_data","_reset_user_data",1)
	register_native("xp_get_user_rank","_get_user_rank",1)
	register_native("xp_check_user_level","CheckPlayerLevel",1)
}

public plugin_init()
{
	new const PLUGIN_VERSION[] = "1.0"//0.0.5
	new const CVAR_EXP_VERSION[] = "n4d_zpstats"
	register_plugin("[ZP] UserVault", PLUGIN_VERSION, "wbyokomo, huehue, djbosma")
	
	iHudStats = CreateHudSyncObj()
	iMsgSayText = get_user_msgid("SayText")
	
	//register_event("HLTV", "event_newround", "a", "1=0", "2=0")
	register_event("DeathMsg", "OnDeathMsg", "a") //use deathmsg easy to trace weapon and hitplace
	register_event_ex("30", "Event_Intermission", RegisterEvent_Global)
	
	RegisterHam(Ham_Player_PreThink, "player", "OnPlayerPreThink")
	
	register_clcmd("say /stats" , "CmdStats")
	register_clcmd("say /rank", "CmdShowRank")
	register_clcmd("say /top15", "CmdTopExpGlobal")
	register_clcmd("say /top10", "CmdTopExpGlobal")
	register_clcmd("say /toponline", "CmdTopExpOnline")
	
	register_clcmd("say_team /stats" , "CmdStats")
	register_clcmd("say_team /rank", "CmdShowRank")
	register_clcmd("say_team /top15", "CmdTopExpGlobal")
	register_clcmd("say_team /top10", "CmdTopExpGlobal")
	register_clcmd("say_team /toponline", "CmdTopExpOnline")
	
	cvar_ammopacks = register_cvar("xp_ammopacks_reward", "1")
	//g_maxplayers = get_maxplayers()
	

	gForward[Forward_Levelup] = CreateMultiForward("xp_user_levelup", ET_IGNORE, FP_CELL, FP_CELL, FP_CELL) //xp_user_levelup(player, level, exp)
	gForward[Forward_Exp_Add] = CreateMultiForward("xp_user_expadd", ET_CONTINUE, FP_CELL, FP_CELL) //xp_user_expadd(player, expadd)
	gForward[Forward_Exp_Set] = CreateMultiForward("xp_user_expset", ET_CONTINUE, FP_CELL, FP_CELL) //xp_user_expset(player, exptotal)
	
	register_cvar(CVAR_EXP_VERSION, PLUGIN_VERSION, FCVAR_SERVER|FCVAR_SPONLY)
	set_cvar_string(CVAR_EXP_VERSION, PLUGIN_VERSION)
}

/*
public event_newround()
{
	new id;
	for(id = 1; id<= g_maxplayers; id++)
		if(is_user_valid(id) && is_user_alive(id) && is_user_connected(id) && !zp_get_user_zombie(id)
		&& !zp_get_user_nemesis(id) && !zp_get_user_survivor(id))
			reward_user(id, 1)
}
*/

public Event_Intermission()
{
	set_task_ex(0.1, "Delayed_Intermission")
}
public Delayed_Intermission()
{
	new iPlayers[MAX_PLAYERS], iNum, id
	get_players_ex(iPlayers, iNum, GetPlayers_ExcludeHLTV|GetPlayers_ExcludeBots)

	for (--iNum; iNum >= 0; iNum--)
	{
		id = iPlayers[iNum]

		if (!is_user_connected(id))
			return

		reward_with_ammopacks(id)
	}
}
public fw_spawn_post(id)
{
	if(zp_get_user_zombie(id) || zp_get_user_survivor(id) || zp_get_user_nemesis(id)
	|| !is_user_alive(id) || !is_user_connected(id) || !is_user_valid(id)) {return;}
	else
		reward_user(id, 0)
}

public zp_user_humanized_post(id)
	fw_spawn_post(id)

reward_user(id, roundstart)
{
	if(get_pcvar_num(cvar_ammopacks) == 1 && roundstart == 1){ reward_with_ammopacks(id);}
}

reward_with_ammopacks(id)
{
	new ap = Ammopacks[gData[id][Data_Level]]
	zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id) + ap)
	//client_print(id, print_chat, "You received %d ammmopacks from the server", ap)
	UTIL_ColorChat(id, "^x04[User Vault]^x01 You received:^x04 %d^x01 ammmopacks from the server", ap)
}

public plugin_cfg()
{
	iVaultHandle = nvault_open(szVaultName)
	
	if(iVaultHandle == INVALID_HANDLE)
	{
		new szText[128]; formatex(szText, 127, "[UserVault] Error opening nVault file [%s]", szVaultName);
		set_fail_state(szText)
	}
	else
	{
		server_print("[UserVault] Database [%s] successfully loaded...", szVaultName)
		
		#if defined PRUNE_DATABASE
		nvault_prune(iVaultHandle, 0, get_systime() - (86400 * iExpiredDays))
		#endif
		
		FormatGlobalTopTen()
		
		#if defined UPDATE_MOTD
		if(file_exists(szFileMotd))
		{
			if(delete_file(szFileMotd))
			{
				if(write_file(szFileMotd, szMotd, -1)) server_print("[UserVault] File [%s] has been updated...", szFileMotd);
			}
		}
		#endif
	}
}

public plugin_end()
{
	nvault_close(iVaultHandle)
}

public client_putinserver(id)
{

	if (is_user_hltv(id))
		return;

	arrayset(gData[id], 0, sizeof(gData[]))
	
	get_user_name(id, gData[id][Data_Name], charsmax(gData[][Data_Name]))
	get_user_authid(id, gData[id][Data_Steamid], charsmax(gData[][Data_Steamid]))
	//get_user_ip(id, gData[id][Data_Ip], charsmax(gData[][Data_Ip]))
	set_task(0.1, "Load_Data", id, gData[id][Data_Name], sizeof(gData[][Data_Name]))
}

public client_disconnected(id)
{
	if (gData[id][Data_Connected])
	{
		gData[id][Data_PlayTime] += get_user_time(id)
		Save_Data(id, gData[id][Data_Name])
		gData[id][Data_Connected] = false
	}
}

public client_infochanged(id)
{
	if (!is_user_connected(id))
		return PLUGIN_HANDLED
	
	static szNames[2][32]
	get_user_name(id, szNames[0], charsmax(szNames[]))
	get_user_info(id, "name", szNames[1], charsmax(szNames[]))

	if (!equali(szNames[1], szNames[0]))
	{
		Save_Data(id, szNames[0])
		set_task(0.1, "Load_Data", id, szNames[1], sizeof(szNames[]))
		gData[id][Data_Name] = szNames[1]
		return PLUGIN_HANDLED
	}
	return PLUGIN_HANDLED
}

public CmdStats(id)
{
	if(!is_user_connected(id)) return PLUGIN_HANDLED;
	
	new menu = menu_create("\yPlayer Stats:", "PlayerStatsMenuHandler")
	new szUserId[32], iPlayers[32], iNum, j, id2, szName[32]
	get_players(iPlayers, iNum, "h")
	for(j=0;j<iNum;j++)
	{
		id2 = iPlayers[j]
		get_user_name(id2, szName, 31)
		formatex(szUserId, 31, "%d", get_user_userid(id2))
		menu_additem(menu, szName, szUserId, 0)
	}
	
	menu_display(id, menu, 0)
	
	return PLUGIN_HANDLED;
}

public PlayerStatsMenuHandler(id, menu, item)
{
	if(!is_user_connected(id))
	{
		menu_destroy(menu)
		return PLUGIN_HANDLED;
	}
	
	if(item == MENU_EXIT)
	{
		menu_destroy(menu)
		return PLUGIN_HANDLED;
	}
	
	new szData[6], szName[64]
	new _access, item_callback
	menu_item_getinfo(menu, item, _access, szData, 5, szName, 63, item_callback)
	
	new userid = str_to_num(szData)
	new player = find_player("k", userid)
	
	if(player && is_user_connected(player))
	{
		GetPlayerStats(player, id)
	}
	
	menu_destroy(menu)
	return PLUGIN_HANDLED;
}

public CmdShowRank(id)
{
	if(!is_user_connected(id)) return PLUGIN_HANDLED;
	
	static Float:ctime; ctime = get_gametime();
	if(fLastCmd > ctime)
	{
		//client_print(id, print_chat, "System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		UTIL_ColorChat(id, "^x04[UserVault]^x01 System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		return PLUGIN_HANDLED;
	}
	
	fLastCmd = ctime+2.0
	new iRank = SortPlayerRank(id)
	if(iRank == -1) UTIL_ColorChat(id, "^x04[UserVault]^x01 Your rank is not been saved yet, please rejoin the server.") //client_print(id, print_chat, "Your rank is not been saved yet, please rejoin the server.");
	else UTIL_ColorChat(id, "^x04%s^x01 rank is^x04 %d^x01/^x04%d^x01 -- Kills:^x04 %d^x01 Deaths:^x04 %d^x01 Stage:^x04 %d^x01 Points:^x04 %d^x01/^x04%d", gData[id][Data_Name], iRank, iTotalEntries, gData[id][Data_Kills], gData[id][Data_Deaths], szRanks[gData[id][Data_Level]], gData[id][Data_Exp], iEXP[gData[id][Data_Level]+1])
	
	return PLUGIN_HANDLED;
}

public CmdTopExpGlobal(id)
{
	if(!is_user_connected(id)) return PLUGIN_HANDLED;
	
	static Float:ctime; ctime = get_gametime();
	if(fLastCmd > ctime)
	{
		//client_print(id, print_chat, "System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		UTIL_ColorChat(id, "^x04[UserVault]^x01 System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		return PLUGIN_HANDLED;
	}
	
	fLastCmd = ctime+2.0
	show_motd(id, szMotd, "TOP-10 Players (GLOBAL)")
	
	return PLUGIN_HANDLED;
}

public CmdTopExpOnline(id)
{
	if(!is_user_connected(id)) return PLUGIN_HANDLED;
	
	static Float:ctime; ctime = get_gametime();
	if(fLastCmd > ctime)
	{
		client_print(id, print_chat, "System is busy please wait for %.1f second(s).", fLastCmd-ctime)
		return PLUGIN_HANDLED;
	}
	
	fLastCmd = ctime+2.0
	static Sort[33][2]
	new players[32], num, count, index
	get_players(players, num)
	
	for(new i = 0; i < num; i++)
	{
		index = players[i]
		Sort[count][0] = index
		Sort[count][1] = gData[index][Data_Exp]
		count++
	}
	
	SortCustom2D(Sort, count, "CompareEXP")
	
	new y = clamp(count, 0, 10)
	new kindex, szMotd2[1536], len
	szMotd2[0] = 0
	
	add(szMotd2, charsmax(szMotd2),
	"<html><style>\
	body{background:url('https://static.brusheezy.com/system/resources/previews/000/013/939/non_2x/grunge-texture-by-krist-photoshop-textures.jpg') repeat;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
	.t{color:#afafaf;text-align:left; }\
	#h{background: #333;border-style: solid;border-width: 1px;border-color: #999;color:#E0E0E0;font-weight:bold;}\
	#p{color:#D41313;}\
	#n{color:#fff;}\
	</style><body>\
	<table cellspacing=0 width=100% class=t>")
	
	add(szMotd2, charsmax(szMotd2),
	"<tr><td id=h width=7%>#</td>\
	<td id=h>Name</td>\
	<td id=h>Points</td>\
	<td id=h>Kills</td>\
	<td id=h>Deaths</td>\
	<td id=h>Online</td></tr>")
	
	len = strlen(szMotd2)
	
	for(new x = 0; x < y; x++)
	{
		kindex = Sort[x][0]
		new iSec, szTimeFormat[32], szName[32]
		iSec = get_user_time(kindex)+gData[kindex][Data_PlayTime]
		GetTimeFormat(iSec, szTimeFormat, 31)
		get_user_name(kindex, szName, 31)
		replace_all(szName, 31, "#", " ")
		replace_all(szName, 31, "<", "&lt")
		replace_all(szName, 31, ">", "&gt")
		
		len += formatex(szMotd2[len], charsmax(szMotd2)-len,
		"<tr><td id=p>%d</td>\
		<td id=n>%s</td>\
		<td>%d</td>\
		<td>%d</td>\
		<td>%d</td>\
		<td>%s</td>", (x+1), szName, gData[kindex][Data_Exp], gData[kindex][Data_Kills], gData[kindex][Data_Deaths], szTimeFormat)
	}
	
	add(szMotd2, charsmax(szMotd2), "</table></body></html>")
	show_motd(id, szMotd2, "TOP Players (Now Online)")
	
	return PLUGIN_HANDLED;
}

public CompareEXP(elem1[], elem2[])
{
	if(elem1[1] > elem2[1]) return -1;
	else if(elem1[1] < elem2[1]) return 1;
	
	return 0;
}

public OnDeathMsg()
{
	new atk, vic, hs, szWpn[4]
	atk = read_data(1)
	vic = read_data(2)
	hs = read_data(3)
	read_data(4, szWpn, 3)
	
	if(is_user_connected(vic))
	{
		gData[vic][Data_Deaths]++
	}
	
	if((atk != vic) && is_user_connected(atk))
	{
		gData[atk][Data_Kills]++
		gData[atk][Data_Exp] += iExpKill
		
		if(hs)
		{
			gData[atk][Data_HeadShot]++
			gData[atk][Data_Exp] += iExpHeadShot
		}
		if(zp_get_user_nemesis(vic))
		{
			gData[atk][Data_NemKills]++
			gData[atk][Data_Exp] += iExpNemKill
		}
		else if(zp_get_user_survivor(vic))
		{
			gData[atk][Data_SurKills]++
			gData[atk][Data_Exp] += iExpSurKill
		}
		
		if(szWpn[0]=='k' && szWpn[1]=='n')
		{
			gData[atk][Data_Knife]++
			gData[atk][Data_Exp] += iExpKnife
			CheckPlayerLevel(atk)
			return;
		}
		
		if(szWpn[0]=='g' && szWpn[1]=='r')
		{
			gData[atk][Data_Nade]++
			gData[atk][Data_Exp] += iExpGrenade
			CheckPlayerLevel(atk)
			return;
		}
		
		CheckPlayerLevel(atk)
	}
}

public zp_user_infected_post(vic, atk)
{
	if(is_user_connected(vic))
	{
		gData[vic][Data_Deaths]++
	}
	
	if((atk != vic) && is_user_connected(atk))
	{
		gData[atk][Data_Kills]++
		gData[atk][Data_Exp] += iExpKill
		CheckPlayerLevel(atk)
	}
}

public OnPlayerPreThink(id)
{
	static Float:ctime; ctime = get_gametime();
	if(fLastHud[id] > ctime) return;
	
	fLastHud[id] = ctime+1.0
	
	if(!is_user_alive(id))
	{
		static iSpec; iSpec = entity_get_int(id, EV_INT_iuser2);
		if(!is_user_alive(iSpec)) return;
		
		set_hudmessage(128, 128, 128, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.6, 0.5, -1)
		ShowSyncHudMsg(id, iHudStats, "        SPECTATING^n%s ^n[ Country: %s ]^n[ HP: %.0f | Ammo: %d ]^n[ %s: %d/%d ]", gData[iSpec][Data_Name], gData[iSpec][Data_Country], entity_get_float(iSpec, EV_FL_health), zp_get_user_ammo_packs(iSpec),szRanks[gData[iSpec][Data_Level]], gData[iSpec][Data_Exp], iEXP[gData[iSpec][Data_Level]+1]) //entity_get_float(iSpec, EV_FL_armorvalue)
		return;
	}
	new iRank
	iRank = SortPlayerRank(id)
	set_hudmessage(4, 128, 4, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.6, 0.5, -1)
	ShowSyncHudMsg(id, iHudStats, "[ %s: %d/%d ]^n[ Rank: %d of %d ]^n              Alive ^n[ Humans:%d|%d:Zombies ]",szRanks[gData[id][Data_Level]], gData[id][Data_Exp], iEXP[gData[id][Data_Level]+1], iRank, iTotalEntries, zp_get_human_count(), zp_get_zombie_count() )
}
/*
public OnPlayerPreThink(id)
{
	static Float:ctime; ctime = get_gametime();
	if(fLastHud[id] > ctime) return;
	
	fLastHud[id] = ctime+1.0
	
	if(!is_user_alive(id))
	{
		static iSpec; iSpec = entity_get_int(id, EV_INT_iuser2);
		if(!is_user_alive(iSpec)) return;
		
		set_hudmessage(128, 128, 128, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.6, 0.5, -1)
		ShowSyncHudMsg(id, iHudStats, "SPECTATING: %s | COUNTRY: %s^nHP: %.0f | ARMOR: %.0f | PACKS: %d^nEXP: %d/%d | LEVEL: %s", gData[iSpec][Data_Name], gData[iSpec][Data_Country], entity_get_float(iSpec, EV_FL_health), entity_get_float(iSpec, EV_FL_armorvalue), zp_get_user_ammo_packs(iSpec), gData[iSpec][Data_Exp], iEXP[gData[iSpec][Data_Level]+1], szRanks[gData[iSpec][Data_Level]])
		return;
	}
	
	set_hudmessage(4, 128, 4, HUD_STATS_X, HUD_STATS_Y, 0, 6.0, 1.1, 0.6, 0.5, -1)
	ShowSyncHudMsg(id, iHudStats, "HP: %.0f | ARMOR: %.0f | PACKS: %d^nEXP: %d/%d | LEVEL: %s^nCOUNTRY: %s", entity_get_float(id, EV_FL_health), entity_get_float(id, EV_FL_armorvalue), zp_get_user_ammo_packs(id), gData[id][Data_Exp], iEXP[gData[id][Data_Level]+1], szRanks[gData[id][Data_Level]], gData[id][Data_Country])
}*/

public _get_user_exp(id)
{
	return gData[id][Data_Exp];
}

public _set_user_exp(id, amount)
{
	gData[id][Data_Exp] = amount
}

public _get_user_playtime(id)
{
	return gData[id][Data_PlayTime];
}

public _set_user_playtime(id, amount)
{
	gData[id][Data_PlayTime] = amount
}

public _get_user_level(id)
{
	return gData[id][Data_Level];
}

public _set_user_level(id, amount)
{
	gData[id][Data_Level] = amount
}

public _get_user_deaths(id)
{
	return gData[id][Data_Deaths];
}

public _set_user_deaths(id, amount)
{
	gData[id][Data_Deaths] = amount
}

public _get_user_frags(id)
{
	return gData[id][Data_Kills];
}

public _set_user_frags(id, amount)
{
	gData[id][Data_Kills] = amount
}

public _get_user_headshot(id)
{
	return gData[id][Data_HeadShot];
}

public _set_user_headshot(id, amount)
{
	gData[id][Data_HeadShot] = amount
}

public _get_user_knife(id)
{
	return gData[id][Data_Knife];
}

public _set_user_knife(id, amount)
{
	gData[id][Data_Knife] = amount
}

public _get_user_nade(id)
{
	return gData[id][Data_Nade];
}

public _set_user_nade(id, amount)
{
	gData[id][Data_Nade] = amount
}

public _get_user_nemesis(id)
{
	return gData[id][Data_NemKills];
}

public _set_user_nemesis(id, amount)
{
	gData[id][Data_NemKills] = amount
}

public _get_user_survivor(id)
{
	return gData[id][Data_SurKills];
}

public _set_user_survivor(id, amount)
{
	gData[id][Data_SurKills] = amount
}

public _reset_user_data(id)
{
	gData[id][Data_Exp] = 0
	gData[id][Data_Kills] = 0
	gData[id][Data_Deaths] = 0
	gData[id][Data_HeadShot] = 0
	gData[id][Data_Knife] = 0
	gData[id][Data_Nade] = 0
	gData[id][Data_NemKills] = 0
	gData[id][Data_SurKills] = 0
	gData[id][Data_PlayTime] = 0
	gData[id][Data_Level] = 0
}

public _get_user_rank(id)
{
	return SortPlayerRank(id);
}

GetTimeFormat(seconds, szTime[], len)
{
	new days, hours, minutes
	days = seconds / 86400;
	hours = ( seconds / 3600 ) % 24;
	minutes = ( seconds / 60 ) % 60;
	seconds = seconds % 60;
	
	if(days)
	{
		formatex(szTime, len, "%dD %dH %dM %dS", days, hours, minutes, seconds)
		return;
	}
	
	if(hours)
	{
		formatex(szTime, len, "%dH %dM %dS", hours, minutes, seconds)
		return;
	}
	
	if(minutes)
	{
		formatex(szTime, len, "%dM %dS", minutes, seconds)
		return;
	}
	
	if(seconds)
	{
		formatex(szTime, len, "%dS", seconds)
	}
}

GetPlayerStats(id, caller)
{
	new szMotd2[1536], len
	szMotd2[0] = 0
	
	add(szMotd2, charsmax(szMotd2),
	"<html><style>\
	body{background: url('https://static.brusheezy.com/system/resources/previews/000/013/939/non_2x/grunge-texture-by-krist-photoshop-textures.jpg') repeat;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
	.t{color:#afafaf;text-align:left;  }\
	#h{background: #333;border-style: solid;border-width: 1px;border-color: #999;color:#E0E0E0;font-weight:bold;}\
	#p{color:#e6e6e6;}\
	#n{color:#fff;}\
	</style><body>\
	<table cellspacing=0 width=100% class=t>")
	
	add(szMotd2, charsmax(szMotd2),
	"<tr><td id=h width=30%>Statistics</td>\
	<td id=h>Ammount</td></tr>")
	
	len = strlen(szMotd2)

	new iSec, szTimeFormat[32], iRank, iPacks, szName[32]
	iSec = get_user_time(id)+gData[id][Data_PlayTime]
	GetTimeFormat(iSec, szTimeFormat, 31)
	iRank = SortPlayerRank(id)
	iPacks = zp_get_user_ammo_packs(id)
	get_user_name(id, szName, 31)
	replace_all(szName, 31, "#", " ")
	replace_all(szName, 31, "<", "&lt")
	replace_all(szName, 31, ">", "&gt")
	
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Nickname</td><td>%s</td>", szName)
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>SteamID</td><td>%s</td>", gData[id][Data_Steamid])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Country</td><td>%s</td>", gData[id][Data_Country])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Rank</td><td>%d of %d</td>", iRank, iTotalEntries)
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Ammo</td><td>%d</td>", iPacks)
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Points</td><td>%d</td>", gData[id][Data_Exp])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Stage</td><td>%s</td>", szRanks[gData[id][Data_Level]])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Kills</td><td>%d</td>", gData[id][Data_Kills])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Deaths</td><td>%d</td>", gData[id][Data_Deaths])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Headshot kills</td><td>%d</td>", gData[id][Data_HeadShot])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Knife kills</td><td>%d</td>", gData[id][Data_Knife])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Grenade kills</td><td>%d</td>", gData[id][Data_Nade])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Nemesis kills</td><td>%d</td>", gData[id][Data_NemKills])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Survivor kills</td><td>%d</td>", gData[id][Data_SurKills])
	len += formatex(szMotd2[len], charsmax(szMotd2)-len, "<tr><td id=p>Online time</td><td>%s</td>", szTimeFormat)
	
	add(szMotd2, charsmax(szMotd2), "</table></body></html>")
	show_motd(caller, szMotd2, "Player Statistics")
}

public CheckPlayerLevel(id)
{
	while((gData[id][Data_Exp] >= iEXP[gData[id][Data_Level]+1]))
	{
		gData[id][Data_Level]++
		UTIL_ColorChat(id, "^x04%s^x01 has been promoted to the Stage of^x04 %s^x01 with^x04 %d^x01 Points.", gData[id][Data_Name], szRanks[gData[id][Data_Level]], gData[id][Data_Exp])
		ExecuteForward(gForward[Forward_Levelup], gForward[Forward_Result], id, gData[id][Data_Level], gData[id][Data_Exp])
	}
}


public Load_Data(szName[], id)
{
	if(!is_user_connected(id))
		return

	new szName[32], szKey[50], szData[164]
	copy(szName, 31, gData[id][Data_Name])
	replace_all(szName, 31, "#", " ")
	formatex(szKey, 49, "%s#EXP", szName)
	//formatex(szKey, 49, "%s#EXP", gData[id][Data_Name])
	//formatex(szKey, 49, "%s#EXP", gData[id][Data_Ip])	

	if (nvault_get(iVaultHandle, szName, szData, charsmax(szData)))
	{
		replace_all(szData, charsmax(szData), "#", " ")
	
		new szExp[8], szKills[8], szDeaths[8], szHeadShot[8], szKnife[8], szNade[8], szNemKill[8], szSurKill[8], szPlayTime[8], szLevel[8]
		parse(szData, szExp, charsmax(szExp), szKills, charsmax(szKills), szDeaths, charsmax(szDeaths), szHeadShot, charsmax(szHeadShot), szKnife, charsmax(szKnife),
			szNade, charsmax(szNade), szNemKill, charsmax(szNemKill), szSurKill, charsmax(szSurKill), szPlayTime, charsmax(szPlayTime), szLevel, charsmax(szLevel))

		gData[id][Data_Exp] = str_to_num(szExp)
		gData[id][Data_Kills] = str_to_num(szKills)
		gData[id][Data_Deaths] = str_to_num(szDeaths)
		gData[id][Data_HeadShot] = str_to_num(szHeadShot)
		gData[id][Data_Knife] = str_to_num(szKnife)
		gData[id][Data_Nade] = str_to_num(szNade)
		gData[id][Data_NemKills] = str_to_num(szNemKill)
		gData[id][Data_SurKills] = str_to_num(szSurKill)
		gData[id][Data_PlayTime] = str_to_num(szPlayTime)
		gData[id][Data_Level] = str_to_num(szLevel)
	}
	else
	{
		_reset_user_data(id)
	}
	gData[id][Data_Connected] = true
}

public Save_Data(id, szName[])
{
	new szKey[50], szData[MAX_FMT_LENGTH]
	replace_all(gData[id][Data_Name], 31, "#", " ")
	formatex(szKey, 49, "%s#EXP", gData[id][Data_Name])
	formatex(szData, charsmax(szData), "%d %d %d %d %d %d %d %d %d %d %s", gData[id][Data_Exp], gData[id][Data_Kills], gData[id][Data_Deaths], gData[id][Data_HeadShot], gData[id][Data_Knife], gData[id][Data_Nade], gData[id][Data_NemKills], gData[id][Data_SurKills], gData[id][Data_PlayTime], gData[id][Data_Level], gData[id][Data_Name])
	nvault_set(iVaultHandle, szName, szData)
}

FormatGlobalTopTen()
{
	enum _:VaultData
	{
		VD_Key[64],
		VD_Value
	}
	
	const MAX_ENTRIES = 10
	new vault = nvault_util_open(szVaultName)
	new Array:entries = ArrayCreate(VaultData)
	new sizeEntries
	new numEntries = nvault_util_count(vault)
	new data[VaultData], value[128], data2[VaultData]
	
	for(new i = 0, pos, timestamp; i < numEntries; i++)
	{
		pos = nvault_util_read(vault, pos, data[VD_Key], charsmax(data[VD_Key]), value, charsmax(value), timestamp)
		data[VD_Value] = str_to_num(value)
		
		if(sizeEntries == 0)
		{
			ArrayPushArray(entries, data)
			sizeEntries++;
		}
		else
		{
			for(timestamp = 0; timestamp <= sizeEntries; timestamp++)
			{
				if(timestamp == sizeEntries)
				{
					if(sizeEntries < MAX_ENTRIES)
					{
						ArrayPushArray(entries, data)
						sizeEntries++;
					}
					
					break;
				}
				
				ArrayGetArray(entries, timestamp, data2)
				
				if(data[VD_Value] >= data2[VD_Value])
				{
					ArrayInsertArrayBefore(entries, timestamp, data)
					
					if(sizeEntries < MAX_ENTRIES)
					{
						sizeEntries++;
					}
					else
					{
						ArrayDeleteItem(entries, sizeEntries)
					}
					
					break;
				}
			}
		}
	}
	
	nvault_util_close(vault)

	new len
	szMotd[0] = 0
	
	add(szMotd, charsmax(szMotd),
	"<html><style>\
	body{background:url('https://static.brusheezy.com/system/resources/previews/000/013/939/non_2x/grunge-texture-by-krist-photoshop-textures.jpg') repeat;font-family:Verdana, Arial, Sans-Serif;font-size:7pt;}\
	.t{color:#afafaf;text-align:left; }\
	#h{background: #333;border-style: solid;border-width: 1px;border-color: #999;color:#E0E0E0;font-weight:bold;}\
	#p{color:#D41313;}\
	#n{color:#fff;}\
	</style><body>\
	<table cellspacing=0 width=100% class=t>")
	
	add(szMotd, charsmax(szMotd),
	"<tr><td id=h width=7%>#</td>\
	<td id=h>Name</td>\
	<td id=h>Points</td>\
	<td id=h>Kills</td>\
	<td id=h>Deaths</td>\
	<td id=h>Online</td></tr>")
	
	len = strlen(szMotd)
	
	for(new i = 0; i < sizeEntries; i++)
	{
		ArrayGetArray(entries, i, data)
		//data[VD_Key][20] = 0
		
		new szDataNew[164]
		nvault_get(iVaultHandle, data[VD_Key], szDataNew, charsmax(szDataNew))
		
		new szExp[8], szKills[8], szDeaths[8], szHeadShot[8], szKnife[8], szNade[8], szNemKill[8], szSurKill[8], szPlayTime[8], szLevel[8], szName3[32]
		parse(szDataNew, szExp, 7, szKills, 7, szDeaths, 7, szHeadShot, 7, szKnife, 7, szNade, 7, szNemKill, 7, szSurKill, 7, szPlayTime, 7, szLevel, 7, szName3, 31)
		
		new iSec, szOnline[32]
		iSec = str_to_num(szPlayTime)
		GetTimeFormat(iSec, szOnline, 31)
		replace_all(szName3, 31, "#", " ")
		replace_all(szName3, 31, "<", "&lt")
		replace_all(szName3, 31, ">", "&gt")
		
		len += formatex(szMotd[len], charsmax(szMotd)-len,
		"<tr><td id=p>%d</td>\
		<td id=n>%s</td>\
		<td>%s</td>\
		<td>%s</td>\
		<td>%s</td>\
		<td>%s</td>", (i+1), szName3, szExp, szKills, szDeaths, szOnline)
	}
	
	add(szMotd, charsmax(szMotd), "</table></body></html>")
	ArrayDestroy(entries)
}

SortPlayerRank(id)
{
	new szName[32], szKey[50]
	copy(szName, 31, gData[id][Data_Name])
	replace_all(szName, 31, "#", " ")
	formatex(szKey, 49, "%s#EXP", szName)
	
	enum _:VaultData
	{
		VD_Key[64],
		VD_Value
	}
	
	new vault = nvault_util_open(szVaultName)
	new Array:entries = ArrayCreate(VaultData)
	new sizeEntries
	new numEntries = nvault_util_count(vault)
	new data[VaultData], value[128], data2[VaultData]
	
	for(new i = 0, pos, timestamp; i < numEntries; i++)
	{
		pos = nvault_util_read(vault, pos, data[VD_Key], charsmax(data[VD_Key]), value, charsmax(value), timestamp)
		data[VD_Value] = str_to_num(value)
		
		if(sizeEntries == 0)
		{
			ArrayPushArray(entries, data)
			sizeEntries++;
		}
		else
		{
			for(timestamp = 0; timestamp <= sizeEntries; timestamp++)
			{
				if(timestamp == sizeEntries)
				{
					if(sizeEntries < numEntries)
					{
						ArrayPushArray(entries, data)
						sizeEntries++;
					}
					
					break;
				}
				
				ArrayGetArray(entries, timestamp, data2)
				
				if(data[VD_Value] >= data2[VD_Value])
				{
					ArrayInsertArrayBefore(entries, timestamp, data)
					
					if(sizeEntries < numEntries)
					{
						sizeEntries++;
					}
					else
					{
						ArrayDeleteItem(entries, sizeEntries)
					}
					
					break;
				}
			}
		}
	}
	
	nvault_util_close(vault)
	iTotalEntries = sizeEntries
	
	for(new i = 0; i < sizeEntries; i++)
	{
		ArrayGetArray(entries, i, data)
		if(equal(data[VD_Key],szKey))
		{
			gData[id][Data_Rank] = i+1
			break;
		}
	}
	
	ArrayDestroy(entries)
	return gData[id][Data_Rank];
}

UTIL_ColorChat(id, const szText[], any:...)
{
	new szBuffer[512]
	
	if(!id)
	{
		new iPlayers[32], iNum, y, id2
		get_players(iPlayers, iNum, "ch")
		for(y=0;y<iNum;y++)
		{
			id2 = iPlayers[y]
			if(!is_user_connected(id2)) continue;
			
			vformat(szBuffer, charsmax(szBuffer), szText, 3)
			message_begin(MSG_ONE_UNRELIABLE, iMsgSayText, _, id2)
			write_byte(id2)
			write_string(szBuffer)
			message_end()
		}
	}
	else
	{
		vformat(szBuffer, charsmax(szBuffer), szText, 3)
		message_begin(MSG_ONE, iMsgSayText, _, id)
		write_byte(id)
		write_string(szBuffer)
		message_end()
	}
}

stock client_cmd_ex(id, const command[], any:...)
{
	#pragma unused command
	
	if (id == 0 || is_user_connected(id))
	{
		new szMessage[256]
		
		format_args(szMessage, charsmax(szMessage), 1)
		
		message_begin(id == 0 ? MSG_ALL : MSG_ONE, 51, _, id)
		write_byte(strlen(szMessage) + 2)
		write_byte(10)
		write_string(szMessage)
		message_end()
	}
}
Нарочно не съм редактирал предишното мнение.
Пиша от избата, защото горе имаме течове..

Отговори

Върни се в “Заявки за плъгини”

Кой е на линия

Потребители, разглеждащи този форум: Season12 и 0 госта