Raised This Month: $12 Target: $400
 3% 

record bot not moving/working


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
The RaiD.
Member
Join Date: Jul 2019
Old 09-28-2021 , 11:02   record bot not moving/working
Reply With Quote #1

iam using kreedz world record bot by
#define PLUGIN "KZ:Bot"
#define VERSION "2.0 Beta"
#define AUTHOR "Garey"
the plugin gives not an error or something like that its working and the name of the bot is RECORD BOT
but its not moving or it not shows the worldrecords for some reason can someone help?
Code:
/*
 *
 * KZ:Bots
 * by: Garey
 *
 * This program is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, version 3.0, as published by the
 * Free Software Foundation.
 *
 * 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/>.
 *
 */

#include <amxmodx>
#include <curl>
#include <amxxarch>
#include <hamsandwich>
#include <fakemeta_util>

#define PLUGIN "KZ:Bot"
#define VERSION "2.0 Beta"
#define AUTHOR "Garey"

#pragma dynamic 131068 // without this line will probly crash the server

#define MAX_SOURCES 16

enum FWrite
{
    FW_NONE = 0,
    FW_DELETESOURCE = (1<<0),
    FW_CANOVERRIDE = (1<<1)
}

new const rec_foldername[10] = "kz_bots";
new const rec_recorder[] = "ent_recorder";
new const rec_demoparser[] = "dem_think";
new Array:record_info[33];

new global_bot;

enum source_data
{
	source_id,
	source_type,
	source_name[32],
	source_time[32],
	source_path[128],
	source_startframe,
	Float:source_starttime,
	Float:source_stoptime,
	Array:source_array
}

new sources_num = 0;
new bot_sources[MAX_SOURCES][source_data]

enum _:MODES
{
     MODE_CYCLE,
     MODE_USE,
     MODE_WAIT
}

new bot_modes[MODES][] =
{
	"Cycle Run",
	"Restart on USE",
	"Restart on USE + Wait on distance"
}


new bool:plr_botnamed[33];
new plr_sound[33];
new plr_mode[33];
new plr_source[33];
new plr_frame_it[33];
new plr_jump[33] = {300, ... };
new plr_saverun_time[32][32];
new bool:plr_delayed_save[33];
new Float:plr_delayed_timer[33];
new bool:plr_playback[33];
new bool:bot_inrestart[33];
new Float:bot_restarttime[33];
new bool:is_recording[33];

enum frame_data
{
	Float:frame_origin[3],
	Float:frame_angles[3],
	Float:frame_velocity[3],
	frame_buttons,
	Float:frame_time
}

new ghost_data[33][frame_data];

new maxplayers;

new cvar_mode;
new cvar_speed;
new cvar_keys;

new map_records_dir[128];

new Trie:start_buttons;
new Trie:stop_buttons

new step_sounds[4]


/************************************************
* 						*
*		SOURCE CODE START 		*
*	 					*
*************************************************/

public plugin_precache()
{
	step_sounds[0] = precache_sound("player/pl_step1.wav");
	step_sounds[1] = precache_sound("player/pl_step2.wav");
	step_sounds[2] = precache_sound("player/pl_step3.wav");
	step_sounds[3] = precache_sound("player/pl_step4.wav");
	
}
public plugin_natives()
{
	register_native("save_run", "native_save_run")
	register_native("pause_run", "native_pause_run")
	register_native("unpause_run", "native_unpause_run")
	register_native("reset_run", "native_reset_run")
}

public plugin_cfg()
{	
	new record_list[128]
	new record_list_cosy[128]
	get_localinfo( "amxx_datadir", map_records_dir, charsmax( map_records_dir ) );
	format(map_records_dir, charsmax(map_records_dir), "%s/%s", map_records_dir,rec_foldername)
	format(record_list, charsmax(record_list), "%s/record_list.txt", map_records_dir);
	format(record_list_cosy, charsmax(record_list_cosy), "%s/record_list2.txt", map_records_dir);
	new sz_mapname[64];
	get_mapname(sz_mapname, 63);
	if(!dir_exists(map_records_dir))
	{
		mkdir(map_records_dir);
	}		
	format(map_records_dir, charsmax(map_records_dir), "%s/%s", map_records_dir,sz_mapname)
	if(!dir_exists(map_records_dir))
	{
		mkdir(map_records_dir)
	}
	
	new szFileName[64]
	new hDir = open_dir(map_records_dir, szFileName, charsmax(szFileName)) 
	do
	{
		if(equal(szFileName, "..") || equal(szFileName, "."))
			continue
			
		new len = strlen(szFileName);
		if(!equal(szFileName[len-3], "rec"))
		{
			continue;
		}
		
		new path[128]
		format(path, 128, "%s/%s", map_records_dir, szFileName);
		load_run(path);			
	}
	while ( next_file( hDir, szFileName, charsmax( szFileName ) ) )
	close_dir(hDir)  
	curl_download_file( record_list, "https://xtreme-jumps.eu/demos.txt", "", "");
	curl_download_file( record_list_cosy, "https://cosy-climbing.net/demoz.txt", "", "");
	set_task(3.0, "create_bot");	
}
public create_bot()
{
	global_bot = makebot("Record Bot");
}

public plugin_init() {
	register_plugin(PLUGIN, VERSION, AUTHOR);	
	register_clcmd( "kzbot_settings","kzbot_settings" );
	register_clcmd( "say /bot","kzbot_menu" );
	register_clcmd( "load_demo" ,"process_demo" );
	start_buttons = TrieCreate();	
	stop_buttons = TrieCreate();	
	new const start_names[][] = { "counter_start", "clockstartbutton", "firsttimerelay", "gogogo", "startcounter", "multi_start" }
	new const stop_names[][] = { "counter_off", "clockstopbutton", "clockstop", "stop_counter", "stopcounter", "multi_stop" }
	for(new i = 0; i < sizeof(start_names); i++)
	{
		TrieSetCell(start_buttons, start_names[i], 1)
	}
	for(new i = 0; i < sizeof(stop_names); i++)
	{
		TrieSetCell(stop_buttons, stop_names[i], 1)
	}
	
	
	RegisterHam( Ham_Use, "func_button", "fw_use", 0);
	register_forward(FM_ClientUserInfoChanged, "fw_clientinfochanged", 1);
	register_forward(FM_AddToFullPack,"fw_addtofullpack", 1)
	register_forward(FM_UpdateClientData, "fw_updateclientdata", 1)
	register_forward(FM_CheckVisibility,"fw_checkvisibility")
	
	cvar_mode = register_cvar("kzbot_on", "1");
	cvar_keys = register_cvar("kzbot_keys", "1");
	cvar_speed = register_cvar("kzbot_speed", "1");
	new ent = fm_create_entity( "info_target" );
	if ( ent )
	{
		set_pev( ent, pev_classname, rec_recorder );
		set_pev( ent, pev_nextthink, get_gametime() + 0.01 );
		RegisterHam( Ham_Think, "info_target", "forward_think", 1 );
	}
	maxplayers = get_maxplayers();
	for ( new i = 1; i <= maxplayers; i++ )
	{
		record_info[i] = ArrayCreate( frame_data );
	}	
	for ( new i = 0;  i < MAX_SOURCES; i++)
	{
		bot_sources[i][source_array] = _:ArrayCreate( frame_data );
	}
}

