modificare WRBOT

Modificari necesare ale pluginurilor

Moderators: Moderatori ajutatori, Moderatori, Echipa eXtreamCS.com

Post Reply
Coco21
Membru nou
Membru nou
Posts: 2
Joined: 12 Apr 2020, 01:27
Detinator Steam: Nu
CS Status: Citesc forumul eXtreamCS.com...!
Fond eXtream: 0

31 Jan 2021, 15:48

SALUT DUPA CUM SPUNE SI TITLUL VREAU S-A MA AJUTATI CU MODIFICAREA PLUGINULUI WRBOT ACEASTA MODIFICARE CONSTA IN CREAEARE UNUI DEMO AL PLAYERULUI CU CEL
MAI BUN TIMP DUPA server !

PLUGIN:
| Afiseaza codul
/*
v0.1 = Старт плагина
v0.2 = Скачивание WR файла через сокеты
v0.3 = После длительных попыток, скачивать файлы с сервера плохая затея, сокет слишком ограничен,
движок не дает скачивать быстрее, если ускорять скачивание, это приводит к краш сервера.
v0.4 = Проба с SQL версией. (Прошла успешно)
v0.5 = KZ Timer || Не прожимает старт в начале
v0.6 = Решил отказатся от Таймера, т.к. время будет не точным.
v0.7 = Проценты вместо таймера
v0.8 = Новое скачивание, include http2
v0.9 = Исправление зависания, если бота кикнуть.
v1.01 = Нормальный таймер
v1.02 = Скорость бота была сделана вычислением текущего FPS сервера
v1.03 = От начало демки, срезается часть фреймов, чтобы моделька начинала проигрывание не из текстур.
v1.04 = Добавлены конфиги
v1.05 = Исправлены неслышаемые шаги
v1.06 = Проверки на наличие спрайтов в папке и возможный precache
v1.07 = Исправлена функция получения времени, сложность в том, что при конвертации из строки в дробное число, появляется погрешность 0.19999
v1.08 = Убрано скачивание через http файл local.ini, вместо этого, реализовано функция добавление файла mysql.
v1.09 = Проверка лицензии
v1.10 = Контроль версии
v1.11 = Бот не реагирует на bhop blocki
v1.12 = Функция получения внешнего IP для проверки лицензии.
v1.13 = Country flag получает по потоковой передаче.'
v1.14 = Оптимизация кода + добавлен код вейза.
v1.15 = Переписан весь код. Добавлен разархиватор ввиде модуля созданный garey, скачивания архива напрямую с сайтов. И парсинг данных непосредственно из демки.
v1.16 = Потоковое получение лицензии, чтоб при старте сервера не было лага.
v1.17 = От первого лица, флаг не видно.
v1.18 = Игнорирование бхоп блоков + кнопка старта и финиша. + объединение в MySQL и nVault в один файл. // Оптимизация.
v1.19 = Фикс на дерганье бота на некоторых картах. Бот игнорирует весь урон, кроме урон от падения.
v1.20 = Проверка параметра sv_lan в случае с параметром 1, выводит сообщение ошибки. Исправление смерти бота.
v1.21 = Добавлена верификация по стиму для тех кто купил паблик бота для лан сервера, переделана запись в файл country даты. Сделан частичный рефакторинг кода.
v1.22 = Оптимизация Mysql. Новая БД, скорость чтение увеличено.
*/
#define nVault
//#define SQL
#define PUB
//#define LAN

#pragma tabsize 0
#include <amxmodx>
#include <amxmisc>
#include <engine>
#include <cstrike>
#include <fakemeta>
#include <hamsandwich>
#include <sockets>
#include <sqlx_bot>
#include <colorchat>

#if defined nVault
	#include <AmxxArch>
	#include <curl>
#endif

#define PLUGIN "KZ[L]WRBOT"
#define VERSION "1.22"
#define AUTHOR "MichaelKheel"
#define SOCKET_SITE "test.kreedz.ru"
#define SOCKET_GET "/index.php"

//#define DEV_DEBUG

new Handle:g_SqlTuple
new Handle:SqlConnection
new g_Error[512]
new g_szMapName[32];
// Массивы для хранения данных
new Array:fPlayerAngle, Array:fPlayerKeys, Array:fPlayerVelo, Array:fPlayerOrigin;
// Для обратного отсчета
new g_timer;
// Timer
new Float:timer_time[33], bool:timer_started[33], bool:IsPaused[33], Float:g_pausetime[33], bool:bot_finish_use[33];
// переменные управления
new g_bot_start, g_bot_enable, g_bot_frame, wr_bot_id;
// Убирает наложение Hud
new SyncHudTimer, SyncHudBotTimer
// Массив для кнопок [0] - start / [1] - finish
new Trie:g_tButtons[2];
// Country Flag
#define CountryData "addons/amxmodx/data/local.ini"
new Local_ini, g_Bot_Icon_ent, url_sprite[64], url_sprite_xz[64];
// Полученные данные из базы
new WR_TIME[130], WR_NAME[130]
// Определенние nextthink
new Float:nExttHink = 0.009
// Первое вхождение на сервер (LAN или PUB verification STEAM)
new bool:firstspawn[33];
// Проверка сервер на sv_lan 1
new bool:b_CvarError = false;
// Верификация пользователя
new gl_verification[17];
// Квары
#if defined PUB
new country_flag;
#endif
new hud_message, timer_bot, timer_option, cooldown_startbot, update_timer, g_xc, g_yc, g_start_frame;
// Игнорирование бхоп блоков для бота
#define SetBhopBlocks(%1,%2)   %1[%2>>5] |=  1<<(%2 & 31)
#define GetBhopBlocks(%1,%2)   %1[%2>>5] &   1<<(%2 & 31)
new g_bBlocks[64]

#if defined DEV_DEBUG
new Float:flStartTime
#endif

#if defined nVault
#define NUM_THREADS 256

#pragma dynamic 32767 // Without this line will crash server!!

#define PEV_PDATA_SAFE    2

#define OFFSET_TEAM            114
#define OFFSET_DEFUSE_PLANT    193
#define HAS_DEFUSE_KIT        (1<<16)
#define OFFSET_INTERNALMODEL    126

new bool:g_Demos = false;

new iXJWRs, iCCWRs, iArchive;
new bool:bFoundDemo = false;
new iDemo_header_size;
new iArchiveName[256];
new iDemoName[256];
new iNavName[256];
new iFile;
new iParsedFile;
#endif

#if defined PUB
new verification, PlayServerIP[17], socketIP[17], bool:g_socket_check = false;
#endif

#if defined LAN
new bool:plugin_activated = false, bool:license = false
#endif

public plugin_precache()
{
	get_mapname(g_szMapName, sizeof(g_szMapName) - 1);
	strtolower(g_szMapName);

	#if defined PUB
		#if defined SQL
			country_flag_add()
		#endif

		#if defined nVault
			parsing_country("xj")
		#endif
	#endif

	new i;
	for(i = 0; i < sizeof(g_tButtons); i++)
		g_tButtons = TrieCreate();

	new szStartTargets[][] = {
	"counter_start", "clockstartbutton", "firsttimerelay", "but_start",
	"counter_start_button", "multi_start", "timer_startbutton", "start_timer_emi", "gogogo"
	};

	for(i = 0; i < sizeof szStartTargets ; i++)
		TrieSetCell(g_tButtons[0], szStartTargets, i);

	new szFinishTargets[][] = {
	"counter_off", "clockstopbutton", "clockstop", "but_stop",
	"counter_stop_button", "multi_stop", "stop_counter", "m_counter_end_emi"
	};

	for (i = 0; i < sizeof szFinishTargets; i++)
		TrieSetCell(g_tButtons[1], szFinishTargets, i);

	new Ent = engfunc( EngFunc_CreateNamedEntity , engfunc( EngFunc_AllocString,"info_target" ) );
	set_pev(Ent, pev_classname, "BotThink");
	set_pev(Ent, pev_nextthink, get_gametime() + 0.01 );
	register_forward( FM_Think, "fwd_Think", 1 );
	fPlayerAngle  = ArrayCreate( 2 );
	fPlayerOrigin = ArrayCreate( 3 );
	fPlayerVelo   = ArrayCreate( 3 );
	fPlayerKeys   = ArrayCreate( 1 );
}

public plugin_init ()
{
	register_plugin( PLUGIN, VERSION, AUTHOR);

	hud_message = register_cvar("hud_message","1");
	timer_bot = register_cvar("timer_bot","1");
	timer_option = register_cvar("timer_option","1");
	cooldown_startbot = register_cvar("cooldown_startbot","5");
	update_timer = register_cvar("update_timer","1");
	g_xc = register_cvar("x_coordinates","-1.0");
	g_yc = register_cvar("y_coordinates","0.35");
	g_start_frame = register_cvar("delete_frame","0");

	#if defined PUB
	country_flag = register_cvar("country_flag","1");
	verification = register_cvar("verification_method", "IP");
	#endif

	#if defined LAN
	RegisterHam(Ham_Spawn, "player", "Ham_PlayerSpawn_P", true);
	register_clcmd("say /playwr", "StartWatchWR");
	register_clcmd("say /stopwr", "Stop");
	#endif
	// Бессмертие бота
	RegisterHam(Ham_TakeDamage, "player", "BotAfterDamage", 0)
	// Регистрация команды для бота
	register_concmd("amx_wrbotmenu", "ClCmd_ReplayMenu");
	//Подключение файла конфига
	new kreedz_cfg[128], ConfigDir[64]
	get_configsdir(ConfigDir, 64)
	formatex(kreedz_cfg,128,"%s/wrbot.cfg", ConfigDir)

	if(file_exists(kreedz_cfg))
	{
		server_cmd("exec %s",kreedz_cfg)
		server_exec()
	}
	else
	{
		server_print("[WR_BOT] Config file is not connected, please check.")
	}

	#if defined PUB
	get_pcvar_string(verification, gl_verification, charsmax( gl_verification ) );
	if(equali(gl_verification, "STEAM")) RegisterHam(Ham_Spawn, "player", "Ham_PlayerSpawn_P", true);
	if(get_pcvar_num(country_flag)) register_forward(FM_AddToFullPack, "addToFullPack", 1)
	#endif

		// Таймер бота
		if(get_pcvar_num(timer_bot) == 1)
		{
			if(get_pcvar_num(update_timer) == 1)
			{
				new iTimer = create_entity("info_target")
				entity_set_float(iTimer, EV_FL_nextthink, get_gametime() + 0.08)
				entity_set_string(iTimer, EV_SZ_classname, "hud_update")
				register_think("hud_update", "timer_task")
			}
			else if(get_pcvar_num(update_timer) == 2)
			{
				set_task(0.1,"timer_task",0,_,_,"b")
			}
			else if(get_pcvar_num(update_timer) == 3)
			{
				new iTimerEnt = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString , "info_target"))
				set_pev(iTimerEnt, pev_classname, "kz_time_think")
				set_pev(iTimerEnt, pev_nextthink, get_gametime() + 1.0)
			}
		}

	// Hud синхронизация
	SyncHudTimer = CreateHudSyncObj()
	SyncHudBotTimer = CreateHudSyncObj()
	// SQL Connect
	g_SqlTuple = SQL_MakeDbTuple(SQL_HOST, SQL_USER, SQL_PASS, SQL_DB);
	plugin_sql()
}

public plugin_sql()
{
	new ErrorCode
	SqlConnection = SQL_Connect(g_SqlTuple,ErrorCode,g_Error,511)

	if(!SqlConnection)
		return pause("a")

	return PLUGIN_CONTINUE
}

public plugin_cfg()
{
	#if defined PUB
		if(equali(gl_verification, "IP"))
		{
			get_user_ip(0, PlayServerIP, 16, 1);
			SQL_Check_license(PlayServerIP);
		}
	#endif

	SetTouch();
}

#if defined PUB
public Ham_PlayerSpawn_P(id)
{
	if(is_user_localhost(id) && is_user_alive(id) && !is_user_bot(id) && firstspawn[id])
	{
		new steamid[32]
		get_user_authid(id, steamid, charsmax(steamid))

		firstspawn[id] = false;
		SQL_Check_license(steamid)
		//set_task(0.5, "plugin_info", id,_,_,"b")
	}
}

public GetTehRealIp( szOutPut[ ], iLen )
{
	new iReturn, iSocket = socket_open( SOCKET_SITE, 80, SOCKET_TCP, iReturn );

	if( iReturn > 0 )
		return 0;

	new sendbuffer[512]
	format(sendbuffer, 511, "GET %s HTTP/1.1^nHost:%s^r^n^r^n", SOCKET_GET, SOCKET_SITE)
	socket_send( iSocket, sendbuffer, 511)
	new szBuffer[ 512 ];
	socket_recv( iSocket, szBuffer, 511 );

	if( !szBuffer[ 0 ] ) {
		socket_close( iSocket );

		return 0;
	}

	iReturn = contain( szBuffer, "IP: " ) + 4;

	if( iReturn > 4 )
		formatex( szOutPut, iLen, szBuffer[ iReturn ] );

	socket_close( iSocket );

	return ( iReturn > 0 );
}
#endif

public SQL_Check_license(value[])
{
	#if defined DEV_DEBUG
	flStartTime = get_gametime();
	#endif

	trim(value);
	new createinto[512]

	#if defined LAN
		formatex(createinto, sizeof createinto - 1, "SELECT * FROM wrbot_user WHERE steamid='%s' AND lan='1'", value)
	#endif

	#if defined PUB
		if(equali(gl_verification, "IP"))
			formatex(createinto, sizeof createinto - 1, "SELECT * FROM wrbot_user WHERE ip_p='%s' AND pub='1'", value)
		else if(equali(gl_verification, "STEAM"))
			formatex(createinto, sizeof createinto - 1, "SELECT * FROM wrbot_user WHERE steamid='%s' AND pub='1'", value)
	#endif

	SQL_ThreadQuery(g_SqlTuple, "SQL_Check_license_Handle", createinto)
}

public SQL_Check_license_Handle(failstate, Handle:hQuery, error[], errcode, cData[], iSize, Float:fQueueTime)
{
	if( failstate == TQUERY_CONNECT_FAILED )
	{
		set_fail_state("Could not connect to database.");
	}
	else if( failstate == TQUERY_QUERY_FAILED )
	{
		set_fail_state("Query failed.");
	}
	else if( errcode )
	{
		log_amx("Error on query: %s", error);
	}
	else
	{
		if (SQL_NumResults(hQuery))
		{
			#if defined LAN
				new servername = SQL_FieldNameToNum(hQuery, "name")
			#else
				new servername = SQL_FieldNameToNum(hQuery, "server_name")
			#endif

			new version = SQL_FieldNameToNum(hQuery, "version")
			new sz_ServerName[128], Float:sz_version;
			new Float:f_ver = str_to_float(VERSION)

			while( SQL_MoreResults(hQuery) )
			{
				SQL_ReadResult(hQuery, servername, sz_ServerName, charsmax(sz_ServerName))
				SQL_ReadResult(hQuery, version, sz_version)
				SQL_NextRow(hQuery)
			}
			server_print("[WR-BOT v%s] Hi %s. Check the license was successful.", VERSION, sz_ServerName)
			if(sz_version > f_ver)
			{
				server_print("*************************************************************************")
				server_print("[WR-BOT] There is a new version, please download and update the plugin!")
				server_print("*************************************************************************")
			}
			#if defined SQL
				SQL_QUERY();

				#if defined PUB
					if(get_pcvar_num(country_flag)) SQL_Country();
				#endif
			#endif

			#if defined nVault
				announce();
			#endif

			#if defined LAN
				license = true;
			#endif
		}
		else
		{
			#if defined PUB
			if(!g_socket_check)
			{
				GetTehRealIp( socketIP, 16 );
				server_print("External IP Server: %s", socketIP)
				SQL_Check_license(socketIP)
				g_socket_check = true;
			}
			else
			{
				server_print("[WR-BOT] You did not buy a license for the plugin, or have not confirmed your profile.")
				return pause("a")
			}
			#endif

			#if defined LAN
			if(b_CvarError)
				ColorChat(0, RED,  "^4[WR-BOT ^3v%s^1]^1 ERROR ... Switch the setting to -> ^3sv_lan 0 ^1", VERSION);
			else
				ColorChat(0, RED, "^4[WR-BOT ^3v%s^1]^1 You did not buy a license for the plugin, or have not confirmed your profile.", VERSION);
			#endif
		}
	}

	SQL_FreeHandle(hQuery)
	return PLUGIN_CONTINUE
}

public BotAfterDamage ( victim, weapon, attacker, Float:damage, damagebits )
{
	if (is_user_bot(victim) || is_user_bot(attacker))
		if ( damagebits & DMG_FALL )
			set_pev(wr_bot_id,pev_health,9999.0)
	else
		return HAM_SUPERCEDE

	return HAM_IGNORED
}

