[ZP] Проблем с VIP 1.9.1 by aaarnas

Въпроси и проблеми свързани с AMXModX.
Аватар
Stoyan VK
Извън линия
Потребител
Потребител
Мнения: 23
Регистриран на: 17 Апр 2017, 19:27
Местоположение: Sofia, Bulgaria
Се отблагодари: 3 пъти
Обратна връзка:

[ZP] Проблем с VIP 1.9.1 by aaarnas

Мнение от Stoyan VK » 09 Окт 2022, 18:21

Здравейте, някой може ли да каже от какво идва този проблем в конзолата на сървъра?

Код за потвърждение: Избери целия код

L 10/09/2022 - 17:55:01: Invalid map handle provided (0)
L 10/09/2022 - 17:55:01: [AMXX] Displaying debug trace (plugin "zm_vip.amxx", version "1.9.1 BETA")
L 10/09/2022 - 17:55:01: [AMXX] Run time error 10: native error (native "TrieKeyExists")
L 10/09/2022 - 17:55:01: [AMXX]    [0] zm_vip.sma::VipsItemIs (line 2980)
L 10/09/2022 - 17:55:01: [AMXX]    [1] zm_vip.sma::zp_fw_items_select_post (line 1683)
.sma, който ползвам е оригиналният от алиедмодс.

Код за потвърждение: Избери целия код

/* Plugin generated by AMXX-Studio */
/* -------------------------------------------------------------------------------------------------

             _____    __  ___   _    __ ____ ____     ___      ____     ____ 
            /__  /   /  |/  /  | |  / //  _// __ \   |__ \    / __ \   / __ \
              / /   / /|_/ /   | | / / / / / /_/ /   __/ /   / / / /  / / / /
             / /__ / /  / /    | |/ /_/ / / ____/   / __/ _ / /_/ /_ / /_/ / 
            /____//_/  /_/     |___//___//_/       /____/(_)\____/(_)\____/  
								BETA VERSION!!!
	    
	Zombie Plague 4.3/5.0 Addon
	ZM VIP - Zombie Plague VIP addon that enables special abilities for players
	and adds VIP system, status and API to server.
	
	Official thread: https://forums.alliedmods.net/showthread.php?t=119719
	
	Author: aaarnas

--------------------------------------------------------------------------------------------------*/

// Ignore thease. Just values for settings.
#define OFF 0
#define ON 1
#define FORCED 2
#define NEW 1
#define OLD 2
#define VAULT 1

#define VERSION "1.9.1 BETA"

// --------------- USER CONFIGURATION START --------------- USER CONFIGURATION START ---------------
// --------------- USER CONFIGURATION START --------------- USER CONFIGURATION START ---------------
// --------------- USER CONFIGURATION START --------------- USER CONFIGURATION START ---------------
// --------------- USER CONFIGURATION START --------------- USER CONFIGURATION START ---------------
// -------------------------------------------------------------------------------------------------
// Choose your using zombie plague version:
// NEW		- Zombie Plague 5.0 or later. (zp_plugin_50.zip | zp508a.zip and later ... )
// OLD		- Zombie Plague 4.3 or earlier. (zp_plugin_43.zip)
// Zombie Plague Advanced - Not supported.
// Daugiau pluginu https://forums.alliedmods.net/showthread.php?t=242196?t=242196

#define MODIFICATION NEW
// -------------------------------------------------------------------------------------------------
// Set wich system to use loading privileges:
// FORCED - Just vips.ini file. Ignores amxmodx.
// ON   - vips.ini and amxmodx (users.ini/database (flag t))
// OFF  - Disables vips.ini file and reads only from amxmodx (users.ini/database (flag t))
#define VIPS_FILE_SYSTEM ON
// -------------------------------------------------------------------------------------------------
// Set if you want to enable extra items menu system (/vm)
// ON  - Enabled
// OFF - Dissabled
#define EXTRA_ITEMS ON
// -------------------------------------------------------------------------------------------------
// Vip privileges flag in users.ini file (t) if NOT using VIPS_FILE_SYSTEM [FORCED] mode. 
#define VIP_SYS_FLAG ADMIN_LEVEL_H
// -------------------------------------------------------------------------------------------------
// Admin flag (from users.ini). Allow access to VIP admin panel, zm_vip_freevip_hour cvar(cmd). 
#define ADMIN_SYS_FLAG ADMIN_LEVEL_E //(ADMIN_LEVEL_E flag is "q")
// -------------------------------------------------------------------------------------------------
// Name of configs/vips.ini|zm_cip.cfg file. In fact, no reason to change.
#define VIPS_FILE "vips.ini"
#define CONFIGS_FILE "zm_vip.cfg"
// -------------------------------------------------------------------------------------------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//--------------- USER CONFIGURATION END --------------- USER CONFIGURATION END ---------------
//////////////////////////// Editing anyting further - taking own risk /////////////////////////////
////////// This means - no support. Using/stealing anything without credits - not allowed //////////

#define EMPTY(%1) (%1[0]==EOS)
#define BIT(%1) (1<<%1)
#define FLAG_A (1<<0)
#define FLAG_B (1<<1)
#define FLAG_C (1<<2)
#define FLAG_D (1<<3)
#define FLAG_E (1<<4)
#define FLAG_F (1<<4)
#define FLAG_K (1<<10)
#define FLAG_N (1<<13)

#define LOAD_FROM_INI	(1<<31)
#define LOAD_FROM_DAT	(1<<30)
#define LOAD_FROM_AMX	(1<<29)
#define LOAD_FROM_NAMES	(1<<28)
#define LOAD_FROM_MAIN	(1<<27)
#define LOAD_MASK	0xFC000000

#include <amxmodx>
#include <amxmisc>
#include <hamsandwich>
#include <fakemeta>
#include <engine>
#include <fun>
#include <regex>
#if MODIFICATION == NEW
#include <cstrike>
#define ZP_ITEM_AVAILABLE 0
#define ZP_ITEM_NOT_AVAILABLE 1
#define ZP_ITEM_DONT_SHOW 2
#define ZP_CLASS_AVAILABLE 0
#define ZP_CLASS_NOT_AVAILABLE 1
#define ZP_CLASS_DONT_SHOW 2
native zp_core_is_zombie(id)
forward zp_fw_core_spawn_post(id)
forward zp_fw_core_infect_pre(id, attacker)
forward zp_fw_core_infect_post(id, attacker)
forward zp_fw_core_cure_post(id, attacker)
native zp_ammopacks_get(id)
native zp_ammopacks_set(id, amount) 
native zp_class_human_menu_text_add(const text[])
forward zp_fw_class_human_select_pre(id, classid)
native zp_class_human_register(const name[], const description[], health, Float:speed, Float:gravity)
native zp_class_zombie_menu_text_add(const text[])
forward zp_fw_class_zombie_select_pre(id, classid)
native zp_class_zombie_register(const name[], const description[], health, Float:speed, Float:gravity)
native zp_items_register(const name[], cost)
forward zp_fw_items_select_pre(id, itemid, ignorecost)
forward zp_fw_items_select_post(id, itemid, ignorecost)
native zp_items_show_menu(id)
native zp_items_menu_text_add(const text[]) 
native cs_set_player_model(id, const model[])
forward zp_fw_grenade_fire_pre(id)
forward zp_fw_grenade_frost_pre(id)
#else
native zp_get_user_bombardier(id)
#define ZP_TEAM_ANY 0
native zp_get_user_zombie(id)
native zp_get_user_next_class(id)
native zp_set_user_zombie_class(id, classid)
native zp_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hp, speed, Float:gravity, Float:knockback)
native zp_override_user_model(id, const newmodel[], modelindex = 0)
native zp_get_user_nemesis(id)
native zp_get_user_survivor(id)
forward zp_user_infect_attempt(id, infector, nemesis)
forward zp_user_infected_post(id, infector, nemesis)
forward zp_user_humanized_post(id, survivor)
forward zp_user_infected_pre(id, infector, nemesis)
forward zp_extra_item_selected(id, itemid)
forward zp_round_started(gamemode, id)
native zp_register_extra_item(const name[], cost, teams)
native zp_force_buy_extra_item(id, itemid, ignorecost = 0)
native zp_get_extra_item_id(const name[])
native zp_get_user_ammo_packs(id)
native zp_set_user_ammo_packs(id, amount)
#define ZP_PLUGIN_HANDLED 97
#endif

new cvar_multijump, cvar_multijump_allow, cvar_armor, cvar_extra_hp_human, cvar_extra_hp_zombie,
cvar_extra_gravity_human, cvar_extra_gravity_zombie ,cvar_unlimited_clip, cvar_no_fall_dmg, 
cvar_extra_dmg, cvar_extra_frags, cvar_extra_kill_ammo, cvar_extra_armor, cvar_extra_infect_ammo,
cvar_extra_infect_health, cvar_extra_ignore_for_special, cvar_damage_reward, cvar_viponly_class,
cvar_chat_viptag, cvar_vip_connected_to_server, cvar_freevip_flags, cvar_vipniscoretable,
cvar_grenades_immunity, cvar_gamemode_disable_flags
#if VIPS_FILE_SYSTEM != FORCED
new cvar_amx_auth_flags
#endif
#if VIPS_FILE_SYSTEM != OFF
new cvar_vip_store_ini
#endif
new cvar_amxmodx_flags, cvar_vip_price, cvar_vip_buy_duration, cvar_vip_buy_flags,
cvar_vip_buy_in_extra_items

#if EXTRA_ITEMS == ON
new cvar_buys_per_round
#if MODIFICATION == OLD
new chached_show_vip_items
#else
new cvar_vip_show_vip_items
#endif
#endif

enum _:player_attributes
{
	AT_MULTIJUMP,		//a(0)
	AT_ARMOR,		//b(1)
	AT_UNLIMITED_CLIP,	//c(2)
	AT_NO_FALL_DMG,		//d(3)
	AT_DAMAGE_REWARD,	//e(4)
	AT_EXTRA_DMG,		//f(5)
	AT_EXTRA_HP,		//g(6)
	AT_EXTRA_GRAVITY,	//h(7)
	AT_EXTRA_FRAGS,		//i(8)
	AT_EXTRA_KILL_AMMO,	//j(9)
	AT_EXTRA_ARMOR,		//k(10)
	AT_EXTRA_INFECT_AMMO,	//l(11)
	AT_EXTRA_INFECT_HEALTH,	//m(12)
	AT_EXTRA_ITEMS,		//n(13)
	AT_VIP_MODEL,		//o(14)
	AT_VIP_CLASS,		//p(15)
	AT_CHATTAG,		//q(16)
	AT_VIPINSCORE,		//r(17)
	AT_GRENADE_IMMUNITY	//s(18)
}

new p_attribs[33][player_attributes]

#define AT_NONE		(1<<25) // z

#define ZV_DURATION_IGNORE		-1
#define ZV_DURATION_PERMANENT		0
#define ZV_DURATION_TILL_DISCONNECT	~'t'
#define ZV_DURATION_TILL_MAP		~('t'|'m')

enum ClassType:cltypes {
	EXTRA_ITEM = 1,
	CLASS_ZOMBIE,
	CLASS_HUMAN
}
#define VipsItemHandle trie_vip_items
new Trie:trie_vip_items

new p_bought_per_round[33]
new bool:p_zombie[33]
new p_jumpsnum[33]
new Float:p_damage[33]
new Float:p_grenade_time[33]

new p_vip_model_zombie[15]
new p_vip_model_human[15]

new is_amxmodx_new_version
#if MODIFICATION == NEW
new is_module_ammopacks_loaded
#endif

new Trie:trie_vips_database
new Array:array_vips_database
new Array:array_vips_database_nick
new amx_password_field_string[30]
enum _:VipCnt {
	
	INI,
	DAT,
	MAIN,
	NAMES,
	AMX
}
new total_vips_count[VipCnt] //0 - main, 1 - names, 2 - amx
#define VIPCNT(%1) total_vips_count[%1]
#define VIPINC(%1) total_vips_count[%1]++
#define VIPDEC(%1) total_vips_count[%1]--
enum _:vips_database_type
{
	AUTH[40],
	PASS[30],
	SETTINGS,
	FLAGS,
	TIMESTAMP,
	INDEX
}
new p_data[33][vips_database_type]

#if EXTRA_ITEMS == ON
new registered_extra_items_num
#if MODIFICATION == NEW
new bool:p_views_extra_items_menu[33]
#else
enum _:item_struct {
	
	item_plid,
	item_name[100],
	item_cost,
	item_team
}
#define ZP_TEAM_ZOMBIE (1<<0)
#define ZP_TEAM_HUMAN (1<<1)
#define ZP_TEAM_NEMESIS (1<<2)
#define ZP_TEAM_SURVIVOR (1<<3)
new Array:array_vip_extra_items
new fw_extraitemselected
#endif
#endif

new vip_buy_extra_item = -1

new current_gamemode

new bool:freevip_enabled
new bool:freevip_inform[33]
new bool:first_spawn[33]
new freevip_hours[4]
new maxplayers
new msg_saytext
new msg_scoreattrib

new const MAXCLIP[] = { -1, 13, -1, 10, 1, 7, -1, 30, 30, 1, 30, 20, 25, 30, 35, 25, 12, 20, 10, 30, 100, 8, 30, 30, 20, 2, 7, 30, 30, -1, 50 }

#define IS_PLAYER(%1) (1<=%1<=maxplayers)
#define ATTRIB(%1,%2) p_attribs[%1][%2]

