426 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
			
		
		
	
	
			426 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			SourcePawn
		
	
	
	
	
	
| #include <sourcemod>
 | |
| #include <cstrike>
 | |
| #include <smlib>
 | |
| #include <sdktools>
 | |
| #include <sdkhooks>
 | |
| #include <botmimic>
 | |
| 
 | |
| //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"
 | |
| };
 | |
| 
 | |
| //is botplayer
 | |
| bool is_bot_player[MAXPLAYERS + 1];
 | |
| bool is_player_jenz[MAXPLAYERS + 1];
 | |
| 
 | |
| 
 | |
| 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)
 | |
| {
 | |
|     is_bot_player[client] = false;
 | |
|     is_player_jenz[client] = false;
 | |
|     is_bot_player_call(client);
 | |
|     reset_bot_finished_surf(client);
 | |
| }
 | |
| 
 | |
| public void OnClientDisconnect(int client)
 | |
| {
 | |
|     is_bot_player[client] = false;
 | |
|     is_player_jenz[client] = false;
 | |
|     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);
 | |
|         if (GetClientTeam(client) == CS_TEAM_T)
 | |
|         {
 | |
|             Client_switch_to_knife(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 void is_bot_player_call(int client)
 | |
| {
 | |
|     bool debug_b = false;
 | |
|     if (debug_b && is_jenz(client))
 | |
|     {
 | |
|         is_player_jenz[client] = true;
 | |
|     }
 | |
|     is_autism_bot1(client);
 | |
|     is_autism_bot2(client); 
 | |
|     is_autism_bot3(client); 
 | |
|     is_autism_bot4(client);
 | |
| }
 | |
| 
 | |
| public bool is_jenz(int client)
 | |
| {
 | |
|     char auth[50];
 | |
|     GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth));
 | |
|     if(StrEqual("[U:1:69566635]", auth, false) || StrEqual("STEAM_0:1:34783317", auth, false))
 | |
|     {
 | |
|         return true;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| public bool is_autism_bot1(int client)
 | |
| {
 | |
|     char auth[50];
 | |
|     GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth));
 | |
|     if (StrEqual("[U:1:120378081]", auth, false) || StrEqual("STEAM_0:1:60189040", auth, false))
 | |
|     {
 | |
|         is_bot_player[client] = true;
 | |
|         return true;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| public bool is_autism_bot2(int client)
 | |
| {
 | |
|     char auth[50];
 | |
|     GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth));
 | |
|     if (StrEqual("[U:1:1036189204]", auth, false) || StrEqual("STEAM_0:0:518094602", auth, false))
 | |
|     {
 | |
|         is_bot_player[client] = true;
 | |
|         return true;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| public bool is_autism_bot3(int client)
 | |
| {
 | |
|     char auth[50];
 | |
|     GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth));
 | |
|     if (StrEqual("[U:1:408797742]", auth, false) || StrEqual("STEAM_0:0:204398871", auth, false))
 | |
|     {
 | |
|         is_bot_player[client] = true;
 | |
|         return true;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| public bool is_autism_bot4(int client)
 | |
| {
 | |
|     char auth[50];
 | |
|     GetClientAuthId(client, AuthId_Engine, auth, sizeof(auth));
 | |
|     if (StrEqual("[U:1:1221121532]", auth, false) || StrEqual("STEAM_0:0:610560766", auth, false))
 | |
|     {
 | |
|         is_bot_player[client] = true;
 | |
|         return true;
 | |
|     }
 | |
|     return false;
 | |
| }
 | |
| 
 | |
| stock Client_switch_to_knife(int client)
 | |
| {
 | |
|     //2 is always knife
 | |
|     int weapon = GetPlayerWeaponSlot(client, 2);
 | |
|     if (Weapon_IsValid(weapon)) {
 | |
|         Client_SetActiveWeapon(client, weapon);
 | |
|     }
 | |
| }
 | |
| 
 | |
| 
 |