public Ham_ButtonUse( id )
{
	new Float:origin[3];
	pev( id, pev_origin, origin );
	new ent = -1;
	while ( (ent = find_ent_in_sphere( ent, origin, 100.0 ) ) != 0 )
	{
		new classname[32];
		pev( ent, pev_classname, classname, charsmax( classname ) );

			new Float:eorigin[3];
			get_brush_entity_origin( ent, eorigin );
			static Float:Distance[2];
			new szTarget[32];
			pev( ent, pev_target, szTarget, 31 );

			if ( TrieKeyExists( g_tButtons[0], szTarget ) )
			{
				if( !g_bot_start && get_pcvar_num(g_start_frame) != 0)
					g_bot_start = g_bot_frame - get_pcvar_num(g_start_frame);

				if( g_bot_start < 0 )
					g_bot_start = 0;

				if ( vector_distance( origin, eorigin ) >= Distance[0] )
				{
					timer_time[id] = get_gametime()
					IsPaused[id] = false
					timer_started[id] = true
					bot_finish_use[id] = false;
				}
				Distance[0] = vector_distance( origin, eorigin );
			}
			if ( TrieKeyExists( g_tButtons[1], szTarget ) )
			{
				if ( vector_distance( origin, eorigin ) >= Distance[1] )
				{
					if (!bot_finish_use[id])
					{
						if(timer_started[id])
						{
							if(get_pcvar_num(cooldown_startbot) == 0)
								Start_Bot();
							else
								StartCountDown();
						}
						timer_started[id] = false;
						bot_finish_use[id] = true;
					}
				}
				Distance[1] = vector_distance( origin, eorigin );
			}
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TIMER ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public timer_task(iTimer)
{
	new Dead[32], deadPlayers
	get_players(Dead, deadPlayers, "bh")
	for(new i=0;i<deadPlayers;i++)
	{
		new specmode = pev(Dead, pev_iuser1)
		if(specmode == 2 || specmode == 4)
		{
			new target = pev(Dead, pev_iuser2)
			if(is_user_alive(target))
			{
				if (timer_started[target] && target == wr_bot_id)
				{
					new Float:kreedztime = get_gametime() - (IsPaused[target] ? get_gametime() - g_pausetime[target] : timer_time[target])
					new imin = floatround( kreedztime / 60.0, floatround_floor );
					new isec = floatround( kreedztime - imin * 60, floatround_floor );
					new mili = floatround( ( kreedztime - ( imin * 60 + isec ) ) * 100, floatround_floor );
					if(get_pcvar_num(timer_option) == 1)
					{
						client_print(Dead, print_center , "[ %02i:%02i.%02i ]",imin, isec, mili, IsPaused[target] ? "| *Paused*" : "")
					}
					else if(get_pcvar_num(timer_option) == 2)
					{
						set_hudmessage(255, 255, 255, get_pcvar_float(g_xc), get_pcvar_float(g_yc), 0, 0.0, 1.0, 0.0, 0.0)
						ShowSyncHudMsg(Dead, SyncHudBotTimer, "[ %02i:%02i.%02i ]",imin, isec, mili, IsPaused[target] ? "| *Paused*" : "")
					}
				}
				else if (!timer_started[target] && target == wr_bot_id)
				{
					client_print(Dead, print_center, "")
				}
			}
		}
	}

	if(get_pcvar_num(update_timer) == 1) entity_set_float(iTimer, EV_FL_nextthink, get_gametime() + 0.07)
}

public Pause()
{
	if(!IsPaused[wr_bot_id])
	{
		g_pausetime[wr_bot_id] = get_gametime() - timer_time[wr_bot_id]
		timer_time[wr_bot_id] = 0.0
		IsPaused[wr_bot_id] = true
		g_bot_enable = 2;
	}
	else
	{
		if(timer_started[wr_bot_id])
		{
			timer_time[wr_bot_id] = get_gametime() - g_pausetime[wr_bot_id]
		}
		IsPaused[wr_bot_id] = false
		g_bot_enable = 1;
	}
}

public fwd_Think( iEnt )
{
	if ( !pev_valid( iEnt ) )
		return(FMRES_IGNORED);

	static className[32];
	pev( iEnt, pev_classname, className, 31 );

#if defined nVault
	if ( equal( className, "DemThink" ) )
	{
		static bool:Finished;
		for(new i = 0; i < NUM_THREADS; i++)
		{
			if(ReadFrames(iFile))
			{
				Finished = true;
				break;
			}
		}

		if(Finished)
		{
			set_pev(iEnt, pev_flags, pev(iEnt, pev_flags) | FL_KILLME)
			fclose( iFile );
			delete_file( iDemoName);
			LoadParsedInfo( iNavName );
		}
		else
		{
			set_pev( iEnt, pev_nextthink, get_gametime() + 0.001 )
		}
	}
	if ( equal( className, "NavThink" ) )
	{
		static bool:Finished;
		for(new i = 0; i < NUM_THREADS; i++)
		{
			if(!ReadParsed(iEnt))
			{
				Finished = true;
				break;
			}
		}

		if(Finished)
		{
			set_pev(iEnt, pev_flags, pev(iEnt, pev_flags) | FL_KILLME)
			//fclose( iFile );
			delete_file(iNavName);
			set_task( 2.0, "StartCountDown");
		}
	}
#endif

	if(equal(className, "kz_time_think"))
	{
		timer_task(1)
		set_pev(iEnt, pev_nextthink, get_gametime() + 0.08)
	}

	if ( equal( className, "BotThink" ) )
	{
		BotThink( wr_bot_id );
		set_pev( iEnt, pev_nextthink, get_gametime() + nExttHink );
	}

	return(FMRES_IGNORED);
}

public BotThink( id )
{
	static Float:ViewOrigin[3], Float:ViewAngle[3], Float:ViewVelocity[3], ViewKeys;

	static Float:last_check, Float:game_time, nFrame;
	game_time = get_gametime();

	if( game_time - last_check > 1.0 )
	{
		if (nFrame < 100)
			nExttHink = nExttHink - 0.0001
		else if (nFrame > 100)
			nExttHink = nExttHink + 0.0001

		nFrame = 0;
		last_check = game_time;
	}

	if(g_bot_enable == 1 && wr_bot_id)
	{
		g_bot_frame++;
		if ( g_bot_frame < ArraySize( fPlayerAngle ) )
		{
			ArrayGetArray( fPlayerOrigin, g_bot_frame, ViewOrigin );
			ArrayGetArray( fPlayerAngle, g_bot_frame, ViewAngle );
			ArrayGetArray( fPlayerVelo, g_bot_frame, ViewVelocity)
			ViewKeys = ArrayGetCell( fPlayerKeys, g_bot_frame );

			if(ViewKeys&IN_ALT1) ViewKeys|=IN_JUMP;
			if(ViewKeys&IN_RUN)  ViewKeys|=IN_DUCK;

			if(ViewKeys&IN_RIGHT)
			{
				engclient_cmd(id, "weapon_usp");
				ViewKeys&=~IN_RIGHT;
			}
			if(ViewKeys&IN_LEFT)
			{
				engclient_cmd(id, "weapon_knife");
				ViewKeys&=~IN_LEFT;
			}
			if ( ViewKeys & IN_USE )
			{
				Ham_ButtonUse( id );
				ViewKeys &= ~IN_USE;
			}

			engfunc(EngFunc_RunPlayerMove, id, ViewAngle, ViewVelocity[0], ViewVelocity[1], 0.0, ViewKeys, 0, 10);
			set_pev( id, pev_v_angle, ViewAngle );
			ViewAngle[0] /= -3.0;
			set_pev(id, pev_velocity, ViewVelocity);
			set_pev(id, pev_angles, ViewAngle);
			set_pev(id, pev_origin, ViewOrigin);
			set_pev(id, pev_button, ViewKeys );

			if( pev( id, pev_gaitsequence ) == 4 && ~pev( id, pev_flags ) & FL_ONGROUND )
				set_pev( id, pev_gaitsequence, 6 );

			if(nFrame == ArraySize( fPlayerAngle ) - 1)
			{
				if(get_pcvar_num(cooldown_startbot) == 0)
					Start_Bot();
				else
					StartCountDown();
			}

		} else  {
			g_bot_frame = 0;
		}
	}
	nFrame++;
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ SETTING MENU ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public ClCmd_ReplayMenu(id)
{
	if(!access(id,ADMIN_MENU))
		return PLUGIN_HANDLED;

	new title[512]
	formatex(title, 500, "\wSetting Bot Replay Menu^nName: \y%s\w^nRecord: \y%s", WR_NAME, WR_TIME)
	new menu = menu_create(title, "ReplayMenu_Handler")
	menu_additem(menu, "Start/Reset", "1");

	if(get_pcvar_num(timer_bot))
	{
		if (g_bot_enable == 1)
		   menu_additem(menu, "Pause^n", "2");
		else
			menu_additem(menu, "Play^n", "2");
	}
	else
	{
		menu_additem(menu, "\dPause - disabled ^n", "2");
	}
	menu_additem(menu, "Kick bot", "3");
	menu_display(id, menu, 0);

	return PLUGIN_HANDLED
}

public ReplayMenu_Handler(id, menu, item)
{
	if(item == MENU_EXIT)
		return PLUGIN_HANDLED;

	switch(item)
	{
		case 0:
		{
			if(!wr_bot_id)
				StartCountDown()
			else
				Start_Bot()
		}
		case 1: if(get_pcvar_num(timer_bot)) Pause();
		case 2:
		{
			if(wr_bot_id)
				server_cmd("kick #%d", get_user_userid(wr_bot_id))
		}
	}
	ClCmd_ReplayMenu(id);
	return PLUGIN_HANDLED;
}

Create_Bot()
{
	new txt[64]
	formatex(txt, charsmax(txt), "[WR] %s %s", WR_NAME, WR_TIME);
	new id = engfunc(EngFunc_CreateFakeClient, txt);
	if(pev_valid(id))
	{
		set_user_info(id, "rate", "10000");
		set_user_info(id, "cl_updaterate", "60");
		set_user_info(id, "cl_cmdrate", "60");
		set_user_info(id, "cl_lw", "1");
		set_user_info(id, "cl_lc", "1");
		set_user_info(id, "cl_dlmax", "128");
		set_user_info(id, "cl_righthand", "1");
		set_user_info(id, "_vgui_menus", "0");
		set_user_info(id, "_ah", "0");
		set_user_info(id, "dm", "0");
		set_user_info(id, "tracker", "0");
		set_user_info(id, "friends", "0");
		set_user_info(id, "*bot", "1");
		set_pev(id, pev_flags, pev(id, pev_flags) | FL_FAKECLIENT);
		set_pev(id, pev_colormap, id);

		dllfunc(DLLFunc_ClientConnect, id, "WR BOT", "127.0.0.1");
		dllfunc(DLLFunc_ClientPutInServer, id);

		cs_set_user_team(id, CS_TEAM_CT);
		cs_set_user_model(id, "sas");

		ham_give_weapon(id,"weapon_knife")
		ham_give_weapon(id,"weapon_usp")
		cs_set_user_bpammo(id, CSW_USP, 250)

		#if defined PUB
			if(get_pcvar_num(country_flag)) create_bot_icon(id)
		#endif

		if(!is_user_alive(id)) dllfunc(DLLFunc_Spawn, id);

		return id;
	}
	return 0;
}

//Начало отсчета
public StartCountDown()
{
	if(!wr_bot_id)
		wr_bot_id = Create_Bot();

	g_timer = get_pcvar_num(cooldown_startbot);
	set_task(1.0, "Show");
}

public Show()
{
	g_timer--;
	set_hudmessage(255, 255, 255, 0.05, 0.2, 0, 6.0, 1.0)

	if(g_timer && g_timer >= 0)
	{
		if(get_pcvar_num(hud_message)) ShowSyncHudMsg(0, SyncHudTimer, "Bot WR run through: %i sec", g_timer);
		set_task(1.0, "Show");
	}
	else {
		if(get_pcvar_num(hud_message)) ShowSyncHudMsg(0, SyncHudTimer, "Bot has started");
		g_bot_enable = 1;
		Start_Bot()
	}
}

Start_Bot()
{
	g_bot_frame = g_bot_start;
	timer_started[wr_bot_id] = false
}

public client_disconnect( id )
{
	if( id == wr_bot_id )
	{
		timer_time[id] = 0.0
		IsPaused[wr_bot_id] = false
		timer_started[wr_bot_id] = false
		g_bot_enable = 0;
		g_bot_frame = 0;
		wr_bot_id = 0;
		destroy_bot_icon()
	}
}

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Icon Bot ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

public create_bot_icon(id)
{
	g_Bot_Icon_ent = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString, "env_sprite"))

		if(file_exists(url_sprite))
			engfunc(EngFunc_SetModel, g_Bot_Icon_ent, url_sprite)
		else if(file_exists(url_sprite_xz))
			engfunc(EngFunc_SetModel, g_Bot_Icon_ent, url_sprite_xz)
		else
			return

	set_pev(g_Bot_Icon_ent, pev_solid, SOLID_NOT)
	set_pev(g_Bot_Icon_ent, pev_movetype, MOVETYPE_FLYMISSILE)
	set_pev(g_Bot_Icon_ent, pev_iuser2, id)
	set_pev(g_Bot_Icon_ent, pev_scale, 0.25)
}

destroy_bot_icon()
{
	if(g_Bot_Icon_ent)
		engfunc(EngFunc_RemoveEntity, g_Bot_Icon_ent)

	g_Bot_Icon_ent = 0
}

public addToFullPack(es, e, ent, host, hostflags, player, pSet)
{
	if(wr_bot_id == host)
	{
		return FMRES_IGNORED;
	}

	if(wr_bot_id)
	{
		if(pev_valid(ent) && (pev(ent, pev_iuser1) == pev(ent, pev_owner)))
		{
			new user = pev(ent, pev_iuser2)
			new specmode = pev(host, pev_iuser1)

			if(is_user_alive(user))
			{
				new Float: playerOrigin[3]
				pev(user, pev_origin, playerOrigin)
				playerOrigin[2] += 42
				engfunc(EngFunc_SetOrigin, ent, playerOrigin)

				if(specmode == 4)
				{
					set_es(es, ES_Effects, EF_NODRAW)
				}
			}
		}
	}

	return FMRES_IGNORED;
}

public BhopTouch(iBlock, id)
{
	if(GetBhopBlocks(g_bBlocks, iBlock))
		if(is_user_bot(id))
			return HAM_SUPERCEDE;

	return PLUGIN_CONTINUE;
}

SetTouch()
{
	RegisterHam(Ham_Touch, "func_door", "BhopTouch");

	new iDoor = FM_NULLENT;
	while((iDoor = find_ent_by_class( iDoor, "func_door")))
		SetBhopBlocks(g_bBlocks, iDoor);
}



//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MySQL Method !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#if defined SQL
public country_flag_add()
{
	new FLAG[4]

	if (file_exists(CountryData))
	{
		new FileOpen = fopen(CountryData, "rt")
		new Text[96], szArg1[25], szArg2[3]

		while(!feof(FileOpen))
		{
			fgets(FileOpen, Text, sizeof(Text) - 1)
			trim(Text)
			replace_all(Text,64,","," ")

			strtok(Text, szArg1, charsmax(szArg1), szArg2, charsmax(szArg2), ' ')

			if(equali(szArg1, g_szMapName))
			{
				FLAG = szArg2;
			}
		}

		fclose(FileOpen)

		if (equali(FLAG, "")) FLAG = "xz";
		if (equali(FLAG, "n-")) FLAG = "xz";

		formatex(url_sprite, charsmax(url_sprite), "sprites/wrbot/%s.spr", FLAG);
		formatex(url_sprite_xz, charsmax(url_sprite_xz), "sprites/wrbot/xz.spr");
		if(file_exists(url_sprite))
			precache_model(url_sprite)
		else if(file_exists(url_sprite_xz))
			precache_model(url_sprite_xz)
		else
			return
	}
}

public SQL_Country()
{
	delete_file(CountryData)
	Local_ini = fopen(CountryData, "w");
	SQL_ThreadQuery(g_SqlTuple, "SQL_WorkHandle", "SELECT * FROM local")
}

public SQL_WorkHandle(failstate, Handle:hQuery, error[], errcode, cData[], iSize, Float:fQueueTime)
{
	if( failstate == TQUERY_CONNECT_FAILED )
	{
		set_fail_state("Could not connect to database.");
	}
	else if( failstate == TQUERY_QUERY_FAILED )
	{
		set_fail_state("Query failed.");
	}
	else if( errcode )
	{
		log_amx("Error on query: %s", error);
	}
	else
	{
		new return_flag[4], sz_map[64];

		while( SQL_MoreResults(hQuery) )
		{
			new sz_map_id = SQL_FieldNameToNum( hQuery, "map" );
			new country_id = SQL_FieldNameToNum( hQuery, "country" );

			SQL_ReadResult(hQuery, sz_map_id, sz_map, charsmax(sz_map))
			SQL_ReadResult(hQuery, country_id, return_flag, charsmax(return_flag))

			fprintf(Local_ini, "%s,%s^n", sz_map,return_flag)
			SQL_NextRow(hQuery)
		}
	}

	fclose(Local_ini);
	SQL_FreeHandle(hQuery)
}

public SQL_QUERY()
{
	new query[256]
	format(query,charsmax(query),"SELECT * FROM `%s`", g_szMapName)
	SQL_ThreadQuery(g_SqlTuple, "SQL_OWN_QUERY", query)
}

public SQL_OWN_QUERY(iFailState, Handle:hQuery, szError[], iErrnum, cData[], iSize, Float:fQueueTime)
{
	if( iFailState != TQUERY_SUCCESS )
	{
		return log_amx("WR BOT ERROR: #%d - %s", iErrnum, szError)
	}

	if (SQL_NumResults(hQuery))
	{
		new stolb_1 = SQL_FieldNameToNum(hQuery, "angle1")
		new stolb_2 = SQL_FieldNameToNum(hQuery, "angle2")
		new stolb_3 = SQL_FieldNameToNum(hQuery, "origin1")
		new stolb_4 = SQL_FieldNameToNum(hQuery, "origin2")
		new stolb_5 = SQL_FieldNameToNum(hQuery, "origin3")
		new stolb_6 = SQL_FieldNameToNum(hQuery, "velocity1")
		new stolb_7 = SQL_FieldNameToNum(hQuery, "velocity2")
		new stolb_8 = SQL_FieldNameToNum(hQuery, "velocity3")
		new stolb_9 = SQL_FieldNameToNum(hQuery, "button")

		new line, Float:WR_TIME_FLOAT, WR_FLAG[4];
		new Float:Angles[3], Float:Origin[3], Float:velocity[3], Keys;

		while( SQL_MoreResults(hQuery) )
		{
			if (!line) {
				SQL_ReadResult(hQuery, stolb_1, WR_TIME_FLOAT)
				line++;
				SQL_NextRow(hQuery)
				continue;
			}

			if (line == 1) {
				SQL_ReadResult(hQuery, stolb_1, WR_NAME, charsmax(WR_NAME))
				line++;
				SQL_NextRow(hQuery)
				continue;
			}
			if (line == 2) {
				SQL_ReadResult(hQuery, stolb_1, WR_FLAG, charsmax(WR_FLAG))
				line++;
				SQL_NextRow(hQuery)
				continue;
			}

			if (line > 2)
			{
				SQL_ReadResult(hQuery, stolb_1, Angles[0])
				SQL_ReadResult(hQuery, stolb_2, Angles[1])
				SQL_ReadResult(hQuery, stolb_3, Origin[0])
				SQL_ReadResult(hQuery, stolb_4, Origin[1])
				SQL_ReadResult(hQuery, stolb_5, Origin[2])
				SQL_ReadResult(hQuery, stolb_6, velocity[0])
				SQL_ReadResult(hQuery, stolb_7, velocity[1])
				SQL_ReadResult(hQuery, stolb_8, velocity[2])
				Keys = SQL_ReadResult(hQuery, stolb_9)

				ArrayPushArray( fPlayerAngle, Angles );
				ArrayPushArray( fPlayerOrigin, Origin );
				ArrayPushArray( fPlayerVelo, velocity );
				ArrayPushCell( fPlayerKeys, Keys );

				line++
				SQL_NextRow(hQuery)
			}
		}

		StringTimer(WR_TIME_FLOAT, WR_TIME, charsmax(WR_TIME));

		#if defined DEV_DEBUG
			server_print("Finished loading demo in %f sec.", get_gametime()-flStartTime);
		#endif
	}
	SQL_FreeHandle(hQuery)

	#if defined PUB
		set_task(2.0, "StartCountDown")
	#endif

	#if defined LAN
		plugin_activated = true;
	#endif

	return PLUGIN_HANDLED
}
#endif

//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ nVault Method !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#if defined nVault

enum _:Consts
{
	HEADER_SIZE         = 544,
	HEADER_SIGNATURE_CHECK_SIZE = 6,
	HEADER_SIGNATURE_SIZE       = 8,
	HEADER_MAPNAME_SIZE     = 260,
	HEADER_GAMEDIR_SIZE     = 260,

	MIN_DIR_ENTRY_COUNT     = 1,
	MAX_DIR_ENTRY_COUNT     = 1024,
	DIR_ENTRY_SIZE          = 92,
	DIR_ENTRY_DESCRIPTION_SIZE  = 64,

	MIN_FRAME_SIZE          = 12,
	FRAME_CONSOLE_COMMAND_SIZE  = 64,
	FRAME_CLIENT_DATA_SIZE      = 32,
	FRAME_EVENT_SIZE        = 84,
	FRAME_WEAPON_ANIM_SIZE      = 8,
	FRAME_SOUND_SIZE_1      = 8,
	FRAME_SOUND_SIZE_2      = 16,
	FRAME_DEMO_BUFFER_SIZE      = 4,
	FRAME_NETMSG_SIZE       = 468,
	FRAME_NETMSG_DEMOINFO_SIZE  = 436,
	FRAME_NETMSG_MOVEVARS_SIZE  = 32,
	FRAME_NETMSG_MIN_MESSAGE_LENGTH = 0,
	FRAME_NETMSG_MAX_MESSAGE_LENGTH = 65536
};

enum DemoHeader {
	netProtocol,
	demoProtocol,
	mapName[HEADER_MAPNAME_SIZE],
	gameDir[HEADER_GAMEDIR_SIZE],
	mapCRC,
	directoryOffset
};

enum DemoEntry {
	dirEntryCount,
	type,
	description[DIR_ENTRY_DESCRIPTION_SIZE],
	flags,
	CDTrack,
	trackTime,
	frameCount,
	offset,
	fileLength,
	frames,
	ubuttons /* INT 16 */
};

enum FrameHeader
{
	Type,
	Float:Timestamp,
	Number
}


enum NetMsgFrame {
	Float:timestamp,
	Float:view[3],
	viewmodel
}

new iDemoEntry[DemoEntry];
new iDemoHeader[DemoHeader];
new iDemoFrame[FrameHeader];

public announce()
{
	new datadir[128];
	new filename[128];
	get_localinfo( "amxx_datadir", datadir, charsmax( datadir ) );
	format( filename, charsmax( datadir ), "%s/list_xj.txt", datadir );
	delete_file(filename);
	iXJWRs = fopen(filename, "wb");
	new CURL:curl = curl_easy_init();
	if(curl)
	{
		curl_easy_setopt(curl, CURLOPT_URL, "http://xtreme-jumps.eu/demos.txt");
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, "write_xj");
		curl_easy_perform(curl, "complite_xj")
	}
}