public fw_clientinfochanged(id, buffer)
{
	if(id == global_bot)
	{
		arrayset(plr_botnamed, false, 32);
	}
}

public client_putinserver(id)
{
	plr_playback[id] = true;
	plr_source[id] = 0;
	plr_frame_it[id] = 0;
	plr_botnamed[id] = false;
}

public client_disconnect(id)
{
	if(plr_delayed_save[id])
	{
		save_run(id, plr_saverun_time[id], false);
		plr_delayed_save[id] = false;
	}
}

public fw_prethink(id)
{		
	static Float:oldorigin[33][3];
	static Float:oldangles[33][3];
	static oldbuttons[33];
	static damaged_frames[33];
	new bool:dontstep = false;
	if(id == global_bot)
	{
		return FMRES_IGNORED;
	}	
		
	if(!is_user_connected(global_bot))
	{
		plr_botnamed[id] = false;
	}
	else if(!is_user_alive(global_bot))
	{
		plr_botnamed[id] = false;
	}
	if(is_user_connected(id) && !plr_botnamed[id] && global_bot && sources_num && plr_frame_it[id])
	{
		update_sourcename(id);
		plr_botnamed[id] = true;
	}
	if(bot_inrestart[id])
	{
		if(get_gametime() > bot_restarttime[id])
		{
			bot_inrestart[id] = false;
			plr_frame_it[id] = 0;
		}
	}
	if(bot_sources[plr_source[id]][source_stoptime] && plr_frame_it[id] > 100 && ghost_data[id][frame_time] >= bot_sources[plr_source[id]][source_stoptime])
	{
		if(!bot_inrestart[id])
		{
			bot_inrestart[id] = true;			
			bot_restarttime[id] = get_gametime()+0.7;
		}
	}
	if(plr_playback[id])
	{		
		if(plr_mode[id] == MODE_WAIT )
		{
			new Float:origin[2][3];
			pev(id, pev_origin, origin[0]);
			xs_vec_copy(ghost_data[id][frame_origin], origin[1]);
			if(get_distance_f(origin[0], origin[1]) < 200.0)
			{
				plr_frame_it[id]++;
			}
			else
			{
				dontstep = true;
			}
		}
		else
			plr_frame_it[id]++;
	}
	else
	{
		dontstep = true;
	}
	if(!bot_sources[plr_source[id]][source_array] || !ArraySize(bot_sources[plr_source[id]][source_array]))
	{
		return FMRES_IGNORED
	}
	if(plr_frame_it[id] > ArraySize(bot_sources[plr_source[id]][source_array])-1)
	{
		if(!bot_inrestart[id])
		{
			bot_inrestart[id] = true;
			bot_restarttime[id] = get_gametime()+0.7;
			get_gametime()
		}
		plr_frame_it[id] = ArraySize(bot_sources[plr_source[id]][source_array])-1;
		return FMRES_IGNORED
	}	
	new Float:vel[3], Float:origins[3];		
	ArrayGetArray(bot_sources[plr_source[id]][source_array], plr_frame_it[id], ghost_data[id]);
	
	new onground = ghost_data[id][frame_velocity][2] == 0.0 || ghost_data[id][frame_velocity][2] == 260.25 ? true : false			
	
	xs_vec_copy(ghost_data[id][frame_origin], origins);			
	xs_vec_copy(ghost_data[id][frame_velocity], vel);
	
	if(ghost_data[id][frame_buttons] & IN_USE && ~oldbuttons[id] & IN_USE)
	{
		if(!bot_sources[plr_source[id]][source_starttime] || !bot_sources[plr_source[id]][source_stoptime])
		{					
			CheckButton(id);
		}
	}
	
	if(get_distance_f(oldorigin[id], origins) > 100.0)
	{			
		damaged_frames[id]++;
	}
	else
	{
		xs_vec_copy(origins, oldorigin[id]);	
		xs_vec_copy(ghost_data[id][frame_angles], oldangles[id]);	
		damaged_frames[id] = 0;
	}
	if(damaged_frames[id] > 10)
	{
		damaged_frames[id] = 0;
		xs_vec_copy(origins, oldorigin[id]);	
		xs_vec_copy(ghost_data[id][frame_angles], oldangles[id]);
	}
	xs_vec_copy(oldorigin[id], ghost_data[id][frame_origin]);
	xs_vec_copy(oldangles[id], ghost_data[id][frame_angles]);
	if(get_distance_f(origins, oldorigin[id]) < 100.0 && !damaged_frames[id])
	{
		xs_vec_copy(ghost_data[id][frame_origin], oldorigin[id]);
		xs_vec_copy(ghost_data[id][frame_angles], oldangles[id]);
	}
	vel[2] = 0.0;
	if(!dontstep)
	{
		if(onground && (vector_length(vel) > 120.0))
		{			
			if(ghost_data[id][frame_buttons] & IN_JUMP  && ~oldbuttons[id] & IN_JUMP && plr_sound[id] < 200)
			{			
				plr_sound[id] = 0;
			}
			if(pev(id, pev_groupinfo) && pev(id, pev_iuser2) == global_bot)
			{
				playback_sound(id, origins);
			}
			else if(!pev(id, pev_groupinfo))
			{
				playback_sound(id, origins);
			}
		}
		
	}
	oldbuttons[id] = ghost_data[id][frame_buttons];
	
	plr_sound[id] -= 10;

	
	return FMRES_IGNORED
}