#define CURRENCY_MONEY 0
#define CURRENCY_AMMO_PACKS 1
public plugin_init() {
	
	register_plugin("ZM VIP", VERSION, "aaarnas") 
	register_dictionary("zm_vip.txt")

	new amxmodx_version[20], amxmodx_version_num
	get_amxx_verstring(amxmodx_version, charsmax(amxmodx_version))
	replace_all(amxmodx_version, charsmax(amxmodx_version), ".", "")
	amxmodx_version_num = str_to_num(amxmodx_version)
	is_amxmodx_new_version = amxmodx_version_num>=183
	
	/////////////////////// CVARS REGISTRATION ///////////////////////
	cvar_multijump = register_cvar("zm_vip_mutijump", "1")
	cvar_multijump_allow = register_cvar("zm_vip_multijump_allow", "ab")
	cvar_armor = register_cvar("zm_vip_armor", "65")
	cvar_unlimited_clip = register_cvar("zm_vip_unlimited_clip", "0")
	cvar_no_fall_dmg = register_cvar("zm_vip_no_fall_dmg", "1")
	cvar_extra_dmg = register_cvar("zm_vip_extra_dmg", "1.2")
	cvar_extra_hp_human = register_cvar("zm_vip_extra_hp_human", "50")
	cvar_extra_hp_zombie = register_cvar("zm_vip_extra_hp_zombie", "500")
	cvar_extra_gravity_human = register_cvar("zm_vip_extra_gravity_human", "0")
	cvar_extra_gravity_zombie = register_cvar("zm_vip_extra_gravity_zombie", "0")
	cvar_extra_frags = register_cvar("zm_vip_extra_frags", "0")
	cvar_extra_kill_ammo = register_cvar("zm_vip_extra_kill_ammo", "1")
	cvar_extra_armor = register_cvar("zm_vip_extra_armor", "0")
	cvar_extra_infect_ammo = register_cvar("zm_vip_extra_infect_ammo", "1")
	cvar_extra_infect_health = register_cvar("zm_vip_extra_infect_health", "100")
	cvar_extra_ignore_for_special = register_cvar("zm_vip_extra_ignore_for_special", "1")
	cvar_damage_reward = register_cvar("zm_vip_damage_reward", "1000")
	cvar_viponly_class = register_cvar("zm_viponly_class", "1")
	cvar_chat_viptag = register_cvar("zm_vip_chattag", "1")
	cvar_vip_connected_to_server = register_cvar("zm_vip_connected_to_server", "1") // 1-chat/2-hud/3-dhud
	cvar_vipniscoretable = register_cvar("zm_vipinscoretable", "1")
#if VIPS_FILE_SYSTEM != FORCED
	cvar_amx_auth_flags = register_cvar("zm_vip_amx_auth_flags", "0") 
#endif
	cvar_amxmodx_flags = register_cvar("zm_vip_amxmodx_flags", "t")
	cvar_grenades_immunity = register_cvar("zm_vip_grenades_immunity", "0")
	cvar_gamemode_disable_flags = register_cvar("zm_vip_gamemode_disable_flags", "0")
	register_concmd("zm_vip_freevip_hour", "set_freevip_hour", ADMIN_CVAR)
	cvar_freevip_flags = register_cvar("zm_vip_freevip_flags", "0")
#if VIPS_FILE_SYSTEM != OFF
	cvar_vip_store_ini = register_cvar("zm_vip_store_ini", "0")
#endif
	cvar_vip_price = register_cvar("zm_vip_price", "0")
	cvar_vip_buy_duration = register_cvar("zm_vip_buy_duration", "1d") // 1h - val, 1d - day// t - tepm/ tm - temp till map
	
	cvar_vip_buy_flags = register_cvar("zm_vip_buy_flags", "0")
	cvar_vip_buy_in_extra_items = register_cvar("zm_vip_buy_in_extra_items", "1")
	
#if EXTRA_ITEMS == ON
	cvar_buys_per_round = register_cvar("zm_vip_buys_per_round", "0")
#if MODIFICATION == NEW
	cvar_vip_show_vip_items = register_cvar("zm_vip_show_vip_items", "2")
#endif
#if MODIFICATION != NEW
	fw_extraitemselected = CreateMultiForward("zv_extra_item_selected", ET_CONTINUE, FP_CELL, FP_CELL)
#endif
#endif	
	maxplayers = get_maxplayers()
	
	msg_saytext = get_user_msgid("SayText")
	msg_scoreattrib = get_user_msgid("ScoreAttrib")
	
	register_clcmd("say /vm", "show_vip_menu")
	register_clcmd("open_vip_menu", "show_vip_menu_console")
	register_clcmd("say /vip", "show_vip_info")
	register_clcmd("say /vips", "show_vips_online")
	
	register_concmd("zm_vip_list", "cmd_list_vips", ADMIN_SYS_FLAG)
	register_concmd("amx_reloadvips", "cmd_vips_reload", ADMIN_SYS_FLAG)
	register_concmd("zm_vip_reload", "cmd_vips_reload", ADMIN_SYS_FLAG)
	register_concmd("zm_vip_remove", "cmd_vips_remove", ADMIN_SYS_FLAG)
	
	register_menu("Menu Buy", MENU_KEY_0|MENU_KEY_1, "forward_buy_menu_handler")
	
	register_event("HLTV", "forward_event_round_start", "a", "1=0", "2=0")
	register_event("DeathMsg", "forward_event_deathmsg", "a")
	register_event("ResetHUD", "forward_event_reset_hud", "be")
	register_message(get_user_msgid("CurWeapon"), "message_cur_weapon")
	register_message(msg_saytext, "message_say_text")
	register_forward(FM_CmdStart, "forward_cmdstart")
#if MODIFICATION != NEW
	RegisterHam(Ham_Spawn, "player", "forward_player_spawn", 1)
#endif
	RegisterHam(Ham_TakeDamage, "player", "forward_player_takedamage_pre")
	RegisterHam(Ham_TakeDamage, "player", "forward_player_takedamage_post", 1)
	RegisterHam(Ham_Think, "grenade", "forward_grenade_think")
	
	trie_vips_database = TrieCreate()
	array_vips_database = ArrayCreate(45, 15)
	
	register_cvar("zp_vip_version", VERSION, FCVAR_SERVER|FCVAR_SPONLY)
	set_cvar_string("zp_vip_version", VERSION)
}


public plugin_natives() {

	register_library("zm_vip")

	set_native_filter("native_filter")
	
	register_native("zv_get_user_flags", "native_zv_get_user_flags")
	register_native("zv_set_user_flags", "native_zv_set_user_flags")
	register_native("zv_remove_user_flags", "native_zv_remove_user_flags")

#if MODIFICATION == NEW
#if EXTRA_ITEMS == ON
	register_native("zv_items_register", "native_zv_items_register", 1)
#endif
	register_native("zv_class_human_register", "native_zv_class_human_register", 1)
	register_native("zv_class_zombie_register", "native_zv_class_zombie_register", 1)
#else
	register_native("zv_register_zombie_class", "native_zv_register_zombie_class", 1)
#if EXTRA_ITEMS == ON	
	register_native("zv_register_extra_item", "native_zv_register_extra_item", 1)
	register_native("zv_register_extra_item2", "native_zv_register_extra_item2", 1)
	register_native("zv_force_buy_extra_item", "native_zv_force_buy_extra_item", 1)
	register_native("zv_get_extra_item_id", "native_zv_get_extra_item_id", 1)
#endif
#endif
}
#if MODIFICATION == NEW
native zp_class_nemesis_get(id)
native zp_class_survivor_get(id)
native zp_class_assassin_get(id)
native zp_class_sniper_get(id)
#endif
new natives_filter_out
enum {
	NATIVE_ZP_CLASS_NEMESIS_GET,
	NATIVE_ZP_CLASS_SURVIVOR_GET,
	NATIVE_ZP_CLASS_ASSASSIN_GET,
	NATIVE_ZP_CLASS_SNIPER_GET,
	NATIVE_ZP_CLASS_BOMBARDIER_GET,
	NATIVE_OVERRIDE_USER_MODEL
}
public native_filter(const name[], index, trap) {
	
	if (!trap) {
#if MODIFICATION == NEW
		if (equal(name, "zp_class_nemesis_get")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_NEMESIS_GET)
		else if(equal(name, "zp_class_survivor_get")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_SURVIVOR_GET)
		else if(equal(name, "zp_class_assassin_get")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_ASSASSIN_GET)
		else if(equal(name, "zp_class_sniper_get")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_SNIPER_GET)
#else
		if (equal(name, "zp_get_user_bombardier")) natives_filter_out |= BIT(NATIVE_ZP_CLASS_BOMBARDIER_GET)
#endif
#if MODIFICATION == OLD
		else if (equal(name, "zp_override_user_model")) {
			p_vip_model_zombie[0] = EOS
			p_vip_model_human[0] = EOS
			log_amx("ERROR: Vip models are not compatible with old Zombie Plague 4.3 version. Use Zombie Plague 4.3 patched or 5.0 to enable this feature.")
			log_amx("Download: https://forums.alliedmods.net/showthread.php?t=72505")
			natives_filter_out |= BIT(NATIVE_OVERRIDE_USER_MODEL)
		}
		else if (equal(name, "zp_get_user_zombie")) {
			set_fail_state("ERROR: This plugin compiled with MODIFICATION - OLD setting. \
			This supports only Zombie plague 4.3 versions.^nPlugin was unable to\
			detect this version, so probably, modification is incorrect.")
		}
#endif
		else {
			return PLUGIN_CONTINUE;
		}
		return PLUGIN_HANDLED;
			
	}
	return PLUGIN_CONTINUE;
}

public plugin_precache() {
#if EXTRA_ITEMS == ON && MODIFICATION == OLD
	new value_str[5]
	read_config("zm_vip_show_vip_items", value_str, charsmax(value_str))
	chached_show_vip_items = str_to_num(value_str)
#endif	
#if MODIFICATION == NEW
	read_config("zm_vip_model_zombie", p_vip_model_zombie, charsmax(p_vip_model_zombie))
	read_config("zm_vip_model_human", p_vip_model_human, charsmax(p_vip_model_human))

	if (!EMPTY(p_vip_model_zombie)) {
		
		new model_path[128]
		formatex(model_path, charsmax(model_path), "models/player/%s/%s.mdl", p_vip_model_zombie, p_vip_model_zombie)
		precache_model(model_path)
		formatex(model_path, charsmax(model_path), "models/player/%s/%sT.mdl", p_vip_model_zombie, p_vip_model_zombie)
		if (file_exists(model_path)) precache_model(model_path)
	}
	if (!EMPTY(p_vip_model_human)) {
		
		new model_path[128]
		formatex(model_path, charsmax(model_path), "models/player/%s/%s.mdl", p_vip_model_human, p_vip_model_human)
		precache_model(model_path)
		formatex(model_path, charsmax(model_path), "models/player/%s/%sT.mdl", p_vip_model_human, p_vip_model_human)
		if (file_exists(model_path)) precache_model(model_path)
	}
#endif
}
public plugin_cfg() {
#if MODIFICATION == NEW	

	if (!LibraryExists("zp50_core", LibType_Library))
		set_fail_state("ERROR: This plugin compiled with MODIFICATION - NEW setting. \
		This supports only Zombie plague 5 version and higher.^nPlugin was unable to\
		detect main Zombie Plague Core plugin.")
		
	is_module_ammopacks_loaded = LibraryExists("zp50_ammopacks", LibType_Library)
#endif
	new file_link[45]
	get_configsdir(file_link, charsmax(file_link))
	format(file_link, charsmax(file_link), "%s/%s", file_link, CONFIGS_FILE)
	if (file_exists(file_link)) {
		server_cmd("exec %s", file_link)
		server_exec()
	}
	else {
		log_amx("WARNING: Missing ^"%s^" file in configs folder. Can't load cvars values.", CONFIGS_FILE)
	}
	
	get_cvar_string("amx_password_field", amx_password_field_string, charsmax(amx_password_field_string))
#if VIPS_FILE_SYSTEM != OFF
	load_ini_file()
#endif
	load_datafile()
		
#if VIPS_FILE_SYSTEM != FORCED
	new num = admins_num()
	for (new i=0; i<num; i++) {
		if (admins_lookup(i, AdminProp_Access)&VIP_SYS_FLAG) {
			VIPINC(AMX)
		}
	}
#endif
	if (!VIPCNT(DAT) && !VIPCNT(INI) && !VIPCNT(AMX))
		log_amx("WARNING: No VIPs loaded from zm_vip system. Maybe there aren't any.")
		
	if (get_pcvar_num(cvar_vip_price) > 0 && get_pcvar_num(cvar_vip_buy_in_extra_items)) {
		
		new buy_vip_text[30], langid = LANG_SERVER
		LookupLangKey(buy_vip_text, charsmax(buy_vip_text), "BUY_VIP", langid)
#if MODIFICATION == NEW
		vip_buy_extra_item = zp_items_register(buy_vip_text, get_pcvar_num(cvar_vip_price))
#else
		vip_buy_extra_item = zp_register_extra_item(buy_vip_text, get_pcvar_num(cvar_vip_price), ZP_TEAM_ANY)
#endif
	}
	
#if EXTRA_ITEMS == ON
	if (!registered_extra_items_num)
		log_amx("WARRNING: No vip extra item plugins loaded.")
#endif
	set_task(1.0, "vip_time_check", 0, _, _, "b")
	
	server_print("-------------------------------------------------------------------------------")
	server_print("This server using ZM VIP %s by aaarnas", VERSION)
	server_print("Successfully loaded %d VIPs", VIPCNT(DAT)+VIPCNT(INI)+VIPCNT(AMX))
	server_print("-------------------------------------------------------------------------------")
}

