From 4ac8779c54f87b243c24e63bafc4af7b6ac31236 Mon Sep 17 00:00:00 2001 From: Flummi Date: Wed, 3 Jul 2024 17:40:28 +0000 Subject: [PATCH] amxmodx/scripting/KZ_Bot.sma aktualisiert --- amxmodx/scripting/KZ_Bot.sma | 3217 +++++++++++----------------------- 1 file changed, 1055 insertions(+), 2162 deletions(-) diff --git a/amxmodx/scripting/KZ_Bot.sma b/amxmodx/scripting/KZ_Bot.sma index 1671287..bf06605 100644 --- a/amxmodx/scripting/KZ_Bot.sma +++ b/amxmodx/scripting/KZ_Bot.sma @@ -1,2232 +1,1125 @@ #include -#include -#include -#include -#include +#include +#include #include +#include +#include #include - -#pragma dynamic 131072; - -#pragma tabsize 0 -#pragma semicolon 1 - -#define PLUGIN "KZ:Bots" -#define VERSION "2.0.6b" -#define AUTHOR "Garey - Destroman Edited" - -#if defined client_disconnected -#define client_disconnect client_disconnected -#endif - - - -#define MAX_SOURCES 16 - -#define DEBUG - -enum dl_data -{ - dl_distance, - dl_name[32], - dl_type[32], - dl_time[32], - dl_mapname[64] -} - - -enum source_data -{ - source_id, - source_type, - source_name[32], //name - source_time[32], //block & type - source_mapname[64], //mapname - source_path[128], - source_startframe, - Float:source_starttime, - Float:source_stoptime, - Array:source_array -} - -new bot_sources[MAX_SOURCES][source_data]; -new dl_sources[MAX_SOURCES][dl_data]; - -new RARArchive[128], g_szCurrentMap[32]; -static g_FOUNDED_COMMUNITY; -new Array: update_file_data; -new Array: need_update_com; - -new bool:CheckAgain = false; -new bool:bFoundDemo = false; -new bool:g_Check_Filetime = false; -new g_Check_Files; -new const dl_dir[] = "addons/amxmodx/data/kz_downloader"; -new const update_file[] = "addons/amxmodx/data/kz_downloader/wr_filetime.ini"; -new const archive_dir[] = "addons/amxmodx/data/kz_downloader/archives"; -new const temp_dir[] = "addons/amxmodx/data/kz_downloader/temp"; -new local_demo_folder[64] = "addons/amxmodx/data/kz_bot"; -new const kz_lj[] = "addons/amxmodx/configs/kz_longjumps2.txt"; -new bool:kz_lj2 = false; - -const COMMUNITIES = 2; - -new const g_szDemoFiles[][][] = -{ - { "demofilesurl", "demosfilename", "rarfilelink", "community"}, - { "https://xtreme-jumps.eu/demos.txt", "addons/amxmodx/data/kz_downloader/demos.txt", "http://files.xtreme-jumps.eu/demos", "Xtreme-Jumps"}, - { "https://cosy-climbing.net/demoz.txt", "addons/amxmodx/data/kz_downloader/demoz.txt", "https://cosy-climbing.net/files/demos", "Cosy-Climbing"} -}; - -enum _:RecordDemo -{ - URLS, - DEMOS, - LINK, - NAME -}; -//////////////////////////////////////////////////////////////////////////////////////////// - -enum FWrite -{ - FW_NONE = 0, - FW_DELETESOURCE = (1<<0), - FW_CANOVERRIDE = (1<<1) -} - -enum -{ - SOURCE_REC = 1, - SOURCE_WR = 2 -} - -new map_records_dir[128]; - -new const rec_recorder[] = "ent_recorder"; -new const rec_demoparser[] = "dem_think"; -new Array:record_info[33]; - -new global_bot; - - -new sources_num = 0; -new src_num = 0; -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], - Float:frame_movetype[3], - frame_buttons, - Float:frame_time -} - -new ghost_data[33][frame_data]; - -new maxplayers; - -new cvar_mode; -new cvar_deletedemos; - - -new Trie:start_buttons; -new Trie:stop_buttons; - -new step_sounds[5][4]; - -//new CheckVisibilityForward; - - -//////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////// -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_precache() -{ - step_sounds[0][0] = precache_sound("player/pl_step1.wav"); - step_sounds[0][1] = precache_sound("player/pl_step2.wav"); - step_sounds[0][2] = precache_sound("player/pl_step3.wav"); - step_sounds[0][3] = precache_sound("player/pl_step4.wav"); - - step_sounds[1][0] = precache_sound("player/pl_slosh1.wav"); - step_sounds[1][1] = precache_sound("player/pl_slosh2.wav"); - step_sounds[1][2] = precache_sound("player/pl_slosh3.wav"); - step_sounds[1][3] = precache_sound("player/pl_slosh4.wav"); - - step_sounds[2][0] = precache_sound("player/pl_wade1.wav"); - step_sounds[2][1] = precache_sound("player/pl_wade2.wav"); - step_sounds[2][2] = precache_sound("player/pl_wade3.wav"); - step_sounds[2][3] = precache_sound("player/pl_wade4.wav"); - - step_sounds[3][0] = precache_sound("player/pl_swim1.wav"); - step_sounds[3][1] = precache_sound("player/pl_swim2.wav"); - step_sounds[3][2] = precache_sound("player/pl_swim3.wav"); - step_sounds[3][3] = precache_sound("player/pl_swim4.wav"); - - step_sounds[4][0] = precache_sound("player/pl_ladder1.wav"); - step_sounds[4][1] = precache_sound("player/pl_ladder2.wav"); - step_sounds[4][2] = precache_sound("player/pl_ladder3.wav"); - step_sounds[4][3] = precache_sound("player/pl_ladder4.wav"); -} - -public plugin_init () -{ - register_plugin( PLUGIN, VERSION, AUTHOR); - - register_clcmd( "kzbot_settings","kzbot_settings" ); - register_clcmd( "amx_botmenu","kzbot_settings" ); - register_clcmd( "say /bot","kzbot_settings" ); - register_clcmd( "say /replay","kzbot_settings" ); - register_clcmd( "say /demo","kzbot_settings" ); - - cvar_mode = register_cvar("kzbot_on", "1"); - cvar_deletedemos = register_cvar("kzbot_removedemos", "0"); - - 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", "fwdUse", 1); - register_forward(FM_AddToFullPack,"fw_addtofullpack_pre", 1); - register_forward(FM_AddToFullPack,"fw_addtofullpack", 1); - register_forward(FM_UpdateClientData, "fw_updateclientdata", 1); - register_forward(FM_CheckVisibility,"checkVisibility"); - register_forward(FM_ClientUserInfoChanged, "fw_clientinfochanged", 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 ); - } - - get_mapname(g_szCurrentMap, charsmax(g_szCurrentMap)); - if(equali(g_szCurrentMap, "kz_longjumps2")) - { - kz_lj2 = true; - kz_longjumps2(); - } - set_task(5.0, "checkwrs"); - -} - -public checkwrs() -{ - if(kz_lj2) - { - new ljname[64]; - - formatex(ljname, charsmax(ljname), "%d_%s", dl_sources[src_num][dl_distance], dl_sources[src_num][dl_type]); - if(!already_parsed(dl_sources[src_num][dl_name], ljname)) - { - Check_Download_Demos( 1, true, true); - } - } - else - { - Check_Download_Demos( 1, false, false); - } -} - -public kz_longjumps2() -{ - if(file_exists(kz_lj)) - { - g_FOUNDED_COMMUNITY = 1; - new lj2_file = fopen( kz_lj, "rb" ); - new Line[64]; - new ExplodedString[4][65]; - - while (!feof(lj2_file)) - { - fgets (lj2_file, Line, charsmax(Line)); - - ExplodeString(ExplodedString, 3, 64, Line, ' '); - if(strlen(Line) > 0) - { - trim(ExplodedString[0]); - trim(ExplodedString[1]); - trim(ExplodedString[2]); - - if(!equal(ExplodedString[0], "Block")) - { - src_num++; - dl_sources[src_num][dl_distance] = str_to_num(ExplodedString[0]); - formatex(dl_sources[src_num][dl_type], charsmax(dl_sources[][dl_type]), ExplodedString[1]); - formatex(dl_sources[src_num][dl_name], charsmax(dl_sources[][dl_name]), ExplodedString[2]); - } - } - } - fclose(lj2_file); - } - else - { - server_print("File %s not exists", kz_lj); - } -} - - -public plugin_cfg() -{ - new file; - if(!dir_exists(dl_dir)) - mkdir(dl_dir); - - if(!file_exists(update_file)) - { - file = fopen(update_file, "w"); - fclose(file); - } - - if(file_size(update_file, 1) < COMMUNITIES) - { - delete_file(update_file); - file = fopen(update_file, "w"); - new line[32]; - for(new data = 1; data <= COMMUNITIES; data++) - { - format(line, charsmax(line), "%d 1337%d", data, data); - write_file(update_file, line, -1); - } - fclose(file); - } - - if(!dir_exists(archive_dir)) - mkdir(archive_dir); - if(!dir_exists(temp_dir)) - mkdir(temp_dir); - if(!dir_exists(local_demo_folder)) - mkdir(local_demo_folder); - if(get_pcvar_num(cvar_deletedemos)) - rmdir_recursive(local_demo_folder); - format(map_records_dir, charsmax(map_records_dir), "%s/%s", local_demo_folder ,g_szCurrentMap); - 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); - - set_task(3.0, "create_bot"); - - update_file_data = ArrayCreate(32); - need_update_com = ArrayCreate(COMMUNITIES); -} - - -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; - } -} - - -//////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////CURL FOR CHECK AND DOWNLOAD DEMOS AND ARCHIVES//////////////////// -////////////////////////////////////////FileType//////////////////////////////////////////// -/////////////////////////////// 0 - Demos, 1 - Archive ///////////////////////////////////// -///////////////////////////////for kz_lj2 community, download/////////////////////////////// - -public Check_Download_Demos(Community, bool:Download, bool:Filetype) -{ - #if defined DEBUG - server_print("PARSING CHECK COMMUNITY-%d, DOWNLOAD-%d, FILETYPE-%d", Community, Download ,Filetype ); - #endif - - new data[3]; - data[1] = Community; - data[2] = Filetype; - - new CURL:curl = curl_easy_init(); - - curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); - curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1); - #if defined DEBUG - //curl_easy_setopt(curl, CURLOPT_VERBOSE, 1); //CURL ANALYZE OPTION - #endif - if(kz_lj2) - { - new Link[256]; - format(Link, charsmax(Link), "%s/lj/%s/%d_%s_%s.rar", g_szDemoFiles[Community][LINK], dl_sources[src_num][dl_type], dl_sources[src_num][dl_distance], dl_sources[src_num][dl_type], dl_sources[src_num][dl_name]); - - #if defined DEBUG - server_print("[LINK] : %s", Link); - #endif - - curl_easy_setopt(curl, CURLOPT_URL, Link); - new archivefile[128]; - format (archivefile, charsmax(archivefile), "%s/%d_%s_%s.rar", archive_dir, dl_sources[src_num][dl_distance], dl_sources[src_num][dl_type], dl_sources[src_num][dl_name]); - - data[0] = fopen(archivefile, "wb"); - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 20); - curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 512); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, data[0]); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, "write"); - curl_easy_perform(curl, "complete", data, sizeof(data)); - } - else - { - if (!Filetype) - { - curl_easy_setopt(curl, CURLOPT_URL, g_szDemoFiles[Community][URLS]); - if(Download) - { - data[0] = fopen(g_szDemoFiles[Community][DEMOS], "wb"); - } - } - else - { - new destname[128]; - format(destname, charsmax(destname), "%s_%s_%s.rar", dl_sources[src_num][dl_mapname], dl_sources[src_num][dl_name], dl_sources[src_num][dl_time]); - - new Link[256]; - format(Link, charsmax(Link), "%s/%s", g_szDemoFiles[Community][LINK], destname); - #if defined DEBUG - server_print("[LINK] : %s", Link); - #endif - - curl_easy_setopt(curl, CURLOPT_URL, Link); - - new archivefile[128]; - format (archivefile, charsmax(archivefile), "%s/%s", archive_dir, destname); - data[0] = fopen(archivefile, "wb"); - } - if(Download) - { - curl_easy_setopt(curl, CURLOPT_BUFFERSIZE, 512); - curl_easy_setopt(curl, CURLOPT_WRITEDATA, data[0]); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, "write"); - } - else - { - curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 20); - curl_easy_setopt(curl, CURLOPT_NOBODY, 1); - curl_easy_setopt(curl, CURLOPT_FILETIME, 1); - curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, "write_null"); - } - curl_easy_perform(curl, "complete", 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 write_null(data[], size, nmemb, file) -{ - new actual_size = size * nmemb; - return actual_size; -} - -public complete(CURL:curl, CURLcode:code, data[]) -{ - new Community = data[1]; - static filetime, iResponceCode; - curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, iResponceCode); - curl_easy_getinfo(curl, CURLINFO_FILETIME, filetime); - curl_easy_cleanup(curl); - - new comm[64]; - - if(data[0]) - { - fclose(data[0]); - } - if(kz_lj2) - { - new filename[128]; - - format (filename, charsmax(filename), "%s/%d_%s_%s.rar", archive_dir, dl_sources[src_num][dl_distance], dl_sources[src_num][dl_type], dl_sources[src_num][dl_name] ); - - if (iResponceCode > 399) - { - delete_file(filename); - #if defined DEBUG - server_print("[ERROR] : iResponceCode: %d", iResponceCode); - #endif - server_print("Can't Download archive %s from file %s", filename , kz_lj); - } - else - { - #if defined DEBUG - server_print("[COMPLETE] : iResponceCode: %d - file: %s", iResponceCode, filename); - #endif - DownloadArchiveComplete(filename); - } - } - else - { - if(!data[0]) - { - if(iResponceCode == 0 && filetime == -1) - { - #if defined DEBUG - server_print("Can't Connect to %s", g_szDemoFiles[Community][NAME]); - #endif - set_task (1.0, "UpdateComplete"); - return; - } - #if defined DEBUG - server_print("Connection to %s successfull", g_szDemoFiles[Community][NAME]); - #endif - new com, dat; - new Line[32], ExplodedString[3][33], newLine[32]; - - new recordsfile = fopen( update_file, "rb" ); - while (!feof(recordsfile)) - { - fgets (recordsfile, Line, charsmax(Line)); - ExplodeString(ExplodedString, 2, 32, Line, ' '); - - if(strlen(Line) > 0) { - - - com = str_to_num(ExplodedString[0]); - dat = str_to_num(ExplodedString[1]); - - - if(com == Community && dat) - { - if((filetime != dat && filetime > 0) || file_exists( g_szDemoFiles[Community][DEMOS]) == 0) - { - dat = filetime; - ArrayPushCell(need_update_com, Community); - } - format(newLine, charsmax(newLine), "%d %d", Community, dat); - ArrayPushString(update_file_data, newLine); - } - } - } - fclose(recordsfile); - if(Community == COMMUNITIES) - { - g_Check_Filetime = true; - new i_size = ArraySize(need_update_com); - if(i_size) - { - bFoundDemo = false; - g_Check_Files = i_size; - delete_file(update_file); - new file = fopen(update_file, "w"); - for(new i = 0; i < COMMUNITIES; i++) - { - ArrayGetString(update_file_data, i, comm, charsmax(comm)); - write_file(update_file, comm, i); - } - fclose(file); - } - } - else - { - Check_Download_Demos(Community + 1, false, false); - return; - } - } - if(g_Check_Filetime) - { - if(g_Check_Files > 0) - { - #if defined DEBUG - server_print("UpdateNeeded() - %d", g_Check_Files); - #endif - new upd; - upd = ArrayGetCell(need_update_com, g_Check_Files - 1); - g_Check_Files--; - Check_Download_Demos(upd, true, false); - return; - } - else - { - g_Check_Filetime = false; - set_task (1.0, "UpdateComplete"); - return; - } - } - if(data[2]) - { - new destname[128]; - - format(destname, charsmax(destname), "%s_%s_%s", dl_sources[src_num][dl_mapname], dl_sources[src_num][dl_name], dl_sources[src_num][dl_time]); - - new filename[128]; - format( filename, charsmax( filename ), "%s/%s.rar",archive_dir, destname); - - if (iResponceCode > 399 && !CheckAgain) - { - delete_file(filename); - bFoundDemo = false; - CheckAgain = true; - #if defined DEBUG - server_print("[ERROR] : iResponceCode: %d", iResponceCode); - #endif - OnDemosComplete(Community); - return; - - } - else if (iResponceCode > 399 && CheckAgain) - { - delete_file(filename); - server_print("*No World Record on this map!"); - } - else - { - if(iResponceCode > 0) - { - CheckAgain = false; - #if defined DEBUG - server_print("[COMPLETE] : iResponceCode: %d - file: %s", iResponceCode, filename); - #endif - DownloadArchiveComplete(filename); - return; - } - } - } - } -} - -public UpdateComplete() -{ - #if defined DEBUG - server_print("UpdateComplete()"); - #endif - if(!bFoundDemo) - { - new i; - for(i = 1; i <= COMMUNITIES; i++) - { - if(bFoundDemo) - { - break; - } - OnDemosComplete(i); - } - } - if(!bFoundDemo) - { - server_print("*No WR on this map!"); - } -} - -public OnDemosComplete(Community) -{ - new demoslist[128]; - format( demoslist, charsmax(demoslist), "%s", g_szDemoFiles[Community][DEMOS] ); - - #if defined DEBUG - server_print( "Parsing %s Demo List", g_szDemoFiles[Community][NAME]); - #endif - new iDemosList = fopen( demoslist, "rb" ); - new ExplodedString[7][64]; - new Line[64]; - - while ( !feof( iDemosList ) ) - { - fgets(iDemosList, Line, charsmax(Line)); - ExplodeString(ExplodedString, 6, 63, Line, ' '); - new parsedmap[64], DLMap[64], Extens[32], Mapa[32]; - - parsedmap = ExplodedString[0]; - trim(parsedmap); - new Float:Time = str_to_float( ExplodedString[1]); - - if (containi(parsedmap, g_szCurrentMap ) == 0 && Time > 0.0) - { - split(parsedmap, Mapa, 31, Extens, 31, "["); - trim(Mapa); - trim(Extens); - - if(equali(Mapa, g_szCurrentMap)) - { - src_num++; - if(containi(parsedmap, "[" ) > -1) - { - format( DLMap, charsmax( DLMap ), "%s[%s", Mapa, Extens ); - if(CheckAgain) - { - strtolower(DLMap); - } - - } - else { - format( DLMap, charsmax( DLMap ), "%s", Mapa ); - if(CheckAgain) - { - strtolower(DLMap); - } - } - - #if defined DEBUG - server_print("Parsedmap |%s|", DLMap); - #endif - bFoundDemo = true; - g_FOUNDED_COMMUNITY = Community; - - formatex(dl_sources[src_num][dl_name], charsmax(dl_sources[][dl_name]), ExplodedString[2]); - formatex(dl_sources[src_num][dl_mapname], charsmax(dl_sources[][dl_mapname]), DLMap); - - fnConvertTime(Time, dl_sources[src_num][dl_time], charsmax( dl_sources[][dl_time])); - - #if defined DEBUG - //server_print("Archivename %s_%s_%s", dl_sources[src_num][dl_mapname], dl_sources[src_num][dl_name], dl_sources[src_num][dl_time]); - #endif - } - } - } - fclose(iDemosList); - if(!already_parsed(dl_sources[src_num][dl_name], dl_sources[src_num][dl_time])) - { - Check_Download_Demos(Community, true, true); - } -} - -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; -} - -//////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////AMXXARCH FOR UNARCHIVE ZIP AND RAR FILES////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////// - -public DownloadArchiveComplete(Archive[]) -{ - format( RARArchive, charsmax( RARArchive ), "%s", Archive); - - #if defined DEBUG - server_print("RARArchive: %s", RARArchive); - #endif - AA_Unarchive(RARArchive, temp_dir, "@OnComplete", 0); -} - - -@OnComplete(id, iError) -{ - if(iError != AA_NO_ERROR) - { - #if defined DEBUG - server_print("Failed to unpack. Error code: %d", iError); - #endif - } - else - { - delete_file(RARArchive); - new destname[128]; - if(kz_lj2) - { - format(destname, charsmax(destname), "%s/%d_%s_%s.dem", temp_dir, dl_sources[src_num][dl_distance], dl_sources[src_num][dl_type], dl_sources[src_num][dl_name]); - } - else - { - format(destname, charsmax(destname), "%s/%s_%s_%s.dem", temp_dir, dl_sources[src_num][dl_mapname], dl_sources[src_num][dl_name], dl_sources[src_num][dl_time]); - } - 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(destname) ); - if(kz_lj2) - { - format(bot_sources[sources_num][source_name], 32, "%s", dl_sources[src_num][dl_name]); - format(bot_sources[sources_num][source_time], 32, "%d_%s", dl_sources[src_num][dl_distance], dl_sources[src_num][dl_type] ); - } - else - { - formatex(bot_sources[sources_num][source_name], 32, "%s", dl_sources[src_num][dl_name]); - formatex(bot_sources[sources_num][source_time], 32, "%s", dl_sources[src_num][dl_time]); - } - set_pev(Ent, pev_nextthink, get_gametime() + 3.0 ); - sources_num++; - } - } - } -} - -//////////////////////////////////////////////////////////////////////////////////////////// -////////////////////////////////////////BOT//////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////// - -public create_bot() -{ - global_bot = makebot("Record Bot"); - // is_recbot[global_bot] = true; -} - - -public fw_clientinfochanged(id, buffer) -{ - if(id == global_bot) - { - arrayset(plr_botnamed, false, 32); - } -} - -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(id) && !plr_botnamed[id] && global_bot && bot_sources[plr_source[id]][source_type] && 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]; - //xs_vec_copy(ghost_data[id][frame_origin], origins); - 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) - { - static Float:botorigin[3]; - pev(id, pev_origin, botorigin); - - new on_ladder; - new ent = 0; - static Float:entorigin[3]; - static Classname[33]; - - // Change distance if you want. - const Float:Distance_ladder = 15.0; - while((ent = engfunc(EngFunc_FindEntityInSphere, ent, botorigin, Distance_ladder)) != 0) { - if(!pev_valid(ent)) - continue; - - pev(ent, pev_classname, Classname, 32); - if(equal(Classname, "func_ladder")) - { - pev(ent, pev_origin, entorigin); - on_ladder = 1; - break; - } - } - - if(/*pev(id, pev_movetype) == MOVETYPE_FLY*/on_ladder) - { - playback_sound(id, origins, 4); - } - else if(pev(id, pev_watertype) == CONTENTS_WATER) - { - if(pev(id, pev_waterlevel) >= 2) - { - playback_sound(id, origins, 3); - } - else if(pev(id, pev_waterlevel) == 1) - { - playback_sound(id, origins, 2); - } - else - { - playback_sound(id, origins, 1); - } - } - else - { - 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,0); - } - else if(!pev(id, pev_groupinfo)) - { - playback_sound(id, origins, 0); - } - } - } - } - oldbuttons[id] = ghost_data[id][frame_buttons]; - - plr_sound[id] -= 10; - - - return FMRES_IGNORED; -} - - -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])) - { - //forward_return(FMV_CELL, dllfunc(DLLFunc_UpdateClientData, ent, sendweapons, cd_handle)); - set_cd(cd_handle, CD_Origin, ghost_data[id][frame_origin]); - - static Float:neworigin[3]; - xs_vec_copy(ghost_data[id][frame_origin], neworigin); - neworigin[2]+= 20.0; - set_pev(ent, pev_origin, neworigin); - 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 && !kz_lj2) - { - client_print(id, print_center, "[ %.2s:%.2s.%.2s ]", sz_time, sz_time[2], sz_time[5]); - } - return FMRES_IGNORED; - } - return FMRES_IGNORED; -} - - -public checkVisibility(id, pset) -{ - if(!pev_valid(id)) - { - return FMRES_IGNORED; - } - - if(id == global_bot) - { - /*unregister_forward(FM_CheckVisibility,CheckVisibilityForward); - CheckVisibilityForward = 0;*/ - - forward_return(FMV_CELL, 1); - return FMRES_SUPERCEDE; - } - return FMRES_IGNORED; -} - -public fw_addtofullpack_pre(es, e, ent, host, hostflags, player, pSet) -{ - if(global_bot == host) - { - return FMRES_IGNORED; - } - if(player) - { - if((global_bot == ent || pev(host, pev_iuser2) == global_bot) && sources_num) - { - engfunc(EngFunc_CheckVisibility,ent, pSet); - - /*if(!engfunc(EngFunc_CheckVisibility,ent, pSet)) - { - if(!CheckVisibilityForward) - { - CheckVisibilityForward = register_forward(FM_CheckVisibility, "checkVisibility"); - } - }*/ - } - } - 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_RenderFx, kRenderFxSolidSlow, 0); - - if(is_user_alive(host)) - { - set_es(es_handle, ES_RenderAmt, floatround(get_distance_f(origin[0], origin[1]) * 255.0 / 360.0, floatround_floor)); - } - else - { - set_es(es_handle, ES_RenderAmt, 150.0); - } - return FMRES_SUPERCEDE; - } - } - } - return FMRES_IGNORED; -} - - - - -public fwdUse(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 * -* * -*************************************************/ - +#include +#include + +#define PLUGIN "KZ_Bot" +#define VERSION "1.23" +#define AUTHOR "Flummi & MichaelKheel" + +//#define DEV_DEBUG + +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; +new SyncHudBotTimer; +new Trie:g_tButtons[2]; +new url_sprite[64], url_sprite_xz[64]; +new WR_TIME[130], WR_NAME[130], WR_COUNTRY[130], WR_SRC[5]; +new Float:nExttHink = 0.009; +new timer_bot, timer_option; +new Float:flStartTime; #define NUM_THREADS 256 -public forward_think( ent ) -{ - static classname[64]; - 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; - } - 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[128]; - DecodeText(pev(ent, pev_iuser3), filename, charsmax(filename)); - fclose( file ); - delete_file(filename); - src_num--; - if(src_num > 0) - { - Check_Download_Demos( g_FOUNDED_COMMUNITY, true, true); - } - new demo_time[32]; - demo_time = bot_sources[source_index][source_time]; - 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; - //new Float:nextthink = 1//0.009; - 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); - //server_print("paused"); - return FMRES_IGNORED; - } - for ( new i = 0; i < inum; i++ ) - { - - new id = players[i]; - - if(global_bot == id) - { - //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 && sources_num) - 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) - bot_sources[plr_source[id]][source_startframe] = plr_frame_it[id]; - bot_sources[plr_source[id]][source_starttime] = _:ghost_data[id][frame_time]; - } - if (!bot_sources[plr_source[id]][source_stoptime] && TrieKeyExists( stop_buttons, target ) ) - { - //bot_findbuttons(id, global_bot) - bot_sources[plr_source[id]][source_stoptime] = _:ghost_data[id][frame_time]; - } - } - } - } -} - - -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); -} - - -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; - - /* server_print( "%d %d %s %s %d %d %d", iDemoHeader[demoProtocol], iDemoHeader[netProtocol], iDemoHeader[mapName], iDemoHeader[gameDir], iDemoHeader[mapCRC], iDemoHeader[directoryOffset], iDemoEntry[dirEntryCount] ); */ -} - - - -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); -} - - -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: - { - //for ( new i = 0; i < 3; ++i ) - //fread( file, _:temp_data[frame_origin][i], BLOCK_INT ); - - 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; -} - - - -//////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////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]; - if(kz_lj2) - { - format(sz_name, charsmax(sz_name), "[WR] %s %s" , bot_sources[plr_source[id]][source_name], bot_sources[plr_source[id]][source_time]); - } - else - { - format(sz_name, charsmax(sz_name), "[%s] %s %.2s:%.2s.%.2s", bot_sources[plr_source[id]][source_type] == SOURCE_WR ? "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"); - //set_task(0.1, "update_sourcename", id) - } - } - } - 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; - - if(global_bot) - update_sourcename(id); - } - case 9: - { - menu_destroy( menu ); - return PLUGIN_HANDLED; - } - } - - kzbot_settings(id); - - return PLUGIN_HANDLED; -} - -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_give_item(bot, "weapon_knife" ); - set_user_godmode( bot, 1 ); - - set_pev(bot, pev_origin, Float:{8192.0, 8192.0, 8192.0}); - return bot; -} +#pragma dynamic 32767 #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; - } +new bool:g_Demos = false; - 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<= 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]) + Start_Bot(); + timer_started[id] = false; + bot_finish_use[id] = true; + } + } + Distance[1] = vector_distance(origin, eorigin); + } + } } -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); +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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[i], pev_iuser1); + if(specmode == 2 || specmode == 4) { + new target = pev(Dead[i], 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[i], print_center, "[ %02i:%02i.%02i | HP: Godmode | 10aa ]", imin, isec, mili, IsPaused[target] ? "| *Paused*" : ""); + } + else if(get_pcvar_num(timer_option) == 2) { + set_hudmessage(255, 255, 255, -1.0, 0.35, 0, 0.0, 1.0, 0.0, 0.0); + ShowSyncHudMsg(Dead[i], SyncHudBotTimer, "[ %02i:%02i.%02i | HP: Godmode | 10aa ]", imin, isec, mili, IsPaused[target] ? "| *Paused*" : ""); + } + } + else if(!timer_started[target] && target == wr_bot_id) { + client_print(Dead[i], print_center, ""); + } + } + } + } + + entity_set_float(iTimer, EV_FL_nextthink, get_gametime() + 0.07) } -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 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 native_pause_run(plugin_id, params) -{ - static id; id = get_param(1); - is_recording[id] = false; +public fwd_Think(iEnt) { + if(!pev_valid(iEnt)) + return(FMRES_IGNORED); + + static className[32]; + pev(iEnt, pev_classname, className, 31); + + 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); + + // rename file iDemoName -> path/iArchiveName.dem + new sDatadir[128], sNewfile[128]; + get_localinfo("amxx_datadir", sDatadir, charsmax(sDatadir)); + format(sNewfile, charsmax(sNewfile), "%s/demos/%s/%s.dem", sDatadir, g_szMapName, iArchiveName); + if(!rename_file(iDemoName, sNewfile, 1)) // relative + delete_file(iDemoName); + + server_print("from: %s", iDemoName); + server_print(" to: %s", sNewfile); + + 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); + delete_file(iNavName); + set_task(2.0, "StartCountDown"); + } + } + + 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 native_unpause_run(plugin_id, params) -{ - static id; id = get_param(1); - is_recording[id] = true; +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) + Start_Bot(); + } + else + g_bot_frame = 0; + } + nFrame++; } -//////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////STOCKS//////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////// +Create_Bot() { + new txt[64] + formatex(txt, charsmax(txt), "[%s] %s %s (%s)", WR_SRC, WR_NAME, WR_TIME, WR_COUNTRY); + new id = engfunc(EngFunc_CreateFakeClient, txt); + if(pev_valid(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_cmdrate", "60"); + set_user_info(id, "cl_lw", "0"); + set_user_info(id, "cl_lc", "0"); + set_user_info(id, "cl_dlmax", "128"); + set_user_info(id, "cl_righthand", "0"); + set_user_info(id, "ah", "1"); + 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_user_info(id, "_cl_autowepswitch", "1"); + set_user_info(id, "_vgui_menu", "0"); + set_user_info(id, "_vgui_menus", "0"); -stock EncodeText( const text[] ) -{ - return engfunc( EngFunc_AllocString, text ); + static szRejectReason[128]; + dllfunc(DLLFunc_ClientConnect, id, "WR BOT", "127.0.0.1" , szRejectReason); + if(!is_user_connected(id)) { + server_print("Connection rejected: %s", szRejectReason); + return 0; + } + + dllfunc(DLLFunc_ClientPutInServer, id); + set_pev(id, pev_spawnflags, pev(id, pev_spawnflags) | FL_FAKECLIENT); + set_pev(id, pev_flags, pev(id, pev_flags) | FL_FAKECLIENT); + + cs_set_user_team(id, CS_TEAM_CT); + cs_set_user_model(id, "sas"); + cs_set_user_bpammo(id, CSW_USP, 250); + + cs_user_spawn(id); + give_item(id, "weapon_knife"); + give_item(id, "weapon_usp"); + set_user_godmode(id, 1); + + return id; + } + return 0; } -stock DecodeText( const text, string[], const length ) -{ - global_get( glb_pStringBase, text, string, length ); +public StartCountDown() { + if(!wr_bot_id) + wr_bot_id = Create_Bot(); + + g_timer = 0; + set_task(1.0, "Show"); } -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); +public Show() { + g_timer--; + set_hudmessage(255, 255, 255, 0.05, 0.2, 0, 6.0, 1.0); + + if(g_timer && g_timer >= 0) + set_task(1.0, "Show"); + else { + g_bot_enable = 1; + Start_Bot(); + } } - -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); +Start_Bot() { + g_bot_frame = g_bot_start; + timer_started[wr_bot_id] = false; } -stock rmdir_recursive(local_demo_folder[]) -{ - new szFileName[64], sz_dest[512]; - new hDir = open_dir(local_demo_folder, szFileName, charsmax(szFileName)); - - if(!hDir) - { - new file = fopen(local_demo_folder, "rb"); - if(file) - { - fclose(file); - } - return; - } - do - { - if(szFileName[0] != '.' && szFileName[1] != '.') - { - format(sz_dest, 511, "%s/%s", local_demo_folder, szFileName); - - if(!dir_exists(sz_dest)) { - - new demfile = fopen(sz_dest, "r"); - new string[300]; - new demo_type[32]; - - fgets(demfile, string, charsmax(string)); - static ExplodedString[14][32]; - ExplodeString( ExplodedString, 4, 127, string, ' ' ); - - copy(demo_type, 32, ExplodedString[2]); - trim(demo_type); - if(equal(demo_type, "DEMO")) - { - fclose(demfile); - delete_file(sz_dest); - } - else - fclose(demfile); - //new result = delete_file(sz_dest); - //server_print("File delete? - %s - %s", sz_dest, result ? "Yes" : "No"); - } - else { - rmdir(sz_dest); - rmdir_recursive(sz_dest); - } - } - } - while ( next_file( hDir, szFileName, charsmax( szFileName ))); - close_dir(hDir); +public client_disconnected(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; + } } -public bool:is_valid_demo_file( file ) -{ - fseek( file, 0, SEEK_END ); - new header_size = ftell( file ); +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, - if ( header_size < 544 ) - { - return(false); - } + 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 +}; - fseek( file, 0, SEEK_SET ); - new signature[6]; +enum DemoHeader { + netProtocol, + demoProtocol, + mapName[HEADER_MAPNAME_SIZE], + gameDir[HEADER_GAMEDIR_SIZE], + mapCRC, + directoryOffset +}; - fread_blocks( file, signature, sizeof(signature), BLOCK_CHAR ); +enum DemoEntry { + dirEntryCount, + type, + description[DIR_ENTRY_DESCRIPTION_SIZE], + flags, + CDTrack, + trackTime, + frameCount, + offset, + fileLength, + frames, + ubuttons +}; - if ( !contain( "HLDEMO", signature ) ) - { - return(false); - } +enum FrameHeader { + Type, + Float:Timestamp, + Number +}; - return(true); +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_FOLLOWLOCATION, 1); + curl_easy_setopt(curl, CURLOPT_URL, "https://xtreme-jumps.eu/demos.txt"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, "write_xj"); + curl_easy_perform(curl, "complite_xj"); + } } - - - -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 ); - } - } +public write_xj(data[], size, nmemb) { + new real_size = size * nmemb; + for(new i = 0; i < nmemb; i++) + if(i < nmemb) + fwrite(iXJWRs, data[i], BLOCK_BYTE); + return real_size; } -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); - } +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 complite_cc(CURLcode:code, CURL:curl) { + curl_easy_cleanup(curl); + fclose(iCCWRs); -public playback_sound(id, Float:origin[3], type) -{ - 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[type][irand], 1.0, ATTN_NORM, PITCH_NORM, 0); - - return 0; + new datadir[128]; + new filename[128]; + get_localinfo("amxx_datadir", datadir, charsmax(datadir)); + format(filename, charsmax(datadir), "%s/list_kzru.txt", datadir); + delete_file(filename); + iKZRUWRs = fopen(filename, "wb"); + new CURL:curl = curl_easy_init(); + if(curl) { + curl_easy_setopt(curl, CURLOPT_URL, "https://kz-rush.ru/demos.txt"); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, "write_kzru"); + curl_easy_perform(curl, "complite_kzru"); + } } -#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(); +public write_kzru(data[], size, nmemb) { + new real_size = size * nmemb; + for(new i = 0; i < nmemb; i++) + if(i < nmemb) + fwrite(iKZRUWRs, data[i], BLOCK_BYTE); + return real_size; } -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 write_cc(data[], size, nmemb) { + new real_size = size * nmemb; + for(new i = 0; i < nmemb; i++) + if(i < nmemb) + fwrite(iCCWRs, data[i], BLOCK_BYTE); + return real_size; } -public update_sourcename( id ) -{ - new sz_name[32]; - - if(kz_lj2) - { - format(sz_name, charsmax(sz_name), "[WR] %s %s", bot_sources[plr_source[id]][source_name], bot_sources[plr_source[id]][source_time]); - } - else - { - format(sz_name, charsmax(sz_name), "[%s] %s %.2s:%.2s.%.2s", bot_sources[plr_source[id]][source_type] == SOURCE_WR ? "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); +public complite_kzru(CURLcode:code, CURL:curl) { + curl_easy_cleanup(curl); + fclose(iKZRUWRs); + OnDemosComplete(0); } -new RecordFile[128]; - -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] = SOURCE_REC; - 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] = SOURCE_WR; - } - else - { - format(RecordFile, charsmax(RecordFile), filename); - } - 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 OnDemosComplete(Index) { + new demoslist[128]; + get_localinfo("amxx_datadir", demoslist, charsmax(demoslist)); + format(demoslist, charsmax(demoslist), "%s/list_xj.txt", demoslist); + 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]; + WR_COUNTRY = ExplodedString[3]; + 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); + WR_SRC = "XJ"; + 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); + 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]; + WR_COUNTRY = ExplodedString[3]; + 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); + WR_SRC = "CC"; + DownloadDemoArchive(iArchiveName, iLink); + } + if(!bFoundDemo) + CheckKZRUList(); +} -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); - if(file_exists(RecordFile)) - delete_file(RecordFile); - } - else - { - copy(sz_name, 32, bot_sources[id][source_name]); - copy(demo_time, 32, bot_sources[id][source_time]); - bot_sources[id][source_type] = SOURCE_WR; - 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); - //client_print(0, print_chat, "%d", ArraySize( record_info[id] )); - - 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) - { - format(RecordFile, charsmax(RecordFile), filename); - new bool:replacesource = false; - new replaceid; - if(sources_num) - { - for(new i = 0; i < sources_num; i++) - { +public CheckKZRUList() { + new demoslist[128]; + get_localinfo("amxx_datadir", demoslist, charsmax(demoslist)); + format(demoslist, charsmax(demoslist), "%s/list_kzru.txt", demoslist); + 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]; + WR_COUNTRY = ExplodedString[3]; + new iLink[512]; + format(iLink, charsmax(iLink), "https://kz-rush.ru/xr_public/demos/maps/cs16/%s.zip", iArchiveName); + new datadir[128]; + get_localinfo("amxx_datadir", datadir, charsmax(datadir)); + format(datadir, charsmax(datadir), "%s/%s.zip", datadir, iArchiveName); + WR_SRC = "KZRU"; + g_demoExt = "zip"; + DownloadDemoArchive(iArchiveName, iLink); + } +} - if(bot_sources[i][source_type] == SOURCE_REC) - { +public DownloadDemoArchive(iArchiveName[], iLink[]) { + new datadir[128]; + new filename[128]; + get_localinfo("amxx_datadir", datadir, charsmax(datadir)); + + new demodir[128], demodirfile[128]; + format(demodir, charsmax(demodir), "%s/demos", datadir); + format(demodirfile, charsmax(demodirfile), "%s/%s", demodir, g_szMapName); - replacesource = true; - ArrayClear(bot_sources[i][source_array]); - replaceid = i; - break; - } - } - } - if(replacesource) - { - arrayset(plr_botnamed, false, 32); - } - 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, id, temp_frame ); - bot_sources[id][source_starttime] = _:temp_frame[frame_time]; - bot_sources[id][source_stoptime] = _:0.0; - bot_sources[id][source_type] = SOURCE_REC; - CloneRun(array, bot_sources[id][source_array], true); - if(!replacesource) - sources_num++; - } -} \ No newline at end of file + if(!dir_exists(demodir)) + mkdir(demodir); + if(!dir_exists(demodirfile)) + mkdir(demodirfile); + + format(filename, charsmax(datadir), "%s/%s.%s", datadir, iArchiveName, g_demoExt); + iArchive = fopen(filename, "wb"); + new CURL:curl = curl_easy_init(); + 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 datadir[128], RARArchive[128]; + + get_localinfo("amxx_datadir", datadir, charsmax(datadir)); + format(RARArchive, charsmax(RARArchive), "%s/%s.%s", datadir, iArchiveName, g_demoExt); + + server_print(" src: %s", WR_SRC); + server_print(" rar: %s", RARArchive); + + AA_Unarchive(RARArchive, datadir, "@OnComplete", 0); +} +@OnComplete(id, iError) { + new datadir[128]; + get_localinfo("amxx_datadir", datadir, charsmax(datadir)); + format(datadir, charsmax(datadir), "%s/%s.%s", datadir, iArchiveName, g_demoExt); + delete_file(datadir); + + if(iError == AA_NO_ERROR) { + new szNavName[256], demodir1[128], demodir2[128]; + get_localinfo("amxx_datadir", datadir, charsmax(datadir)); + format(szNavName, sizeof(szNavName), "%s", datadir, iArchiveName); + format(demodir1, sizeof(demodir1), "%s/demos", szNavName); + format(demodir2, sizeof(demodir2), "%s/demos/%s", szNavName, g_szMapName); + + if(!dir_exists(demodir1)) + mkdir(demodir1); + if(!dir_exists(demodir2)) + mkdir(demodir2); + + 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(); + } + } + else + LoadParsedInfo(iNavName); + + flStartTime = get_gametime(); + } + else + server_print("Failed to unpack. Error code: %d", iError); +} + +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); + 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("demo is not valid!"); +} + +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); + fread(file, iDemoHeader[netProtocol], BLOCK_INT); + 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); + + 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); +} + +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); + fseek(iFile, iSeek, SEEK_SET); + fgets(iFile, szLineData, charsmax(szLineData)); + 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 { + server_print("Finished loading demo in %f sec.", get_gametime() - flStartTime); + 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); + static sum; + + if(!feof(file)) { + new FrameType = ReadFrameHeader(file); + new breakme; + switch(FrameType) { + case 0: { } + case 1: { + new Float:Origin[3], Float:ViewAngles[3], Float:velocity[3], iAsd[1024]; + fseek(file, 4, SEEK_CUR); + for(new i = 0; i < 3; ++i) + fseek(file, 4, SEEK_CUR); + for(new i = 0; i < 3; ++i) + fread(file, _:ViewAngles[i], BLOCK_INT); + fseek(file, 64, SEEK_CUR); + for(new i = 0; i < 3; ++i) + fread(file, _:velocity[i], BLOCK_INT); + for(new i = 0; i < 3; ++i) + fread(file, _:Origin[i], BLOCK_INT); + fseek(file, 124, SEEK_CUR); + for(new i = 0; i < 3; ++i) + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + fseek(file, 2, SEEK_CUR); + 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); + new length; + fread(file, length, BLOCK_INT); + fseek(file, length, SEEK_CUR); + } + 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) + fseek(file, 4, SEEK_CUR); + for(new i = 0; i < 3; ++i) + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + } + case 5: { + breakme = 2; + } + case 6: { + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + for(new i = 0; i < 3; ++i) + fseek(file, 4, SEEK_CUR); + for(new i = 0; i < 3; ++i) + fseek(file, 4, SEEK_CUR); + for(new i = 0; i < 3; ++i) + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + fseek(file, 4, SEEK_CUR); + } + 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 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); + + 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"); +} + +public client_connect(id) { + if(is_user_bot(id)) + return; +} + +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); +}