#include #include #include #include //for recording surfing properly with things such as trigger_pushes should sm_botmimic_snapshotinterval be set to 50 public Plugin myinfo = { name = "test surfing plugin", author = "jenzur", description = "hello ", version = "1.1", url = "www.unloze.com" }; float bot_finished_surf_coords[MAXPLAYERS + 1][3]; char map_coorindates[65][256]; char map_recordname[65][256]; bool round_switch = false; Handle g_hTraceTimer = null; Database g_dDatabase; public void OnPluginStart() { for (int i = 1; i <= MaxClients; i++) if (IsValidClient(i)) { reset_client(i); reset_bot_finished_surf(i); } g_hTraceTimer = CreateTimer(0.30, update_mimic_coords, _, TIMER_REPEAT); OnMapStart(); HookEvent("round_start", Event_RoundStart, EventHookMode_Pre); HookEvent("round_end", OnRoundEnd, EventHookMode_Pre); } public void OnPluginEnd() { for (int i = 1; i <= MaxClients; i++) if (IsValidClient(i)) { reset_client(i); reset_bot_finished_surf(i); } if (g_hTraceTimer != null) delete g_hTraceTimer; } public Action OnRoundEnd(Handle event, const char[] name, bool dontBroadcast) { perform_resets(); } public void Event_RoundStart(Handle event, const char[] name, bool dontBroadcast) { perform_resets(); } public void perform_resets() { round_switch = true; for (int i = 1; i <= MaxClients; i++) if (IsValidClient(i)) { reset_client(i); reset_bot_finished_surf(i); } CreateTimer(7.00, reset_round_switch, INVALID_HANDLE); } public Action reset_round_switch(Handle timer, any data) { round_switch = false; } stock bool IsValidClient(int client) { if (client > 0 && client <= MaxClients && IsClientConnected(client) && IsClientInGame(client)) return true; return false; } public void OnClientPostAdminCheck(int client) { reset_bot_finished_surf(client); } public void OnClientDisconnect(int client) { reset_bot_finished_surf(client); } public void reset_bot_finished_surf(int client) { bot_finished_surf_coords[client][0] = 0.0; bot_finished_surf_coords[client][1] = 0.0; bot_finished_surf_coords[client][2] = 0.0; } public void reset_client(int client) { if (BotMimic_IsPlayerMimicing(client)) { BotMimic_StopPlayerMimic(client); } } public int BotMimic_OnPlayerMimicLoops(int client) { char map_name[256]; GetCurrentMap(map_name, sizeof(map_name)); if (StrContains(map_name, "ze_surf", false) == -1) { reset_client(client); reset_bot_finished_surf(client); } else if (bot_finished_surf_coords[client][0] != 0.0) { reset_client(client); TeleportEntity(client, bot_finished_surf_coords[client], NULL_VECTOR, NULL_VECTOR); reset_bot_finished_surf(client); } else { GetEntPropVector(client, Prop_Send, "m_vecOrigin", bot_finished_surf_coords[client]); } } public Action update_mimic_coords(Handle timer, any data) { for (int i = 1; i <= MaxClients; i++) if (IsValidClient(i) && is_bot_player(i)) { if (bot_finished_surf_coords[i][0] != 0.0) { GetEntPropVector(i, Prop_Send, "m_vecOrigin", bot_finished_surf_coords[i]); } } if (round_switch) { return Plugin_Continue; } Handle records_list = BotMimic_GetLoadedRecordList(); for (int i = 0; i < sizeof(map_coorindates); i++) { bool found = false; char char_coord[3][256]; if (strlen(map_coorindates[i]) > 0) { ExplodeString(map_coorindates[i], " ", char_coord, sizeof(char_coord[]), sizeof(char_coord[])); float coords[3]; coords[0] = StringToFloat(char_coord[0]); coords[1] = StringToFloat(char_coord[1]); coords[2] = StringToFloat(char_coord[2]); for (int j = 1; j <= MaxClients; j++) { if (IsValidClient(j) && bot_finished_surf_coords[j][0] == 0.0 && is_bot_player(j)) { float distance = get_power_distance(j, coords); if (distance < 225.0) { char path[1024]; for (int f = 0; f < GetArraySize(records_list); f++) { if (f != i) continue; GetArrayString(records_list, f, path, sizeof(path)); for (int h = 0; h < sizeof(map_recordname); h++) { //i != h assures coordinates match the right iterated name if (strlen(map_recordname[h]) == 0 || i != h) { continue; } if (StrEqual(path, map_recordname[h], false)) { BotMimic_PlayRecordFromFile(j, path); found = true; } if (found) break; } if (found) break; } } } if (found) break; } } if (found) break; } return Plugin_Continue; } public float get_power_distance(int target_player, float [3]pos) { float vec[3]; GetClientAbsOrigin(target_player, vec); return GetVectorDistance(vec, pos); } public int BotMimic_OnRecordSaved(int client, char[] name, char[] category, char[] subdir, char[] file) { //file = The actual path to the saved .rec file. char sQuery[256]; Format(sQuery, sizeof(sQuery), "UPDATE `maps_coordinates` SET `recordname` = '%s' WHERE `recordname` = 'unknown'", file); g_dDatabase.Query(SQL_insertQuery_record_saved, sQuery, _, DBPrio_High); } public Action BotMimic_OnStartRecording(int client, char[] name, char[] category, char[] subdir, char[] path) { float bot_start_coords[3]; GetEntPropVector(client, Prop_Send, "m_vecOrigin", bot_start_coords); char map_name[256]; GetCurrentMap(map_name, sizeof(map_name)); char sQuery[256]; char coords[3][256]; FloatToString(bot_start_coords[0], coords[0], sizeof(coords[])); FloatToString(bot_start_coords[1], coords[1], sizeof(coords[])); FloatToString(bot_start_coords[2], coords[2], sizeof(coords[])); Format(sQuery, sizeof(sQuery), "insert into `maps_coordinates` (`mapname`, `recordname`, `coordinate`) VALUES ('%s', 'unknown', '%s %s %s')", map_name, coords[0], coords[1], coords[2]); g_dDatabase.Query(SQL_insertQuery, sQuery, _, DBPrio_High); } public void select_map_related_surfs() { char map_name[256]; GetCurrentMap(map_name, sizeof(map_name)); char sQuery[256]; Format(sQuery, sizeof(sQuery), "select recordname, coordinate from `maps_coordinates` where mapname = '%s'", map_name); g_dDatabase.Query(SQL_OnQueryCompleted, sQuery, _, DBPrio_High); } public void SQL_OnQueryCompleted(Database db, DBResultSet results, const char[] error, DataPack data) { if (!db || strlen(error)) { LogError("Query error: %s", error); return; } int iterator = 0; for (int i = 0; i < sizeof(map_coorindates); i++) { Format(map_coorindates[i], sizeof(map_coorindates[]), ""); Format(map_recordname[i], sizeof(map_recordname[]), ""); } while (results.RowCount > 0 && results.FetchRow()) { results.FetchString(0, map_recordname[iterator], sizeof(map_recordname[])); results.FetchString(1, map_coorindates[iterator], sizeof(map_coorindates[])); iterator++; } } public void OnMapStart() { for (int i = 1; i <= MaxClients; i++) if (IsValidClient(i)) { reset_bot_finished_surf(i); } char map_name[256]; GetCurrentMap(map_name, sizeof(map_name)); if (!g_dDatabase) Database.Connect(SQL_OnDatabaseConnect, "bot_surfing"); else if(StrContains(map_name, "ze_surf", false) != -1) { //should not be needed for (int i = 0; i < sizeof(map_coorindates); i++) { Format(map_coorindates[i], sizeof(map_coorindates[]), ""); Format(map_recordname[i], sizeof(map_recordname[]), ""); } select_map_related_surfs(); } } public void SQL_OnDatabaseConnect(Database db, const char[] error, any data) { if(!db || strlen(error)) { LogError("Database error: %s", error); return; } g_dDatabase = db; char sQuery[256]; Format(sQuery, sizeof(sQuery), "CREATE TABLE IF NOT EXISTS `maps_coordinates` (`mapname` VARCHAR(254) NOT NULL, `coordinate` VARCHAR(254) NOT NULL, `recordname` VARCHAR(254) NOT NULL, PRIMARY KEY (`mapname`, `recordname`, `coordinate`))"); g_dDatabase.Query(SQL_FinishedQuery_creating_tables, sQuery, _, DBPrio_High); } public void SQL_insertQuery_record_saved(Database db, DBResultSet results, const char[] error, DataPack data) { if (!db || strlen(error)) { LogError("Query error: %s", error); } select_map_related_surfs(); } public void SQL_insertQuery(Database db, DBResultSet results, const char[] error, DataPack data) { if (!db || strlen(error)) { LogError("Query error: %s", error); } } public void SQL_FinishedQuery_creating_tables(Database db, DBResultSet results, const char[] error, DataPack data) { if (!db || strlen(error)) { LogError("Query error: %s", error); } char map_name[256]; GetCurrentMap(map_name, sizeof(map_name)); if (StrContains(map_name, "ze_surf", false) != -1) { select_map_related_surfs(); } } public bool is_bot_player(int client) { bool debug_b = false; if (debug_b && is_jenz(client)) { return true; } return is_autism_bot1(client) || is_autism_bot2(client) || is_autism_bot3(client) || is_autism_bot4(client); //change to true for debugging on dev } public bool is_jenz(int client) { char auth[50]; GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth)); return StrEqual("[U:1:69566635]", auth, false) || StrEqual("STEAM_0:1:34783317", auth, false); } public bool is_autism_bot1(int client) { char auth[50]; GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth)); return StrEqual("[U:1:120378081]", auth, false) || StrEqual("STEAM_0:1:60189040", auth, false); } public bool is_autism_bot2(int client) { char auth[50]; GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth)); return StrEqual("[U:1:1036189204]", auth, false) || StrEqual("STEAM_0:0:518094602", auth, false); } public bool is_autism_bot3(int client) { char auth[50]; GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth)); return StrEqual("[U:1:408797742]", auth, false) || StrEqual("STEAM_0:0:204398871", auth, false); } public bool is_autism_bot4(int client) { char auth[50]; GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth)); return StrEqual("[U:1:1221121532]", auth, false) || StrEqual("STEAM_0:0:610560766", auth, false); }