f0.gg-kreedzsrv/amxmodx/scripting/KZ_Bot.sma

1126 lines
33 KiB
Plaintext

#include <amxmodx>
#include <amxmisc>
#include <engine>
#include <cstrike>
#include <fakemeta_util>
#include <hamsandwich>
#include <fun>
#include <kz_wrbot/AmxxArch>
#include <kz_wrbot/curl>
#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
#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
new bool:g_Demos = false;
new iXJWRs, iCCWRs, iKZRUWRs, iArchive;
new bool:bFoundDemo = false;
new iDemo_header_size;
new iArchiveName[256];
new iDemoName[256];
new iNavName[256];
new iFile;
new iParsedFile;
new g_demoExt[32] = "rar";
public plugin_precache() {
get_mapname(g_szMapName, sizeof(g_szMapName) - 1);
strtolower(g_szMapName);
parsing_country("xj");
new i;
for(i = 0; i < sizeof(g_tButtons); i++)
g_tButtons[i] = TrieCreate();
new szStartTargets[][] = {
"counter_start", "clockstartbutton", "firsttimerelay", "but_start",
"counter_start_button", "multi_start", "timer_startbutton", "start_timer_emi", "gogogo"
};
for(i = 0; i < sizeof szStartTargets ; i++)
TrieSetCell(g_tButtons[0], szStartTargets[i], i);
new szFinishTargets[][] = {
"counter_off", "clockstopbutton", "clockstop", "but_stop",
"counter_stop_button", "multi_stop", "stop_counter", "m_counter_end_emi"
};
for(i = 0; i < sizeof szFinishTargets; i++)
TrieSetCell(g_tButtons[1], szFinishTargets[i], i);
new Ent = engfunc(EngFunc_CreateNamedEntity , engfunc(EngFunc_AllocString, "info_target"));
set_pev(Ent, pev_classname, "BotThink");
set_pev(Ent, pev_nextthink, get_gametime() + 0.01);
register_forward(FM_Think, "fwd_Think", 1);
fPlayerAngle = ArrayCreate(2);
fPlayerOrigin = ArrayCreate(3);
fPlayerVelo = ArrayCreate(3);
fPlayerKeys = ArrayCreate(1);
}
public plugin_init() {
register_plugin(PLUGIN, VERSION, AUTHOR);
timer_bot = register_cvar("timer_bot", "1");
timer_option = register_cvar("timer_option", "1"); // 1 txt, 2 hud
new kreedz_cfg[128], ConfigDir[64];
get_configsdir(ConfigDir, 64);
formatex(kreedz_cfg, 128, "%s/wrbot.cfg", ConfigDir);
if(file_exists(kreedz_cfg)) {
server_cmd("exec %s", kreedz_cfg);
server_exec();
}
else
server_print("[WR_BOT] Config file is not connected, please check.");
if(get_pcvar_num(timer_bot) == 1) {
new iTimerEnt = engfunc(EngFunc_CreateNamedEntity, engfunc(EngFunc_AllocString , "info_target"));
set_pev(iTimerEnt, pev_classname, "kz_time_think");
set_pev(iTimerEnt, pev_nextthink, get_gametime() + 1.0);
}
SyncHudBotTimer = CreateHudSyncObj();
announce();
}
public Ham_ButtonUse(id) {
new Float:origin[3];
pev(id, pev_origin, origin);
new ent = -1;
while((ent = find_ent_in_sphere(ent, origin, 100.0)) != 0) {
new classname[32];
pev(ent, pev_classname, classname, charsmax(classname));
new Float:eorigin[3];
get_brush_entity_origin(ent, eorigin);
static Float:Distance[2];
new szTarget[32];
pev(ent, pev_target, szTarget, 31);
if(TrieKeyExists(g_tButtons[0], szTarget)) {
if(g_bot_start < 0)
g_bot_start = 0;
if(vector_distance(origin, eorigin) >= Distance[0]) {
timer_time[id] = get_gametime();
IsPaused[id] = false;
timer_started[id] = true;
bot_finish_use[id] = false;
}
Distance[0] = vector_distance(origin, eorigin);
}
if(TrieKeyExists(g_tButtons[1], szTarget)) {
if(vector_distance(origin, eorigin) >= Distance[1]) {
if(!bot_finish_use[id]) {
if(timer_started[id])
Start_Bot();
timer_started[id] = false;
bot_finish_use[id] = true;
}
}
Distance[1] = vector_distance(origin, eorigin);
}
}
}
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ TIMER ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
public timer_task(iTimer) {
new Dead[32], deadPlayers;
get_players(Dead, deadPlayers, "bh");
for(new i = 0; i < deadPlayers; i++) {
new specmode = pev(Dead[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 Pause() {
if(!IsPaused[wr_bot_id]) {
g_pausetime[wr_bot_id] = get_gametime() - timer_time[wr_bot_id];
timer_time[wr_bot_id] = 0.0;
IsPaused[wr_bot_id] = true;
g_bot_enable = 2;
}
else {
if(timer_started[wr_bot_id]) {
timer_time[wr_bot_id] = get_gametime() - g_pausetime[wr_bot_id];
}
IsPaused[wr_bot_id] = false;
g_bot_enable = 1;
}
}
public fwd_Think(iEnt) {
if(!pev_valid(iEnt))
return(FMRES_IGNORED);
static className[32];
pev(iEnt, pev_classname, className, 31);
if(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 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++;
}
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");
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;
}
public StartCountDown() {
if(!wr_bot_id)
wr_bot_id = Create_Bot();
g_timer = 0;
set_task(1.0, "Show");
}
public Show() {
g_timer--;
set_hudmessage(255, 255, 255, 0.05, 0.2, 0, 6.0, 1.0);
if(g_timer && g_timer >= 0)
set_task(1.0, "Show");
else {
g_bot_enable = 1;
Start_Bot();
}
}
Start_Bot() {
g_bot_frame = g_bot_start;
timer_started[wr_bot_id] = false;
}
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;
}
}
enum _:Consts {
HEADER_SIZE = 544,
HEADER_SIGNATURE_CHECK_SIZE = 6,
HEADER_SIGNATURE_SIZE = 8,
HEADER_MAPNAME_SIZE = 260,
HEADER_GAMEDIR_SIZE = 260,
MIN_DIR_ENTRY_COUNT = 1,
MAX_DIR_ENTRY_COUNT = 1024,
DIR_ENTRY_SIZE = 92,
DIR_ENTRY_DESCRIPTION_SIZE = 64,
MIN_FRAME_SIZE = 12,
FRAME_CONSOLE_COMMAND_SIZE = 64,
FRAME_CLIENT_DATA_SIZE = 32,
FRAME_EVENT_SIZE = 84,
FRAME_WEAPON_ANIM_SIZE = 8,
FRAME_SOUND_SIZE_1 = 8,
FRAME_SOUND_SIZE_2 = 16,
FRAME_DEMO_BUFFER_SIZE = 4,
FRAME_NETMSG_SIZE = 468,
FRAME_NETMSG_DEMOINFO_SIZE = 436,
FRAME_NETMSG_MOVEVARS_SIZE = 32,
FRAME_NETMSG_MIN_MESSAGE_LENGTH = 0,
FRAME_NETMSG_MAX_MESSAGE_LENGTH = 65536
};
enum DemoHeader {
netProtocol,
demoProtocol,
mapName[HEADER_MAPNAME_SIZE],
gameDir[HEADER_GAMEDIR_SIZE],
mapCRC,
directoryOffset
};
enum DemoEntry {
dirEntryCount,
type,
description[DIR_ENTRY_DESCRIPTION_SIZE],
flags,
CDTrack,
trackTime,
frameCount,
offset,
fileLength,
frames,
ubuttons
};
enum FrameHeader {
Type,
Float:Timestamp,
Number
};
enum NetMsgFrame {
Float:timestamp,
Float:view[3],
viewmodel
};
new iDemoEntry[DemoEntry];
new iDemoHeader[DemoHeader];
new iDemoFrame[FrameHeader];
public announce() {
new datadir[128];
new filename[128];
get_localinfo("amxx_datadir", datadir, charsmax(datadir));
format(filename, charsmax(datadir), "%s/list_xj.txt", datadir);
delete_file(filename);
iXJWRs = fopen(filename, "wb");
new CURL:curl = curl_easy_init();
if(curl) {
//curl_easy_setopt(curl, CURLOPT_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");
}
}
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;
}
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);
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");
}
}
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;
}
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 complite_kzru(CURLcode:code, CURL:curl) {
curl_easy_cleanup(curl);
fclose(iKZRUWRs);
OnDemosComplete(0);
}
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 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);
}
}
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);
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);
}