public write_xj(data[], size, nmemb) {
	new real_size = size*nmemb

	for(new i = 0; i < nmemb; i++)
	{
		if(i < nmemb)
		fwrite(iXJWRs, data, BLOCK_BYTE);
	}

	return real_size

}

public complite_xj(CURLcode:code, CURL:curl) {
	curl_easy_cleanup(curl)
	fclose(iXJWRs);

	new datadir[128];
	new filename[128];
	get_localinfo( "amxx_datadir", datadir, charsmax( datadir ) );
	format( filename, charsmax( datadir ), "%s/list_cc.txt", datadir );
	delete_file(filename);
	iCCWRs = fopen(filename, "wb");
	new CURL:curl = curl_easy_init();
	if(curl)
	{
		curl_easy_setopt(curl, CURLOPT_URL, "https://cosy-climbing.net/demoz.txt");
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, "write_cc");
		curl_easy_perform(curl, "complite_cc")
	}
}

public write_cc(data[], size, nmemb) {
	new real_size = size*nmemb

	for(new i = 0; i < nmemb; i++)
	{
		if(i < nmemb)
		fwrite(iCCWRs, data, BLOCK_BYTE);
	}

	return real_size

}

public complite_cc(CURLcode:code, CURL:curl) {
	curl_easy_cleanup(curl)
	fclose(iCCWRs);

	OnDemosComplete(0);
}

public OnDemosComplete( Index )
{
		new demoslist[128];
		get_localinfo( "amxx_datadir", demoslist, charsmax( demoslist ) );
		format( demoslist, charsmax( demoslist ), "%s/list_xj.txt", demoslist );
		#if defined DEV_DEBUG
		server_print( "Parsing XJ Demo List" );
		#endif
		new iDemosList  = fopen( demoslist, "rb" );
		new ExplodedString[7][128];
		new Line[128];
		new MapName[64];
		get_mapname( MapName, 63 );
		format( MapName, charsmax( MapName ), "%s ", MapName );
		while ( !feof( iDemosList ) )
		{
			fgets( iDemosList, Line, charsmax( Line ) );
			ExplodeString( ExplodedString, 6, 127, Line, ' ' );
			new parsedmap[128];
			parsedmap = ExplodedString[0];
			format( parsedmap, charsmax( parsedmap ), "%s ", parsedmap );
			if ( containi( parsedmap, MapName ) > -1 )
			{
				bFoundDemo = true;
				break;
			}
		}
		if ( !bFoundDemo )
		{
			get_mapname( MapName, 63 );
			format( MapName, charsmax( MapName ), "%s[", MapName );
			fseek( iDemosList, 0, SEEK_SET );
			while ( !feof( iDemosList ) )
			{
				fgets( iDemosList, Line, charsmax( Line ) );
				ExplodeString( ExplodedString, 6, 127, Line, ' ' );
				if ( containi( ExplodedString[0], MapName ) > -1 )
				{
					bFoundDemo = true;
					break;
				}
			}
		}
		else
		{
			new Float:Date = str_to_float( ExplodedString[1] );
			new sWRTime[24];
			fnConvertTime( Date, sWRTime, charsmax( sWRTime ) );
			format( iArchiveName, charsmax( iArchiveName ), "%s_%s_%s", ExplodedString[0], ExplodedString[2], sWRTime );
			StringTimer(Date, WR_TIME, sizeof(WR_TIME) - 1);
			WR_NAME = ExplodedString[2];
			new iLink[512];
			format( iLink, charsmax( iLink ), "http://files.xtreme-jumps.eu/demos/%s.rar", iArchiveName );
			new datadir[128];
			get_localinfo( "amxx_datadir", datadir, charsmax( datadir ) );
			format( datadir, charsmax( datadir ), "%s/%s.rar", datadir, iArchiveName );
			DownloadDemoArchive(iArchiveName, iLink);
		}

		if(!bFoundDemo)
		{
			CheckCCList();
		}
}

public CheckCCList()
{
	new demoslist[128];
	get_localinfo( "amxx_datadir", demoslist, charsmax( demoslist ) );
	format( demoslist, charsmax( demoslist ), "%s/list_cc.txt", demoslist );
	#if defined DEV_DEBUG
	server_print( "Parsing Cosy Demo List" );
	#endif
	new iDemosList  = fopen( demoslist, "rb" );
	new ExplodedString[7][128];
	new Line[128];
	new MapName[64];
	get_mapname( MapName, 63 );
	format( MapName, charsmax( MapName ), "%s ", MapName );
	while ( !feof( iDemosList ) )
	{
		fgets( iDemosList, Line, charsmax( Line ) );
		ExplodeString( ExplodedString, 6, 127, Line, ' ' );
		new parsedmap[128];
		parsedmap = ExplodedString[0];
		format( parsedmap, charsmax( parsedmap ), "%s ", parsedmap );
		if ( containi( parsedmap, MapName ) > -1 )
		{
			bFoundDemo = true;
			break;
		}
	}
	if ( !bFoundDemo )
	{
		get_mapname( MapName, 63 );
		format( MapName, charsmax( MapName ), "%s[", MapName );
		fseek( iDemosList, 0, SEEK_SET );
		while ( !feof( iDemosList ) )
		{
			fgets( iDemosList, Line, charsmax( Line ) );
			ExplodeString( ExplodedString, 6, 127, Line, ' ' );
			if ( containi( ExplodedString[0], MapName ) > -1 )
			{
				bFoundDemo = true;
				break;
			}
		}
	}else  {
		new Float:Date = str_to_float( ExplodedString[1] );
		new sWRTime[24];
		fnConvertTime( Date, sWRTime, charsmax( sWRTime ) );
		format( iArchiveName, charsmax( iArchiveName ), "%s_%s_%s", ExplodedString[0], ExplodedString[2], sWRTime );
		StringTimer(Date, WR_TIME, sizeof(WR_TIME) - 1);
		WR_NAME = ExplodedString[2];
		new iLink[512];
		format( iLink, charsmax( iLink ), "https://cosy-climbing.net/files/demos/%s.rar", iArchiveName );
		new datadir[128];
		get_localinfo( "amxx_datadir", datadir, charsmax( datadir ) );
		format( datadir, charsmax( datadir ), "%s/%s.rar", datadir, iArchiveName );
		DownloadDemoArchive(iArchiveName, iLink);
	}
}



public DownloadDemoArchive(iArchiveName[], iLink[])
{
	new datadir[128];
	new filename[128];
	get_localinfo( "amxx_datadir", datadir, charsmax( datadir ) );
	format( filename, charsmax( datadir ), "%s/%s.rar",datadir, iArchiveName );
	//delete_file(filename);
	iArchive = fopen(filename, "wb");
	new CURL:curl = curl_easy_init();
	//server_print("%s iLink", iLink);
	if(curl)
	{
		curl_easy_setopt(curl, CURLOPT_URL, iLink);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, "write_archive");
		curl_easy_perform(curl, "complite_archive")
	}
}

public write_archive(data[], size, nmemb) {
	new real_size = size*nmemb

	for(new i = 0; i < nmemb; i++)
	{
		if(i < nmemb)
		fwrite(iArchive, data[i], BLOCK_BYTE);
	}

	return real_size

}

public complite_archive(CURLcode:code, CURL:curl) {
	curl_easy_cleanup(curl)
	fclose(iArchive);

	OnArchiveComplete();
}


public OnArchiveComplete()
{
	new RARArchive[128];

	format( RARArchive, charsmax( RARArchive ), "%s.rar", iArchiveName );
	AA_Unarchive(RARArchive);
	new datadir[128];
	get_localinfo( "amxx_datadir", datadir, charsmax( datadir ) );
	format( datadir, charsmax( datadir ), "%s/%s.rar", datadir, iArchiveName );
	delete_file( datadir );

	new szNavName[256];

	get_localinfo( "amxx_datadir", datadir, charsmax( datadir ) );
	format( szNavName, sizeof(szNavName), "%s", datadir, iArchiveName );
	if(!dir_exists(szNavName))
	{
		mkdir(szNavName);
	}
	format( iNavName, sizeof(iNavName), "%s/%s.nav", datadir, iArchiveName );
	format( iDemoName, sizeof(iDemoName), "%s/%s.dem", datadir, iArchiveName );
	if ( !file_exists( iNavName ) )
	{
		iFile = fopen( iDemoName, "rb" );
		if ( iFile )
		{
			iParsedFile = fopen( iNavName, "w" );
			ReadHeaderX();
			/*fclose(iFile);
			fclose(iParsedFile);
			LoadParsedInfo( szNavName );*/
		}
	}else  {
		LoadParsedInfo( iNavName );
	}

	#if defined DEV_DEBUG
	flStartTime = get_gametime();
	#endif
}


public fnConvertTime( Float:time, convert_time[], len )
{
	new sTemp[24];
	new Float:fSeconds = time, iMinutes;

	iMinutes        = floatround( fSeconds / 60.0, floatround_floor );
	fSeconds        -= iMinutes * 60.0;
	new intpart     = floatround( fSeconds, floatround_floor );
	new Float:decpart   = (fSeconds - intpart) * 100.0;
	intpart         = floatround( decpart );

	formatex( sTemp, charsmax( sTemp ), "%02i%02.0f.%02d", iMinutes, fSeconds, intpart );


	formatex( convert_time, len, sTemp );
	#if defined DEV_DEBUG
	server_print( "%f %s, %s",time, sTemp, convert_time);
	#endif
	return(PLUGIN_HANDLED);
}

public LoadParsedInfo(szNavName[])
{
	iFile = fopen( szNavName, "rb" );
	new Ent = engfunc( EngFunc_CreateNamedEntity , engfunc( EngFunc_AllocString,"info_target" ) );
	set_pev(Ent, pev_classname, "NavThink");
	set_pev(Ent, pev_nextthink, get_gametime() + 0.01 );
}

public ReadHeaderX()
{
	if ( IsValidDemoFile( iFile ) )
	{
		ReadHeader( iFile );
		new Ent = engfunc( EngFunc_CreateNamedEntity , engfunc( EngFunc_AllocString,"info_target" ) );
		set_pev(Ent, pev_classname, "DemThink");
		set_pev(Ent, pev_nextthink, get_gametime() + 0.01 );

	}else {
		server_print( "NOTVALID" );
	}
}

public bool:IsValidDemoFile( file )
{
	fseek( file, 0, SEEK_END );
	iDemo_header_size = ftell( file );


	if ( iDemo_header_size < HEADER_SIZE )
	{
		return(false);
	}

	fseek( file, 0, SEEK_SET );
	new signature[HEADER_SIGNATURE_CHECK_SIZE];


	fread_blocks( file, signature, sizeof(signature), BLOCK_CHAR );

	if ( !contain( "HLDEMO", signature ) )
	{
		return(false);
	}

	return(true);
}


public ReadHeader( file )
{
	fseek( file, HEADER_SIGNATURE_SIZE, SEEK_SET );

	fread( file, iDemoHeader[demoProtocol], BLOCK_INT );

	if ( iDemoHeader[demoProtocol] != 5 )
	{
	}

	fread( file, iDemoHeader[netProtocol], BLOCK_INT );

	if ( iDemoHeader[netProtocol] != 48 )
	{
	}

	fread_blocks( file, iDemoHeader[mapName], HEADER_MAPNAME_SIZE, BLOCK_CHAR );
	fread_blocks( file, iDemoHeader[gameDir], HEADER_GAMEDIR_SIZE, BLOCK_CHAR );

	fread( file, iDemoHeader[mapCRC], BLOCK_INT );
	fread( file, iDemoHeader[directoryOffset], BLOCK_INT );

	fseek( file, iDemoHeader[directoryOffset], SEEK_SET );

	new newPosition = ftell( file );

	if ( newPosition != iDemoHeader[directoryOffset] )
	{
		/*server_print( "kek :(" );*/
	}
	fread( file, iDemoEntry[dirEntryCount], BLOCK_INT );
	for ( new i = 0; i < iDemoEntry[dirEntryCount]; i++ )
	{
		fread( file, iDemoEntry[type], BLOCK_INT );
		fread_blocks( file, iDemoEntry[description], DIR_ENTRY_DESCRIPTION_SIZE, BLOCK_CHAR );
		fread( file, iDemoEntry[flags], BLOCK_INT );
		fread( file, iDemoEntry[CDTrack], BLOCK_INT );
		fread( file, iDemoEntry[trackTime], BLOCK_INT );
		fread( file, iDemoEntry[frameCount], BLOCK_INT );
		fread( file, iDemoEntry[offset], BLOCK_INT );
		fread( file, iDemoEntry[fileLength], BLOCK_INT );
	}

	fseek( file, iDemoEntry[offset], SEEK_SET );

/* server_print( "%d %d %s %s %d %d %d", iDemoHeader[demoProtocol], iDemoHeader[netProtocol], iDemoHeader[mapName], iDemoHeader[gameDir], iDemoHeader[mapCRC], iDemoHeader[directoryOffset], iDemoEntry[dirEntryCount] ); */
}