public fw_checkvisibility(id,pset)
{		
	forward_return(FMV_CELL, 1);	
	return FMRES_SUPERCEDE;	
}
public fw_updateclientdata(id, sendweapons, cd_handle )
{	
	if(id == global_bot)
		return FMRES_IGNORED;
			
	new ent = pev(id, pev_iuser2);
	if(!ent)
		return FMRES_IGNORED;
	
	if((global_bot == ent && sources_num) && (ArraySize(bot_sources[plr_source[id]][source_array]) > plr_frame_it[id]))
	{
		set_cd(cd_handle, CD_Origin, ghost_data[id][frame_origin]);
		set_cd(cd_handle, CD_iUser1, pev(id, pev_iuser1));
		set_cd(cd_handle, CD_iUser2, ent);
		set_cd(cd_handle, CD_Velocity, ghost_data[id][frame_velocity]);
		if(ghost_data[id][frame_buttons] & IN_DUCK)		
			set_cd(cd_handle, CD_ViewOfs, Float:{0.0, 0.0, 12.0});
		else
			set_cd(cd_handle, CD_ViewOfs, Float:{0.0, 0.0, 17.0});		
		static sz_time[12];	
		static Float:ftime
		
		if(bot_sources[plr_source[id]][source_stoptime] && plr_frame_it[id] > 100 && ghost_data[id][frame_time] >= bot_sources[plr_source[id]][source_stoptime])
		{
			ftime = bot_sources[plr_source[id]][source_stoptime]-bot_sources[plr_source[id]][source_starttime];
			if(!bot_inrestart[id])
			{
				bot_inrestart[id] = true;			
				bot_restarttime[id] = get_gametime()+0.7;
			}
		}
		else
		{			
			ftime = ghost_data[id][frame_time]-bot_sources[plr_source[id]][source_starttime];
		}
	
		fnConvertTime( ftime, sz_time, charsmax( sz_time ) );
		if(ftime > 0.0)
		{
			client_print(id, print_center, "[ %.2s:%.2s.%.2s ]", sz_time, sz_time[2], sz_time[5]);
		}
		else
			client_print(id, print_center, "[ PRE-RECORD ]");
			
		if(get_pcvar_num(cvar_speed))
		{
			new Float:vel[3];
			xs_vec_copy(ghost_data[id][frame_velocity], vel);
			vel[2] = 0.0
			set_hudmessage( 255, 255, 225, -1.0, 0.83, 0, 0.0, 0.05, 0.0, 0.0, 2);
			show_hudmessage(id, "%0.f units", vector_length(vel));
		}
		if(get_pcvar_num(cvar_keys))
		{
			new b = ghost_data[id][frame_buttons];
			set_hudmessage(255, 255, 225, -1.0, 0.490, 0, 0.0, 0.05, 0.0, 0.0, 4);
			show_hudmessage(id, "   %s^n %s     %s^n    %s^n%s^n%s", 
			b & IN_FORWARD ? "W" : " ", 
			b & IN_MOVELEFT ? "A" : " ", 
			b & IN_MOVERIGHT ? "D" : " ", 
			b & IN_BACK ? "S" : " ", 
			b & IN_JUMP ? "JUMP" : " ", 
			b & IN_DUCK ? "DUCK" : " ");
		}
		return FMRES_SUPERCEDE;
	}
	return FMRES_IGNORED;
}
public fw_addtofullpack(es_handle,e,ent,host,hostflags,player,pSet)
{
	if(global_bot == host)
	{		
		return FMRES_IGNORED;
	}
		
	if(player)
	{		
		if(ArraySize(bot_sources[plr_source[host]][source_array]) > plr_frame_it[host])
		if(global_bot == ent && sources_num)
		{
			new Float:origin[2][3];
			pev(host, pev_origin, origin[0]);
			xs_vec_copy(ghost_data[host][frame_origin], origin[1]);
			new spec = pev(host, pev_iuser2);
			if(spec && spec != ent)
			{
				ghost_data[host] = ghost_data[spec];
			}	
			set_es(es_handle, ES_Velocity, ghost_data[host][frame_velocity]);
			ghost_data[host][frame_angles][0] /= -3.0;
			new bool:onground = ghost_data[host][frame_velocity][2] == 0.0 ? true : false
			animate_legs(es_handle, ghost_data[host][frame_buttons], onground);
			set_es(es_handle, ES_Angles, ghost_data[host][frame_angles]);
			set_es(es_handle, ES_Origin, ghost_data[host][frame_origin]);				
			set_es(es_handle, ES_Solid, SOLID_NOT);			
			// fix ugly sequence
			set_es(es_handle, ES_Sequence , 75);
			set_es(es_handle, ES_RenderMode, kRenderTransAdd);			
			set_es(es_handle, ES_RenderFx, kRenderFxSolidFast, 0);				
			set_es(es_handle, ES_RenderAmt, floatround(get_distance_f(origin[0], origin[1]) * 255.0 / 360.0, floatround_floor));
			return FMRES_SUPERCEDE;
		}
	}
	
	return FMRES_IGNORED;
}


public fw_use(ent, id)
{
	if(!pev_valid(id) ||  id > maxplayers)
	{
		return HAM_IGNORED;
	}

	
	new target[32]
	pev(ent, pev_target, target, charsmax(target))
	
	new bool:start_timer = false;
	new bool:stop_timer = false;
	if(TrieKeyExists(start_buttons, target))
	{
		start_timer = true;
	}
	else if(TrieKeyExists(stop_buttons, target))
	{
		stop_timer = true;
	}
	
	if(id == global_bot)
	{
		if(start_timer && !bot_sources[plr_source[id]][source_starttime])
		{
			bot_sources[plr_source[id]][source_starttime] = _:ghost_data[id][frame_time];
			bot_sources[plr_source[id]][source_startframe] = plr_frame_it[id];
		}
		else if(stop_timer && !bot_sources[plr_source[id]][source_stoptime])
		{
			bot_sources[plr_source[id]][source_stoptime] = _:ghost_data[id][frame_time];
		}
		return HAM_SUPERCEDE;
	}
	
	if(start_timer && plr_mode[id] >= MODE_USE)
	{	
		plr_frame_it[id] = bot_sources[plr_source[id]][source_startframe];
	}
	
	return HAM_IGNORED;
}

/************************************************
* 						*
*	RECORDING & PLAYBACK ARRAYS SECTION 	*
*	 					*
*************************************************/

#define NUM_THREADS 256

public forward_think( ent )
{	
	static classname[64]
	static si;
	pev(ent, pev_classname, classname, 63);
	if ( equal( classname, rec_demoparser ) )
	{
		new file = pev(ent, pev_iuser1);
		new source_index = pev(ent, pev_iuser2);
		if(!file)
		{
			set_pev( ent, pev_flags, pev(ent, pev_flags) | FL_KILLME);
			return FMRES_IGNORED;
		}
		if(si != source_index)
		{
			si = source_index;
		}
		new bool:Finished;
		if(!Finished)
		{
			for(new i = 0; i < NUM_THREADS; i++)
			{
				if(read_frames(file, bot_sources[source_index][source_array]))
				{
					Finished = true;
					break;
				}
			}
		}
		if(Finished)
		{
			new filename[64]
			DecodeText(pev(ent, pev_iuser3), filename, charsmax(filename))
			fclose( file );
			new demo_time[32]
			demo_time = bot_sources[source_index][source_time]
			bot_sources[source_index][source_type] = 1;
			save_run(source_index, demo_time, true)
			set_pev(ent, pev_iuser1, 0);
			set_pev( ent, pev_flags, pev(ent, pev_flags) | FL_KILLME);
		}
		else
		{
			set_pev( ent, pev_nextthink, get_gametime() + 0.001 )
		}		
		return FMRES_IGNORED;	
	}
	else if(equal(classname, rec_recorder))
	{
		new Float:nextthink =  0.01;
		if(!get_pcvar_num(cvar_mode))
			return FMRES_IGNORED;
		else
		{
			static players[32], inum;
			get_players( players, inum );
			
			if(global_bot && inum == 1)
			{
				set_pev( ent, pev_nextthink, get_gametime()+nextthink);
				return FMRES_IGNORED;
			}		
			for ( new i = 0; i < inum; i++ )
			{	
				
				new id = players[i];
					
				if(global_bot == id)
				{	
					set_pev(id, pev_solid, SOLID_NOT)
					dllfunc(DLLFunc_PlayerPreThink, id);
					dllfunc(DLLFunc_PlayerPostThink,  id);
					dllfunc(DLLFunc_UpdateClientData,  id);
					set_pev(id, pev_solid, SOLID_SLIDEBOX)
					set_pev(id, pev_deadflag, DEAD_NO);
					set_pev(id, pev_health, 100.0);					
				}	
				else 
				{
					if(global_bot)
						fw_prethink(id);
						
					if(is_recording[id] || plr_delayed_save[id])
					{						
						if(plr_delayed_save[id])
						{
							if(get_gametime() > plr_delayed_timer[id])
							{
								plr_delayed_save[id] = false;
								save_run(id, plr_saverun_time[id], false);
							}
						}
						player_record( id )
					}
				}								
			}
		}
		
		set_pev( ent, pev_nextthink, get_gametime()+nextthink);
	}
	
	
	return FMRES_IGNORED;	
}