_get_pcvar_flags(pcvar) {

	new flags[30]
	get_pcvar_string(pcvar, flags, charsmax(flags))
	
	if (flags[0] == '0')
		return 0;
	
	return read_flags(flags);
}
set_user_atribs(id, double_attrib_update = false) {
	
	if (id == 0) return;
		
	new hour_flags = 0
	
	new gamemode_disable_flags = 0
	if (current_gamemode != 0) {
		gamemode_disable_flags = _get_pcvar_flags(cvar_gamemode_disable_flags)
	}
	
	if(freevip_enabled && freevip_hour_check()) {
			
		hour_flags = _get_pcvar_flags(cvar_freevip_flags)
		if (hour_flags == 0)
			hour_flags = -1
		
		if (!freevip_inform[id]) {
			freevip_inform[id] = true
			if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L!", id, "FREE_VIP_GOT")
			else _client_print_color(id, "^4[ZMVIP] ^1%L!", id, "FREE_VIP_GOT")
			client_cmd(id, "spk /sound/buttons/bell1.wav")
		}
	}
	else if (freevip_inform[id]) {
		freevip_inform[id] = false
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L...", id, "FREE_VIP_EXPIRED")
		else _client_print_color(id, "^4[ZMVIP] ^1%L...", id, "FREE_VIP_EXPIRED")
		client_cmd(id, "spk /sound/buttons/blip1.wav")
	}
	
	static i, d, value
	static const double_attribs[] = {
		AT_MULTIJUMP,
		AT_EXTRA_HP,
		AT_EXTRA_GRAVITY
	}
	d = 0
	
	for(i=0; i<player_attributes;) {
		
		if (double_attrib_update) {
			
			if (d >= sizeof(double_attribs))
				break;
				
			i = double_attribs[d++];
		}	
		
		if (p_data[id][FLAGS] == 0 && hour_flags == 0)
			break;
		
		if (!(BIT(i) & p_data[id][FLAGS]) && !(BIT(i) & hour_flags) || (BIT(i) & gamemode_disable_flags)) {
			i++
			continue;
		}
		
		value = 0
		switch(i) {
			case AT_MULTIJUMP: {
				new jnum = get_pcvar_num(cvar_multijump)
				if(jnum) {
					static nflags, isspecial
					nflags = _get_pcvar_flags(cvar_multijump_allow)
					isspecial = is_special_character(id)
					
					if((nflags & FLAG_A && !p_zombie[id]) || (nflags & FLAG_B && p_zombie[id]) && !isspecial) value = jnum
					else if((nflags & FLAG_C && !p_zombie[id]) || (nflags & FLAG_D && p_zombie[id]) && isspecial) value = jnum
				}
			}
			case AT_ARMOR: value = get_pcvar_num(cvar_armor)
			case AT_UNLIMITED_CLIP: value = get_pcvar_num(cvar_unlimited_clip)
			case AT_NO_FALL_DMG: value = get_pcvar_num(cvar_no_fall_dmg)
			case AT_EXTRA_DMG: value = ((get_pcvar_float(cvar_extra_dmg)>0)?1:0)
			case AT_EXTRA_HP: value = get_pcvar_num(p_zombie[id]?cvar_extra_hp_zombie:cvar_extra_hp_human)
			case AT_EXTRA_GRAVITY: value = (get_pcvar_float(p_zombie[id]?cvar_extra_gravity_zombie:cvar_extra_gravity_human)>0.0)?1:0
			case AT_EXTRA_FRAGS: value = get_pcvar_num(cvar_extra_frags)
			case AT_EXTRA_KILL_AMMO: value = get_pcvar_num(cvar_extra_kill_ammo)
			case AT_EXTRA_ARMOR: value = get_pcvar_num(cvar_extra_armor)
			case AT_EXTRA_INFECT_AMMO: value = get_pcvar_num(cvar_extra_infect_ammo)
			case AT_EXTRA_INFECT_HEALTH: value = get_pcvar_num(cvar_extra_infect_health)
#if EXTRA_ITEMS == ON
			case AT_EXTRA_ITEMS: value = p_data[id][FLAGS]?1:0
#endif
			case AT_DAMAGE_REWARD: value = get_pcvar_num(cvar_damage_reward)
#if MODIFICATION != OLD
			case AT_VIP_MODEL: value = (p_vip_model_zombie[0]!=EOS||p_vip_model_human[0]!=EOS)
#endif
			case AT_VIP_CLASS: value = get_pcvar_num(cvar_viponly_class)
			case AT_CHATTAG: value = get_pcvar_num(cvar_chat_viptag)
			case AT_VIPINSCORE: value = get_pcvar_num(cvar_vipniscoretable)
			case AT_GRENADE_IMMUNITY: value = _get_pcvar_flags(cvar_grenades_immunity)
		}
		ATTRIB(id, i) = value
		
		if (!double_attrib_update)
			i++
	}
}
public forward_event_round_start() {
		
	arrayset(p_bought_per_round, 0, sizeof(p_bought_per_round))
	current_gamemode = 0
}
public forward_event_deathmsg() {
	
	static attacker, victim
	attacker = read_data(1)
	victim = read_data(2)
	
	if (attacker == victim)
		return;
		
	if(IS_PLAYER(attacker)) {
		if (get_pcvar_num(cvar_extra_ignore_for_special) && is_special_character(attacker))
			return;
			
		if (ATTRIB(attacker, AT_EXTRA_ARMOR) && !p_zombie[attacker] && p_zombie[victim])
			set_user_armor(attacker, get_user_armor(attacker)+ATTRIB(attacker, AT_EXTRA_ARMOR))
		if(ATTRIB(attacker, AT_EXTRA_KILL_AMMO))
			zv_currency_give(attacker, p_attribs[attacker][AT_EXTRA_KILL_AMMO])
		if(ATTRIB(attacker, AT_EXTRA_FRAGS))
			set_user_frags(attacker, get_user_frags(attacker)+ATTRIB(attacker, AT_EXTRA_FRAGS))
	}			
}

public forward_event_reset_hud(id) {
	
	if (ATTRIB(id, AT_VIPINSCORE)) {
		if(is_user_alive(id)) {
			message_begin(MSG_ALL, msg_scoreattrib)
			write_byte(id)
			write_byte(4)
			message_end()
		}
	}
}
#if MODIFICATION == NEW
public zp_fw_core_spawn_post(id) {
#else
public forward_player_spawn(id) {
#endif
#if MODIFICATION == NEW
	p_zombie[id] = zp_core_is_zombie(id)?true:false
#else
	p_zombie[id] = zp_get_user_zombie(id)?true:false
#endif
	set_user_atribs(id)
	
	if (first_spawn[id]) {
		set_task(1.0, "show_vip_timeleft", id, _, _, "a", 6)
		first_spawn[id] = false
	}
}

public forward_player_takedamage_pre(victim, inflictor, attacker, Float:damage, damage_type) {
	
	if(damage_type & DMG_FALL && ATTRIB(victim, AT_NO_FALL_DMG)) return HAM_SUPERCEDE;
	else if(IS_PLAYER(attacker) && ATTRIB(attacker, AT_EXTRA_DMG)) {
			
		if (get_pcvar_num(cvar_extra_ignore_for_special) && is_special_character(attacker))
			return HAM_IGNORED;
			
		SetHamParamFloat(4, damage*get_pcvar_float(cvar_extra_dmg))
		return HAM_HANDLED;
	}
	
	return HAM_IGNORED;
}
public forward_player_takedamage_post(victim, inflictor, attacker, Float:damage, damage_type) {
	
	if(IS_PLAYER(attacker) && ATTRIB(attacker, AT_DAMAGE_REWARD)) {
		
		if(p_damage[attacker] > ATTRIB(attacker, AT_DAMAGE_REWARD)) {
			
			zv_currency_give(attacker, 1)
			p_damage[attacker] = 0.0
		}
		else
			p_damage[attacker] += damage
	}
}

public forward_cmdstart(id, uc_handle) {
	
	static button, flags
	button = get_uc(uc_handle, UC_Buttons)
	flags = entity_get_int(id, EV_INT_flags)
	
	if(flags & FL_ONGROUND)
		p_jumpsnum[id] = 0
	
	if(button & IN_JUMP && !(get_user_oldbutton(id) & IN_JUMP)) {
		
		if(!(flags & FL_ONGROUND) && ++p_jumpsnum[id] <= ATTRIB(id, AT_MULTIJUMP)) {
			
			static Float:velocity[3]
			entity_get_vector(id, EV_VEC_velocity, velocity)
			velocity[2] = random_float(265.0,285.0)
			entity_set_vector(id,EV_VEC_velocity,velocity)
		}
	}
}
#define EV_NADE_TYPE	EV_INT_flTimeStepSound
#define NADE_TYPE_INFECTION	1111 
public forward_grenade_think(ent) {
		
	if (is_valid_ent(ent) && entity_get_int(ent, EV_NADE_TYPE) == NADE_TYPE_INFECTION) {
		p_grenade_time[entity_get_edict(ent, EV_ENT_owner)] = get_gametime()
	}
}
// Credits: MeRcyLeZZ
public message_cur_weapon(msg_id, msg_dest, msg_entity)
{
	if (!is_user_alive(msg_entity) || get_msg_arg_int(1) != 1) return;
	
	static weapon, clip
	weapon = get_msg_arg_int(2)
	clip = get_msg_arg_int(3)
	
	if (MAXCLIP[weapon] > 2 && ATTRIB(msg_entity, AT_UNLIMITED_CLIP)) {
		
		set_msg_arg_int(3, get_msg_argtype(3), MAXCLIP[weapon])
		
		if (clip < 2) {
			
			static wname[32], weapon_ent
			get_weaponname(weapon, wname, sizeof wname - 1)
			weapon_ent = find_ent_by_owner(-1, wname, msg_entity)
			//		   OFFSET_CLIPAMMO	OFFSET_LINUX_WEAPONS
			set_pdata_int(weapon_ent, 51, MAXCLIP[weapon], 4)
		}
	}
}

enum _:ChanellsStruct {
	channel[8],
	translation[42]
}
new const chat_channels[][ChanellsStruct] = {
    {"CT", "^1(Humans) ^4[VIP] ^3%s^1 :  %s"},
    {"T", "^1(Zombies) ^4[VIP] ^3%s^1 :  %s"},
    {"CT_Dead", "^1*DEAD*(Humans) ^4[VIP] ^3%s^1 :  %s"},
    {"T_Dead", "^1*DEAD*(Zombies) ^4[VIP] ^3%s^1 :  %s"},
    {"Spec", "^1(Spectator) ^4[VIP] ^3%s^1 :  %s"},
    {"All", "^4[VIP] ^3%s :  ^1%s"},
    {"AllDead", "^1*DEAD* ^4[VIP] ^3%s^1 :  %s"},
    {"AllSpec", "^1*SPEC* ^4[VIP] ^3%s^1 :  %s"}
}
 
public message_say_text(msg_id, msg_dest, msg_entity) {
	
	if (!ATTRIB(msg_dest, AT_CHATTAG))
		return;
		
	static message[250]
	get_msg_arg_string(2, message, charsmax(message))
	
	if (ATTRIB(msg_dest, AT_CHATTAG) == 1) {
		if (message[0] == '#' && message[9] == 'C' && equali(message, "#Cstrike_Chat_", 14)) {
			new i
			
			for (i=0; i<sizeof(chat_channels); i++) {
				if (equal(message[14], chat_channels[i][channel])) {
					
					set_msg_arg_string(2, chat_channels[i][translation])
					get_user_name(msg_dest, message, charsmax(message))
					set_msg_arg_string(3, message)
					return;
				}
			}
		}
		else {
			format(message, charsmax(message), "^4[VIP]%s", message)
			set_msg_arg_string(2, message)
		}
	}
	else if (ATTRIB(msg_dest, AT_CHATTAG) == 2) {
		if (message[9] == 'C' && equali(message, "#Cstrike_Chat_", 14)) {
			
			get_msg_arg_string(4, message, charsmax(message))
			static tag_index
			
			do {		
				tag_index = findtag(message, "<VIP>")
				if (tag_index != -1) {
					while (message[tag_index+5] != EOS) {
						message[tag_index] = message[tag_index+5]; tag_index++
					}
					message[tag_index] = EOS
				}
			}
			while (tag_index != -1)
				;
				
			if (ATTRIB(msg_dest, AT_CHATTAG))
				format(message, charsmax(message), "<VIP> %s", message)
				
			set_msg_arg_string(4, message)
		}
	}
}

public client_infochanged(id) {
	
	new info[5]
	read_argv(1, info, charsmax(info))
	if (equal(info, "name"))
		VipsDBGet(id)
}

public client_putinserver(id) {
	
	p_data[id][FLAGS] = 0
	p_data[id][SETTINGS] = 0
	p_data[id][TIMESTAMP] = 0
	first_spawn[id] = true
	arrayset(p_attribs[id], 0, player_attributes)
	freevip_inform[id] = false
	p_grenade_time[id] = 0.0
	p_damage[id] = 0.0
	p_jumpsnum[id] = 0
		
	if (!VipsDBGet(id))
		return;
	
	if (p_data[id][TIMESTAMP] > 0 && p_data[id][TIMESTAMP] < get_systime()) {
		
		VipsDBRemove(id)
		return;
	}
	
	if (p_data[id][FLAGS]) {
		new authid[30], ip[30], name[45]
		get_user_name(id, name, charsmax(name))
		get_user_authid(id, authid, charsmax(authid))
		get_user_ip(id, ip, charsmax(ip), 1)
		log_amx("[ZMVIP] VIP Connected: %s (%s) [%s].", name, authid, ip)
	}
		
	if (ATTRIB(id, AT_CHATTAG) && get_pcvar_num(cvar_vip_connected_to_server)) {
		
		new name[35]
		get_user_name(id, name, charsmax(name))
		switch (get_pcvar_num(cvar_vip_connected_to_server)) {
			case 1:
				if (is_amxmodx_new_version) client_print_color(0, 0, "^4[VIP] %s ^1%L.", name, LANG_PLAYER, "CONNECTED_TO_SERVER")
				else _client_print_color(0, "^4[VIP] %s ^1%L.", name, LANG_PLAYER, "CONNECTED_TO_SERVER")
			case 2: {
				set_hudmessage(255, 170, 0, 0.02, 0.71, 0, 6.0, 6.0)
				show_hudmessage(0, "[VIP] %s %L", name, LANG_PLAYER, "CONNECTED_TO_SERVER")
			}
			case 3: {
				if (is_amxmodx_new_version) {
					set_dhudmessage(255, 170, 0, 0.02, 0.71, 0, 6.0, 6.0)
					show_dhudmessage(0, "[VIP] %s %L", name, LANG_PLAYER, "CONNECTED_TO_SERVER")
				}
				else {
					_set_dhudmessage(255, 170, 0, 0.02, 0.71, 0, 6.0, 6.0)
					_show_dhudmessage(0, "[VIP] %s %L", name, LANG_PLAYER, "CONNECTED_TO_SERVER")
				}
			}
		}		
	}
}
public client_disconnect(id) {
	
	p_data[id][FLAGS] = 0
	p_damage[id] = 0.0
	p_jumpsnum[id] = 0
	p_data[id][SETTINGS] = 0
	
	if (p_data[id][TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT) {
		VipsDBRemove(id)
		return;
	}
	
	if (p_data[id][TIMESTAMP] == ZV_DURATION_TILL_MAP) {
		p_data[id][PASS][charsmax(p_data[][PASS])] = floatround(get_gametime()*100, floatround_floor)
		VipsDBSet(id)
	}
}

public show_vip_info(id) {
	
	if (file_exists("vip.txt")) {
		
		show_motd(id, "vip.txt")
	}
	else {
		log_amx("WARNING: Missing vip.txt file in cstrike directory. It's used by /vip command to show information about privileges on server.")
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "NO_VIP_TXT")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "NO_VIP_TXT")
		print_admin_contacts(id)
	}
}
public show_vips_online(id) {
	
	new bool:first = true, message[256], len
	
	for (new i=0; i<maxplayers; i++) {
		
		if (p_data[i][FLAGS]) {
			
			if (!first) {
				
				message[len++] = ','
				message[len++] = ' '
			}
			message[len++] = '^4'
			message[len] = EOS
			len += get_user_name(i, message[len], charsmax(message)-len)
			message[len++] = '^1'
			message[len] = EOS
			
			first = false
		}
	}
	
	if (first) {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L...", id, "NO_VIP_ONLINE")
		else _client_print_color(id, "^4[ZMVIP] ^1%L...", id, "NO_VIP_ONLINE")
	}
	else {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L: %s.", id, "ONLINE_VIPS", message)
		else _client_print_color(id, "^4[ZMVIP] ^1%L: %s.", id, "ONLINE_VIPS", message)
	}
	
	print_admin_contacts(id)
	
	return PLUGIN_CONTINUE;
}
show_buy_menu(id) {
	
	new duration = get_cvar_duration(cvar_vip_buy_duration)
	
	if (duration == -1) {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "SERVER_CONFIG_ERROR")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "SERVER_CONFIG_ERROR")
		return;
	}
		
	new timeleft[100]
	convert_duration_to_string(id, duration, timeleft, charsmax(timeleft))
	
	new menu[250]
	formatex(menu, charsmax(menu),\
	"\r%L^n^n\
	%L: \y%d %L^n\
	\r%L: \y%s^n^n\
	\r1. \w%L^n^n\
	\r0. \w%L", id, "BUY_VIP_PRIVILEGE",
	id, "PRICE", get_pcvar_num(cvar_vip_price), id, zv_get_currency()==CURRENCY_AMMO_PACKS?"AMMO_PACKS":"MONEY",
	id, "TIME", timeleft,
	id, "BUY", id, "EXIT")
	
	show_menu(id, MENU_KEY_0|MENU_KEY_1, menu, -1, "Menu Buy")
}