public ReadParsed( iEnt )
{
	if ( iFile )
	{
		new szLineData[512];
		static sExplodedLine[11][150];
		if ( !feof( iFile ) )
		{
			fseek(iFile, 0, SEEK_CUR);
			new iSeek = ftell(iFile);
			fseek(iFile, 0, SEEK_END);
			#if defined DEV_DEBUG
			new iFinish = ftell(iFile);
			server_print("%.2f%% NAV READED", float(iSeek)/float(iFinish)*100.0);
			#endif
			fseek(iFile, iSeek, SEEK_SET);

			/* read one line */
			fgets( iFile, szLineData, charsmax( szLineData ) );


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

			ExplodeString( sExplodedLine, 10, 50, szLineData, '|' );
			if ( equal( sExplodedLine[1], "ASD" ) )
			{
				new Keys        = str_to_num( sExplodedLine[2] );
				new Float:Angles[3];
				Angles[0]   = str_to_float( sExplodedLine[3] );
				Angles[1]   = str_to_float( sExplodedLine[4] );
				Angles[2]   = 0.0;
				new Float:Origin[3];
				Origin[0]   = str_to_float( sExplodedLine[5] );
				Origin[1]   = str_to_float( sExplodedLine[6] );
				Origin[2]   = str_to_float( sExplodedLine[7] );
				new Float:velocity[3]
				velocity[0] = str_to_float( sExplodedLine[8] );
				velocity[1] = str_to_float( sExplodedLine[9] );
				velocity[2] = 0.0;

			ArrayPushArray( fPlayerAngle, Angles );
			ArrayPushArray( fPlayerOrigin, Origin );
				ArrayPushArray( fPlayerVelo, velocity );
				ArrayPushCell( fPlayerKeys, Keys );
			}
			set_pev( iEnt, pev_nextthink, get_gametime()+0.0001 );
			return true;
		}
		else
		{
			#if defined DEV_DEBUG
			server_print("Finished loading demo in %f sec.", get_gametime()-flStartTime);
			#endif
			return false;
		}
	}

	return false;
}
public ReadFrames( file )
{

	fseek(file, 0, SEEK_CUR);
	new iSeek = ftell(file);
	fseek(file, 0, SEEK_END);
	fseek(iFile, iSeek, SEEK_SET);
	#if defined DEV_DEBUG
	new iFinish = ftell(file);
	server_print("%.2f%% DEMO PARSED", float(iSeek)/float(iFinish)*100.0);
	#endif

	static sum;

	if ( !feof( file ) )
	{
		new FrameType = ReadFrameHeader( file );
		new breakme;
		/*
		 * server_print( "TOTAL: %d", FrameType );
		 * server_print( "LEL%d %d %d", FrameType, iDemoFrame[Timestamp], iDemoFrame[Number] );
		 */
		switch ( FrameType )
		{
			case 0:
			{
			}
			case 1:
			{
				new Float:Origin[3], Float:ViewAngles[3], Float:velocity[3], iAsd[1024];
				fseek( file, 4, SEEK_CUR );                             // read_object(demo, f.DemoInfo.timestamp);
				for ( new i = 0; i < 3; ++i )
					fseek( file, 4, SEEK_CUR );                     // read_object(demo, f.DemoInfo.RefParams.vieworg);
				for ( new i = 0; i < 3; ++i )
					fread( file, _:ViewAngles[i], BLOCK_INT );  // read_object(demo, f.DemoInfo.RefParams.viewangles);

				fseek( file, 64, SEEK_CUR );                            // пропуск до следующего участка.

				for ( new i = 0; i < 3; ++i )
					fread( file, _:velocity[i], BLOCK_INT );        // read_object(demo, f.DemoInfo.RefParams.simvel);
				for ( new i = 0; i < 3; ++i )
					fread( file, _:Origin[i], BLOCK_INT );          // read_object(demo, f.DemoInfo.RefParams.simorg);

				fseek( file, 124, SEEK_CUR );                       // пропуск до следующего участка.

				for ( new i = 0; i < 3; ++i )
					fseek( file, 4, SEEK_CUR );                     // read_object(demo, f.DemoInfo.UserCmd.viewangles);

				fseek( file, 4, SEEK_CUR );                     /* read_object(demo, f.ForwardMove); */
				fseek( file, 4, SEEK_CUR );                     /* read_object(demo, f.SideMove); */
				fseek( file, 4, SEEK_CUR );                     /* read_object(demo, f.UpmoveMove); */
				fseek( file, 2, SEEK_CUR );                     /* read_object(demo, f.lightlevel && f.align_2; */
				fread( file, iDemoEntry[ubuttons], BLOCK_SHORT );

				format( iAsd, charsmax( iAsd ), "%d|ASD|%d|%.4f|%.4f|%.3f|%.3f|%f|%.3f|%.3f|%.3f^n",sum, iDemoEntry[ubuttons], ViewAngles[0], ViewAngles[1], Origin[0],Origin[1],Origin[2], velocity[0], velocity[1], velocity[2] );
				fputs( iParsedFile, iAsd );
				fseek( file, 196, SEEK_CUR ); // static
				new length;
				fread( file, length, BLOCK_INT ); // static
				fseek( file, length, SEEK_CUR ); // static
			}
			case 2:
			{
			}
			case 3:
			{
				new ConsoleCmd[FRAME_CONSOLE_COMMAND_SIZE];
				fread_blocks( file, ConsoleCmd, FRAME_CONSOLE_COMMAND_SIZE, BLOCK_CHAR );
			}
			case 4:
			{
				sum++;
				for ( new i = 0; i < 3; ++i )                               // Бот чуть выше земли и pre будет показывать, как UP
					fseek( file, 4, SEEK_CUR );                             // write_object(o, f->origin[i]);
				for ( new i = 0; i < 3; ++i )                               // write_object(o, f->viewangles[i]);
					fseek( file, 4, SEEK_CUR );

				fseek( file, 4, SEEK_CUR );                             // write_object(o, f->weaponBits);
				fseek( file, 4, SEEK_CUR );                             // write_object(o, f->fov);
			}
			case 5:
			{
				breakme = 2;
			}
			case 6:
			{
				fseek( file, 4, SEEK_CUR );             /* read_object(demo, f.flags); */
				fseek( file, 4, SEEK_CUR );             /* read_object(demo, f.index); */
				fseek( file, 4, SEEK_CUR );             /* read_object(demo, f.delay); */
				fseek( file, 4, SEEK_CUR );             /* read_object(demo, f.EventArgs.flags); */
				fseek( file, 4, SEEK_CUR );             /* read_object(demo, f.EventArgs.entityIndex); */
				for ( new i = 0; i < 3; ++i )
					fseek( file, 4, SEEK_CUR );     /* read_object(demo, f.EventArgs.origin[i]); */
				for ( new i = 0; i < 3; ++i )
					fseek( file, 4, SEEK_CUR );     /* read_object(demo, f.EventArgs.angles[i]); */
				for ( new i = 0; i < 3; ++i )
					fseek( file, 4, SEEK_CUR );     /* read_object(demo, f.EventArgs.velocity[i]); */
				fseek( file, 4, SEEK_CUR );             /* read_object(demo, f.EventArgs.ducking); */
				fseek( file, 4, SEEK_CUR );             /* read_object(demo, f.EventArgs.fparam1); */
				fseek( file, 4, SEEK_CUR );             /* read_object(demo, f.EventArgs.fparam2); */
				fseek( file, 4, SEEK_CUR );             /* read_object(demo, f.EventArgs.iparam1); */
				fseek( file, 4, SEEK_CUR );             /* read_object(demo, f.EventArgs.iparam2); */
				fseek( file, 4, SEEK_CUR );             /* read_object(demo, f.EventArgs.bparam1); */
				fseek( file, 4, SEEK_CUR );             /* read_object(demo, f.EventArgs.bparam2); */
			}
			case 7:
			{
				fseek( file, 8, SEEK_CUR );
			}
			case 8:
			{
				fseek( file, 4, SEEK_CUR );
				new length;
				fread( file, length, BLOCK_INT );
				new msg[128];
				fread_blocks( file, msg, length, BLOCK_CHAR );
				fseek( file, 16, SEEK_CUR );
			}
			case 9:
			{
				new length = 0;
				fread( file, length, BLOCK_INT );
				new buffer[4];
				fread_blocks( file, buffer, length, BLOCK_BYTE );
			}
			default:
			{
				breakme = 2;
			}
		}

		if(breakme == 2)
		{
			return true;
		}
	}

	return false;
}


public ReadFrameHeader( file )
{
	fread( file, iDemoFrame[Type], BLOCK_BYTE );
	fread( file, _:iDemoFrame[Timestamp], BLOCK_INT );
	fread( file, iDemoFrame[Number], BLOCK_INT );

	return(iDemoFrame[Type]);
}

public ExplodeString( p_szOutput[][], p_nMax, p_nSize, p_szInput[], p_szDelimiter )
{
	new nIdx    = 0, l = strlen( p_szInput );
	new nLen    = (1 + copyc( p_szOutput[nIdx], p_nSize, p_szInput, p_szDelimiter ) );
	while ( (nLen < l) && (++nIdx < p_nMax) )
		nLen += (1 + copyc( p_szOutput[nIdx], p_nSize, p_szInput[nLen], p_szDelimiter ) );
	return(nIdx);
}

public check_dir()
{
	new demoslist[32], file[64];
	get_localinfo( "amxx_datadir", demoslist, charsmax( demoslist ) );
	new dirh = open_dir(demoslist, file, 63) // открывает дерикторию
	// Цикл с переборкой файлов
	while(next_file(dirh, file, 63))
	{
		new left[128], right[128], g_right[32], g_left[32], texturl[128]
		strtok(file, left, 127, right, 127, '.') // Уберает из названия карты, символы после <" . ">
		strtok(right, g_left, 31, g_right, 31, '.') // Повторно убираем <" . "> т.к. в демке 2 точки
		formatex(texturl, charsmax(texturl), "%s/%s", demoslist, file) // url для удаления файлов

		if(equali(g_right, "dem") || equali(g_right, "nav") || equali(g_right, "rar") || equali(g_right, "zip")) // Условия сравнения файла на наличие bsp
		{
			delete_file(texturl)
		}
	}
}

public parsing_country(data[])
{
	new demoslist[128];
	get_localinfo( "amxx_datadir", demoslist, charsmax( demoslist ) );
	if(equali(data, "xj"))
		format( demoslist, charsmax( demoslist ), "%s/list_xj.txt", demoslist );
	else if(equali(data, "cc"))
		format( demoslist, charsmax( demoslist ), "%s/list_cc.txt", demoslist );

	#if defined DEV_DEBUG
	server_print( "Parsing XJ Demo List" );
	#endif
	new iDemosList  = fopen( demoslist, "rb" );
	new ExplodedString[7][128];
	new Line[128];
	new MapName[64];
	get_mapname( MapName, 63 );
	format( MapName, charsmax( MapName ), "%s ", MapName );
	while ( !feof( iDemosList ) )
	{
		fgets( iDemosList, Line, charsmax( Line ) );
		ExplodeString( ExplodedString, 6, 127, Line, ' ' );
		new parsedmap[128];
		parsedmap = ExplodedString[0];
		format( parsedmap, charsmax( parsedmap ), "%s ", parsedmap );
		if ( containi( parsedmap, MapName ) > -1 )
		{
			g_Demos = true;
			break;
		}
	}
	if ( !g_Demos )
	{
		get_mapname( MapName, 63 );
		format( MapName, charsmax( MapName ), "%s[", MapName );
		fseek( iDemosList, 0, SEEK_SET );
		while ( !feof( iDemosList ) )
		{
			fgets( iDemosList, Line, charsmax( Line ) );
			ExplodeString( ExplodedString, 6, 127, Line, ' ' );
			if ( containi( ExplodedString[0], MapName ) > -1 )
			{
				g_Demos = true;
				break;
			}
		}
	}
	else
	{
		new FLAG[10]
		formatex(FLAG, charsmax(FLAG), "%s", ExplodedString[3]);
		trim(FLAG)
		if (equali(FLAG, "")) FLAG = "xz";
		if (equali(FLAG, "n-")) FLAG = "xz";

		formatex(url_sprite, charsmax(url_sprite), "sprites/wrbot/%s.spr", FLAG);
		formatex(url_sprite_xz, charsmax(url_sprite_xz), "sprites/wrbot/xz.spr");
		if(file_exists(url_sprite))
			precache_model(url_sprite)
		else if(file_exists(url_sprite_xz))
			precache_model(url_sprite_xz)
		else
			return
	}

	if ( !g_Demos && equali(data, "xj") )
		parsing_country("cc")
}
#endif


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Lan Version !!! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#if defined LAN
public StartWatchWR(id)
{
	if (license)
	{
		if(plugin_activated)
		{
			StartCountDown();
			client_cmd(0, "spk fvox/activated")

			if(!is_user_bot(id) && is_user_localhost(id) && cs_get_user_team(id) != CS_TEAM_SPECTATOR)
			{
				set_task(0.5, "ct", id);
			}
		}
		else
		{
			ColorChat(id, RED,  "^4[WR-BOT]^1 Please wait a moment, plugin receives data.")
		}
	}
	else
	{
		if(b_CvarError)
			ColorChat(id, RED,  "^4[WR-BOT ^3v%s^1]^1 ERROR ... Switch the setting to -> ^3sv_lan 0 ^1", VERSION);
		else
			ColorChat(id, RED, "^4[WR-BOT ^3v%s^1]^1 You did not buy a license for the plugin, or have not confirmed your profile.", VERSION);
	}
}

public plugin_info(id)
{
	if(plugin_activated && license && is_user_connected(id))
	{
		remove_task(id)
		client_cmd(0, "spk fvox/blip")
		set_hudmessage(159, 165, 255, 0.05, 0.3, 2, 0.1, 7.0, 0.03)
		show_hudmessage(id, "Loading DEMO completed^nYou can see the WR right now /playwr^n")
		ColorChat(id, RED,  "^4[WR-BOT ^3v%s^1]^1 All the information you can see on the site ^3KREEDZ.RU ^1", VERSION)
	}
}

public Stop(id)
{
	if (license)
	{
		server_cmd("kick #%d", get_user_userid(wr_bot_id))
		ct(id)
		client_cmd(0, "spk fvox/deactivated")
	}
}

public ct(id)
{
	new CsTeams:team = cs_get_user_team(id)
	if (team == CS_TEAM_CT || team == CS_TEAM_T)
	{
		cs_set_user_team(id,CS_TEAM_SPECTATOR)
		set_pev(id, pev_solid, SOLID_NOT)
		set_pev(id, pev_movetype, MOVETYPE_FLY)
		set_pev(id, pev_effects, EF_NODRAW)
		set_pev(id, pev_deadflag, DEAD_DEAD)
		client_cmd(id, ";specmode 4") //first person
		static name[32]
		get_user_name(wr_bot_id, name,31)
		client_cmd(id, "follow ^"%s^"",name)
	}
	else
	{
		cs_set_user_team(id,CS_TEAM_CT)
		set_pev(id, pev_effects, 0)
		set_pev(id, pev_movetype, MOVETYPE_WALK)
		set_pev(id, pev_deadflag, DEAD_NO)
		set_pev(id, pev_takedamage, DAMAGE_AIM)
		CmdRespawn(id)
		// Возвращение оружия в спеках
		//strip_user_weapons(id)
		ham_give_weapon(id,"weapon_knife")
		ham_give_weapon(id,"weapon_usp")
	}
	return PLUGIN_HANDLED
}

public Ham_PlayerSpawn_P(id)
{
	if(is_user_localhost(id) && is_user_alive(id) && !is_user_bot(id) && firstspawn[id])
	{
		new steamid[32]
		get_user_authid(id, steamid, charsmax(steamid))

		firstspawn[id] = false;
		SQL_Check_license(steamid)
		set_task(0.5, "plugin_info", id,_,_,"b")
	}

	if(is_user_alive(id) && is_user_bot(id))
	{
		ham_give_weapon(id,"weapon_knife")
		ham_give_weapon(id,"weapon_usp")
	}
}

public CmdRespawn(id)
{
	if ( get_user_team(id) == 3 )
		return PLUGIN_HANDLED
	else
		ExecuteHamB(Ham_CS_RoundRespawn, id)

	return PLUGIN_HANDLED
}
#endif

public client_connect(id)
{
	if(is_user_bot(id)) return
	#if defined LAN
		new bool:LANus = true;
	#else
		new bool:LANus = false;
	#endif

	if(LANus || equali(gl_verification, "STEAM"))
	{
		firstspawn[id] = true
		b_CvarError = false
		set_task(2.0, "Client_Cvars", id);
	}
}

public Client_Cvars(id)
{
	query_client_cvar(id, "sv_lan" ,"Check_Cvars");
}

public Check_Cvars(id, const szVar[], const szValue[])
{
	if((equali(szVar, "sv_lan") && str_to_num(szValue) != 0))
	{
		ColorChat(id, RED,  "^4[WR-BOT ^3v%s^1]^1 ERROR ... Switch the setting to -> ^3sv_lan 0 ^1", VERSION);
		b_CvarError = true;
	}
}

stock is_user_localhost(id)
{
	new szIP[16];
	get_user_ip(id, szIP, sizeof(szIP) - 1, 1);

	if(equal(szIP, "loopback") || equal(szIP, "127.0.0.1"))
	{
		return true;
	}
	return false;
}

stock ham_give_weapon(id,weapon[])
{
	if(!equal(weapon,"weapon_",7))
		return 0

	new wEnt = engfunc(EngFunc_CreateNamedEntity,engfunc(EngFunc_AllocString,weapon));

	if(!pev_valid(wEnt))
		return 0

	set_pev(wEnt,pev_spawnflags,SF_NORESPAWN);
	dllfunc(DLLFunc_Spawn,wEnt)

	if(!ExecuteHamB(Ham_AddPlayerItem,id,wEnt))
	{
		if(pev_valid(wEnt)) set_pev(wEnt,pev_flags,pev(wEnt,pev_flags) | FL_KILLME);
		return 0
	}

	ExecuteHamB(Ham_Item_AttachToPlayer,wEnt,id)
	return 1
}

stock StringTimer(const Float:flRealTime, szOutPut[], const iSizeOutPut)
{
	static Float:flTime, iMinutes, iSeconds, iMiliSeconds, Float:iMili;
	new string[12]

	flTime = flRealTime;

	if(flTime < 0.0) flTime = 0.0;

	iMinutes = floatround(flTime / 60, floatround_floor);
	iSeconds = floatround(flTime - (iMinutes * 60), floatround_floor);
	iMili = floatfract(flRealTime)
	formatex(string, 11, "%.02f", iMili >= 0 ? iMili + 0.005 : iMili - 0.005);
	iMiliSeconds = floatround(str_to_float(string) * 100, floatround_floor);

	formatex(szOutPut, iSizeOutPut, "%02d:%02d.%02d", iMinutes, iSeconds, iMiliSeconds);
}


AmxxArch.inc:
| Afiseaza codul
/*
  *
 * 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/>.
 *
 * See LICENSE.TXT file for more information.
 *
 */
 #if defined _AmxxArch_included
	#endinput
#endif
#define _AmxxArch_included


#if AMXX_VERSION_NUM >= 175
	#pragma reqlib AmxxArch
	#if !defined AMXMODX_NOAUTOLOAD
		#pragma loadlib AmxxArch
	#endif
#else
	#pragma library AmxxArch
#endif


native AA_Unarchive( const filename[] );



/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang11274\\ f0\\ fs16 \n\\ par }
*/


curl.inc:
| Afiseaza codul
#if defined _curl_included
	#endinput
#endif
#define _curl_included

#include <curl_consts>

#if AMXX_VERSION_NUM >= 175
 #pragma reqlib curl
 #if !defined AMXMODX_NOAUTOLOAD
  #pragma loadlib curl
 #endif
#else
 #pragma library curl
#endif

enum _:curl_off_t {
	curl_off_left,
	curl_off_right
}

native curl_easy_escape(const CURL:handle, const url[], escapedUrl[], const len)
native curl_easy_unescape(const CURL:handle, const url[], unescapedUrl[], const len)

native CURL:curl_easy_init()
native void:curl_easy_perform(const CURL:handle, const callbackComplite[], const data[] = {}, const data_len = 0)
native CURLcode:curl_easy_setopt(const CURL:handle, const CURLoption:option, any:...)
native void:curl_easy_cleanup(const CURL:handle)
native void:curl_easy_reset(const CURL:handle)
native CURLcode:curl_easy_getinfo(const CURL:handle, const CURLINFO:info, any:...)
native void:curl_easy_strerror(const CURLcode:code, errorBuf[], const len)

native CURLFORMcode:curl_formadd(&curl_httppost:first, &curl_httppost:last, any:...)
native void:curl_formfree(&curl_httppost:first)

native curl_slist:curl_slist_append(curl_slist:list, buffer[])
native void:curl_slist_free_all(curl_slist:list)

native void:curl_version(buf[], len)
/* AMXX-Studio Notes - DO NOT MODIFY BELOW HERE
*{\\ rtf1\\ ansi\\ deff0{\\ fonttbl{\\ f0\\ fnil Tahoma;}}\n\\ viewkind4\\ uc1\\ pard\\ lang1049\\ f0\\ fs16 \n\\ par }
*/



curl_consts.inc

| Afiseaza codul
#if defined _curlconst_included
	#endinput
#endif
#define _curlconst_included

#define CURL_ERROR_SIZE 256