public CheckButton( id )
{	
	static ent = -1;
	static Float:origin[3];
	xs_vec_copy(ghost_data[id][frame_origin], origin);
	while ( (ent = fm_find_ent_in_sphere( ent, origin, 100.0 ) ) != 0 )
	{
		new classname[32];
		pev( ent, pev_classname, classname, charsmax( classname ) );
		if ( equal( classname, "func_button" ) )
		{
			new Float:eorigin[3];
			fm_get_brush_entity_origin( ent, eorigin );
			static target[32];
			pev( ent, pev_target, target, 31 );
			if(global_bot)
			{
				if (!bot_sources[plr_source[id]][source_starttime] && TrieKeyExists( start_buttons, target ) )
				{
					bot_findbuttons(id, global_bot)
				}
				if (!bot_sources[plr_source[id]][source_stoptime] && TrieKeyExists( stop_buttons, target ) )
				{
					bot_findbuttons(id, global_bot)
				}
			}
		}
	}
}


public bot_findbuttons(id, bot)
{
	plr_source[bot] = plr_source[id];
	plr_frame_it[bot] = plr_frame_it[id];
	ghost_data[bot][frame_time] = _:ghost_data[id][frame_time];
	set_pev(bot, pev_origin, 	ghost_data[id][frame_origin]);
	set_pev(bot, pev_button, 	ghost_data[id][frame_buttons]);
	set_pev(bot, pev_movetype, 	MOVETYPE_WALK);
	set_pev(bot, pev_v_angle, 	ghost_data[id][frame_angles]);
	
	set_pev(bot, pev_angles, ghost_data[id][frame_angles]);
	set_pev(bot, pev_fixangle, 1);	
	engfunc( EngFunc_RunPlayerMove, bot, ghost_data[id][frame_angles], ghost_data[id][frame_velocity][0], ghost_data[id][frame_velocity][1], ghost_data[id][frame_velocity][2], 0, 0, 10);
	engfunc( EngFunc_RunPlayerMove, bot, ghost_data[id][frame_angles], ghost_data[id][frame_velocity][0], ghost_data[id][frame_velocity][1], ghost_data[id][frame_velocity][2], IN_USE, 0,10);
}

public player_record( id )
{
	static temp_data[frame_data];
		
	temp_data[frame_buttons] 	= pev(id, pev_button);
	
	pev(id, pev_origin, 	temp_data[frame_origin]);
	pev(id, pev_v_angle, 	temp_data[frame_angles]);
	pev(id, pev_velocity,  	temp_data[frame_velocity]);	
	temp_data[frame_time] = _:get_gametime();
	
	ArrayPushArray(record_info[id], temp_data);
}


/************************************************
* 						*
*		DEMO PARSING SECTION 		*
*	 					*
*************************************************/

/* 
 Function:
	read_demo_header

 Description:
	Read demo header file from given file pointer
 
 Comment:
	There will be magic numbers, i don't wanna create defines for this because i use this only in this function and only for jump offsets in file
 If you wanna know what this numbers means, check old WRBot or C++ Project DemTools by Yalter
*/

stock  bool:read_demo_header( file )
{
	static temp, entries;
	fseek( file, 8,    SEEK_SET );
	fread( file, temp, BLOCK_INT );

	if ( temp != 5 )
	{
		return false;
	}

	fread( file, temp, BLOCK_INT );

	if ( temp != 48 )
	{
		return false;
	}

	fseek( file, 260, SEEK_CUR );
	fseek( file, 260, SEEK_CUR );

	fseek( file, BLOCK_INT, SEEK_CUR );
	fread( file, temp, BLOCK_INT );

	fseek( file, temp, SEEK_SET );

	fread( file, entries, BLOCK_INT );
	for ( new i = 0; i < entries; i++ )
	{		
		fseek( file, BLOCK_INT, SEEK_CUR );
		fseek( file, 64, SEEK_CUR );
		fseek( file, BLOCK_INT, SEEK_CUR );
		fseek( file, BLOCK_INT, SEEK_CUR );
		fseek( file, BLOCK_INT, SEEK_CUR );
		fseek( file, BLOCK_INT, SEEK_CUR );
		fread( file, temp, BLOCK_INT );
		fseek( file, BLOCK_INT, SEEK_CUR );
	}

	fseek( file, temp, SEEK_SET );
		
	return true;
}

/* 
 Function:
	read_frame_header

 Description:
	Read frame header
 
 Comment:
	There will be magic numbers, i don't wanna create defines for this because i use this only in this function and only for jump offsets in file
 If you wanna know what this numbers means, check old WRBot or C++ Project DemTools by Yalter
*/


public read_frame_header( file, &Float:gametime)
{
	static type;
	fread( file, type, BLOCK_BYTE );
	fread( file, _:gametime, BLOCK_INT );
	fseek( file, 4, SEEK_CUR);

	return(type);
}


/* 
 Function:
	read_frames

 Description:
	Read frames and push it to array
 
 Comment:
	There will be magic numbers, i don't wanna create defines for this because i use this only in this function and only for jump offsets in file
 If you wanna know what this numbers means, check old WRBot or C++ Project DemTools by Yalter
*/