public forward_buy_menu_handler(id, key) {
	
	if (key == 0) {
		
		new player_has = zv_currency_get(id)
		
		if (player_has >= get_pcvar_num(cvar_vip_price)) {
			
			new duration
			duration = get_cvar_duration(cvar_vip_buy_duration)
			
			if (duration == -1) {
				if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "SERVER_CONFIG_ERROR")
				else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "SERVER_CONFIG_ERROR")
				print_admin_contacts(id)
				return;
			}
			
			zv_currency_set(id, player_has-get_pcvar_num(cvar_vip_price))
			native_zv_set_user_flags(id, duration, _get_pcvar_flags(cvar_vip_buy_flags))
			
			if (duration >= 0) {
				
				if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP")
				else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP")
			}
			else {
				if (duration == ZV_DURATION_TILL_MAP) { 
					
					if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP_TILL_MD")
					else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP_TILL_MD")
				}
				else if (duration == ZV_DURATION_TILL_DISCONNECT) { 
					
					if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP_TILL_D")
					else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "PURCHASED_VIP_TILL_D")
				}
			}
			client_cmd(id, "spk /sound/buttons/bell1.wav")
		}
		else {
			if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L %L!", id, "NOT_ENOUGHT", id,\
			zv_get_currency()==CURRENCY_AMMO_PACKS?"AMMO_PACKS":"MONEY")
			else _client_print_color(id, "^4[ZMVIP] ^1%L %L!", id, "NOT_ENOUGHT", id,\
			zv_get_currency()==CURRENCY_AMMO_PACKS?"AMMO_PACKS":"MONEY")
			client_cmd(id, "spk /sound/buttons/blip1.wav")
		}
	}
}

//////////////////////// VIP MENU FUNCTIONS //////////////////////
public show_vip_menu_console(id) {
	
	show_vip_menu(id)
	return PLUGIN_HANDLED;
}
public show_vip_menu(id) {
#if EXTRA_ITEMS == OFF
	if (p_data[id][FLAGS]) {
		
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "ALREADY_VIP_INFO")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "ALREADY_VIP_INFO")
	}
	else if (get_pcvar_num(cvar_vip_price) > 0) {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP")
		show_buy_menu(id)
		return PLUGIN_CONTINUE;
	}
	else {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP_INFO")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP_INFO")
		return PLUGIN_CONTINUE;
	}
#else
	if (!ATTRIB(id, AT_EXTRA_ITEMS)) {
		
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP_MENU")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "YOU_ARE_NOT_VIP_MENU")
		show_buy_menu(id)
		return PLUGIN_CONTINUE;
	}
		
	new maximum = get_pcvar_num(cvar_buys_per_round)
	if (maximum && p_bought_per_round[id] > maximum) {
		
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L", id, "EXCEEDED_BUY_LIMIT", maximum)
		else _client_print_color(id, "^4[ZMVIP] ^1%L", id, "EXCEEDED_BUY_LIMIT", maximum)
		return PLUGIN_CONTINUE;
	}
#if MODIFICATION == NEW
	
	if (is_user_alive(id)) {
		p_views_extra_items_menu[id] = true
		zp_items_show_menu(id)
		p_views_extra_items_menu[id] = false
	}
	else {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "NOT_ALIVE")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "NOT_ALIVE")
	}
#else
	
	if(registered_extra_items_num) {
		
		new item_data[item_struct], item_string[250], menu_header[40]
		formatex(menu_header, charsmax(menu_header), "\r%L:", id, "VIP_MENU_TOP")
		new menu = menu_create(menu_header, "show_vip_menu_handler")
		
		new bool:special = is_special_character(id)?true:false;
		new info[5]
		
		for(new i=0; i<registered_extra_items_num; i++) {
			
			ArrayGetArray(array_vip_extra_items, i, item_data)
			
			if (item_data[item_team] > 0
			&& (item_data[item_team]&ZP_TEAM_ZOMBIE && !p_zombie[id])
			|| (item_data[item_team]&ZP_TEAM_HUMAN && p_zombie[id])
			|| (item_data[item_team]&(ZP_TEAM_NEMESIS|ZP_TEAM_SURVIVOR) && !special)	
			)
				continue;
			
			formatex(item_string, charsmax(item_string), "%s \y%d %L", \
			item_data[item_name], item_data[item_cost], id, zv_get_currency()==CURRENCY_AMMO_PACKS?"AMMO_PACKS":"MONEY")
			num_to_str(i, info, charsmax(info))
			menu_additem(menu, item_string, info)
		}
			
		if(menu_items(menu)) menu_display(id, menu, 0)
		else {
			if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "NO_ITEMS_FOR_TEAM")
			else _client_print_color(id, "^4[ZMVIP] ^3%L.", id, "NO_ITEMS_FOR_TEAM")
		}
	}
	else {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "NO_PLUGINS_LOADED")
		else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "NO_PLUGINS_LOADED")
	}
#endif
#endif
	static timeleft[100]
	convert_duration_to_string(id, max(p_data[id][TIMESTAMP]-get_systime(), 0), timeleft, charsmax(timeleft))
	
	if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1VIP %L: ^3%s", id, "TIMELEFT", timeleft)
	else _client_print_color(id, "^4[ZMVIP] ^1VIP %L: ^3%s", id, "TIMELEFT", timeleft)
	
	return PLUGIN_CONTINUE
}
#if MODIFICATION != NEW && EXTRA_ITEMS == ON
public show_vip_menu_handler(id, menu, item)
{
	if(item == MENU_EXIT )
	{
		menu_destroy(menu)
		return PLUGIN_HANDLED
	}

	new item_id, _blank, info[5]
	menu_item_getinfo(menu, item, _blank, info, charsmax(info), "", _blank, _blank)
	
	item_id = str_to_num(info)

	new retval, item_data[item_struct]
	ArrayGetArray(array_vip_extra_items, item_id, item_data)
	
	if (chached_show_vip_items)
		ExecuteForward(fw_extraitemselected, retval, id, item_data[item_plid])
	else
		ExecuteForward(fw_extraitemselected, retval, id, item_id)
		
	if (retval < ZP_PLUGIN_HANDLED) {
		zv_currency_set(id, zv_currency_get(id)-item_data[item_cost])
		if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L '^4%s^1'", id, "PURCHASED", item_data[item_name])
		else _client_print_color(id, "^4[ZMVIP] ^1%L '^4%s^1'", id, "PURCHASED", item_data[item_name])
		p_bought_per_round[id]++
	}
	
	menu_destroy(menu)
	return PLUGIN_HANDLED
}
#endif
public vip_time_check() {
	
	static id, timestamp
	timestamp = get_systime()
	
	for (id=1; id<33; id++) {
		if (p_data[id][TIMESTAMP] > 0 && p_data[id][TIMESTAMP] < timestamp) {
			
			native_zv_remove_user_flags(id)
		}
	}
}

is_special_character(id) {
		
	if(p_zombie[id]) {
#if MODIFICATION == NEW
		if(!(natives_filter_out & BIT(NATIVE_ZP_CLASS_NEMESIS_GET)) && zp_class_nemesis_get(id)
		|| !(natives_filter_out & BIT(NATIVE_ZP_CLASS_ASSASSIN_GET)) && zp_class_assassin_get(id)
		)
			return true;
#else
		if(zp_get_user_nemesis(id)
		|| !(natives_filter_out & BIT(NATIVE_ZP_CLASS_BOMBARDIER_GET)) && zp_get_user_bombardier(id)
		)
			return true;
#endif
	}
	else {
#if MODIFICATION == NEW
		if(!(natives_filter_out & BIT(NATIVE_ZP_CLASS_SURVIVOR_GET)) && zp_class_survivor_get(id)
		|| !(natives_filter_out & BIT(NATIVE_ZP_CLASS_SNIPER_GET)) && zp_class_sniper_get(id)
		)
			return true;
#else
		return zp_get_user_survivor(id)
#endif
	}
	return false;
}

check_named_privileges(id, nick[], pass[]) {
	
	new num
	if (!array_vips_database_nick || !(num = VIPCNT(NAMES))) {
		p_data[id][SETTINGS] = 0
		p_data[id][FLAGS] = 0
		return false;
	}
	
	for (new index=0; index<num; index++) {
		ArrayGetArray(array_vips_database_nick, index, p_data[id])
		if (p_data[id][SETTINGS] & FLAG_C) {
			if (((p_data[id][SETTINGS]&FLAG_N)?contain(nick, p_data[id][AUTH]):containi(nick, p_data[id][AUTH])) == -1)
				continue;
		}
		else {
			if (!((p_data[id][SETTINGS]&FLAG_N)?equal(nick, p_data[id][AUTH]):equali(nick, p_data[id][AUTH])))
				continue;
		}
		
		if (!EMPTY(p_data[id][PASS])) {
		
			p_data[id][PASS][charsmax(p_data[][PASS])] = EOS
			if (!equal(p_data[id][PASS], pass)) {
				if (p_data[id][SETTINGS] & FLAG_K) {
					return false;
				}
				else {
					client_print(id, print_console, "[ZMVIP] %L.", id, "PASS_NOT_MATCH")
					continue;
				}
			}
		}
		p_data[id][INDEX] = index
		return true;
	}
	
	p_data[id][SETTINGS] = 0
	p_data[id][FLAGS] = 0
	return false;
}
public cmd_vips_remove(id, level, cid) {
	
	if(id != 0 && !(get_user_flags(id) & level))
		return PLUGIN_HANDLED;

	if (read_argc() < 1) {
		console_print(id, "[ZM VIP] %L: zm_vip_remove <NICK/AUTH/IP>.", id, "USAGE")
		return PLUGIN_HANDLED;
	}
	
	new argument[40]
	read_argv(1, argument, charsmax(argument))
	
	new player = cmd_target(id, argument, CMDTARGET_OBEY_IMMUNITY|CMDTARGET_ALLOW_SELF|CMDTARGET_NO_BOTS)
	if (!player)
		return PLUGIN_HANDLED;
	
	new name[40]
	get_user_name(player, name, charsmax(name))
	
	if (!p_data[player][FLAGS]) {
		console_print(id, "[ZM VIP] %L", id, "DOES_NOT_HAVE_VIP", name)
		return PLUGIN_HANDLED;
	}
	
	if (native_zv_remove_user_flags(player))
		console_print(id, "[ZM VIP] %L.", id, "PRIVILEGE_REMOVED", name)
	else
		console_print(id, "[ZM VIP] %L.", id, "PLUGIN_ERROR_REMOVING", name)
	
	return PLUGIN_HANDLED;
}

public cmd_vips_reload(id, level, cid) {
	
	if(id != 0 && !(get_user_flags(id) & level))
		return PLUGIN_HANDLED;

	server_cmd("amx_reloadadmins")
	server_exec()
	
	TrieClear(trie_vips_database)
	ArrayClear(array_vips_database)
	if (array_vips_database_nick)
		ArrayClear(array_vips_database_nick)
		
	arrayset(total_vips_count, 0, sizeof(total_vips_count))
#if VIPS_FILE_SYSTEM != OFF
	load_ini_file()
#endif
	load_datafile()
		
#if VIPS_FILE_SYSTEM != FORCED
	new num_admins = admins_num()
	for (new i=0; i<num_admins; i++) {
		if (admins_lookup(i, AdminProp_Access)&VIP_SYS_FLAG) {
			VIPINC(AMX)
		}
	}
#endif
	new players[32], num_players, i
	get_players(players, num_players, "ch")
	
	for (i=0; i<num_players; i++) {
		VipsDBGet(players[i])
	}
	
	if (id) {
		static authid[30], ip[30], name[45]
		get_user_name(id, name, charsmax(name))
		get_user_authid(id, authid, charsmax(authid))
		get_user_ip(id, ip, charsmax(ip), 1)
		log_amx("Cmd exec: zm_vip_reload. By: %s (%s) (%s)", name, authid, ip)
	}
	else
		log_amx("Cmd exec: zm_vip_reload. From server console")
	
	console_print(id, "[ZM VIP] Reloaded %d vips", VIPCNT(DAT)+VIPCNT(INI)+VIPCNT(AMX))
	return PLUGIN_HANDLED;
}