/*#if defined(WIN32)
#define CURL_SOCKET_BAD (~0)
#else
#define CURL_SOCKET_BAD -1
#endif*/

#define CURLPAUSE_RECV      (1<<0)
#define CURLPAUSE_RECV_CONT (0)

#define CURLPAUSE_SEND      (1<<2)
#define CURLPAUSE_SEND_CONT (0)

#define CURLPAUSE_ALL       (CURLPAUSE_RECV|CURLPAUSE_SEND)
#define CURLPAUSE_CONT      (CURLPAUSE_RECV_CONT|CURLPAUSE_SEND_CONT)

/* CURLPROTO_ defines are for the CURLOPT_*PROTOCOLS options */
#define CURLPROTO_HTTP   (1<<0)
#define CURLPROTO_HTTPS  (1<<1)
#define CURLPROTO_FTP    (1<<2)
#define CURLPROTO_FTPS   (1<<3)
#define CURLPROTO_SCP    (1<<4)
#define CURLPROTO_SFTP   (1<<5)
#define CURLPROTO_TELNET (1<<6)
#define CURLPROTO_LDAP   (1<<7)
#define CURLPROTO_LDAPS  (1<<8)
#define CURLPROTO_DICT   (1<<9)
#define CURLPROTO_FILE   (1<<10)
#define CURLPROTO_TFTP   (1<<11)
#define CURLPROTO_IMAP   (1<<12)
#define CURLPROTO_IMAPS  (1<<13)
#define CURLPROTO_POP3   (1<<14)
#define CURLPROTO_POP3S  (1<<15)
#define CURLPROTO_SMTP   (1<<16)
#define CURLPROTO_SMTPS  (1<<17)
#define CURLPROTO_RTSP   (1<<18)
#define CURLPROTO_RTMP   (1<<19)
#define CURLPROTO_RTMPT  (1<<20)
#define CURLPROTO_RTMPE  (1<<21)
#define CURLPROTO_RTMPTE (1<<22)
#define CURLPROTO_RTMPS  (1<<23)
#define CURLPROTO_RTMPTS (1<<24)
#define CURLPROTO_GOPHER (1<<25)
#define CURLPROTO_ALL    (~0) /* enable everything */

/*
 * Bitmasks for CURLOPT_HTTPAUTH and CURLOPT_PROXYAUTH options:
 *
 * CURLAUTH_NONE         - No HTTP authentication
 * CURLAUTH_BASIC        - HTTP Basic authentication (default)
 * CURLAUTH_DIGEST       - HTTP Digest authentication
 * CURLAUTH_GSSNEGOTIATE - HTTP GSS-Negotiate authentication
 * CURLAUTH_NTLM         - HTTP NTLM authentication
 * CURLAUTH_DIGEST_IE    - HTTP Digest authentication with IE flavour
 * CURLAUTH_NTLM_WB      - HTTP NTLM authentication delegated to winbind helper
 * CURLAUTH_ONLY         - Use together with a single other type to force no
 *                         authentication or just that single type
 * CURLAUTH_ANY          - All fine types set
 * CURLAUTH_ANYSAFE      - All fine types except Basic
 */

#define CURLAUTH_NONE         0
#define CURLAUTH_BASIC        (1<<0)
#define CURLAUTH_DIGEST       (1<<1)
#define CURLAUTH_GSSNEGOTIATE (1<<2)
#define CURLAUTH_NTLM         (1<<3)
#define CURLAUTH_DIGEST_IE    (1<<4)
#define CURLAUTH_NTLM_WB      (1<<5)
#define CURLAUTH_ONLY         (1<<31)
#define CURLAUTH_ANY          (~CURLAUTH_DIGEST_IE)
#define CURLAUTH_ANYSAFE      (~(CURLAUTH_BASIC|CURLAUTH_DIGEST_IE))

#define CURLSSH_AUTH_ANY       ~0     /* all types supported by the server */
#define CURLSSH_AUTH_NONE      0      /* none allowed, silly but complete */
#define CURLSSH_AUTH_PUBLICKEY (1<<0) /* public/private key files */
#define CURLSSH_AUTH_PASSWORD  (1<<1) /* password */
#define CURLSSH_AUTH_HOST      (1<<2) /* host key files */
#define CURLSSH_AUTH_KEYBOARD  (1<<3) /* keyboard interactive */
#define CURLSSH_AUTH_AGENT     (1<<4) /* agent (ssh-agent, pageant...) */
#define CURLSSH_AUTH_DEFAULT CURLSSH_AUTH_ANY

#define CURLGSSAPI_DELEGATION_NONE        0      /* no delegation (default) */
#define CURLGSSAPI_DELEGATION_POLICY_FLAG (1<<0) /* if permitted by policy */
#define CURLGSSAPI_DELEGATION_FLAG        (1<<1) /* delegate always */

/* symbols to use with CURLOPT_POSTREDIR.
   CURL_REDIR_POST_301, CURL_REDIR_POST_302 and CURL_REDIR_POST_303
   can be bitwise ORed so that CURL_REDIR_POST_301 | CURL_REDIR_POST_302
   | CURL_REDIR_POST_303 == CURL_REDIR_POST_ALL */

#define CURL_REDIR_GET_ALL  0
#define CURL_REDIR_POST_301 1
#define CURL_REDIR_POST_302 2
#define CURL_REDIR_POST_303 4
#define CURL_REDIR_POST_ALL \
    (CURL_REDIR_POST_301|CURL_REDIR_POST_302|CURL_REDIR_POST_303)

/* bitmask defines for CURLOPT_HEADEROPT */
#define CURLHEADER_UNIFIED  0
#define CURLHEADER_SEPARATE (1<<0)

  /* Below here follows defines for the CURLOPT_IPRESOLVE option. If a host
     name resolves addresses using more than one IP protocol version, this
     option might be handy to force libcurl to use a specific IP version. */
#define CURL_IPRESOLVE_WHATEVER 0 /* default, resolves addresses to all IP
                                     versions that your system allows */
#define CURL_IPRESOLVE_V4       1 /* resolve to ipv4 addresses */
#define CURL_IPRESOLVE_V6       2 /* resolve to ipv6 addresses */

/* Definition of bits for the CURLOPT_SSL_OPTIONS argument: */

/* - ALLOW_BEAST tells libcurl to allow the BEAST SSL vulnerability in the
   name of improving interoperability with older servers. Some SSL libraries
   have introduced work-arounds for this flaw but those work-arounds sometimes
   make the SSL communication fail. To regain functionality with those broken
   servers, a user can this way allow the vulnerability back. */
#define CURLSSLOPT_ALLOW_BEAST (1<<0)

/* This is a magic return code for the write callback that, when returned,
   will signal libcurl to pause receiving on the current transfer. */
#define CURL_WRITEFUNC_PAUSE 0x10000001

/* This is a return code for the read callback that, when returned, will
   signal libcurl to immediately abort the current transfer. */
#define CURL_READFUNC_ABORT 0x10000000
/* This is a return code for the read callback that, when returned, will
   signal libcurl to pause sending data on the current transfer. */
#define CURL_READFUNC_PAUSE 0x10000001

enum curlioerr {
  CURLIOE_OK,            /* I/O operation successful */
  CURLIOE_UNKNOWNCMD,    /* command was unknown to callback */
  CURLIOE_FAILRESTART,   /* failed to restart the read */
  CURLIOE_LAST           /* never use */
}

enum curliocmd {
  CURLIOCMD_NOP,         /* no operation */
  CURLIOCMD_RESTARTREAD, /* restart the read stream from start */
  CURLIOCMD_LAST         /* never use */
}

enum curlsocktype {
  CURLSOCKTYPE_IPCXN,  /* socket created for a specific IP connection */
  CURLSOCKTYPE_ACCEPT, /* socket created by accept() call */
  CURLSOCKTYPE_LAST    /* never use */
}

/* The return code from the sockopt_callback can signal information back
   to libcurl: */
#define CURL_SOCKOPT_OK 0
#define CURL_SOCKOPT_ERROR 1 /* causes libcurl to abort and return
                                CURLE_ABORTED_BY_CALLBACK */
#define CURL_SOCKOPT_ALREADY_CONNECTED 2


/*
 * Public API enums for RTSP requests
 */
enum {
    CURL_RTSPREQ_NONE, /* first in list */
    CURL_RTSPREQ_OPTIONS,
    CURL_RTSPREQ_DESCRIBE,
    CURL_RTSPREQ_ANNOUNCE,
    CURL_RTSPREQ_SETUP,
    CURL_RTSPREQ_PLAY,
    CURL_RTSPREQ_PAUSE,
    CURL_RTSPREQ_TEARDOWN,
    CURL_RTSPREQ_GET_PARAMETER,
    CURL_RTSPREQ_SET_PARAMETER,
    CURL_RTSPREQ_RECORD,
    CURL_RTSPREQ_RECEIVE,
    CURL_RTSPREQ_LAST /* last in list */
}

enum {
  CURL_SSLVERSION_DEFAULT,
  CURL_SSLVERSION_TLSv1, /* TLS 1.x */
  CURL_SSLVERSION_SSLv2,
  CURL_SSLVERSION_SSLv3,
  CURL_SSLVERSION_TLSv1_0,
  CURL_SSLVERSION_TLSv1_1,
  CURL_SSLVERSION_TLSv1_2,

  CURL_SSLVERSION_LAST /* never use, keep last */
}

  /* These enums are for use with the CURLOPT_HTTP_VERSION option. */
enum {
  CURL_HTTP_VERSION_NONE, /* setting this means we don't care, and that we'd
                             like the library to choose the best possible
                             for us! */
  CURL_HTTP_VERSION_1_0,  /* please use HTTP 1.0 in the request */
  CURL_HTTP_VERSION_1_1,  /* please use HTTP 1.1 in the request */
  CURL_HTTP_VERSION_2_0,  /* please use HTTP 2.0 in the request */

  CURL_HTTP_VERSION_LAST /* *ILLEGAL* http version */
}

  /* These enums are for use with the CURLOPT_NETRC option. */
enum CURL_NETRC_OPTION {
  CURL_NETRC_IGNORED,     /* The .netrc will never be read.
                           * This is the default. */
  CURL_NETRC_OPTIONAL,    /* A user:password in the URL will be preferred
                           * to one in the .netrc. */
  CURL_NETRC_REQUIRED,    /* A user:password in the URL will be ignored.
                           * Unless one is set programmatically, the .netrc
                           * will be queried. */
  CURL_NETRC_LAST
}

enum curl_proxytype {
  CURLPROXY_HTTP = 0,   /* added in 7.10, new in 7.19.4 default is to use
                           CONNECT HTTP/1.1 */
  CURLPROXY_HTTP_1_0 = 1,   /* added in 7.19.4, force to use CONNECT
                               HTTP/1.0  */
  CURLPROXY_SOCKS4 = 4, /* support added in 7.15.2, enum existed already
                           in 7.10 */
  CURLPROXY_SOCKS5 = 5, /* added in 7.10 */
  CURLPROXY_SOCKS4A = 6, /* added in 7.18.0 */
  CURLPROXY_SOCKS5_HOSTNAME = 7 /* Use the SOCKS5 protocol but pass along the
                                   host name rather than the IP address. added
                                   in 7.18.0 */
}  /* this enum was added in 7.10 */

enum curl_infotype {
   CURLINFO_TEXT = 0,
   CURLINFO_HEADER_IN,    /* 1 */
   CURLINFO_HEADER_OUT,   /* 2 */
   CURLINFO_DATA_IN,      /* 3 */
   CURLINFO_DATA_OUT,     /* 4 */
   CURLINFO_SSL_DATA_IN,  /* 5 */
   CURLINFO_SSL_DATA_OUT, /* 6 */
   CURLINFO_END
}

/* use this for multipart formpost building */
/* Returns code for curl_formadd()
 *
 * Returns:
 * CURL_FORMADD_OK             on success
 * CURL_FORMADD_MEMORY         if the FormInfo allocation fails
 * CURL_FORMADD_OPTION_TWICE   if one option is given twice for one Form
 * CURL_FORMADD_NULL           if a null pointer was given for a char
 * CURL_FORMADD_MEMORY         if the allocation of a FormInfo struct failed
 * CURL_FORMADD_UNKNOWN_OPTION if an unknown option was used
 * CURL_FORMADD_INCOMPLETE     if the some FormInfo is not complete (or error)
 * CURL_FORMADD_MEMORY         if a curl_httppost struct cannot be allocated
 * CURL_FORMADD_MEMORY         if some allocation for string copying failed.
 * CURL_FORMADD_ILLEGAL_ARRAY  if an illegal option is used in an array
 *
 ***************************************************************************/
enum CURLFORMcode {
  CURL_FORMADD_OK, /* first, no error */

  CURL_FORMADD_MEMORY,
  CURL_FORMADD_OPTION_TWICE,
  CURL_FORMADD_NULL,
  CURL_FORMADD_UNKNOWN_OPTION,
  CURL_FORMADD_INCOMPLETE,
  CURL_FORMADD_ILLEGAL_ARRAY,
  CURL_FORMADD_DISABLED, /* libcurl was built with this disabled */

  CURL_FORMADD_LAST /* last */
}

/* parameter for the CURLOPT_FTP_FILEMETHOD option */
enum curl_ftpmethod {
  CURLFTPMETHOD_DEFAULT,   /* let libcurl pick */
  CURLFTPMETHOD_MULTICWD,  /* single CWD operation for each path part */
  CURLFTPMETHOD_NOCWD,     /* no CWD at all */
  CURLFTPMETHOD_SINGLECWD, /* one CWD to full dir, then work on file */
  CURLFTPMETHOD_LAST       /* not an option, never use */
}

/* parameter for the CURLOPT_FTP_SSL_CCC option */
enum curl_ftpccc {
  CURLFTPSSL_CCC_NONE,    /* do not send CCC */
  CURLFTPSSL_CCC_PASSIVE, /* Let the server initiate the shutdown */
  CURLFTPSSL_CCC_ACTIVE,  /* Initiate the shutdown */
  CURLFTPSSL_CCC_LAST     /* not an option, never use */
}

/* parameter for the CURLOPT_FTPSSLAUTH option */
enum curl_ftpauth {
  CURLFTPAUTH_DEFAULT, /* let libcurl decide */
  CURLFTPAUTH_SSL,     /* use "AUTH SSL" */
  CURLFTPAUTH_TLS,     /* use "AUTH TLS" */
  CURLFTPAUTH_LAST /* not an option, never use */
}

/* parameter for the CURLOPT_FTP_CREATE_MISSING_DIRS option */
enum curl_ftpcreatedir {
  CURLFTP_CREATE_DIR_NONE,  /* do NOT create missing dirs! */
  CURLFTP_CREATE_DIR,       /* (FTP/SFTP) if CWD fails, try MKD and then CWD
                               again if MKD succeeded, for SFTP this does
                               similar magic */
  CURLFTP_CREATE_DIR_RETRY, /* (FTP only) if CWD fails, try MKD and then CWD
                               again even if MKD failed! */
  CURLFTP_CREATE_DIR_LAST   /* not an option, never use */
}

/* parameter for the CURLOPT_USE_SSL option */
enum curl_usessl {
  CURLUSESSL_NONE,    /* do not attempt to use SSL */
  CURLUSESSL_TRY,     /* try using SSL, proceed anyway otherwise */
  CURLUSESSL_CONTROL, /* SSL for the control connection or fail */
  CURLUSESSL_ALL,     /* SSL for all communication or fail */
  CURLUSESSL_LAST     /* not an option, never use */
}

#define CFINIT(%0) CURLFORM_%0
enum CURLformoption {
  CFINIT(NOTHING),        /********* the first one is unused ************/

  /*  */
  CFINIT(COPYNAME),
  CFINIT(PTRNAME),
  CFINIT(NAMELENGTH),
  CFINIT(COPYCONTENTS),
  CFINIT(PTRCONTENTS),
  CFINIT(CONTENTSLENGTH),
  CFINIT(FILECONTENT),
  CFINIT(ARRAY),
  CFINIT(OBSOLETE),
  CFINIT(FILE),

  CFINIT(BUFFER),
  CFINIT(BUFFERPTR),
  CFINIT(BUFFERLENGTH),

  CFINIT(CONTENTTYPE),
  CFINIT(CONTENTHEADER),
  CFINIT(FILENAME),
  CFINIT(END),
  CFINIT(OBSOLETE2),

  CFINIT(STREAM),

  CURLFORM_LASTENTRY /* the last unused */
}

#undef CFINIT /* done */