public read_frames( file, Array:array_to )
{
	new temp_data[frame_data];
	//if ( !feof( file ) )
	{
		new Float:gametime;
		new type = read_frame_header( file, gametime );
		new bool:breakme;		
		
		switch ( type )
		{
			case 0:
			{				
			}
			case 1:
			{				
				static length;	
				fseek( file, 84, SEEK_CUR );
				//fread( file, _:temp_data[frame_onground], BLOCK_INT );
				fseek( file, 8, SEEK_CUR );
				//fseek( file, 92, SEEK_CUR );
				fread( file, _:temp_data[frame_velocity][0], BLOCK_INT );
				fread( file, _:temp_data[frame_velocity][1], BLOCK_INT );
				fread( file, _:temp_data[frame_velocity][2], BLOCK_INT );
				for ( new i = 0; i < 3; ++i )
					fread( file, _:temp_data[frame_origin][i], BLOCK_INT )
				fseek( file, 124, SEEK_CUR );
				fread( file, _:temp_data[frame_angles][0], BLOCK_INT );
				fread( file, _:temp_data[frame_angles][1], BLOCK_INT );
				fread( file, _:temp_data[frame_angles][2], BLOCK_INT );
				fseek( file, 14, SEEK_CUR );
				fread( file, temp_data[frame_buttons], BLOCK_SHORT );
				fseek( file, 196, SEEK_CUR );
				fread( file, length, BLOCK_INT );
				fseek( file, length, SEEK_CUR );
			}
			case 2:
			{
			}
			case 3:
			{
				fseek( file, 64, SEEK_CUR);
			}
			case 4:
			{
				fseek( file, 32, SEEK_CUR );

			}
			case 5:
			{
				breakme = true;
			}
			case 6:
			{
				fseek( file, 84, SEEK_CUR );
			}
			case 7:
			{
				fseek( file, 8, SEEK_CUR );
			}
			case 8:
			{				
				static length;
				fseek( file, 4, SEEK_CUR );
				fread( file, length, BLOCK_INT );
				fseek( file, length, SEEK_CUR );
				fseek( file, 16, SEEK_CUR );
			}
			case 9:
			{
				static length;
				fread( file, length, BLOCK_INT );
				fseek( file, length, SEEK_CUR );
			}
			default:
			{
				breakme = true;
			}
		}

		if(type == 1)
		{
			temp_data[frame_time] = _:gametime;
			ArrayPushArray(array_to, temp_data);		
		}
		
		if(breakme)
		{
			return true;
		}		
	}

	return false;
}

/************************************************
* 						*
*		FILE OPERATING SECTION 		*
*	 					*
*************************************************/

public load_run(filename[128])
{
	new file = fopen(filename, "r");
	new string[300];
	new player_name[32], demo_time[32], demo_type[32];
	
	fgets(file, string, charsmax(string));
	if(containi(string, "HEADER") == -1)
	{		
		fclose(file)
		
		return -1;
	}
	static ExplodedString[14][32];
	ExplodeString( ExplodedString, 4, 127, string, ' ' );
	
	copy(player_name, 32, ExplodedString[1])
	copy(demo_type, 32, ExplodedString[2])
	copy(demo_time, 32, ExplodedString[3])
	static temp_frame[frame_data];
	new id = sources_num;	
	bot_sources[id][source_type] = 0;
	bot_sources[id][source_id] = sources_num;
	bot_sources[id][source_name] = player_name;
	bot_sources[id][source_time] = demo_time;
	bot_sources[id][source_path] = filename;	
	remove_quotes(bot_sources[id][source_name])
	remove_quotes(bot_sources[id][source_time])
	remove_quotes(demo_type)
	trim(bot_sources[id][source_name])
	trim(bot_sources[id][source_time])
	trim(demo_type)
	if(equal(demo_type, "DEMO"))
	{
		bot_sources[id][source_type] = 1;
	}	
	sources_num++
	ArrayClear(bot_sources[id][source_array]);
	while(fgets(file, string, charsmax(string)))
	{
		ExplodeString( ExplodedString, 13, 31, string, ' ' );
		temp_frame[frame_origin][0] = _:str_to_float(ExplodedString[1])
		temp_frame[frame_origin][1] = _:str_to_float(ExplodedString[2])
		temp_frame[frame_origin][2] = _:str_to_float(ExplodedString[3])
		temp_frame[frame_angles][0] = _:str_to_float(ExplodedString[4])
		temp_frame[frame_angles][1] = _:str_to_float(ExplodedString[5])
		temp_frame[frame_angles][2] = _:str_to_float(ExplodedString[6])
		temp_frame[frame_velocity][0] = _:str_to_float(ExplodedString[7]) 
		temp_frame[frame_velocity][1] = _:str_to_float(ExplodedString[8])
		temp_frame[frame_velocity][2] = _:str_to_float(ExplodedString[9])
		temp_frame[frame_buttons] = _:str_to_num(ExplodedString[10])
		temp_frame[frame_time] = _:str_to_float(ExplodedString[11])
		ArrayPushArray(bot_sources[id][source_array], temp_frame)
		
	}
	fclose(file)
	
	return id;
}