public cmd_list_vips(id, level, cid) {
	
	if(id != 0 && !(get_user_flags(id) & level))
		return PLUGIN_HANDLED;
	
	new key[40], i, size = ArraySize(array_vips_database)
	new data[vips_database_type]
	
	console_print(id, "Main VIPs: %d", VIPCNT(MAIN)+VIPCNT(NAMES))
	new load_types[][] = {"DAT", "INI", "AMX"}
	new load_type, flags_str[30], time_str[25]
	
	for (i=0; i<size; i++) {
		
		ArrayGetString(array_vips_database, i, key, sizeof(key))
		
		if (EMPTY(key))
			continue;
		
		if (!TrieGetArray(trie_vips_database, key, data, vips_database_type))
			continue;
		
		if (data[SETTINGS] & LOAD_FROM_DAT)
			load_type = 0
#if VIPS_FILE_SYSTEM != OFF
		if (data[SETTINGS] & LOAD_FROM_INI)
			load_type = 1
#endif
#if VIPS_FILE_SYSTEM != FORCED
		if (data[SETTINGS] & LOAD_FROM_AMX)
			load_type = 2
#endif
		flags_str[0] = EOS
		time_str[0] = EOS
		if (data[FLAGS] == -1)
			add(flags_str, charsmax(flags_str), "All")
		else
			get_flags(data[FLAGS], flags_str, charsmax(flags_str))
		
		if (data[TIMESTAMP] == ZV_DURATION_PERMANENT)
			add(time_str, charsmax(time_str), "Permanent")
		else if (data[TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT)
			add(time_str, charsmax(time_str), "Disconnect")
		else if (data[TIMESTAMP] == ZV_DURATION_TILL_MAP)
			add(time_str, charsmax(time_str), "Map change")
		else
			format_time(time_str, charsmax(time_str), "%Y/%m/%d-%H:%M", data[TIMESTAMP])
			
		console_print(id, "%s| ^"%s^" ^"%s^" ^"%s^"", load_types[load_type],
		data[AUTH], flags_str, time_str)
	}
	
	if (array_vips_database_nick) {
		size = ArraySize(array_vips_database_nick)
		for (i=0; i<size; i++) {
			
			ArrayGetArray(array_vips_database_nick, i, data)
			
			if (data[SETTINGS] & LOAD_FROM_DAT)
				load_type = 0
#if VIPS_FILE_SYSTEM != OFF
			if (data[SETTINGS] & LOAD_FROM_INI)
				load_type = 1
#endif
#if VIPS_FILE_SYSTEM != FORCED
			if (data[SETTINGS] & LOAD_FROM_AMX)
				load_type = 2
#endif
			
			if (data[FLAGS] == -1)
				add(flags_str, charsmax(flags_str), "All")
			else
				get_flags(data[FLAGS], flags_str, charsmax(flags_str))
			
			if (data[TIMESTAMP] == ZV_DURATION_PERMANENT)
				add(time_str, charsmax(time_str), "Permanent")
			else if (data[TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT)
				add(time_str, charsmax(time_str), "Disconnect")
			else if (data[TIMESTAMP] == ZV_DURATION_TILL_MAP)
				add(time_str, charsmax(time_str), "Map change")
			else
				format_time(time_str, charsmax(time_str), "%Y/%m/%d-%H:%M", data[TIMESTAMP])
				
			console_print(id, "%s| ^"%s^" ^"%s^" ^"%s^"", load_types[load_type],
			data[AUTH], flags_str, time_str)
		}
	}
#if VIPS_FILE_SYSTEM != FORCED
	console_print(id, "Amx VIPs: %d", VIPCNT(AMX))
	
	new num_admins = admins_num()
	for (new i=0; i<num_admins; i++) {
		if (admins_lookup(i, AdminProp_Access)&VIP_SYS_FLAG) {
			new auth[40]
			admins_lookup(i, AdminProp_Auth, auth, charsmax(auth))
			
			console_print(id, "AMX| ^"%s^"", auth)
		}
	}
#endif
	return PLUGIN_HANDLED;
}
		
public set_freevip_hour(id, level, cid) {
	
	if(id != 0 && !(get_user_flags(id) & level))
		return PLUGIN_HANDLED;
	
	if (read_argc() < 2)  {
		
		if (freevip_enabled)
			console_print(id, "^"zm_vip_freevip_hour^" is ^"%d:%d-%d:%d^"", \
			freevip_hours[0], freevip_hours[1], freevip_hours[2], freevip_hours[3])
		else
			console_print(id, "^"zm_vip_freevip_hour^" is ^"off^"")
		return PLUGIN_HANDLED;
	}
	
	new string[12], index
	read_argv(1, string, charsmax(string))
	
	if(string[0] == 'o' || (string[0] == '0' && string[1] == EOS)) {
		freevip_enabled = false
		return PLUGIN_HANDLED;
	}
	
	if (string[2] == ':') {
		freevip_hours[0] = (string[0]-'0')*10+(string[1]-'0')
		freevip_hours[1] = (string[3]-'0')*10+(string[4]-'0')
		index = 5
	}
	else if (string[1] == ':') {
		freevip_hours[0] = (string[0]-'0')
		freevip_hours[1] = (string[2]-'0')*10+(string[3]-'0')
		index = 4
	}
	else {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	if (freevip_hours[0] >= 24 || freevip_hours[1] >= 60) {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	if (string[index++] != '-') {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	if (string[index+2] == ':') {
		freevip_hours[2] = (string[index]-'0')*10+(string[index+1]-'0')
		freevip_hours[3] = (string[index+3]-'0')*10+(string[index+4]-'0')
	}
	else if (string[index+1] == ':') {
		freevip_hours[2] = (string[index]-'0')
		freevip_hours[3] = (string[index+2]-'0')*10+(string[index+3]-'0')
	}
	else {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	if (freevip_hours[2] >= 24 || freevip_hours[3] >= 60) {
		log_amx("ERROR: Inccorect zm_freevip_hour cvar value! Set correctly, or turn off by typing ^"off^".")
		return PLUGIN_HANDLED;
	}
	
	freevip_enabled = true
	
	return PLUGIN_HANDLED;
}

freevip_hour_check() {

	if (freevip_hours[0] == freevip_hours[2] && freevip_hours[1] == freevip_hours[3]) {
		return true;
	}
	
	new h, m, s
	time(h, m, s)
	
	new hour_low, hour_high
	hour_low = freevip_hours[0]*100+freevip_hours[1]
	hour_high = freevip_hours[2]*100+freevip_hours[3]
	
	if ((hour_low <= (h*100+m) < hour_high) || (hour_high <= (h*100+m) < hour_low))
		return true;
	
	return false
}

//////////////////////// API STUFF ///////////////////////////
#if MODIFICATION == NEW
public zp_fw_core_infect_pre(id, attacker) {
#else
public zp_user_infect_attempt(id, attacker, nemesis) {
#endif
	if (ATTRIB(id, AT_GRENADE_IMMUNITY) & FLAG_A && p_grenade_time[attacker] 
	&& get_gametime()-p_grenade_time[attacker] < 0.5)
#if MODIFICATION == NEW
		return PLUGIN_HANDLED;
#else
		return ZP_PLUGIN_HANDLED;
#endif
	
	return PLUGIN_CONTINUE;
}
#if MODIFICATION == NEW
public zp_fw_core_infect_post(id, attacker) {
#else
public zp_user_infected_post(id, attacker) {
#endif	
	p_zombie[id] = true
	p_grenade_time[id] = 0.0
	
	set_user_atribs(id, true)
	set_user_atribs(attacker, true)
	
	if (get_pcvar_num(cvar_extra_ignore_for_special) && is_special_character(id))
		return;
	
	if (ATTRIB(id, AT_EXTRA_GRAVITY)) {
		new Float:gravity = get_user_gravity(id)-get_pcvar_float(cvar_extra_gravity_zombie)
		if (gravity < 0.0) gravity = 0.0
		set_user_gravity(id, gravity)
	}
	
	if(ATTRIB(attacker, AT_EXTRA_INFECT_HEALTH))
		set_user_health(attacker, get_user_health(attacker)+ATTRIB(attacker, AT_EXTRA_INFECT_HEALTH))
		
	if(ATTRIB(id, AT_EXTRA_HP))
		set_user_health(id, get_user_health(id)+ATTRIB(id, AT_EXTRA_HP))
	
	if(ATTRIB(attacker, AT_EXTRA_FRAGS))
		set_user_frags(attacker, get_user_frags(attacker)+ATTRIB(attacker, AT_EXTRA_FRAGS))
	
	if(ATTRIB(attacker, AT_EXTRA_INFECT_AMMO))
			zv_currency_give(attacker, p_attribs[attacker][AT_EXTRA_INFECT_AMMO])
#if MODIFICATION != OLD
	if(ATTRIB(id, AT_VIP_MODEL) && !EMPTY(p_vip_model_zombie))
#if MODIFICATION == NEW
		cs_set_player_model(id, p_vip_model_zombie)
#endif
#if MODIFICATION == OLD
		if (natives_filter_out & BIT(NATIVE_OVERRIDE_USER_MODEL)) {
			log_amx("WARNING: You are using old zombie plague version, that don't support custom VIP models.")
		}
		else
			zp_override_user_model(id, p_vip_model_zombie)
#endif
#endif
}
#if MODIFICATION == NEW
public zp_fw_core_cure_post(id) {
#else
public zp_user_humanized_post(id) {
#endif
	p_zombie[id] = false
	
	set_user_atribs(id, true)
	
	if (get_pcvar_num(cvar_extra_ignore_for_special) && is_special_character(id))
		return;
		
	if (ATTRIB(id, AT_EXTRA_GRAVITY)) {
		new Float:gravity = get_user_gravity(id)-get_pcvar_float(cvar_extra_gravity_human)
		if (gravity < 0.04) gravity = 0.04
		
		set_user_gravity(id, gravity)
	}
	if(ATTRIB(id, AT_EXTRA_HP))
		set_user_health(id, get_user_health(id)+ATTRIB(id, AT_EXTRA_HP))
	
	if(ATTRIB(id, AT_ARMOR))
		set_user_armor(id, ATTRIB(id, AT_ARMOR))
		
#if MODIFICATION != OLD
	if(ATTRIB(id, AT_VIP_MODEL) && !EMPTY(p_vip_model_human))
#if MODIFICATION == NEW
		cs_set_player_model(id, p_vip_model_human)
#endif
#if MODIFICATION == OLD
		if (natives_filter_out & BIT(NATIVE_OVERRIDE_USER_MODEL)) {
			log_amx("WARNING: You are using old zombie plague version, that don't support custom VIP models.")
		}
		else
			zp_override_user_model(id, p_vip_model_human)
#endif
#endif
}
#if MODIFICATION == NEW
public zp_fw_gamemodes_start(gamemode) {
#else
public zp_round_started(gamemode) {
	gamemode -= 1
#endif
	current_gamemode = gamemode
}
#if MODIFICATION == NEW
public zp_fw_grenade_fire_pre(id) {
	return (ATTRIB(id, AT_GRENADE_IMMUNITY) & FLAG_B)?PLUGIN_HANDLED:PLUGIN_CONTINUE;
}
public zp_fw_grenade_frost_pre(id) {
	return (ATTRIB(id, AT_GRENADE_IMMUNITY) & FLAG_C)?PLUGIN_HANDLED:PLUGIN_CONTINUE;
}
#endif
#if MODIFICATION == NEW
#if EXTRA_ITEMS == ON
public zp_fw_items_select_post(id, itemid, ignorecost) {
	
	if (VipsItemIs(EXTRA_ITEM, itemid))
		p_bought_per_round[id]++
}
#endif
public zp_fw_items_select_pre(id, itemid, ignorecost) {

	if (itemid == vip_buy_extra_item) {
		show_buy_menu(id)
		return ZP_ITEM_NOT_AVAILABLE;
	}
#if EXTRA_ITEMS == ON
	if (!registered_extra_items_num)
		return ZP_ITEM_AVAILABLE;
	
	if (VipsItemIs(EXTRA_ITEM, itemid)) {
		if (get_pcvar_num(cvar_vip_show_vip_items) > 0) {
		
			zp_items_menu_text_add("*VIP*")
			
			if (ATTRIB(id, AT_EXTRA_ITEMS)) {
				new maximum = get_pcvar_num(cvar_buys_per_round)
				if (maximum && p_bought_per_round[id] > maximum) {
					if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L", id, "EXCEEDED_BUY_LIMIT", maximum)
					else _client_print_color(id, "^4[ZMVIP] ^1%L", id, "EXCEEDED_BUY_LIMIT", maximum)
					return ZP_ITEM_NOT_AVAILABLE;
				}
				else {
					return ZP_ITEM_AVAILABLE;
				}
			}
			else
				return get_pcvar_num(cvar_vip_show_vip_items)==2?ZP_ITEM_NOT_AVAILABLE:ZP_ITEM_DONT_SHOW;
		}
	}
	else if (p_views_extra_items_menu[id])
		return ZP_ITEM_DONT_SHOW;
#endif
	return ZP_ITEM_AVAILABLE;
}

public zp_fw_class_human_select_pre(id, classid) {
	
	if (!VipsItemHandle)
		return ZP_CLASS_AVAILABLE;
		
	if (VipsItemIs(CLASS_HUMAN, classid)) {
	
		zp_class_human_menu_text_add("*VIP*")
		return (ATTRIB(id, AT_VIP_CLASS))?ZP_CLASS_AVAILABLE:ZP_CLASS_NOT_AVAILABLE;
	}
	
	return ZP_CLASS_AVAILABLE;
}

public zp_fw_class_zombie_select_pre(id, classid) {
	
	if (!VipsItemHandle)
		return ZP_CLASS_AVAILABLE;
		
	if (VipsItemIs(CLASS_ZOMBIE, classid)) {
	
		zp_class_zombie_menu_text_add("*VIP*")
		return (ATTRIB(id, AT_VIP_CLASS))?ZP_CLASS_AVAILABLE:ZP_CLASS_NOT_AVAILABLE;
	}
	
	return ZP_CLASS_AVAILABLE;
}
#endif
#if MODIFICATION != NEW
public zp_user_infected_pre(id) {
	
	if(VipsItemHandle && !ATTRIB(id, AT_VIP_CLASS)) { 
		
		if(VipsItemIs(CLASS_ZOMBIE, zp_get_user_next_class(id))) {
			zp_set_user_zombie_class(id, 0)
			client_print(id, print_center, "%L", id, "VIPONLY_CLASS")
			if (is_amxmodx_new_version) client_print_color(id, id, "^4[ZMVIP] ^1%L.", id, "VIPONLY_CLASS_INFO")
			else _client_print_color(id, "^4[ZMVIP] ^1%L.", id, "VIPONLY_CLASS_INFO")
		}
	}
}
public zp_extra_item_selected(id, itemid) {
	
	if (itemid == vip_buy_extra_item) {
		show_buy_menu(id)
		return ZP_PLUGIN_HANDLED;
	}
	return 1;
}
#endif
// Natives

public native_zv_get_user_flags(id) {
	return p_data[id][FLAGS];
}

public native_zv_set_user_flags(id, duration, flags) {
	
	new i, num, timestamp = get_systime(duration)
	
	if (id) {
		if (!is_user_connected(id))
			return false;
			
		goto skip_loop;
	}
	
	new players[32]
	get_players(players, num, "ch")
	
	for (i=0; i<num; i++) {
		id = players[i]
		
		skip_loop:
		
		if (!p_data[id][FLAGS] && duration == ZV_DURATION_IGNORE)
			return false;
		
		p_data[id][FLAGS] = flags==0?-1:flags;
		p_data[id][TIMESTAMP] = timestamp
		
		VipsDBSet(id)
		set_user_atribs(id)
	}
	
	return true;
}

public native_zv_remove_user_flags(id) {
	
	new i, num
	if (!VIPCNT(DAT) && !VIPCNT(INI) && !VIPCNT(AMX))
		return false;
	
	if (id) {
		
		if (!is_user_connected(id) || !p_data[id][FLAGS])
			return false;
		
		p_data[id][FLAGS] = 0
		p_data[id][TIMESTAMP] = 0
		arrayset(p_attribs[id], 0, player_attributes)
		
		return VipsDBRemove(id);
	}
	
	new players[32]
	get_players(players, num, "ch")
	
	for (i=0; i<num; i++) {
		id = players[i]
		
		p_data[id][FLAGS] = 0
		p_data[id][TIMESTAMP] = 0
		arrayset(p_attribs[id], 0, player_attributes)
		
		VipsDBRemove(id)
	}
	
	return true;
}

#if MODIFICATION == NEW
public native_zv_class_human_register(const name[], const description[], health, Float:speed, Float:gravity) {
	
	param_convert(1)
	param_convert(2)
	new class_id = zp_class_human_register(name, description, health, speed, gravity)
	
	VipsItemSet(CLASS_HUMAN, class_id)
	return class_id
}
public native_zv_class_zombie_register(const name[], const description[], health, Float:speed, Float:gravity) {

	param_convert(1)
	param_convert(2)
	new class_id = zp_class_zombie_register(name, description, health, speed, gravity)
	
	VipsItemSet(CLASS_ZOMBIE, class_id)
	return class_id
}
#if EXTRA_ITEMS == ON
public native_zv_items_register(const name[], cost) {
	
	param_convert(1)
	new item_id = zp_items_register(name, cost)
	
	VipsItemSet(EXTRA_ITEM, item_id)
	registered_extra_items_num++
	return item_id
}
#endif
#endif
#if MODIFICATION != NEW
public native_zv_register_zombie_class(const name[], const info[], const model[], const clawmodel[], hp, speed, Float:gravity, Float:knockback) {

	param_convert(1)
	param_convert(2)
	param_convert(3)
	param_convert(4)
	new class_id = zp_register_zombie_class(name, info, model, clawmodel, hp, speed, gravity, knockback)
	
	VipsItemSet(CLASS_ZOMBIE, class_id)
	return class_id
}
#if EXTRA_ITEMS == ON
public native_zv_register_extra_item2(const name[], cost, team) {

	param_convert(1)
	
	new item_data[item_struct]
	
	if(!array_vip_extra_items)
		array_vip_extra_items = ArrayCreate(item_struct)
	
	formatex(item_data[item_name], charsmax(item_data[item_name]), "*VIP* %s", name)
	item_data[item_cost] = cost
	item_data[item_team] = team
	
	if (chached_show_vip_items) {
	
		item_data[item_plid] = zp_register_extra_item(name, cost, team)
		
		VipsItemSet(EXTRA_ITEM, item_data[item_plid])
	}
	
	ArrayPushArray(array_vip_extra_items, item_data)
	registered_extra_items_num++
	
	return chached_show_vip_items?item_data[item_plid]:registered_extra_items_num
}
public native_zv_register_extra_item(const name[], const description[], cost, team) {
	
	param_convert(1)
	param_convert(2)
	
	new item_data[item_struct]
	
	if(!array_vip_extra_items)
		array_vip_extra_items = ArrayCreate(item_struct)
	
	formatex(item_data[item_name], charsmax(item_data[item_name]), "*VIP* %s \r[%s]", name, description)
	item_data[item_cost] = cost
	item_data[item_team] = team
	
	if (chached_show_vip_items) {
		
		item_data[item_plid] = zp_register_extra_item(name, cost, team)
		
		VipsItemSet(EXTRA_ITEM, item_data[item_plid])
	}
	
	ArrayPushArray(array_vip_extra_items, item_data)
	registered_extra_items_num++
	
	return chached_show_vip_items?item_data[item_plid]:registered_extra_items_num
}
public native_zv_force_buy_extra_item(id, itemid, ignorecost) {
	
	if (chached_show_vip_items) {
			
		zp_force_buy_extra_item(id, itemid, ignorecost)
		return;
	}
	
	new retval
	ExecuteForward(fw_extraitemselected, retval, id, itemid)
		
	if (retval >= ZP_PLUGIN_HANDLED && !ignorecost) {
		new item_data[item_struct]
		ArrayGetArray(array_vip_extra_items, itemid, item_data)
		zv_currency_set(id, zv_currency_get(id)+item_data[item_cost])
	}
}
public native_zv_get_extra_item_id(const name[]) {
	
	param_convert(1)
	
	if (chached_show_vip_items) {
		
		return zp_get_extra_item_id(name)
	}
	
	new item_data[item_struct]
	for (new i=0; i<registered_extra_items_num; i++) {
		
		ArrayGetArray(array_vip_extra_items, i, item_data)	
		if (equali(name, item_data[item_name]))
			return i;
	}
	
	return -1;
}
#endif
#endif
new dummy_record_count
public plugin_end() {
	if (dummy_record_count > 5)
		write_datafile()
	
/*	if (trie_vip_zombie_classes)
		TrieDestroy(trie_vip_zombie_classes)
#if MODIFICATION == NEW
	if (trie_vip_human_classes)
		TrieDestroy(trie_vip_human_classes)
#endif
#if EXTRA_ITEMS == ON
	if (trie_vip_extra_items)
		TrieDestroy(trie_vip_extra_items)
#if MODIFICATION != NEW
	if (array_vip_extra_items)
		ArrayDestroy(array_vip_extra_items)
#endif
#endif
	if (trie_vips_database)
		TrieDestroy(trie_vips_database)
	if (array_vips_database_nick)
		ArrayDestroy(array_vips_database_nick)
	*/
}
/*encode_date(d[]) { // TOOD: delete
	
	new ret
	d[4] = d[7] = EOS 
	ret += str_to_num(d)
	ret = (ret<<8)
	ret += str_to_num(d[5])
	ret = (ret<<8)
	ret += str_to_num(d[8])
	
	return ret
}

decode_date(d, ds[]) {

	num_to_str((d>>16), ds, 4)
	num_to_str((d>>8)&0xFF, ds[5], 4)
	num_to_str(d&0xFF, ds[8], 4)
	ds[4] = ds[7] = ':'
	ds[10] = EOS
}*/
stock zv_get_currency() {
#if MODIFICATION == NEW
	if (is_module_ammopacks_loaded)
		return CURRENCY_AMMO_PACKS;
	else
		return CURRENCY_MONEY;
#endif
	return CURRENCY_AMMO_PACKS;
}
stock zv_currency_give(id, amount) {
#if MODIFICATION == NEW
	if (is_module_ammopacks_loaded)
		zp_ammopacks_set(id, zp_ammopacks_get(id)+amount)
	else
		cs_set_user_money(id, cs_get_user_money(id)+amount)
#else
	zp_set_user_ammo_packs(id, zp_get_user_ammo_packs(id)+amount)
#endif
}
stock zv_currency_set(id, amount) {
#if MODIFICATION == NEW
	if (is_module_ammopacks_loaded)
		zp_ammopacks_set(id, amount)
	else
		cs_set_user_money(id, amount)
#else
	zp_set_user_ammo_packs(id, amount)
#endif
}
stock zv_currency_get(id) {
#if MODIFICATION == NEW
	if (is_module_ammopacks_loaded)
		return zp_ammopacks_get(id)
	else
		return cs_get_user_money(id)
	
	return 0;
#else
	return zp_get_user_ammo_packs(id)
#endif
}
#if VIPS_FILE_SYSTEM != OFF
load_ini_file() {

	new vipsfile[70]
	get_configsdir(vipsfile, charsmax(vipsfile))
	format(vipsfile, charsmax(vipsfile), "%s/%s", vipsfile, VIPS_FILE)
	new handle = fopen(vipsfile, "rt")
	
	new tempfilename[] = "temp.file";
	new temph = fopen(tempfilename, "wt")
	
	if(handle) {
		
		new vip_data[vips_database_type]

		new str_auth[50], data1[30], data2[30]
		new /*ret, */bool:comma_open, bool:line_removed = false
		new line[200], line_num, line_len;
		new i=0, s=0
		new datatype = 0
		new timestamp = get_systime()
		//new AuthType:authtype

		while(!feof(handle)) {

			comma_open = false
			line_len = fgets(handle, line, charsmax(line))
			line_num++
			
			i = 0
			datatype = 0
				
			if (line[i] == ';'
			|| line[i] == '/'
			|| line[i] == 'X'
			|| line[i] == EOS) {
				fputs(temph, line)
				continue;
			}
			
			vip_data[AUTH][0] = EOS
			vip_data[PASS][0] = EOS
			vip_data[SETTINGS] = 0
			vip_data[FLAGS] = 0
			vip_data[TIMESTAMP] = 0
			
			for(;;) {
				switch (line[i]) {
				case 'C': vip_data[SETTINGS] |= FLAG_C
				case 'N': vip_data[SETTINGS] |= FLAG_N
				case 'F': vip_data[SETTINGS] |= FLAG_F
				case 'K': vip_data[SETTINGS] |= FLAG_K
				default: goto loop_exit;
				}
				i++
			}
			
			loop_exit:
			
			for (;;) {
				
				if (i > charsmax(line)) {
					log_amx("ERROR: ^"%s^" Syntax error on line (%d:%d):^n^"%s^".^nLine too long.", VIPS_FILE, line_num, i+1, line)
					fputs(temph, line)
					goto global_continue;
				}
				if (line[i] == '"') {
					
					comma_open = !comma_open
					i++
					
					if (comma_open) datatype++
					else {
						switch (datatype) {
							
							case 1: str_auth[s] = EOS
							case 2: data1[s] = EOS
							case 3: data2[s] = EOS
							default: {
								log_amx("ERROR: ^"%s^" Syntax error on line (%d:%d):^n^"%s^". Too many parameters.", VIPS_FILE, line_num, i+1, line)
								fputs(temph, line)
								goto global_continue;
							}
						}
					}
					s = 0
					continue;
				}
				
				if (comma_open) {
					
					switch (datatype) {
						
						case 1: str_auth[s++] = line[i]
						case 2: data1[s++] = line[i]
						case 3: data2[s++] = line[i]
					}
				}
				else if (line[i] == '|') {
					
					new idx, fidx
					static frmt[] = "|//|:|"
					idx = i
					fidx = 0
					
					while (i < line_len) {
						
						if (frmt[fidx] == line[i]) {
							if (++fidx == charsmax(frmt))
								break;
						}
						else if (line[i] > '9' || line[i] < '0')
							break;
						i++
					}
					
					if (fidx == charsmax(frmt) && i < line_len) {
						vip_data[TIMESTAMP] = parse_time(line[idx], "|%Y/%m/%d|%H:%M|")
						break;
					}
					else {
						log_amx("ERROR: ^"%s^" Syntax error on line (%d:%d):^n^"%s^". Incorrect time.", VIPS_FILE, line_num, i+1, line)
						fputs(temph, line)
						goto global_continue;
					}
				}
				else if (line[i] == '^r' || line[i] == EOS || line[i] == '^n') {
					break;
				}
				else if (line[i] != ' ') {
					log_amx("ERROR: ^"%s^" Syntax error on line (%d:%d):^n^"%s^". Unknown symbol '%c'.", VIPS_FILE, line_num, i+1, line, line[i])
					fputs(temph, line)
					goto global_continue;
				}
				i++
			}
			
			switch (datatype) {
			case 1: {
				vip_data[FLAGS] = -1	
			}
			case 2: {
				vip_data[FLAGS] = read_flags(data1)
			}
			case 3: {
				copy(vip_data[PASS], charsmax(vip_data[PASS]), data1) 
				vip_data[FLAGS] = read_flags(data2)
			}
			}
			
			copy(vip_data[AUTH], charsmax(vip_data[AUTH]), str_auth)
			
			if (!(vip_data[SETTINGS] & (FLAG_C|FLAG_N|FLAG_F)))
				strtoupper(vip_data[AUTH])
				
			vip_data[SETTINGS] |= LOAD_FROM_INI
			VIPINC(INI)
			
			VipsDBInsert(vip_data)
			
			if (vip_data[TIMESTAMP] > 0 && timestamp > vip_data[TIMESTAMP]) {
				line_removed = true
				continue;
			}
			
			fputs(temph, line)
			
			global_continue:
		}
		
		
		fclose(handle)
		fclose(temph)
    
		if(line_removed) {
			
			delete_file(vipsfile)
			while (!rename_file(tempfilename, vipsfile, 1)) { }
		}
		else {
			delete_file(tempfilename)
		}
	}
	else log_amx("ERROR: Missing %s file in configs folder. Can't load zm_vip privileges.", VIPS_FILE)
}
remove_from_ini(data[vips_database_type]) {
	
	if (!VIPCNT(INI))
		return;
	
	new vipsfile[70]
	get_configsdir(vipsfile, charsmax(vipsfile))
	format(vipsfile, charsmax(vipsfile), "%s/%s", vipsfile, VIPS_FILE)
	new handle = fopen(vipsfile, "r+")
	
	if (handle) {
	
		new i, line[200], line_len, start

		while(!feof(handle)) {
			
			line_len = fgets(handle, line, charsmax(line))
			i = 0
			
			if (line[i] == ';'
			|| line[i] == '/'
			|| line[i] == 'X'
			|| line[i] == EOS) {
				continue;
			}
			
			start = 0
			while (start < line_len) {
				
				if (line[start++] == '"')
					break;
			}
			
			if (start >= line_len) continue;
			
			while (start < line_len) {
				
				if (line[start] == '"') {
					line[start] = EOS
					break;
				}
				start++
			}
			
			if (start >= line_len) continue;
			
			strtoupper(line[start])
			if (equal(line[start], data[AUTH])) {
				fseek(handle, -line_len, SEEK_CUR)
				fputc(handle, 'X')
				VIPDEC(INI)
				break;
			}
		}
		fclose(handle)
	}
	else
		log_amx("ERROR: Failed to read '%s' file.", vipsfile)
}
add_to_ini(data[vips_database_type]) {

	new vipsfile[70]
	get_configsdir(vipsfile, charsmax(vipsfile))
	format(vipsfile, charsmax(vipsfile), "%s/%s", vipsfile, VIPS_FILE)
	new handle = fopen(vipsfile, "at")
	
	if (handle) {
		new line[120], len
		len += formatex(line, charsmax(line), 
		"%s%s%s%s ^"%s^"",
		data[SETTINGS]&FLAG_C?"C":"",
		data[SETTINGS]&FLAG_N?"N":"",
		data[SETTINGS]&FLAG_F?"F":"",
		data[SETTINGS]&FLAG_K?"K":"",
		data[AUTH])
		
		if (!EMPTY(data[PASS]))
			len += formatex(line[len], charsmax(line)-len, " ^"%s^"", data[PASS])
		
		if (data[FLAGS] != -1) {
			new flags_str[30]
			get_flags(data[FLAGS], flags_str, charsmax(flags_str))
			len += formatex(line[len], charsmax(line)-len, " ^"%s^"", flags_str)
		}
		
		if (data[TIMESTAMP])
			len += format_time(line[len], charsmax(line)-len, " |%Y/%m/%d|%H:%M|", data[TIMESTAMP])
		
		VIPINC(INI)
		fputs(handle, line)
		fclose(handle)
	}
}
#endif
convert_duration_to_string(id, duration, string[], len) {
	
	if (duration == ZV_DURATION_TILL_MAP) {
		LookupLangKey(string, len, "TILL_MAPCHANGE", id)
		return;
	}
	else if (duration == ZV_DURATION_TILL_DISCONNECT) {
		LookupLangKey(string, len, "TILL_DISCONNECT", id)
		return;	
	}
	
	new index, time_unit[20] = {' '}, unit
	new week_word[][] = {"WEEK", "WEEKS", "WEEKSW"}
	new day_word[][] = {"DAY", "DAYS", "DAYSW"}
	new hour_word[][] = {"HOUR", "HOURS", "HOURSW"}
	new minute_word[][] = {"MINUTE", "MINUTES", "MINUTESW"}
	new second_word[][] = {"SECOND", "SECONDS", "SECONDSW"}
	
	if (duration >= 604800) {
		unit = duration/604800
		
		index += num_to_str(unit, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit), 
		week_word[(unit%10==1)?0:((unit%10==0||10<unit%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
		duration %= 604800
	}
	if (duration >= 86400) {
		if (index) { string[index] = ' '; string[++index] = EOS; }
		unit = duration/86400
		index += num_to_str(unit, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit),
		day_word[(unit%10==1)?0:((unit%10==0||10<unit%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
		duration %= 86400
	}
	if (duration >= 3600) {
		if (index) { string[index] = ' '; string[++index] = EOS; }
		unit = duration/3600
		index += num_to_str(unit, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit),
		hour_word[(unit%10==1)?0:((unit%10==0||10<unit%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
		duration %= 3600
	}
	if (duration >= 60) {
		if (index) { string[index] = ' '; string[++index] = EOS; }
		unit = duration/60
		index += num_to_str(unit, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit),
		minute_word[(unit%10==1)?0:((unit%10==0||10<unit%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
		duration %= 60
	}
	if (duration) {
		if (index) { string[index] = ' '; string[++index] = EOS; }
		index += num_to_str(duration, string[index], len-index)
		LookupLangKey(time_unit[1], charsmax(time_unit),
		second_word[(duration%10==1)?0:((duration%10==0||10<duration%100<20)?2:1)], id)
		index += add(string[index], len-index, time_unit)
	}
}

get_cvar_duration(cvar) {
	
	new dur[20], duration
	get_pcvar_string(cvar, dur, charsmax(dur))
	
	new len = strlen(dur)
	
	if (len) {
		
		switch (dur[len-1]) {

		case 'w': {
			dur[len-1] = EOS
			duration = str_to_num(dur)
			if (duration) {
				duration *= 7*24*3600
			}
		}
		case 'd': {
			dur[len-1] = EOS
			duration = str_to_num(dur)
			if (duration) {
				duration *= 24*3600
			}
		}
		case 'h': {
			dur[len-1] = EOS
			duration = str_to_num(dur)
			if (duration) {
				duration *= 3600
			}
		}
		case 's': {
			dur[len-1] = EOS
			duration = str_to_num(dur)
		}
		case 'm': {
			if (len-2 >= 0 && dur[len-2] == 't') {
				goto case_t
			}
			dur[len-1] = EOS
			duration = str_to_num(dur)
			if (duration) {
				duration *= 60
			}
		}
		case 't': {
			case_t:
			
			duration = ZV_DURATION_TILL_DISCONNECT
			if (dur[len-1] == 'm') {
				duration = ZV_DURATION_TILL_MAP
			}
		}
		default: {

			duration = str_to_num(dur)
			if (duration > 0) {
				duration *= 24*3600
			}
			else {
				log_amx("WARNING: Incorrect zm_vip_buy_duration cvar value ^"%s^".", dur)
				return -1;
			}
		}
		}
	}
	
	return duration
}
add_to_datafile(data[vips_database_type]) {
	
	new datafile[70]
	get_datadir(datafile, charsmax(datafile))
	add(datafile, charsmax(datafile), "/zm_vip.dat")
	
	new handle = fopen(datafile, "ab")
	
	if (handle) {
		
		fwrite_blocks(handle, data, 70, BLOCK_CHAR)
		fwrite_raw(handle, data[SETTINGS], 4, 3)
		fclose(handle)
		VIPINC(DAT)
	}
	else
		log_amx("ERROR: Failed to write '%s' file.", datafile)
}

remove_from_datafile(data[vips_database_type]) {
	
	if (!(data[SETTINGS] & LOAD_FROM_DAT))
		return;
	
	new datafile[70], bytes_in_file
	get_datadir(datafile, charsmax(datafile))
	add(datafile, charsmax(datafile), "/zm_vip.dat")
	
	bytes_in_file = file_size(datafile)
	
	new handle = fopen(datafile, "r+")
	
	if (handle) {
		
		new auth[sizeof(data[AUTH])]
		while (ftell(handle) < bytes_in_file) {
			
			fread_blocks(handle, auth, sizeof(data[AUTH]), BLOCK_CHAR)
			
			if (equal(auth, data[AUTH])) {
				fseek(handle, -sizeof(data[AUTH]), SEEK_CUR)
				fputc(handle, 0)
				VIPDEC(DAT)
				
				fseek(handle, sizeof(data[AUTH])+sizeof(data[PASS])+12-1, SEEK_CUR)
			}
			else {
				fseek(handle, sizeof(data[PASS])+12, SEEK_CUR)
			}
		}
		fclose(handle)
	}
	else
		log_amx("ERROR: Failed to read '%s' file.", datafile)
}
load_datafile() {
	
	new datafile[70]
	get_datadir(datafile, charsmax(datafile))
	add(datafile, charsmax(datafile), "/zm_vip.dat")
	
	if (!file_exists(datafile))
		return;
		
	new handle = fopen(datafile, "rb")
	
	if (handle) {
		
		new data[vips_database_type]
		while (!feof(handle)) {
			
			fread_blocks(handle, data, 70, BLOCK_CHAR)
			fread_raw(handle, data[SETTINGS], 4, 3)
			
			if (EMPTY(data[AUTH])) {
				dummy_record_count++
				continue;
			}
			data[SETTINGS] &= ~LOAD_MASK
			data[SETTINGS] |= LOAD_FROM_DAT
			VIPINC(DAT)
			
			VipsDBInsert(data)
		}
		fclose(handle)
	}
	else
		log_amx("ERROR: Failed to read '%s' file.", datafile)
}

write_datafile() {
	
	new datafile[70]
	get_datadir(datafile, charsmax(datafile))
	add(datafile, charsmax(datafile), "/zm_vip.dat")
	
	if (!VIPCNT(DAT) && file_exists(datafile)) {
		delete_file(datafile)
		return;
	}
	
	new handle = fopen(datafile, "wb")
	
	if (handle) {
		
		new key[40], i, size = ArraySize(array_vips_database)
		new data[vips_database_type]
		new timestamp = get_systime()
		
		for (i=0; i<size; i++) {
			
			ArrayGetString(array_vips_database, i, key, sizeof(key))
			
			if (EMPTY(key))
				continue;
			
			if (!TrieGetArray(trie_vips_database, key, data, vips_database_type))
				continue;
			
			if (!(data[SETTINGS] & LOAD_FROM_DAT))
				continue;
				
			if (data[TIMESTAMP] == ZV_DURATION_TILL_MAP)
				continue;
				
			if (data[TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT) {
				
				if (data[PASS][charsmax(data[PASS])]+1 
				< floatround(get_gametime()*100, floatround_floor))
					continue;
				else
					data[PASS][charsmax(data[PASS])] = EOS
			}
			
			if (data[TIMESTAMP] <= timestamp)
				continue
			
			fwrite_blocks(handle, data, 70, BLOCK_CHAR)
			fwrite_raw(handle, data[SETTINGS], 4, 3)
		}
		
		if (array_vips_database_nick) {
			size = ArraySize(array_vips_database_nick)
			for (i=0; i<size; i++) {
				
				ArrayGetArray(array_vips_database_nick, i, data)
				
				if (EMPTY(data[AUTH]))
					continue;
					
				if (data[TIMESTAMP] == ZV_DURATION_TILL_MAP)
					continue;
					
				if (data[TIMESTAMP] == ZV_DURATION_TILL_DISCONNECT) {
					
					if (data[PASS][charsmax(data[PASS])]+1 
					< floatround(get_gametime()*100, floatround_floor))
						continue;
					else
						data[PASS][charsmax(data[PASS])] = EOS
				}
				
				if (data[TIMESTAMP] <= timestamp)
					continue
				
				data[SETTINGS] &= ~LOAD_MASK
				fwrite_blocks(handle, data, 70, BLOCK_CHAR)
				fwrite_raw(handle, data[SETTINGS], 4, 3)
			}
		}
		
		fclose(handle)
	}
	else
		log_amx("ERROR: Failed to write '%s' file.", datafile)
}

print_admin_contacts(id) {

	new contact[60]
	get_cvar_string("amx_contactinfo", contact, charsmax(contact))
	if(!EMPTY(contact))  {
		if (is_amxmodx_new_version) client_print_color(id, id, "^4%L: ^1%s.", id, "ADMIN_CONTACTS", contact)
		else _client_print_color(id, "^4%L: ^1%s.", id, "ADMIN_CONTACTS", contact)
	}
}

public show_vip_timeleft(id) {
	
	new timeleft[100]
	if (!p_data[id][TIMESTAMP])
		LookupLangKey(timeleft, charsmax(timeleft), "PERMANENT", id)
	else
		convert_duration_to_string(id, max(p_data[id][TIMESTAMP]-get_systime(), 0), timeleft, charsmax(timeleft))
	
	if (is_amxmodx_new_version) {
		set_dhudmessage(51, 118, 4, 0.02, 0.52, 0, 6.0, 0.9, 0.1, 0.3)
		show_dhudmessage(id, "VIP: %s", timeleft)
	}
	else {
		_set_dhudmessage(51, 118, 4, 0.02, 0.52, 0, 6.0, 0.9, 0.1, 0.3)	
		_show_dhudmessage(id, "VIP: %s", timeleft)
	}
}
stock timestamp_to_date(stamp, date_str[], dchars, time_str[], tchars) {
			
	new y=1970, m=1, d=1, cstamp = stamp
	new hours, mins
	
	while(cstamp >= 31536000) {
	
		cstamp -= (!(y%400)||((y%100)&&!(y%4)))?31622400:31536000
		y++;
	}
	
	while(cstamp >=	2419200) {
		
		switch(m) {
			case 2, 4, 6, 9: cstamp -= (!(y%400)||((y%100)&&!(y%4)))?2505600:2419200
			case 11:  cstamp -= 2592000
			case 1, 3, 5, 7, 8, 10, 12: cstamp -= 2678400
		}
		m++
	}

	while(cstamp >= 86400) {
	
		cstamp -= 86400
		d++
	}
	
	hours = cstamp/3600
	mins = (cstamp%3600)/60
	
	formatex(date_str, dchars, "%d/%d/%d%", y, m, d)
	formatex(time_str, tchars, "%d:%d", hours, mins)
}
/*stock date_to_timestamp(date_str[], time_str[]) {
		
	new y, m, d, i
	new hours, mins
	new temp_str[15], num[6]
	strtok(date_str, num, charsmax(num), temp_str, charsmax(temp_str), '/')
	y = str_to_num(num)
	strtok(temp_str, num, charsmax(num), temp_str, charsmax(temp_str), '/')
	m = str_to_num(num)
	d = str_to_num(temp_str)
	strtok(time_str, num, charsmax(num), temp_str, charsmax(temp_str), ':')
	hours = str_to_num(num)
	mins = str_to_num(temp_str)
	
	new stamp
	
	for (i=1970; y > i; i++)
		stamp += (!(i%400)||((i%100)&&!(i%4)))?31622400:31536000

	for (i=1; m > i; i++) {
		
		switch(i) {
			case 2, 4, 6, 9: stamp += (!(y%400)||((y%100)&&!(y%4)))?2505600:2419200
			case 11:  stamp += 2592000
			case 1, 3, 5, 7, 8, 10, 12: stamp += 2678400
		}
	}
	stamp += d*86400
	stamp += hours*3600
	stamp += mins*60
	return stamp;
}*/

stock findtag(msg[], tag[]) {
	
	static i, d
	i = 0
	while (msg[i] != EOS) {
		if (msg[i] == tag[0]) {
			
			d = 0
			while (tag[d]!=EOS&&msg[i+d]!=EOS) {
				if (tag[d]!=msg[i+d] && ((65<=tag[d]<=90) && (tag[d]+32)!=msg[i+d]))
					break;
				d++
			}
			if (tag[d] == EOS) {
				return i;
			}
		}
		i++
	}
	return -1;
}
stock read_config(cvar[], value[], len) {
	
	new directory[40]
	get_configsdir(directory, charsmax(directory))
	format(directory, charsmax(directory), "%s/%s", directory, CONFIGS_FILE)
	value[0] = EOS
	
	new handle = fopen(directory, "rt")
	if (handle) {
		
		new line[100], place
		while (!feof(handle)) {
			fgets(handle, line, charsmax(line))
			
			if ((place = contain(line, cvar)) != -1) {
				
				while (line[place] != '"' && line[place] != EOS) { place++; }
				
				if (line[place] == '"') {
					
					place++
					new index
					while (line[place] != '"' && line[place] != EOS && index < len) {
						
						value[index++] = line[place++] 
					}
					value[index] = EOS
					break;
				}
			}
		}
		fclose(handle)
	}
}
#if AMXX_VERSION_NUM < 183
native client_print_color(index, sender, const message[], any:...);
#endif
stock _client_print_color(id, const message[], any:...)
{	
	static buffer[512], argscount
	argscount = numargs()
	
	if (!id) {
		
		static players[32], num, player, i, i2
		get_players(players, num , "ch")
			
		for (i = 0; i < num; i++) {
			
			player = players[i]
			
			static changed[5], changedcount
			changedcount = 0
			
			for (i2 = 2; i2 < argscount; i2++)
			{
				if (getarg(i2) == LANG_PLAYER)
				{
					setarg(i2, 0, player)
					changed[changedcount] = i2
					changedcount++
				}
			}
			
			vformat(buffer, charsmax(buffer), message, 3)
					
			message_begin(MSG_ONE_UNRELIABLE, msg_saytext, _, player)
			write_byte(player)
			write_string(buffer)
			message_end()
			
			for (i2 = 0; i2 < changedcount; i2++)
				setarg(changed[i2], 0, LANG_PLAYER)
		}
	}
	else {
		
		vformat(buffer, charsmax(buffer), message, 3)
				
		message_begin(MSG_ONE_UNRELIABLE, msg_saytext, _, id)
		write_byte(id)
		write_string(buffer)
		message_end()
	}
}

stock __dhud_color;
stock __dhud_x;
stock __dhud_y;
stock __dhud_effect;
stock __dhud_fxtime;
stock __dhud_holdtime;
stock __dhud_fadeintime;
stock __dhud_fadeouttime;
stock __dhud_reliable;

#if AMXX_VERSION_NUM < 183
native set_dhudmessage(red=200, green=100, blue=0, Float:x=-1.0, Float:y=0.35, effects=0, Float:fxtime=6.0, Float:holdtime=12.0, Float:fadeintime=0.1, Float:fadeouttime=0.2);
#endif
stock _set_dhudmessage( red = 0, green = 160, blue = 0, Float:x = -1.0, Float:y = 0.65, effects = 2, Float:fxtime = 6.0, Float:holdtime = 3.0, Float:fadeintime = 0.1, Float:fadeouttime = 1.5, bool:reliable = false )
{
	#define clamp_byte(%1)       ( clamp( %1, 0, 255 ) )
	#define pack_color(%1,%2,%3) ( %3 + ( %2 << 8 ) + ( %1 << 16 ) )

	__dhud_color       = pack_color( clamp_byte( red ), clamp_byte( green ), clamp_byte( blue ) );
	__dhud_x           = _:x;
	__dhud_y           = _:y;
	__dhud_effect      = effects;
	__dhud_fxtime      = _:fxtime;
	__dhud_holdtime    = _:holdtime;
	__dhud_fadeintime  = _:fadeintime;
	__dhud_fadeouttime = _:fadeouttime;
	__dhud_reliable    = _:reliable;

	return 1;
}
#if AMXX_VERSION_NUM < 183
native show_dhudmessage(index, const message[], any:...);
#endif
stock _show_dhudmessage(index, const message[], any:... )
{	
	new buffer[ 128 ];
	new numArguments = numargs();

	if( numArguments == 2 )
	{
		send_dhudMessage( index, message );
	}
	else if( index || numArguments == 3 )
	{
		vformat( buffer, charsmax( buffer ), message, 3 );
		send_dhudMessage( index, buffer );
	}
	else
	{
		new playersList[ 32 ], numPlayers;
		get_players( playersList, numPlayers, "ch" );

		if( !numPlayers )
		{
			return 0;
		}

		new Array:handleArrayML = ArrayCreate();

		for( new i = 2, j; i < numArguments; i++ )
		{
			if( getarg( i ) == LANG_PLAYER )
			{
				while( ( buffer[ j ] = getarg( i + 1, j++ ) ) ) {}
				j = 0;

				if( GetLangTransKey( buffer ) != TransKey_Bad )
				{
					ArrayPushCell( handleArrayML, i++ );
				}
			}
		}

		new size = ArraySize( handleArrayML );

		if( !size )
		{
			vformat( buffer, charsmax( buffer ), message, 3 );
			send_dhudMessage( index, buffer );
		}
		else
		{
			for( new i = 0, j; i < numPlayers; i++ )
			{
				index = playersList[ i ];

				for( j = 0; j < size; j++ )
				{
					setarg( ArrayGetCell( handleArrayML, j ), 0, index );
				}

				vformat( buffer, charsmax( buffer ), message, 3 );
				send_dhudMessage( index, buffer );
			}
		}

		ArrayDestroy( handleArrayML );
	}

	return 1;
}
stock send_dhudMessage( const index, const message[] )
{
	message_begin( __dhud_reliable ? ( index ? MSG_ONE : MSG_ALL ) : ( index ? MSG_ONE_UNRELIABLE : MSG_BROADCAST ), SVC_DIRECTOR, _, index );
	{
		write_byte( strlen( message ) + 31 );
		write_byte( DRC_CMD_MESSAGE );
		write_byte( __dhud_effect );
		write_long( __dhud_color );
		write_long( __dhud_x );
		write_long( __dhud_y );
		write_long( __dhud_fadeintime );
		write_long( __dhud_fadeouttime );
		write_long( __dhud_holdtime );
		write_long( __dhud_fxtime );
		write_string( message );
	}
	message_end();
}

VipsItemIs(ClassType:type, itemid) {
	
	static strnum[6]
	num_to_str(itemid, strnum[1], charsmax(strnum)-1)
	strnum[0] = _:type
	
	return TrieKeyExists(trie_vip_items, strnum)
}
VipsItemSet(ClassType:type, itemid) {
	
	if (!trie_vip_items)
		trie_vip_items = TrieCreate()
		
	new strnum[6]
	num_to_str(itemid, strnum[1], charsmax(strnum)-1)
	strnum[0] = _:type
	
	return TrieSetCell(trie_vip_items, strnum, 1)
}

stock VipsDBGet(const id) {
	
	if (!(1 <= id < 33))
		return false;
		
	p_data[id][FLAGS] = 0
	p_data[id][SETTINGS] = 0
	
	if (!VIPCNT(DAT) && !VIPCNT(INI) && !VIPCNT(AMX))
		return false;
	
	static authid[30], ip[30], name[45]
	get_user_info(id, "name", name, charsmax(name))
	get_user_authid(id, authid, charsmax(authid))
	get_user_ip(id, ip, charsmax(ip), 1)
	
	static uppername[45], client_password[30]
	
	copy(uppername, charsmax(uppername), name)
	strtoupper(uppername)
	get_user_info(id, amx_password_field_string, client_password, charsmax(client_password))
	
	if (VIPCNT(MAIN) && TrieGetArray(trie_vips_database, authid, p_data[id], vips_database_type)) 
	{ p_data[id][SETTINGS] |= LOAD_FROM_MAIN; }
	else if(VIPCNT(MAIN) && TrieGetArray(trie_vips_database, ip, p_data[id], vips_database_type)) 
	{ p_data[id][SETTINGS] |= LOAD_FROM_MAIN; }
	else if(VIPCNT(MAIN) && TrieGetArray(trie_vips_database, uppername, p_data[id], vips_database_type)) 
	{ p_data[id][SETTINGS] |= LOAD_FROM_MAIN; }
	else if (VIPCNT(NAMES) && check_named_privileges(id, name, client_password) > 0) 
	{ p_data[id][SETTINGS] |= LOAD_FROM_NAMES; }
	
	if (!EMPTY(p_data[id][PASS]) && p_data[id][SETTINGS] & FLAG_K && !equal(p_data[id][PASS], client_password)) {
		p_data[id][SETTINGS] = 0
		p_data[id][FLAGS] = 0
		server_cmd("kick #%d ^"[ZMVIP] %L.^"", get_user_userid(id), id, "INVALID_PASS")
		return false;
	}
		
#if VIPS_FILE_SYSTEM != FORCED
	if(get_user_flags(id) & VIP_SYS_FLAG) {
		
		new flags = _get_pcvar_flags(cvar_amx_auth_flags)
		if (flags == 0)
			p_data[id][FLAGS] = -1
		else
			p_data[id][FLAGS] |= flags
		p_data[id][TIMESTAMP] = 0
		p_data[id][SETTINGS] |= LOAD_FROM_AMX
	}
#endif
	if (p_data[id][FLAGS]) {
		new flags = _get_pcvar_flags(cvar_amxmodx_flags)
		if (flags > 0)
		set_user_flags(id, flags)
	}
	
	if (!p_data[id][FLAGS]) {
		p_data[id][SETTINGS] = 0
		p_data[id][TIMESTAMP] = 0
		arrayset(p_attribs[id], 0, player_attributes)
		return false;
	}
	
	console_print(id, "* VIP Privileges set")
	return true;
}
	

stock VipsDBSet(const id) {
	
	if (!(1 <= id < 33))
		return false;
	
	if (p_data[id][SETTINGS]&LOAD_MASK) {
		
		if (p_data[id][SETTINGS]&(LOAD_FROM_MAIN)) {
			TrieSetArray(trie_vips_database, p_data[id][AUTH], p_data[id], vips_database_type)
		}
		else if (p_data[id][SETTINGS]&LOAD_FROM_NAMES) {
			ArraySetArray(array_vips_database_nick, p_data[id][INDEX], p_data[id])
		}
#if VIPS_FILE_SYSTEM != FORCED
		else if (p_data[id][SETTINGS]&LOAD_FROM_AMX) {
			
			p_data[id][SETTINGS] = 0
			VipsDBSet(id)
		}
#endif
#if VIPS_FILE_SYSTEM != OFF
		if (p_data[id][SETTINGS]&LOAD_FROM_INI) {
			remove_from_ini(p_data[id])
			add_to_ini(p_data[id])
		}
		else if (p_data[id][SETTINGS]&LOAD_FROM_DAT) {
			remove_from_datafile(p_data[id])
			add_to_datafile(p_data[id])
		}
#else
		remove_from_datafile(p_data[id])
		add_to_datafile(p_data[id])	
#endif
		return true;
	}
	
	get_user_authid(id, p_data[id][AUTH], charsmax(p_data[][AUTH]))
	if (p_data[id][AUTH][7] != ':')
		get_user_ip(id, p_data[id][AUTH], charsmax(p_data[][AUTH]), 1)
	
	p_data[id][PASS] = EOS
#if VIPS_FILE_SYSTEM != OFF
	if (get_pcvar_num(cvar_vip_store_ini)&&(p_data[id][TIMESTAMP]!=ZV_DURATION_TILL_MAP)){
		
		p_data[id][SETTINGS] = LOAD_FROM_INI
	}
	else {
		p_data[id][SETTINGS] = LOAD_FROM_DAT
	}
#else
	p_data[id][SETTINGS] = LOAD_FROM_DAT
#endif
	if (p_data[id][SETTINGS] & LOAD_FROM_DAT)
		add_to_datafile(p_data[id])
#if VIPS_FILE_SYSTEM != OFF
	if (p_data[id][SETTINGS] & LOAD_FROM_INI)
		add_to_ini(p_data[id])
#endif	
	return VipsDBInsert(p_data[id]);
}
stock VipsDBInsert(data[vips_database_type]) {
	
	if (data[SETTINGS] & ~(LOAD_MASK|FLAG_K)) {
		
		if(!array_vips_database_nick)
			array_vips_database_nick = ArrayCreate(vips_database_type, 10)
			
		data[SETTINGS] |= LOAD_FROM_NAMES
		data[INDEX] = ArraySize(array_vips_database_nick)
		ArrayPushArray(array_vips_database_nick, data)
		VIPINC(NAMES)
		
		return true;
	}
	
	data[INDEX] = ArraySize(array_vips_database)
	ArrayPushString(array_vips_database, data[AUTH])
	TrieSetArray(trie_vips_database, data[AUTH], data, vips_database_type)
	VIPINC(MAIN)
	
	return true;
}

stock VipsDBRemove(const id) {
	
	if (!(1 <= id < 33))
		return false;
	
	if (p_data[id][SETTINGS]&LOAD_MASK) {
		
		p_data[id][FLAGS] = 0
		p_data[id][TIMESTAMP] = 0
		if (p_data[id][SETTINGS]&(LOAD_FROM_MAIN)) {
			
			TrieDeleteKey(trie_vips_database, p_data[id][AUTH])
			ArraySetString(array_vips_database, p_data[id][INDEX], "")
			VIPDEC(MAIN)
			
			if (p_data[id][SETTINGS]&LOAD_FROM_MAIN)
				remove_from_datafile(p_data[id])
#if VIPS_FILE_SYSTEM != OFF
			if (p_data[id][SETTINGS]&LOAD_FROM_INI)
				remove_from_ini(p_data[id])
#endif
		}
		else if (p_data[id][SETTINGS]&LOAD_FROM_NAMES) {
			
			p_data[id][AUTH][0] = EOS
			ArraySetArray(array_vips_database_nick, p_data[id][INDEX], p_data[id])
			VIPDEC(NAMES)
		}
#if VIPS_FILE_SYSTEM != FORCED
		else if (p_data[id][SETTINGS]&LOAD_FROM_AMX) {
			
			remove_user_flags(id, VIP_SYS_FLAG)
			// VIPCNT(AMX) not decremented, because we don't delete from amxmodx dynamic
			// admin list. There is no efficient way to do this. Only by flushing all admins
		}
#endif
		new flags = _get_pcvar_flags(cvar_amxmodx_flags)
		if (flags > 0)
			remove_user_flags(id, flags)
		
		p_data[id][SETTINGS] = 0
		return true;
	}
	
	return false;
}
"Бъди промяната, която искаш да видиш в света." ~ Махатма Ганди

  • Подобни теми
    Отговори
    Преглеждания
     Последно мнение

Обратно към “Поддръжка / Помощ”

Кой е на линия

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