diff --git a/SprayManager/scripting/SprayManager.sp b/SprayManager/scripting/SprayManager.sp index 3a01235c..a91cf658 100644 --- a/SprayManager/scripting/SprayManager.sp +++ b/SprayManager/scripting/SprayManager.sp @@ -5,8 +5,8 @@ #include #undef REQUIRE_PLUGIN - #include +#define REQUIRE_PLUGIN #pragma newdecls required @@ -60,11 +60,11 @@ float g_SprayAABB[MAXPLAYERS + 1][AABBTotalPoints]; public Plugin myinfo = { - name = "Spray Manager", - description = "A plugin to help manage player sprays.", - author = "Obus", - version = "1.1.5", - url = "https://github.com/CSSZombieEscape/sm-plugins/tree/master/SprayManager" + name = "Spray Manager", + description = "A plugin to help manage player sprays.", + author = "Obus", + version = "1.2.0", + url = "https://github.com/CSSZombieEscape/sm-plugins/tree/master/SprayManager" } public APLRes AskPluginLoad2(Handle hThis, bool bLate, char[] err, int iErrLen) @@ -128,6 +128,18 @@ public void OnPluginStart() public void OnPluginEnd() { + for (int i = 1; i <= MaxClients; i++) + { + if (!IsValidClient(i) || IsFakeClient(i)) + continue; + + if (g_vecSprayOrigin[i][0] == 0.0) + continue; + + g_bAllowSpray = true; + SprayClientDecal(i, 0, ACTUAL_NULL_VECTOR); + } + RemoveTempEntHook("Player Decal", HookDecal); RemoveNormalSoundHook(HookSprayer); @@ -641,7 +653,7 @@ void Menu_Spray(int client) for (int i = 1; i <= MaxClients; i++) { - if (!IsValidClient(i)) + if (!IsValidClient(i) || IsFakeClient(i)) continue; char sUserID[16]; @@ -1259,7 +1271,7 @@ public Action Command_AdminSpray(int client, int argc) GetCmdArg(1, sArgs, sizeof(sArgs)); - if (!(iTargetCount = ProcessTargetString(sArgs, client, iTargets, MAXPLAYERS, 0, sTargetName, sizeof(sTargetName), bIsML))) + if ((iTargetCount = ProcessTargetString(sArgs, client, iTargets, MAXPLAYERS, COMMAND_FILTER_NO_BOTS, sTargetName, sizeof(sTargetName), bIsML)) <= 0) { ReplyToTargetError(client, iTargetCount); return Plugin_Handled; @@ -1275,16 +1287,14 @@ public Action Command_AdminSpray(int client, int argc) return Plugin_Handled; } - else - { - float vecEndPos[3]; - TracePlayerAngles(client, vecEndPos); - g_bAllowSpray = true; - ForceSpray(client, client); + float vecEndPos[3]; + TracePlayerAngles(client, vecEndPos); - PrintToChat(client, "\x01\x04[SprayManager]\x01 Sprayed your own spray."); - } + g_bAllowSpray = true; + ForceSpray(client, client); + + PrintToChat(client, "\x01\x04[SprayManager]\x01 Sprayed your own spray."); return Plugin_Handled; } @@ -1438,20 +1448,48 @@ public Action Command_RemoveSpray(int client, int argc) return Plugin_Handled; } + if (argc > 0) + { + char sArgs[64]; + char sTargetName[MAX_TARGET_LENGTH]; + int iTargets[MAXPLAYERS]; + int iTargetCount; + bool bIsML; + + GetCmdArg(1, sArgs, sizeof(sArgs)); + + if ((iTargetCount = ProcessTargetString(sArgs, client, iTargets, MAXPLAYERS, COMMAND_FILTER_NO_BOTS, sTargetName, sizeof(sTargetName), bIsML)) <= 0) + { + ReplyToTargetError(client, iTargetCount); + return Plugin_Handled; + } + + for (int i = 0; i < iTargetCount; i++) + { + g_bAllowSpray = true; + SprayClientDecal(iTargets[i], 0, ACTUAL_NULL_VECTOR); + } + + PrintToChat(client, "\x01\x04[SprayManager]\x01 Removed \x04%s\x01's spray(s).", sTargetName); + + return Plugin_Handled; + } + float vecEndPos[3]; + if (TracePlayerAngles(client, vecEndPos)) { for (int i = 1; i <= MaxClients; i++) { - if (IsPointInsideAABB(vecEndPos, g_SprayAABB[i])) - { - g_bAllowSpray = true; - SprayClientDecal(i, 0, ACTUAL_NULL_VECTOR); + if (!IsPointInsideAABB(vecEndPos, g_SprayAABB[i])) + continue; - PrintToChat(client, "\x01\x04[SprayManager]\x01 You have successfully removed \x04%N\x01's spray.", i); + g_bAllowSpray = true; + SprayClientDecal(i, 0, ACTUAL_NULL_VECTOR); - return Plugin_Handled; - } + PrintToChat(client, "\x01\x04[SprayManager]\x01 Removed \x04%N\x01's spray.", i); + + return Plugin_Handled; } } @@ -1554,6 +1592,8 @@ public Action HookDecal(const char[] sTEName, const int[] iClients, int iNumClie g_bAllowSpray = false; + g_iSprayLifetime[client] = 0; + g_vecSprayOrigin[client][0] = vecOrigin[0]; g_vecSprayOrigin[client][1] = vecOrigin[1]; g_vecSprayOrigin[client][2] = vecOrigin[2]; @@ -1724,10 +1764,17 @@ public void OnSQLTableCreated(Handle hParent, Handle hChild, const char[] err, a { if (g_bLoadedLate) { - for (int i = 1; i <= MaxClients; i++) + if (CreateTimer(2.5, RetryUpdatingPlayerInfo) == null) { - if (IsValidClient(i)) + LogError("Failed to create player info updater timer, attempting to update info now."); + + for (int i = 1; i <= MaxClients; i++) + { + if (!IsValidClient) + continue; + OnClientPostAdminCheck(i); + } } } @@ -1770,10 +1817,17 @@ public void OnSQLSprayBlacklistCreated(Handle hParent, Handle hChild, const char { if (g_bLoadedLate) { - for (int i = 1; i <= MaxClients; i++) + if (CreateTimer(2.5, RetryUpdatingPlayerInfo) == null) { - if (IsValidClient(i)) + LogError("Failed to create player info updater timer, attempting to update info now."); + + for (int i = 1; i <= MaxClients; i++) + { + if (!IsValidClient) + continue; + OnClientPostAdminCheck(i); + } } } @@ -1791,6 +1845,17 @@ public Action RetryBlacklistTableCreation(Handle hTimer) SQL_TQuery(g_hDatabase, OnSQLSprayBlacklistCreated, "CREATE TABLE IF NOT EXISTS `sprayblacklist` (`sprayhash` VARCHAR(16) NOT NULL, `sprayer` VARCHAR(32) NOT NULL, `sprayersteamid` VARCHAR(32) NOT NULL, PRIMARY KEY(sprayhash)) CHARACTER SET utf8 COLLATE utf8_general_ci;"); } +public Action RetryUpdatingPlayerInfo(Handle hTimer) +{ + for (int i = 1; i <= MaxClients; i++) + { + if (!IsValidClient) + continue; + + OnClientPostAdminCheck(i); + } +} + public void CVarHook_DecalFrequency(ConVar cvar, const char[] sOldValue, const char[] sNewValue) { if (cvar == g_cvarHookedDecalFrequency) @@ -1888,6 +1953,7 @@ bool SprayUnbanClient(int client) strcopy(g_sBanIssuerSID[client], sizeof(g_sBanIssuerSID[]), ""); strcopy(g_sBanReason[client], sizeof(g_sBanReason[]), ""); g_bSprayBanned[client] = false; + g_iSprayLifetime[client] = 0; g_iSprayBanTimestamp[client] = 0; g_iSprayUnbanTimestamp[client] = -1; g_fNextSprayTime[client] = 0.0; @@ -2057,6 +2123,7 @@ bool ForceSpray(int client, int target, bool bPlaySound=true) return false; float vecEndPos[3]; + if (TracePlayerAngles(client, vecEndPos)) { SprayClientDecal(target, 0, vecEndPos); @@ -2153,6 +2220,7 @@ void ClearPlayerInfo(int client) strcopy(g_sSprayHash[client], sizeof(g_sSprayHash[]), ""); g_bSprayBanned[client] = false; g_bSprayHashBanned[client] = false; + g_iSprayLifetime[client] = 0; g_iSprayBanTimestamp[client] = 0; g_iSprayUnbanTimestamp[client] = -1; g_fNextSprayTime[client] = 0.0; @@ -2191,7 +2259,7 @@ void FormatRemainingTime(int iTimestamp, char[] sBuffer, int iBuffSize) seconds, SingularOrMultiple(seconds) ? "Seconds" : "Second"); } else - Format(sBuffer, iBuffSize, "%d %s", seconds, SingularOrMultiple(seconds)?"Seconds":"Second"); + Format(sBuffer, iBuffSize, "%d %s", seconds, SingularOrMultiple(seconds) ? "Seconds":"Second"); } bool IsPointInsideAABB(float vecPoint[3], float AABB[6]) diff --git a/Teleport/scripting/Teleport.sp b/Teleport/scripting/Teleport.sp new file mode 100644 index 00000000..24172883 --- /dev/null +++ b/Teleport/scripting/Teleport.sp @@ -0,0 +1,275 @@ +#pragma semicolon 1 + +#include +#include + +#pragma newdecls required + +public Plugin myinfo = +{ + name = "Teleport Commands", + author = "Obus", + description = "Adds commands to teleport players.", + version = "1.0", + url = "" +} + +public void OnPluginStart() +{ + LoadTranslations("common.phrases"); + + RegAdminCmd("sm_bring", Command_Bring, ADMFLAG_GENERIC, "Brings a player to your position."); + RegAdminCmd("sm_goto", Command_Goto, ADMFLAG_GENERIC, "Teleports you to a player."); + RegAdminCmd("sm_send", Command_Send, ADMFLAG_GENERIC, "Sends a player to another player."); + RegAdminCmd("sm_tpaim", Command_TpAim, ADMFLAG_GENERIC, "Teleports a player to your crosshair."); +} + +public Action Command_Bring(int client, int argc) +{ + if (!client) + { + PrintToServer("[SM] Cannot use command from server console."); + return Plugin_Handled; + } + + if (argc < 1) + { + PrintToChat(client, "[SM] Usage: sm_bring "); + return Plugin_Handled; + } + + float vecClientPos[3]; + char sArgs[64]; + char sTargetName[MAX_TARGET_LENGTH]; + int iTargets[MAXPLAYERS]; + int iTargetCount; + bool bIsML; + + GetCmdArg(1, sArgs, sizeof(sArgs)); + GetClientAbsOrigin(client, vecClientPos); + + if ((iTargetCount = ProcessTargetString(sArgs, client, iTargets, MAXPLAYERS, COMMAND_FILTER_ALIVE, sTargetName, sizeof(sTargetName), bIsML)) <= 0) + { + ReplyToTargetError(client, iTargetCount); + return Plugin_Handled; + } + + for (int i = 0; i < iTargetCount; i++) + { + TeleportEntity(iTargets[i], vecClientPos, NULL_VECTOR, NULL_VECTOR); + } + + PrintToChatAll("\x01[SM] \x04%N\x01: Brought \x04%s\x01.", client, sTargetName); + + return Plugin_Handled; +} + +public Action Command_Goto(int client, int argc) +{ + if (!client) + { + PrintToServer("[SM] Cannot use command from server console."); + return Plugin_Handled; + } + + if (argc < 1) + { + PrintToChat(client, "[SM] Usage: sm_goto "); + return Plugin_Handled; + } + + int iTarget; + char sTarget[32]; + + GetCmdArg(1, sTarget, sizeof(sTarget)); + + if (!strcmp(sTarget, "@aim")) + { + if (argc > 1) + { + char sOption[2]; + + GetCmdArg(2, sOption, sizeof(sOption)); + + if (StringToInt(sOption) <= 0) + { + float vecEndPos[3]; + + if (!TracePlayerAngles(client, vecEndPos)) + { + PrintToChat(client, "[SM] Couldn't perform trace to your crosshair."); + return Plugin_Handled; + } + + TeleportEntity(client, vecEndPos, NULL_VECTOR, NULL_VECTOR); + PrintToChatAll("\x01[SM] \x04%N\x01: Teleported to their crosshair.", client); + + return Plugin_Handled; + } + } + + int AimTarget = GetClientAimTarget(client, true); + + if (AimTarget == -1) + { + float vecEndPos[3]; + + if (!TracePlayerAngles(client, vecEndPos)) + { + PrintToChat(client, "[SM] Couldn't perform trace to your crosshair."); + return Plugin_Handled; + } + + TeleportEntity(client, vecEndPos, NULL_VECTOR, NULL_VECTOR); + PrintToChatAll("\x01[SM] \x04%N\x01: Teleported to their crosshair.", client); + + return Plugin_Handled; + } + } + + if (!(iTarget = FindTarget(client, sTarget))) + return Plugin_Handled; + + float vecTargetPos[3]; + + GetClientAbsOrigin(iTarget, vecTargetPos); + + TeleportEntity(client, vecTargetPos, NULL_VECTOR, NULL_VECTOR); + + PrintToChatAll("\x01[SM] \x04%N\x01: Teleported to \x04%N\x01.", client, iTarget); + + return Plugin_Handled; +} + +public Action Command_Send(int client, int argc) +{ + if (argc < 2) + { + PrintToChat(client, "[SM] Usage: sm_send "); + return Plugin_Handled; + } + + float vecTargetPos[3]; + int iTarget; + char sArgs[32]; + char sTarget[32]; + char sTargetName[MAX_TARGET_LENGTH]; + int iTargets[MAXPLAYERS]; + int iTargetCount; + bool bIsML; + + GetCmdArg(1, sArgs, sizeof(sArgs)); + GetCmdArg(2, sTarget, sizeof(sTarget)); + + if ((iTargetCount = ProcessTargetString(sArgs, client, iTargets, MAXPLAYERS, COMMAND_FILTER_ALIVE, sTargetName, sizeof(sTargetName), bIsML)) <= 0) + { + ReplyToTargetError(client, iTargetCount); + return Plugin_Handled; + } + + if (!strcmp(sTarget, "@aim")) + { + if (!client) + { + ReplyToCommand(client, "[SM] Cannot use @aim from server console."); + return Plugin_Handled; + } + + float vecEndPos[3]; + + if (!TracePlayerAngles(client, vecEndPos)) + { + PrintToChat(client, "[SM] Couldn't perform trace to your crosshair."); + return Plugin_Handled; + } + + for (int i = 0; i < iTargetCount; i++) + { + TeleportEntity(iTargets[i], vecEndPos, NULL_VECTOR, NULL_VECTOR); + } + + PrintToChatAll("\x01[SM] \x04%N\x01: Teleported \x04%s\x01 to their crosshair.", client, sTargetName); + + return Plugin_Handled; + } + + if (!(iTarget = FindTarget(client, sTarget))) + return Plugin_Handled; + + GetClientAbsOrigin(iTarget, vecTargetPos); + + for (int i = 0; i < iTargetCount; i++) + { + TeleportEntity(iTargets[i], vecTargetPos, NULL_VECTOR, NULL_VECTOR); + } + + PrintToChatAll("\x01[SM] \x04%N\x01: Teleported \x04%s\x01 to \x04%N\x01.", client, sTargetName, iTarget); + + return Plugin_Handled; +} + +public Action Command_TpAim(int client, int argc) +{ + if (!client) + { + PrintToServer("[SM] Cannot use command from server console."); + return Plugin_Handled; + } + + float vecEndPos[3]; + char sArgs[32]; + char sTargetName[MAX_TARGET_LENGTH]; + int iTargets[MAXPLAYERS]; + int iTargetCount; + bool bIsML; + + GetCmdArg(1, sArgs, sizeof(sArgs)); + + if ((iTargetCount = ProcessTargetString(sArgs, client, iTargets, MAXPLAYERS, COMMAND_FILTER_ALIVE, sTargetName, sizeof(sTargetName), bIsML)) <= 0) + { + ReplyToTargetError(client, iTargetCount); + return Plugin_Handled; + } + + TracePlayerAngles(client, vecEndPos); + + for (int i = 0; i < iTargetCount; i++) + { + TeleportEntity(iTargets[i], vecEndPos, NULL_VECTOR, NULL_VECTOR); + } + + PrintToChatAll("\x01[SM] \x04%N\x01: Teleported \x04%s\x01 to their crosshair.", client, sTargetName); + + return Plugin_Handled; +} + +bool TracePlayerAngles(int client, float vecResult[3]) +{ + if (!IsClientInGame(client)) + return false; + + float vecEyeAngles[3]; + float vecEyeOrigin[3]; + + GetClientEyeAngles(client, vecEyeAngles); + GetClientEyePosition(client, vecEyeOrigin); + + Handle hTraceRay = TR_TraceRayFilterEx(vecEyeOrigin, vecEyeAngles, MASK_SHOT_HULL, RayType_Infinite, FilterPlayers); + + if (TR_DidHit(hTraceRay)) + { + TR_GetEndPosition(vecResult, hTraceRay); + CloseHandle(hTraceRay); + + return true; + } + + CloseHandle(hTraceRay); + + return false; +} + +stock bool FilterPlayers(int entity, int contentsMask) +{ + return entity > MaxClients; +}