2021-07-25 12:20:46 +00:00
|
|
|
#include <amxmodx>
|
2024-07-03 17:40:28 +00:00
|
|
|
#include <amxmisc>
|
|
|
|
#include <engine>
|
2021-07-25 12:20:46 +00:00
|
|
|
#include <cstrike>
|
2024-07-03 17:40:28 +00:00
|
|
|
#include <fakemeta_util>
|
|
|
|
#include <hamsandwich>
|
2021-07-25 12:20:46 +00:00
|
|
|
#include <fun>
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
#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;
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
#define NUM_THREADS 256
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
#pragma dynamic 32767
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
#define PEV_PDATA_SAFE 2
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
#define OFFSET_TEAM 114
|
|
|
|
#define OFFSET_DEFUSE_PLANT 193
|
|
|
|
#define HAS_DEFUSE_KIT (1<<16)
|
|
|
|
#define OFFSET_INTERNALMODEL 126
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
new bool:g_Demos = false;
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
new iXJWRs, iCCWRs, iKZRUWRs, iArchive;
|
2021-07-25 12:20:46 +00:00
|
|
|
new bool:bFoundDemo = false;
|
2024-07-03 17:40:28 +00:00
|
|
|
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);
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
public plugin_init() {
|
|
|
|
register_plugin(PLUGIN, VERSION, AUTHOR);
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
timer_bot = register_cvar("timer_bot", "1");
|
|
|
|
timer_option = register_cvar("timer_option", "1"); // 1 txt, 2 hud
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
new kreedz_cfg[128], ConfigDir[64];
|
|
|
|
get_configsdir(ConfigDir, 64);
|
|
|
|
formatex(kreedz_cfg, 128, "%s/wrbot.cfg", ConfigDir);
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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.");
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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);
|
|
|
|
}
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
SyncHudBotTimer = CreateHudSyncObj();
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
announce();
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
}
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 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)
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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;
|
|
|
|
}
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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);
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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++;
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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;
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
public StartCountDown() {
|
|
|
|
if(!wr_bot_id)
|
|
|
|
wr_bot_id = Create_Bot();
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
g_timer = 0;
|
|
|
|
set_task(1.0, "Show");
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
public Show() {
|
|
|
|
g_timer--;
|
|
|
|
set_hudmessage(255, 255, 255, 0.05, 0.2, 0, 6.0, 1.0);
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
if(g_timer && g_timer >= 0)
|
|
|
|
set_task(1.0, "Show");
|
|
|
|
else {
|
|
|
|
g_bot_enable = 1;
|
|
|
|
Start_Bot();
|
|
|
|
}
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
Start_Bot() {
|
|
|
|
g_bot_frame = g_bot_start;
|
|
|
|
timer_started[wr_bot_id] = false;
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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;
|
|
|
|
}
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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
|
|
|
|
};
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
enum DemoHeader {
|
|
|
|
netProtocol,
|
|
|
|
demoProtocol,
|
|
|
|
mapName[HEADER_MAPNAME_SIZE],
|
|
|
|
gameDir[HEADER_GAMEDIR_SIZE],
|
|
|
|
mapCRC,
|
|
|
|
directoryOffset
|
|
|
|
};
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
enum DemoEntry {
|
|
|
|
dirEntryCount,
|
|
|
|
type,
|
|
|
|
description[DIR_ENTRY_DESCRIPTION_SIZE],
|
|
|
|
flags,
|
|
|
|
CDTrack,
|
|
|
|
trackTime,
|
|
|
|
frameCount,
|
|
|
|
offset,
|
|
|
|
fileLength,
|
|
|
|
frames,
|
|
|
|
ubuttons
|
|
|
|
};
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
enum FrameHeader {
|
|
|
|
Type,
|
|
|
|
Float:Timestamp,
|
|
|
|
Number
|
|
|
|
};
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
enum NetMsgFrame {
|
|
|
|
Float:timestamp,
|
|
|
|
Float:view[3],
|
|
|
|
viewmodel
|
|
|
|
};
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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");
|
|
|
|
}
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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;
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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");
|
|
|
|
}
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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");
|
|
|
|
}
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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;
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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;
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
public complite_kzru(CURLcode:code, CURL:curl) {
|
|
|
|
curl_easy_cleanup(curl);
|
|
|
|
fclose(iKZRUWRs);
|
|
|
|
OnDemosComplete(0);
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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();
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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();
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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);
|
|
|
|
}
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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");
|
|
|
|
}
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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;
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
public complite_archive(CURLcode:code, CURL:curl) {
|
|
|
|
curl_easy_cleanup(curl);
|
|
|
|
fclose(iArchive);
|
|
|
|
OnArchiveComplete();
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
public OnArchiveComplete() {
|
|
|
|
new datadir[128], RARArchive[128];
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
get_localinfo("amxx_datadir", datadir, charsmax(datadir));
|
|
|
|
format(RARArchive, charsmax(RARArchive), "%s/%s.%s", datadir, iArchiveName, g_demoExt);
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
server_print(" src: %s", WR_SRC);
|
|
|
|
server_print(" rar: %s", RARArchive);
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
AA_Unarchive(RARArchive, datadir, "@OnComplete", 0);
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
2024-07-03 17:40:28 +00:00
|
|
|
@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);
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
public fnConvertTime(Float:time, convert_time[], len) {
|
|
|
|
new sTemp[24];
|
|
|
|
new Float:fSeconds = time, iMinutes;
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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);
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
formatex(sTemp, charsmax(sTemp), "%02i%02.0f.%02d", iMinutes, fSeconds, intpart);
|
|
|
|
formatex(convert_time, len, sTemp);
|
|
|
|
return PLUGIN_HANDLED;
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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);
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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!");
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
public bool:IsValidDemoFile(file) {
|
|
|
|
fseek(file, 0, SEEK_END);
|
|
|
|
iDemo_header_size = ftell(file);
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
if(iDemo_header_size < HEADER_SIZE)
|
|
|
|
return false;
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
fseek(file, 0, SEEK_SET);
|
|
|
|
new signature[HEADER_SIGNATURE_CHECK_SIZE];
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
fread_blocks(file, signature, sizeof(signature), BLOCK_CHAR);
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
if(!contain("HLDEMO", signature))
|
|
|
|
return false;
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
return true;
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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);
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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;
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
2024-07-03 17:40:28 +00:00
|
|
|
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;
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
public ReadFrameHeader(file) {
|
|
|
|
fread(file, iDemoFrame[Type], BLOCK_BYTE);
|
|
|
|
fread(file, _:iDemoFrame[Timestamp], BLOCK_INT);
|
|
|
|
fread(file, iDemoFrame[Number], BLOCK_INT);
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
return(iDemoFrame[Type]);
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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);
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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");
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
public client_connect(id) {
|
|
|
|
if(is_user_bot(id))
|
|
|
|
return;
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
stock StringTimer(const Float:flRealTime, szOutPut[], const iSizeOutPut) {
|
|
|
|
static Float:flTime, iMinutes, iSeconds, iMiliSeconds, Float:iMili;
|
|
|
|
new string[12];
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
flTime = flRealTime;
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
if(flTime < 0.0)
|
|
|
|
flTime = 0.0;
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
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);
|
2021-07-25 12:20:46 +00:00
|
|
|
|
2024-07-03 17:40:28 +00:00
|
|
|
formatex(szOutPut, iSizeOutPut, "%02d:%02d.%02d", iMinutes, iSeconds, iMiliSeconds);
|
2021-07-25 12:20:46 +00:00
|
|
|
}
|