public save_run(id, demo_time[32], bool:is_demofile)
{
	new sz_name[32], sz_steam[32], filename[128]
	if(!is_demofile)
	{
		get_user_name(id, sz_name, 63);	
		get_user_authid(id, sz_steam, 63);
	}
	else
	{
		copy(sz_name, 32, bot_sources[id][source_name]);
		copy(demo_time, 32, bot_sources[id][source_time])
		sz_steam = "DEMO"
	}
	replace_all(sz_name, charsmax(sz_name), "^"", "");
	replace_all(sz_name, charsmax(sz_name), "^'", "");
	
	format(filename, charsmax(filename), "%s/[%s] %s.rec", map_records_dir, demo_time, sz_name);
	new file = fopen(filename, "wb");
	new string[300];
	format(string, charsmax(string), "HEADER ^"%s^" ^"%s^" ^"%s^" ^n", sz_name, sz_steam, demo_time);
	fputs(file, string);
	
	new Array:array;
	if(is_demofile)
	{
		array = bot_sources[id][source_array]
		
	}
	else
	{
		array = record_info[id]
	}
	
	new arrsize = ArraySize(array);
	new temp_frame[frame_data];	
	for(new i = 0; i < arrsize; i++ )
	{
		ArrayGetArray( array, i, temp_frame );		
		format(string, charsmax(string), "INFO %f %f %f %f %f %f %f %f %f %d %f^n", temp_frame[frame_origin][0],
		temp_frame[frame_origin][1], temp_frame[frame_origin][2], temp_frame[frame_angles][0], temp_frame[frame_angles][1],
		temp_frame[frame_angles][2], temp_frame[frame_velocity][0], temp_frame[frame_velocity][1], temp_frame[frame_velocity][2],
		temp_frame[frame_buttons], temp_frame[frame_time]);
		fputs(file, string);
	}
		
	fclose(file);
	
	if(!is_demofile)
	{
		new bool:replacesource = false;
		new replaceid;
		if(sources_num)
		{
			for(new i = 0; i < sources_num; i++)
			{
				if(!bot_sources[id][source_type])
				{
					replacesource = true;
					replaceid = i;
					break;
				}
			}
		}	
		if(replacesource)
		{
			arrayset(plr_botnamed, false, 32);
			new recordbackup[128];
			format(recordbackup, charsmax(recordbackup), "%s.bak", bot_sources[replaceid][source_path]);
			fcopy(bot_sources[replaceid][source_path],recordbackup, FW_CANOVERRIDE | FW_DELETESOURCE);
		}		
		new id = sources_num;
		if(replacesource)	
			id = replaceid;
		
		bot_sources[id][source_id] = id;
		bot_sources[id][source_name] = sz_name;
		bot_sources[id][source_time] = demo_time;	
		bot_sources[id][source_path] = filename;		
		bot_sources[id][source_startframe] = 0;	
		ArrayGetArray( array, 1, temp_frame );	
		bot_sources[id][source_starttime] = _:temp_frame[frame_time];
		bot_sources[id][source_stoptime] = _:0.0;
		bot_sources[id][source_type] = 0;			
		CloneRun(array, bot_sources[id][source_array], true);
		
		if(!replacesource)
			sources_num++
		//kzbot_create_bot(id);
		
	}
}

public already_parsed(player_name[], wr_time[])
{
	for(new i = 0; i < MAX_SOURCES; i++)
	{
		remove_quotes(bot_sources[i][source_name])
		remove_quotes(bot_sources[i][source_time])
		trim(bot_sources[i][source_name])
		trim(bot_sources[i][source_time])
		if(equal(bot_sources[i][source_time],wr_time) && equal(bot_sources[i][source_name], player_name))
		{
			return true;
		}		
	}
	return false;
}
public OnDemosComplete(is_cosy)
{		
	new iArchiveName[256];	
	new datadir[128], record_list[128];
	get_localinfo( "amxx_datadir", datadir, charsmax( datadir ) );
	format(datadir, charsmax(datadir), "%s/%s", datadir, rec_foldername);	
	if(!is_cosy)
	{
		format(record_list, charsmax(record_list), "%s/record_list.txt", datadir);
		server_print( "Parsing XJ Demo List" );
	}
	else
	{
		format(record_list, charsmax(record_list), "%s/record_list2.txt", datadir);
		server_print( "Parsing CC Demo List" );
	}
	new ExplodedString[7][128];
	new Line[128];
	new MapName[2][64];
	get_mapname( MapName[0], 63 );
	format(MapName[1], charsmax(MapName[]), "%s[", MapName[0]);
	format(MapName[0], charsmax(MapName[]), "%s ", MapName[0]);
	new lines = file_size(record_list, 1);
	for(new i = 1; i < lines; i++)
	{	
		new len;
		read_file(record_list, i, Line, charsmax( Line ), len);
		//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[0] ) > -1 || containi( parsedmap, MapName[1] ) > -1  )
		{
			new sWRTime[24];
			new Float:Date = str_to_float( ExplodedString[1] );
			fnConvertTime( Date, sWRTime, charsmax( sWRTime ) );
			if(is_cosy)
				strtolower(ExplodedString[0]);
			format( iArchiveName, charsmax( iArchiveName ), "%s_%s_%s", ExplodedString[0], ExplodedString[2], sWRTime );
			new iLink[512];
			if(!is_cosy)
				format( iLink, charsmax( iLink ), "http://files.xtreme-jumps.eu/demos/%s.rar", iArchiveName );
			else
				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 );	
			
			if(!already_parsed(ExplodedString[2], sWRTime))
				curl_download_file(datadir, iLink, ExplodedString[2], sWRTime );		
		}
	}
	return -1;
}

public process_list( filename[] )
{
	if(contain(filename, "record_list2") != -1)
	{
		OnDemosComplete(1);
	}
	else
		OnDemosComplete(0);		
}
public process_demo(id)
{
	new filename[128]
	read_args(filename, charsmax(filename))
	new file = fopen(filename, "rb");
	if(is_valid_demo_file(file))
	{
		if(read_demo_header( file ))
		{
			new Ent = engfunc( EngFunc_CreateNamedEntity , engfunc( EngFunc_AllocString,"info_target" ) );
			set_pev(Ent, pev_classname, rec_demoparser);
			set_pev(Ent, pev_iuser1, file );
			set_pev(Ent, pev_iuser2, sources_num );
			set_pev(Ent, pev_iuser3, EncodeText(filename) );
			formatex(bot_sources[sources_num][source_name], 32, "test");
			formatex(bot_sources[sources_num][source_time], 32, "test");
			set_pev(Ent, pev_nextthink, get_gametime() + 0.01 );				
			sources_num++
		}
	}
	
}
public process_archive( filename[128], player_name[], wr_time[])
{
	//new length = strlen(filename);
	new destname[128]
	//delete_file(filename);
	get_localinfo( "amxx_datadir", destname, charsmax( destname ) );
	format(destname, charsmax(destname), "%s/demo%d.dem", destname, sources_num);
	AA_Unarchive(filename, destname);	
	//replace(filename, length, ".rar", ".dem");
	new file = fopen(destname, "rb");
	if(is_valid_demo_file(file))
	{
		if(read_demo_header( file ))
		{
			new Ent = engfunc( EngFunc_CreateNamedEntity , engfunc( EngFunc_AllocString,"info_target" ) );
			set_pev(Ent, pev_classname, rec_demoparser);
			set_pev(Ent, pev_iuser1, file );
			set_pev(Ent, pev_iuser2, sources_num );
			set_pev(Ent, pev_iuser3, EncodeText(filename) );
			formatex(bot_sources[sources_num][source_name], 32, "%s", player_name, wr_time);
			formatex(bot_sources[sources_num][source_time], 32, "%s", wr_time);
			set_pev(Ent, pev_nextthink, get_gametime() + 3.0 );				
			sources_num++
		}
	}
}

public bool:is_valid_demo_file( file )
{
	fseek( file, 0, SEEK_END );
	new header_size = ftell( file );


	if ( header_size < 544 )
	{
		return(false);
	}

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

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

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

	return(true);
}



/************************************************
* 						*
*	      INTERNET STREAM SECTION (CURL)	*	
*	 					*
*************************************************/

#define CURL_BUFFER_SIZE 256

public curl_download_file( file[], link[], player_name[], wr_time[]  )
{
	new data[4]
	
	data[0] = fopen(file, "wb")
	data[1] = EncodeText( file );
	data[2] = EncodeText( player_name );
	data[3] = EncodeText( wr_time );
   
	new CURL:curl = curl_easy_init();
	curl_easy_setopt(curl, CURLOPT_URL, link);
	curl_easy_setopt(curl, CURLOPT_WRITEDATA, data[0]);
	/* ATTENTION ATTENTION ATTENTION
	
	Without CURLOPT_NOSIGNAL on Linux Machines CURL can cause SEG FAULT even on idle state (idk why), better not remove this line
	
	ATTENTION ATTENTION ATTENTION*/
	curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1);
	curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, "write");
	curl_easy_perform(curl, "complite", data, sizeof(data));
}

public write(data[], size, nmemb, file)
{
	new actual_size = size * nmemb;
	
	fwrite_blocks(file, data, actual_size, BLOCK_CHAR)
	
	return actual_size	
}

public complite(CURL:curl, CURLcode:code, data[])
{
	static file[128];
	static player_name[32];
	static wr_time[16];	
	fclose(data[0])	
	curl_easy_cleanup(curl)	
	DecodeText(data[1], file, charsmax(file))
	DecodeText(data[2], player_name, charsmax(player_name))
	DecodeText(data[3], wr_time, charsmax(wr_time))
	
	if(containi(file, ".txt") != -1)
	{
		process_list(file);
	}
	else
	{
		process_archive(file, player_name, wr_time);
	}	
}