enum CURLcode {
  CURLE_OK = 0,
  CURLE_UNSUPPORTED_PROTOCOL,    /* 1 */
  CURLE_FAILED_INIT,             /* 2 */
  CURLE_URL_MALFORMAT,           /* 3 */
  CURLE_NOT_BUILT_IN,            /* 4 - [was obsoleted in August 2007 for
                                    7.17.0, reused in April 2011 for 7.21.5] */
  CURLE_COULDNT_RESOLVE_PROXY,   /* 5 */
  CURLE_COULDNT_RESOLVE_HOST,    /* 6 */
  CURLE_COULDNT_CONNECT,         /* 7 */
  CURLE_FTP_WEIRD_SERVER_REPLY,  /* 8 */
  CURLE_REMOTE_ACCESS_DENIED,    /* 9 a service was denied by the server
                                    due to lack of access - when login fails
                                    this is not returned. */
  CURLE_FTP_ACCEPT_FAILED,       /* 10 - [was obsoleted in April 2006 for
                                    7.15.4, reused in Dec 2011 for 7.24.0]*/
  CURLE_FTP_WEIRD_PASS_REPLY,    /* 11 */
  CURLE_FTP_ACCEPT_TIMEOUT,      /* 12 - timeout occurred accepting server
                                    [was obsoleted in August 2007 for 7.17.0,
                                    reused in Dec 2011 for 7.24.0]*/
  CURLE_FTP_WEIRD_PASV_REPLY,    /* 13 */
  CURLE_FTP_WEIRD_227_FORMAT,    /* 14 */
  CURLE_FTP_CANT_GET_HOST,       /* 15 */
  CURLE_OBSOLETE16,              /* 16 - NOT USED */
  CURLE_FTP_COULDNT_SET_TYPE,    /* 17 */
  CURLE_PARTIAL_FILE,            /* 18 */
  CURLE_FTP_COULDNT_RETR_FILE,   /* 19 */
  CURLE_OBSOLETE20,              /* 20 - NOT USED */
  CURLE_QUOTE_ERROR,             /* 21 - quote command failure */
  CURLE_HTTP_RETURNED_ERROR,     /* 22 */
  CURLE_WRITE_ERROR,             /* 23 */
  CURLE_OBSOLETE24,              /* 24 - NOT USED */
  CURLE_UPLOAD_FAILED,           /* 25 - failed upload "command" */
  CURLE_READ_ERROR,              /* 26 - couldn't open/read from file */
  CURLE_OUT_OF_MEMORY,           /* 27 */
  /* Note: CURLE_OUT_OF_MEMORY may sometimes indicate a conversion error
           instead of a memory allocation error if CURL_DOES_CONVERSIONS
           is defined
  */
  CURLE_OPERATION_TIMEDOUT,      /* 28 - the timeout time was reached */
  CURLE_OBSOLETE29,              /* 29 - NOT USED */
  CURLE_FTP_PORT_FAILED,         /* 30 - FTP PORT operation failed */
  CURLE_FTP_COULDNT_USE_REST,    /* 31 - the REST command failed */
  CURLE_OBSOLETE32,              /* 32 - NOT USED */
  CURLE_RANGE_ERROR,             /* 33 - RANGE "command" didn't work */
  CURLE_HTTP_POST_ERROR,         /* 34 */
  CURLE_SSL_CONNECT_ERROR,       /* 35 - wrong when connecting with SSL */
  CURLE_BAD_DOWNLOAD_RESUME,     /* 36 - couldn't resume download */
  CURLE_FILE_COULDNT_READ_FILE,  /* 37 */
  CURLE_LDAP_CANNOT_BIND,        /* 38 */
  CURLE_LDAP_SEARCH_FAILED,      /* 39 */
  CURLE_OBSOLETE40,              /* 40 - NOT USED */
  CURLE_FUNCTION_NOT_FOUND,      /* 41 */
  CURLE_ABORTED_BY_CALLBACK,     /* 42 */
  CURLE_BAD_FUNCTION_ARGUMENT,   /* 43 */
  CURLE_OBSOLETE44,              /* 44 - NOT USED */
  CURLE_INTERFACE_FAILED,        /* 45 - CURLOPT_INTERFACE failed */
  CURLE_OBSOLETE46,              /* 46 - NOT USED */
  CURLE_TOO_MANY_REDIRECTS ,     /* 47 - catch endless re-direct loops */
  CURLE_UNKNOWN_OPTION,          /* 48 - User specified an unknown option */
  CURLE_TELNET_OPTION_SYNTAX ,   /* 49 - Malformed telnet option */
  CURLE_OBSOLETE50,              /* 50 - NOT USED */
  CURLE_PEER_FAILED_VERIFICATION, /* 51 - peer's certificate or fingerprint
                                     wasn't verified fine */
  CURLE_GOT_NOTHING,             /* 52 - when this is a specific error */
  CURLE_SSL_ENGINE_NOTFOUND,     /* 53 - SSL crypto engine not found */
  CURLE_SSL_ENGINE_SETFAILED,    /* 54 - can not set SSL crypto engine as
                                    default */
  CURLE_SEND_ERROR,              /* 55 - failed sending network data */
  CURLE_RECV_ERROR,              /* 56 - failure in receiving network data */
  CURLE_OBSOLETE57,              /* 57 - NOT IN USE */
  CURLE_SSL_CERTPROBLEM,         /* 58 - problem with the local certificate */
  CURLE_SSL_CIPHER,              /* 59 - couldn't use specified cipher */
  CURLE_SSL_CACERT,              /* 60 - problem with the CA cert (path?) */
  CURLE_BAD_CONTENT_ENCODING,    /* 61 - Unrecognized/bad encoding */
  CURLE_LDAP_INVALID_URL,        /* 62 - Invalid LDAP URL */
  CURLE_FILESIZE_EXCEEDED,       /* 63 - Maximum file size exceeded */
  CURLE_USE_SSL_FAILED,          /* 64 - Requested FTP SSL level failed */
  CURLE_SEND_FAIL_REWIND,        /* 65 - Sending the data requires a rewind
                                    that failed */
  CURLE_SSL_ENGINE_INITFAILED,   /* 66 - failed to initialise ENGINE */
  CURLE_LOGIN_DENIED,            /* 67 - user, password or similar was not
                                    accepted and we failed to login */
  CURLE_TFTP_NOTFOUND,           /* 68 - file not found on server */
  CURLE_TFTP_PERM,               /* 69 - permission problem on server */
  CURLE_REMOTE_DISK_FULL,        /* 70 - out of disk space on server */
  CURLE_TFTP_ILLEGAL,            /* 71 - Illegal TFTP operation */
  CURLE_TFTP_UNKNOWNID,          /* 72 - Unknown transfer ID */
  CURLE_REMOTE_FILE_EXISTS,      /* 73 - File already exists */
  CURLE_TFTP_NOSUCHUSER,         /* 74 - No such user */
  CURLE_CONV_FAILED,             /* 75 - conversion failed */
  CURLE_CONV_REQD,               /* 76 - caller must register conversion
                                    callbacks using curl_easy_setopt options
                                    CURLOPT_CONV_FROM_NETWORK_FUNCTION,
                                    CURLOPT_CONV_TO_NETWORK_FUNCTION, and
                                    CURLOPT_CONV_FROM_UTF8_FUNCTION */
  CURLE_SSL_CACERT_BADFILE,      /* 77 - could not load CACERT file, missing
                                    or wrong format */
  CURLE_REMOTE_FILE_NOT_FOUND,   /* 78 - remote file not found */
  CURLE_SSH,                     /* 79 - error from the SSH layer, somewhat
                                    generic so the error message will be of
                                    interest when this has happened */

  CURLE_SSL_SHUTDOWN_FAILED,     /* 80 - Failed to shut down the SSL
                                    connection */
  CURLE_AGAIN,                   /* 81 - socket is not ready for send/recv,
                                    wait till it's ready and try again (Added
                                    in 7.18.2) */
  CURLE_SSL_CRL_BADFILE,         /* 82 - could not load CRL file, missing or
                                    wrong format (Added in 7.19.0) */
  CURLE_SSL_ISSUER_ERROR,        /* 83 - Issuer check failed.  (Added in
                                    7.19.0) */
  CURLE_FTP_PRET_FAILED,         /* 84 - a PRET command failed */
  CURLE_RTSP_CSEQ_ERROR,         /* 85 - mismatch of RTSP CSeq numbers */
  CURLE_RTSP_SESSION_ERROR,      /* 86 - mismatch of RTSP Session Ids */
  CURLE_FTP_BAD_FILE_LIST,       /* 87 - unable to parse FTP file list */
  CURLE_CHUNK_FAILED,            /* 88 - chunk callback reported error */
  CURLE_NO_CONNECTION_AVAILABLE, /* 89 - No connection available, the
                                    session will be queued */
  CURL_LAST /* never use! */
}


#define CURLINFO_STRING   0x100000
#define CURLINFO_LONG     0x200000
#define CURLINFO_DOUBLE   0x300000
#define CURLINFO_SLIST    0x400000
#define CURLINFO_MASK     0x0fffff
#define CURLINFO_TYPEMASK 0xf00000

enum CURLINFO {
  CURLINFO_NONE, /* first, never use this */
  CURLINFO_EFFECTIVE_URL    = CURLINFO_STRING + 1,
  CURLINFO_RESPONSE_CODE    = CURLINFO_LONG   + 2,
  CURLINFO_TOTAL_TIME       = CURLINFO_DOUBLE + 3,
  CURLINFO_NAMELOOKUP_TIME  = CURLINFO_DOUBLE + 4,
  CURLINFO_CONNECT_TIME     = CURLINFO_DOUBLE + 5,
  CURLINFO_PRETRANSFER_TIME = CURLINFO_DOUBLE + 6,
  CURLINFO_SIZE_UPLOAD      = CURLINFO_DOUBLE + 7,
  CURLINFO_SIZE_DOWNLOAD    = CURLINFO_DOUBLE + 8,
  CURLINFO_SPEED_DOWNLOAD   = CURLINFO_DOUBLE + 9,
  CURLINFO_SPEED_UPLOAD     = CURLINFO_DOUBLE + 10,
  CURLINFO_HEADER_SIZE      = CURLINFO_LONG   + 11,
  CURLINFO_REQUEST_SIZE     = CURLINFO_LONG   + 12,
  CURLINFO_SSL_VERIFYRESULT = CURLINFO_LONG   + 13,
  CURLINFO_FILETIME         = CURLINFO_LONG   + 14,
  CURLINFO_CONTENT_LENGTH_DOWNLOAD   = CURLINFO_DOUBLE + 15,
  CURLINFO_CONTENT_LENGTH_UPLOAD     = CURLINFO_DOUBLE + 16,
  CURLINFO_STARTTRANSFER_TIME = CURLINFO_DOUBLE + 17,
  CURLINFO_CONTENT_TYPE     = CURLINFO_STRING + 18,
  CURLINFO_REDIRECT_TIME    = CURLINFO_DOUBLE + 19,
  CURLINFO_REDIRECT_COUNT   = CURLINFO_LONG   + 20,
  CURLINFO_PRIVATE          = CURLINFO_STRING + 21,
  CURLINFO_HTTP_CONNECTCODE = CURLINFO_LONG   + 22,
  CURLINFO_HTTPAUTH_AVAIL   = CURLINFO_LONG   + 23,
  CURLINFO_PROXYAUTH_AVAIL  = CURLINFO_LONG   + 24,
  CURLINFO_OS_ERRNO         = CURLINFO_LONG   + 25,
  CURLINFO_NUM_CONNECTS     = CURLINFO_LONG   + 26,
  CURLINFO_SSL_ENGINES      = CURLINFO_SLIST  + 27,
  CURLINFO_COOKIELIST       = CURLINFO_SLIST  + 28,
  CURLINFO_LASTSOCKET       = CURLINFO_LONG   + 29,
  CURLINFO_FTP_ENTRY_PATH   = CURLINFO_STRING + 30,
  CURLINFO_REDIRECT_URL     = CURLINFO_STRING + 31,
  CURLINFO_PRIMARY_IP       = CURLINFO_STRING + 32,
  CURLINFO_APPCONNECT_TIME  = CURLINFO_DOUBLE + 33,
  CURLINFO_CERTINFO         = CURLINFO_SLIST  + 34,
  CURLINFO_CONDITION_UNMET  = CURLINFO_LONG   + 35,
  CURLINFO_RTSP_SESSION_ID  = CURLINFO_STRING + 36,
  CURLINFO_RTSP_CLIENT_CSEQ = CURLINFO_LONG   + 37,
  CURLINFO_RTSP_SERVER_CSEQ = CURLINFO_LONG   + 38,
  CURLINFO_RTSP_CSEQ_RECV   = CURLINFO_LONG   + 39,
  CURLINFO_PRIMARY_PORT     = CURLINFO_LONG   + 40,
  CURLINFO_LOCAL_IP         = CURLINFO_STRING + 41,
  CURLINFO_LOCAL_PORT       = CURLINFO_LONG   + 42,
  CURLINFO_TLS_SESSION      = CURLINFO_SLIST  + 43,
  /* Fill in new entries below here! */

  CURLINFO_LASTONE          = 43
}

#define CURLOPTTYPE_LONG          0
#define CURLOPTTYPE_OBJECTPOINT   10000
#define CURLOPTTYPE_FUNCTIONPOINT 20000
#define CURLOPTTYPE_OFF_T         30000

#define LONG          CURLOPTTYPE_LONG
#define OBJECTPOINT   CURLOPTTYPE_OBJECTPOINT
#define FUNCTIONPOINT CURLOPTTYPE_FUNCTIONPOINT
#define OFF_T         CURLOPTTYPE_OFF_T

#define CINIT(%0,%1,%2) CURLOPT_%0 = %1 + %2

enum CURLoption {
  /* This is the FILE * or void * the regular output should be written to. */
  CINIT(WRITEDATA, OBJECTPOINT, 1),

  /* The full URL to get/put */
  CINIT(URL,  OBJECTPOINT, 2),

  /* Port number to connect to, if other than default. */
  CINIT(PORT, LONG, 3),

  /* Name of proxy to use. */
  CINIT(PROXY, OBJECTPOINT, 4),

  /* "user:password;options" to use when fetching. */
  CINIT(USERPWD, OBJECTPOINT, 5),

  /* "user:password" to use with proxy. */
  CINIT(PROXYUSERPWD, OBJECTPOINT, 6),

  /* Range to get, specified as an ASCII string. */
  CINIT(RANGE, OBJECTPOINT, 7),

  /* not used */

  /* Specified file stream to upload from (use as input): */
  CINIT(READDATA, OBJECTPOINT, 9),

  /* Buffer to receive error messages in, must be at least CURL_ERROR_SIZE
   * bytes big. If this is not used, error messages go to stderr instead: */
  CINIT(ERRORBUFFER, OBJECTPOINT, 10),

  /* Function that will be called to store the output (instead of fwrite). The
   * parameters will use fwrite() syntax, make sure to follow them. */
  CINIT(WRITEFUNCTION, FUNCTIONPOINT, 11),

  /* Function that will be called to read the input (instead of fread). The
   * parameters will use fread() syntax, make sure to follow them. */
  CINIT(READFUNCTION, FUNCTIONPOINT, 12),

  /* Time-out the read operation after this amount of seconds */
  CINIT(TIMEOUT, LONG, 13),

  /* If the CURLOPT_INFILE is used, this can be used to inform libcurl about
   * how large the file being sent really is. That allows better error
   * checking and better verifies that the upload was successful. -1 means
   * unknown size.
   *
   * For large file support, there is also a _LARGE version of the key
   * which takes an off_t type, allowing platforms with larger off_t
   * sizes to handle larger files.  See below for INFILESIZE_LARGE.
   */
  CINIT(INFILESIZE, LONG, 14),

  /* POST static input fields. */
  CINIT(POSTFIELDS, OBJECTPOINT, 15),

  /* Set the referrer page (needed by some CGIs) */
  CINIT(REFERER, OBJECTPOINT, 16),

  /* Set the FTP PORT string (interface name, named or numerical IP address)
     Use i.e '-' to use default address. */
  CINIT(FTPPORT, OBJECTPOINT, 17),

  /* Set the User-Agent string (examined by some CGIs) */
  CINIT(USERAGENT, OBJECTPOINT, 18),

  /* If the download receives less than "low speed limit" bytes/second
   * during "low speed time" seconds, the operations is aborted.
   * You could i.e if you have a pretty high speed connection, abort if
   * it is less than 2000 bytes/sec during 20 seconds.
   */

  /* Set the "low speed limit" */
  CINIT(LOW_SPEED_LIMIT, LONG, 19),

  /* Set the "low speed time" */
  CINIT(LOW_SPEED_TIME, LONG, 20),

  /* Set the continuation offset.
   *
   * Note there is also a _LARGE version of this key which uses
   * off_t types, allowing for large file offsets on platforms which
   * use larger-than-32-bit off_t's.  Look below for RESUME_FROM_LARGE.
   */
  CINIT(RESUME_FROM, LONG, 21),

  /* Set cookie in request: */
  CINIT(COOKIE, OBJECTPOINT, 22),

  /* This points to a linked list of headers, struct curl_slist kind. This
     list is also used for RTSP (in spite of its name) */
  CINIT(HTTPHEADER, OBJECTPOINT, 23),

  /* This points to a linked list of post entries, struct curl_httppost */
  CINIT(HTTPPOST, OBJECTPOINT, 24),

  /* name of the file keeping your private SSL-certificate */
  CINIT(SSLCERT, OBJECTPOINT, 25),

  /* password for the SSL or SSH private key */
  CINIT(KEYPASSWD, OBJECTPOINT, 26),

  /* send TYPE parameter? */
  CINIT(CRLF, LONG, 27),

  /* send linked-list of QUOTE commands */
  CINIT(QUOTE, OBJECTPOINT, 28),

  /* send FILE * or void * to store headers to, if you use a callback it
     is simply passed to the callback unmodified */
  CINIT(HEADERDATA, OBJECTPOINT, 29),

  /* point to a file to read the initial cookies from, also enables
     "cookie awareness" */
  CINIT(COOKIEFILE, OBJECTPOINT, 31),

  /* What version to specifically try to use.
     See CURL_SSLVERSION defines below. */
  CINIT(SSLVERSION, LONG, 32),

  /* What kind of HTTP time condition to use, see defines */
  CINIT(TIMECONDITION, LONG, 33),

  /* Time to use with the above condition. Specified in number of seconds
     since 1 Jan 1970 */
  CINIT(TIMEVALUE, LONG, 34),

  /* 35 = OBSOLETE */

  /* Custom request, for customizing the get command like
     HTTP: DELETE, TRACE and others
     FTP: to use a different list command
     */
  CINIT(CUSTOMREQUEST, OBJECTPOINT, 36),

  /* HTTP request, for odd commands like DELETE, TRACE and others */
  CINIT(STDERR, OBJECTPOINT, 37),

  /* 38 is not used */

  /* send linked-list of post-transfer QUOTE commands */
  CINIT(POSTQUOTE, OBJECTPOINT, 39),

  CINIT(OBSOLETE40, OBJECTPOINT, 40), /* OBSOLETE, do not use! */

  CINIT(VERBOSE, LONG, 41),      /* talk a lot */
  CINIT(HEADER, LONG, 42),       /* throw the header out too */
  CINIT(NOPROGRESS, LONG, 43),   /* shut off the progress meter */
  CINIT(NOBODY, LONG, 44),       /* use HEAD to get http document */
  CINIT(FAILONERROR, LONG, 45),  /* no output on http error codes >= 300 */
  CINIT(UPLOAD, LONG, 46),       /* this is an upload */
  CINIT(POST, LONG, 47),         /* HTTP POST method */
  CINIT(DIRLISTONLY, LONG, 48),  /* bare names when listing directories */

  CINIT(APPEND, LONG, 50),       /* Append instead of overwrite on upload! */

  /* Specify whether to read the user+password from the .netrc or the URL.
   * This must be one of the CURL_NETRC_* enums below. */
  CINIT(NETRC, LONG, 51),

  CINIT(FOLLOWLOCATION, LONG, 52),  /* use Location: Luke! */

  CINIT(TRANSFERTEXT, LONG, 53), /* transfer data in text/ASCII format */
  CINIT(PUT, LONG, 54),          /* HTTP PUT */

  /* 55 = OBSOLETE */

  /* DEPRECATED
   * Function that will be called instead of the internal progress display
   * function. This function should be defined as the curl_progress_callback
   * prototype defines. */
  CINIT(PROGRESSFUNCTION, FUNCTIONPOINT, 56),

  /* Data passed to the CURLOPT_PROGRESSFUNCTION and CURLOPT_XFERINFOFUNCTION
     callbacks */
  CINIT(PROGRESSDATA, OBJECTPOINT, 57),
#define CURLOPT_XFERINFODATA CURLOPT_PROGRESSDATA

  /* We want the referrer field set automatically when following locations */
  CINIT(AUTOREFERER, LONG, 58),

  /* Port of the proxy, can be set in the proxy string as well with:
     "[host]:[port]" */
  CINIT(PROXYPORT, LONG, 59),

  /* size of the POST input data, if strlen() is not good to use */
  CINIT(POSTFIELDSIZE, LONG, 60),

  /* tunnel non-http operations through a HTTP proxy */
  CINIT(HTTPPROXYTUNNEL, LONG, 61),

  /* Set the interface string to use as outgoing network interface */
  CINIT(INTERFACE, OBJECTPOINT, 62),

  /* Set the krb4/5 security level, this also enables krb4/5 awareness.  This
   * is a string, 'clear', 'safe', 'confidential' or 'private'.  If the string
   * is set but doesn't match one of these, 'private' will be used.  */
  CINIT(KRBLEVEL, OBJECTPOINT, 63),

  /* Set if we should verify the peer in ssl handshake, set 1 to verify. */
  CINIT(SSL_VERIFYPEER, LONG, 64),

  /* The CApath or CAfile used to validate the peer certificate
     this option is used only if SSL_VERIFYPEER is true */
  CINIT(CAINFO, OBJECTPOINT, 65),

  /* 66 = OBSOLETE */
  /* 67 = OBSOLETE */

  /* Maximum number of http redirects to follow */
  CINIT(MAXREDIRS, LONG, 68),

  /* Pass a long set to 1 to get the date of the requested document (if
     possible)! Pass a zero to shut it off. */
  CINIT(FILETIME, LONG, 69),

  /* This points to a linked list of telnet options */
  CINIT(TELNETOPTIONS, OBJECTPOINT, 70),

  /* Max amount of cached alive connections */
  CINIT(MAXCONNECTS, LONG, 71),

  CINIT(OBSOLETE72, LONG, 72), /* OBSOLETE, do not use! */

  /* 73 = OBSOLETE */

  /* Set to explicitly use a new connection for the upcoming transfer.
     Do not use this unless you're absolutely sure of this, as it makes the
     operation slower and is less friendly for the network. */
  CINIT(FRESH_CONNECT, LONG, 74),

  /* Set to explicitly forbid the upcoming transfer's connection to be re-used
     when done. Do not use this unless you're absolutely sure of this, as it
     makes the operation slower and is less friendly for the network. */
  CINIT(FORBID_REUSE, LONG, 75),

  /* Set to a file name that contains random data for libcurl to use to
     seed the random engine when doing SSL connects. */
  CINIT(RANDOM_FILE, OBJECTPOINT, 76),

  /* Set to the Entropy Gathering Daemon socket pathname */
  CINIT(EGDSOCKET, OBJECTPOINT, 77),

  /* Time-out connect operations after this amount of seconds, if connects are
     OK within this time, then fine... This only aborts the connect phase. */
  CINIT(CONNECTTIMEOUT, LONG, 78),

  /* Function that will be called to store headers (instead of fwrite). The
   * parameters will use fwrite() syntax, make sure to follow them. */
  CINIT(HEADERFUNCTION, FUNCTIONPOINT, 79),

  /* Set this to force the HTTP request to get back to GET. Only really usable
     if POST, PUT or a custom request have been used first.
   */
  CINIT(HTTPGET, LONG, 80),

  /* Set if we should verify the Common name from the peer certificate in ssl
   * handshake, set 1 to check existence, 2 to ensure that it matches the
   * provided hostname. */
  CINIT(SSL_VERIFYHOST, LONG, 81),

  /* Specify which file name to write all known cookies in after completed
     operation. Set file name to "-" (dash) to make it go to stdout. */
  CINIT(COOKIEJAR, OBJECTPOINT, 82),

  /* Specify which SSL ciphers to use */
  CINIT(SSL_CIPHER_LIST, OBJECTPOINT, 83),

  /* Specify which HTTP version to use! This must be set to one of the
     CURL_HTTP_VERSION* enums set below. */
  CINIT(HTTP_VERSION, LONG, 84),

  /* Specifically switch on or off the FTP engine's use of the EPSV command. By
     default, that one will always be attempted before the more traditional
     PASV command. */
  CINIT(FTP_USE_EPSV, LONG, 85),

  /* type of the file keeping your SSL-certificate ("DER", "PEM", "ENG") */
  CINIT(SSLCERTTYPE, OBJECTPOINT, 86),

  /* name of the file keeping your private SSL-key */
  CINIT(SSLKEY, OBJECTPOINT, 87),

  /* type of the file keeping your private SSL-key ("DER", "PEM", "ENG") */
  CINIT(SSLKEYTYPE, OBJECTPOINT, 88),

  /* crypto engine for the SSL-sub system */
  CINIT(SSLENGINE, OBJECTPOINT, 89),

  /* set the crypto engine for the SSL-sub system as default
     the param has no meaning...
   */
  CINIT(SSLENGINE_DEFAULT, LONG, 90),

  /* Non-zero value means to use the global dns cache */
  CINIT(DNS_USE_GLOBAL_CACHE, LONG, 91), /* DEPRECATED, do not use! */

  /* DNS cache timeout */
  CINIT(DNS_CACHE_TIMEOUT, LONG, 92),

  /* send linked-list of pre-transfer QUOTE commands */
  CINIT(PREQUOTE, OBJECTPOINT, 93),

  /* set the debug function */
  CINIT(DEBUGFUNCTION, FUNCTIONPOINT, 94),

  /* set the data for the debug function */
  CINIT(DEBUGDATA, OBJECTPOINT, 95),

  /* mark this as start of a cookie session */
  CINIT(COOKIESESSION, LONG, 96),

  /* The CApath directory used to validate the peer certificate
     this option is used only if SSL_VERIFYPEER is true */
  CINIT(CAPATH, OBJECTPOINT, 97),

  /* Instruct libcurl to use a smaller receive buffer */
  CINIT(BUFFERSIZE, LONG, 98),

  /* Instruct libcurl to not use any signal/alarm handlers, even when using
     timeouts. This option is useful for multi-threaded applications.
     See libcurl-the-guide for more background information. */
  CINIT(NOSIGNAL, LONG, 99),

  /* Provide a CURLShare for mutexing non-ts data */
  CINIT(SHARE, OBJECTPOINT, 100),

  /* indicates type of proxy. accepted values are CURLPROXY_HTTP (default),
     CURLPROXY_SOCKS4, CURLPROXY_SOCKS4A and CURLPROXY_SOCKS5. */
  CINIT(PROXYTYPE, LONG, 101),

  /* Set the Accept-Encoding string. Use this to tell a server you would like
     the response to be compressed. Before 7.21.6, this was known as
     CURLOPT_ENCODING */
  CINIT(ACCEPT_ENCODING, OBJECTPOINT, 102),

  /* Set pointer to private data */
  CINIT(PRIVATE, OBJECTPOINT, 103),

  /* Set aliases for HTTP 200 in the HTTP Response header */
  CINIT(HTTP200ALIASES, OBJECTPOINT, 104),

  /* Continue to send authentication (user+password) when following locations,
     even when hostname changed. This can potentially send off the name
     and password to whatever host the server decides. */
  CINIT(UNRESTRICTED_AUTH, LONG, 105),

  /* Specifically switch on or off the FTP engine's use of the EPRT command (
     it also disables the LPRT attempt). By default, those ones will always be
     attempted before the good old traditional PORT command. */
  CINIT(FTP_USE_EPRT, LONG, 106),

  /* Set this to a bitmask value to enable the particular authentications
     methods you like. Use this in combination with CURLOPT_USERPWD.
     Note that setting multiple bits may cause extra network round-trips. */
  CINIT(HTTPAUTH, LONG, 107),

  /* Set the ssl context callback function, currently only for OpenSSL ssl_ctx
     in second argument. The function must be matching the
     curl_ssl_ctx_callback proto. */
  CINIT(SSL_CTX_FUNCTION, FUNCTIONPOINT, 108),

  /* Set the userdata for the ssl context callback function's third
     argument */
  CINIT(SSL_CTX_DATA, OBJECTPOINT, 109),

  /* FTP Option that causes missing dirs to be created on the remote server.
     In 7.19.4 we introduced the convenience enums for this option using the
     CURLFTP_CREATE_DIR prefix.
  */
  CINIT(FTP_CREATE_MISSING_DIRS, LONG, 110),

  /* Set this to a bitmask value to enable the particular authentications
     methods you like. Use this in combination with CURLOPT_PROXYUSERPWD.
     Note that setting multiple bits may cause extra network round-trips. */
  CINIT(PROXYAUTH, LONG, 111),

  /* FTP option that changes the timeout, in seconds, associated with
     getting a response.  This is different from transfer timeout time and
     essentially places a demand on the FTP server to acknowledge commands
     in a timely manner. */
  CINIT(FTP_RESPONSE_TIMEOUT, LONG, 112),
#define CURLOPT_SERVER_RESPONSE_TIMEOUT CURLOPT_FTP_RESPONSE_TIMEOUT

  /* Set this option to one of the CURL_IPRESOLVE_* defines (see below) to
     tell libcurl to resolve names to those IP versions only. This only has
     affect on systems with support for more than one, i.e IPv4 _and_ IPv6. */
  CINIT(IPRESOLVE, LONG, 113),

  /* Set this option to limit the size of a file that will be downloaded from
     an HTTP or FTP server.

     Note there is also _LARGE version which adds large file support for
     platforms which have larger off_t sizes.  See MAXFILESIZE_LARGE below. */
  CINIT(MAXFILESIZE, LONG, 114),

  /* See the comment for INFILESIZE above, but in short, specifies
   * the size of the file being uploaded.  -1 means unknown.
   */
  CINIT(INFILESIZE_LARGE, OFF_T, 115),

  /* Sets the continuation offset.  There is also a LONG version of this;
   * look above for RESUME_FROM.
   */
  CINIT(RESUME_FROM_LARGE, OFF_T, 116),

  /* Sets the maximum size of data that will be downloaded from
   * an HTTP or FTP server.  See MAXFILESIZE above for the LONG version.
   */
  CINIT(MAXFILESIZE_LARGE, OFF_T, 117),

  /* Set this option to the file name of your .netrc file you want libcurl
     to parse (using the CURLOPT_NETRC option). If not set, libcurl will do
     a poor attempt to find the user's home directory and check for a .netrc
     file in there. */
  CINIT(NETRC_FILE, OBJECTPOINT, 118),

  /* Enable SSL/TLS for FTP, pick one of:
     CURLUSESSL_TRY     - try using SSL, proceed anyway otherwise
     CURLUSESSL_CONTROL - SSL for the control connection or fail
     CURLUSESSL_ALL     - SSL for all communication or fail
  */
  CINIT(USE_SSL, LONG, 119),

  /* The _LARGE version of the standard POSTFIELDSIZE option */
  CINIT(POSTFIELDSIZE_LARGE, OFF_T, 120),

  /* Enable/disable the TCP Nagle algorithm */
  CINIT(TCP_NODELAY, LONG, 121),

  /* 122 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
  /* 123 OBSOLETE. Gone in 7.16.0 */
  /* 124 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
  /* 125 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
  /* 126 OBSOLETE, used in 7.12.3. Gone in 7.13.0 */
  /* 127 OBSOLETE. Gone in 7.16.0 */
  /* 128 OBSOLETE. Gone in 7.16.0 */

  /* When FTP over SSL/TLS is selected (with CURLOPT_USE_SSL), this option
     can be used to change libcurl's default action which is to first try
     "AUTH SSL" and then "AUTH TLS" in this order, and proceed when a OK
     response has been received.

     Available parameters are:
     CURLFTPAUTH_DEFAULT - let libcurl decide
     CURLFTPAUTH_SSL     - try "AUTH SSL" first, then TLS
     CURLFTPAUTH_TLS     - try "AUTH TLS" first, then SSL
  */
  CINIT(FTPSSLAUTH, LONG, 129),

  CINIT(IOCTLFUNCTION, FUNCTIONPOINT, 130),
  CINIT(IOCTLDATA, OBJECTPOINT, 131),

  /* 132 OBSOLETE. Gone in 7.16.0 */
  /* 133 OBSOLETE. Gone in 7.16.0 */

  /* zero terminated string for pass on to the FTP server when asked for
     "account" info */
  CINIT(FTP_ACCOUNT, OBJECTPOINT, 134),

  /* feed cookies into cookie engine */
  CINIT(COOKIELIST, OBJECTPOINT, 135),

  /* ignore Content-Length */
  CINIT(IGNORE_CONTENT_LENGTH, LONG, 136),

  /* Set to non-zero to skip the IP address received in a 227 PASV FTP server
     response. Typically used for FTP-SSL purposes but is not restricted to
     that. libcurl will then instead use the same IP address it used for the
     control connection. */
  CINIT(FTP_SKIP_PASV_IP, LONG, 137),

  /* Select "file method" to use when doing FTP, see the curl_ftpmethod
     above. */
  CINIT(FTP_FILEMETHOD, LONG, 138),

  /* Local port number to bind the socket to */
  CINIT(LOCALPORT, LONG, 139),

  /* Number of ports to try, including the first one set with LOCALPORT.
     Thus, setting it to 1 will make no additional attempts but the first.
  */
  CINIT(LOCALPORTRANGE, LONG, 140),

  /* no transfer, set up connection and let application use the socket by
     extracting it with CURLINFO_LASTSOCKET */
  CINIT(CONNECT_ONLY, LONG, 141),

  /* Function that will be called to convert from the
     network encoding (instead of using the iconv calls in libcurl) */
  CINIT(CONV_FROM_NETWORK_FUNCTION, FUNCTIONPOINT, 142),

  /* Function that will be called to convert to the
     network encoding (instead of using the iconv calls in libcurl) */
  CINIT(CONV_TO_NETWORK_FUNCTION, FUNCTIONPOINT, 143),

  /* Function that will be called to convert from UTF8
     (instead of using the iconv calls in libcurl)
     Note that this is used only for SSL certificate processing */
  CINIT(CONV_FROM_UTF8_FUNCTION, FUNCTIONPOINT, 144),

  /* if the connection proceeds too quickly then need to slow it down */
  /* limit-rate: maximum number of bytes per second to send or receive */
  CINIT(MAX_SEND_SPEED_LARGE, OFF_T, 145),
  CINIT(MAX_RECV_SPEED_LARGE, OFF_T, 146),

  /* Pointer to command string to send if USER/PASS fails. */
  CINIT(FTP_ALTERNATIVE_TO_USER, OBJECTPOINT, 147),

  /* callback function for setting socket options */
  CINIT(SOCKOPTFUNCTION, FUNCTIONPOINT, 148),
  CINIT(SOCKOPTDATA, OBJECTPOINT, 149),

  /* set to 0 to disable session ID re-use for this transfer, default is
     enabled (== 1) */
  CINIT(SSL_SESSIONID_CACHE, LONG, 150),

  /* allowed SSH authentication methods */
  CINIT(SSH_AUTH_TYPES, LONG, 151),

  /* Used by scp/sftp to do public/private key authentication */
  CINIT(SSH_PUBLIC_KEYFILE, OBJECTPOINT, 152),
  CINIT(SSH_PRIVATE_KEYFILE, OBJECTPOINT, 153),

  /* Send CCC (Clear Command Channel) after authentication */
  CINIT(FTP_SSL_CCC, LONG, 154),

  /* Same as TIMEOUT and CONNECTTIMEOUT, but with ms resolution */
  CINIT(TIMEOUT_MS, LONG, 155),
  CINIT(CONNECTTIMEOUT_MS, LONG, 156),

  /* set to zero to disable the libcurl's decoding and thus pass the raw body
     data to the application even when it is encoded/compressed */
  CINIT(HTTP_TRANSFER_DECODING, LONG, 157),
  CINIT(HTTP_CONTENT_DECODING, LONG, 158),

  /* Permission used when creating new files and directories on the remote
     server for protocols that support it, SFTP/SCP/FILE */
  CINIT(NEW_FILE_PERMS, LONG, 159),
  CINIT(NEW_DIRECTORY_PERMS, LONG, 160),

  /* Set the behaviour of POST when redirecting. Values must be set to one
     of CURL_REDIR* defines below. This used to be called CURLOPT_POST301 */
  CINIT(POSTREDIR, LONG, 161),

  /* used by scp/sftp to verify the host's public key */
  CINIT(SSH_HOST_PUBLIC_KEY_MD5, OBJECTPOINT, 162),

  /* Callback function for opening socket (instead of socket(2)). Optionally,
     callback is able change the address or refuse to connect returning
     CURL_SOCKET_BAD.  The callback should have type
     curl_opensocket_callback */
  CINIT(OPENSOCKETFUNCTION, FUNCTIONPOINT, 163),
  CINIT(OPENSOCKETDATA, OBJECTPOINT, 164),

  /* POST volatile input fields. */
  CINIT(COPYPOSTFIELDS, OBJECTPOINT, 165),

  /* set transfer mode (;type=<a|i>) when doing FTP via an HTTP proxy */
  CINIT(PROXY_TRANSFER_MODE, LONG, 166),

  /* Callback function for seeking in the input stream */
  CINIT(SEEKFUNCTION, FUNCTIONPOINT, 167),
  CINIT(SEEKDATA, OBJECTPOINT, 168),

  /* CRL file */
  CINIT(CRLFILE, OBJECTPOINT, 169),

  /* Issuer certificate */
  CINIT(ISSUERCERT, OBJECTPOINT, 170),

  /* (IPv6) Address scope */
  CINIT(ADDRESS_SCOPE, LONG, 171),

  /* Collect certificate chain info and allow it to get retrievable with
     CURLINFO_CERTINFO after the transfer is complete. */
  CINIT(CERTINFO, LONG, 172),

  /* "name" and "pwd" to use when fetching. */
  CINIT(USERNAME, OBJECTPOINT, 173),
  CINIT(PASSWORD, OBJECTPOINT, 174),

    /* "name" and "pwd" to use with Proxy when fetching. */
  CINIT(PROXYUSERNAME, OBJECTPOINT, 175),
  CINIT(PROXYPASSWORD, OBJECTPOINT, 176),

  /* Comma separated list of hostnames defining no-proxy zones. These should
     match both hostnames directly, and hostnames within a domain. For
     example, local.com will match local.com and www.local.com, but NOT
     notlocal.com or www.notlocal.com. For compatibility with other
     implementations of this, .local.com will be considered to be the same as
     local.com. A single * is the only valid wildcard, and effectively
     disables the use of proxy. */
  CINIT(NOPROXY, OBJECTPOINT, 177),

  /* block size for TFTP transfers */
  CINIT(TFTP_BLKSIZE, LONG, 178),

  /* Socks Service */
  CINIT(SOCKS5_GSSAPI_SERVICE, OBJECTPOINT, 179),

  /* Socks Service */
  CINIT(SOCKS5_GSSAPI_NEC, LONG, 180),

  /* set the bitmask for the protocols that are allowed to be used for the
     transfer, which thus helps the app which takes URLs from users or other
     external inputs and want to restrict what protocol(s) to deal
     with. Defaults to CURLPROTO_ALL. */
  CINIT(PROTOCOLS, LONG, 181),

  /* set the bitmask for the protocols that libcurl is allowed to follow to,
     as a subset of the CURLOPT_PROTOCOLS ones. That means the protocol needs
     to be set in both bitmasks to be allowed to get redirected to. Defaults
     to all protocols except FILE and SCP. */
  CINIT(REDIR_PROTOCOLS, LONG, 182),

  /* set the SSH knownhost file name to use */
  CINIT(SSH_KNOWNHOSTS, OBJECTPOINT, 183),

  /* set the SSH host key callback, must point to a curl_sshkeycallback
     function */
  CINIT(SSH_KEYFUNCTION, FUNCTIONPOINT, 184),

  /* set the SSH host key callback custom pointer */
  CINIT(SSH_KEYDATA, OBJECTPOINT, 185),

  /* set the SMTP mail originator */
  CINIT(MAIL_FROM, OBJECTPOINT, 186),

  /* set the SMTP mail receiver(s) */
  CINIT(MAIL_RCPT, OBJECTPOINT, 187),

  /* FTP: send PRET before PASV */
  CINIT(FTP_USE_PRET, LONG, 188),

  /* RTSP request method (OPTIONS, SETUP, PLAY, etc...) */
  CINIT(RTSP_REQUEST, LONG, 189),

  /* The RTSP session identifier */
  CINIT(RTSP_SESSION_ID, OBJECTPOINT, 190),

  /* The RTSP stream URI */
  CINIT(RTSP_STREAM_URI, OBJECTPOINT, 191),

  /* The Transport: header to use in RTSP requests */
  CINIT(RTSP_TRANSPORT, OBJECTPOINT, 192),

  /* Manually initialize the client RTSP CSeq for this handle */
  CINIT(RTSP_CLIENT_CSEQ, LONG, 193),

  /* Manually initialize the server RTSP CSeq for this handle */
  CINIT(RTSP_SERVER_CSEQ, LONG, 194),

  /* The stream to pass to INTERLEAVEFUNCTION. */
  CINIT(INTERLEAVEDATA, OBJECTPOINT, 195),

  /* Let the application define a custom write method for RTP data */
  CINIT(INTERLEAVEFUNCTION, FUNCTIONPOINT, 196),

  /* Turn on wildcard matching */
  CINIT(WILDCARDMATCH, LONG, 197),

  /* Directory matching callback called before downloading of an
     individual file (chunk) started */
  CINIT(CHUNK_BGN_FUNCTION, FUNCTIONPOINT, 198),

  /* Directory matching callback called after the file (chunk)
     was downloaded, or skipped */
  CINIT(CHUNK_END_FUNCTION, FUNCTIONPOINT, 199),

  /* Change match (fnmatch-like) callback for wildcard matching */
  CINIT(FNMATCH_FUNCTION, FUNCTIONPOINT, 200),

  /* Let the application define custom chunk data pointer */
  CINIT(CHUNK_DATA, OBJECTPOINT, 201),

  /* FNMATCH_FUNCTION user pointer */
  CINIT(FNMATCH_DATA, OBJECTPOINT, 202),

  /* send linked-list of name:port:address sets */
  CINIT(RESOLVE, OBJECTPOINT, 203),

  /* Set a username for authenticated TLS */
  CINIT(TLSAUTH_USERNAME, OBJECTPOINT, 204),

  /* Set a password for authenticated TLS */
  CINIT(TLSAUTH_PASSWORD, OBJECTPOINT, 205),

  /* Set authentication type for authenticated TLS */
  CINIT(TLSAUTH_TYPE, OBJECTPOINT, 206),

  /* Set to 1 to enable the "TE:" header in HTTP requests to ask for
     compressed transfer-encoded responses. Set to 0 to disable the use of TE:
     in outgoing requests. The current default is 0, but it might change in a
     future libcurl release.

     libcurl will ask for the compressed methods it knows of, and if that
     isn't any, it will not ask for transfer-encoding at all even if this
     option is set to 1.

  */
  CINIT(TRANSFER_ENCODING, LONG, 207),

  /* Callback function for closing socket (instead of close(2)). The callback
     should have type curl_closesocket_callback */
  CINIT(CLOSESOCKETFUNCTION, FUNCTIONPOINT, 208),
  CINIT(CLOSESOCKETDATA, OBJECTPOINT, 209),

  /* allow GSSAPI credential delegation */
  CINIT(GSSAPI_DELEGATION, LONG, 210),

  /* Set the name servers to use for DNS resolution */
  CINIT(DNS_SERVERS, OBJECTPOINT, 211),

  /* Time-out accept operations (currently for FTP only) after this amount
     of miliseconds. */
  CINIT(ACCEPTTIMEOUT_MS, LONG, 212),

  /* Set TCP keepalive */
  CINIT(TCP_KEEPALIVE, LONG, 213),

  /* non-universal keepalive knobs (Linux, AIX, HP-UX, more) */
  CINIT(TCP_KEEPIDLE, LONG, 214),
  CINIT(TCP_KEEPINTVL, LONG, 215),

  /* Enable/disable specific SSL features with a bitmask, see CURLSSLOPT_* */
  CINIT(SSL_OPTIONS, LONG, 216),

  /* Set the SMTP auth originator */
  CINIT(MAIL_AUTH, OBJECTPOINT, 217),

  /* Enable/disable SASL initial response */
  CINIT(SASL_IR, LONG, 218),

  /* Function that will be called instead of the internal progress display
   * function. This function should be defined as the curl_xferinfo_callback
   * prototype defines. (Deprecates CURLOPT_PROGRESSFUNCTION) */
  CINIT(XFERINFOFUNCTION, FUNCTIONPOINT, 219),

  /* The XOAUTH2 bearer token */
  CINIT(XOAUTH2_BEARER, OBJECTPOINT, 220),

  /* Set the interface string to use as outgoing network
   * interface for DNS requests.
   * Only supported by the c-ares DNS backend */
  CINIT(DNS_INTERFACE, OBJECTPOINT, 221),

  /* Set the local IPv4 address to use for outgoing DNS requests.
   * Only supported by the c-ares DNS backend */
  CINIT(DNS_LOCAL_IP4, OBJECTPOINT, 222),

  /* Set the local IPv4 address to use for outgoing DNS requests.
   * Only supported by the c-ares DNS backend */
  CINIT(DNS_LOCAL_IP6, OBJECTPOINT, 223),

  /* Set authentication options directly */
  CINIT(LOGIN_OPTIONS, OBJECTPOINT, 224),

  /* Enable/disable TLS NPN extension (http2 over ssl might fail without) */
  CINIT(SSL_ENABLE_NPN, LONG, 225),

  /* Enable/disable TLS ALPN extension (http2 over ssl might fail without) */
  CINIT(SSL_ENABLE_ALPN, LONG, 226),

  /* Time to wait for a response to a HTTP request containing an
   * Expect: 100-continue header before sending the data anyway. */
  CINIT(EXPECT_100_TIMEOUT_MS, LONG, 227),

  /* This points to a linked list of headers used for proxy requests only,
     struct curl_slist kind */
  CINIT(PROXYHEADER, OBJECTPOINT, 228),

  /* Pass in a bitmask of "header options" */
  CINIT(HEADEROPT, LONG, 229),

  CURLOPT_LASTENTRY /* the last unused */
}

#undef LONG
#undef OBJECTPOINT
#undef FUNCTIONPOINT
#undef OFF_T
#undef CINIT


sqlx_bot.inc
| Afiseaza codul
/**
 * SQLX - Newer version of SQL stuff
 */

#if defined _sqlx_included
  #endinput
#endif
#define _sqlx_included

//eh..
#define SQL_NumRows SQL_NumResults

#if AMXX_VERSION_NUM >= 175
 #pragma reqclass sqlx
 #if !defined AMXMODX_NOAUTOLOAD
  #pragma defclasslib sqlx mysql
 #endif //!defined AMXMODX_NOAUTOLOAD
#endif //AMXX_VERSION_NUM


#define SQL_HOST ""
#define SQL_USER ""
#define SQL_PASS ""
#define SQL_DB ""

enum Handle
{
   Empty_Handle
};
/**
 * Creates a connection information tuple.
 * This tuple must be passed into connection routines.
 * Freeing the tuple is not necessary, but is a good idea if you
 *  create many of them.  You can cache these handles globally.
 * !!NOTE!! I have seen most people think that this connects to the DB.
 *   Nowhere does it say this, and in fact it does not.  It only caches
 *   the connection information, the host/user/pass/etc.
 *
 * The optional timeout parameter specifies how long connections should wait before
 * giving up.  If 0, the default (which is undefined) is used.
 *
 */
native Handle:SQL_MakeDbTuple(const host[], const user[], const pass[], const db[], timeout=0);


/**
 * Frees an SQL handle.
 * The handle can be to anything (tuple, connection, query, results, etc).
 * If you free a database connection, it closes the connection as well.
 */
native SQL_FreeHandle(Handle:h);


/**
 * Opens a database connection.
 * Returns an SQL handle, which must be freed.
 * Returns Empty_Handle on failure.
 */
native Handle:SQL_Connect(Handle:cine_tuple, &errcode, error[], maxlength);


/**
 * Prepares a query.
 * The query must always be freed.
 * This does not actually do the query!
 */
native Handle:SQL_PrepareQuery(Handle:db, const fmt[], any:...);


/**
 * Back-quotes characters in a string for database querying.
 * Note: The buffer's maximum size should be 2*strlen(string) to catch
 * all scenarios.
 *
 * @param db				Database handle for localization, or Empty_Handle
 *                          for when a handle is not available.
 * @param buffer			Buffer to copy to.
 * @param buflen			Maximum size of the buffer.
 * @param string			String to backquote (should not overlap buffer).
 * @return					Length of new string, or -1 on failure.
 */
native SQL_QuoteString(Handle:db, buffer[], buflen, const string[]);

/**
 * Back-quotes characters in a string for database querying.
 * Note: The buffer's maximum size should be 2*strlen(string) to catch
 * all scenarios.
 *
 * @param db				Database handle for localization, or Empty_Handle
 *                          for when a handle is not available.
 * @param buffer			Buffer to copy to.
 * @param buflen			Maximum size of the buffer.
 * @param fmt				Format of string to backquote (should not overlap buffer).
 * @param ...				Format arguments.
 * @return					Length of new string, or -1 on failure.
 */
native SQL_QuoteStringFmt(Handle:db, buffer[], buflen, const fmt[], any:...);


#define TQUERY_CONNECT_FAILED	-2
#define TQUERY_QUERY_FAILED	-1
#define TQUERY_SUCCESS		0
/**
 * Prepares and executes a threaded query.
 * This will not interrupt gameplay in the event of a poor/lossed
 *  connection, however, the interface is more complicated and
 *  asynchronous.  Furthermore, a new connection/disconnection is
 *  made for each query to simplify driver support.
 * The handler should look like:
 *
 * @param failstate - One of the three TQUERY_ defines.
 * @param query - Handle to the query, do not free it.
 * @param error - An error message, if any.
 * @param errnum - An error code, if any.
 * @param data - Data array you passed in.
 * @param size - Size of the data array you passed in.
 * @param queuetime - Amount of gametime that passed while the query was resolving.
 *
 * public QueryHandler(failstate, Handle:query, error[], errnum, data[], size, Float:queuetime)
 *
 * Note! The handle you pass in is a DB Tuple, NOT an active connection!
 * Note! The handle does not need to be freed.
 * Also note: This function is not guaranteed to be in another thread
 *  (in fact - it's not).  You're seeing data "after the fact",
 *  and as such to execute another query you should run
 *  SQL_ThreadQuery again with new data.
 */
native SQL_ThreadQuery(Handle:db_tuple, const handler[], const query[], const data[]="", dataSize=0);


/**
 * Executes a query.
 * Returns 1 if the query succeeded.
 * Returns 0 if the query failed.
 * NOTE: You can call this multiple times as long as its parent
 *  connection is kept open.  Each time the result set will be freed
 *  from the previous call.
 */
native SQL_Execute(Handle:query);

/**
 * Gets information about a failed query error.
 * Returns the errorcode.
 */
native SQL_QueryError(Handle:query, error[], maxlength);


/**
 * Returns 1 if there are more results to be read,
 *  0 otherwise.
 */
native SQL_MoreResults(Handle:query);


/**
 * Tells whether a specific column in the current row
 *  is NULL or not.
 */
native SQL_IsNull(Handle:query, column);

/**
 * Retrieves the current result.
 * A successful query starts at the first result,
 *  so you should not call SQL_NextRow() first.
 * Passing no extra params - return int
 * Passing one extra param - return float in 1st extra arg
 * Passing two extra params - return string in 1st arg, max length in 2nd
 * Example:
 *  new num = SQL_ReadResult(query, 0)
 *  new Float:num2
 *  new str[32]
 *  SQL_ReadResult(query, 1, num2)
 *  SQL_ReadResult(query, 2, str, 31)
 */
native SQL_ReadResult(Handle:query, column, {Float,_}:...);


/**
 * Advances to the next result (return value should be ignored).
 */
native SQL_NextRow(Handle:query);


/**
 * Returns the number of affected rows.
 */
native SQL_AffectedRows(Handle:query);


/**
 * Returns the number of rows total.
 */
native SQL_NumResults(Handle:query);


/**
 * Returns the number of columns total.
 */
native SQL_NumColumns(Handle:query);


/**
 * Returns the name of a column.
 * Errors on a bad field number.
 */
native SQL_FieldNumToName(Handle:query, num, name[], maxlength);


/**
 * Returns the number of a named column, or -1 if not found.
 */
native SQL_FieldNameToNum(Handle:query, const name[]);


/**
 * Rewinds a result set to the first row.
 */
native SQL_Rewind(Handle:query);


/**
 * Returns the insert id of the last INSERT query.
 * Returns 0 otherwise.
 */
native SQL_GetInsertId(Handle:query);


/**
 * Returns which driver this plugin is currently bound to.
 */
native SQL_GetAffinity(driver[], maxlen);

/**
 * Sets driver affinity.  You can use this to force a particular
 *  driver implementation.  This will automatically change all SQL
 *  natives in your plugin to be "bound" to the module in question.
 * If no such module is found, it will return 0.  This isn't necessarily bad -
 *  the user might have typed the wrong driver.  Unless your plugin is built
 *  to handle different driver types at once, you should let this error pass.
 * Note, that using this while you have open handles to another database
 *  type will cause problems.  I.e., you cannot open a handle, switch
 *  affinity, then close the handle with a different driver.
 * Switching affinity is an O(n*m) operation, where n is the number of
 *  SQL natives and m is the number of used natives in total.
 * Intuitive programmers will note that this causes problems for threaded queries.
 *  You will have to either force your script to work under one affinity, or to
 *  pack the affinity type into the query data, check it against the current, then
 *  set the new affinity if necessary.  Then, restore the old for safety.
 */
native SQL_SetAffinity(const driver[]);

/**
 * Returns the original query string that a query handle used.
 */
native SQL_GetQueryString(Handle:query, buffer[], maxlength);

/**
 * For queries which return multiple result sets, this advances to the next
 * result set if one is available.  Otherwise, the current result set is
 * destroyed and will no longer be accessible.
 *
 * This function will always return false on SQLite, and when using threaded
 * queries in MySQL.  Nonetheless, it has the same effect of removing the last
 * result set.
 *
 * @param query		Query Handle.
 * @return			True on success, false on failure.
 */
native bool:SQL_NextResultSet(Handle:query);

/**
 * This function can be used to find out if a table in a Sqlite database exists.
 * (updated for newer API)
 */
stock bool:sqlite_TableExists(Handle:db, const table[])
{
	new Handle:query = SQL_PrepareQuery(
					db,
					"SELECT name FROM sqlite_master WHERE type='table' AND name='%s' LIMIT 1;",
					table);

	if (!SQL_Execute(query) || !SQL_NumResults(query))
	{
		SQL_FreeHandle(query);
		return false;
	}

	SQL_FreeHandle(query);

	return true;
}

/**
 * Use this for executing a query where you don't care about the result.
 * Returns 0 on failure, 1 on success
 */
stock SQL_SimpleQuery(Handle:db, const query[], error[]="", maxlength=0, &rows=0)
{
	new Handle:hQuery = SQL_PrepareQuery(db, "%s", query);

	if (!SQL_Execute(hQuery))
	{
		SQL_QueryError(hQuery, error, maxlength);
		SQL_FreeHandle(hQuery);
		return 0;
	}

	rows = SQL_NumResults(hQuery);

	SQL_FreeHandle(hQuery);

	return 1;
}

/**
 * Use this for executing a query where you don't care about the result.
 * Returns 0 on failure, 1 on success
 */
stock SQL_SimpleQueryFmt(Handle:db, error[]="", maxlength=0, &rows=0, const fmt[], any:...)
{
	static query_buf[2048];
	vformat(query_buf, 2047, fmt, 6);

	new Handle:hQuery = SQL_PrepareQuery(db, "%s", query_buf);

	if (!SQL_Execute(hQuery))
	{
		SQL_QueryError(hQuery, error, maxlength);
		SQL_FreeHandle(hQuery);
		return 0;
	}

	rows = SQL_NumResults(hQuery);

	SQL_FreeHandle(hQuery);

	return 1;
}

/**
 * Use this for executing a query and not caring about the error.
 * Returns -1 on error, >=0 on success (with number of affected rows)
 */
stock SQL_QueryAndIgnore(Handle:db, const queryfmt[], any:...)
{
	static query[4096];
	new Handle:hQuery;
	new ret;

	vformat(query, sizeof(query)-1, queryfmt, 3);

	hQuery = SQL_PrepareQuery(db, "%s", query);

	if (SQL_Execute(hQuery))
	{
		ret = SQL_AffectedRows(hQuery);
	} else {
		ret = -1;
	}

	SQL_FreeHandle(hQuery);

	return ret;
}

stock Handle:SQL_MakeStdTuple(timeout = 0)
{
static get_type[12], set_type[12];
SQL_GetAffinity(get_type, 12);

if (!equali(get_type, set_type))
{
	if (!SQL_SetAffinity(set_type))
	{
		log_amx("Failed to set affinity from %s to %s.", get_type, set_type);
	}
}

return SQL_MakeDbTuple(SQL_HOST, SQL_USER, SQL_PASS, SQL_DB, timeout);
}
Post Reply

Return to “Modificari pluginuri”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 5 guests