/************************************************
* 						*
*		BOT MANAGE SECTION 		*
*	 					*
*************************************************/

public kzbot_settings(id)
{
	new menu = menu_create( "\rBot Playback:", "kzbot_settings_handle" );
	new text[256];	
	menu_additem( menu, "\wStart/Restart Bot", "1");	
	menu_additem( menu, "\wPause/Unpause Bot", "2");
	menu_additem( menu, "\wStop Bot", "3");
	if(global_bot)
		menu_additem( menu, "\wKick Bot", "4", ADMIN_KICK);			
	else
		menu_additem( menu, "\wAdd Bot", "4", ADMIN_KICK);	
	menu_additem( menu, "\wFast forward", "5");	
	menu_additem( menu, "\wFast backward", "6");
	format(text, charsmax(text), "\wFast Interval: %0.f sec ", float(plr_jump[id])/100.0);	
	menu_additem(menu, text, "7");
	format(text, charsmax(text), "\wBot mode: %s", bot_modes[plr_mode[id]]);	
	menu_additem(menu, text, "8");
	new sz_name[32]
	format(sz_name, charsmax(sz_name), "[%s] %s %.2s:%.2s.%.2s", bot_sources[plr_source[id]][source_type] == 1 ? "WR" : "REC", bot_sources[plr_source[id]][source_name], bot_sources[plr_source[id]][source_time], bot_sources[plr_source[id]][source_time][2], bot_sources[plr_source[id]][source_time][5]);
	format(text, charsmax(text), "\wBot Source: %s", sz_name);
	menu_additem( menu, text, "9");
	menu_additem( menu, "Exit", "0" )
	
	menu_setprop(menu, MPROP_PERPAGE, 0);
	menu_setprop( menu, MPROP_EXIT, MEXIT_ALL );
	menu_display( id, menu, 0 );
	
	return PLUGIN_HANDLED;
}

public kzbot_settings_handle(id, menu, item)
{
	if( item == MENU_EXIT ) 
	{ 
		menu_destroy( menu ); 
		return PLUGIN_HANDLED; 
	} 
	switch( item )
	{
		case 0:
		{		
			plr_frame_it[id] = 0;
			plr_playback[id] = true;
		}
		case 1:
		{		
			plr_playback[id] = !plr_playback[id]
		}
		case 2:
		{		
			plr_frame_it[id] = 0;
			plr_playback[id] = false;
		}
		case 3:
		{
			if((get_user_flags(id) & ADMIN_KICK))
			{
				if(global_bot)
				{
					server_cmd("kick #%d",get_user_userid(global_bot))				
					global_bot = 0;
				}
				else
				{
					global_bot = makebot("Record bot");
					arrayset(plr_botnamed, false, 32);
				}
			}
		}
		case 4:
		{
			plr_frame_it[id] += plr_jump[id];			
			if(plr_frame_it[id] > ArraySize(bot_sources[plr_source[id]][source_array])-1)
			{
				plr_frame_it[id] = 0;
			}
		}
		case 5:
		{
			plr_frame_it[id] -= plr_jump[id];
			
			if(plr_frame_it[id] < 0)
			{
				plr_frame_it[id] = 0;
			}
		}
		case 6:
		{
			plr_jump[id] += 300;
			if(plr_jump[id] > 3000)
			{
				plr_jump[id] = 300;
			}
			
		}
		case 7:
		{
			if(++plr_mode[id] > sizeof(bot_modes)-1)
				plr_mode[id] = 0;
		}
		case 8:
		{
			if(++plr_source[id] == sources_num)
				plr_source[id] = 0;
			
			update_sourcename(id)				
		}
		case 9:
		{
			menu_destroy( menu ); 
			return PLUGIN_HANDLED; 
		}
	}
	
	kzbot_settings(id)
	
	return PLUGIN_HANDLED; 
}

public kzbot_menu(id)
{
	kzbot_settings(id);

}

public makebot(name[64])
{	
	remove_quotes(name);
	trim(name)
	new bot = engfunc( EngFunc_CreateFakeClient, name );
	if ( !bot )
	{
		server_print( "Couldn't create a bot, server full?" );
		return 0;
	}
	
	engfunc( EngFunc_FreeEntPrivateData, bot );
	bot_settings( bot );

	static szRejectReason[128];
	dllfunc( DLLFunc_ClientConnect, bot, name, "127.0.0.1", szRejectReason );
	if ( !is_user_connected( bot ) )
	{
		server_print( "Connection rejected: %s", szRejectReason );
		return 0;
	}

	dllfunc( DLLFunc_ClientPutInServer, bot );
	set_pev( bot, pev_spawnflags, pev( bot, pev_spawnflags ) | FL_FAKECLIENT );
	set_pev( bot, pev_flags, pev( bot, pev_flags ) | FL_FAKECLIENT );

	engclient_cmd( bot , "jointeam" , "2" )
	engclient_cmd( bot , "joinclass" , "1" )
	fm_cs_set_user_team(bot, 2);
	ExecuteHamB( Ham_CS_RoundRespawn, bot );
	fm_set_user_godmode( bot, 1 );
	return bot;
}

public bot_settings( id )
{
	set_user_info( id, "model", "gordon" );
	set_user_info( id, "rate", "3500" );
	set_user_info( id, "cl_updaterate", "30" );
	set_user_info( id, "cl_lw", "0" );
	set_user_info( id, "cl_lc", "0" );
	set_user_info( id, "tracker", "0" );
	set_user_info( id, "cl_dlmax", "128" );
	set_user_info( id, "lefthand", "1" );
	set_user_info( id, "friends", "0" );
	set_user_info( id, "dm", "0" );
	set_user_info( id, "ah", "1" );

	set_user_info( id, "*bot", "1" );
	set_user_info( id, "_cl_autowepswitch", "0" );
	set_user_info( id, "_vgui_menu", "0" );         /* disable vgui so we dont have to */
	set_user_info( id, "_vgui_menus", "0" );        /* register both 2 types of menus :) */
}

	
/************************************************
* 						*
*		NATIVES SECTION 		*
*	 					*
*************************************************/


public delayed_save(id, data[32])
{
	plr_saverun_time[id] = data;
	plr_delayed_save[id] = true;
	plr_delayed_timer[id] = get_gametime() + 1.0;
}

public native_save_run(plugin_id, params)
{
	static id; id = get_param(1);
	new demo_time[32];
	get_string(2,demo_time,31);
	delayed_save(id, demo_time);
}

public native_reset_run(plugin_id, params)
{
	static id; id = get_param(1);
	if(plr_delayed_save[id])
	{
		save_run(id, plr_saverun_time[id], false);
		plr_delayed_save[id] = false;
	}
	if(global_bot != id)
		ArrayClear(record_info[id]);
}

public native_pause_run(plugin_id, params)
{
	static id; id = get_param(1);
	is_recording[id] = false;
}

public native_unpause_run(plugin_id, params)
{
	static id; id = get_param(1);
	is_recording[id] = true;	
}
	
/************************************************
* 						*
*		STOCK UTILITIES SECTION 	*
*	 					*
*************************************************/

#define BUFFERSIZE    256

stock fcopy(read_path[], dest_path[], FWrite:flags = FW_NONE) 
{ 
    // Prepare for read  
    new fp_read = fopen(read_path, "rb") 

    // No file to read, errors! 
    if (!fp_read) 
    { 
        fclose(fp_read) 
        return 0 
    } 

    // If the native cannot override 
    if (file_exists(dest_path) && !(flags & FW_CANOVERRIDE)) 
    {
        return 0 
    } 

    // Prepare for write  
    new fp_write = fopen(dest_path, "wb") 

    // Used for copying 
    static buffer[BUFFERSIZE] 
    static readsize 
  
    // Find the size of the files
    fseek(fp_read, 0, SEEK_END);
    new fsize = ftell(fp_read);
    fseek(fp_read, 0, SEEK_SET);
  
    // Here we copy the info 
    for (new j = 0; j < fsize; j += BUFFERSIZE) 
    { 
        readsize = fread_blocks(fp_read, buffer, BUFFERSIZE, BLOCK_CHAR); 
        fwrite_blocks(fp_write, buffer, readsize, BLOCK_CHAR); 
    } 
  
    // Close the files 
    fclose(fp_read) 
    fclose(fp_write) 
  
    // Can delete source? 
    if (flags & FW_DELETESOURCE) 
        delete_file(read_path) 
  
    // Success 
    return 1 
}  

stock 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);
}


stock 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 );

	return(PLUGIN_HANDLED);
}

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

stock fm_cs_set_user_team(id, team)
{
    if(!(1 <= id <= maxplayers) || pev_valid(id) != PEV_PDATA_SAFE)
    {
        return 0
    }

    switch(team)
    {
        case 1:
        {
            new iDefuser = get_pdata_int(id, OFFSET_DEFUSE_PLANT)
            if(iDefuser & HAS_DEFUSE_KIT)
            {
                iDefuser -= HAS_DEFUSE_KIT
                set_pdata_int(id, OFFSET_DEFUSE_PLANT, iDefuser)
            }
            set_pdata_int(id, OFFSET_TEAM, 1)
        //    set_pdata_int(id, OFFSET_INTERNALMODEL, 4)
        }
        case 2:
        {
            if(pev(id, pev_weapons) & (1<<CSW_C4))
            {
                engclient_cmd(id, "drop", "weapon_c4")
            }
            set_pdata_int(id, OFFSET_TEAM, 2)
        //    set_pdata_int(id, OFFSET_INTERNALMODEL, 6)
        }
    }

    dllfunc(DLLFunc_ClientUserInfoChanged, id, engfunc(EngFunc_GetInfoKeyBuffer, id))

    return 1
}

stock EncodeText( const text[] )
{
	return engfunc( EngFunc_AllocString, text )
}

stock DecodeText( const text, string[], const length )
{
	global_get( glb_pStringBase, text, string, length )
}

stock animate_legs(es_handle,  keys, bool:onground)
{
	#define InMove (keys & IN_FORWARD || keys & IN_LEFT || keys & IN_RIGHT || keys & IN_BACK)
	
	//client_print(0, print_chat, "%d", onground);
	if (onground)
	{
		if ( keys & IN_DUCK && InMove )
		{
			set_es(es_handle, ES_GaitSequence, 5 );
		}else if ( keys & IN_DUCK )
		{
			set_es(es_handle, ES_GaitSequence, 2 );
		}else  {
			set_es(es_handle, ES_GaitSequence, 4 );
		}
		if ( keys & IN_JUMP )
		{
			set_es(es_handle, ES_GaitSequence, 6 );
		}else  {
			set_es(es_handle, ES_GaitSequence, 4 );
		}
	}else  {
		set_es(es_handle, ES_GaitSequence, 6 );
		
		if ( keys & IN_DUCK )
		{
			set_es(es_handle, ES_GaitSequence, 5 );
		}
	}
}

stock CloneRun( Array:source_arr, Array:dest_arr, bool:clean )
{
	static len; len = ArraySize(source_arr);	
	static data[frame_data];
	
	if(clean)
		ArrayClear(dest_arr);
		
	for(new i = 0; i < len; i++)
	{
		ArrayGetArray(source_arr, i, data);
		ArrayPushArray(dest_arr, data);
	}
}

stock kick_user(id)
{
	new userid2 = get_user_userid(id)
	if (is_user_bot(id))
		server_cmd("kick #%d", userid2)
}

public playback_sound(id, Float:origin[3])
{
	static stepleft[33];
	
	if(plr_sound[id] > 0)
	{
		return 0;
	}
	
	stepleft[id] = !stepleft[id]
	new irand = random_num(0,1) + (stepleft[id] * 2)
	plr_sound[id] = 300;
	spawnStaticSound(id, origin, step_sounds[irand], 1.0, ATTN_NORM, PITCH_NORM, 0);
	
	return 0;
}


#define clamp_byte(%1)     ( clamp( %1, 0, 255 ) ) 
#define write_coord_f(%1)  ( engfunc( EngFunc_WriteCoord, %1 ) )

stock spawnStaticSound( const index, const Float:origin[3], const soundIndex, const Float:vol, const Float:atten, const pitch, const flags ) 
{     
    message_begin( index ? MSG_ONE : MSG_ALL, SVC_SPAWNSTATICSOUND, .player = index );
    {
        write_coord_f( origin[0] ); 
        write_coord_f( origin[1] ); 
        write_coord_f( origin[2] );
        write_short( soundIndex );
        write_byte( clamp_byte( floatround( vol * 255 ) ) );
        write_byte( clamp_byte( floatround( atten * 64 ) ) );
        write_short( 0 );        
        write_byte( pitch ); 
        write_byte( flags );   
    }
    message_end();
}

stock set_user_fake_name(const id, const name[])
{	
	message_begin(MSG_ONE, SVC_UPDATEUSERINFO, _, id)	
	write_byte(global_bot - 1)
	write_long(get_user_userid(global_bot))
	write_char('\')
	write_char('n')
	write_char('a')
	write_char('m')
	write_char('e')
	write_char('\')
	write_string(name)
	for(new i; i < 16; i++) write_byte(0)
	message_end()
}

public update_sourcename( id )
{
	new sz_name[32]
	format(sz_name, charsmax(sz_name), "[%s] %s %.2s:%.2s.%.2s", bot_sources[plr_source[id]][source_type] == 1 ? "WR" : "REC", bot_sources[plr_source[id]][source_name], bot_sources[plr_source[id]][source_time], bot_sources[plr_source[id]][source_time][2], bot_sources[plr_source[id]][source_time][5]);
	set_user_fake_name(id, sz_name);	
}
The RaiD. is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 01:47.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode