Misc: Move shared stuff to shared git.
This commit is contained in:
parent
52afea0b79
commit
73ac24c65c
@ -1,130 +0,0 @@
|
|||||||
#include <sourcemod>
|
|
||||||
|
|
||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#define PLUGIN_VERSION "1.0"
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "AdminCheats",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Allows usage of (most) cheat commands for admins.",
|
|
||||||
version = PLUGIN_VERSION,
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
ConVar g_CVar_sv_cheats;
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
g_CVar_sv_cheats = FindConVar("sv_cheats");
|
|
||||||
g_CVar_sv_cheats.Flags &= ~FCVAR_NOTIFY;
|
|
||||||
g_CVar_sv_cheats.Flags &= ~FCVAR_REPLICATED;
|
|
||||||
g_CVar_sv_cheats.AddChangeHook(OnConVarChanged);
|
|
||||||
g_CVar_sv_cheats.SetInt(1);
|
|
||||||
|
|
||||||
MakeCheatCommand("give");
|
|
||||||
|
|
||||||
int NumHooks = 0;
|
|
||||||
char sConCommand[128];
|
|
||||||
bool IsCommand;
|
|
||||||
int Flags;
|
|
||||||
Handle hSearch = FindFirstConCommand(sConCommand, sizeof(sConCommand), IsCommand, Flags);
|
|
||||||
do
|
|
||||||
{
|
|
||||||
if(IsCommand && Flags & FCVAR_CHEAT)
|
|
||||||
{
|
|
||||||
AddCommandListener(OnCheatCommand, sConCommand);
|
|
||||||
NumHooks++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(FindNextConCommand(hSearch, sConCommand, sizeof(sConCommand), IsCommand, Flags));
|
|
||||||
|
|
||||||
AddCommandListener(OnCheatCommand, "kill"); NumHooks++;
|
|
||||||
AddCommandListener(OnCheatCommand, "explode"); NumHooks++;
|
|
||||||
|
|
||||||
PrintToServer("Hooked %d cheat commands.", NumHooks);
|
|
||||||
|
|
||||||
UpdateClients();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginEnd()
|
|
||||||
{
|
|
||||||
g_CVar_sv_cheats.SetInt(0);
|
|
||||||
g_CVar_sv_cheats.Flags |= FCVAR_NOTIFY;
|
|
||||||
g_CVar_sv_cheats.Flags |= FCVAR_REPLICATED;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
|
||||||
{
|
|
||||||
g_CVar_sv_cheats.SetInt(1);
|
|
||||||
CreateTimer(0.1, Timer_UpdateClients);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Timer_UpdateClients(Handle timer, Handle hndl)
|
|
||||||
{
|
|
||||||
UpdateClients();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void UpdateClients()
|
|
||||||
{
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(i) && !IsFakeClient(i) && IsClientAuthorized(i))
|
|
||||||
OnClientPostAdminCheck(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPutInServer(int client)
|
|
||||||
{
|
|
||||||
if(IsFakeClient(client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
SendConVarValue(client, g_CVar_sv_cheats, "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPostAdminCheck(int client)
|
|
||||||
{
|
|
||||||
if(IsFakeClient(client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(g_CVar_sv_cheats.BoolValue && CheckCommandAccess(client, "", ADMFLAG_CHEATS))
|
|
||||||
SendConVarValue(client, g_CVar_sv_cheats, "1");
|
|
||||||
else
|
|
||||||
SendConVarValue(client, g_CVar_sv_cheats, "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnCheatCommand(int client, const char[] command, int argc)
|
|
||||||
{
|
|
||||||
if(client == 0)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
if(IsClientAuthorized(client) && CheckCommandAccess(client, "", ADMFLAG_CHEATS))
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
if(!argc && (StrEqual(command, "kill") || StrEqual(command, "explode")))
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
|
|
||||||
{
|
|
||||||
if(!impulse)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
if(impulse == 100 || impulse == 201)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
if(IsClientAuthorized(client) && CheckCommandAccess(client, "", ADMFLAG_CHEATS))
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void MakeCheatCommand(const char[] name)
|
|
||||||
{
|
|
||||||
int Flags = GetCommandFlags(name);
|
|
||||||
if(Flags != INVALID_FCVAR_FLAGS)
|
|
||||||
SetCommandFlags(name, FCVAR_CHEAT | Flags);
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdkhooks>
|
|
||||||
#include <sdktools>
|
|
||||||
|
|
||||||
bool g_bIsAdmin[MAXPLAYERS + 1] = {false, ...};
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "AdminIcon",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Gives admins a defuser.",
|
|
||||||
version = "1.0",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
g_bIsAdmin[client] = false;
|
|
||||||
if(IsClientInGame(client) && !IsFakeClient(client) && IsClientAuthorized(client))
|
|
||||||
OnClientPostAdminCheck(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientConnected(int client)
|
|
||||||
{
|
|
||||||
g_bIsAdmin[client] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientDisconnect(int client)
|
|
||||||
{
|
|
||||||
g_bIsAdmin[client] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPostAdminCheck(int client)
|
|
||||||
{
|
|
||||||
if(IsFakeClient(client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(GetAdminFlag(GetUserAdmin(client), Admin_Generic))
|
|
||||||
g_bIsAdmin[client] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnGameFrame()
|
|
||||||
{
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(g_bIsAdmin[client])
|
|
||||||
{
|
|
||||||
if(IsClientObserver(client))
|
|
||||||
SetEntProp(client, Prop_Send, "m_bHasDefuser", 0);
|
|
||||||
else
|
|
||||||
SetEntProp(client, Prop_Send, "m_bHasDefuser", 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnEntityCreated(int entity, const char[] classname)
|
|
||||||
{
|
|
||||||
if(IsValidEntity(entity) && StrEqual(classname, "item_defuser"))
|
|
||||||
{
|
|
||||||
SDKHook(entity, SDKHook_Spawn, OnWeaponSpawned);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnWeaponSpawned(int entity)
|
|
||||||
{
|
|
||||||
AcceptEntityInput(entity, "Kill");
|
|
||||||
}
|
|
@ -1,493 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
|
|
||||||
#pragma dynamic 128*1024
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
#include <SteamWorks>
|
|
||||||
#include <cstrike>
|
|
||||||
#include <AdvancedTargeting>
|
|
||||||
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
Handle g_FriendsArray[MAXPLAYERS + 1] = {INVALID_HANDLE, ...};
|
|
||||||
bool g_bLateLoad = false;
|
|
||||||
|
|
||||||
#include "SteamAPI.secret" //#define STEAM_API_KEY here
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "Advanced Targeting",
|
|
||||||
author = "BotoX + Obus",
|
|
||||||
description = "Adds extra targeting methods",
|
|
||||||
version = "1.2",
|
|
||||||
url = "https://github.com/CSSZombieEscape/sm-plugins/tree/master/AdvancedTargeting/"
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
AddMultiTargetFilter("@admins", Filter_Admin, "Admins", false);
|
|
||||||
AddMultiTargetFilter("@!admins", Filter_NotAdmin, "Not Admins", false);
|
|
||||||
AddMultiTargetFilter("@friends", Filter_Friends, "Steam Friends", false);
|
|
||||||
AddMultiTargetFilter("@!friends", Filter_NotFriends, "Not Steam Friends", false);
|
|
||||||
AddMultiTargetFilter("@random", Filter_Random, "a Random Player", false);
|
|
||||||
AddMultiTargetFilter("@randomct", Filter_RandomCT, "a Random CT", false);
|
|
||||||
AddMultiTargetFilter("@randomt", Filter_RandomT, "a Random T", false);
|
|
||||||
|
|
||||||
RegConsoleCmd("sm_admins", Command_Admins, "Currently online admins.");
|
|
||||||
RegConsoleCmd("sm_friends", Command_Friends, "Currently online friends.");
|
|
||||||
|
|
||||||
if(g_bLateLoad)
|
|
||||||
{
|
|
||||||
char sSteam32ID[32];
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(i) && !IsFakeClient(i) && IsClientAuthorized(i) &&
|
|
||||||
GetClientAuthId(i, AuthId_Steam2, sSteam32ID, sizeof(sSteam32ID)))
|
|
||||||
{
|
|
||||||
OnClientAuthorized(i, sSteam32ID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginEnd()
|
|
||||||
{
|
|
||||||
RemoveMultiTargetFilter("@admins", Filter_Admin);
|
|
||||||
RemoveMultiTargetFilter("@!admins", Filter_NotAdmin);
|
|
||||||
RemoveMultiTargetFilter("@friends", Filter_Friends);
|
|
||||||
RemoveMultiTargetFilter("@!friends", Filter_NotFriends);
|
|
||||||
RemoveMultiTargetFilter("@random", Filter_Random);
|
|
||||||
RemoveMultiTargetFilter("@randomct", Filter_RandomCT);
|
|
||||||
RemoveMultiTargetFilter("@randomt", Filter_RandomT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
|
|
||||||
{
|
|
||||||
CreateNative("IsClientFriend", Native_IsClientFriend);
|
|
||||||
CreateNative("ReadClientFriends", Native_ReadClientFriends);
|
|
||||||
RegPluginLibrary("AdvancedTargeting");
|
|
||||||
|
|
||||||
g_bLateLoad = late;
|
|
||||||
return APLRes_Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Admins(int client, int args)
|
|
||||||
{
|
|
||||||
char aBuf[1024];
|
|
||||||
char aBuf2[MAX_NAME_LENGTH];
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(i) && !IsFakeClient(i) && GetAdminFlag(GetUserAdmin(i), Admin_Generic))
|
|
||||||
{
|
|
||||||
GetClientName(i, aBuf2, sizeof(aBuf2));
|
|
||||||
StrCat(aBuf, sizeof(aBuf), aBuf2);
|
|
||||||
StrCat(aBuf, sizeof(aBuf), ", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(strlen(aBuf))
|
|
||||||
{
|
|
||||||
aBuf[strlen(aBuf) - 2] = 0;
|
|
||||||
ReplyToCommand(client, "[SM] Admins currently online: %s", aBuf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ReplyToCommand(client, "[SM] Admins currently online: none");
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Friends(int client, int args)
|
|
||||||
{
|
|
||||||
if(!client)
|
|
||||||
return Plugin_Handled;
|
|
||||||
|
|
||||||
if(g_FriendsArray[client] == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
PrintToChat(client, "[SM] Could not read your friendslist, your profile must be set to public!");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char aBuf[1024];
|
|
||||||
char aBuf2[MAX_NAME_LENGTH];
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(i) && !IsFakeClient(i) && IsClientAuthorized(i))
|
|
||||||
{
|
|
||||||
int Steam3ID = GetSteamAccountID(i);
|
|
||||||
|
|
||||||
if(FindValueInArray(g_FriendsArray[client], Steam3ID) != -1)
|
|
||||||
{
|
|
||||||
GetClientName(i, aBuf2, sizeof(aBuf2));
|
|
||||||
StrCat(aBuf, sizeof(aBuf), aBuf2);
|
|
||||||
StrCat(aBuf, sizeof(aBuf), ", ");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(strlen(aBuf))
|
|
||||||
{
|
|
||||||
aBuf[strlen(aBuf) - 2] = 0;
|
|
||||||
PrintToChat(client, "[SM] Friends currently online: %s", aBuf);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
PrintToChat(client, "[SM] Friends currently online: none");
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Filter_Admin(const char[] sPattern, Handle hClients, int client)
|
|
||||||
{
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(i) && !IsFakeClient(i) && GetAdminFlag(GetUserAdmin(i), Admin_Generic))
|
|
||||||
{
|
|
||||||
PushArrayCell(hClients, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Filter_NotAdmin(const char[] sPattern, Handle hClients, int client)
|
|
||||||
{
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(i) && !IsFakeClient(i) && !GetAdminFlag(GetUserAdmin(i), Admin_Generic))
|
|
||||||
{
|
|
||||||
PushArrayCell(hClients, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Filter_Friends(const char[] sPattern, Handle hClients, int client)
|
|
||||||
{
|
|
||||||
if(g_FriendsArray[client] == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
PrintToChat(client, "[SM] Could not read your friendslist, your profile must be set to public!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(i != client && IsClientInGame(i) && !IsFakeClient(i) && IsClientAuthorized(i))
|
|
||||||
{
|
|
||||||
int Steam3ID = GetSteamAccountID(i);
|
|
||||||
|
|
||||||
if(FindValueInArray(g_FriendsArray[client], Steam3ID) != -1)
|
|
||||||
PushArrayCell(hClients, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Filter_NotFriends(const char[] sPattern, Handle hClients, int client)
|
|
||||||
{
|
|
||||||
if(g_FriendsArray[client] == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
PrintToChat(client, "[SM] Could not read your friendslist, your profile must be set to public!");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(i != client && IsClientInGame(i) && !IsFakeClient(i) && IsClientAuthorized(i))
|
|
||||||
{
|
|
||||||
int Steam3ID = GetSteamAccountID(i);
|
|
||||||
|
|
||||||
if(FindValueInArray(g_FriendsArray[client], Steam3ID) == -1)
|
|
||||||
PushArrayCell(hClients, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Filter_Random(const char[] sPattern, Handle hClients, int client)
|
|
||||||
{
|
|
||||||
int iRand = GetRandomInt(1, MaxClients);
|
|
||||||
|
|
||||||
if(IsClientInGame(iRand) && IsPlayerAlive(iRand))
|
|
||||||
PushArrayCell(hClients, iRand);
|
|
||||||
else
|
|
||||||
Filter_Random(sPattern, hClients, client);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Filter_RandomCT(const char[] sPattern, Handle hClients, int client)
|
|
||||||
{
|
|
||||||
int iCTCount = GetTeamClientCount(CS_TEAM_CT);
|
|
||||||
|
|
||||||
if(!iCTCount)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int[] iCTs = new int[iCTCount];
|
|
||||||
|
|
||||||
int iCurIndex;
|
|
||||||
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(!IsClientInGame(i) || GetClientTeam(i) != CS_TEAM_CT)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(!IsPlayerAlive(i))
|
|
||||||
{
|
|
||||||
iCTCount--;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
iCTs[iCurIndex] = i;
|
|
||||||
iCurIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
PushArrayCell(hClients, iCTs[GetRandomInt(0, iCTCount-1)]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool Filter_RandomT(const char[] sPattern, Handle hClients, int client)
|
|
||||||
{
|
|
||||||
int iTCount = GetTeamClientCount(CS_TEAM_T);
|
|
||||||
|
|
||||||
if(!iTCount)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int[] iTs = new int[iTCount];
|
|
||||||
|
|
||||||
int iCurIndex;
|
|
||||||
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(!IsClientInGame(i) || GetClientTeam(i) != CS_TEAM_T)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(!IsPlayerAlive(i))
|
|
||||||
{
|
|
||||||
iTCount--;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
iTs[iCurIndex] = i;
|
|
||||||
iCurIndex++;
|
|
||||||
}
|
|
||||||
|
|
||||||
PushArrayCell(hClients, iTs[GetRandomInt(0, iTCount-1)]);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientAuthorized(int client, const char[] auth)
|
|
||||||
{
|
|
||||||
if(IsFakeClient(client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
char sSteam64ID[32];
|
|
||||||
Steam32IDtoSteam64ID(auth, sSteam64ID, sizeof(sSteam64ID));
|
|
||||||
|
|
||||||
static char sRequest[256];
|
|
||||||
FormatEx(sRequest, sizeof(sRequest), "http://api.steampowered.com/ISteamUser/GetFriendList/v0001/?key=%s&steamid=%s&relationship=friend&format=vdf", STEAM_API_KEY, sSteam64ID);
|
|
||||||
|
|
||||||
Handle hRequest = SteamWorks_CreateHTTPRequest(k_EHTTPMethodGET, sRequest);
|
|
||||||
if (!hRequest ||
|
|
||||||
!SteamWorks_SetHTTPRequestContextValue(hRequest, client) ||
|
|
||||||
!SteamWorks_SetHTTPCallbacks(hRequest, OnTransferComplete) ||
|
|
||||||
!SteamWorks_SendHTTPRequest(hRequest))
|
|
||||||
{
|
|
||||||
CloseHandle(hRequest);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientDisconnect(int client)
|
|
||||||
{
|
|
||||||
if(g_FriendsArray[client] != INVALID_HANDLE)
|
|
||||||
CloseHandle(g_FriendsArray[client]);
|
|
||||||
|
|
||||||
g_FriendsArray[client] = INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int OnTransferComplete(Handle hRequest, bool bFailure, bool bRequestSuccessful, EHTTPStatusCode eStatusCode, int client)
|
|
||||||
{
|
|
||||||
if(bFailure || !bRequestSuccessful || eStatusCode != k_EHTTPStatusCode200OK)
|
|
||||||
{
|
|
||||||
// Private profile or maybe steam down?
|
|
||||||
//LogError("SteamAPI HTTP Response failed: %d", eStatusCode);
|
|
||||||
CloseHandle(hRequest);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Length;
|
|
||||||
SteamWorks_GetHTTPResponseBodySize(hRequest, Length);
|
|
||||||
|
|
||||||
char[] sData = new char[Length];
|
|
||||||
SteamWorks_GetHTTPResponseBodyData(hRequest, sData, Length);
|
|
||||||
//SteamWorks_GetHTTPResponseBodyCallback(hRequest, APIWebResponse, client);
|
|
||||||
|
|
||||||
CloseHandle(hRequest);
|
|
||||||
|
|
||||||
APIWebResponse(sData, client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void APIWebResponse(const char[] sData, int client)
|
|
||||||
{
|
|
||||||
KeyValues Response = new KeyValues("SteamAPIResponse");
|
|
||||||
if(!Response.ImportFromString(sData, "SteamAPIResponse"))
|
|
||||||
{
|
|
||||||
LogError("ImportFromString(sData, \"SteamAPIResponse\") failed.");
|
|
||||||
delete Response;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!Response.JumpToKey("friends"))
|
|
||||||
{
|
|
||||||
LogError("JumpToKey(\"friends\") failed.");
|
|
||||||
delete Response;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No friends?
|
|
||||||
if(!Response.GotoFirstSubKey())
|
|
||||||
{
|
|
||||||
//LogError("GotoFirstSubKey() failed.");
|
|
||||||
delete Response;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(g_FriendsArray[client] != INVALID_HANDLE)
|
|
||||||
CloseHandle(g_FriendsArray[client]);
|
|
||||||
|
|
||||||
g_FriendsArray[client] = CreateArray();
|
|
||||||
|
|
||||||
char sCommunityID[32];
|
|
||||||
do
|
|
||||||
{
|
|
||||||
Response.GetString("steamid", sCommunityID, sizeof(sCommunityID));
|
|
||||||
|
|
||||||
PushArrayCell(g_FriendsArray[client], Steam64toSteam3(sCommunityID));
|
|
||||||
}
|
|
||||||
while(Response.GotoNextKey());
|
|
||||||
|
|
||||||
delete Response;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
stock bool Steam32IDtoSteam64ID(const char[] sSteam32ID, char[] sSteam64ID, int Size)
|
|
||||||
{
|
|
||||||
if(strlen(sSteam32ID) < 11 || strncmp(sSteam32ID[0], "STEAM_0:", 8))
|
|
||||||
{
|
|
||||||
sSteam64ID[0] = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
int iUpper = 765611979;
|
|
||||||
int isSteam64ID = StringToInt(sSteam32ID[10]) * 2 + 60265728 + sSteam32ID[8] - 48;
|
|
||||||
|
|
||||||
int iDiv = isSteam64ID / 100000000;
|
|
||||||
int iIdx = 9 - (iDiv ? (iDiv / 10 + 1) : 0);
|
|
||||||
iUpper += iDiv;
|
|
||||||
|
|
||||||
IntToString(isSteam64ID, sSteam64ID[iIdx], Size - iIdx);
|
|
||||||
iIdx = sSteam64ID[9];
|
|
||||||
IntToString(iUpper, sSteam64ID, Size);
|
|
||||||
sSteam64ID[9] = iIdx;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
stock int Steam64toSteam3(const char[] sSteam64ID)
|
|
||||||
{
|
|
||||||
if(strlen(sSteam64ID) != 17)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
// convert SteamID64 to array of integers
|
|
||||||
int aSteam64ID[17];
|
|
||||||
for(int i = 0; i < 17; i++)
|
|
||||||
aSteam64ID[i] = sSteam64ID[i] - 48;
|
|
||||||
|
|
||||||
// subtract individual SteamID64 identifier (0x0110000100000000)
|
|
||||||
int aSteam64IDIdent[] = {7, 6, 5, 6, 1, 1, 9, 7, 9, 6, 0, 2, 6, 5, 7, 2, 8};
|
|
||||||
int Carry = 0;
|
|
||||||
for(int i = 16; i >= 0; i--)
|
|
||||||
{
|
|
||||||
if(aSteam64ID[i] < aSteam64IDIdent[i] + Carry)
|
|
||||||
{
|
|
||||||
aSteam64ID[i] = aSteam64ID[i] - aSteam64IDIdent[i] - Carry + 10;
|
|
||||||
Carry = 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
aSteam64ID[i] = aSteam64ID[i] - aSteam64IDIdent[i] - Carry;
|
|
||||||
Carry = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
char aBuf[17];
|
|
||||||
int j = 0;
|
|
||||||
bool ZereosDone = false;
|
|
||||||
for(int i = 0; i < 17; i++)
|
|
||||||
{
|
|
||||||
if(!ZereosDone && !aSteam64ID[i])
|
|
||||||
continue;
|
|
||||||
ZereosDone = true;
|
|
||||||
|
|
||||||
aBuf[j++] = aSteam64ID[i] + 48;
|
|
||||||
}
|
|
||||||
|
|
||||||
return StringToInt(aBuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Native_IsClientFriend(Handle plugin, int numParams)
|
|
||||||
{
|
|
||||||
int client = GetNativeCell(1);
|
|
||||||
int friend = GetNativeCell(2);
|
|
||||||
|
|
||||||
if(client > MaxClients || client <= 0 || friend > MaxClients || friend <= 0)
|
|
||||||
{
|
|
||||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!IsClientInGame(client) || !IsClientInGame(friend))
|
|
||||||
{
|
|
||||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not in-game.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(IsFakeClient(client) || IsFakeClient(friend))
|
|
||||||
{
|
|
||||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is fake-client.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(g_FriendsArray[client] == INVALID_HANDLE)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if(IsClientAuthorized(friend))
|
|
||||||
{
|
|
||||||
int Steam3ID = GetSteamAccountID(friend);
|
|
||||||
|
|
||||||
if(FindValueInArray(g_FriendsArray[client], Steam3ID) != -1)
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Native_ReadClientFriends(Handle plugin, int numParams)
|
|
||||||
{
|
|
||||||
int client = GetNativeCell(1);
|
|
||||||
|
|
||||||
if(client > MaxClients || client <= 0)
|
|
||||||
{
|
|
||||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(g_FriendsArray[client] != INVALID_HANDLE)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
#if defined _AdvancedTargeting_Included
|
|
||||||
#endinput
|
|
||||||
#endif
|
|
||||||
#define _AdvancedTargeting_Included
|
|
||||||
|
|
||||||
native int IsClientFriend(int client, int friend);
|
|
||||||
native int ReadClientFriends(int client);
|
|
||||||
|
|
||||||
public SharedPlugin __pl_AdvancedTargeting =
|
|
||||||
{
|
|
||||||
name = "AdvancedTargeting",
|
|
||||||
file = "AdvancedTargeting.smx",
|
|
||||||
#if defined REQUIRE_PLUGIN
|
|
||||||
required = 1,
|
|
||||||
#else
|
|
||||||
required = 0,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#if !defined REQUIRE_PLUGIN
|
|
||||||
public __pl_AdvancedTargeting_SetNTVOptional()
|
|
||||||
{
|
|
||||||
MarkNativeAsOptional("IsClientFriend");
|
|
||||||
MarkNativeAsOptional("ReadClientFriends");
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,71 +0,0 @@
|
|||||||
#include <sourcemod>
|
|
||||||
|
|
||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
int g_Client_CommandCount[MAXPLAYERS + 1];
|
|
||||||
float g_Client_LastFlood[MAXPLAYERS + 1];
|
|
||||||
|
|
||||||
#define MAX_COMMANDS 100
|
|
||||||
#define INTERVAL 1.0
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "AntiFlood",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "",
|
|
||||||
version = "1.0",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
/* Late load */
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(client))
|
|
||||||
OnClientConnected(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
AddCommandListener(OnAnyCommand, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientConnected(int client)
|
|
||||||
{
|
|
||||||
g_Client_CommandCount[client] = 0;
|
|
||||||
g_Client_LastFlood[client] = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//public Action OnClientCommand(int client, int args)
|
|
||||||
public Action OnAnyCommand(int client, const char[] command, int argc)
|
|
||||||
{
|
|
||||||
if(FloodCheck(client))
|
|
||||||
return Plugin_Handled;
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientSettingsChanged(int client)
|
|
||||||
{
|
|
||||||
FloodCheck(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FloodCheck(int client)
|
|
||||||
{
|
|
||||||
if(client <= 0 || client > MaxClients)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(++g_Client_CommandCount[client] <= MAX_COMMANDS)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
float Time = GetGameTime();
|
|
||||||
if(Time >= g_Client_LastFlood[client] + INTERVAL)
|
|
||||||
{
|
|
||||||
g_Client_LastFlood[client] = Time;
|
|
||||||
g_Client_CommandCount[client] = 0;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
KickClientEx(client, "STOP FLOODING THE SERVER!!!");
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,115 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <cstrike>
|
|
||||||
|
|
||||||
#undef REQUIRE_PLUGIN
|
|
||||||
#tryinclude <zombiereloaded>
|
|
||||||
#define REQUIRE_PLUGIN
|
|
||||||
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
bool g_bZRLoaded;
|
|
||||||
|
|
||||||
ConVar g_cvarJumpsUntilBlock = null;
|
|
||||||
ConVar g_cvarIntervalBetweenJumps = null;
|
|
||||||
ConVar g_cvarCooldownInterval = null;
|
|
||||||
|
|
||||||
float g_fLastJumpTime[MAXPLAYERS + 1];
|
|
||||||
|
|
||||||
int g_iFastJumpCount[MAXPLAYERS + 1];
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "Anti Jump Spam",
|
|
||||||
author = "Obus",
|
|
||||||
description = "Prevents clients from spamming jump to avoid knockback in crawl spaces.",
|
|
||||||
version = "1.0.0",
|
|
||||||
url = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
g_cvarJumpsUntilBlock = CreateConVar("sm_ajs_jumpsuntilblock", "5", "Successive jumps until anti jump-spam kicks in.");
|
|
||||||
g_cvarIntervalBetweenJumps = CreateConVar("sm_ajs_jumpinterval", "0.2", "If a client jumps faster than this their jumps will be blocked after the amount of jumps specified in \"sm_ajs_jumpsuntilblock\" is reached.");
|
|
||||||
g_cvarCooldownInterval = CreateConVar("sm_ajs_cooldowninterval", "0.0", "Changes the amount of time required for a jump to not be considered spam anymore. (Setting this to 0 makes the interval sm_ajs_jumpinterval * 2)");
|
|
||||||
|
|
||||||
AutoExecConfig(true, "plugin.antijumpspam");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnAllPluginsLoaded()
|
|
||||||
{
|
|
||||||
g_bZRLoaded = LibraryExists("zombiereloaded");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnLibraryAdded(const char[] sName)
|
|
||||||
{
|
|
||||||
if (strcmp(sName, "zombiereloaded", false) == 0)
|
|
||||||
g_bZRLoaded = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnLibraryRemoved(const char[] sName)
|
|
||||||
{
|
|
||||||
if (strcmp(sName, "zombiereloaded", false) == 0)
|
|
||||||
g_bZRLoaded = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientDisconnect(int client)
|
|
||||||
{
|
|
||||||
g_fLastJumpTime[client] = 0.0;
|
|
||||||
g_iFastJumpCount[client] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnPlayerRunCmd(int client, int &buttons)
|
|
||||||
{
|
|
||||||
static bool bHoldingJump[MAXPLAYERS + 1];
|
|
||||||
|
|
||||||
#if defined _zr_included
|
|
||||||
if (!IsPlayerAlive(client) || (g_bZRLoaded && !ZR_IsClientZombie(client)) || (!g_bZRLoaded && GetClientTeam(client) != CS_TEAM_T))
|
|
||||||
return Plugin_Continue;
|
|
||||||
#else
|
|
||||||
if (!IsPlayerAlive(client) || GetClientTeam(client) != CS_TEAM_T)
|
|
||||||
return Plugin_Continue;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (buttons & IN_JUMP && GetEntityFlags(client) & FL_ONGROUND)
|
|
||||||
{
|
|
||||||
float fCurTime = GetEngineTime();
|
|
||||||
float fTimeSinceLastJump = fCurTime - g_fLastJumpTime[client];
|
|
||||||
|
|
||||||
if (!bHoldingJump[client])
|
|
||||||
{
|
|
||||||
if (fTimeSinceLastJump > (g_cvarCooldownInterval.FloatValue > 0.0 ? g_cvarCooldownInterval.FloatValue : g_cvarIntervalBetweenJumps.FloatValue * 2.0) && g_iFastJumpCount[client] > 0)
|
|
||||||
{
|
|
||||||
int iJumpsToDeduct = RoundToFloor(fTimeSinceLastJump / (g_cvarCooldownInterval.FloatValue > 0.0 ? g_cvarCooldownInterval.FloatValue : g_cvarIntervalBetweenJumps.FloatValue * 2));
|
|
||||||
|
|
||||||
iJumpsToDeduct = iJumpsToDeduct <= g_iFastJumpCount[client] ? iJumpsToDeduct : g_iFastJumpCount[client];
|
|
||||||
|
|
||||||
g_iFastJumpCount[client] -= iJumpsToDeduct;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (g_iFastJumpCount[client] >= g_cvarJumpsUntilBlock.IntValue)
|
|
||||||
{
|
|
||||||
buttons &= ~IN_JUMP;
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bHoldingJump[client])
|
|
||||||
{
|
|
||||||
bHoldingJump[client] = true;
|
|
||||||
|
|
||||||
if (fTimeSinceLastJump < g_cvarIntervalBetweenJumps.FloatValue)
|
|
||||||
g_iFastJumpCount[client]++;
|
|
||||||
|
|
||||||
g_fLastJumpTime[client] = fCurTime;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (bHoldingJump[client])
|
|
||||||
{
|
|
||||||
bHoldingJump[client] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
@ -1,79 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
|
|
||||||
#define REMIND_INTERVAL 5.0
|
|
||||||
|
|
||||||
bool g_IsMasked[MAXPLAYERS + 1] = {false, ...};
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "AntiPingMask",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Shows real ping when client tries to mask it.",
|
|
||||||
version = "1.0",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnClientDisconnect(int client)
|
|
||||||
{
|
|
||||||
g_IsMasked[client] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMapStart()
|
|
||||||
{
|
|
||||||
CreateTimer(REMIND_INTERVAL, Timer_Remind, _, TIMER_REPEAT | TIMER_FLAG_NO_MAPCHANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Timer_Remind(Handle Timer, any Data)
|
|
||||||
{
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(g_IsMasked[client] && IsClientInGame(client))
|
|
||||||
PrintToChat(client, "[SM] Please turn off your pingmask! (cl_cmdrate 100)");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientSettingsChanged(int client)
|
|
||||||
{
|
|
||||||
static char sCmdRate[32];
|
|
||||||
GetClientInfo(client, "cl_cmdrate", sCmdRate, sizeof(sCmdRate));
|
|
||||||
bool bBadCmdRate = !IsNatural(sCmdRate);
|
|
||||||
|
|
||||||
if(bBadCmdRate)
|
|
||||||
g_IsMasked[client] = true;
|
|
||||||
else
|
|
||||||
g_IsMasked[client] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnGameFrame()
|
|
||||||
{
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(g_IsMasked[client])
|
|
||||||
ForcePing(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ForcePing(int client)
|
|
||||||
{
|
|
||||||
int iResEnt = GetPlayerResourceEntity();
|
|
||||||
if(iResEnt == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
int iLatency = RoundToNearest(GetClientAvgLatency(client, NetFlow_Outgoing) * 1000.0);
|
|
||||||
SetEntProp(iResEnt, Prop_Send, "m_iPing", iLatency, _, client);
|
|
||||||
}
|
|
||||||
|
|
||||||
stock bool IsNatural(const char[] sString)
|
|
||||||
{
|
|
||||||
for(int i = 0; sString[i]; i++)
|
|
||||||
{
|
|
||||||
if(!IsCharNumeric(sString[i]))
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,227 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#include <sourcemod>
|
|
||||||
|
|
||||||
ConVar g_hTvEnabled;
|
|
||||||
ConVar g_hAutoRecord;
|
|
||||||
ConVar g_hMinPlayersStart;
|
|
||||||
ConVar g_hIgnoreBots;
|
|
||||||
ConVar g_hTimeStart;
|
|
||||||
ConVar g_hTimeStop;
|
|
||||||
ConVar g_hFinishMap;
|
|
||||||
ConVar g_hDemoPath;
|
|
||||||
|
|
||||||
bool g_bRestartRecording = false;
|
|
||||||
bool g_bIsRecording = false;
|
|
||||||
bool g_bIsManual = false;
|
|
||||||
|
|
||||||
int g_iRestartRecording;
|
|
||||||
|
|
||||||
// Default: o=rx,g=rx,u=rwx | 755
|
|
||||||
#define DIRECTORY_PERMISSIONS (FPERM_O_READ|FPERM_O_EXEC | FPERM_G_READ|FPERM_G_EXEC | FPERM_U_READ|FPERM_U_WRITE|FPERM_U_EXEC)
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "Auto Recorder",
|
|
||||||
author = "Stevo.TVR",
|
|
||||||
description = "Automates SourceTV recording based on player count and time of day.",
|
|
||||||
version = "1.2.0",
|
|
||||||
url = "http://www.theville.org"
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
g_hAutoRecord = CreateConVar("sm_autorecord_enable", "1", "Enable automatic recording", _, true, 0.0, true, 1.0);
|
|
||||||
g_hMinPlayersStart = CreateConVar("sm_autorecord_minplayers", "4", "Minimum players on server to start recording", _, true, 0.0);
|
|
||||||
g_hIgnoreBots = CreateConVar("sm_autorecord_ignorebots", "1", "Ignore bots in the player count", _, true, 0.0, true, 1.0);
|
|
||||||
g_hTimeStart = CreateConVar("sm_autorecord_timestart", "-1", "Hour in the day to start recording (0-23, -1 disables)");
|
|
||||||
g_hTimeStop = CreateConVar("sm_autorecord_timestop", "-1", "Hour in the day to stop recording (0-23, -1 disables)");
|
|
||||||
g_hFinishMap = CreateConVar("sm_autorecord_finishmap", "1", "If 1, continue recording until the map ends", _, true, 0.0, true, 1.0);
|
|
||||||
g_hDemoPath = CreateConVar("sm_autorecord_path", "demos/", "Path to store recorded demos");
|
|
||||||
|
|
||||||
AutoExecConfig(true, "autorecorder");
|
|
||||||
|
|
||||||
RegAdminCmd("sm_record", Command_Record, ADMFLAG_KICK, "Starts a SourceTV demo");
|
|
||||||
RegAdminCmd("sm_stoprecord", Command_StopRecord, ADMFLAG_KICK, "Stops the current SourceTV demo");
|
|
||||||
|
|
||||||
HookEvent("round_start", OnRoundStart);
|
|
||||||
|
|
||||||
g_hTvEnabled = FindConVar("tv_enable");
|
|
||||||
|
|
||||||
static char sPath[PLATFORM_MAX_PATH];
|
|
||||||
GetConVarString(g_hDemoPath, sPath, sizeof(sPath));
|
|
||||||
|
|
||||||
if(!DirExists(sPath))
|
|
||||||
CreateDirectory(sPath, DIRECTORY_PERMISSIONS);
|
|
||||||
|
|
||||||
HookConVarChange(g_hMinPlayersStart, OnConVarChanged);
|
|
||||||
HookConVarChange(g_hIgnoreBots, OnConVarChanged);
|
|
||||||
HookConVarChange(g_hTimeStart, OnConVarChanged);
|
|
||||||
HookConVarChange(g_hTimeStop, OnConVarChanged);
|
|
||||||
HookConVarChange(g_hDemoPath, OnConVarChanged);
|
|
||||||
|
|
||||||
CreateTimer(300.0, Timer_CheckStatus, _, TIMER_REPEAT);
|
|
||||||
|
|
||||||
StopRecord();
|
|
||||||
CheckStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnRoundStart(Event hEvent, const char[] sEvent, bool bDontBroadcast)
|
|
||||||
{
|
|
||||||
if(g_bRestartRecording && g_iRestartRecording <= GetTime())
|
|
||||||
{
|
|
||||||
StopRecord();
|
|
||||||
CheckStatus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
|
||||||
{
|
|
||||||
if(convar == g_hDemoPath)
|
|
||||||
{
|
|
||||||
if(!DirExists(newValue))
|
|
||||||
CreateDirectory(newValue, DIRECTORY_PERMISSIONS);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
CheckStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMapEnd()
|
|
||||||
{
|
|
||||||
if(g_bIsRecording)
|
|
||||||
{
|
|
||||||
StopRecord();
|
|
||||||
g_bIsManual = false;
|
|
||||||
|
|
||||||
g_bRestartRecording = false;
|
|
||||||
g_iRestartRecording = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPutInServer(int client)
|
|
||||||
{
|
|
||||||
CheckStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientDisconnect_Post(int client)
|
|
||||||
{
|
|
||||||
CheckStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Timer_CheckStatus(Handle hTimer)
|
|
||||||
{
|
|
||||||
CheckStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Record(int client, int args)
|
|
||||||
{
|
|
||||||
if(g_bIsRecording)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] SourceTV is already recording!");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
StartRecord();
|
|
||||||
g_bIsManual = true;
|
|
||||||
|
|
||||||
ReplyToCommand(client, "[SM] SourceTV is now recording...");
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_StopRecord(int client, int args)
|
|
||||||
{
|
|
||||||
if(!g_bIsRecording)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] SourceTV is not recording!");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
StopRecord();
|
|
||||||
|
|
||||||
if(g_bIsManual)
|
|
||||||
{
|
|
||||||
g_bIsManual = false;
|
|
||||||
CheckStatus();
|
|
||||||
}
|
|
||||||
|
|
||||||
ReplyToCommand(client, "[SM] Stopped recording.");
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckStatus()
|
|
||||||
{
|
|
||||||
if(GetConVarBool(g_hAutoRecord) && !g_bIsManual)
|
|
||||||
{
|
|
||||||
int iMinClients = GetConVarInt(g_hMinPlayersStart);
|
|
||||||
|
|
||||||
int iTimeStart = GetConVarInt(g_hTimeStart);
|
|
||||||
int iTimeStop = GetConVarInt(g_hTimeStop);
|
|
||||||
bool bReverseTimes = (iTimeStart > iTimeStop);
|
|
||||||
|
|
||||||
static char sCurrentTime[4];
|
|
||||||
FormatTime(sCurrentTime, sizeof(sCurrentTime), "%H", GetTime());
|
|
||||||
int iCurrentTime = StringToInt(sCurrentTime);
|
|
||||||
|
|
||||||
if(GetPlayerCount() >= iMinClients+1 && (iTimeStart < 0 || (iCurrentTime >= iTimeStart && (bReverseTimes || iCurrentTime < iTimeStop))))
|
|
||||||
{
|
|
||||||
StartRecord();
|
|
||||||
}
|
|
||||||
else if(g_bIsRecording && !GetConVarBool(g_hFinishMap) && (iTimeStop < 0 || iCurrentTime >= iTimeStop))
|
|
||||||
{
|
|
||||||
StopRecord();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int GetPlayerCount()
|
|
||||||
{
|
|
||||||
if(!GetConVarBool(g_hIgnoreBots))
|
|
||||||
return GetClientCount(false) - 1;
|
|
||||||
|
|
||||||
int iNumPlayers = 0;
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(IsClientConnected(i) && !IsFakeClient(i))
|
|
||||||
iNumPlayers++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return iNumPlayers;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StartRecord()
|
|
||||||
{
|
|
||||||
if(GetConVarBool(g_hTvEnabled) && !g_bIsRecording)
|
|
||||||
{
|
|
||||||
static char sPath[PLATFORM_MAX_PATH];
|
|
||||||
static char sMap[PLATFORM_MAX_PATH];
|
|
||||||
static char sTime[16];
|
|
||||||
|
|
||||||
GetConVarString(g_hDemoPath, sPath, sizeof(sPath));
|
|
||||||
FormatTime(sTime, sizeof(sTime), "%Y%m%d-%H%M%S", GetTime());
|
|
||||||
GetCurrentMap(sMap, sizeof(sMap));
|
|
||||||
|
|
||||||
// replace slashes in map path name with dashes, to prevent fail on workshop maps
|
|
||||||
ReplaceString(sMap, sizeof(sMap), "/", "-", false);
|
|
||||||
|
|
||||||
ServerCommand("tv_record \"%s/auto-%s-%s\"", sPath, sTime, sMap);
|
|
||||||
g_bIsRecording = true;
|
|
||||||
|
|
||||||
LogMessage("Recording to auto-%s-%s.dem", sTime, sMap);
|
|
||||||
|
|
||||||
g_bRestartRecording = true;
|
|
||||||
g_iRestartRecording = GetTime() + 1800;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void StopRecord()
|
|
||||||
{
|
|
||||||
if(GetConVarBool(g_hTvEnabled))
|
|
||||||
{
|
|
||||||
ServerCommand("tv_stoprecord");
|
|
||||||
g_bIsRecording = false;
|
|
||||||
|
|
||||||
g_bRestartRecording = false;
|
|
||||||
g_iRestartRecording = -1;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,118 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#include <sourcemod>
|
|
||||||
|
|
||||||
#define PLUGIN_PREFIX "\x04[ConVar Suppression]\x03 "
|
|
||||||
#define PLUGIN_VERSION "1.0"
|
|
||||||
|
|
||||||
new Handle:g_hGlobalTrie = INVALID_HANDLE;
|
|
||||||
|
|
||||||
public Plugin:myinfo =
|
|
||||||
{
|
|
||||||
name = "ConVar Suppression", /* https://www.youtube.com/watch?v=ZhjtChtUmBE&hd=1 */
|
|
||||||
author = "Kyle Sanderson",
|
|
||||||
description = "Atleast we have candy.",
|
|
||||||
version = PLUGIN_VERSION,
|
|
||||||
url = "http://www.SourceMod.net/"
|
|
||||||
};
|
|
||||||
|
|
||||||
public OnPluginStart()
|
|
||||||
{
|
|
||||||
g_hGlobalTrie = CreateTrie();
|
|
||||||
HookEvent("server_cvar", Event_ServerCvar, EventHookMode_Pre);
|
|
||||||
RegAdminCmd("sm_suppressconvar", OnSupressConVar, ADMFLAG_ROOT, "Supress a ConVar from displaying changes to Clients.");
|
|
||||||
|
|
||||||
CreateConVar("sm_convarsuppression_version", PLUGIN_VERSION, "Version string for ConVar Supression.", FCVAR_REPLICATED|FCVAR_DONTRECORD|FCVAR_NOTIFY);
|
|
||||||
|
|
||||||
AutoExecConfig(true, "plugin.ConVarSupression");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action:OnSupressConVar(client, argc)
|
|
||||||
{
|
|
||||||
if (client && !IsClientInGame(client)) /* Isn't needed, but makes me feel safe inside. */
|
|
||||||
{
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
decl String:sCommand[256];
|
|
||||||
|
|
||||||
if (argc < 2)
|
|
||||||
{
|
|
||||||
if (!GetCmdArg(0, sCommand, sizeof(sCommand)))
|
|
||||||
{
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReplyToCommand(client, "%s%s <convar> <enabled|disabled>", PLUGIN_PREFIX, sCommand);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!GetCmdArg(2, sCommand, sizeof(sCommand)))
|
|
||||||
{
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrimString(sCommand);
|
|
||||||
new iValue = -1;
|
|
||||||
|
|
||||||
if (!IsCharNumeric(sCommand[0]))
|
|
||||||
{
|
|
||||||
switch (CharToLower(sCommand[0]))
|
|
||||||
{
|
|
||||||
case 'd':
|
|
||||||
{
|
|
||||||
iValue = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 'e':
|
|
||||||
{
|
|
||||||
iValue = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
iValue = StringToInt(sCommand);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!GetCmdArg(1, sCommand, sizeof(sCommand)))
|
|
||||||
{
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (iValue)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
{
|
|
||||||
RemoveFromTrie(g_hGlobalTrie, sCommand);
|
|
||||||
if (client)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "%sRemoved ConVar: %s", PLUGIN_PREFIX, sCommand);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
SetTrieValue(g_hGlobalTrie, sCommand, 1, true);
|
|
||||||
if (client)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "%sAdded Hook for ConVar: %s", PLUGIN_PREFIX, sCommand);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "%sIllegal Input for Enabled/Disabled with ConVar: %s", PLUGIN_PREFIX, sCommand);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action:Event_ServerCvar(Handle:event, const String:name[], bool:dontBroadcast)
|
|
||||||
{
|
|
||||||
decl String:sConVarName[64];
|
|
||||||
new iValue;
|
|
||||||
|
|
||||||
GetEventString(event, "cvarname", sConVarName, sizeof(sConVarName));
|
|
||||||
return (GetTrieValue(g_hGlobalTrie, sConVarName, iValue) && iValue) ? Plugin_Handled : Plugin_Continue;
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
"Games"
|
|
||||||
{
|
|
||||||
"#default"
|
|
||||||
{
|
|
||||||
"Addresses"
|
|
||||||
{
|
|
||||||
"GameOver"
|
|
||||||
{
|
|
||||||
"linux"
|
|
||||||
{
|
|
||||||
"signature" "g_fGameOver"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"Signatures"
|
|
||||||
{
|
|
||||||
"g_fGameOver"
|
|
||||||
{
|
|
||||||
"library" "server"
|
|
||||||
"linux" "@g_fGameOver"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,387 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
|
|
||||||
#define VOTE_NO "###no###"
|
|
||||||
#define VOTE_YES "###yes###"
|
|
||||||
|
|
||||||
ConVar g_cvarExtendVoteTime = null;
|
|
||||||
ConVar g_cvarExtendVotePercent = null;
|
|
||||||
ConVar g_cvarMpMaxRounds = null;
|
|
||||||
ConVar g_cvarMpFragLimit = null;
|
|
||||||
ConVar g_cvarMpWinLimit = null;
|
|
||||||
ConVar g_cvarMpTimeLimit = null;
|
|
||||||
|
|
||||||
bool g_bGameOver = false;
|
|
||||||
Address g_pGameOver;
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "Map extend tools",
|
|
||||||
author = "Obus + BotoX",
|
|
||||||
description = "Adds map extension commands.",
|
|
||||||
version = "1.0",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
LoadTranslations("common.phrases");
|
|
||||||
LoadTranslations("basevotes.phrases");
|
|
||||||
|
|
||||||
g_cvarMpMaxRounds = FindConVar("mp_maxrounds");
|
|
||||||
g_cvarMpFragLimit = FindConVar("mp_fraglimit");
|
|
||||||
g_cvarMpWinLimit = FindConVar("mp_winlimit");
|
|
||||||
g_cvarMpTimeLimit = FindConVar("mp_timelimit");
|
|
||||||
|
|
||||||
g_cvarExtendVoteTime = CreateConVar("sm_extendvote_time", "15", "Time that will be added to mp_timelimit shall the extend vote succeed", FCVAR_NONE, true, 1.0);
|
|
||||||
g_cvarExtendVotePercent = CreateConVar("sm_extendvote_percent", "0.6", "Percentage of \"yes\" votes required to consider the vote successful", FCVAR_NONE, true, 0.05, true, 1.0);
|
|
||||||
|
|
||||||
AutoExecConfig(true, "plugin.Extend");
|
|
||||||
|
|
||||||
if (g_cvarMpMaxRounds != null)
|
|
||||||
RegAdminCmd("sm_extend_rounds", Command_Extend_Rounds, ADMFLAG_GENERIC, "Add more rounds to mp_maxrounds");
|
|
||||||
else
|
|
||||||
LogMessage("Failed to find \"mp_maxrounds\" console variable, related commands will be disabled.");
|
|
||||||
|
|
||||||
if (g_cvarMpFragLimit != null)
|
|
||||||
RegAdminCmd("sm_extend_frags", Command_Extend_Frags, ADMFLAG_GENERIC, "Add more frags to mp_fraglimit");
|
|
||||||
else
|
|
||||||
LogMessage("Failed to find \"mp_fraglimit\" console variable, related commands will be disabled.");
|
|
||||||
|
|
||||||
if (g_cvarMpWinLimit != null)
|
|
||||||
RegAdminCmd("sm_extend_wins", Command_Extend_Wins, ADMFLAG_GENERIC, "Add more wins to mp_winlimit");
|
|
||||||
else
|
|
||||||
LogMessage("Failed to find \"mp_winlimit\" console variable, related commands will be disabled.");
|
|
||||||
|
|
||||||
if (g_cvarMpTimeLimit != null)
|
|
||||||
{
|
|
||||||
RegAdminCmd("sm_extend", Command_Extend, ADMFLAG_GENERIC, "Add more time to mp_timelimit");
|
|
||||||
RegAdminCmd("sm_extend_time", Command_Extend, ADMFLAG_GENERIC, "Add more time to mp_timelimit");
|
|
||||||
RegAdminCmd("sm_extendvote", Command_ExtendVote, ADMFLAG_GENERIC, "sm_extendvote [time] - Start an extendvote");
|
|
||||||
RegAdminCmd("sm_voteextend", Command_ExtendVote, ADMFLAG_GENERIC, "sm_voteextend [time] - Start an extendvote");
|
|
||||||
RegAdminCmd("sm_extend_vote", Command_ExtendVote, ADMFLAG_GENERIC, "sm_extend_vote [time] - Start an extendvote");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogMessage("Failed to find \"mp_timelimit\" console variable, related commands will be disabled.");
|
|
||||||
}
|
|
||||||
|
|
||||||
Handle hGameConf = LoadGameConfigFile("Extend.games");
|
|
||||||
if(hGameConf == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
g_bGameOver = false;
|
|
||||||
LogError("Couldn't load Extend.games game config! GameOver cancel disabled.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!(g_pGameOver = GameConfGetAddress(hGameConf, "GameOver")))
|
|
||||||
{
|
|
||||||
g_bGameOver = false;
|
|
||||||
CloseHandle(hGameConf);
|
|
||||||
LogError("Couldn't get GameOver address from game config! GameOver cancel disabled.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_bGameOver = true;
|
|
||||||
CloseHandle(hGameConf);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Extend_Rounds(int client, int argc)
|
|
||||||
{
|
|
||||||
if (argc < 1)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Usage: sm_extend_rounds <rounds>");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sArgs[16];
|
|
||||||
|
|
||||||
GetCmdArg(1, sArgs, sizeof(sArgs));
|
|
||||||
|
|
||||||
if (sArgs[0] == '-')
|
|
||||||
{
|
|
||||||
int iRoundsToDeduct;
|
|
||||||
|
|
||||||
if (!StringToIntEx(sArgs[1], iRoundsToDeduct))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Invalid value");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_cvarMpMaxRounds.IntValue -= iRoundsToDeduct;
|
|
||||||
|
|
||||||
LogAction(client, -1, "\"%L\" deducted \"%d\" rounds from \"mp_maxrounds\"", client, iRoundsToDeduct);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
int iRoundsToAdd;
|
|
||||||
|
|
||||||
if (!StringToIntEx(sArgs, iRoundsToAdd))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Invalid value");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_cvarMpMaxRounds.IntValue += iRoundsToAdd;
|
|
||||||
CancelGameOver();
|
|
||||||
|
|
||||||
LogAction(client, -1, "\"%L\" added \"%d\" rounds to \"mp_maxrounds\"", client, iRoundsToAdd);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Extend_Frags(int client, int argc)
|
|
||||||
{
|
|
||||||
if (argc < 1)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Usage: sm_extend_frags <frags>");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sArgs[16];
|
|
||||||
|
|
||||||
GetCmdArg(1, sArgs, sizeof(sArgs));
|
|
||||||
|
|
||||||
if (sArgs[0] == '-')
|
|
||||||
{
|
|
||||||
int iFragsToDeduct;
|
|
||||||
|
|
||||||
if (!StringToIntEx(sArgs[1], iFragsToDeduct))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Invalid value");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_cvarMpFragLimit.IntValue -= iFragsToDeduct;
|
|
||||||
|
|
||||||
LogAction(client, -1, "\"%L\" deducted \"%d\" frags from \"mp_fraglimit\"", client, iFragsToDeduct);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
int iFragsToAdd;
|
|
||||||
|
|
||||||
if (!StringToIntEx(sArgs, iFragsToAdd))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Invalid value");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_cvarMpFragLimit.IntValue += iFragsToAdd;
|
|
||||||
CancelGameOver();
|
|
||||||
|
|
||||||
LogAction(client, -1, "\"%L\" added \"%d\" frags to \"mp_fraglimit\"", client, iFragsToAdd);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Extend_Wins(int client, int argc)
|
|
||||||
{
|
|
||||||
if (argc < 1)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Usage: sm_extend_wins <wins>");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sArgs[16];
|
|
||||||
|
|
||||||
GetCmdArg(1, sArgs, sizeof(sArgs));
|
|
||||||
|
|
||||||
if (sArgs[0] == '-')
|
|
||||||
{
|
|
||||||
int iWinsToDeduct;
|
|
||||||
|
|
||||||
if (!StringToIntEx(sArgs[1], iWinsToDeduct))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Invalid value");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_cvarMpWinLimit.IntValue -= iWinsToDeduct;
|
|
||||||
|
|
||||||
LogAction(client, -1, "\"%L\" deducted \"%d\" wins from \"mp_winlimit\"", client, iWinsToDeduct);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
int iWinsToAdd;
|
|
||||||
|
|
||||||
if (!StringToIntEx(sArgs, iWinsToAdd))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Invalid value");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_cvarMpWinLimit.IntValue += iWinsToAdd;
|
|
||||||
CancelGameOver();
|
|
||||||
|
|
||||||
LogAction(client, -1, "\"%L\" added \"%d\" wins to \"mp_winlimit\"", client, iWinsToAdd);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Extend(int client, int argc)
|
|
||||||
{
|
|
||||||
if (argc < 1)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Usage: sm_extend <time>");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sArgs[16];
|
|
||||||
|
|
||||||
GetCmdArg(1, sArgs, sizeof(sArgs));
|
|
||||||
|
|
||||||
if (sArgs[0] == '-')
|
|
||||||
{
|
|
||||||
int iMinutesToDeduct;
|
|
||||||
|
|
||||||
if (!StringToIntEx(sArgs[1], iMinutesToDeduct))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Invalid value");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_cvarMpTimeLimit.IntValue -= iMinutesToDeduct;
|
|
||||||
|
|
||||||
LogAction(client, -1, "\"%L\" deducted \"%d\" minutes from \"mp_timelimit\"", client, iMinutesToDeduct);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
int iMinutesToAdd;
|
|
||||||
|
|
||||||
if (!StringToIntEx(sArgs, iMinutesToAdd))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Invalid value");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_cvarMpTimeLimit.IntValue += iMinutesToAdd;
|
|
||||||
CancelGameOver();
|
|
||||||
|
|
||||||
LogAction(client, -1, "\"%L\" added \"%d\" minutes to \"mp_timelimit\"", client, iMinutesToAdd);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
int g_ExtendTime = 0;
|
|
||||||
public Action Command_ExtendVote(int client, int argc)
|
|
||||||
{
|
|
||||||
if (IsVoteInProgress())
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] %t", "Vote in Progress");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_ExtendTime = g_cvarExtendVoteTime.IntValue;
|
|
||||||
if(argc == 1)
|
|
||||||
{
|
|
||||||
char sArg[64];
|
|
||||||
GetCmdArg(1, sArg, sizeof(sArg));
|
|
||||||
int Tmp = StringToInt(sArg);
|
|
||||||
if(Tmp > 0)
|
|
||||||
g_ExtendTime = Tmp > 30 ? 30 : Tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu hVoteMenu = new Menu(Handler_VoteCallback, MenuAction_End|MenuAction_DisplayItem|MenuAction_VoteCancel|MenuAction_VoteEnd);
|
|
||||||
hVoteMenu.SetTitle("Extend the current map (%d minutes)?", g_ExtendTime);
|
|
||||||
|
|
||||||
hVoteMenu.AddItem(VOTE_YES, "Yes");
|
|
||||||
hVoteMenu.AddItem(VOTE_NO, "No");
|
|
||||||
|
|
||||||
hVoteMenu.OptionFlags = MENUFLAG_BUTTON_NOVOTE;
|
|
||||||
hVoteMenu.ExitButton = false;
|
|
||||||
hVoteMenu.DisplayVoteToAll(20);
|
|
||||||
|
|
||||||
ShowActivity2(client, "[SM] ", "Initiated an extend vote");
|
|
||||||
LogAction(client, -1, "\"%L\" initiated an extend vote.", client);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Handler_VoteCallback(Menu menu, MenuAction action, int param1, int param2)
|
|
||||||
{
|
|
||||||
if (action == MenuAction_End)
|
|
||||||
{
|
|
||||||
delete menu;
|
|
||||||
}
|
|
||||||
else if (action == MenuAction_DisplayItem)
|
|
||||||
{
|
|
||||||
char display[64];
|
|
||||||
menu.GetItem(param2, "", 0, _, display, sizeof(display));
|
|
||||||
|
|
||||||
if (strcmp(display, VOTE_NO) == 0 || strcmp(display, VOTE_YES) == 0)
|
|
||||||
{
|
|
||||||
char buffer[255];
|
|
||||||
Format(buffer, sizeof(buffer), "%T", display, param1);
|
|
||||||
|
|
||||||
return RedrawMenuItem(buffer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (action == MenuAction_VoteCancel && param1 == VoteCancel_NoVotes)
|
|
||||||
{
|
|
||||||
PrintToChatAll("[SM] %t", "No Votes Cast");
|
|
||||||
}
|
|
||||||
else if (action == MenuAction_VoteEnd)
|
|
||||||
{
|
|
||||||
char item[64], display[64];
|
|
||||||
float percent, limit;
|
|
||||||
int votes, totalVotes;
|
|
||||||
|
|
||||||
GetMenuVoteInfo(param2, votes, totalVotes);
|
|
||||||
menu.GetItem(param1, item, sizeof(item), _, display, sizeof(display));
|
|
||||||
|
|
||||||
if (strcmp(item, VOTE_NO) == 0)
|
|
||||||
{
|
|
||||||
votes = totalVotes - votes;
|
|
||||||
}
|
|
||||||
|
|
||||||
limit = g_cvarExtendVotePercent.FloatValue;
|
|
||||||
percent = FloatDiv(float(votes),float(totalVotes));
|
|
||||||
|
|
||||||
if ((strcmp(item, VOTE_YES) == 0 && FloatCompare(percent, limit) < 0) || strcmp(item, VOTE_NO) == 0)
|
|
||||||
{
|
|
||||||
LogAction(-1, -1, "Extend vote failed.");
|
|
||||||
PrintToChatAll("[SM] %t", "Vote Failed", RoundToNearest(100.0 * limit), RoundToNearest(100.0 * percent), totalVotes);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LogAction(-1, -1, "Extend vote successful, extending current map by \"%d\" minutes", g_ExtendTime);
|
|
||||||
PrintToChatAll("[SM] %t", "Vote Successful", RoundToNearest(100.0 * percent), totalVotes);
|
|
||||||
|
|
||||||
g_cvarMpTimeLimit.IntValue += g_ExtendTime;
|
|
||||||
CancelGameOver();
|
|
||||||
|
|
||||||
if (strcmp(item, VOTE_NO) == 0 || strcmp(item, VOTE_YES) == 0)
|
|
||||||
{
|
|
||||||
strcopy(item, sizeof(item), display);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CancelGameOver()
|
|
||||||
{
|
|
||||||
if (!g_bGameOver)
|
|
||||||
return;
|
|
||||||
|
|
||||||
StoreToAddress(g_pGameOver, 0, NumberType_Int8);
|
|
||||||
|
|
||||||
for (int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if (IsClientInGame(client))
|
|
||||||
{
|
|
||||||
if (IsClientObserver(client))
|
|
||||||
SetEntityMoveType(client, MOVETYPE_NOCLIP);
|
|
||||||
else
|
|
||||||
SetEntityMoveType(client, MOVETYPE_WALK);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,47 +0,0 @@
|
|||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
|
|
||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "FixAngles",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "",
|
|
||||||
version = "1.0",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnMapStart()
|
|
||||||
{
|
|
||||||
CreateTimer(1.0, CheckAngles, 0, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action CheckAngles(Handle timer)
|
|
||||||
{
|
|
||||||
int entity = INVALID_ENT_REFERENCE;
|
|
||||||
while((entity = FindEntityByClassname(entity, "func_rotating")) != INVALID_ENT_REFERENCE)
|
|
||||||
{
|
|
||||||
if(!HasEntProp(entity, Prop_Send, "m_angRotation"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
static float aAngles[3];
|
|
||||||
GetEntPropVector(entity, Prop_Send, "m_angRotation", aAngles);
|
|
||||||
|
|
||||||
bool bChanged = false;
|
|
||||||
for(int i = 0; i < 3; i++)
|
|
||||||
{
|
|
||||||
if(aAngles[i] < -360 || aAngles[i] > 360)
|
|
||||||
{
|
|
||||||
aAngles[i] = float(RoundFloat(aAngles[i]) % 360);
|
|
||||||
bChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bChanged)
|
|
||||||
SetEntPropVector(entity, Prop_Send, "m_angRotation", aAngles);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
@ -1,129 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools_entoutput>
|
|
||||||
#include <sdktools_entinput>
|
|
||||||
#include <sdktools_engine>
|
|
||||||
#include <sdkhooks>
|
|
||||||
#include <dhooks>
|
|
||||||
|
|
||||||
public Plugin:myinfo =
|
|
||||||
{
|
|
||||||
name = "FixGameUI",
|
|
||||||
author = "hlstriker + GoD-Tony",
|
|
||||||
description = "Fixes game_ui entity bug.",
|
|
||||||
version = "1.0",
|
|
||||||
url = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
new g_iAttachedGameUI[MAXPLAYERS+1];
|
|
||||||
new Handle:g_hAcceptInput = INVALID_HANDLE;
|
|
||||||
|
|
||||||
public OnPluginStart()
|
|
||||||
{
|
|
||||||
HookEvent("player_death", Event_PlayerDeath, EventHookMode_Post);
|
|
||||||
|
|
||||||
HookEntityOutput("game_ui", "PlayerOn", GameUI_PlayerOn);
|
|
||||||
HookEntityOutput("game_ui", "PlayerOff", GameUI_PlayerOff);
|
|
||||||
|
|
||||||
// Gamedata.
|
|
||||||
Handle hConfig = LoadGameConfigFile("sdktools.games");
|
|
||||||
if (hConfig == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
SetFailState("Couldn't load sdktools game config!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
new offset = GameConfGetOffset(hConfig, "AcceptInput");
|
|
||||||
if (offset == -1)
|
|
||||||
{
|
|
||||||
SetFailState("Failed to find AcceptInput offset");
|
|
||||||
}
|
|
||||||
CloseHandle(hConfig);
|
|
||||||
|
|
||||||
// DHooks.
|
|
||||||
g_hAcceptInput = DHookCreate(offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, Hook_AcceptInput);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_CharPtr);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_Object, 20); //varaint_t is a union of 12 (float[3]) plus two int type params 12 + 8 = 20
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_Int);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action:Event_PlayerDeath(Handle:hEvent, const String:szName[], bool:bDontBroadcast)
|
|
||||||
{
|
|
||||||
new iClient = GetClientOfUserId(GetEventInt(hEvent, "userid"));
|
|
||||||
RemoveFromGameUI(iClient);
|
|
||||||
SetClientViewEntity(iClient, iClient);
|
|
||||||
|
|
||||||
new iFlags = GetEntityFlags(iClient);
|
|
||||||
iFlags &= ~FL_ONTRAIN;
|
|
||||||
iFlags &= ~FL_FROZEN;
|
|
||||||
iFlags &= ~FL_ATCONTROLS;
|
|
||||||
SetEntityFlags(iClient, iFlags);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OnClientDisconnect(iClient)
|
|
||||||
{
|
|
||||||
RemoveFromGameUI(iClient);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameUI_PlayerOn(const String:szOutput[], iCaller, iActivator, Float:fDelay)
|
|
||||||
{
|
|
||||||
if(!(1 <= iActivator <= MaxClients))
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_iAttachedGameUI[iActivator] = EntIndexToEntRef(iCaller);
|
|
||||||
}
|
|
||||||
|
|
||||||
public GameUI_PlayerOff(const String:szOutput[], iCaller, iActivator, Float:fDelay)
|
|
||||||
{
|
|
||||||
if(!(1 <= iActivator <= MaxClients))
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_iAttachedGameUI[iActivator] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
RemoveFromGameUI(iClient)
|
|
||||||
{
|
|
||||||
if(!g_iAttachedGameUI[iClient])
|
|
||||||
return;
|
|
||||||
|
|
||||||
new iEnt = EntRefToEntIndex(g_iAttachedGameUI[iClient]);
|
|
||||||
if(iEnt == INVALID_ENT_REFERENCE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
AcceptEntityInput(iEnt, "Deactivate", iClient, iEnt);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OnEntityCreated(entity, const String:classname[])
|
|
||||||
{
|
|
||||||
if (StrEqual(classname, "game_ui"))
|
|
||||||
{
|
|
||||||
DHookEntity(g_hAcceptInput, false, entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MRESReturn:Hook_AcceptInput(thisptr, Handle:hReturn, Handle:hParams)
|
|
||||||
{
|
|
||||||
new String:sCommand[128];
|
|
||||||
DHookGetParamString(hParams, 1, sCommand, sizeof(sCommand));
|
|
||||||
|
|
||||||
if (StrEqual(sCommand, "Deactivate"))
|
|
||||||
{
|
|
||||||
new pPlayer = GetEntPropEnt(thisptr, Prop_Data, "m_player");
|
|
||||||
|
|
||||||
if (pPlayer == -1)
|
|
||||||
{
|
|
||||||
// Manually disable think.
|
|
||||||
SetEntProp(thisptr, Prop_Data, "m_nNextThinkTick", -1);
|
|
||||||
|
|
||||||
DHookSetReturn(hReturn, false);
|
|
||||||
return MRES_Supercede;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
DHookSetReturn(hReturn, true);
|
|
||||||
return MRES_Ignored;
|
|
||||||
}
|
|
@ -1,14 +0,0 @@
|
|||||||
"Games"
|
|
||||||
{
|
|
||||||
"#default"
|
|
||||||
{
|
|
||||||
"Signatures"
|
|
||||||
{
|
|
||||||
"CCSPlayer_StockPlayerAmmo"
|
|
||||||
{
|
|
||||||
"library" "server"
|
|
||||||
"linux" "@_ZN9CCSPlayer15StockPlayerAmmoEP17CBaseCombatWeapon"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,112 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
#include <sdkhooks>
|
|
||||||
#include <cstrike>
|
|
||||||
|
|
||||||
// void CCSPlayer::StockPlayerAmmo( CBaseCombatWeapon *pNewWeapon )
|
|
||||||
Handle g_hCCSPlayer_StockPlayerAmmo;
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "FixPlayerEquip",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Fix lag caused by game_player_equip entity.",
|
|
||||||
version = "1.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
Handle hGameConf = LoadGameConfigFile("FixPlayerEquip.games");
|
|
||||||
if(hGameConf == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
SetFailState("Couldn't load FixPlayerEquip.games game config!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// void CCSPlayer::StockPlayerAmmo( CBaseCombatWeapon *pNewWeapon )
|
|
||||||
StartPrepSDKCall(SDKCall_Player);
|
|
||||||
if(!PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, "CCSPlayer_StockPlayerAmmo"))
|
|
||||||
{
|
|
||||||
CloseHandle(hGameConf);
|
|
||||||
SetFailState("PrepSDKCall_SetFromConf(hGameConf, SDKConf_Signature, \"CCSPlayer_StockPlayerAmmo\" failed!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
PrepSDKCall_AddParameter(SDKType_CBaseEntity, SDKPass_Pointer);
|
|
||||||
g_hCCSPlayer_StockPlayerAmmo = EndPrepSDKCall();
|
|
||||||
|
|
||||||
CloseHandle(hGameConf);
|
|
||||||
|
|
||||||
/* Late Load */
|
|
||||||
int entity = INVALID_ENT_REFERENCE;
|
|
||||||
while((entity = FindEntityByClassname(entity, "game_player_equip")) != INVALID_ENT_REFERENCE)
|
|
||||||
{
|
|
||||||
OnEntityCreated(entity, "game_player_equip");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnEntityCreated(int entity, const char[] classname)
|
|
||||||
{
|
|
||||||
if(StrEqual(classname, "game_player_equip"))
|
|
||||||
{
|
|
||||||
SDKHook(entity, SDKHook_Use, OnUse);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnUse(int entity, int client)
|
|
||||||
{
|
|
||||||
static int s_MaxEquip = -1;
|
|
||||||
if(s_MaxEquip == -1)
|
|
||||||
s_MaxEquip = GetEntPropArraySize(entity, Prop_Data, "m_weaponNames");
|
|
||||||
|
|
||||||
if(client > MaxClients || client <= 0)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
bool bGaveAmmo = false;
|
|
||||||
|
|
||||||
for(int i = 0; i < s_MaxEquip; i++)
|
|
||||||
{
|
|
||||||
char sWeapon[32];
|
|
||||||
GetEntPropString(entity, Prop_Data, "m_weaponNames", sWeapon, sizeof(sWeapon), i);
|
|
||||||
|
|
||||||
if(!sWeapon[0])
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(strncmp(sWeapon, "ammo_", 5, false) == 0)
|
|
||||||
{
|
|
||||||
if(!bGaveAmmo)
|
|
||||||
{
|
|
||||||
int iWeapon = INVALID_ENT_REFERENCE;
|
|
||||||
if((iWeapon = GetPlayerWeaponSlot(client, CS_SLOT_PRIMARY)) != INVALID_ENT_REFERENCE)
|
|
||||||
StockPlayerAmmo(client, iWeapon);
|
|
||||||
|
|
||||||
if((iWeapon = GetPlayerWeaponSlot(client, CS_SLOT_SECONDARY)) != INVALID_ENT_REFERENCE)
|
|
||||||
StockPlayerAmmo(client, iWeapon);
|
|
||||||
|
|
||||||
bGaveAmmo = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(StrEqual(sWeapon, "item_kevlar", false))
|
|
||||||
{
|
|
||||||
SetEntProp(client, Prop_Send, "m_ArmorValue", 100, 1);
|
|
||||||
}
|
|
||||||
else if(StrEqual(sWeapon, "item_assaultsuit", false))
|
|
||||||
{
|
|
||||||
SetEntProp(client, Prop_Send, "m_ArmorValue", 100, 1);
|
|
||||||
SetEntProp(client, Prop_Send, "m_bHasHelmet", 1, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
GivePlayerItem(client, sWeapon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
int StockPlayerAmmo(int client, int iWeapon)
|
|
||||||
{
|
|
||||||
return SDKCall(g_hCCSPlayer_StockPlayerAmmo, client, iWeapon);
|
|
||||||
}
|
|
@ -1,19 +0,0 @@
|
|||||||
"Games"
|
|
||||||
{
|
|
||||||
"cstrike"
|
|
||||||
{
|
|
||||||
"Offsets"
|
|
||||||
{
|
|
||||||
"Teleport"
|
|
||||||
{
|
|
||||||
"windows" "108"
|
|
||||||
"linux" "109"
|
|
||||||
}
|
|
||||||
"FallInit"
|
|
||||||
{
|
|
||||||
"windows" "346"
|
|
||||||
"linux" "347"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,101 +0,0 @@
|
|||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
#include <dhooks>
|
|
||||||
|
|
||||||
#define SF_WEAPON_START_CONSTRAINED (1<<0)
|
|
||||||
|
|
||||||
Handle hFallInit;
|
|
||||||
Handle hTeleport;
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "FixPointTeleport",
|
|
||||||
author = "zaCade",
|
|
||||||
description = "Fix crashes caused by point_teleport entity teleporting weapons.",
|
|
||||||
version = "1.0.0"
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
Handle hGameConf;
|
|
||||||
if ((hGameConf = LoadGameConfigFile("FixPointTeleport.games")) == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
SetFailState("Couldn't load \"FixPointTeleport.games\" game config!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// CBaseCombatWeapon::FallInit()
|
|
||||||
StartPrepSDKCall(SDKCall_Entity);
|
|
||||||
|
|
||||||
if (!PrepSDKCall_SetFromConf(hGameConf, SDKConf_Virtual, "FallInit"))
|
|
||||||
{
|
|
||||||
CloseHandle(hGameConf);
|
|
||||||
SetFailState("PrepSDKCall_SetFromConf(hGameConf, SDKConf_Virtual, \"FallInit\") failed!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
hFallInit = EndPrepSDKCall();
|
|
||||||
|
|
||||||
// CBaseEntity::Teleport(Vector const*, QAngle const*, Vector const*)
|
|
||||||
int iOffset;
|
|
||||||
if ((iOffset = GameConfGetOffset(hGameConf, "Teleport")) == -1)
|
|
||||||
{
|
|
||||||
CloseHandle(hGameConf);
|
|
||||||
SetFailState("GameConfGetOffset(hGameConf, \"Teleport\") failed!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((hTeleport = DHookCreate(iOffset, HookType_Entity, ReturnType_Void, ThisPointer_CBaseEntity, OnEntityTeleport)) == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
CloseHandle(hGameConf);
|
|
||||||
SetFailState("DHookCreate(iOffset, HookType_Entity, ReturnType_Void, ThisPointer_CBaseEntity, OnEntityTeleport) failed!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
DHookAddParam(hTeleport, HookParamType_VectorPtr);
|
|
||||||
DHookAddParam(hTeleport, HookParamType_ObjectPtr);
|
|
||||||
DHookAddParam(hTeleport, HookParamType_VectorPtr);
|
|
||||||
|
|
||||||
// Late load.
|
|
||||||
int entity = INVALID_ENT_REFERENCE;
|
|
||||||
while ((entity = FindEntityByClassname(entity, "weapon_*")) != INVALID_ENT_REFERENCE)
|
|
||||||
{
|
|
||||||
OnEntityCreated(entity, "weapon_*");
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(hGameConf);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
public void OnEntityCreated(int entity, const char[] classname)
|
|
||||||
{
|
|
||||||
if (strncmp(classname, "weapon_", 7, false) == 0)
|
|
||||||
{
|
|
||||||
DHookEntity(hTeleport, true, entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
public MRESReturn OnEntityTeleport(int entity, Handle hParams)
|
|
||||||
{
|
|
||||||
if (IsValidEntity(entity))
|
|
||||||
{
|
|
||||||
// Dont reinitialize, if we dont have spawnflags or are missing the start constrained spawnflag.
|
|
||||||
if (!HasEntProp(entity, Prop_Data, "m_spawnflags") || (GetEntProp(entity, Prop_Data, "m_spawnflags") & SF_WEAPON_START_CONSTRAINED) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
SDKCall(hFallInit, entity);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,44 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
|
|
||||||
#pragma newdecls required
|
|
||||||
#define PLUGIN_VERSION "1.0"
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "Flashlight",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Dead flashlight, block sound from other clients.",
|
|
||||||
version = PLUGIN_VERSION,
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
AddNormalSoundHook(OnSound);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnSound(int clients[64], int &numClients, char sample[PLATFORM_MAX_PATH], int &entity, int &channel, float &volume, int &level, int &pitch, int &flags)
|
|
||||||
{
|
|
||||||
if(entity >= 1 && entity <= MAXPLAYERS && StrEqual(sample, "items/flashlight1.wav", false))
|
|
||||||
{
|
|
||||||
numClients = 1;
|
|
||||||
clients[0] = entity;
|
|
||||||
return Plugin_Changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
|
|
||||||
{
|
|
||||||
// Dead flashlight
|
|
||||||
if(impulse == 100 && !IsPlayerAlive(client))
|
|
||||||
{
|
|
||||||
SetEntProp(client, Prop_Send, "m_fEffects", GetEntProp(client, Prop_Send, "m_fEffects") ^ 4);
|
|
||||||
ClientCommand(client, "playgamesound \"items/flashlight1.wav\"");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
@ -1,206 +0,0 @@
|
|||||||
//====================================================================================================
|
|
||||||
//
|
|
||||||
// Name: ForceInput
|
|
||||||
// Author: zaCade + BotoX
|
|
||||||
// Description: Allows admins to force inputs on entities. (ent_fire)
|
|
||||||
//
|
|
||||||
//====================================================================================================
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
|
|
||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "ForceInput",
|
|
||||||
author = "zaCade + BotoX",
|
|
||||||
description = "Allows admins to force inputs on entities. (ent_fire)",
|
|
||||||
version = "2.1.1",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
LoadTranslations("common.phrases");
|
|
||||||
|
|
||||||
RegAdminCmd("sm_forceinput", Command_ForceInput, ADMFLAG_RCON);
|
|
||||||
RegAdminCmd("sm_forceinputplayer", Command_ForceInputPlayer, ADMFLAG_RCON);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
public Action Command_ForceInputPlayer(int client, int args)
|
|
||||||
{
|
|
||||||
if(GetCmdArgs() < 2)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Usage: sm_forceinputplayer <target> <input> [parameter]");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sArguments[3][256];
|
|
||||||
GetCmdArg(1, sArguments[0], sizeof(sArguments[]));
|
|
||||||
GetCmdArg(2, sArguments[1], sizeof(sArguments[]));
|
|
||||||
GetCmdArg(3, sArguments[2], sizeof(sArguments[]));
|
|
||||||
|
|
||||||
char sTargetName[MAX_TARGET_LENGTH];
|
|
||||||
int aTargetList[MAXPLAYERS];
|
|
||||||
int TargetCount;
|
|
||||||
bool TnIsMl;
|
|
||||||
|
|
||||||
if((TargetCount = ProcessTargetString(
|
|
||||||
sArguments[0],
|
|
||||||
client,
|
|
||||||
aTargetList,
|
|
||||||
MAXPLAYERS,
|
|
||||||
COMMAND_FILTER_CONNECTED|COMMAND_FILTER_NO_IMMUNITY,
|
|
||||||
sTargetName,
|
|
||||||
sizeof(sTargetName),
|
|
||||||
TnIsMl)) <= 0)
|
|
||||||
{
|
|
||||||
ReplyToTargetError(client, TargetCount);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < TargetCount; i++)
|
|
||||||
{
|
|
||||||
if(!IsValidEntity(aTargetList[i]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(sArguments[2][0])
|
|
||||||
SetVariantString(sArguments[2]);
|
|
||||||
|
|
||||||
AcceptEntityInput(aTargetList[i], sArguments[1], aTargetList[i], aTargetList[i]);
|
|
||||||
ReplyToCommand(client, "[SM] Input successful.");
|
|
||||||
LogAction(client, -1, "\"%L\" used ForceInputPlayer on \"%L\": \"%s %s\"", client, aTargetList[i], sArguments[1], sArguments[2]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
public Action Command_ForceInput(int client, int args)
|
|
||||||
{
|
|
||||||
if(GetCmdArgs() < 2)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Usage: sm_forceinput <classname/targetname> <input> [parameter]");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sArguments[3][256];
|
|
||||||
GetCmdArg(1, sArguments[0], sizeof(sArguments[]));
|
|
||||||
GetCmdArg(2, sArguments[1], sizeof(sArguments[]));
|
|
||||||
GetCmdArg(3, sArguments[2], sizeof(sArguments[]));
|
|
||||||
|
|
||||||
if(StrEqual(sArguments[0], "!self"))
|
|
||||||
{
|
|
||||||
if(sArguments[2][0])
|
|
||||||
SetVariantString(sArguments[2]);
|
|
||||||
|
|
||||||
AcceptEntityInput(client, sArguments[1], client, client);
|
|
||||||
ReplyToCommand(client, "[SM] Input successful.");
|
|
||||||
LogAction(client, -1, "\"%L\" used ForceInput on himself: \"%s %s\"", client, sArguments[1], sArguments[2]);
|
|
||||||
}
|
|
||||||
else if(StrEqual(sArguments[0], "!target"))
|
|
||||||
{
|
|
||||||
float fPosition[3];
|
|
||||||
float fAngles[3];
|
|
||||||
GetClientEyePosition(client, fPosition);
|
|
||||||
GetClientEyeAngles(client, fAngles);
|
|
||||||
|
|
||||||
Handle hTrace = TR_TraceRayFilterEx(fPosition, fAngles, MASK_SOLID, RayType_Infinite, TraceRayFilter, client);
|
|
||||||
|
|
||||||
if(TR_DidHit(hTrace))
|
|
||||||
{
|
|
||||||
int entity = TR_GetEntityIndex(hTrace);
|
|
||||||
|
|
||||||
if(entity <= 1 || !IsValidEntity(entity))
|
|
||||||
{
|
|
||||||
CloseHandle(hTrace);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sArguments[2][0])
|
|
||||||
SetVariantString(sArguments[2]);
|
|
||||||
|
|
||||||
AcceptEntityInput(entity, sArguments[1], client, client);
|
|
||||||
ReplyToCommand(client, "[SM] Input successful.");
|
|
||||||
|
|
||||||
char sClassname[64];
|
|
||||||
char sTargetname[64];
|
|
||||||
GetEntPropString(entity, Prop_Data, "m_iClassname", sClassname, sizeof(sClassname));
|
|
||||||
GetEntPropString(entity, Prop_Data, "m_iName", sTargetname, sizeof(sTargetname));
|
|
||||||
LogAction(client, -1, "\"%L\" used ForceInput on Entity \"%d\" - \"%s\" - \"%s\": \"%s %s\"", client, entity, sClassname, sTargetname, sArguments[1], sArguments[2]);
|
|
||||||
}
|
|
||||||
CloseHandle(hTrace);
|
|
||||||
}
|
|
||||||
else if(sArguments[0][0] == '#') // HammerID
|
|
||||||
{
|
|
||||||
int HammerID = StringToInt(sArguments[0][1]);
|
|
||||||
|
|
||||||
int entity = INVALID_ENT_REFERENCE;
|
|
||||||
while((entity = FindEntityByClassname(entity, "*")) != INVALID_ENT_REFERENCE)
|
|
||||||
{
|
|
||||||
if(GetEntProp(entity, Prop_Data, "m_iHammerID") == HammerID)
|
|
||||||
{
|
|
||||||
if(sArguments[2][0])
|
|
||||||
SetVariantString(sArguments[2]);
|
|
||||||
|
|
||||||
AcceptEntityInput(entity, sArguments[1], client, client);
|
|
||||||
ReplyToCommand(client, "[SM] Input successful.");
|
|
||||||
|
|
||||||
char sClassname[64];
|
|
||||||
char sTargetname[64];
|
|
||||||
GetEntPropString(entity, Prop_Data, "m_iClassname", sClassname, sizeof(sClassname));
|
|
||||||
GetEntPropString(entity, Prop_Data, "m_iName", sTargetname, sizeof(sTargetname));
|
|
||||||
LogAction(client, -1, "\"%L\" used ForceInput on Entity \"%d\" - \"%s\" - \"%s\": \"%s %s\"", client, entity, sClassname, sTargetname, sArguments[1], sArguments[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int Wildcard = FindCharInString(sArguments[0], '*');
|
|
||||||
|
|
||||||
int entity = INVALID_ENT_REFERENCE;
|
|
||||||
while((entity = FindEntityByClassname(entity, "*")) != INVALID_ENT_REFERENCE)
|
|
||||||
{
|
|
||||||
char sClassname[64];
|
|
||||||
char sTargetname[64];
|
|
||||||
GetEntPropString(entity, Prop_Data, "m_iClassname", sClassname, sizeof(sClassname));
|
|
||||||
GetEntPropString(entity, Prop_Data, "m_iName", sTargetname, sizeof(sTargetname));
|
|
||||||
|
|
||||||
if(strncmp(sClassname, sArguments[0], Wildcard, false) == 0
|
|
||||||
|| strncmp(sTargetname, sArguments[0], Wildcard, false) == 0)
|
|
||||||
{
|
|
||||||
if(sArguments[2][0])
|
|
||||||
SetVariantString(sArguments[2]);
|
|
||||||
|
|
||||||
AcceptEntityInput(entity, sArguments[1], client, client);
|
|
||||||
ReplyToCommand(client, "[SM] Input successful.");
|
|
||||||
LogAction(client, -1, "\"%L\" used ForceInput on Entity \"%d\" - \"%s\" - \"%s\": \"%s %s\"", client, entity, sClassname, sTargetname, sArguments[1], sArguments[2]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
public bool TraceRayFilter(int entity, int mask, any client)
|
|
||||||
{
|
|
||||||
if(entity == client)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,20 +0,0 @@
|
|||||||
"Games"
|
|
||||||
{
|
|
||||||
"#default"
|
|
||||||
{
|
|
||||||
"#supported"
|
|
||||||
{
|
|
||||||
"engine" "orangebox"
|
|
||||||
"engine" "orangebox_valve"
|
|
||||||
"engine" "css"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Offsets"
|
|
||||||
{
|
|
||||||
"CBaseClient::UpdateAcknowledgedFramecount"
|
|
||||||
{
|
|
||||||
"linux" "44"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,106 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
#include <FullUpdate>
|
|
||||||
|
|
||||||
Handle g_hCBaseClient_UpdateAcknowledgedFramecount;
|
|
||||||
int g_iLastFullUpdate[MAXPLAYERS + 1] = { 0, ... };
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "FullUpdate",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Serverside cl_fullupdate",
|
|
||||||
version = "1.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
Handle hGameConf = LoadGameConfigFile("FullUpdate.games");
|
|
||||||
if(hGameConf == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
SetFailState("Couldn't load FullUpdate.games game config!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// void CBaseClient::UpdateAcknowledgedFramecount()
|
|
||||||
StartPrepSDKCall(SDKCall_Raw);
|
|
||||||
|
|
||||||
if(!PrepSDKCall_SetFromConf(hGameConf, SDKConf_Virtual, "CBaseClient::UpdateAcknowledgedFramecount"))
|
|
||||||
{
|
|
||||||
CloseHandle(hGameConf);
|
|
||||||
SetFailState("PrepSDKCall_SetFromConf(hGameConf, SDKConf_Virtual, \"CBaseClient::UpdateAcknowledgedFramecount\" failed!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
CloseHandle(hGameConf);
|
|
||||||
|
|
||||||
PrepSDKCall_AddParameter(SDKType_PlainOldData, SDKPass_Plain);
|
|
||||||
|
|
||||||
g_hCBaseClient_UpdateAcknowledgedFramecount = EndPrepSDKCall();
|
|
||||||
|
|
||||||
RegConsoleCmd("sm_fullupdate", Command_FullUpdate);
|
|
||||||
RegConsoleCmd("cl_fullupdate", Command_FullUpdate);
|
|
||||||
RegConsoleCmd("fullupdate", Command_FullUpdate);
|
|
||||||
}
|
|
||||||
|
|
||||||
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
|
|
||||||
{
|
|
||||||
CreateNative("ClientFullUpdate", Native_FullUpdate);
|
|
||||||
RegPluginLibrary("FullUpdate");
|
|
||||||
|
|
||||||
return APLRes_Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientConnected(int client)
|
|
||||||
{
|
|
||||||
g_iLastFullUpdate[client] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FullUpdate(int client)
|
|
||||||
{
|
|
||||||
if(g_iLastFullUpdate[client] + 1 > GetTime())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// The IClient vtable is +4 from the IGameEventListener2 (CBaseClient) vtable due to multiple inheritance.
|
|
||||||
Address pIClient = GetClientIClient(client) - view_as<Address>(4);
|
|
||||||
if(!pIClient)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
SDKCall(g_hCBaseClient_UpdateAcknowledgedFramecount, pIClient, -1);
|
|
||||||
|
|
||||||
g_iLastFullUpdate[client] = GetTime();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Native_FullUpdate(Handle plugin, int numParams)
|
|
||||||
{
|
|
||||||
int client = GetNativeCell(1);
|
|
||||||
|
|
||||||
if(client > MaxClients || client <= 0)
|
|
||||||
{
|
|
||||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!IsClientInGame(client))
|
|
||||||
{
|
|
||||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not in-game.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(IsFakeClient(client))
|
|
||||||
{
|
|
||||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is fake-client.");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FullUpdate(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_FullUpdate(int client, int args)
|
|
||||||
{
|
|
||||||
FullUpdate(client);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
#if defined _FullUpdate_Included
|
|
||||||
#endinput
|
|
||||||
#endif
|
|
||||||
#define _FullUpdate_Included
|
|
||||||
|
|
||||||
native bool ClientFullUpdate(int client);
|
|
||||||
|
|
||||||
public SharedPlugin __pl_FullUpdate =
|
|
||||||
{
|
|
||||||
name = "FullUpdate",
|
|
||||||
file = "FullUpdate.smx",
|
|
||||||
#if defined REQUIRE_PLUGIN
|
|
||||||
required = 1,
|
|
||||||
#else
|
|
||||||
required = 0,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#if !defined REQUIRE_PLUGIN
|
|
||||||
public __pl_FullUpdate_SetNTVOptional()
|
|
||||||
{
|
|
||||||
MarkNativeAsOptional("ClientFullUpdate");
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,18 +0,0 @@
|
|||||||
"GlowColors"
|
|
||||||
{
|
|
||||||
"Red" "255 0 0"
|
|
||||||
"Green" "0 255 0"
|
|
||||||
"Yellow" "255 255 0"
|
|
||||||
"Purple" "255 0 255"
|
|
||||||
"Pink" "255 0 128"
|
|
||||||
"Orange" "255 128 0"
|
|
||||||
"Blue" "0 128 255"
|
|
||||||
"Lightblue" "0 0 255"
|
|
||||||
"Cyan" "0 255 255"
|
|
||||||
"Olive" "128 255 0"
|
|
||||||
"Lime" "0 255 128"
|
|
||||||
"Violet" "128 0 255"
|
|
||||||
"White" "200 200 200"
|
|
||||||
"Grey" "128 128 128"
|
|
||||||
"Gold" "238 201 0"
|
|
||||||
}
|
|
@ -1,535 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
#include <sdkhooks>
|
|
||||||
#include <clientprefs>
|
|
||||||
#include <regex>
|
|
||||||
#include <dhooks>
|
|
||||||
#undef REQUIRE_PLUGIN
|
|
||||||
#include <zombiereloaded>
|
|
||||||
#define REQUIRE_PLUGIN
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "GlowColors",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Change your clients colors.",
|
|
||||||
version = "1.2",
|
|
||||||
url = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID )
|
|
||||||
Handle g_hAcceptInput;
|
|
||||||
|
|
||||||
Menu g_GlowColorsMenu;
|
|
||||||
Handle g_hClientCookie = INVALID_HANDLE;
|
|
||||||
|
|
||||||
ConVar g_Cvar_MinBrightness;
|
|
||||||
Regex g_Regex_RGB;
|
|
||||||
Regex g_Regex_HEX;
|
|
||||||
|
|
||||||
int g_aGlowColor[MAXPLAYERS + 1][3];
|
|
||||||
float g_aRainbowFrequency[MAXPLAYERS + 1];
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
Handle hGameConf = LoadGameConfigFile("sdktools.games");
|
|
||||||
if(hGameConf == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
SetFailState("Couldn't load sdktools game config!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Offset = GameConfGetOffset(hGameConf, "AcceptInput");
|
|
||||||
g_hAcceptInput = DHookCreate(Offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, AcceptInput);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_CharPtr);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_Object, 20, DHookPass_ByVal|DHookPass_ODTOR|DHookPass_OCTOR|DHookPass_OASSIGNOP); //varaint_t is a union of 12 (float[3]) plus two int type params 12 + 8 = 20
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_Int);
|
|
||||||
|
|
||||||
CloseHandle(hGameConf);
|
|
||||||
|
|
||||||
g_hClientCookie = RegClientCookie("glowcolor", "", CookieAccess_Protected);
|
|
||||||
|
|
||||||
g_Regex_RGB = CompileRegex("^(([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])\\s+){2}([01]?[0-9]?[0-9]|2[0-4][0-9]|25[0-5])$");
|
|
||||||
g_Regex_HEX = CompileRegex("^(#?)([A-Fa-f0-9]{6})$");
|
|
||||||
|
|
||||||
RegAdminCmd("sm_glowcolors", Command_GlowColors, ADMFLAG_CUSTOM2, "Change your players glowcolor. sm_glowcolors <RRGGBB HEX | 0-255 0-255 0-255 RGB CODE>");
|
|
||||||
RegAdminCmd("sm_glowcolours", Command_GlowColors, ADMFLAG_CUSTOM2, "Change your players glowcolor. sm_glowcolours <RRGGBB HEX | 0-255 0-255 0-255 RGB CODE>");
|
|
||||||
RegAdminCmd("sm_glowcolor", Command_GlowColors, ADMFLAG_CUSTOM2, "Change your players glowcolor. sm_glowcolor <RRGGBB HEX | 0-255 0-255 0-255 RGB CODE>");
|
|
||||||
RegAdminCmd("sm_glowcolour", Command_GlowColors, ADMFLAG_CUSTOM2, "Change your players glowcolor. sm_glowcolour <RRGGBB HEX | 0-255 0-255 0-255 RGB CODE>");
|
|
||||||
RegAdminCmd("sm_colors", Command_GlowColors, ADMFLAG_CUSTOM2, "Change your players glowcolor. sm_colors <RRGGBB HEX | 0-255 0-255 0-255 RGB CODE>");
|
|
||||||
RegAdminCmd("sm_colours", Command_GlowColors, ADMFLAG_CUSTOM2, "Change your players glowcolor. sm_colours <RRGGBB HEX | 0-255 0-255 0-255 RGB CODE>");
|
|
||||||
RegAdminCmd("sm_color", Command_GlowColors, ADMFLAG_CUSTOM2, "Change your players glowcolor. sm_color <RRGGBB HEX | 0-255 0-255 0-255 RGB CODE>");
|
|
||||||
RegAdminCmd("sm_colour", Command_GlowColors, ADMFLAG_CUSTOM2, "Change your players glowcolor. sm_colour <RRGGBB HEX | 0-255 0-255 0-255 RGB CODE>");
|
|
||||||
RegAdminCmd("sm_glow", Command_GlowColors, ADMFLAG_CUSTOM2, "Change your players glowcolor. sm_glow <RRGGBB HEX | 0-255 0-255 0-255 RGB CODE>");
|
|
||||||
|
|
||||||
RegAdminCmd("sm_rainbow", Command_Rainbow, ADMFLAG_CUSTOM1, "Enable rainbow glowcolors. sm_rainbow [frequency]");
|
|
||||||
|
|
||||||
HookEvent("player_spawn", Event_ApplyGlowColor, EventHookMode_Post);
|
|
||||||
HookEvent("player_team", Event_ApplyGlowColor, EventHookMode_Post);
|
|
||||||
|
|
||||||
g_Cvar_MinBrightness = CreateConVar("sm_glowcolor_minbrightness", "100", "Lowest brightness value for glowcolor.", 0, true, 0.0, true, 255.0);
|
|
||||||
|
|
||||||
AutoExecConfig(true, "plugin.GlowColors");
|
|
||||||
|
|
||||||
LoadConfig();
|
|
||||||
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(client))
|
|
||||||
{
|
|
||||||
OnClientPutInServer(client);
|
|
||||||
|
|
||||||
if(!IsFakeClient(client) && AreClientCookiesCached(client))
|
|
||||||
{
|
|
||||||
OnClientCookiesCached(client);
|
|
||||||
ApplyGlowColor(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginEnd()
|
|
||||||
{
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(client) && !IsFakeClient(client) && AreClientCookiesCached(client))
|
|
||||||
{
|
|
||||||
OnClientDisconnect(client);
|
|
||||||
ApplyGlowColor(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete g_GlowColorsMenu;
|
|
||||||
CloseHandle(g_hClientCookie);
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadConfig()
|
|
||||||
{
|
|
||||||
char sConfigFile[PLATFORM_MAX_PATH];
|
|
||||||
BuildPath(Path_SM, sConfigFile, sizeof(sConfigFile), "configs/GlowColors.cfg");
|
|
||||||
if(!FileExists(sConfigFile))
|
|
||||||
{
|
|
||||||
SetFailState("Could not find config: \"%s\"", sConfigFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyValues Config = new KeyValues("GlowColors");
|
|
||||||
if(!Config.ImportFromFile(sConfigFile))
|
|
||||||
{
|
|
||||||
delete Config;
|
|
||||||
SetFailState("ImportFromFile() failed!");
|
|
||||||
}
|
|
||||||
if(!Config.GotoFirstSubKey(false))
|
|
||||||
{
|
|
||||||
delete Config;
|
|
||||||
SetFailState("GotoFirstSubKey() failed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
g_GlowColorsMenu = new Menu(MenuHandler_GlowColorsMenu, MenuAction_Select);
|
|
||||||
g_GlowColorsMenu.SetTitle("GlowColors");
|
|
||||||
g_GlowColorsMenu.ExitButton = true;
|
|
||||||
|
|
||||||
g_GlowColorsMenu.AddItem("255 255 255", "None");
|
|
||||||
|
|
||||||
char sKey[32];
|
|
||||||
char sValue[16];
|
|
||||||
do
|
|
||||||
{
|
|
||||||
Config.GetSectionName(sKey, sizeof(sKey));
|
|
||||||
Config.GetString(NULL_STRING, sValue, sizeof(sValue));
|
|
||||||
|
|
||||||
g_GlowColorsMenu.AddItem(sValue, sKey);
|
|
||||||
}
|
|
||||||
while(Config.GotoNextKey(false));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPutInServer(int client)
|
|
||||||
{
|
|
||||||
g_aGlowColor[client][0] = 255;
|
|
||||||
g_aGlowColor[client][1] = 255;
|
|
||||||
g_aGlowColor[client][2] = 255;
|
|
||||||
g_aRainbowFrequency[client] = 0.0;
|
|
||||||
|
|
||||||
DHookEntity(g_hAcceptInput, false, client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientCookiesCached(int client)
|
|
||||||
{
|
|
||||||
if(IsClientAuthorized(client))
|
|
||||||
ReadClientCookies(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPostAdminCheck(int client)
|
|
||||||
{
|
|
||||||
if(AreClientCookiesCached(client))
|
|
||||||
ReadClientCookies(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ReadClientCookies(int client)
|
|
||||||
{
|
|
||||||
char sCookie[16];
|
|
||||||
if(CheckCommandAccess(client, "sm_glowcolors", ADMFLAG_CUSTOM2))
|
|
||||||
GetClientCookie(client, g_hClientCookie, sCookie, sizeof(sCookie));
|
|
||||||
|
|
||||||
if(StrEqual(sCookie, ""))
|
|
||||||
{
|
|
||||||
g_aGlowColor[client][0] = 255;
|
|
||||||
g_aGlowColor[client][1] = 255;
|
|
||||||
g_aGlowColor[client][2] = 255;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ColorStringToArray(sCookie, g_aGlowColor[client]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientDisconnect(int client)
|
|
||||||
{
|
|
||||||
if(CheckCommandAccess(client, "sm_glowcolors", ADMFLAG_CUSTOM2))
|
|
||||||
{
|
|
||||||
if(g_aGlowColor[client][0] == 255 &&
|
|
||||||
g_aGlowColor[client][1] == 255 &&
|
|
||||||
g_aGlowColor[client][2] == 255)
|
|
||||||
{
|
|
||||||
SetClientCookie(client, g_hClientCookie, "");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char sCookie[16];
|
|
||||||
FormatEx(sCookie, sizeof(sCookie), "%d %d %d",
|
|
||||||
g_aGlowColor[client][0],
|
|
||||||
g_aGlowColor[client][1],
|
|
||||||
g_aGlowColor[client][2]);
|
|
||||||
|
|
||||||
SetClientCookie(client, g_hClientCookie, sCookie);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
g_aGlowColor[client][0] = 255;
|
|
||||||
g_aGlowColor[client][1] = 255;
|
|
||||||
g_aGlowColor[client][2] = 255;
|
|
||||||
|
|
||||||
if(g_aRainbowFrequency[client])
|
|
||||||
SDKUnhook(client, SDKHook_PostThinkPost, OnPostThinkPost);
|
|
||||||
g_aRainbowFrequency[client] = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPostThinkPost(int client)
|
|
||||||
{
|
|
||||||
float i = GetGameTime();
|
|
||||||
float Frequency = g_aRainbowFrequency[client];
|
|
||||||
|
|
||||||
int Red = RoundFloat(Sine(Frequency * i + 0.0) * 127.0 + 128.0);
|
|
||||||
int Green = RoundFloat(Sine(Frequency * i + 2.0943951) * 127.0 + 128.0);
|
|
||||||
int Blue = RoundFloat(Sine(Frequency * i + 4.1887902) * 127.0 + 128.0);
|
|
||||||
|
|
||||||
ToolsSetEntityColor(client, Red, Green, Blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID )
|
|
||||||
public MRESReturn AcceptInput(int pThis, Handle hReturn, Handle hParams)
|
|
||||||
{
|
|
||||||
// Should not happen?
|
|
||||||
if(DHookIsNullParam(hParams, 2))
|
|
||||||
return MRES_Ignored;
|
|
||||||
|
|
||||||
int client = EntRefToEntIndex(DHookGetParam(hParams, 2));
|
|
||||||
if(client < 1 || client > MAXPLAYERS)
|
|
||||||
return MRES_Ignored;
|
|
||||||
|
|
||||||
char szInputName[32];
|
|
||||||
DHookGetParamString(hParams, 1, szInputName, sizeof(szInputName));
|
|
||||||
|
|
||||||
if(!StrEqual(szInputName, "addoutput", false))
|
|
||||||
return MRES_Ignored;
|
|
||||||
|
|
||||||
char sValue[128];
|
|
||||||
DHookGetParamObjectPtrString(hParams, 4, 0, ObjectValueType_String, sValue, sizeof(sValue));
|
|
||||||
int iValueLen = strlen(sValue);
|
|
||||||
|
|
||||||
int aArgs[4] = {0, ...};
|
|
||||||
int iArgs = 0;
|
|
||||||
bool bFound = false;
|
|
||||||
|
|
||||||
for(int i = 0; i < iValueLen; i++)
|
|
||||||
{
|
|
||||||
if(sValue[i] == ' ')
|
|
||||||
{
|
|
||||||
if(bFound)
|
|
||||||
{
|
|
||||||
sValue[i] = '\0';
|
|
||||||
bFound = false;
|
|
||||||
|
|
||||||
if(iArgs > sizeof(aArgs))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!bFound)
|
|
||||||
{
|
|
||||||
aArgs[iArgs++] = i;
|
|
||||||
bFound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(strncmp(sValue[aArgs[0]], "rendercolor", 11, false) == 0)
|
|
||||||
{
|
|
||||||
int aColor[3];
|
|
||||||
aColor[0] = StringToInt(sValue[aArgs[1]]) & 0xFF;
|
|
||||||
aColor[1] = StringToInt(sValue[aArgs[2]]) & 0xFF;
|
|
||||||
aColor[2] = StringToInt(sValue[aArgs[3]]) & 0xFF;
|
|
||||||
|
|
||||||
if(aColor[0] == 255 && aColor[1] == 255 && aColor[2] == 255)
|
|
||||||
{
|
|
||||||
ApplyGlowColor(client);
|
|
||||||
DHookSetReturn(hReturn, true);
|
|
||||||
return MRES_Supercede;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(StrEqual(sValue[aArgs[0]], "rendermode", false))
|
|
||||||
{
|
|
||||||
RenderMode renderMode = view_as<RenderMode>(StringToInt(sValue[aArgs[1]]) & 0xFF);
|
|
||||||
if(renderMode == RENDER_NORMAL)
|
|
||||||
{
|
|
||||||
ApplyGlowColor(client);
|
|
||||||
return MRES_Ignored;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return MRES_Ignored;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_GlowColors(int client, int args)
|
|
||||||
{
|
|
||||||
if(args < 1)
|
|
||||||
{
|
|
||||||
DisplayGlowColorMenu(client);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Color;
|
|
||||||
|
|
||||||
if(args == 1)
|
|
||||||
{
|
|
||||||
char sColorString[32];
|
|
||||||
GetCmdArgString(sColorString, sizeof(sColorString));
|
|
||||||
|
|
||||||
if(!IsValidHex(sColorString))
|
|
||||||
{
|
|
||||||
PrintToChat(client, "Invalid HEX color code supplied.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
Color = StringToInt(sColorString, 16);
|
|
||||||
|
|
||||||
g_aGlowColor[client][0] = (Color >> 16) & 0xFF;
|
|
||||||
g_aGlowColor[client][1] = (Color >> 8) & 0xFF;
|
|
||||||
g_aGlowColor[client][2] = (Color >> 0) & 0xFF;
|
|
||||||
}
|
|
||||||
else if(args == 3)
|
|
||||||
{
|
|
||||||
char sColorString[32];
|
|
||||||
GetCmdArgString(sColorString, sizeof(sColorString));
|
|
||||||
|
|
||||||
if(!IsValidRGBNum(sColorString))
|
|
||||||
{
|
|
||||||
PrintToChat(client, "Invalid RGB color code supplied.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
ColorStringToArray(sColorString, g_aGlowColor[client]);
|
|
||||||
|
|
||||||
Color = (g_aGlowColor[client][0] << 16) +
|
|
||||||
(g_aGlowColor[client][1] << 8) +
|
|
||||||
(g_aGlowColor[client][2] << 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
char sCommand[32];
|
|
||||||
GetCmdArg(0, sCommand, sizeof(sCommand));
|
|
||||||
PrintToChat(client, "[SM] Usage: %s <RRGGBB HEX | 0-255 0-255 0-255 RGB CODE>", sCommand);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!ApplyGlowColor(client))
|
|
||||||
return Plugin_Handled;
|
|
||||||
|
|
||||||
if(GetCmdReplySource() == SM_REPLY_TO_CHAT)
|
|
||||||
PrintToChat(client, "\x01[SM] Set color to: \x07%06X%06X\x01", Color, Color);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Rainbow(int client, int args)
|
|
||||||
{
|
|
||||||
float Frequency = 1.0;
|
|
||||||
if(args >= 1)
|
|
||||||
{
|
|
||||||
char sArg[32];
|
|
||||||
GetCmdArg(1, sArg, sizeof(sArg));
|
|
||||||
Frequency = StringToFloat(sArg);
|
|
||||||
if(Frequency > 10.0)
|
|
||||||
Frequency = 10.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!Frequency || (args < 1 && g_aRainbowFrequency[client]))
|
|
||||||
{
|
|
||||||
if(g_aRainbowFrequency[client])
|
|
||||||
SDKUnhook(client, SDKHook_PostThinkPost, OnPostThinkPost);
|
|
||||||
|
|
||||||
g_aRainbowFrequency[client] = 0.0;
|
|
||||||
PrintToChat(client, "[SM] Disabled rainbow glowcolors.");
|
|
||||||
|
|
||||||
ApplyGlowColor(client);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!g_aRainbowFrequency[client])
|
|
||||||
SDKHook(client, SDKHook_PostThinkPost, OnPostThinkPost);
|
|
||||||
|
|
||||||
g_aRainbowFrequency[client] = Frequency;
|
|
||||||
PrintToChat(client, "[SM] Enabled rainbow glowcolors. (Frequency = %f)", Frequency);
|
|
||||||
}
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DisplayGlowColorMenu(int client)
|
|
||||||
{
|
|
||||||
g_GlowColorsMenu.Display(client, MENU_TIME_FOREVER);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int MenuHandler_GlowColorsMenu(Menu menu, MenuAction action, int param1, int param2)
|
|
||||||
{
|
|
||||||
switch(action)
|
|
||||||
{
|
|
||||||
case MenuAction_Select:
|
|
||||||
{
|
|
||||||
char aItem[16];
|
|
||||||
menu.GetItem(param2, aItem, sizeof(aItem));
|
|
||||||
|
|
||||||
ColorStringToArray(aItem, g_aGlowColor[param1]);
|
|
||||||
int Color = (g_aGlowColor[param1][0] << 16) +
|
|
||||||
(g_aGlowColor[param1][1] << 8) +
|
|
||||||
(g_aGlowColor[param1][2] << 0);
|
|
||||||
|
|
||||||
ApplyGlowColor(param1);
|
|
||||||
PrintToChat(param1, "\x01[SM] Set color to: \x07%06X%06X\x01", Color, Color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Event_ApplyGlowColor(Event event, const char[] name, bool dontBroadcast)
|
|
||||||
{
|
|
||||||
int client = GetClientOfUserId(GetEventInt(event, "userid"));
|
|
||||||
if(!client)
|
|
||||||
return;
|
|
||||||
|
|
||||||
CreateTimer(0.1, Timer_ApplyGlowcolor, client, TIMER_FLAG_NO_MAPCHANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
|
|
||||||
{
|
|
||||||
ApplyGlowColor(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ZR_OnClientHumanPost(int client, bool respawn, bool protect)
|
|
||||||
{
|
|
||||||
ApplyGlowColor(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Timer_ApplyGlowcolor(Handle timer, int client)
|
|
||||||
{
|
|
||||||
ApplyGlowColor(client);
|
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ApplyGlowColor(int client)
|
|
||||||
{
|
|
||||||
if(!IsClientInGame(client))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
bool Ret = true;
|
|
||||||
int Brightness = ColorBrightness(g_aGlowColor[client][0], g_aGlowColor[client][1], g_aGlowColor[client][2]);
|
|
||||||
if(Brightness < g_Cvar_MinBrightness.IntValue)
|
|
||||||
{
|
|
||||||
PrintToChat(client, "Your glowcolor is too dark! (brightness = %d/255, allowed values are >= %d)",
|
|
||||||
Brightness, g_Cvar_MinBrightness.IntValue);
|
|
||||||
|
|
||||||
g_aGlowColor[client][0] = 255;
|
|
||||||
g_aGlowColor[client][1] = 255;
|
|
||||||
g_aGlowColor[client][2] = 255;
|
|
||||||
Ret = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(IsPlayerAlive(client))
|
|
||||||
ToolsSetEntityColor(client, g_aGlowColor[client][0], g_aGlowColor[client][1], g_aGlowColor[client][2]);
|
|
||||||
|
|
||||||
return Ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void ToolsGetEntityColor(int entity, int aColor[4])
|
|
||||||
{
|
|
||||||
static bool s_GotConfig = false;
|
|
||||||
static char s_sProp[32];
|
|
||||||
|
|
||||||
if(!s_GotConfig)
|
|
||||||
{
|
|
||||||
Handle GameConf = LoadGameConfigFile("core.games");
|
|
||||||
bool Exists = GameConfGetKeyValue(GameConf, "m_clrRender", s_sProp, sizeof(s_sProp));
|
|
||||||
CloseHandle(GameConf);
|
|
||||||
|
|
||||||
if(!Exists)
|
|
||||||
strcopy(s_sProp, sizeof(s_sProp), "m_clrRender");
|
|
||||||
|
|
||||||
s_GotConfig = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Offset = GetEntSendPropOffs(entity, s_sProp);
|
|
||||||
|
|
||||||
for(int i = 0; i < 4; i++)
|
|
||||||
aColor[i] = GetEntData(entity, Offset + i, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void ToolsSetEntityColor(int client, int Red, int Green, int Blue)
|
|
||||||
{
|
|
||||||
int aColor[4];
|
|
||||||
ToolsGetEntityColor(client, aColor);
|
|
||||||
|
|
||||||
SetEntityRenderColor(client, Red, Green, Blue, aColor[3]);
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void ColorStringToArray(const char[] sColorString, int aColor[3])
|
|
||||||
{
|
|
||||||
char asColors[4][4];
|
|
||||||
ExplodeString(sColorString, " ", asColors, sizeof(asColors), sizeof(asColors[]));
|
|
||||||
|
|
||||||
aColor[0] = StringToInt(asColors[0]) & 0xFF;
|
|
||||||
aColor[1] = StringToInt(asColors[1]) & 0xFF;
|
|
||||||
aColor[2] = StringToInt(asColors[2]) & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
stock bool IsValidRGBNum(char[] sString)
|
|
||||||
{
|
|
||||||
if(g_Regex_RGB.Match(sString) > 0)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
stock bool IsValidHex(char[] sString)
|
|
||||||
{
|
|
||||||
if(g_Regex_HEX.Match(sString) > 0)
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
stock int ColorBrightness(int Red, int Green, int Blue)
|
|
||||||
{
|
|
||||||
// http://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx
|
|
||||||
return RoundToFloor(SquareRoot(
|
|
||||||
Red * Red * 0.241 +
|
|
||||||
Green * Green + 0.691 +
|
|
||||||
Blue * Blue + 0.068));
|
|
||||||
}
|
|
@ -1,8 +0,0 @@
|
|||||||
>> Event #106 || "Challenging and rarely played" <<
|
|
||||||
/n
|
|
||||||
Maps :
|
|
||||||
- ze_mist_v1_3
|
|
||||||
- ze_undertale_g_v1_2s2
|
|
||||||
- ze_grau_s2
|
|
||||||
/n
|
|
||||||
1. Got it
|
|
@ -1,6 +0,0 @@
|
|||||||
>>UNLOZE Falldamage Fun<<
|
|
||||||
/n
|
|
||||||
We have enabled fall damage for humans on this map.
|
|
||||||
Watch out!
|
|
||||||
/n
|
|
||||||
1. Got it
|
|
@ -1,12 +0,0 @@
|
|||||||
>>UNLOZE Nemesis Fun<<
|
|
||||||
/n
|
|
||||||
Nemesis Mode is enabled on this map.
|
|
||||||
This mode has only a few but really strong zombies.
|
|
||||||
Nemesis zombies do not infect humans, but kill them instead.
|
|
||||||
They have more health, are faster and have minimal knock-back from guns.
|
|
||||||
/n
|
|
||||||
Human Tips:
|
|
||||||
You have one smoke grenade that will freeze the nemesis for 1.5 seconds.
|
|
||||||
Your knife is your best option to get rid of a nemesis zombie.
|
|
||||||
/n
|
|
||||||
1. Got it
|
|
@ -1,10 +0,0 @@
|
|||||||
Hello this is dog
|
|
||||||
/n
|
|
||||||
/n
|
|
||||||
How did those two lines get there?
|
|
||||||
/n
|
|
||||||
What is happening?
|
|
||||||
I blame Zuff.
|
|
||||||
/n
|
|
||||||
/n
|
|
||||||
1. Got it
|
|
@ -1,12 +0,0 @@
|
|||||||
>>UNLOZE Zombie Hunting Fun<<
|
|
||||||
/n
|
|
||||||
Zombie Hunting is enabled on this map.
|
|
||||||
Humans need to kill all zombies until the time runs up or zombies win.
|
|
||||||
Zombies have very low health.
|
|
||||||
If you die as a zombie you respawn back as a human.
|
|
||||||
/n
|
|
||||||
Zombie Tips:
|
|
||||||
Use !noblock to enable collision for 5 seconds.
|
|
||||||
This is useful to overcome obstacles by stacking on each other.
|
|
||||||
/n
|
|
||||||
1. Got it
|
|
@ -1,115 +0,0 @@
|
|||||||
#include <sourcemod>
|
|
||||||
|
|
||||||
#define MAXLINES 20
|
|
||||||
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
/* CONVARS */
|
|
||||||
ConVar g_cvInfoMessageFile;
|
|
||||||
|
|
||||||
/* STRINGS */
|
|
||||||
char g_sBuffer[MAXLINES][192];
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "InfoMessage",
|
|
||||||
author = "Neon",
|
|
||||||
description = "",
|
|
||||||
version = "1.0.0",
|
|
||||||
url = "https://steamcommunity.com/id/n3ontm"
|
|
||||||
};
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
g_cvInfoMessageFile = CreateConVar("sm_info_message_file", "null", "", FCVAR_NONE);
|
|
||||||
HookConVarChange(g_cvInfoMessageFile, Cvar_FileChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
public void Cvar_FileChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
|
||||||
{
|
|
||||||
for (int i = 0; i <= (MAXLINES - 1); i++)
|
|
||||||
g_sBuffer[i] = "";
|
|
||||||
|
|
||||||
char sFile[PLATFORM_MAX_PATH];
|
|
||||||
char sLine[192];
|
|
||||||
char sFilename[192];
|
|
||||||
GetConVarString(g_cvInfoMessageFile, sFilename, sizeof(sFilename))
|
|
||||||
|
|
||||||
if (StrEqual(sFilename, "null"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
BuildPath(Path_SM, sFile, sizeof(sFile), "configs/info_messages/%s.txt", sFilename);
|
|
||||||
|
|
||||||
Handle hFile = OpenFile(sFile, "r");
|
|
||||||
|
|
||||||
if(hFile != INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
int iLine = 0;
|
|
||||||
while (!IsEndOfFile(hFile))
|
|
||||||
{
|
|
||||||
if (!ReadFileLine(hFile, sLine, sizeof(sLine)))
|
|
||||||
break;
|
|
||||||
|
|
||||||
TrimString(sLine);
|
|
||||||
g_sBuffer[iLine] = sLine;
|
|
||||||
iLine++;
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(hFile);
|
|
||||||
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LogError("[SM] File not found! (configs/info_messages/%s.txt)", sFilename);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
int MenuHandler_NotifyPanel(Menu hMenu, MenuAction iAction, int iParam1, int iParam2)
|
|
||||||
{
|
|
||||||
switch (iAction)
|
|
||||||
{
|
|
||||||
case MenuAction_Select, MenuAction_Cancel:
|
|
||||||
delete hMenu;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose:
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
public void OnClientPutInServer(int client)
|
|
||||||
{
|
|
||||||
char sFilename[192];
|
|
||||||
GetConVarString(g_cvInfoMessageFile, sFilename, sizeof(sFilename))
|
|
||||||
|
|
||||||
if (StrEqual(sFilename, "null"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
Panel hNotifyPanel = new Panel(GetMenuStyleHandle(MenuStyle_Radio));
|
|
||||||
|
|
||||||
for (int i = 0; i <= (MAXLINES - 1); i++)
|
|
||||||
{
|
|
||||||
if (StrEqual(g_sBuffer[i], ""))
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (StrEqual(g_sBuffer[i], "/n"))
|
|
||||||
{
|
|
||||||
hNotifyPanel.DrawItem("", ITEMDRAW_SPACER);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
hNotifyPanel.DrawItem(g_sBuffer[i], ITEMDRAW_RAWLINE);
|
|
||||||
}
|
|
||||||
|
|
||||||
hNotifyPanel.SetKeys(1023);
|
|
||||||
hNotifyPanel.Send(client, MenuHandler_NotifyPanel, 0);
|
|
||||||
delete hNotifyPanel;
|
|
||||||
}
|
|
@ -1,112 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <multicolors>
|
|
||||||
|
|
||||||
Handle g_hCVar_NotificationTime = INVALID_HANDLE;
|
|
||||||
char g_sAttackerSID[MAXPLAYERS + 1][32];
|
|
||||||
int g_iNotificationTime[MAXPLAYERS + 1];
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "Knife Notifications",
|
|
||||||
author = "Obus + BotoX",
|
|
||||||
description = "Notify administrators when zombies have been knifed by humans.",
|
|
||||||
version = "2.2",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
g_hCVar_NotificationTime = CreateConVar("sm_knifenotifytime", "5", "Amount of time to pass before a knifed zombie is considered \"not knifed\" anymore.", 0, true, 0.0, true, 60.0);
|
|
||||||
|
|
||||||
if(!HookEventEx("player_hurt", Event_PlayerHurt, EventHookMode_Pre))
|
|
||||||
SetFailState("[Knife-Notifications] Failed to hook \"player_hurt\" event.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public int GetClientFromSteamID(const char[] auth)
|
|
||||||
{
|
|
||||||
char clientAuth[32];
|
|
||||||
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(!IsClientAuthorized(client))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
GetClientAuthId(client, AuthId_Steam2, clientAuth, sizeof(clientAuth));
|
|
||||||
|
|
||||||
if(StrEqual(auth, clientAuth))
|
|
||||||
return client;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Event_PlayerHurt(Handle hEvent, const char[] name, bool dontBroadcast)
|
|
||||||
{
|
|
||||||
int victim;
|
|
||||||
int attacker;
|
|
||||||
char sWepName[64];
|
|
||||||
char sAtkSID[32];
|
|
||||||
char sVictSID[32];
|
|
||||||
GetEventString(hEvent, "weapon", sWepName, sizeof(sWepName));
|
|
||||||
|
|
||||||
if((victim = GetClientOfUserId(GetEventInt(hEvent, "userid"))) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if((attacker = GetClientOfUserId(GetEventInt(hEvent, "attacker"))) == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!IsClientInGame(victim) || !IsPlayerAlive(victim))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(!IsClientInGame(attacker) || !IsPlayerAlive(attacker))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(victim != attacker && GetClientTeam(victim) == 2 && GetClientTeam(attacker) == 3)
|
|
||||||
{
|
|
||||||
if(StrEqual(sWepName, "knife"))
|
|
||||||
{
|
|
||||||
int damage = GetEventInt(hEvent, "dmg_health");
|
|
||||||
|
|
||||||
if(damage < 35)
|
|
||||||
return;
|
|
||||||
|
|
||||||
GetClientAuthId(attacker, AuthId_Steam2, sAtkSID, sizeof(sAtkSID));
|
|
||||||
GetClientAuthId(attacker, AuthId_Steam2, g_sAttackerSID[victim], sizeof(g_sAttackerSID[]));
|
|
||||||
GetClientAuthId(victim, AuthId_Steam2, sVictSID, sizeof(sVictSID));
|
|
||||||
LogMessage("%L knifed %L", attacker, victim);
|
|
||||||
|
|
||||||
g_iNotificationTime[victim] = (GetTime() + GetConVarInt(g_hCVar_NotificationTime));
|
|
||||||
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(IsClientConnected(i) && IsClientInGame(i) && (IsClientSourceTV(i) || GetAdminFlag(GetUserAdmin(i), Admin_Generic)))
|
|
||||||
CPrintToChat(i, "{green}[SM] {blue}%N {default}knifed {red}%N", attacker, victim);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(victim != attacker && GetClientTeam(attacker) == 2 && GetClientTeam(victim) == 3)
|
|
||||||
{
|
|
||||||
int pOldKnifer;
|
|
||||||
pOldKnifer = GetClientFromSteamID(g_sAttackerSID[attacker]);
|
|
||||||
|
|
||||||
if(g_iNotificationTime[attacker] > GetTime() && (victim != pOldKnifer))
|
|
||||||
{
|
|
||||||
char sAtkAttackerName[MAX_NAME_LENGTH];
|
|
||||||
GetClientAuthId(attacker, AuthId_Steam2, sAtkSID, sizeof(sAtkSID));
|
|
||||||
|
|
||||||
if(pOldKnifer != -1)
|
|
||||||
{
|
|
||||||
GetClientName(pOldKnifer, sAtkAttackerName, sizeof(sAtkAttackerName));
|
|
||||||
LogMessage("%L killed %L (Recently knifed by %L)", attacker, victim, pOldKnifer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LogMessage("%L killed %L (Recently knifed by a disconnected player [%s])", attacker, victim, g_sAttackerSID[attacker]);
|
|
||||||
|
|
||||||
CPrintToChatAll("{green}[SM] {red}%N {green}(%s){default} killed {blue}%N{default} - knifed by {blue}%s {green}(%s)",
|
|
||||||
attacker, sAtkSID, victim, (pOldKnifer != -1) ? sAtkAttackerName : "a disconnected player", g_sAttackerSID[attacker]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,342 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
|
|
||||||
KeyValues g_Config;
|
|
||||||
bool g_Enabled = false;
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "MapAdmin",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Adminroom teleport and changing stages.",
|
|
||||||
version = "0.1",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
LoadTranslations("common.phrases");
|
|
||||||
|
|
||||||
char sConfigFile[PLATFORM_MAX_PATH];
|
|
||||||
BuildPath(Path_SM, sConfigFile, sizeof(sConfigFile), "configs/MapAdmin.cfg");
|
|
||||||
|
|
||||||
if(!FileExists(sConfigFile))
|
|
||||||
{
|
|
||||||
SetFailState("Could not find config: \"%s\"", sConfigFile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_Config = new KeyValues("maps");
|
|
||||||
if(!g_Config.ImportFromFile(sConfigFile))
|
|
||||||
{
|
|
||||||
delete g_Config;
|
|
||||||
SetFailState("ImportFromFile() failed!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
g_Config.Rewind();
|
|
||||||
|
|
||||||
RegAdminCmd("sm_adminroom", Command_AdminRoom, ADMFLAG_GENERIC, "sm_adminroom [#userid|name]");
|
|
||||||
RegAdminCmd("sm_stage", Command_Stage, ADMFLAG_GENERIC, "sm_stage <stage>");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMapStart()
|
|
||||||
{
|
|
||||||
g_Enabled = false;
|
|
||||||
g_Config.Rewind();
|
|
||||||
|
|
||||||
char sMapName[PLATFORM_MAX_PATH];
|
|
||||||
GetCurrentMap(sMapName, sizeof(sMapName));
|
|
||||||
|
|
||||||
if(g_Config.JumpToKey(sMapName, false))
|
|
||||||
g_Enabled = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_AdminRoom(int client, int argc)
|
|
||||||
{
|
|
||||||
if(!g_Enabled)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] The current map is not supported.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sAdminRoom[64];
|
|
||||||
g_Config.GetString("adminroom", sAdminRoom, sizeof(sAdminRoom), "");
|
|
||||||
|
|
||||||
if(!sAdminRoom[0])
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] The current map does not have an adminroom (configured).");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(argc > 1)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Usage: sm_adminroom [#userid|name]");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sOrigins[3][16];
|
|
||||||
ExplodeString(sAdminRoom, " ", sOrigins, sizeof(sOrigins), sizeof(sOrigins[]));
|
|
||||||
|
|
||||||
float fOrigin[3];
|
|
||||||
fOrigin[0] = StringToFloat(sOrigins[0]);
|
|
||||||
fOrigin[1] = StringToFloat(sOrigins[1]);
|
|
||||||
fOrigin[2] = StringToFloat(sOrigins[2]);
|
|
||||||
|
|
||||||
char sArgs[64];
|
|
||||||
char sTargetName[MAX_TARGET_LENGTH];
|
|
||||||
int iTargets[MAXPLAYERS];
|
|
||||||
int iTargetCount;
|
|
||||||
bool bIsML;
|
|
||||||
|
|
||||||
if(argc == 1)
|
|
||||||
GetCmdArg(1, sArgs, sizeof(sArgs));
|
|
||||||
else
|
|
||||||
strcopy(sArgs, sizeof(sArgs), "@me");
|
|
||||||
|
|
||||||
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], fOrigin, NULL_VECTOR, NULL_VECTOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowActivity2(client, "\x01[SM] \x04", "\x01Teleported \x04%s\x01 to the adminroom.", sTargetName);
|
|
||||||
if(iTargetCount > 1)
|
|
||||||
LogAction(client, -1, "\"%L\" teleported \"%s\" to the adminroom.", client, sTargetName);
|
|
||||||
else
|
|
||||||
LogAction(client, iTargets[0], "\"%L\" teleported \"%L\" to the adminroom.", client, iTargets[0]);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Stage(int client, int argc)
|
|
||||||
{
|
|
||||||
if(!g_Enabled)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] The current map is not supported.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!g_Config.JumpToKey("stages", false))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] The current map does not have stages (configured).");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!g_Config.GotoFirstSubKey(false))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] The current map does not have any stages configured.");
|
|
||||||
g_Config.GoBack(); // "stages"
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(argc < 1)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Available stages:");
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
char sSection[32];
|
|
||||||
g_Config.GetSectionName(sSection, sizeof(sSection));
|
|
||||||
|
|
||||||
char sName[64];
|
|
||||||
g_Config.GetString("name", sName, sizeof(sName), "MISSING_NAME");
|
|
||||||
|
|
||||||
if(!g_Config.JumpToKey("triggers", false))
|
|
||||||
{
|
|
||||||
g_Config.GoBack(); // "stages"
|
|
||||||
g_Config.GoBack(); // "GotoFirstSubKey"
|
|
||||||
|
|
||||||
ReplyToCommand(client, "Config error in stage \"%s\"(\"%s\"), missing \"triggers\" block.", sSection, sName);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!g_Config.GotoFirstSubKey(false))
|
|
||||||
{
|
|
||||||
g_Config.GoBack(); // "stages"
|
|
||||||
g_Config.GoBack(); // "GotoFirstSubKey"
|
|
||||||
g_Config.GoBack(); // "triggers"
|
|
||||||
|
|
||||||
ReplyToCommand(client, "Config error in stage \"%s\"(\"%s\"), empty \"triggers\" block.", sSection, sName);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sTriggers[128];
|
|
||||||
do
|
|
||||||
{
|
|
||||||
char sTrigger[32];
|
|
||||||
g_Config.GetString(NULL_STRING, sTrigger, sizeof(sTrigger));
|
|
||||||
|
|
||||||
StrCat(sTrigger, sizeof(sTrigger), ", ");
|
|
||||||
StrCat(sTriggers, sizeof(sTriggers), sTrigger);
|
|
||||||
} while(g_Config.GotoNextKey(false));
|
|
||||||
|
|
||||||
g_Config.GoBack(); // "triggers"
|
|
||||||
g_Config.GoBack(); // "GotoFirstSubKey"
|
|
||||||
|
|
||||||
// Remove last ", "
|
|
||||||
sTriggers[strlen(sTriggers) - 2] = 0;
|
|
||||||
|
|
||||||
ReplyToCommand(client, "%s: %s", sName, sTriggers);
|
|
||||||
|
|
||||||
} while(g_Config.GotoNextKey(false));
|
|
||||||
|
|
||||||
g_Config.GoBack(); // "stages"
|
|
||||||
g_Config.GoBack(); // "GotoFirstSubKey"
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sArg[64];
|
|
||||||
GetCmdArgString(sArg, sizeof(sArg));
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
char sSection[32];
|
|
||||||
g_Config.GetSectionName(sSection, sizeof(sSection));
|
|
||||||
|
|
||||||
char sName[64];
|
|
||||||
g_Config.GetString("name", sName, sizeof(sName), "MISSING_NAME");
|
|
||||||
|
|
||||||
if(!g_Config.JumpToKey("triggers", false))
|
|
||||||
{
|
|
||||||
g_Config.GoBack(); // "stages"
|
|
||||||
g_Config.GoBack(); // "GotoFirstSubKey"
|
|
||||||
|
|
||||||
ReplyToCommand(client, "Config error in stage \"%s\"(\"%s\"), missing \"triggers\" block.", sSection, sName);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!g_Config.GotoFirstSubKey(false))
|
|
||||||
{
|
|
||||||
g_Config.GoBack(); // "stages"
|
|
||||||
g_Config.GoBack(); // "GotoFirstSubKey"
|
|
||||||
g_Config.GoBack(); // "triggers"
|
|
||||||
|
|
||||||
ReplyToCommand(client, "Config error in stage \"%s\"(\"%s\"), empty \"triggers\" block.", sSection, sName);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bFound = false;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
char sTrigger[32];
|
|
||||||
g_Config.GetString(NULL_STRING, sTrigger, sizeof(sTrigger));
|
|
||||||
|
|
||||||
if(StrEqual(sArg, sTrigger, true))
|
|
||||||
{
|
|
||||||
bFound = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while(g_Config.GotoNextKey(false));
|
|
||||||
|
|
||||||
g_Config.GoBack(); // "triggers"
|
|
||||||
g_Config.GoBack(); // "GotoFirstSubKey"
|
|
||||||
|
|
||||||
if(!bFound)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ReplyToCommand(client, "Triggering \"%s\"", sName);
|
|
||||||
|
|
||||||
if(!g_Config.JumpToKey("actions", false))
|
|
||||||
{
|
|
||||||
g_Config.GoBack(); // "stages"
|
|
||||||
g_Config.GoBack(); // "GotoFirstSubKey"
|
|
||||||
|
|
||||||
ReplyToCommand(client, "Config error in stage \"%s\"(\"%s\"), missing \"actions\" block.", sSection, sName);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!g_Config.GotoFirstSubKey(false))
|
|
||||||
{
|
|
||||||
g_Config.GoBack(); // "stages"
|
|
||||||
g_Config.GoBack(); // "GotoFirstSubKey"
|
|
||||||
g_Config.GoBack(); // "actions"
|
|
||||||
|
|
||||||
ReplyToCommand(client, "Config error in stage \"%s\"(\"%s\"), empty \"actions\" block.", sSection, sName);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
char sAction[256];
|
|
||||||
g_Config.GetString(NULL_STRING, sAction, sizeof(sAction));
|
|
||||||
|
|
||||||
int iDelim = FindCharInString(sAction, ':');
|
|
||||||
if(iDelim == -1)
|
|
||||||
{
|
|
||||||
char sActionSection[32];
|
|
||||||
g_Config.GetSectionName(sActionSection, sizeof(sActionSection));
|
|
||||||
|
|
||||||
g_Config.GoBack(); // "actions"
|
|
||||||
g_Config.GoBack(); // "GotoFirstSubKey"
|
|
||||||
g_Config.GoBack(); // "stages"
|
|
||||||
g_Config.GoBack(); // "GotoFirstSubKey"
|
|
||||||
|
|
||||||
ReplyToCommand(client, "Config error in stage \"%s\"(\"%s\"), action \"%s\" missing delim ':'.", sSection, sName, sActionSection);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
ReplyToCommand(client, "Firing \"%s\"", sAction);
|
|
||||||
sAction[iDelim++] = 0;
|
|
||||||
|
|
||||||
int entity = INVALID_ENT_REFERENCE;
|
|
||||||
while((entity = FindEntityByTargetname(entity, sAction, "*")) != INVALID_ENT_REFERENCE)
|
|
||||||
{
|
|
||||||
AcceptEntityInput(entity, sAction[iDelim], client, client);
|
|
||||||
}
|
|
||||||
|
|
||||||
} while(g_Config.GotoNextKey(false));
|
|
||||||
|
|
||||||
g_Config.GoBack(); // "actions"
|
|
||||||
g_Config.GoBack(); // "GotoFirstSubKey"
|
|
||||||
|
|
||||||
ShowActivity2(client, "\x01[SM] \x04", "\x01Changed the stage to \x04%s\x01.", sName);
|
|
||||||
LogAction(client, -1, "\"%L\" changed the stage to \"%s\".", client, sName);
|
|
||||||
|
|
||||||
break;
|
|
||||||
} while(g_Config.GotoNextKey(false));
|
|
||||||
|
|
||||||
g_Config.GoBack(); // "stages"
|
|
||||||
g_Config.GoBack(); // "GotoFirstSubKey"
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
int FindEntityByTargetname(int entity, const char[] sTargetname, const char[] sClassname="*")
|
|
||||||
{
|
|
||||||
if(sTargetname[0] == '#') // HammerID
|
|
||||||
{
|
|
||||||
int HammerID = StringToInt(sTargetname[1]);
|
|
||||||
|
|
||||||
while((entity = FindEntityByClassname(entity, sClassname)) != INVALID_ENT_REFERENCE)
|
|
||||||
{
|
|
||||||
if(GetEntProp(entity, Prop_Data, "m_iHammerID") == HammerID)
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // Targetname
|
|
||||||
{
|
|
||||||
int Wildcard = FindCharInString(sTargetname, '*');
|
|
||||||
char sTargetnameBuf[64];
|
|
||||||
|
|
||||||
while((entity = FindEntityByClassname(entity, sClassname)) != INVALID_ENT_REFERENCE)
|
|
||||||
{
|
|
||||||
if(GetEntPropString(entity, Prop_Data, "m_iName", sTargetnameBuf, sizeof(sTargetnameBuf)) <= 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(strncmp(sTargetnameBuf, sTargetname, Wildcard) == 0)
|
|
||||||
return entity;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return INVALID_ENT_REFERENCE;
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
"filters"
|
|
||||||
{
|
|
||||||
// this is what the filtered characters are replaced by, do "" to just remove them
|
|
||||||
"censor" ""
|
|
||||||
|
|
||||||
// regex expression for filtering, matches are replaced by the censor, here we are using a whitelist - this would strip unicode characters
|
|
||||||
"filter" "[^A-Za-z0-9\s!@#$%^&*()-_+=-`~\\\]\[{}|';:/.,?><]"
|
|
||||||
|
|
||||||
// series of regex expressions for names POST FILTER, matches will get replacement names
|
|
||||||
"banned"
|
|
||||||
{
|
|
||||||
"1" "[Aa4]+[Dd]+[Mm]+[IiL1]+[nN]+"
|
|
||||||
"2" "@((!?)me|(c?)t(s?)|(!?)admins|(!?)friends|random((c?)t?)|humans|spec|alive|dead|aim|bots)"
|
|
||||||
}
|
|
||||||
|
|
||||||
// replacement names, granted by banned filter, or if the name is too short (<2)
|
|
||||||
"names"
|
|
||||||
{
|
|
||||||
"1" "BAD_NAME"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,350 +0,0 @@
|
|||||||
#include <sdktools>
|
|
||||||
#include <regex>
|
|
||||||
#include <basecomm>
|
|
||||||
|
|
||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
Regex g_FilterExpr;
|
|
||||||
char g_FilterChar[2] = "";
|
|
||||||
ArrayList g_BannedExprs;
|
|
||||||
ArrayList g_ReplacementNames;
|
|
||||||
int g_iBlockNameChangeEvents[MAXPLAYERS + 1] = {0, ...};
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "NameFilter",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Filters player names",
|
|
||||||
version = "1.0"
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
HookEvent("player_changename", Event_ChangeName, EventHookMode_Pre);
|
|
||||||
HookUserMessage(GetUserMessageId("SayText2"), UserMessage_SayText2, true);
|
|
||||||
|
|
||||||
LoadConfig();
|
|
||||||
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(IsClientConnected(i))
|
|
||||||
OnClientConnected(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientConnected(int client)
|
|
||||||
{
|
|
||||||
g_iBlockNameChangeEvents[client] = 0;
|
|
||||||
|
|
||||||
if(IsFakeClient(client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
char sName[MAX_NAME_LENGTH];
|
|
||||||
GetClientName(client, sName, sizeof(sName));
|
|
||||||
|
|
||||||
if(FilterName(client, sName))
|
|
||||||
SetClientName(client, sName);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPutInServer(int client)
|
|
||||||
{
|
|
||||||
if(IsFakeClient(client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
char sName[MAX_NAME_LENGTH];
|
|
||||||
GetClientName(client, sName, sizeof(sName));
|
|
||||||
|
|
||||||
if(FilterName(client, sName))
|
|
||||||
{
|
|
||||||
g_iBlockNameChangeEvents[client] = 2;
|
|
||||||
SetClientName(client, sName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Event_ChangeName(Event event, const char[] name, bool dontBroadcast)
|
|
||||||
{
|
|
||||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
|
||||||
if(g_iBlockNameChangeEvents[client])
|
|
||||||
{
|
|
||||||
g_iBlockNameChangeEvents[client]--;
|
|
||||||
SetEventBroadcast(event, true);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action UserMessage_SayText2(UserMsg msg_id, BfRead msg, const int[] players, int playersNum, bool reliable, bool init)
|
|
||||||
{
|
|
||||||
if(!reliable)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
int client;
|
|
||||||
char sMessage[32];
|
|
||||||
char sOldName[MAX_NAME_LENGTH];
|
|
||||||
char sNewName[MAX_NAME_LENGTH];
|
|
||||||
|
|
||||||
if(GetUserMessageType() == UM_Protobuf)
|
|
||||||
{
|
|
||||||
PbReadString(msg, "msg_name", sMessage, sizeof(sMessage));
|
|
||||||
|
|
||||||
if(!(sMessage[0] == '#' && StrContains(sMessage, "Name_Change")))
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
client = PbReadInt(msg, "ent_idx");
|
|
||||||
PbReadString(msg, "params", sOldName, sizeof(sOldName), 1);
|
|
||||||
PbReadString(msg, "params", sNewName, sizeof(sNewName), 2);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
client = BfReadByte(msg);
|
|
||||||
BfReadByte(msg);
|
|
||||||
BfReadString(msg, sMessage, sizeof(sMessage));
|
|
||||||
|
|
||||||
if(!(sMessage[0] == '#' && StrContains(sMessage, "Name_Change")))
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
BfReadString(msg, sOldName, sizeof(sOldName));
|
|
||||||
BfReadString(msg, sNewName, sizeof(sNewName));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(g_iBlockNameChangeEvents[client])
|
|
||||||
{
|
|
||||||
g_iBlockNameChangeEvents[client]--;
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool bGagged = BaseComm_IsClientGagged(client);
|
|
||||||
if(FilterName(client, sNewName) || bGagged)
|
|
||||||
{
|
|
||||||
if(StrEqual(sOldName, sNewName) || bGagged)
|
|
||||||
{
|
|
||||||
g_iBlockNameChangeEvents[client] = 3;
|
|
||||||
SetClientName(client, sOldName);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_iBlockNameChangeEvents[client] = 3;
|
|
||||||
SetClientName(client, sOldName);
|
|
||||||
|
|
||||||
DataPack pack = new DataPack();
|
|
||||||
pack.WriteCell(client);
|
|
||||||
pack.WriteString(sNewName);
|
|
||||||
|
|
||||||
CreateTimer(0.1, Timer_ChangeName, pack);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Timer_ChangeName(Handle timer, any data)
|
|
||||||
{
|
|
||||||
DataPack pack = view_as<DataPack>(data);
|
|
||||||
pack.Reset();
|
|
||||||
|
|
||||||
int client = pack.ReadCell();
|
|
||||||
char sName[MAX_NAME_LENGTH];
|
|
||||||
pack.ReadString(sName, sizeof(sName));
|
|
||||||
|
|
||||||
delete pack;
|
|
||||||
|
|
||||||
SetClientName(client, sName);
|
|
||||||
|
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadConfig()
|
|
||||||
{
|
|
||||||
if(g_FilterExpr != INVALID_HANDLE)
|
|
||||||
CloseHandle(g_FilterExpr);
|
|
||||||
|
|
||||||
if(g_BannedExprs)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < g_BannedExprs.Length; i++)
|
|
||||||
{
|
|
||||||
Handle hRegex = g_BannedExprs.Get(i);
|
|
||||||
CloseHandle(hRegex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete g_BannedExprs;
|
|
||||||
delete g_ReplacementNames;
|
|
||||||
|
|
||||||
static char sConfigFile[PLATFORM_MAX_PATH];
|
|
||||||
BuildPath(Path_SM, sConfigFile, sizeof(sConfigFile), "configs/NameFilter.cfg");
|
|
||||||
if(!FileExists(sConfigFile))
|
|
||||||
SetFailState("Could not find config: \"%s\"", sConfigFile);
|
|
||||||
|
|
||||||
KeyValues Config = new KeyValues("NameFilter");
|
|
||||||
if(!Config.ImportFromFile(sConfigFile))
|
|
||||||
{
|
|
||||||
delete Config;
|
|
||||||
SetFailState("ImportFromFile() failed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
Config.GetString("censor", g_FilterChar, 2, "*");
|
|
||||||
|
|
||||||
static char sBuffer[256];
|
|
||||||
Config.GetString("filter", sBuffer, 256);
|
|
||||||
|
|
||||||
char sError[256];
|
|
||||||
RegexError iError;
|
|
||||||
g_FilterExpr = CompileRegex(sBuffer, PCRE_UTF8, sError, sizeof(sError), iError);
|
|
||||||
if(iError != REGEX_ERROR_NONE)
|
|
||||||
{
|
|
||||||
delete Config;
|
|
||||||
SetFailState(sError);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_BannedExprs = new ArrayList();
|
|
||||||
if(Config.JumpToKey("banned"))
|
|
||||||
{
|
|
||||||
if(Config.GotoFirstSubKey(false))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
Config.GetString(NULL_STRING, sBuffer, sizeof(sBuffer));
|
|
||||||
|
|
||||||
Handle hRegex = CompileRegex(sBuffer, PCRE_UTF8, sError, sizeof(sError), iError);
|
|
||||||
if(iError != REGEX_ERROR_NONE)
|
|
||||||
LogError("Error parsing banned filter: %s", sError);
|
|
||||||
else
|
|
||||||
g_BannedExprs.Push(hRegex);
|
|
||||||
} while(Config.GotoNextKey(false));
|
|
||||||
Config.GoBack();
|
|
||||||
}
|
|
||||||
Config.GoBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
g_ReplacementNames = new ArrayList(ByteCountToCells(MAX_NAME_LENGTH));
|
|
||||||
if(Config.JumpToKey("names"))
|
|
||||||
{
|
|
||||||
if(Config.GotoFirstSubKey(false))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
Config.GetString(NULL_STRING, sBuffer, sizeof(sBuffer));
|
|
||||||
|
|
||||||
g_ReplacementNames.PushString(sBuffer);
|
|
||||||
} while(Config.GotoNextKey(false));
|
|
||||||
Config.GoBack();
|
|
||||||
}
|
|
||||||
Config.GoBack();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!g_ReplacementNames.Length)
|
|
||||||
{
|
|
||||||
LogError("Warning, you didn't specify any replacement names!");
|
|
||||||
g_ReplacementNames.PushString("BAD_NAME");
|
|
||||||
}
|
|
||||||
|
|
||||||
delete Config;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FilterName(int client, char[] sName, int Length = MAX_NAME_LENGTH)
|
|
||||||
{
|
|
||||||
bool bChanged = false;
|
|
||||||
RegexError iError;
|
|
||||||
|
|
||||||
// SourceMod Regex bug
|
|
||||||
int Guard;
|
|
||||||
for(Guard = 0; Guard < 100; Guard++)
|
|
||||||
{
|
|
||||||
if (!strlen(sName))
|
|
||||||
break;
|
|
||||||
|
|
||||||
int Match = MatchRegex(g_FilterExpr, sName, iError);
|
|
||||||
if(iError != REGEX_ERROR_NONE)
|
|
||||||
{
|
|
||||||
if(iError == REGEX_ERROR_BADUTF8)
|
|
||||||
{
|
|
||||||
sName[0] = 0;
|
|
||||||
bChanged = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
LogError("Regex Error: %d", iError);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Match <= 0)
|
|
||||||
break;
|
|
||||||
|
|
||||||
for(int i = 0; i < Match; i++)
|
|
||||||
{
|
|
||||||
char sMatch[MAX_NAME_LENGTH];
|
|
||||||
if(GetRegexSubString(g_FilterExpr, i, sMatch, sizeof(sMatch)))
|
|
||||||
{
|
|
||||||
if(ReplaceStringEx(sName, Length, sMatch, g_FilterChar) != -1)
|
|
||||||
bChanged = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(Guard == 100)
|
|
||||||
LogError("SourceMod Regex failed! \"%s\"", sName);
|
|
||||||
|
|
||||||
if(g_BannedExprs)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < g_BannedExprs.Length; i++)
|
|
||||||
{
|
|
||||||
if (!strlen(sName))
|
|
||||||
break;
|
|
||||||
|
|
||||||
Handle hRegex = g_BannedExprs.Get(i);
|
|
||||||
int Match = MatchRegex(hRegex, sName, iError);
|
|
||||||
if(iError != REGEX_ERROR_NONE)
|
|
||||||
{
|
|
||||||
LogError("Regex Error: %d", iError);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Match <= 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int RandomName = client % g_ReplacementNames.Length;
|
|
||||||
g_ReplacementNames.GetString(RandomName, sName, Length);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!bChanged)
|
|
||||||
bChanged = TerminateNameUTF8(sName);
|
|
||||||
|
|
||||||
if(bChanged)
|
|
||||||
{
|
|
||||||
TerminateNameUTF8(sName);
|
|
||||||
|
|
||||||
if(strlen(sName) < 2)
|
|
||||||
{
|
|
||||||
int RandomName = client % g_ReplacementNames.Length;
|
|
||||||
g_ReplacementNames.GetString(RandomName, sName, Length);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return bChanged;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ensures that utf8 names are properly terminated
|
|
||||||
stock bool TerminateNameUTF8(char[] name)
|
|
||||||
{
|
|
||||||
int len = strlen(name);
|
|
||||||
for(int i = 0; i < len; i++)
|
|
||||||
{
|
|
||||||
int bytes = IsCharMB(name[i]);
|
|
||||||
if(bytes > 1)
|
|
||||||
{
|
|
||||||
if(len - i < bytes)
|
|
||||||
{
|
|
||||||
name[i] = '\0';
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
i += bytes - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
"Games"
|
|
||||||
{
|
|
||||||
"cstrike"
|
|
||||||
{
|
|
||||||
"Offsets"
|
|
||||||
{
|
|
||||||
"RadiusDamage"
|
|
||||||
{
|
|
||||||
"windows" "68"
|
|
||||||
"linux" "69"
|
|
||||||
"mac" "69"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"csgo"
|
|
||||||
{
|
|
||||||
"Offsets"
|
|
||||||
{
|
|
||||||
"RadiusDamage"
|
|
||||||
{
|
|
||||||
"windows" "68"
|
|
||||||
"linux" "69"
|
|
||||||
"mac" "69"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,70 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <dhooks>
|
|
||||||
#include <sdkhooks>
|
|
||||||
|
|
||||||
Handle g_hRadiusDamage = INVALID_HANDLE;
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "Napalm Lag Fix",
|
|
||||||
author = "GoD-Tony + BotoX",
|
|
||||||
description = "Prevents lag when napalm is used on players",
|
|
||||||
version = "1.0.4",
|
|
||||||
url = "https://forums.alliedmods.net/showthread.php?t=188093"
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
// Gamedata.
|
|
||||||
Handle hConfig = LoadGameConfigFile("napalmlagfix.games");
|
|
||||||
if(hConfig == INVALID_HANDLE)
|
|
||||||
SetFailState("Could not find gamedata file: napalmlagfix.games.txt");
|
|
||||||
|
|
||||||
int offset = GameConfGetOffset(hConfig, "RadiusDamage");
|
|
||||||
if(offset == -1)
|
|
||||||
SetFailState("Failed to find RadiusDamage offset");
|
|
||||||
|
|
||||||
CloseHandle(hConfig);
|
|
||||||
|
|
||||||
// DHooks
|
|
||||||
g_hRadiusDamage = DHookCreate(offset, HookType_GameRules, ReturnType_Void, ThisPointer_Ignore, Hook_RadiusDamage);
|
|
||||||
DHookAddParam(g_hRadiusDamage, HookParamType_ObjectPtr); // 1 - CTakeDamageInfo &info
|
|
||||||
DHookAddParam(g_hRadiusDamage, HookParamType_VectorPtr); // 2 - Vector &vecSrc
|
|
||||||
DHookAddParam(g_hRadiusDamage, HookParamType_Float); // 3 - float flRadius
|
|
||||||
DHookAddParam(g_hRadiusDamage, HookParamType_Int); // 4 - int iClassIgnore
|
|
||||||
DHookAddParam(g_hRadiusDamage, HookParamType_CBaseEntity); // 5 - CBaseEntity *pEntityIgnore
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMapStart()
|
|
||||||
{
|
|
||||||
DHookGamerules(g_hRadiusDamage, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MRESReturn Hook_RadiusDamage(Handle hParams)
|
|
||||||
{
|
|
||||||
if(DHookIsNullParam(hParams, 5))
|
|
||||||
return MRES_Ignored;
|
|
||||||
|
|
||||||
int iDmgBits = DHookGetParamObjectPtrVar(hParams, 1, 60, ObjectValueType_Int);
|
|
||||||
int iEntIgnore = DHookGetParam(hParams, 5);
|
|
||||||
|
|
||||||
if(!(iDmgBits & DMG_BURN))
|
|
||||||
return MRES_Ignored;
|
|
||||||
|
|
||||||
// Block napalm damage if it's coming from another client.
|
|
||||||
if(1 <= iEntIgnore <= MaxClients)
|
|
||||||
return MRES_Supercede;
|
|
||||||
|
|
||||||
// Block napalm that comes from grenades
|
|
||||||
char sEntClassName[64];
|
|
||||||
if(GetEntityClassname(iEntIgnore, sEntClassName, sizeof(sEntClassName)))
|
|
||||||
{
|
|
||||||
if(!strcmp(sEntClassName, "hegrenade_projectile"))
|
|
||||||
return MRES_Supercede;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MRES_Ignored;
|
|
||||||
}
|
|
@ -1,15 +0,0 @@
|
|||||||
"Games"
|
|
||||||
{
|
|
||||||
"cstrike"
|
|
||||||
{
|
|
||||||
"Offsets"
|
|
||||||
{
|
|
||||||
"OnDamagedByExplosion"
|
|
||||||
{
|
|
||||||
"windows" "335"
|
|
||||||
"linux" "336"
|
|
||||||
"mac" "336"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
#include <dhooks>
|
|
||||||
|
|
||||||
// int CCSPlayer::OnDamagedByExplosion(CTakeDamageInfo const&)
|
|
||||||
Handle g_hDamagedByExplosion;
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "NoGrenadeRinging",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Block the annoying ringing noise when a grenade explodes next to you",
|
|
||||||
version = "1.0.1",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
Handle hTemp = LoadGameConfigFile("NoGrenadeRinging.games");
|
|
||||||
if(hTemp == INVALID_HANDLE)
|
|
||||||
SetFailState("Why you no has gamedata?");
|
|
||||||
|
|
||||||
int Offset = GameConfGetOffset(hTemp, "OnDamagedByExplosion");
|
|
||||||
g_hDamagedByExplosion = DHookCreate(Offset, HookType_Entity, ReturnType_Int, ThisPointer_CBaseEntity, OnDamagedByExplosion);
|
|
||||||
DHookAddParam(g_hDamagedByExplosion, HookParamType_ObjectPtr);
|
|
||||||
CloseHandle(hTemp);
|
|
||||||
|
|
||||||
/* Late load */
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(client))
|
|
||||||
OnClientPutInServer(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPutInServer(int client)
|
|
||||||
{
|
|
||||||
// Don't add removal callback for this one
|
|
||||||
DHookEntity(g_hDamagedByExplosion, false, client);
|
|
||||||
}
|
|
||||||
|
|
||||||
// int CCSPlayer::OnDamagedByExplosion(CTakeDamageInfo const&)
|
|
||||||
public MRESReturn OnDamagedByExplosion(int pThis, Handle hReturn, Handle hParams)
|
|
||||||
{
|
|
||||||
// Block call
|
|
||||||
DHookSetReturn(hReturn, 0);
|
|
||||||
return MRES_Supercede;
|
|
||||||
}
|
|
@ -1,91 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdkhooks>
|
|
||||||
#include <clientprefs>
|
|
||||||
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
Handle g_hNoShakeCookie;
|
|
||||||
ConVar g_Cvar_NoShakeGlobal;
|
|
||||||
|
|
||||||
bool g_bNoShake[MAXPLAYERS + 1] = {false, ...};
|
|
||||||
bool g_bNoShakeGlobal = false;
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "NoShake",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Disable env_shake",
|
|
||||||
version = "1.0.1",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
RegConsoleCmd("sm_shake", Command_Shake, "[NoShake] Disables or enables screen shakes.");
|
|
||||||
RegConsoleCmd("sm_noshake", Command_Shake, "[NoShake] Disables or enables screen shakes.");
|
|
||||||
|
|
||||||
g_hNoShakeCookie = RegClientCookie("noshake_cookie", "NoShake", CookieAccess_Protected);
|
|
||||||
|
|
||||||
g_Cvar_NoShakeGlobal = CreateConVar("sm_noshake_global", "0", "Disable screenshake globally.", 0, true, 0.0, true, 1.0);
|
|
||||||
g_bNoShakeGlobal = g_Cvar_NoShakeGlobal.BoolValue;
|
|
||||||
g_Cvar_NoShakeGlobal.AddChangeHook(OnConVarChanged);
|
|
||||||
|
|
||||||
HookUserMessage(GetUserMessageId("Shake"), MsgHook, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientCookiesCached(int client)
|
|
||||||
{
|
|
||||||
static char sCookieValue[2];
|
|
||||||
GetClientCookie(client, g_hNoShakeCookie, sCookieValue, sizeof(sCookieValue));
|
|
||||||
g_bNoShake[client] = StringToInt(sCookieValue) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
|
||||||
{
|
|
||||||
if(StringToInt(newValue) > StringToInt(oldValue))
|
|
||||||
PrintToChatAll("\x03[NoShake]\x01 Enabled NoShake globally!");
|
|
||||||
else if(StringToInt(newValue) < StringToInt(oldValue))
|
|
||||||
PrintToChatAll("\x03[NoShake]\x01 Disabled NoShake globally!");
|
|
||||||
|
|
||||||
g_bNoShakeGlobal = StringToInt(newValue) != 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action MsgHook(UserMsg msg_id, BfRead msg, const int[] players, int playersNum, bool reliable, bool init)
|
|
||||||
{
|
|
||||||
if(playersNum == 1 && (g_bNoShakeGlobal || g_bNoShake[players[0]]))
|
|
||||||
return Plugin_Handled;
|
|
||||||
else
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Shake(int client, int args)
|
|
||||||
{
|
|
||||||
if(g_bNoShakeGlobal)
|
|
||||||
return Plugin_Handled;
|
|
||||||
|
|
||||||
if(!AreClientCookiesCached(client))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "\x03[NoShake]\x01 Please wait. Your settings are still loading.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(g_bNoShake[client])
|
|
||||||
{
|
|
||||||
g_bNoShake[client] = false;
|
|
||||||
ReplyToCommand(client, "\x03[NoShake]\x01 has been disabled!");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_bNoShake[client] = true;
|
|
||||||
ReplyToCommand(client, "\x03[NoShake]\x01 has been enabled!");
|
|
||||||
}
|
|
||||||
|
|
||||||
static char sCookieValue[2];
|
|
||||||
IntToString(g_bNoShake[client], sCookieValue, sizeof(sCookieValue));
|
|
||||||
SetClientCookie(client, g_hNoShakeCookie, sCookieValue);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
@ -1,339 +0,0 @@
|
|||||||
#include <sourcemod>
|
|
||||||
#include <sdkhooks>
|
|
||||||
#include <dhooks>
|
|
||||||
#undef REQUIRE_PLUGIN
|
|
||||||
#include <zombiereloaded>
|
|
||||||
#define REQUIRE_PLUGIN
|
|
||||||
|
|
||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "PlayerVisibility",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Fades players away when you get close to them.",
|
|
||||||
version = "1.2",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
// bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID )
|
|
||||||
Handle g_hAcceptInput;
|
|
||||||
|
|
||||||
ConVar g_CVar_MaxDistance;
|
|
||||||
ConVar g_CVar_MinFactor;
|
|
||||||
ConVar g_CVar_MinAlpha;
|
|
||||||
ConVar g_CVar_MinPlayers;
|
|
||||||
|
|
||||||
float g_fMaxDistance;
|
|
||||||
float g_fMinFactor;
|
|
||||||
float g_fMinAlpha;
|
|
||||||
int g_iMinPlayers;
|
|
||||||
|
|
||||||
int g_Client_Alpha[MAXPLAYERS + 1] = {255, ...};
|
|
||||||
bool g_Client_bEnabled[MAXPLAYERS + 1] = {false, ...};
|
|
||||||
|
|
||||||
bool g_Plugin_zombiereloaded = false;
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
Handle hGameConf = LoadGameConfigFile("sdktools.games");
|
|
||||||
if(hGameConf == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
SetFailState("Couldn't load sdktools game config!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Offset = GameConfGetOffset(hGameConf, "AcceptInput");
|
|
||||||
g_hAcceptInput = DHookCreate(Offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, AcceptInput);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_CharPtr);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_Object, 20, DHookPass_ByVal|DHookPass_ODTOR|DHookPass_OCTOR|DHookPass_OASSIGNOP); //varaint_t is a union of 12 (float[3]) plus two int type params 12 + 8 = 20
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_Int);
|
|
||||||
|
|
||||||
CloseHandle(hGameConf);
|
|
||||||
|
|
||||||
g_CVar_MaxDistance = CreateConVar("sm_pvis_maxdistance", "100.0", "Distance at which models stop fading.", 0, true, 0.0);
|
|
||||||
g_fMaxDistance = g_CVar_MaxDistance.FloatValue;
|
|
||||||
g_CVar_MaxDistance.AddChangeHook(OnConVarChanged);
|
|
||||||
|
|
||||||
g_CVar_MinFactor = CreateConVar("sm_pvis_minfactor", "0.75", "Smallest allowed alpha factor per client.", 0, true, 0.0, true, 1.0);
|
|
||||||
g_fMinFactor = g_CVar_MinFactor.FloatValue;
|
|
||||||
g_CVar_MinFactor.AddChangeHook(OnConVarChanged);
|
|
||||||
|
|
||||||
g_CVar_MinAlpha = CreateConVar("sm_pvis_minalpha", "75.0", "Minimum allowed alpha value.", 0, true, 0.0, true, 255.0);
|
|
||||||
g_fMinAlpha = g_CVar_MinAlpha.FloatValue;
|
|
||||||
g_CVar_MinAlpha.AddChangeHook(OnConVarChanged);
|
|
||||||
|
|
||||||
g_CVar_MinPlayers = CreateConVar("sm_pvis_minplayers", "3.0", "Minimum players within distance to enable fading.", 0, true, 0.0, true, 255.0);
|
|
||||||
g_iMinPlayers = g_CVar_MinPlayers.IntValue;
|
|
||||||
g_CVar_MinPlayers.AddChangeHook(OnConVarChanged);
|
|
||||||
|
|
||||||
AutoExecConfig(true, "plugin.PlayerVisibility");
|
|
||||||
|
|
||||||
HookEvent("player_spawn", Event_Spawn, EventHookMode_Post);
|
|
||||||
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(client))
|
|
||||||
OnClientPutInServer(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnAllPluginsLoaded()
|
|
||||||
{
|
|
||||||
g_Plugin_zombiereloaded = LibraryExists("zombiereloaded");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginEnd()
|
|
||||||
{
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(client))
|
|
||||||
{
|
|
||||||
if(g_Client_bEnabled[client] && g_Client_Alpha[client] != 255.0)
|
|
||||||
SetEntityRenderMode(client, RENDER_NORMAL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
|
||||||
{
|
|
||||||
if(convar == g_CVar_MaxDistance)
|
|
||||||
g_fMaxDistance = g_CVar_MaxDistance.FloatValue;
|
|
||||||
|
|
||||||
else if(convar == g_CVar_MinFactor)
|
|
||||||
g_fMinFactor = g_CVar_MinFactor.FloatValue;
|
|
||||||
|
|
||||||
else if(convar == g_CVar_MinAlpha)
|
|
||||||
g_fMinAlpha = g_CVar_MinAlpha.FloatValue;
|
|
||||||
|
|
||||||
else if(convar == g_CVar_MinPlayers)
|
|
||||||
g_iMinPlayers = g_CVar_MinPlayers.IntValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPutInServer(int client)
|
|
||||||
{
|
|
||||||
g_Client_Alpha[client] = 255;
|
|
||||||
g_Client_bEnabled[client] = true;
|
|
||||||
|
|
||||||
SDKHook(client, SDKHook_PostThinkPost, OnPostThinkPost);
|
|
||||||
DHookEntity(g_hAcceptInput, false, client);
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID )
|
|
||||||
public MRESReturn AcceptInput(int pThis, Handle hReturn, Handle hParams)
|
|
||||||
{
|
|
||||||
// Should not happen?
|
|
||||||
if(DHookIsNullParam(hParams, 2))
|
|
||||||
return MRES_Ignored;
|
|
||||||
|
|
||||||
int client = EntRefToEntIndex(DHookGetParam(hParams, 2));
|
|
||||||
if(client < 1 || client > MAXPLAYERS)
|
|
||||||
return MRES_Ignored;
|
|
||||||
|
|
||||||
if(!g_Client_bEnabled[client])
|
|
||||||
return MRES_Ignored;
|
|
||||||
|
|
||||||
char szInputName[32];
|
|
||||||
DHookGetParamString(hParams, 1, szInputName, sizeof(szInputName));
|
|
||||||
|
|
||||||
if(!StrEqual(szInputName, "addoutput", false))
|
|
||||||
return MRES_Ignored;
|
|
||||||
|
|
||||||
char sValue[128];
|
|
||||||
DHookGetParamObjectPtrString(hParams, 4, 0, ObjectValueType_String, sValue, sizeof(sValue));
|
|
||||||
int iValueLen = strlen(sValue);
|
|
||||||
|
|
||||||
int aArgs[4] = {0, ...};
|
|
||||||
int iArgs = 0;
|
|
||||||
bool bFound = false;
|
|
||||||
|
|
||||||
for(int i = 0; i < iValueLen; i++)
|
|
||||||
{
|
|
||||||
if(sValue[i] == ' ')
|
|
||||||
{
|
|
||||||
if(bFound)
|
|
||||||
{
|
|
||||||
sValue[i] = '\0';
|
|
||||||
bFound = false;
|
|
||||||
|
|
||||||
if(iArgs > sizeof(aArgs))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!bFound)
|
|
||||||
{
|
|
||||||
aArgs[iArgs++] = i;
|
|
||||||
bFound = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(StrEqual(szInputName, "addoutput", false))
|
|
||||||
{
|
|
||||||
if(StrEqual(sValue[aArgs[0]], "rendermode", false))
|
|
||||||
{
|
|
||||||
RenderMode renderMode = view_as<RenderMode>(StringToInt(sValue[aArgs[1]]) & 0xFF);
|
|
||||||
if(renderMode == RENDER_ENVIRONMENTAL)
|
|
||||||
{
|
|
||||||
ToolsSetEntityAlpha(client, 255);
|
|
||||||
g_Client_Alpha[client] = 255;
|
|
||||||
g_Client_bEnabled[client] = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_Client_bEnabled[client] = true;
|
|
||||||
}
|
|
||||||
else if(StrEqual(sValue[aArgs[0]], "renderfx", false))
|
|
||||||
{
|
|
||||||
RenderFx renderFx = view_as<RenderFx>(StringToInt(sValue[aArgs[1]]) & 0xFF);
|
|
||||||
if(renderFx != RENDERFX_NONE)
|
|
||||||
{
|
|
||||||
ToolsSetEntityAlpha(client, 255);
|
|
||||||
g_Client_Alpha[client] = 255;
|
|
||||||
g_Client_bEnabled[client] = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_Client_bEnabled[client] = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(StrEqual(szInputName, "alpha", false))
|
|
||||||
{
|
|
||||||
int iAlpha = StringToInt(sValue[aArgs[0]]) & 0xFF;
|
|
||||||
if(iAlpha == 0)
|
|
||||||
{
|
|
||||||
ToolsSetEntityAlpha(client, 255);
|
|
||||||
g_Client_Alpha[client] = 255;
|
|
||||||
g_Client_bEnabled[client] = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
g_Client_bEnabled[client] = true;
|
|
||||||
return MRES_Supercede;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return MRES_Ignored;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Event_Spawn(Event event, const char[] name, bool dontBroadcast)
|
|
||||||
{
|
|
||||||
int client = GetClientOfUserId(GetEventInt(event, "userid"));
|
|
||||||
if(!client)
|
|
||||||
return;
|
|
||||||
|
|
||||||
CreateTimer(0.1, Timer_SpawnPost, client, TIMER_FLAG_NO_MAPCHANGE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Timer_SpawnPost(Handle timer, int client)
|
|
||||||
{
|
|
||||||
if(!IsClientInGame(client) || !IsPlayerAlive(client))
|
|
||||||
return Plugin_Stop;
|
|
||||||
|
|
||||||
ToolsSetEntityAlpha(client, 255);
|
|
||||||
g_Client_Alpha[client] = 255;
|
|
||||||
g_Client_bEnabled[client] = true;
|
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
|
|
||||||
{
|
|
||||||
ToolsSetEntityAlpha(client, 255);
|
|
||||||
g_Client_Alpha[client] = 255;
|
|
||||||
g_Client_bEnabled[client] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ZR_OnClientHumanPost(int client, bool respawn, bool protect)
|
|
||||||
{
|
|
||||||
ToolsSetEntityAlpha(client, 255);
|
|
||||||
g_Client_Alpha[client] = 255;
|
|
||||||
g_Client_bEnabled[client] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPostThinkPost(int client)
|
|
||||||
{
|
|
||||||
if(!g_Client_bEnabled[client])
|
|
||||||
return;
|
|
||||||
|
|
||||||
int PlayersInRange = 0;
|
|
||||||
float fAlpha = 255.0;
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(i == client || !IsClientInGame(i) || !IsPlayerAlive(i))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(g_Plugin_zombiereloaded && !ZR_IsClientHuman(i))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
static float fVec1[3];
|
|
||||||
static float fVec2[3];
|
|
||||||
GetClientAbsOrigin(client, fVec1);
|
|
||||||
GetClientAbsOrigin(i, fVec2);
|
|
||||||
|
|
||||||
float fDistance = GetVectorDistance(fVec1, fVec2, false);
|
|
||||||
if(fDistance <= g_fMaxDistance)
|
|
||||||
{
|
|
||||||
PlayersInRange++;
|
|
||||||
|
|
||||||
float fFactor = fDistance / g_fMaxDistance;
|
|
||||||
if(fFactor < g_fMinFactor)
|
|
||||||
fFactor = g_fMinFactor;
|
|
||||||
|
|
||||||
fAlpha *= fFactor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(fAlpha < g_fMinAlpha)
|
|
||||||
fAlpha = g_fMinAlpha;
|
|
||||||
|
|
||||||
if(PlayersInRange < g_iMinPlayers)
|
|
||||||
fAlpha = 255.0;
|
|
||||||
|
|
||||||
int Alpha = RoundToNearest(fAlpha);
|
|
||||||
|
|
||||||
if(Alpha == g_Client_Alpha[client])
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_Client_Alpha[client] = Alpha;
|
|
||||||
ToolsSetEntityAlpha(client, Alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void ToolsSetEntityAlpha(int client, int Alpha)
|
|
||||||
{
|
|
||||||
if(Alpha == 255)
|
|
||||||
{
|
|
||||||
SetEntityRenderMode(client, RENDER_NORMAL);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int aColor[4];
|
|
||||||
ToolsGetEntityColor(client, aColor);
|
|
||||||
|
|
||||||
SetEntityRenderMode(client, RENDER_TRANSCOLOR);
|
|
||||||
SetEntityRenderColor(client, aColor[0], aColor[1], aColor[2], Alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void ToolsGetEntityColor(int entity, int aColor[4])
|
|
||||||
{
|
|
||||||
static bool s_GotConfig = false;
|
|
||||||
static char s_sProp[32];
|
|
||||||
|
|
||||||
if(!s_GotConfig)
|
|
||||||
{
|
|
||||||
Handle GameConf = LoadGameConfigFile("core.games");
|
|
||||||
bool Exists = GameConfGetKeyValue(GameConf, "m_clrRender", s_sProp, sizeof(s_sProp));
|
|
||||||
CloseHandle(GameConf);
|
|
||||||
|
|
||||||
if(!Exists)
|
|
||||||
strcopy(s_sProp, sizeof(s_sProp), "m_clrRender");
|
|
||||||
|
|
||||||
s_GotConfig = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Offset = GetEntSendPropOffs(entity, s_sProp);
|
|
||||||
|
|
||||||
for(int i = 0; i < 4; i++)
|
|
||||||
aColor[i] = GetEntData(entity, Offset + i, 1) & 0xFF;
|
|
||||||
}
|
|
@ -1,139 +0,0 @@
|
|||||||
"PointServerCommandFilter"
|
|
||||||
{
|
|
||||||
"say" {}
|
|
||||||
"exec" {}
|
|
||||||
"echo" {}
|
|
||||||
|
|
||||||
// sv_*
|
|
||||||
"sv_enablebunnyhopping" {}
|
|
||||||
"sv_airaccelerate" {}
|
|
||||||
"sv_turbophysics" {}
|
|
||||||
"sv_gravity"
|
|
||||||
{
|
|
||||||
"allow"
|
|
||||||
{
|
|
||||||
"min" "100"
|
|
||||||
"max" "1000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"sv_accelerate"
|
|
||||||
{
|
|
||||||
"clamp"
|
|
||||||
{
|
|
||||||
"min" "-5"
|
|
||||||
"max" "5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"sv_friction"
|
|
||||||
{
|
|
||||||
"clamp"
|
|
||||||
{
|
|
||||||
"min" "0"
|
|
||||||
"max" "4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"phys_pushscale"
|
|
||||||
{
|
|
||||||
"clamp"
|
|
||||||
{
|
|
||||||
"min" "0"
|
|
||||||
"max" "5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// mp_ *
|
|
||||||
"mp_freezetime"
|
|
||||||
{
|
|
||||||
"clamp"
|
|
||||||
{
|
|
||||||
"min" "0"
|
|
||||||
"max" "6"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"mp_restartgame"
|
|
||||||
{
|
|
||||||
"clamp"
|
|
||||||
{
|
|
||||||
"value" "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"mp_roundtime"
|
|
||||||
{
|
|
||||||
"clamp"
|
|
||||||
{
|
|
||||||
"min" "1"
|
|
||||||
"max" "60"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"mp_timelimit"
|
|
||||||
{
|
|
||||||
"clamp"
|
|
||||||
{
|
|
||||||
"min" "25"
|
|
||||||
"max" "85"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// sm_*
|
|
||||||
"sm_gravity" {}
|
|
||||||
"sm_freeze" {}
|
|
||||||
"sm_timebomb" {}
|
|
||||||
"sm_firebomb" {}
|
|
||||||
"sm_freezebomb" {}
|
|
||||||
"sm_slay" {}
|
|
||||||
"sm_say" {}
|
|
||||||
"sm_csay" {}
|
|
||||||
"sm_tsay" {}
|
|
||||||
"sm_hsay" {}
|
|
||||||
"sm_setcooldown" {}
|
|
||||||
|
|
||||||
"sm_startrace" {}
|
|
||||||
"sm_endrace" {}
|
|
||||||
"sm_cancelrace" {}
|
|
||||||
"sm_makovote" {}
|
|
||||||
|
|
||||||
// mce_*
|
|
||||||
"mce_extend"
|
|
||||||
{
|
|
||||||
"clamp"
|
|
||||||
{
|
|
||||||
"min" "1"
|
|
||||||
"max" "4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// zr_*
|
|
||||||
"zr_class_modify" {}
|
|
||||||
"zr_class_reload" {}
|
|
||||||
"zr_config_reload" {}
|
|
||||||
"zr_restrict" {}
|
|
||||||
"zr_unrestrict" {}
|
|
||||||
"zr_ambientsounds" {}
|
|
||||||
"zr_ambientsounds_file" {}
|
|
||||||
"zr_ambientsounds_volume" {}
|
|
||||||
"zr_ambientsounds_length" {}
|
|
||||||
"zr_roundend_overlay" {}
|
|
||||||
"zr_roundend_overlays_human" {}
|
|
||||||
"zr_roundend_overlays_zombie" {}
|
|
||||||
"zr_respawn" {}
|
|
||||||
"zr_respawn_delay"
|
|
||||||
{
|
|
||||||
"clamp"
|
|
||||||
{
|
|
||||||
"min" "5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"zr_infect_mzombie_ratio" {}
|
|
||||||
"zr_infect_mzombie_respawn" {}
|
|
||||||
"zr_infect_spawntime_min" {}
|
|
||||||
"zr_infect_spawntime_max" {}
|
|
||||||
"zr_infect_sound" {}
|
|
||||||
"zr_ztele_zombie" {}
|
|
||||||
"zr_ztele_human_before" {}
|
|
||||||
"zr_ztele_human_after" {}
|
|
||||||
"zr_ztele_delay_zombie" {}
|
|
||||||
"zr_ztele_delay_human" {}
|
|
||||||
"zr_ztele_max_zombie" {}
|
|
||||||
"zr_ztele_max_human" {}
|
|
||||||
"zr_ztele_autocancel" {}
|
|
||||||
}
|
|
@ -1,74 +0,0 @@
|
|||||||
// Example config to showcase features
|
|
||||||
// This is a whitelist
|
|
||||||
"PointServerCommandFilter"
|
|
||||||
{
|
|
||||||
// Allow all
|
|
||||||
"say" {}
|
|
||||||
"exec" {}
|
|
||||||
|
|
||||||
// Allow "1"
|
|
||||||
mp_restartgame "1"
|
|
||||||
|
|
||||||
// Regex: Allow all cvars/commands that start with mp_
|
|
||||||
"/mp_.*/" {}
|
|
||||||
|
|
||||||
// Allow regex as paramter
|
|
||||||
"echo" "/DEBUG:.*/"
|
|
||||||
|
|
||||||
// Allow anything but
|
|
||||||
"sm"
|
|
||||||
{
|
|
||||||
"allow" {}
|
|
||||||
"deny"
|
|
||||||
{
|
|
||||||
"value" "/plugins unload/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Allow the following
|
|
||||||
"sm"
|
|
||||||
{
|
|
||||||
"allow"
|
|
||||||
{
|
|
||||||
"value" "/plugins unload/"
|
|
||||||
"value" "/plugins load/"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// also like this
|
|
||||||
"sm"
|
|
||||||
{
|
|
||||||
"allow" "/plugins unload/"
|
|
||||||
"allow" "/plugins load/"
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only allow values between (including) 100 and 1000
|
|
||||||
"sv_gravity"
|
|
||||||
{
|
|
||||||
"allow"
|
|
||||||
{
|
|
||||||
"min" "100"
|
|
||||||
"max" "1000"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only allow values between 0 and 6,
|
|
||||||
// clamping if parmeter is outside of this range
|
|
||||||
// Example: 10 becomes 6 | -1 becomes 0
|
|
||||||
"mp_freezetime"
|
|
||||||
{
|
|
||||||
"clamp"
|
|
||||||
{
|
|
||||||
"min" "0"
|
|
||||||
"max" "6"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Override since clamp has no paramters
|
|
||||||
"mp_restartgame"
|
|
||||||
{
|
|
||||||
"clamp"
|
|
||||||
{
|
|
||||||
"value" "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,592 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
#include <cstrike>
|
|
||||||
#include <regex>
|
|
||||||
#include <dhooks>
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#define COMMAND_SIZE 1024
|
|
||||||
|
|
||||||
// bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID )
|
|
||||||
Handle g_hAcceptInput;
|
|
||||||
|
|
||||||
StringMap g_Rules;
|
|
||||||
ArrayList g_aRules;
|
|
||||||
ArrayList g_Regexes;
|
|
||||||
ArrayList g_RegexRules;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
MODE_NONE = 0,
|
|
||||||
MODE_ALL = 1,
|
|
||||||
MODE_STRVALUE = 2,
|
|
||||||
MODE_INTVALUE = 4,
|
|
||||||
MODE_FLOATVALUE = 8,
|
|
||||||
MODE_REGEXVALUE = 16,
|
|
||||||
|
|
||||||
MODE_MIN = 32,
|
|
||||||
MODE_MAX = 64,
|
|
||||||
|
|
||||||
MODE_ALLOW = 128,
|
|
||||||
MODE_DENY = 256, // Reverse
|
|
||||||
MODE_CLAMP = 512,
|
|
||||||
|
|
||||||
STATE_NONE = 0,
|
|
||||||
STATE_ALLOW = 1,
|
|
||||||
STATE_DENY = 2,
|
|
||||||
STATE_CLAMPMIN = 4,
|
|
||||||
STATE_CLAMPMAX = 8
|
|
||||||
};
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "PointServerCommandFilter",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Filters point_servercommand->Command() using user-defined rules to restrict maps.",
|
|
||||||
version = "1.0",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
Handle hGameConf = LoadGameConfigFile("sdktools.games");
|
|
||||||
if(hGameConf == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
SetFailState("Couldn't load sdktools game config!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Offset = GameConfGetOffset(hGameConf, "AcceptInput");
|
|
||||||
g_hAcceptInput = DHookCreate(Offset, HookType_Entity, ReturnType_Bool, ThisPointer_CBaseEntity, AcceptInput);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_CharPtr);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_CBaseEntity);
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_Object, 20, DHookPass_ByVal|DHookPass_ODTOR|DHookPass_OCTOR|DHookPass_OASSIGNOP); //varaint_t is a union of 12 (float[3]) plus two int type params 12 + 8 = 20
|
|
||||||
DHookAddParam(g_hAcceptInput, HookParamType_Int);
|
|
||||||
|
|
||||||
CloseHandle(hGameConf);
|
|
||||||
|
|
||||||
/* Late Load */
|
|
||||||
int entity = INVALID_ENT_REFERENCE;
|
|
||||||
while((entity = FindEntityByClassname(entity, "point_servercommand")) != INVALID_ENT_REFERENCE)
|
|
||||||
{
|
|
||||||
OnEntityCreated(entity, "point_servercommand");
|
|
||||||
}
|
|
||||||
|
|
||||||
LoadConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnEntityCreated(int entity, const char[] classname)
|
|
||||||
{
|
|
||||||
if(StrEqual(classname, "point_servercommand"))
|
|
||||||
{
|
|
||||||
DHookEntity(g_hAcceptInput, false, entity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// bool CBaseEntity::AcceptInput( const char *szInputName, CBaseEntity *pActivator, CBaseEntity *pCaller, variant_t Value, int outputID )
|
|
||||||
public MRESReturn AcceptInput(int pThis, Handle hReturn, Handle hParams)
|
|
||||||
{
|
|
||||||
char szInputName[128];
|
|
||||||
DHookGetParamString(hParams, 1, szInputName, sizeof(szInputName));
|
|
||||||
|
|
||||||
if(!StrEqual(szInputName, "Command", false))
|
|
||||||
return MRES_Ignored;
|
|
||||||
|
|
||||||
int client = 0;
|
|
||||||
if(!DHookIsNullParam(hParams, 2))
|
|
||||||
client = DHookGetParam(hParams, 2);
|
|
||||||
|
|
||||||
char sCommand[COMMAND_SIZE];
|
|
||||||
DHookGetParamObjectPtrString(hParams, 4, 0, ObjectValueType_String, sCommand, sizeof(sCommand));
|
|
||||||
|
|
||||||
int bReplaced = 0;
|
|
||||||
if(client > 0 && client <= MaxClients && IsClientInGame(client))
|
|
||||||
{
|
|
||||||
char sName[MAX_NAME_LENGTH];
|
|
||||||
GetClientName(client, sName, sizeof(sName));
|
|
||||||
|
|
||||||
char sSteamId[32];
|
|
||||||
GetClientAuthId(client, AuthId_Engine, sSteamId, sizeof(sSteamId));
|
|
||||||
|
|
||||||
char sUserID[32];
|
|
||||||
FormatEx(sUserID, sizeof(sUserID), "#%d", GetClientUserId(client));
|
|
||||||
|
|
||||||
char sTeam[32];
|
|
||||||
if(GetClientTeam(client) == CS_TEAM_CT)
|
|
||||||
strcopy(sTeam, sizeof(sTeam), "@ct");
|
|
||||||
else if(GetClientTeam(client) == CS_TEAM_T)
|
|
||||||
strcopy(sTeam, sizeof(sTeam), "@t");
|
|
||||||
|
|
||||||
bReplaced += ReplaceString(sCommand, sizeof(sCommand), "!activator.name", sName, false);
|
|
||||||
bReplaced += ReplaceString(sCommand, sizeof(sCommand), "!activator.steamid", sSteamId, false);
|
|
||||||
bReplaced += ReplaceString(sCommand, sizeof(sCommand), "!activator.team", sTeam, false);
|
|
||||||
bReplaced += ReplaceString(sCommand, sizeof(sCommand), "!activator", sUserID, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
Action iAction = PointServerCommandForward(sCommand);
|
|
||||||
|
|
||||||
if(iAction == Plugin_Stop)
|
|
||||||
{
|
|
||||||
DHookSetReturn(hReturn, false);
|
|
||||||
return MRES_Supercede;
|
|
||||||
}
|
|
||||||
else if(iAction == Plugin_Changed || GetEngineVersion() == Engine_CSGO || bReplaced)
|
|
||||||
{
|
|
||||||
ServerCommand(sCommand);
|
|
||||||
DHookSetReturn(hReturn, true);
|
|
||||||
return MRES_Supercede;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MRES_Ignored;
|
|
||||||
}
|
|
||||||
|
|
||||||
Action PointServerCommandForward(char[] sOrigCommand)
|
|
||||||
{
|
|
||||||
static char sCommandRight[1024];
|
|
||||||
static char sCommandLeft[128];
|
|
||||||
strcopy(sCommandRight, sizeof(sCommandRight), sOrigCommand);
|
|
||||||
TrimString(sCommandRight);
|
|
||||||
|
|
||||||
int Split = SplitString(sCommandRight, " ", sCommandLeft, sizeof(sCommandLeft));
|
|
||||||
if(Split == -1)
|
|
||||||
{
|
|
||||||
strcopy(sCommandLeft, sizeof(sCommandLeft), sCommandRight);
|
|
||||||
Split = 0;
|
|
||||||
}
|
|
||||||
TrimString(sCommandLeft);
|
|
||||||
strcopy(sCommandRight, sizeof(sCommandRight), sCommandRight[Split]);
|
|
||||||
|
|
||||||
StringToLower(sCommandLeft);
|
|
||||||
StringToLower(sCommandRight);
|
|
||||||
|
|
||||||
ArrayList RuleList;
|
|
||||||
if(g_Rules.GetValue(sCommandLeft, RuleList))
|
|
||||||
return MatchRuleList(RuleList, sOrigCommand, sCommandLeft, sCommandRight);
|
|
||||||
|
|
||||||
for(int i = 0; i < g_Regexes.Length; i++)
|
|
||||||
{
|
|
||||||
Regex hRegex = g_Regexes.Get(i);
|
|
||||||
if(MatchRegex(hRegex, sCommandLeft) > 0)
|
|
||||||
{
|
|
||||||
RuleList = g_RegexRules.Get(i);
|
|
||||||
return MatchRuleList(RuleList, sOrigCommand, sCommandLeft, sCommandRight);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogMessage("Blocked (No Rule): \"%s\"", sOrigCommand);
|
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
Action MatchRuleList(ArrayList RuleList, char[] sOrigCommand, const char[] sCommandLeft, const char[] sCommandRight)
|
|
||||||
{
|
|
||||||
for(int r = 0; r < RuleList.Length; r++)
|
|
||||||
{
|
|
||||||
int State = STATE_NONE;
|
|
||||||
StringMap Rule = RuleList.Get(r);
|
|
||||||
int Mode;
|
|
||||||
Rule.GetValue("mode", Mode);
|
|
||||||
bool IsNumeric = IsCharNumeric(sCommandRight[0]) || (sCommandRight[0] == '-' && IsCharNumeric(sCommandRight[1]));
|
|
||||||
|
|
||||||
if(Mode & MODE_ALL)
|
|
||||||
State |= STATE_ALLOW;
|
|
||||||
else if(Mode & MODE_STRVALUE)
|
|
||||||
{
|
|
||||||
static char sValue[512];
|
|
||||||
Rule.GetString("value", sValue, sizeof(sValue));
|
|
||||||
if(strcmp(sCommandRight, sValue) == 0)
|
|
||||||
State |= STATE_ALLOW;
|
|
||||||
}
|
|
||||||
else if(Mode & MODE_INTVALUE)
|
|
||||||
{
|
|
||||||
int WantValue;
|
|
||||||
int IsValue;
|
|
||||||
Rule.GetValue("value", WantValue);
|
|
||||||
IsValue = StringToInt(sCommandRight);
|
|
||||||
|
|
||||||
if(IsNumeric && WantValue == IsValue)
|
|
||||||
State |= STATE_ALLOW;
|
|
||||||
}
|
|
||||||
else if(Mode & MODE_FLOATVALUE)
|
|
||||||
{
|
|
||||||
float WantValue;
|
|
||||||
float IsValue;
|
|
||||||
Rule.GetValue("value", WantValue);
|
|
||||||
IsValue = StringToFloat(sCommandRight);
|
|
||||||
|
|
||||||
if(IsNumeric && FloatCompare(IsValue, WantValue) == 0)
|
|
||||||
State |= STATE_ALLOW;
|
|
||||||
}
|
|
||||||
else if(Mode & MODE_REGEXVALUE)
|
|
||||||
{
|
|
||||||
Regex hRegex;
|
|
||||||
Rule.GetValue("value", hRegex);
|
|
||||||
if(MatchRegex(hRegex, sCommandRight) > 0)
|
|
||||||
State |= STATE_ALLOW;
|
|
||||||
}
|
|
||||||
|
|
||||||
float MinValue;
|
|
||||||
float MaxValue;
|
|
||||||
float IsValue = StringToFloat(sCommandRight);
|
|
||||||
if(!IsNumeric && (Mode & MODE_MIN || Mode & MODE_MAX))
|
|
||||||
continue; // Ignore non-numerical
|
|
||||||
|
|
||||||
if(Mode & MODE_MIN)
|
|
||||||
{
|
|
||||||
Rule.GetValue("minvalue", MinValue);
|
|
||||||
|
|
||||||
if(IsValue >= MinValue)
|
|
||||||
State |= STATE_ALLOW;
|
|
||||||
else
|
|
||||||
State |= STATE_DENY | STATE_CLAMPMIN;
|
|
||||||
}
|
|
||||||
if(Mode & MODE_MAX)
|
|
||||||
{
|
|
||||||
Rule.GetValue("maxvalue", MaxValue);
|
|
||||||
|
|
||||||
if(IsValue <= MaxValue)
|
|
||||||
State |= STATE_ALLOW;
|
|
||||||
else
|
|
||||||
State |= STATE_DENY | STATE_CLAMPMAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reverse mode
|
|
||||||
if(Mode & MODE_DENY && State & STATE_ALLOW && !(State & STATE_DENY))
|
|
||||||
{
|
|
||||||
LogMessage("Blocked (Deny): \"%s\"", sOrigCommand);
|
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Clamping?
|
|
||||||
// If there is no clamp rule (State == STATE_NONE) try to clamp to "clampvalue"
|
|
||||||
// aka. always clamp to "clampvalue" if there are no rules in clamp mode
|
|
||||||
if(Mode & MODE_CLAMP && (State & STATE_DENY || State == STATE_NONE))
|
|
||||||
{
|
|
||||||
bool Clamp = false;
|
|
||||||
float ClampValue;
|
|
||||||
if(Rule.GetValue("clampvalue", ClampValue))
|
|
||||||
Clamp = true;
|
|
||||||
else if(State & STATE_CLAMPMIN)
|
|
||||||
{
|
|
||||||
ClampValue = MinValue;
|
|
||||||
Clamp = true;
|
|
||||||
}
|
|
||||||
else if(State & STATE_CLAMPMAX)
|
|
||||||
{
|
|
||||||
ClampValue = MaxValue;
|
|
||||||
Clamp = true;
|
|
||||||
}
|
|
||||||
if(Clamp)
|
|
||||||
{
|
|
||||||
LogMessage("Clamped (%f -> %f): \"%s\"", IsValue, ClampValue, sOrigCommand);
|
|
||||||
FormatEx(sOrigCommand, COMMAND_SIZE, "%s %f", sCommandLeft, ClampValue);
|
|
||||||
return Plugin_Changed;
|
|
||||||
}
|
|
||||||
else // Can this even happen? Yesh, dumb user. -> "clamp" {}
|
|
||||||
{
|
|
||||||
LogMessage("Blocked (!Clamp): \"%s\"", sOrigCommand);
|
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(Mode & MODE_CLAMP && State & STATE_ALLOW)
|
|
||||||
{
|
|
||||||
LogMessage("Allowed (Clamp): \"%s\"", sOrigCommand);
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Mode & MODE_ALLOW && State & STATE_ALLOW && !(State & STATE_DENY))
|
|
||||||
{
|
|
||||||
LogMessage("Allowed (Allow): \"%s\"", sOrigCommand);
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
LogMessage("Blocked (No Match): \"%s\"", sOrigCommand);
|
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Cleanup()
|
|
||||||
{
|
|
||||||
if(!g_Rules)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for(int i = 0; i < g_aRules.Length; i++)
|
|
||||||
{
|
|
||||||
ArrayList RuleList = g_aRules.Get(i);
|
|
||||||
CleanupRuleList(RuleList);
|
|
||||||
}
|
|
||||||
delete g_aRules;
|
|
||||||
delete g_Rules;
|
|
||||||
|
|
||||||
for(int i = 0; i < g_Regexes.Length; i++)
|
|
||||||
{
|
|
||||||
Regex hRegex = g_Regexes.Get(i);
|
|
||||||
delete hRegex;
|
|
||||||
|
|
||||||
ArrayList RuleList = g_RegexRules.Get(i);
|
|
||||||
CleanupRuleList(RuleList);
|
|
||||||
}
|
|
||||||
delete g_Regexes;
|
|
||||||
delete g_RegexRules;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CleanupRuleList(ArrayList RuleList)
|
|
||||||
{
|
|
||||||
for(int j = 0; j < RuleList.Length; j++)
|
|
||||||
{
|
|
||||||
StringMap Rule = RuleList.Get(j);
|
|
||||||
|
|
||||||
int Mode;
|
|
||||||
if(Rule.GetValue("mode", Mode))
|
|
||||||
{
|
|
||||||
if(Mode & MODE_REGEXVALUE)
|
|
||||||
{
|
|
||||||
Regex hRegex;
|
|
||||||
Rule.GetValue("value", hRegex);
|
|
||||||
delete hRegex;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
delete Rule;
|
|
||||||
}
|
|
||||||
delete RuleList;
|
|
||||||
}
|
|
||||||
|
|
||||||
void LoadConfig()
|
|
||||||
{
|
|
||||||
if(g_Rules)
|
|
||||||
Cleanup();
|
|
||||||
|
|
||||||
static char sConfigFile[PLATFORM_MAX_PATH];
|
|
||||||
BuildPath(Path_SM, sConfigFile, sizeof(sConfigFile), "configs/PointServerCommandFilter.cfg");
|
|
||||||
if(!FileExists(sConfigFile))
|
|
||||||
SetFailState("Could not find config: \"%s\"", sConfigFile);
|
|
||||||
|
|
||||||
KeyValues Config = new KeyValues("PointServerCommandFilter");
|
|
||||||
if(!Config.ImportFromFile(sConfigFile))
|
|
||||||
{
|
|
||||||
delete Config;
|
|
||||||
SetFailState("ImportFromFile() failed!");
|
|
||||||
}
|
|
||||||
if(!Config.GotoFirstSubKey(false))
|
|
||||||
{
|
|
||||||
delete Config;
|
|
||||||
SetFailState("GotoFirstSubKey() failed!");
|
|
||||||
}
|
|
||||||
|
|
||||||
g_Rules = new StringMap();
|
|
||||||
g_aRules = new ArrayList();
|
|
||||||
g_Regexes = new ArrayList();
|
|
||||||
g_RegexRules = new ArrayList();
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
static char sLeft[128];
|
|
||||||
Config.GetSectionName(sLeft, sizeof(sLeft));
|
|
||||||
StringToLower(sLeft);
|
|
||||||
int LeftLen = strlen(sLeft);
|
|
||||||
|
|
||||||
ArrayList RuleList;
|
|
||||||
|
|
||||||
if(sLeft[0] == '/' && sLeft[LeftLen - 1] == '/')
|
|
||||||
{
|
|
||||||
sLeft[LeftLen - 1] = 0;
|
|
||||||
Regex hRegex;
|
|
||||||
static char sError[512];
|
|
||||||
hRegex = CompileRegex(sLeft[1], PCRE_CASELESS, sError, sizeof(sError));
|
|
||||||
if(hRegex == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
LogError("Regex error from %s", sLeft);
|
|
||||||
LogError(sError);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RuleList = new ArrayList();
|
|
||||||
g_Regexes.Push(hRegex);
|
|
||||||
g_RegexRules.Push(RuleList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(!g_Rules.GetValue(sLeft, RuleList))
|
|
||||||
{
|
|
||||||
RuleList = new ArrayList();
|
|
||||||
g_Rules.SetValue(sLeft, RuleList);
|
|
||||||
g_aRules.Push(RuleList);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Section
|
|
||||||
if(Config.GotoFirstSubKey(false))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
static char sSection[128];
|
|
||||||
Config.GetSectionName(sSection, sizeof(sSection));
|
|
||||||
|
|
||||||
int Mode = MODE_NONE;
|
|
||||||
if(strcmp(sSection, "deny", false) == 0)
|
|
||||||
Mode |= MODE_DENY;
|
|
||||||
else if(strcmp(sSection, "allow", false) == 0)
|
|
||||||
Mode |= MODE_ALLOW;
|
|
||||||
else if(strcmp(sSection, "clamp", false) == 0)
|
|
||||||
Mode |= MODE_CLAMP;
|
|
||||||
|
|
||||||
// Section
|
|
||||||
if(Config.GotoFirstSubKey(false))
|
|
||||||
{
|
|
||||||
StringMap Rule = new StringMap();
|
|
||||||
int RuleMode = MODE_NONE;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
static char sKey[128];
|
|
||||||
Config.GetSectionName(sKey, sizeof(sKey));
|
|
||||||
|
|
||||||
if(strcmp(sKey, "min", false) == 0)
|
|
||||||
{
|
|
||||||
float Value = Config.GetFloat(NULL_STRING);
|
|
||||||
Rule.SetValue("minvalue", Value);
|
|
||||||
RuleMode |= MODE_MIN;
|
|
||||||
}
|
|
||||||
else if(strcmp(sKey, "max", false) == 0)
|
|
||||||
{
|
|
||||||
float Value = Config.GetFloat(NULL_STRING);
|
|
||||||
Rule.SetValue("maxvalue", Value);
|
|
||||||
RuleMode |= MODE_MAX;
|
|
||||||
}
|
|
||||||
else if(Mode & MODE_CLAMP)
|
|
||||||
{
|
|
||||||
float Value = Config.GetFloat(NULL_STRING);
|
|
||||||
Rule.SetValue("clampvalue", Value);
|
|
||||||
RuleMode |= MODE_CLAMP;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StringMap Rule_ = new StringMap();
|
|
||||||
if(ParseRule(Config, sLeft, Mode, Rule_))
|
|
||||||
RuleList.Push(Rule_);
|
|
||||||
else
|
|
||||||
delete Rule_;
|
|
||||||
}
|
|
||||||
} while(Config.GotoNextKey(false));
|
|
||||||
Config.GoBack();
|
|
||||||
|
|
||||||
if(RuleMode != MODE_NONE)
|
|
||||||
{
|
|
||||||
Rule.SetValue("mode", Mode | RuleMode);
|
|
||||||
RuleList.Push(Rule);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
delete Rule;
|
|
||||||
}
|
|
||||||
else // Value
|
|
||||||
{
|
|
||||||
StringMap Rule = new StringMap();
|
|
||||||
|
|
||||||
if(ParseRule(Config, sLeft, Mode, Rule))
|
|
||||||
RuleList.Push(Rule);
|
|
||||||
else
|
|
||||||
delete Rule;
|
|
||||||
}
|
|
||||||
|
|
||||||
} while(Config.GotoNextKey(false));
|
|
||||||
Config.GoBack();
|
|
||||||
}
|
|
||||||
else // Value
|
|
||||||
{
|
|
||||||
StringMap Rule = new StringMap();
|
|
||||||
|
|
||||||
if(ParseRule(Config, sLeft, MODE_ALLOW, Rule))
|
|
||||||
RuleList.Push(Rule);
|
|
||||||
else
|
|
||||||
delete Rule;
|
|
||||||
}
|
|
||||||
} while(Config.GotoNextKey(false));
|
|
||||||
delete Config;
|
|
||||||
|
|
||||||
for(int i = 0; i < g_aRules.Length; i++)
|
|
||||||
{
|
|
||||||
ArrayList RuleList = g_aRules.Get(i);
|
|
||||||
SortADTArrayCustom(RuleList, SortRuleList);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ParseRule(KeyValues Config, const char[] sLeft, int Mode, StringMap Rule)
|
|
||||||
{
|
|
||||||
static char sValue[512];
|
|
||||||
if(Config.GetDataType(NULL_STRING) == KvData_String)
|
|
||||||
{
|
|
||||||
Config.GetString(NULL_STRING, sValue, sizeof(sValue));
|
|
||||||
|
|
||||||
int ValueLen = strlen(sValue);
|
|
||||||
if(sValue[0] == '/' && sValue[ValueLen - 1] == '/')
|
|
||||||
{
|
|
||||||
sValue[ValueLen - 1] = 0;
|
|
||||||
Regex hRegex;
|
|
||||||
static char sError[512];
|
|
||||||
hRegex = CompileRegex(sValue[1], PCRE_CASELESS, sError, sizeof(sError));
|
|
||||||
if(hRegex == INVALID_HANDLE)
|
|
||||||
{
|
|
||||||
LogError("Regex error in %s from %s", sLeft, sValue[1]);
|
|
||||||
LogError(sError);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Rule.SetValue("mode", Mode | MODE_REGEXVALUE);
|
|
||||||
Rule.SetValue("value", hRegex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
StringToLower(sValue);
|
|
||||||
Rule.SetValue("mode", Mode | MODE_STRVALUE);
|
|
||||||
Rule.SetString("value", sValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if(Config.GetDataType(NULL_STRING) == KvData_Int)
|
|
||||||
{
|
|
||||||
int Value = Config.GetNum(NULL_STRING);
|
|
||||||
Rule.SetValue("mode", Mode | MODE_INTVALUE);
|
|
||||||
Rule.SetValue("value", Value);
|
|
||||||
}
|
|
||||||
else if(Config.GetDataType(NULL_STRING) == KvData_Float)
|
|
||||||
{
|
|
||||||
float Value = Config.GetFloat(NULL_STRING);
|
|
||||||
Rule.SetValue("mode", Mode | MODE_FLOATVALUE);
|
|
||||||
Rule.SetValue("value", Value);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
Rule.SetValue("mode", Mode | MODE_ALL);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int SortRuleList(int index1, int index2, Handle array, Handle hndl)
|
|
||||||
{
|
|
||||||
StringMap Rule1 = GetArrayCell(array, index1);
|
|
||||||
StringMap Rule2 = GetArrayCell(array, index2);
|
|
||||||
|
|
||||||
int Mode1;
|
|
||||||
int Mode2;
|
|
||||||
Rule1.GetValue("mode", Mode1);
|
|
||||||
Rule2.GetValue("mode", Mode2);
|
|
||||||
|
|
||||||
// Deny should be first
|
|
||||||
if(Mode1 & MODE_DENY && !(Mode2 & MODE_DENY))
|
|
||||||
return -1;
|
|
||||||
if(Mode2 & MODE_DENY && !(Mode1 & MODE_DENY))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
// Clamp should be last
|
|
||||||
if(Mode1 & MODE_CLAMP && !(Mode2 & MODE_CLAMP))
|
|
||||||
return 1;
|
|
||||||
if(Mode2 & MODE_CLAMP && !(Mode1 & MODE_CLAMP))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void StringToLower(char[] Str)
|
|
||||||
{
|
|
||||||
for(int i = 0; Str[i]; i++)
|
|
||||||
Str[i] = CharToLower(Str[i]);
|
|
||||||
}
|
|
@ -1,73 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdkhooks>
|
|
||||||
#include <zombiereloaded>
|
|
||||||
|
|
||||||
ConVar g_Cvar_QuickSwitch_Knife;
|
|
||||||
float g_flNextAttack[MAXPLAYERS + 1] = {0.0, ...};
|
|
||||||
bool g_bSetNextAttack[MAXPLAYERS + 1] = false;
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "Knife QuickSwitch",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Switching to knife without delay.",
|
|
||||||
version = "1.0",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
g_Cvar_QuickSwitch_Knife = CreateConVar("sm_quickswitch_knife", "1", "Enable Knife QuickSwitch.", 0, true, 0.0, true, 1.0);
|
|
||||||
|
|
||||||
AutoExecConfig(true, "plugin.QuickSwitch");
|
|
||||||
|
|
||||||
/* Handle late load */
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(client))
|
|
||||||
OnClientPutInServer(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPutInServer(int client)
|
|
||||||
{
|
|
||||||
g_flNextAttack[client] = 0.0;
|
|
||||||
g_bSetNextAttack[client] = false;
|
|
||||||
SDKHook(client, SDKHook_WeaponSwitch, OnWeaponSwitch);
|
|
||||||
SDKHook(client, SDKHook_WeaponSwitchPost, OnWeaponSwitchPost);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnWeaponSwitch(int client, int weapon)
|
|
||||||
{
|
|
||||||
if(!g_Cvar_QuickSwitch_Knife.BoolValue || !IsPlayerAlive(client) || ZR_IsClientZombie(client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
char sWeaponName[32];
|
|
||||||
GetEdictClassname(weapon, sWeaponName, sizeof(sWeaponName));
|
|
||||||
|
|
||||||
if(!StrEqual(sWeaponName, "weapon_knife"))
|
|
||||||
return;
|
|
||||||
|
|
||||||
float flNextPrimaryAttack = GetEntPropFloat(weapon, Prop_Data, "m_flNextPrimaryAttack");
|
|
||||||
float flNextSecondaryAttack = GetEntPropFloat(weapon, Prop_Data, "m_flNextSecondaryAttack");
|
|
||||||
|
|
||||||
if(flNextPrimaryAttack > g_flNextAttack[client])
|
|
||||||
g_flNextAttack[client] = flNextPrimaryAttack;
|
|
||||||
|
|
||||||
if(flNextSecondaryAttack > g_flNextAttack[client])
|
|
||||||
g_flNextAttack[client] = flNextSecondaryAttack;
|
|
||||||
|
|
||||||
g_bSetNextAttack[client] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnWeaponSwitchPost(int client, int weapon)
|
|
||||||
{
|
|
||||||
if(g_bSetNextAttack[client])
|
|
||||||
{
|
|
||||||
SetEntPropFloat(client, Prop_Send, "m_flNextAttack", g_flNextAttack[client]);
|
|
||||||
g_bSetNextAttack[client] = false;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "RoundTime",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Change roundtime instantly and remove limit.",
|
|
||||||
version = "1.0",
|
|
||||||
url = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
ConVar g_CVar_mp_roundtime;
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
g_CVar_mp_roundtime = FindConVar("mp_roundtime");
|
|
||||||
g_CVar_mp_roundtime.SetBounds(ConVarBound_Upper, true, 546.0); // empirically determined
|
|
||||||
g_CVar_mp_roundtime.AddChangeHook(OnConVarChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
|
||||||
{
|
|
||||||
GameRules_SetProp("m_iRoundTime", StringToInt(newValue) * 60);
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
"levels"
|
|
||||||
{
|
|
||||||
"0"
|
|
||||||
{
|
|
||||||
"name" "Level 0"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"DeleteOutput" "m_OnUser1 leveling_counter"
|
|
||||||
"DeleteOutput" "m_OnUser4 score10,ApplyScore"
|
|
||||||
"m_iFrags" "0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"name" "Level 1"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser1" "leveling_counter,Add,1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser1 leveling_counter,Add,1,0,-1"
|
|
||||||
"AddOutput" "OnUser4 score10,ApplyScore,,0,-1"
|
|
||||||
"m_iFrags" "10"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"name" "Level 2"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser1" "leveling_counter,Add,2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser1 leveling_counter,Add,2,0,-1"
|
|
||||||
"AddOutput" "OnUser4 score10,ApplyScore,,0,-1"
|
|
||||||
"AddOutput" "OnUser4 score10,ApplyScore,,0,-1"
|
|
||||||
"m_iFrags" "20"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"name" "Level 3"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser1" "leveling_counter,Add,3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser1 leveling_counter,Add,3,0,-1"
|
|
||||||
"AddOutput" "OnUser4 score10,ApplyScore,,0,-1"
|
|
||||||
"AddOutput" "OnUser4 score10,ApplyScore,,0,-1"
|
|
||||||
"AddOutput" "OnUser4 score10,ApplyScore,,0,-1"
|
|
||||||
"m_iFrags" "30"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
"levels"
|
|
||||||
{
|
|
||||||
"0"
|
|
||||||
{
|
|
||||||
"name" "Level 0"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"name" "Level 1"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"name" "Level 2"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "a"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "a"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"name" "Level 3"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "b"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "b"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
"levels"
|
|
||||||
{
|
|
||||||
"0"
|
|
||||||
{
|
|
||||||
"name" "Level 0"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"name" "Level 1"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" ""
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"name" "Level 2"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "a"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "a"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"name" "Level 3"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "b"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "b"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,60 +0,0 @@
|
|||||||
"levels"
|
|
||||||
{
|
|
||||||
"0"
|
|
||||||
{
|
|
||||||
"name" "Level 0"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"DeleteOutput" "m_OnUser4 Map_Level_Check"
|
|
||||||
"m_iFrags" "0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"name" "Level 1"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser4" "Map_Level_Check,Add,1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser4 Map_Level_Check,Add,1,0,-1"
|
|
||||||
"m_iFrags" "100"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"name" "Level 2"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser4" "Map_Level_Check,Add,2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser4 Map_Level_Check,Add,2,0,-1"
|
|
||||||
"m_iFrags" "200"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"name" "Level 3"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser4" "Map_Level_Check,Add,3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser4 Map_Level_Check,Add,3,0,-1"
|
|
||||||
"m_iFrags" "300"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,92 +0,0 @@
|
|||||||
"levels"
|
|
||||||
{
|
|
||||||
"0"
|
|
||||||
{
|
|
||||||
"name" "Level 0"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"DeleteOutput" "m_OnUser2 leveling_counter"
|
|
||||||
"m_iFrags" "0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"name" "Level 1"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser2" "leveling_counter,add,1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser2 leveling_counter,add,1,0,-1"
|
|
||||||
"m_iFrags" "100"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"name" "Level 2"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser2" "leveling_counter,add,2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser2 leveling_counter,add,2,0,-1"
|
|
||||||
"m_iFrags" "200"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"name" "Level 3"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser2" "leveling_counter,add,3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser2 leveling_counter,add,3,0,-1"
|
|
||||||
"m_iFrags" "300"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"4"
|
|
||||||
{
|
|
||||||
"name" "Level 4"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser2" "leveling_counter,add,4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser2 leveling_counter,add,4,0,-1"
|
|
||||||
"m_iFrags" "400"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"5"
|
|
||||||
{
|
|
||||||
"name" "Level 5"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser2" "leveling_counter,add,5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser2 leveling_counter,add,5,0,-1"
|
|
||||||
"m_iFrags" "500"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,92 +0,0 @@
|
|||||||
"levels"
|
|
||||||
{
|
|
||||||
"0"
|
|
||||||
{
|
|
||||||
"name" "Level 0"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" ""
|
|
||||||
"m_iFrags" "0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"name" "Level 1"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "Level_1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "Level_1"
|
|
||||||
"m_iFrags" "100"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"name" "Level 2"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "Level_2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "Level_2"
|
|
||||||
"m_iFrags" "200"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"name" "Level 3"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "Level_3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "Level_3"
|
|
||||||
"m_iFrags" "300"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"4"
|
|
||||||
{
|
|
||||||
"name" "Level 4"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "Level_4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "Level_4"
|
|
||||||
"m_iFrags" "400"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"5"
|
|
||||||
{
|
|
||||||
"name" "Level 5"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "Level_5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "Level_5"
|
|
||||||
"m_iFrags" "500"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
"levels"
|
|
||||||
{
|
|
||||||
"0"
|
|
||||||
{
|
|
||||||
"name" "Level 0"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" ""
|
|
||||||
"m_iFrags" "0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"name" "Level 1"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "1"
|
|
||||||
"m_iFrags" "100"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"name" "Level 2"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "2"
|
|
||||||
"m_iFrags" "200"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"name" "Level 3"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "3"
|
|
||||||
"m_iFrags" "300"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"4"
|
|
||||||
{
|
|
||||||
"name" "Level 4"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "4"
|
|
||||||
"m_iFrags" "400"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
"levels"
|
|
||||||
{
|
|
||||||
"0"
|
|
||||||
{
|
|
||||||
"name" "Level 0"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"DeleteOutput" "m_OnUser3 map_wandlevels"
|
|
||||||
"m_iFrags" "0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"name" "Level 1"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser3" "map_wandlevels,Add,1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser3 map_wandlevels,Add,1,0,-1"
|
|
||||||
"m_iFrags" "100"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"name" "Level 2"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser3" "map_wandlevels,Add,2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser3 map_wandlevels,Add,2,0,-1"
|
|
||||||
"m_iFrags" "200"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"name" "Level 3"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser3" "map_wandlevels,Add,3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser3 map_wandlevels,Add,3,0,-1"
|
|
||||||
"m_iFrags" "300"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"4"
|
|
||||||
{
|
|
||||||
"name" "Level 4"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser3" "map_wandlevels,Add,4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser3 map_wandlevels,Add,4,0,-1"
|
|
||||||
"m_iFrags" "400"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
"levels"
|
|
||||||
{
|
|
||||||
"0"
|
|
||||||
{
|
|
||||||
"name" "Level 0"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"DeleteOutput" "m_OnUser3 map_wandlevels"
|
|
||||||
"m_iFrags" "0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"name" "Level 1"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser3" "map_wandlevels,Add,1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser3 map_wandlevels,Add,1,0,-1"
|
|
||||||
"m_iFrags" "100"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"name" "Level 2"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser3" "map_wandlevels,Add,2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser3 map_wandlevels,Add,2,0,-1"
|
|
||||||
"m_iFrags" "200"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"name" "Level 3"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser3" "map_wandlevels,Add,3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser3 map_wandlevels,Add,3,0,-1"
|
|
||||||
"m_iFrags" "300"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"4"
|
|
||||||
{
|
|
||||||
"name" "Level 4"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"math"
|
|
||||||
{
|
|
||||||
"m_OnUser3" "map_wandlevels,Add,4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"AddOutput" "OnUser3 map_wandlevels,Add,4,0,-1"
|
|
||||||
"m_iFrags" "400"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,92 +0,0 @@
|
|||||||
"levels"
|
|
||||||
{
|
|
||||||
"0"
|
|
||||||
{
|
|
||||||
"name" "Level 0"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" ""
|
|
||||||
"m_iFrags" "0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"name" "Level 1"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "1"
|
|
||||||
"m_iFrags" "100"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"name" "Level 2"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "2"
|
|
||||||
"m_iFrags" "200"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"name" "Level 3"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "3"
|
|
||||||
"m_iFrags" "300"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"4"
|
|
||||||
{
|
|
||||||
"name" "Level 4"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "4"
|
|
||||||
"m_iFrags" "400"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"5"
|
|
||||||
{
|
|
||||||
"name" "Level 5"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "5"
|
|
||||||
"m_iFrags" "500"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,92 +0,0 @@
|
|||||||
"levels"
|
|
||||||
{
|
|
||||||
"0"
|
|
||||||
{
|
|
||||||
"name" "Level 0"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" ""
|
|
||||||
"m_iFrags" "0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"name" "Level 1"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "1"
|
|
||||||
"m_iFrags" "100"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"name" "Level 2"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "2"
|
|
||||||
"m_iFrags" "200"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"name" "Level 3"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "3"
|
|
||||||
"m_iFrags" "300"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"4"
|
|
||||||
{
|
|
||||||
"name" "Level 4"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "4"
|
|
||||||
"m_iFrags" "400"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"5"
|
|
||||||
{
|
|
||||||
"name" "Level 5"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "5"
|
|
||||||
"m_iFrags" "500"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,92 +0,0 @@
|
|||||||
"levels"
|
|
||||||
{
|
|
||||||
"0"
|
|
||||||
{
|
|
||||||
"name" "Level 0"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" ""
|
|
||||||
"m_iFrags" "0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"name" "Level 1"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "1"
|
|
||||||
"m_iFrags" "100"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"name" "Level 2"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "2"
|
|
||||||
"m_iFrags" "200"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"name" "Level 3"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "3"
|
|
||||||
"m_iFrags" "300"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"4"
|
|
||||||
{
|
|
||||||
"name" "Level 4"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "4"
|
|
||||||
"m_iFrags" "400"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"5"
|
|
||||||
{
|
|
||||||
"name" "Level 5"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "5"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "5"
|
|
||||||
"m_iFrags" "500"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
"levels"
|
|
||||||
{
|
|
||||||
"0"
|
|
||||||
{
|
|
||||||
"name" "Level 0"
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" ""
|
|
||||||
"m_iFrags" "0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"1"
|
|
||||||
{
|
|
||||||
"name" "Level 1"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "1"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "1"
|
|
||||||
"m_iFrags" "100"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"2"
|
|
||||||
{
|
|
||||||
"name" "Level 2"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "2"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "2"
|
|
||||||
"m_iFrags" "200"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"3"
|
|
||||||
{
|
|
||||||
"name" "Level 3"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "3"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "3"
|
|
||||||
"m_iFrags" "300"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"4"
|
|
||||||
{
|
|
||||||
"name" "Level 4"
|
|
||||||
"match"
|
|
||||||
{
|
|
||||||
"props"
|
|
||||||
{
|
|
||||||
"m_iName" "4"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"restore"
|
|
||||||
{
|
|
||||||
"m_iName" "4"
|
|
||||||
"m_iFrags" "400"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,521 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
#include <outputinfo>
|
|
||||||
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
StringMap g_PlayerLevels;
|
|
||||||
KeyValues g_Config;
|
|
||||||
KeyValues g_PropAltNames;
|
|
||||||
|
|
||||||
#define PLUGIN_VERSION "2.0"
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "SaveLevel",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Saves players level on maps when they disconnect and restore them on connect.",
|
|
||||||
version = PLUGIN_VERSION,
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
LoadTranslations("common.phrases");
|
|
||||||
|
|
||||||
g_PropAltNames = new KeyValues("PropAltNames");
|
|
||||||
g_PropAltNames.SetString("m_iName", "targetname");
|
|
||||||
|
|
||||||
RegAdminCmd("sm_level", Command_Level, ADMFLAG_GENERIC, "Set a players map level.");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginEnd()
|
|
||||||
{
|
|
||||||
if(g_Config)
|
|
||||||
delete g_Config;
|
|
||||||
if(g_PlayerLevels)
|
|
||||||
delete g_PlayerLevels;
|
|
||||||
delete g_PropAltNames;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMapStart()
|
|
||||||
{
|
|
||||||
if(g_Config)
|
|
||||||
delete g_Config;
|
|
||||||
if(g_PlayerLevels)
|
|
||||||
delete g_PlayerLevels;
|
|
||||||
|
|
||||||
char sMapName[PLATFORM_MAX_PATH];
|
|
||||||
GetCurrentMap(sMapName, sizeof(sMapName));
|
|
||||||
|
|
||||||
char sConfigFile[PLATFORM_MAX_PATH];
|
|
||||||
BuildPath(Path_SM, sConfigFile, sizeof(sConfigFile), "configs/savelevel/%s.cfg", sMapName);
|
|
||||||
if(!FileExists(sConfigFile))
|
|
||||||
{
|
|
||||||
LogMessage("Could not find mapconfig: \"%s\"", sConfigFile);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
LogMessage("Found mapconfig: \"%s\"", sConfigFile);
|
|
||||||
|
|
||||||
g_Config = new KeyValues("levels");
|
|
||||||
if(!g_Config.ImportFromFile(sConfigFile))
|
|
||||||
{
|
|
||||||
delete g_Config;
|
|
||||||
LogMessage("ImportFromFile() failed!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
g_Config.Rewind();
|
|
||||||
|
|
||||||
if(!g_Config.GotoFirstSubKey())
|
|
||||||
{
|
|
||||||
delete g_Config;
|
|
||||||
LogMessage("GotoFirstSubKey() failed!");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_PlayerLevels = new StringMap();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPostAdminCheck(int client)
|
|
||||||
{
|
|
||||||
if(!g_Config)
|
|
||||||
return;
|
|
||||||
|
|
||||||
char sSteamID[32];
|
|
||||||
GetClientAuthId(client, AuthId_Steam3, sSteamID, sizeof(sSteamID));
|
|
||||||
|
|
||||||
static char sTargets[128];
|
|
||||||
if(g_PlayerLevels.GetString(sSteamID, sTargets, sizeof(sTargets)))
|
|
||||||
{
|
|
||||||
g_PlayerLevels.Remove(sSteamID);
|
|
||||||
|
|
||||||
char sNames[128];
|
|
||||||
static char asTargets[4][32];
|
|
||||||
int Split = ExplodeString(sTargets, ";", asTargets, sizeof(asTargets), sizeof(asTargets[]));
|
|
||||||
|
|
||||||
int Found = 0;
|
|
||||||
for(int i = 0; i < Split; i++)
|
|
||||||
{
|
|
||||||
static char sName[32];
|
|
||||||
if(RestoreLevel(client, asTargets[i], sName, sizeof(sName)))
|
|
||||||
{
|
|
||||||
if(Found)
|
|
||||||
StrCat(sNames, sizeof(sNames), ", ");
|
|
||||||
Found++;
|
|
||||||
|
|
||||||
StrCat(sNames, sizeof(sNames), sName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(Found)
|
|
||||||
PrintToChatAll("\x03[SaveLevel]\x01 \x04%N\x01 has been restored to: \x04%s", client, sNames);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientDisconnect(int client)
|
|
||||||
{
|
|
||||||
if(!g_Config || !g_PlayerLevels || !IsClientInGame(client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
char sTargets[128];
|
|
||||||
if(GetLevel(client, sTargets, sizeof(sTargets)))
|
|
||||||
{
|
|
||||||
char sSteamID[32];
|
|
||||||
GetClientAuthId(client, AuthId_Steam3, sSteamID, sizeof(sSteamID));
|
|
||||||
g_PlayerLevels.SetString(sSteamID, sTargets, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RestoreLevel(int client, const char[] sTarget, char[] sName = NULL_STRING, int NameLen = 0)
|
|
||||||
{
|
|
||||||
g_Config.Rewind();
|
|
||||||
|
|
||||||
if(!g_Config.JumpToKey(sTarget))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(NameLen)
|
|
||||||
g_Config.GetString("name", sName, NameLen);
|
|
||||||
|
|
||||||
static char sKey[32];
|
|
||||||
static char sValue[1024];
|
|
||||||
|
|
||||||
if(!g_Config.JumpToKey("restore"))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(!g_Config.GotoFirstSubKey(false))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
g_Config.GetSectionName(sKey, sizeof(sKey));
|
|
||||||
g_Config.GetString(NULL_STRING, sValue, sizeof(sValue));
|
|
||||||
if(StrEqual(sKey, "AddOutput", false))
|
|
||||||
{
|
|
||||||
SetVariantString(sValue);
|
|
||||||
AcceptEntityInput(client, sKey, client, client);
|
|
||||||
}
|
|
||||||
else if(StrEqual(sKey, "DeleteOutput", false))
|
|
||||||
{
|
|
||||||
int Index;
|
|
||||||
// Output (e.g. m_OnUser1)
|
|
||||||
int Target = FindCharInString(sValue, ' ');
|
|
||||||
if(Target == -1)
|
|
||||||
{
|
|
||||||
while((Index = FindOutput(client, sValue, 0)) != -1)
|
|
||||||
DeleteOutput(client, sValue, Index);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
sValue[Target] = 0; Target++;
|
|
||||||
while(IsCharSpace(sValue[Target]))
|
|
||||||
Target++;
|
|
||||||
|
|
||||||
// Target (e.g. leveling_counter)
|
|
||||||
int Input = FindCharInString(sValue[Target], ',');
|
|
||||||
if(Input == -1)
|
|
||||||
{
|
|
||||||
while((Index = FindOutput(client, sValue, 0, sValue[Target])) != -1)
|
|
||||||
DeleteOutput(client, sValue, Index);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
sValue[Input] = 0; Input++;
|
|
||||||
|
|
||||||
// Input (e.g. add)
|
|
||||||
int Parameter = Input + FindCharInString(sValue[Input], ',');
|
|
||||||
if(Input == -1)
|
|
||||||
{
|
|
||||||
while((Index = FindOutput(client, sValue, 0, sValue[Target], sValue[Input])) != -1)
|
|
||||||
DeleteOutput(client, sValue, Index);
|
|
||||||
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
sValue[Parameter] = 0; Parameter++;
|
|
||||||
|
|
||||||
// Parameter (e.g. 1)
|
|
||||||
while((Index = FindOutput(client, sValue, 0, sValue[Target], sValue[Input], sValue[Parameter])) != -1)
|
|
||||||
DeleteOutput(client, sValue, Index);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
PropFieldType Type;
|
|
||||||
int NumBits;
|
|
||||||
int Offset = FindDataMapInfo(client, sKey, Type, NumBits);
|
|
||||||
if(Offset != -1)
|
|
||||||
{
|
|
||||||
if(Type == PropField_Integer)
|
|
||||||
{
|
|
||||||
int Value = StringToInt(sValue);
|
|
||||||
SetEntData(client, Offset, Value, NumBits / 8, false);
|
|
||||||
}
|
|
||||||
else if(Type == PropField_Float)
|
|
||||||
{
|
|
||||||
float Value = StringToFloat(sValue);
|
|
||||||
SetEntDataFloat(client, Offset, Value, false);
|
|
||||||
}
|
|
||||||
else if(Type == PropField_String)
|
|
||||||
{
|
|
||||||
SetEntDataString(client, Offset, sValue, strlen(sValue) + 1, false);
|
|
||||||
}
|
|
||||||
else if(Type == PropField_String_T)
|
|
||||||
{
|
|
||||||
static char sAltKey[32];
|
|
||||||
g_PropAltNames.GetString(sKey, sAltKey, sizeof(sAltKey), NULL_STRING);
|
|
||||||
if(sAltKey[0])
|
|
||||||
DispatchKeyValue(client, sAltKey, sValue);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(g_Config.GotoNextKey(false));
|
|
||||||
|
|
||||||
g_Config.Rewind();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GetLevel(int client, char[] sTargets, int TargetsLen, char[] sNames = NULL_STRING, int NamesLen = 0)
|
|
||||||
{
|
|
||||||
if(!g_Config || !g_PlayerLevels || !IsClientInGame(client))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
g_Config.Rewind();
|
|
||||||
g_Config.GotoFirstSubKey();
|
|
||||||
|
|
||||||
static char sTarget[32];
|
|
||||||
static char sName[32];
|
|
||||||
static char sKey[32];
|
|
||||||
static char sValue[1024];
|
|
||||||
static char sOutput[1024];
|
|
||||||
bool Found = false;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
g_Config.GetSectionName(sTarget, sizeof(sTarget));
|
|
||||||
g_Config.GetString("name", sName, sizeof(sName));
|
|
||||||
|
|
||||||
if(!g_Config.JumpToKey("match"))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int Matches = 0;
|
|
||||||
int ExactMatches = g_Config.GetNum("ExactMatches", -1);
|
|
||||||
int MinMatches = g_Config.GetNum("MinMatches", -1);
|
|
||||||
int MaxMatches = g_Config.GetNum("MaxMatches", -1);
|
|
||||||
|
|
||||||
if(!g_Config.GotoFirstSubKey(false))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
static char sSection[32];
|
|
||||||
g_Config.GetSectionName(sSection, sizeof(sSection));
|
|
||||||
|
|
||||||
if(StrEqual(sSection, "outputs"))
|
|
||||||
{
|
|
||||||
int _Matches = 0;
|
|
||||||
int _ExactMatches = g_Config.GetNum("ExactMatches", -1);
|
|
||||||
int _MinMatches = g_Config.GetNum("MinMatches", -1);
|
|
||||||
int _MaxMatches = g_Config.GetNum("MaxMatches", -1);
|
|
||||||
|
|
||||||
if(g_Config.GotoFirstSubKey(false))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
g_Config.GetSectionName(sKey, sizeof(sKey));
|
|
||||||
g_Config.GetString(NULL_STRING, sValue, sizeof(sValue));
|
|
||||||
|
|
||||||
int Count = GetOutputCount(client, sKey);
|
|
||||||
for(int i = 0; i < Count; i++)
|
|
||||||
{
|
|
||||||
GetOutputFormatted(client, sKey, i, sOutput, sizeof(sOutput));
|
|
||||||
sOutput[FindCharInString(sOutput, ',', true)] = 0;
|
|
||||||
sOutput[FindCharInString(sOutput, ',', true)] = 0;
|
|
||||||
|
|
||||||
if(StrEqual(sValue, sOutput))
|
|
||||||
_Matches++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(g_Config.GotoNextKey(false));
|
|
||||||
|
|
||||||
g_Config.GoBack();
|
|
||||||
}
|
|
||||||
g_Config.GoBack();
|
|
||||||
|
|
||||||
Matches += CalcMatches(_Matches, _ExactMatches, _MinMatches, _MaxMatches);
|
|
||||||
}
|
|
||||||
else if(StrEqual(sSection, "props"))
|
|
||||||
{
|
|
||||||
int _Matches = 0;
|
|
||||||
int _ExactMatches = g_Config.GetNum("ExactMatches", -1);
|
|
||||||
int _MinMatches = g_Config.GetNum("MinMatches", -1);
|
|
||||||
int _MaxMatches = g_Config.GetNum("MaxMatches", -1);
|
|
||||||
|
|
||||||
if(g_Config.GotoFirstSubKey(false))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
g_Config.GetSectionName(sKey, sizeof(sKey));
|
|
||||||
g_Config.GetString(NULL_STRING, sValue, sizeof(sValue));
|
|
||||||
|
|
||||||
GetEntPropString(client, Prop_Data, sKey, sOutput, sizeof(sOutput));
|
|
||||||
|
|
||||||
if(StrEqual(sValue, sOutput))
|
|
||||||
_Matches++;
|
|
||||||
}
|
|
||||||
while(g_Config.GotoNextKey(false));
|
|
||||||
|
|
||||||
g_Config.GoBack();
|
|
||||||
}
|
|
||||||
g_Config.GoBack();
|
|
||||||
|
|
||||||
Matches += CalcMatches(_Matches, _ExactMatches, _MinMatches, _MaxMatches);
|
|
||||||
}
|
|
||||||
else if(StrEqual(sSection, "math"))
|
|
||||||
{
|
|
||||||
if(g_Config.GotoFirstSubKey(false))
|
|
||||||
{
|
|
||||||
do
|
|
||||||
{
|
|
||||||
g_Config.GetSectionName(sKey, sizeof(sKey));
|
|
||||||
g_Config.GetString(NULL_STRING, sValue, sizeof(sValue));
|
|
||||||
|
|
||||||
int Target = 0;
|
|
||||||
int Input;
|
|
||||||
int Parameter;
|
|
||||||
|
|
||||||
Input = FindCharInString(sValue[Target], ',');
|
|
||||||
sValue[Input] = 0; Input++;
|
|
||||||
|
|
||||||
Parameter = Input + FindCharInString(sValue[Input], ',');
|
|
||||||
sValue[Parameter] = 0; Parameter++;
|
|
||||||
|
|
||||||
int Value = 0;
|
|
||||||
int Count = GetOutputCount(client, sKey);
|
|
||||||
for(int i = 0; i < Count; i++)
|
|
||||||
{
|
|
||||||
int _Target = 0;
|
|
||||||
int _Input;
|
|
||||||
int _Parameter;
|
|
||||||
|
|
||||||
_Input = GetOutputTarget(client, sKey, i, sOutput[_Target], sizeof(sOutput) - _Target);
|
|
||||||
sOutput[_Input] = 0; _Input++;
|
|
||||||
|
|
||||||
_Parameter = _Input + GetOutputTargetInput(client, sKey, i, sOutput[_Input], sizeof(sOutput) - _Input);
|
|
||||||
sOutput[_Parameter] = 0; _Parameter++;
|
|
||||||
|
|
||||||
GetOutputParameter(client, sKey, i, sOutput[_Parameter], sizeof(sOutput) - _Parameter);
|
|
||||||
|
|
||||||
if(!StrEqual(sOutput[_Target], sValue[Target]))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int _Value = StringToInt(sOutput[_Parameter]);
|
|
||||||
|
|
||||||
if(StrEqual(sOutput[_Input], "add", false))
|
|
||||||
Value += _Value;
|
|
||||||
else if(StrEqual(sOutput[_Input], "subtract", false))
|
|
||||||
Value -= _Value;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Result = StringToInt(sValue[Parameter]);
|
|
||||||
if(StrEqual(sValue[Input], "subtract", false))
|
|
||||||
Result *= -1;
|
|
||||||
|
|
||||||
if(Value == Result)
|
|
||||||
Matches += 1;
|
|
||||||
}
|
|
||||||
while(g_Config.GotoNextKey(false));
|
|
||||||
|
|
||||||
g_Config.GoBack();
|
|
||||||
}
|
|
||||||
g_Config.GoBack();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(g_Config.GotoNextKey(false));
|
|
||||||
|
|
||||||
g_Config.GoBack();
|
|
||||||
|
|
||||||
if(CalcMatches(Matches, ExactMatches, MinMatches, MaxMatches))
|
|
||||||
{
|
|
||||||
if(Found)
|
|
||||||
{
|
|
||||||
if(TargetsLen)
|
|
||||||
StrCat(sTargets, TargetsLen, ";");
|
|
||||||
if(NamesLen)
|
|
||||||
StrCat(sNames, NamesLen, ", ");
|
|
||||||
}
|
|
||||||
|
|
||||||
Found = true;
|
|
||||||
if(TargetsLen)
|
|
||||||
StrCat(sTargets, TargetsLen, sTarget);
|
|
||||||
if(NamesLen)
|
|
||||||
StrCat(sNames, NamesLen, sName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while(g_Config.GotoNextKey());
|
|
||||||
|
|
||||||
g_Config.Rewind();
|
|
||||||
if(!Found)
|
|
||||||
return false;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Level(int client, int args)
|
|
||||||
{
|
|
||||||
if(!g_Config)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] The current map is not supported.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(args < 2)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Usage: sm_level <target> <level>");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sTarget[MAX_TARGET_LENGTH];
|
|
||||||
char sTargetName[MAX_TARGET_LENGTH];
|
|
||||||
int iTargets[MAXPLAYERS];
|
|
||||||
int iTargetCount;
|
|
||||||
bool bIsML;
|
|
||||||
|
|
||||||
GetCmdArg(1, sTarget, sizeof(sTarget));
|
|
||||||
if((iTargetCount = ProcessTargetString(sTarget, client, iTargets, MAXPLAYERS, 0, sTargetName, sizeof(sTargetName), bIsML)) <= 0)
|
|
||||||
{
|
|
||||||
ReplyToTargetError(client, iTargetCount);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sLevel[32];
|
|
||||||
GetCmdArg(2, sLevel, sizeof(sLevel));
|
|
||||||
|
|
||||||
int Level;
|
|
||||||
if(!StringToIntEx(sLevel, Level))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Level has to be a number.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
IntToString(Level, sLevel, sizeof(sLevel));
|
|
||||||
|
|
||||||
g_Config.Rewind();
|
|
||||||
if(!g_Config.JumpToKey("0"))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Setting levels on the current map is not supported.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
g_Config.GoBack();
|
|
||||||
|
|
||||||
if(Level && !g_Config.JumpToKey(sLevel))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Level %s could not be found.", sLevel);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
g_Config.Rewind();
|
|
||||||
|
|
||||||
char sPrevNames[128];
|
|
||||||
if(iTargetCount == 1)
|
|
||||||
GetLevel(iTargets[0], sPrevNames, 0, sPrevNames, sizeof(sPrevNames));
|
|
||||||
|
|
||||||
char sName[32];
|
|
||||||
for(int i = 0; i < iTargetCount; i++)
|
|
||||||
{
|
|
||||||
// Reset level first
|
|
||||||
if(Level)
|
|
||||||
{
|
|
||||||
if(!RestoreLevel(iTargets[i], "0"))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Failed resetting level on %L.", iTargets[i]);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!RestoreLevel(iTargets[i], sLevel, sName, sizeof(sName)))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Failed setting level to %s on %L.", sLevel, iTargets[i]);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
LogAction(client, iTargets[i], "Set %L to %s", iTargets[i], sName);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(sPrevNames[0])
|
|
||||||
ShowActivity2(client, "\x03[SaveLevel]\x01 ", "Set \x04%s\x01 from \x04%s\x01 to \x04%s\x01", sTargetName, sPrevNames, sName);
|
|
||||||
else
|
|
||||||
ShowActivity2(client, "\x03[SaveLevel]\x01 ", "Set \x04%s\x01 to \x04%s\x01", sTargetName, sName);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
stock int CalcMatches(int Matches, int ExactMatches, int MinMatches, int MaxMatches)
|
|
||||||
{
|
|
||||||
int Value = 0;
|
|
||||||
if((ExactMatches == -1 && MinMatches == -1 && MaxMatches == -1 && Matches) ||
|
|
||||||
Matches == ExactMatches ||
|
|
||||||
(MinMatches != -1 && MaxMatches == -1 && Matches >= MinMatches) ||
|
|
||||||
(MaxMatches != -1 && MinMatches == -1 && Matches <= MaxMatches) ||
|
|
||||||
(MinMatches != -1 && MaxMatches != -1 && Matches >= MinMatches && Matches <= MaxMatches))
|
|
||||||
{
|
|
||||||
Value++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Value;
|
|
||||||
}
|
|
@ -1,416 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdkhooks>
|
|
||||||
#include <CSSFixes>
|
|
||||||
#undef REQUIRE_PLUGIN
|
|
||||||
#include <zombiereloaded>
|
|
||||||
#define REQUIRE_PLUGIN
|
|
||||||
#include <SelectiveBhop>
|
|
||||||
|
|
||||||
ConVar g_CVar_sv_enablebunnyhopping;
|
|
||||||
ConVar g_CVar_zr_disablebunnyhopping;
|
|
||||||
|
|
||||||
enum
|
|
||||||
{
|
|
||||||
LIMITED_NONE = 0,
|
|
||||||
LIMITED_GENERAL = 1,
|
|
||||||
|
|
||||||
// Temp
|
|
||||||
LIMITED_ZOMBIE = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
bool g_bEnabled = false;
|
|
||||||
bool g_bZombieEnabled = false;
|
|
||||||
bool g_bInOnPlayerRunCmd = false;
|
|
||||||
|
|
||||||
int g_ClientLimited[MAXPLAYERS + 1] = {LIMITED_NONE, ...};
|
|
||||||
int g_ActiveLimitedFlags = LIMITED_GENERAL;
|
|
||||||
|
|
||||||
StringMap g_ClientLimitedCache;
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "Selective Bunnyhop",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Disables bunnyhop on certain players/groups",
|
|
||||||
version = "0.1"
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
LoadTranslations("common.phrases");
|
|
||||||
|
|
||||||
g_CVar_sv_enablebunnyhopping = FindConVar("sv_enablebunnyhopping");
|
|
||||||
g_CVar_sv_enablebunnyhopping.Flags &= ~FCVAR_REPLICATED;
|
|
||||||
g_CVar_sv_enablebunnyhopping.AddChangeHook(OnConVarChanged);
|
|
||||||
g_bEnabled = g_CVar_sv_enablebunnyhopping.BoolValue;
|
|
||||||
|
|
||||||
g_CVar_zr_disablebunnyhopping = CreateConVar("zr_disablebunnyhopping", "0", "Disable bhop for zombies.", FCVAR_NOTIFY);
|
|
||||||
g_CVar_zr_disablebunnyhopping.AddChangeHook(OnConVarChanged);
|
|
||||||
g_bZombieEnabled = g_CVar_zr_disablebunnyhopping.BoolValue;
|
|
||||||
|
|
||||||
g_ClientLimitedCache = new StringMap();
|
|
||||||
|
|
||||||
HookEvent("round_start", Event_RoundStart, EventHookMode_PostNoCopy);
|
|
||||||
|
|
||||||
RegAdminCmd("sm_bhop", Command_Bhop, ADMFLAG_GENERIC, "sm_bhop <#userid|name> <0|1>");
|
|
||||||
|
|
||||||
RegConsoleCmd("sm_bhopstatus", Command_Status, "sm_bhopstatus [#userid|name]");
|
|
||||||
|
|
||||||
/* Late load */
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(!IsClientInGame(i) || IsFakeClient(i))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(ZR_IsClientZombie(i))
|
|
||||||
AddLimitedFlag(i, LIMITED_ZOMBIE);
|
|
||||||
}
|
|
||||||
|
|
||||||
UpdateLimitedFlags();
|
|
||||||
UpdateClients();
|
|
||||||
}
|
|
||||||
|
|
||||||
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
|
|
||||||
{
|
|
||||||
CreateNative("LimitBhop", Native_LimitBhop);
|
|
||||||
CreateNative("IsBhopLimited", Native_IsBhopLimited);
|
|
||||||
RegPluginLibrary("SelectiveBhop");
|
|
||||||
|
|
||||||
return APLRes_Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginEnd()
|
|
||||||
{
|
|
||||||
g_CVar_sv_enablebunnyhopping.BoolValue = g_bEnabled;
|
|
||||||
g_CVar_sv_enablebunnyhopping.Flags |= FCVAR_REPLICATED|FCVAR_NOTIFY;
|
|
||||||
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(i) && !IsFakeClient(i))
|
|
||||||
{
|
|
||||||
if(g_CVar_sv_enablebunnyhopping.BoolValue)
|
|
||||||
g_CVar_sv_enablebunnyhopping.ReplicateToClient(i, "1");
|
|
||||||
else
|
|
||||||
g_CVar_sv_enablebunnyhopping.ReplicateToClient(i, "0");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMapEnd()
|
|
||||||
{
|
|
||||||
g_ClientLimitedCache.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPutInServer(int client)
|
|
||||||
{
|
|
||||||
TransmitConVar(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientDisconnect(int client)
|
|
||||||
{
|
|
||||||
// Remove temp
|
|
||||||
int LimitedFlag = g_ClientLimited[client] & ~(LIMITED_ZOMBIE);
|
|
||||||
|
|
||||||
if(LimitedFlag != LIMITED_NONE)
|
|
||||||
{
|
|
||||||
char sSteamID[64];
|
|
||||||
if(GetClientAuthId(client, AuthId_Engine, sSteamID, sizeof(sSteamID)))
|
|
||||||
g_ClientLimitedCache.SetValue(sSteamID, LimitedFlag, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_ClientLimited[client] = LIMITED_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPostAdminCheck(int client)
|
|
||||||
{
|
|
||||||
char sSteamID[64];
|
|
||||||
if(GetClientAuthId(client, AuthId_Engine, sSteamID, sizeof(sSteamID)))
|
|
||||||
{
|
|
||||||
int LimitedFlag;
|
|
||||||
if(g_ClientLimitedCache.GetValue(sSteamID, LimitedFlag))
|
|
||||||
{
|
|
||||||
AddLimitedFlag(client, LimitedFlag);
|
|
||||||
g_ClientLimitedCache.Remove(sSteamID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
|
||||||
{
|
|
||||||
if(convar == g_CVar_sv_enablebunnyhopping)
|
|
||||||
{
|
|
||||||
if(g_bInOnPlayerRunCmd)
|
|
||||||
return;
|
|
||||||
|
|
||||||
g_bEnabled = convar.BoolValue;
|
|
||||||
UpdateClients();
|
|
||||||
}
|
|
||||||
else if(convar == g_CVar_zr_disablebunnyhopping)
|
|
||||||
{
|
|
||||||
g_bZombieEnabled = convar.BoolValue;
|
|
||||||
UpdateLimitedFlags();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon, int &subtype, int &cmdnum, int &tickcount, int &seed, int mouse[2])
|
|
||||||
{
|
|
||||||
if(!g_bEnabled)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
bool bEnableBunnyhopping = !(g_ClientLimited[client] & g_ActiveLimitedFlags);
|
|
||||||
if(bEnableBunnyhopping == g_CVar_sv_enablebunnyhopping.BoolValue)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
if(!g_bInOnPlayerRunCmd)
|
|
||||||
{
|
|
||||||
g_CVar_sv_enablebunnyhopping.Flags &= ~FCVAR_NOTIFY;
|
|
||||||
g_bInOnPlayerRunCmd = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_CVar_sv_enablebunnyhopping.BoolValue = bEnableBunnyhopping;
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnRunThinkFunctionsPost(bool simulating)
|
|
||||||
{
|
|
||||||
if(g_bInOnPlayerRunCmd)
|
|
||||||
{
|
|
||||||
g_CVar_sv_enablebunnyhopping.BoolValue = g_bEnabled;
|
|
||||||
g_CVar_sv_enablebunnyhopping.Flags |= FCVAR_NOTIFY;
|
|
||||||
g_bInOnPlayerRunCmd = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn)
|
|
||||||
{
|
|
||||||
AddLimitedFlag(client, LIMITED_ZOMBIE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ZR_OnClientHumanPost(int client, bool respawn, bool protect)
|
|
||||||
{
|
|
||||||
RemoveLimitedFlag(client, LIMITED_ZOMBIE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void ZR_OnClientRespawned(int client, ZR_RespawnCondition condition)
|
|
||||||
{
|
|
||||||
if(condition == ZR_Respawn_Human)
|
|
||||||
RemoveLimitedFlag(client, LIMITED_ZOMBIE);
|
|
||||||
else
|
|
||||||
AddLimitedFlag(client, LIMITED_ZOMBIE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Event_RoundStart(Event event, const char[] name, bool dontBroadcast)
|
|
||||||
{
|
|
||||||
RemoveLimitedFlag(-1, LIMITED_ZOMBIE);
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateLimitedFlags()
|
|
||||||
{
|
|
||||||
int Flags = LIMITED_GENERAL;
|
|
||||||
|
|
||||||
if(g_bZombieEnabled)
|
|
||||||
Flags |= LIMITED_ZOMBIE;
|
|
||||||
|
|
||||||
if(g_ActiveLimitedFlags != Flags)
|
|
||||||
{
|
|
||||||
g_ActiveLimitedFlags = Flags;
|
|
||||||
UpdateClients();
|
|
||||||
}
|
|
||||||
g_ActiveLimitedFlags = Flags;
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void AddLimitedFlag(int client, int Flag)
|
|
||||||
{
|
|
||||||
if(client == -1)
|
|
||||||
{
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
_AddLimitedFlag(i, Flag);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_AddLimitedFlag(client, Flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void _AddLimitedFlag(int client, int Flag)
|
|
||||||
{
|
|
||||||
bool bWasLimited = view_as<bool>(g_ClientLimited[client] & g_ActiveLimitedFlags);
|
|
||||||
g_ClientLimited[client] |= Flag;
|
|
||||||
bool bIsLimited = view_as<bool>(g_ClientLimited[client] & g_ActiveLimitedFlags);
|
|
||||||
|
|
||||||
if(bIsLimited != bWasLimited)
|
|
||||||
TransmitConVar(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void RemoveLimitedFlag(int client, int Flag)
|
|
||||||
{
|
|
||||||
if(client == -1)
|
|
||||||
{
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
_RemoveLimitedFlag(i, Flag);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
_RemoveLimitedFlag(client, Flag);
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void _RemoveLimitedFlag(int client, int Flag)
|
|
||||||
{
|
|
||||||
bool bWasLimited = view_as<bool>(g_ClientLimited[client] & g_ActiveLimitedFlags);
|
|
||||||
g_ClientLimited[client] &= ~Flag;
|
|
||||||
bool bIsLimited = view_as<bool>(g_ClientLimited[client] & g_ActiveLimitedFlags);
|
|
||||||
|
|
||||||
if(bIsLimited != bWasLimited)
|
|
||||||
TransmitConVar(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void UpdateClients()
|
|
||||||
{
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(i))
|
|
||||||
TransmitConVar(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void TransmitConVar(int client)
|
|
||||||
{
|
|
||||||
if(!IsClientInGame(client) || IsFakeClient(client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool bIsLimited = view_as<bool>(g_ClientLimited[client] & g_ActiveLimitedFlags);
|
|
||||||
|
|
||||||
if(g_bEnabled && !bIsLimited)
|
|
||||||
g_CVar_sv_enablebunnyhopping.ReplicateToClient(client, "1");
|
|
||||||
else
|
|
||||||
g_CVar_sv_enablebunnyhopping.ReplicateToClient(client, "0");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Bhop(int client, int argc)
|
|
||||||
{
|
|
||||||
if(argc < 2)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Usage: sm_bhop <#userid|name> <0|1>");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sArg[64];
|
|
||||||
char sArg2[2];
|
|
||||||
char sTargetName[MAX_TARGET_LENGTH];
|
|
||||||
int iTargets[MAXPLAYERS];
|
|
||||||
int iTargetCount;
|
|
||||||
bool bIsML;
|
|
||||||
bool bValue;
|
|
||||||
|
|
||||||
GetCmdArg(1, sArg, sizeof(sArg));
|
|
||||||
GetCmdArg(2, sArg2, sizeof(sArg2));
|
|
||||||
|
|
||||||
bValue = sArg2[0] == '1' ? true : false;
|
|
||||||
|
|
||||||
if((iTargetCount = ProcessTargetString(sArg, client, iTargets, MAXPLAYERS, COMMAND_FILTER_NO_MULTI, sTargetName, sizeof(sTargetName), bIsML)) <= 0)
|
|
||||||
{
|
|
||||||
ReplyToTargetError(client, iTargetCount);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i = 0; i < iTargetCount; i++)
|
|
||||||
{
|
|
||||||
if(bValue)
|
|
||||||
RemoveLimitedFlag(iTargets[i], LIMITED_GENERAL);
|
|
||||||
else
|
|
||||||
AddLimitedFlag(iTargets[i], LIMITED_GENERAL);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowActivity2(client, "\x01[SM] \x04", "\x01\x04%s\x01 bunnyhop on target \x04%s", bValue ? "Un-limited" : "Limited", sTargetName);
|
|
||||||
|
|
||||||
if(iTargetCount > 1)
|
|
||||||
LogAction(client, -1, "\"%L\" %s bunnyhop on target \"%s\"", client, bValue ? "Un-limited" : "Limited", sTargetName);
|
|
||||||
else
|
|
||||||
LogAction(client, iTargets[0], "\"%L\" %s bunnyhop on target \"%L\"", client, bValue ? "Un-limited" : "Limited", iTargets[0]);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Status(int client, int argc)
|
|
||||||
{
|
|
||||||
if (argc && CheckCommandAccess(client, "", ADMFLAG_BAN, true))
|
|
||||||
{
|
|
||||||
char sArgument[64];
|
|
||||||
GetCmdArg(1, sArgument, sizeof(sArgument));
|
|
||||||
|
|
||||||
int target = -1;
|
|
||||||
if((target = FindTarget(client, sArgument, true, false)) == -1)
|
|
||||||
return Plugin_Handled;
|
|
||||||
|
|
||||||
if(IsBhopLimited(target))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] %N their bhop is currently: limited", target);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] %N their bhop is currently: unlimited", target);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(IsBhopLimited(client))
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] your bhop is currently: limited");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] your bhop is currently: unlimited");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Native_LimitBhop(Handle plugin, int numParams)
|
|
||||||
{
|
|
||||||
int client = GetNativeCell(1);
|
|
||||||
bool bLimited = view_as<bool>(GetNativeCell(2));
|
|
||||||
|
|
||||||
if(client > MaxClients || client <= 0)
|
|
||||||
{
|
|
||||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!IsClientInGame(client))
|
|
||||||
{
|
|
||||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not in-game.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(bLimited)
|
|
||||||
AddLimitedFlag(client, LIMITED_GENERAL);
|
|
||||||
else
|
|
||||||
RemoveLimitedFlag(client, LIMITED_GENERAL);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int Native_IsBhopLimited(Handle plugin, int numParams)
|
|
||||||
{
|
|
||||||
int client = GetNativeCell(1);
|
|
||||||
|
|
||||||
if(client > MaxClients || client <= 0)
|
|
||||||
{
|
|
||||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not valid.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!IsClientInGame(client))
|
|
||||||
{
|
|
||||||
ThrowNativeError(SP_ERROR_NATIVE, "Client is not in-game.");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int LimitedFlag = g_ClientLimited[client] & ~(LIMITED_ZOMBIE);
|
|
||||||
|
|
||||||
return LimitedFlag != LIMITED_NONE;
|
|
||||||
}
|
|
@ -1,26 +0,0 @@
|
|||||||
#if defined _SelectiveBhop_Included
|
|
||||||
#endinput
|
|
||||||
#endif
|
|
||||||
#define _SelectiveBhop_Included
|
|
||||||
|
|
||||||
native int LimitBhop(int client, bool bLimited);
|
|
||||||
native int IsBhopLimited(int client);
|
|
||||||
|
|
||||||
public SharedPlugin __pl_SelectiveBhop =
|
|
||||||
{
|
|
||||||
name = "SelectiveBhop",
|
|
||||||
file = "SelectiveBhop.smx",
|
|
||||||
#if defined REQUIRE_PLUGIN
|
|
||||||
required = 1,
|
|
||||||
#else
|
|
||||||
required = 0,
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#if !defined REQUIRE_PLUGIN
|
|
||||||
public __pl_SelectiveBhop_SetNTVOptional()
|
|
||||||
{
|
|
||||||
MarkNativeAsOptional("LimitBhop");
|
|
||||||
MarkNativeAsOptional("IsBhopLimited");
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,150 +0,0 @@
|
|||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
|
|
||||||
#define VERSION "1.2.1"
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "Slope Landing Fix",
|
|
||||||
author = "Mev & Blacky",
|
|
||||||
description = "Makes it so landing on a slope will gaurantee a boost.",
|
|
||||||
version = VERSION,
|
|
||||||
url = "http://steamcommunity.com/id/blaackyy/ & http://steamcommunity.com/id/mevv/"
|
|
||||||
}
|
|
||||||
|
|
||||||
float g_vCurrent[MAXPLAYERS + 1][3];
|
|
||||||
float g_vLast[MAXPLAYERS + 1][3];
|
|
||||||
|
|
||||||
bool g_bOnGround[MAXPLAYERS + 1];
|
|
||||||
bool g_bLastOnGround[MAXPLAYERS + 1];
|
|
||||||
|
|
||||||
ConVar g_hSlopeFixEnable;
|
|
||||||
bool g_bSlopeFixEnable;
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
CreateConVar("slopefix_version", VERSION, "Slope fix version", FCVAR_NOTIFY|FCVAR_REPLICATED);
|
|
||||||
|
|
||||||
g_hSlopeFixEnable = CreateConVar("slopefix_enable", "1", "Enables slope fix.", FCVAR_NOTIFY, true, 0.0, true, 1.0);
|
|
||||||
HookConVarChange(g_hSlopeFixEnable, OnEnableSlopeFixChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnConfigsExecuted()
|
|
||||||
{
|
|
||||||
g_bSlopeFixEnable = GetConVarBool(g_hSlopeFixEnable);
|
|
||||||
}
|
|
||||||
|
|
||||||
public OnEnableSlopeFixChanged(Handle:convar, const String:oldValue[], const String:newValue[])
|
|
||||||
{
|
|
||||||
g_bSlopeFixEnable = bool:StringToInt(newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
public bool TraceRayDontHitSelf(int entity, int mask, any data)
|
|
||||||
{
|
|
||||||
return entity != data && !(0 < entity <= MaxClients);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnPlayerRunCmd(int client, int &buttons, int &impulse, float vel[3], float angles[3], int &weapon)
|
|
||||||
{
|
|
||||||
if(g_bSlopeFixEnable == true)
|
|
||||||
{
|
|
||||||
g_bLastOnGround[client] = g_bOnGround[client];
|
|
||||||
|
|
||||||
if (GetEntityFlags(client) & FL_ONGROUND)
|
|
||||||
g_bOnGround[client] = true;
|
|
||||||
else
|
|
||||||
g_bOnGround[client] = false;
|
|
||||||
|
|
||||||
g_vLast[client][0] = g_vCurrent[client][0];
|
|
||||||
g_vLast[client][1] = g_vCurrent[client][1];
|
|
||||||
g_vLast[client][2] = g_vCurrent[client][2];
|
|
||||||
g_vCurrent[client][0] = GetEntPropFloat(client, Prop_Send, "m_vecVelocity[0]");
|
|
||||||
g_vCurrent[client][1] = GetEntPropFloat(client, Prop_Send, "m_vecVelocity[1]");
|
|
||||||
g_vCurrent[client][2] = GetEntPropFloat(client, Prop_Send, "m_vecVelocity[2]");
|
|
||||||
|
|
||||||
// Check if player landed on the ground
|
|
||||||
if (g_bOnGround[client] == true && g_bLastOnGround[client] == false)
|
|
||||||
{
|
|
||||||
// Set up and do tracehull to find out if the player landed on a slope
|
|
||||||
float vPos[3];
|
|
||||||
GetEntPropVector(client, Prop_Data, "m_vecOrigin", vPos);
|
|
||||||
|
|
||||||
float vMins[3];
|
|
||||||
GetEntPropVector(client, Prop_Send, "m_vecMins", vMins);
|
|
||||||
|
|
||||||
float vMaxs[3];
|
|
||||||
GetEntPropVector(client, Prop_Send, "m_vecMaxs", vMaxs);
|
|
||||||
|
|
||||||
float vEndPos[3];
|
|
||||||
vEndPos[0] = vPos[0];
|
|
||||||
vEndPos[1] = vPos[1];
|
|
||||||
vEndPos[2] = vPos[2] - FindConVar("sv_maxvelocity").FloatValue;
|
|
||||||
|
|
||||||
TR_TraceHullFilter(vPos, vEndPos, vMins, vMaxs, MASK_PLAYERSOLID_BRUSHONLY, TraceRayDontHitSelf, client);
|
|
||||||
|
|
||||||
if(TR_DidHit())
|
|
||||||
{
|
|
||||||
// Gets the normal vector of the surface under the player
|
|
||||||
float vPlane[3], vLast[3];
|
|
||||||
TR_GetPlaneNormal(INVALID_HANDLE, vPlane);
|
|
||||||
|
|
||||||
// Make sure it's not flat ground and not a surf ramp (1.0 = flat ground, < 0.7 = surf ramp)
|
|
||||||
if(0.7 <= vPlane[2] < 1.0)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
Copy the ClipVelocity function from sdk2013
|
|
||||||
(https://mxr.alliedmods.net/hl2sdk-sdk2013/source/game/shared/gamemovement.cpp#3145)
|
|
||||||
With some minor changes to make it actually work
|
|
||||||
*/
|
|
||||||
vLast[0] = g_vLast[client][0];
|
|
||||||
vLast[1] = g_vLast[client][1];
|
|
||||||
vLast[2] = g_vLast[client][2];
|
|
||||||
vLast[2] -= (FindConVar("sv_gravity").FloatValue * GetTickInterval() * 0.5);
|
|
||||||
|
|
||||||
float fBackOff = GetVectorDotProduct(vLast, vPlane);
|
|
||||||
|
|
||||||
float change, vVel[3];
|
|
||||||
for(int i; i < 2; i++)
|
|
||||||
{
|
|
||||||
change = vPlane[i] * fBackOff;
|
|
||||||
vVel[i] = vLast[i] - change;
|
|
||||||
}
|
|
||||||
|
|
||||||
float fAdjust = GetVectorDotProduct(vVel, vPlane);
|
|
||||||
if(fAdjust < 0.0)
|
|
||||||
{
|
|
||||||
for(int i; i < 2; i++)
|
|
||||||
{
|
|
||||||
vVel[i] -= (vPlane[i] * fAdjust);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
vVel[2] = 0.0;
|
|
||||||
vLast[2] = 0.0;
|
|
||||||
|
|
||||||
// Make sure the player is going down a ramp by checking if they actually will gain speed from the boost
|
|
||||||
if(GetVectorLength(vVel) > GetVectorLength(vLast))
|
|
||||||
SetClientVelocity(client, vVel);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void SetClientVelocity(int client, float vVelocity[3])
|
|
||||||
{
|
|
||||||
static bool GotOffset = false;
|
|
||||||
static int Offset = -1;
|
|
||||||
|
|
||||||
if(!GotOffset)
|
|
||||||
{
|
|
||||||
Offset = FindDataMapInfo(client, "m_vecAbsVelocity");
|
|
||||||
GotOffset = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Apply velocity on client.
|
|
||||||
if(Offset != -1) // Fixes trigger OnStartTouch/OnEndTouch bug
|
|
||||||
SetEntDataVector(client, Offset, vVelocity);
|
|
||||||
else // Fallback to old one
|
|
||||||
TeleportEntity(client, NULL_VECTOR, NULL_VECTOR, vVelocity);
|
|
||||||
}
|
|
@ -1,6 +0,0 @@
|
|||||||
"LightmappedGeneric"
|
|
||||||
{
|
|
||||||
"$basetexture" "decals\spraymanager\1"
|
|
||||||
"$decal" 1
|
|
||||||
"$decalscale" 0.500000
|
|
||||||
}
|
|
Binary file not shown.
@ -1,6 +0,0 @@
|
|||||||
"LightmappedGeneric"
|
|
||||||
{
|
|
||||||
"$basetexture" "decals\spraymanager\2"
|
|
||||||
"$decal" 1
|
|
||||||
"$decalscale" 0.500000
|
|
||||||
}
|
|
Binary file not shown.
@ -1,8 +0,0 @@
|
|||||||
"LightmappedGeneric"
|
|
||||||
{
|
|
||||||
"$basetexture" "decals\spraymanager\3"
|
|
||||||
"$translucent" "1"
|
|
||||||
"$decal" "1"
|
|
||||||
"$decalscale" 1.000000
|
|
||||||
"$surfaceprop" "Default"
|
|
||||||
}
|
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -1,45 +0,0 @@
|
|||||||
"Games"
|
|
||||||
{
|
|
||||||
"#default"
|
|
||||||
{
|
|
||||||
"Addresses"
|
|
||||||
{
|
|
||||||
"HostTimeFrame"
|
|
||||||
{
|
|
||||||
"windows"
|
|
||||||
{
|
|
||||||
"signature" "GetStatsString"
|
|
||||||
"read" "79"
|
|
||||||
// ALTERNATIVE 1: -4
|
|
||||||
}
|
|
||||||
"linux"
|
|
||||||
{
|
|
||||||
"signature" "host_frametime"
|
|
||||||
}
|
|
||||||
"mac"
|
|
||||||
{
|
|
||||||
"signature" "host_frametime"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
"Signatures"
|
|
||||||
{
|
|
||||||
"GetStatsString"
|
|
||||||
{
|
|
||||||
"library" "engine"
|
|
||||||
"windows" "\x55\x8B\xEC\x83\xEC\x0C\xD9\xEE\x8D\x45\xFC\x56\x57\x50\x8D\x45\xF8"
|
|
||||||
/* 55 8B EC 83 EC 0C D9 EE 8D 45 FC 56 57 50 8D 45 F8 */
|
|
||||||
/* ALTERNATIVE 1: 2B F0 D9 E8 8D 47 FF DE F1 56 83 EC 08 DD 1C 24 50 */
|
|
||||||
}
|
|
||||||
|
|
||||||
"host_frametime"
|
|
||||||
{
|
|
||||||
"library" "engine"
|
|
||||||
"linux" "@host_frametime"
|
|
||||||
"mac" "@host_frametime"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,204 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
#include <connect>
|
|
||||||
|
|
||||||
#tryinclude "serverfps.inc"
|
|
||||||
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
ConVar g_Cvar_HostIP;
|
|
||||||
ConVar g_Cvar_HostPort;
|
|
||||||
ConVar g_Cvar_HostName;
|
|
||||||
ConVar g_Cvar_HostTags;
|
|
||||||
|
|
||||||
#if !defined _serverfps_included
|
|
||||||
int g_iTickRate;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "Status Fixer",
|
|
||||||
author = "zaCade + BotoX + Obus",
|
|
||||||
description = "Fixes the \"status\" command",
|
|
||||||
version = "2.0",
|
|
||||||
url = "https://github.com/CSSZombieEscape/sm-plugins/tree/master/Status/"
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
g_Cvar_HostIP = FindConVar("hostip");
|
|
||||||
g_Cvar_HostPort = FindConVar("hostport");
|
|
||||||
g_Cvar_HostName = FindConVar("hostname");
|
|
||||||
g_Cvar_HostTags = FindConVar("sv_tags");
|
|
||||||
|
|
||||||
AddCommandListener(Command_Status, "status");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Status(int client, const char[] command, int args)
|
|
||||||
{
|
|
||||||
if(!client)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
static char sServerName[128];
|
|
||||||
static char sServerTags[128];
|
|
||||||
static char sServerAdress[128];
|
|
||||||
|
|
||||||
int iServerIP = g_Cvar_HostIP.IntValue;
|
|
||||||
int iServerPort = g_Cvar_HostPort.IntValue;
|
|
||||||
|
|
||||||
g_Cvar_HostName.GetString(sServerName, sizeof(sServerName));
|
|
||||||
g_Cvar_HostTags.GetString(sServerTags, sizeof(sServerTags));
|
|
||||||
|
|
||||||
Format(sServerAdress, sizeof(sServerAdress), "%d.%d.%d.%d:%d", iServerIP >>> 24 & 255, iServerIP >>> 16 & 255, iServerIP >>> 8 & 255, iServerIP & 255, iServerPort);
|
|
||||||
|
|
||||||
static char sMapName[128];
|
|
||||||
GetCurrentMap(sMapName, sizeof(sMapName));
|
|
||||||
|
|
||||||
float fPosition[3];
|
|
||||||
GetClientAbsOrigin(client, fPosition);
|
|
||||||
|
|
||||||
float fClientDataIn = GetClientAvgData(client, NetFlow_Incoming);
|
|
||||||
float fClientDataOut = GetClientAvgData(client, NetFlow_Outgoing);
|
|
||||||
float fServerDataIn;
|
|
||||||
float fServerDataOut;
|
|
||||||
|
|
||||||
GetServerNetStats(fServerDataIn, fServerDataOut);
|
|
||||||
|
|
||||||
int iRealClients;
|
|
||||||
int iFakeClients;
|
|
||||||
int iTotalClients;
|
|
||||||
|
|
||||||
for(int player = 1; player <= MaxClients; player++)
|
|
||||||
{
|
|
||||||
if(IsClientConnected(player))
|
|
||||||
{
|
|
||||||
iTotalClients++;
|
|
||||||
|
|
||||||
if(IsFakeClient(player))
|
|
||||||
iFakeClients++;
|
|
||||||
else
|
|
||||||
iRealClients++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined _serverfps_included
|
|
||||||
float fServerTickRate = 1.0 / GetTickInterval();
|
|
||||||
float fServerFPS = GetServerFPS();
|
|
||||||
|
|
||||||
fServerFPS = fServerFPS <= fServerTickRate ? fServerFPS : fServerTickRate;
|
|
||||||
#else
|
|
||||||
int iServerTickRate = RoundToZero(1.0 / GetTickInterval());
|
|
||||||
int iTickRate = g_iTickRate;
|
|
||||||
|
|
||||||
iTickRate = iTickRate <= iServerTickRate ? iTickRate : iServerTickRate;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PrintToConsole(client, "hostname: %s",
|
|
||||||
sServerName);
|
|
||||||
|
|
||||||
#if defined _serverfps_included
|
|
||||||
PrintToConsole(client, "tickrate : %.2f/%.2f (%d%%)",
|
|
||||||
fServerFPS, fServerTickRate, RoundToNearest((fServerFPS / fServerTickRate) * 100));
|
|
||||||
#else
|
|
||||||
PrintToConsole(client, "tickrate : %d/%d (%d%%)",
|
|
||||||
iTickRate, iServerTickRate, RoundToNearest((float(iTickRate) / float(iServerTickRate)) * 100));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PrintToConsole(client, "udp/ip : %s",
|
|
||||||
sServerAdress);
|
|
||||||
|
|
||||||
PrintToConsole(client, "net I/O : %.2f/%.2f KiB/s (You: %.2f/%.2f KiB/s)",
|
|
||||||
fServerDataIn / 1024, fServerDataOut / 1024, fClientDataIn / 1024, fClientDataOut / 1024);
|
|
||||||
|
|
||||||
PrintToConsole(client, "map : %s at: %.0f x, %.0f y, %.0f z",
|
|
||||||
sMapName, fPosition[0], fPosition[1], fPosition[2]);
|
|
||||||
|
|
||||||
PrintToConsole(client, "tags : %s",
|
|
||||||
sServerTags);
|
|
||||||
|
|
||||||
PrintToConsole(client, "edicts : %d/%d/%d (used/max/free)",
|
|
||||||
GetEntityCount(), GetMaxEntities(), GetMaxEntities() - GetEntityCount());
|
|
||||||
|
|
||||||
PrintToConsole(client, "players : %d %s | %d %s (%d/%d)",
|
|
||||||
iRealClients, Multiple(iRealClients) ? "humans" : "human", iFakeClients, Multiple(iFakeClients) ? "bots" : "bot", iTotalClients, MaxClients);
|
|
||||||
|
|
||||||
PrintToConsole(client, "# %8s %40s %24s %12s %4s %4s %s %s",
|
|
||||||
"userid", "name", "uniqueid", "connected", "ping", "loss", "state", "addr");
|
|
||||||
|
|
||||||
for(int player = 1; player <= MaxClients; player++)
|
|
||||||
{
|
|
||||||
if(!IsClientConnected(player))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
static char sPlayerID[8];
|
|
||||||
static char sPlayerName[MAX_NAME_LENGTH + 2];
|
|
||||||
static char sPlayerAuth[24];
|
|
||||||
char sPlayerTime[12];
|
|
||||||
char sPlayerPing[4];
|
|
||||||
char sPlayerLoss[4];
|
|
||||||
static char sPlayerState[16];
|
|
||||||
char sPlayerAddr[16];
|
|
||||||
|
|
||||||
FormatEx(sPlayerID, sizeof(sPlayerID), "%d", GetClientUserId(player));
|
|
||||||
FormatEx(sPlayerName, sizeof(sPlayerName), "\"%N\"", player);
|
|
||||||
|
|
||||||
if(!GetClientAuthId(player, AuthId_Steam2, sPlayerAuth, sizeof(sPlayerAuth)))
|
|
||||||
FormatEx(sPlayerAuth, sizeof(sPlayerAuth), "STEAM_ID_PENDING");
|
|
||||||
|
|
||||||
if(!IsFakeClient(player))
|
|
||||||
{
|
|
||||||
int iHours = RoundToFloor((GetClientTime(player) / 3600));
|
|
||||||
int iMinutes = RoundToFloor((GetClientTime(player) - (iHours * 3600)) / 60);
|
|
||||||
int iSeconds = RoundToFloor((GetClientTime(player) - (iHours * 3600)) - (iMinutes * 60));
|
|
||||||
|
|
||||||
if (iHours)
|
|
||||||
FormatEx(sPlayerTime, sizeof(sPlayerTime), "%d:%02d:%02d", iHours, iMinutes, iSeconds);
|
|
||||||
else
|
|
||||||
FormatEx(sPlayerTime, sizeof(sPlayerTime), "%d:%02d", iMinutes, iSeconds);
|
|
||||||
|
|
||||||
FormatEx(sPlayerPing, sizeof(sPlayerPing), "%d", RoundFloat(GetClientLatency(player, NetFlow_Outgoing) * 800));
|
|
||||||
FormatEx(sPlayerLoss, sizeof(sPlayerLoss), "%d", RoundFloat(GetClientAvgLoss(player, NetFlow_Outgoing) * 100));
|
|
||||||
}
|
|
||||||
|
|
||||||
if(IsClientInGame(player))
|
|
||||||
if (SteamClientAuthenticated(sPlayerAuth))
|
|
||||||
FormatEx(sPlayerState, sizeof(sPlayerState), "active");
|
|
||||||
else
|
|
||||||
FormatEx(sPlayerState, sizeof(sPlayerState), "nosteam");
|
|
||||||
else
|
|
||||||
FormatEx(sPlayerState, sizeof(sPlayerState), "spawning");
|
|
||||||
|
|
||||||
if(GetAdminFlag(GetUserAdmin(client), Admin_RCON))
|
|
||||||
GetClientIP(player, sPlayerAddr, sizeof(sPlayerAddr));
|
|
||||||
|
|
||||||
PrintToConsole(client, "# %8s %40s %24s %12s %4s %4s %s %s",
|
|
||||||
sPlayerID, sPlayerName, sPlayerAuth, sPlayerTime, sPlayerPing, sPlayerLoss, sPlayerState, sPlayerAddr);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnGameFrame()
|
|
||||||
{
|
|
||||||
#if !defined _serverfps_included //Inaccurate fallback
|
|
||||||
static float fLastEngineTime;
|
|
||||||
static int iTicks;
|
|
||||||
float fCurEngineTime = GetEngineTime(); //GetEngineTime() will become less and less accurate as server uptime goes up!
|
|
||||||
|
|
||||||
iTicks++;
|
|
||||||
|
|
||||||
if (fCurEngineTime - fLastEngineTime >= 1.0)
|
|
||||||
{
|
|
||||||
g_iTickRate = iTicks;
|
|
||||||
iTicks = 0;
|
|
||||||
fLastEngineTime = fCurEngineTime;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
stock bool Multiple(int num)
|
|
||||||
{
|
|
||||||
return (!num || num > 1);
|
|
||||||
}
|
|
@ -1,49 +0,0 @@
|
|||||||
#if defined _serverfps_included
|
|
||||||
#endinput
|
|
||||||
#endif
|
|
||||||
#define _serverfps_included
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
|
|
||||||
stock float GetServerFPS()
|
|
||||||
{
|
|
||||||
return 1.0 / view_as<float>(LoadFromAddress(GetHostTimeFrame(), NumberType_Int32));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Internal Functions
|
|
||||||
*/
|
|
||||||
stock Handle GetServerFPSConf()
|
|
||||||
{
|
|
||||||
static Handle hGameConf = null;
|
|
||||||
|
|
||||||
if (hGameConf == null)
|
|
||||||
{
|
|
||||||
hGameConf = LoadGameConfigFile("serverfps.games");
|
|
||||||
|
|
||||||
if (hGameConf == null)
|
|
||||||
{
|
|
||||||
SetFailState("Couldn't find \"serverfps.games\" configuration file");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return hGameConf;
|
|
||||||
}
|
|
||||||
|
|
||||||
stock Address GetHostTimeFrame()
|
|
||||||
{
|
|
||||||
static Address pHostTimeFrame = Address_Null;
|
|
||||||
|
|
||||||
if (pHostTimeFrame == Address_Null)
|
|
||||||
{
|
|
||||||
pHostTimeFrame = GameConfGetAddress(GetServerFPSConf(), "HostTimeFrame");
|
|
||||||
|
|
||||||
if (pHostTimeFrame == Address_Null)
|
|
||||||
{
|
|
||||||
SetFailState("Failed to find time frame address");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return pHostTimeFrame;
|
|
||||||
}
|
|
@ -1,693 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
#include <cstrike>
|
|
||||||
#include <clientprefs>
|
|
||||||
#include <multicolors>
|
|
||||||
|
|
||||||
#define PLUGIN_VERSION "3.1.0"
|
|
||||||
|
|
||||||
bool g_bStopWeaponSounds[MAXPLAYERS+1] = { false, ... };
|
|
||||||
bool g_bStopMapMusic[MAXPLAYERS+1] = { false, ... };
|
|
||||||
|
|
||||||
bool g_bStopWeaponSoundsHooked = false;
|
|
||||||
bool g_bStopMapMusicHooked = false;
|
|
||||||
|
|
||||||
StringMap g_MapMusic;
|
|
||||||
|
|
||||||
Handle g_hCookieStopSound = null;
|
|
||||||
Handle g_hCookieStopMapMusic = null;
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "Toggle Game Sounds",
|
|
||||||
author = "GoD-Tony, edit by Obus + BotoX, Oleg Tsvetkov",
|
|
||||||
description = "Allows clients to stop hearing weapon sounds and map music",
|
|
||||||
version = PLUGIN_VERSION,
|
|
||||||
url = "http://www.sourcemod.net/"
|
|
||||||
};
|
|
||||||
|
|
||||||
public APLRes AskPluginLoad2(Handle myself, bool late, char[] error, int err_max)
|
|
||||||
{
|
|
||||||
if(GetEngineVersion() != Engine_CSGO && GetEngineVersion() != Engine_CSS)
|
|
||||||
{
|
|
||||||
strcopy(error, err_max, "This plugin supports only CS:GO and CS:S!");
|
|
||||||
return APLRes_Failure;
|
|
||||||
}
|
|
||||||
|
|
||||||
return APLRes_Success;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
// Load translations
|
|
||||||
LoadTranslations("plugin.stopsound.phrases");
|
|
||||||
LoadTranslations("common.phrases"); // For On/Off buttons in Cookies Menu
|
|
||||||
|
|
||||||
g_MapMusic = new StringMap();
|
|
||||||
|
|
||||||
// Detect game and hook appropriate tempent.
|
|
||||||
AddTempEntHook("Shotgun Shot", Hook_ShotgunShot);
|
|
||||||
|
|
||||||
// Ambient sounds
|
|
||||||
AddAmbientSoundHook(Hook_AmbientSound);
|
|
||||||
|
|
||||||
// Map music will be caught here
|
|
||||||
HookEvent("round_end", Event_RoundEnd);
|
|
||||||
HookEvent("player_spawn", Event_PlayerSpawn);
|
|
||||||
|
|
||||||
CreateConVar("sm_stopsound_version", PLUGIN_VERSION, "Toggle Weapon Sounds", FCVAR_NOTIFY|FCVAR_DONTRECORD|FCVAR_REPLICATED);
|
|
||||||
RegConsoleCmd("sm_stopsound", Command_StopSound, "Toggle hearing weapon sounds");
|
|
||||||
RegConsoleCmd("sm_sound", Command_StopSound, "Toggle hearing weapon sounds");
|
|
||||||
RegConsoleCmd("sm_stopmusic", Command_StopMusic, "Toggle hearing map music");
|
|
||||||
RegConsoleCmd("sm_music", Command_StopMusic, "Toggle hearing map music");
|
|
||||||
|
|
||||||
// Cookies
|
|
||||||
g_hCookieStopSound = RegClientCookie("weaponsound_blocked", "Are weapon sounds enabled", CookieAccess_Protected);
|
|
||||||
g_hCookieStopMapMusic = RegClientCookie("mapmusic_blocked", "Are map music enabled", CookieAccess_Protected);
|
|
||||||
|
|
||||||
SetCookieMenuItem(CookieMenuHandler_StopSounds, 0, "Stop sounds");
|
|
||||||
|
|
||||||
// Suppress reload sound effects
|
|
||||||
UserMsg ReloadEffect = GetUserMessageId("ReloadEffect");
|
|
||||||
|
|
||||||
// Game-specific setup
|
|
||||||
if(GetEngineVersion() == Engine_CSGO)
|
|
||||||
{
|
|
||||||
// Weapon sounds will be caught here.
|
|
||||||
AddNormalSoundHook(Hook_NormalSound_CSGO);
|
|
||||||
|
|
||||||
if(ReloadEffect != INVALID_MESSAGE_ID)
|
|
||||||
{
|
|
||||||
HookUserMessage(ReloadEffect, Hook_ReloadEffect_CSGO, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // CS:S
|
|
||||||
{
|
|
||||||
// Weapon sounds will be caught here.
|
|
||||||
AddNormalSoundHook(Hook_NormalSound_CSS);
|
|
||||||
|
|
||||||
if(ReloadEffect != INVALID_MESSAGE_ID)
|
|
||||||
{
|
|
||||||
HookUserMessage(ReloadEffect, Hook_ReloadEffect_CSS, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Late load
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(client) && AreClientCookiesCached(client))
|
|
||||||
{
|
|
||||||
OnClientCookiesCached(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginEnd()
|
|
||||||
{
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(client))
|
|
||||||
{
|
|
||||||
OnClientDisconnect(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Remove tempent hook
|
|
||||||
RemoveTempEntHook("Shotgun Shot", Hook_ShotgunShot);
|
|
||||||
|
|
||||||
// Remove ambient sound hook
|
|
||||||
RemoveAmbientSoundHook(Hook_AmbientSound);
|
|
||||||
|
|
||||||
// Find ReloadEffect
|
|
||||||
UserMsg ReloadEffect = GetUserMessageId("ReloadEffect");
|
|
||||||
|
|
||||||
// Remove game-specific
|
|
||||||
if(GetEngineVersion() == Engine_CSGO)
|
|
||||||
{
|
|
||||||
RemoveNormalSoundHook(Hook_NormalSound_CSGO);
|
|
||||||
|
|
||||||
if(ReloadEffect != INVALID_MESSAGE_ID)
|
|
||||||
UnhookUserMessage(ReloadEffect, Hook_ReloadEffect_CSGO, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RemoveNormalSoundHook(Hook_NormalSound_CSS);
|
|
||||||
|
|
||||||
if(ReloadEffect != INVALID_MESSAGE_ID)
|
|
||||||
UnhookUserMessage(ReloadEffect, Hook_ReloadEffect_CSS, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMapStart()
|
|
||||||
{
|
|
||||||
g_MapMusic.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Event_RoundEnd(Event event, const char[] name, bool dontBroadcast)
|
|
||||||
{
|
|
||||||
g_MapMusic.Clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Event_PlayerSpawn(Event event, const char[] name, bool dontBroadcast)
|
|
||||||
{
|
|
||||||
int client = GetClientOfUserId(event.GetInt("userid"));
|
|
||||||
|
|
||||||
if(!IsClientInGame(client) || GetClientTeam(client) <= CS_TEAM_SPECTATOR)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(g_bStopWeaponSounds[client])
|
|
||||||
CPrintToChat(client, "%t %t", "Chat Prefix", "Weapon sounds disabled");
|
|
||||||
|
|
||||||
if(g_bStopMapMusic[client])
|
|
||||||
CPrintToChat(client, "%t %t", "Chat Prefix", "Map music disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_StopSound(int client, int args)
|
|
||||||
{
|
|
||||||
if(client == 0)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Cannot use command from server console.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_bStopWeaponSounds[client] = !g_bStopWeaponSounds[client];
|
|
||||||
CheckWeaponSoundsHooks();
|
|
||||||
|
|
||||||
if(g_bStopWeaponSounds[client])
|
|
||||||
{
|
|
||||||
SetClientCookie(client, g_hCookieStopSound, "1");
|
|
||||||
CReplyToCommand(client, "%t %t", "Chat Prefix", "Weapon sounds disabled");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetClientCookie(client, g_hCookieStopSound, "");
|
|
||||||
CReplyToCommand(client, "%t %t", "Chat Prefix", "Weapon sounds enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_StopMusic(int client, int args)
|
|
||||||
{
|
|
||||||
if(client == 0)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Cannot use command from server console.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_bStopMapMusic[client] = !g_bStopMapMusic[client];
|
|
||||||
CheckMapMusicHooks();
|
|
||||||
|
|
||||||
if(g_bStopMapMusic[client])
|
|
||||||
{
|
|
||||||
SetClientCookie(client, g_hCookieStopMapMusic, "1");
|
|
||||||
CReplyToCommand(client, "%t %t", "Chat Prefix", "Map music disabled");
|
|
||||||
StopMapMusic(client);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetClientCookie(client, g_hCookieStopMapMusic, "");
|
|
||||||
CReplyToCommand(client, "%t %t", "Chat Prefix", "Map music enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientCookiesCached(int client)
|
|
||||||
{
|
|
||||||
char sBuffer[2];
|
|
||||||
|
|
||||||
// Weapon Sounds cookie
|
|
||||||
GetClientCookie(client, g_hCookieStopSound, sBuffer, sizeof(sBuffer));
|
|
||||||
|
|
||||||
if(sBuffer[0] != '\0')
|
|
||||||
{
|
|
||||||
g_bStopWeaponSounds[client] = true;
|
|
||||||
g_bStopWeaponSoundsHooked = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_bStopWeaponSounds[client] = false;
|
|
||||||
|
|
||||||
// Map Music cookie
|
|
||||||
GetClientCookie(client, g_hCookieStopMapMusic, sBuffer, sizeof(sBuffer));
|
|
||||||
|
|
||||||
if(sBuffer[0] != '\0')
|
|
||||||
{
|
|
||||||
g_bStopMapMusic[client] = true;
|
|
||||||
g_bStopMapMusicHooked = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
g_bStopMapMusic[client] = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientDisconnect(int client)
|
|
||||||
{
|
|
||||||
g_bStopWeaponSounds[client] = false;
|
|
||||||
g_bStopMapMusic[client] = false;
|
|
||||||
|
|
||||||
CheckWeaponSoundsHooks();
|
|
||||||
CheckMapMusicHooks();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckWeaponSoundsHooks()
|
|
||||||
{
|
|
||||||
bool bShouldHook = false;
|
|
||||||
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(g_bStopWeaponSounds[i])
|
|
||||||
{
|
|
||||||
bShouldHook = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fake (un)hook because toggling actual hooks will cause server instability.
|
|
||||||
g_bStopWeaponSoundsHooked = bShouldHook;
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckMapMusicHooks()
|
|
||||||
{
|
|
||||||
bool bShouldHook = false;
|
|
||||||
|
|
||||||
for(int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if(g_bStopMapMusic[i])
|
|
||||||
{
|
|
||||||
bShouldHook = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fake (un)hook because toggling actual hooks will cause server instability.
|
|
||||||
g_bStopMapMusicHooked = bShouldHook;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StopMapMusic(int client)
|
|
||||||
{
|
|
||||||
int entity = INVALID_ENT_REFERENCE;
|
|
||||||
|
|
||||||
char sEntity[16];
|
|
||||||
char sSample[PLATFORM_MAX_PATH];
|
|
||||||
|
|
||||||
StringMapSnapshot MapMusicSnap = g_MapMusic.Snapshot();
|
|
||||||
for(int i = 0; i < MapMusicSnap.Length; i++)
|
|
||||||
{
|
|
||||||
MapMusicSnap.GetKey(i, sEntity, sizeof(sEntity));
|
|
||||||
|
|
||||||
if((entity = EntRefToEntIndex(StringToInt(sEntity))) == INVALID_ENT_REFERENCE)
|
|
||||||
{
|
|
||||||
g_MapMusic.Remove(sEntity);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_MapMusic.GetString(sEntity, sSample, sizeof(sSample));
|
|
||||||
|
|
||||||
EmitSoundToClient(client, sSample, entity, SNDCHAN_STATIC, SNDLEVEL_NONE, SND_STOPLOOPING, SNDVOL_NORMAL, SNDPITCH_NORMAL);
|
|
||||||
}
|
|
||||||
delete MapMusicSnap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void CookieMenuHandler_StopSounds(int client, CookieMenuAction action, any info, char[] buffer, int maxlen)
|
|
||||||
{
|
|
||||||
if(action == CookieMenuAction_DisplayOption)
|
|
||||||
{
|
|
||||||
Format(buffer, maxlen, "%T", "Cookie Menu Stop Sounds", client);
|
|
||||||
}
|
|
||||||
else if(action == CookieMenuAction_SelectOption)
|
|
||||||
{
|
|
||||||
ShowStopSoundsSettingsMenu(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ShowStopSoundsSettingsMenu(int client)
|
|
||||||
{
|
|
||||||
Menu menu = new Menu(MenuHandler_StopSoundsSettings);
|
|
||||||
|
|
||||||
menu.SetTitle("%T", "Cookie Menu Stop Sounds Title", client);
|
|
||||||
|
|
||||||
char sBuffer[128];
|
|
||||||
|
|
||||||
Format(sBuffer, sizeof(sBuffer), "%T%T", "Weapon Sounds", client, g_bStopWeaponSounds[client] ? "Disabled" : "Enabled", client);
|
|
||||||
menu.AddItem("0", sBuffer);
|
|
||||||
|
|
||||||
Format(sBuffer, sizeof(sBuffer), "%T%T", "Map Sounds", client, g_bStopMapMusic[client] ? "Disabled" : "Enabled", client);
|
|
||||||
menu.AddItem("1", sBuffer);
|
|
||||||
|
|
||||||
menu.ExitBackButton = true;
|
|
||||||
menu.Display(client, MENU_TIME_FOREVER);
|
|
||||||
}
|
|
||||||
|
|
||||||
public int MenuHandler_StopSoundsSettings(Menu menu, MenuAction action, int client, int selection)
|
|
||||||
{
|
|
||||||
if(action == MenuAction_Cancel)
|
|
||||||
{
|
|
||||||
ShowCookieMenu(client);
|
|
||||||
}
|
|
||||||
else if(action == MenuAction_Select)
|
|
||||||
{
|
|
||||||
if(selection == 0)
|
|
||||||
{
|
|
||||||
g_bStopWeaponSounds[client] = !g_bStopWeaponSounds[client];
|
|
||||||
CheckWeaponSoundsHooks();
|
|
||||||
|
|
||||||
if(g_bStopWeaponSounds[client])
|
|
||||||
{
|
|
||||||
SetClientCookie(client, g_hCookieStopSound, "1");
|
|
||||||
CPrintToChat(client, "%t %t", "Chat Prefix", "Weapon sounds disabled");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetClientCookie(client, g_hCookieStopSound, "");
|
|
||||||
CPrintToChat(client, "%t %t", "Chat Prefix", "Weapon sounds enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
else if(selection == 1)
|
|
||||||
{
|
|
||||||
g_bStopMapMusic[client] = !g_bStopMapMusic[client];
|
|
||||||
CheckMapMusicHooks();
|
|
||||||
|
|
||||||
if(g_bStopMapMusic[client])
|
|
||||||
{
|
|
||||||
SetClientCookie(client, g_hCookieStopMapMusic, "1");
|
|
||||||
CPrintToChat(client, "%t %t", "Chat Prefix", "Map music disabled");
|
|
||||||
StopMapMusic(client);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SetClientCookie(client, g_hCookieStopMapMusic, "");
|
|
||||||
CPrintToChat(client, "%t %t", "Chat Prefix", "Map music enabled");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowStopSoundsSettingsMenu(client);
|
|
||||||
}
|
|
||||||
else if(action == MenuAction_End)
|
|
||||||
{
|
|
||||||
delete menu;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Hook_NormalSound_CSS(int clients[MAXPLAYERS], int &numClients, char sample[PLATFORM_MAX_PATH],
|
|
||||||
int &entity, int &channel, float &volume, int &level, int &pitch, int &flags,
|
|
||||||
char soundEntry[PLATFORM_MAX_PATH], int &seed)
|
|
||||||
{
|
|
||||||
if(!g_bStopWeaponSoundsHooked)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
// Ignore non-weapon sounds.
|
|
||||||
if(channel != SNDCHAN_WEAPON &&
|
|
||||||
!(channel == SNDCHAN_AUTO && strncmp(sample, "physics/flesh", 13) == 0) &&
|
|
||||||
!(channel == SNDCHAN_VOICE && StrContains(sample, "player/headshot", true) != -1))
|
|
||||||
{
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int j = 0;
|
|
||||||
for(int i = 0; i < numClients; i++)
|
|
||||||
{
|
|
||||||
int client = clients[i];
|
|
||||||
if(!g_bStopWeaponSounds[client] && IsClientInGame(client))
|
|
||||||
{
|
|
||||||
// Keep client.
|
|
||||||
clients[j] = clients[i];
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
numClients = j;
|
|
||||||
|
|
||||||
return (numClients > 0) ? Plugin_Changed : Plugin_Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Hook_NormalSound_CSGO(int clients[MAXPLAYERS], int &numClients, char sample[PLATFORM_MAX_PATH],
|
|
||||||
int &entity, int &channel, float &volume, int &level, int &pitch, int &flags,
|
|
||||||
char soundEntry[PLATFORM_MAX_PATH], int &seed)
|
|
||||||
{
|
|
||||||
if(!g_bStopWeaponSoundsHooked)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
// Ignore non-weapon sounds.
|
|
||||||
if(channel != SNDCHAN_WEAPON &&
|
|
||||||
!(channel == SNDCHAN_AUTO && strncmp(sample, "physics/flesh", 13) == 0) &&
|
|
||||||
!(channel == SNDCHAN_STATIC && StrContains(sample, "player/headshot", true) != -1))
|
|
||||||
{
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
int j = 0;
|
|
||||||
for(int i = 0; i < numClients; i++)
|
|
||||||
{
|
|
||||||
int client = clients[i];
|
|
||||||
if(!g_bStopWeaponSounds[client] && IsClientInGame(client))
|
|
||||||
{
|
|
||||||
// Keep client.
|
|
||||||
clients[j] = clients[i];
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
numClients = j;
|
|
||||||
|
|
||||||
return (numClients > 0) ? Plugin_Changed : Plugin_Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Hook_ShotgunShot(const char[] te_name, const int[] Players, int numClients, float delay)
|
|
||||||
{
|
|
||||||
if(!g_bStopWeaponSoundsHooked)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
// Check which clients need to be excluded.
|
|
||||||
int[] newClients = new int[numClients];
|
|
||||||
int newTotal = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i < numClients; i++)
|
|
||||||
{
|
|
||||||
if(!g_bStopWeaponSounds[Players[i]])
|
|
||||||
{
|
|
||||||
newClients[newTotal++] = Players[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(newTotal == numClients)
|
|
||||||
{
|
|
||||||
// No clients were excluded.
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
else if(newTotal == 0)
|
|
||||||
{
|
|
||||||
// All clients were excluded and there is no need to broadcast.
|
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Re-broadcast to clients that still need it.
|
|
||||||
if(GetEngineVersion() == Engine_CSGO)
|
|
||||||
{
|
|
||||||
float vTemp[3];
|
|
||||||
TE_Start("Shotgun Shot");
|
|
||||||
TE_ReadVector("m_vecOrigin", vTemp);
|
|
||||||
TE_WriteVector("m_vecOrigin", vTemp);
|
|
||||||
TE_WriteFloat("m_vecAngles[0]", TE_ReadFloat("m_vecAngles[0]"));
|
|
||||||
TE_WriteFloat("m_vecAngles[1]", TE_ReadFloat("m_vecAngles[1]"));
|
|
||||||
TE_WriteNum("m_weapon", TE_ReadNum("m_weapon"));
|
|
||||||
TE_WriteNum("m_iMode", TE_ReadNum("m_iMode"));
|
|
||||||
TE_WriteNum("m_iSeed", TE_ReadNum("m_iSeed"));
|
|
||||||
TE_WriteNum("m_iPlayer", TE_ReadNum("m_iPlayer"));
|
|
||||||
TE_WriteFloat("m_fInaccuracy", TE_ReadFloat("m_fInaccuracy"));
|
|
||||||
TE_WriteFloat("m_fSpread", TE_ReadFloat("m_fSpread"));
|
|
||||||
TE_Send(newClients, newTotal, delay);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
float vTemp[3];
|
|
||||||
TE_Start("Shotgun Shot");
|
|
||||||
TE_ReadVector("m_vecOrigin", vTemp);
|
|
||||||
TE_WriteVector("m_vecOrigin", vTemp);
|
|
||||||
TE_WriteFloat("m_vecAngles[0]", TE_ReadFloat("m_vecAngles[0]"));
|
|
||||||
TE_WriteFloat("m_vecAngles[1]", TE_ReadFloat("m_vecAngles[1]"));
|
|
||||||
TE_WriteNum("m_iWeaponID", TE_ReadNum("m_iWeaponID"));
|
|
||||||
TE_WriteNum("m_iMode", TE_ReadNum("m_iMode"));
|
|
||||||
TE_WriteNum("m_iSeed", TE_ReadNum("m_iSeed"));
|
|
||||||
TE_WriteNum("m_iPlayer", TE_ReadNum("m_iPlayer"));
|
|
||||||
TE_WriteFloat("m_fInaccuracy", TE_ReadFloat("m_fInaccuracy"));
|
|
||||||
TE_WriteFloat("m_fSpread", TE_ReadFloat("m_fSpread"));
|
|
||||||
TE_Send(newClients, newTotal, delay);
|
|
||||||
}
|
|
||||||
|
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Hook_ReloadEffect_CSS(UserMsg msg_id, BfRead msg, const int[] players, int playersNum, bool reliable, bool init)
|
|
||||||
{
|
|
||||||
if(!g_bStopWeaponSoundsHooked)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
int client = msg.ReadShort();
|
|
||||||
|
|
||||||
// Check which clients need to be excluded.
|
|
||||||
int[] newClients = new int[playersNum];
|
|
||||||
int newTotal = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i < playersNum; i++)
|
|
||||||
{
|
|
||||||
int client_ = players[i];
|
|
||||||
if(IsClientInGame(client_) && !g_bStopWeaponSounds[client_])
|
|
||||||
{
|
|
||||||
newClients[newTotal++] = client_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(newTotal == playersNum)
|
|
||||||
{
|
|
||||||
// No clients were excluded.
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
else if(newTotal == 0)
|
|
||||||
{
|
|
||||||
// All clients were excluded and there is no need to broadcast.
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataPack pack = new DataPack();
|
|
||||||
pack.WriteCell(client);
|
|
||||||
pack.WriteCell(newTotal);
|
|
||||||
|
|
||||||
for(int i = 0; i < newTotal; i++)
|
|
||||||
{
|
|
||||||
pack.WriteCell(newClients[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
RequestFrame(OnReloadEffect, pack);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Hook_ReloadEffect_CSGO(UserMsg msg_id, Protobuf msg, const int[] players, int playersNum, bool reliable, bool init)
|
|
||||||
{
|
|
||||||
if(!g_bStopWeaponSoundsHooked)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
int client = PbReadInt(msg, "entidx");
|
|
||||||
|
|
||||||
// Check which clients need to be excluded.
|
|
||||||
int[] newClients = new int[playersNum];
|
|
||||||
int newTotal = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i < playersNum; i++)
|
|
||||||
{
|
|
||||||
int client_ = players[i];
|
|
||||||
if(IsClientInGame(client_) && !g_bStopWeaponSounds[client_])
|
|
||||||
{
|
|
||||||
newClients[newTotal++] = client_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(newTotal == playersNum)
|
|
||||||
{
|
|
||||||
// No clients were excluded.
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
else if(newTotal == 0)
|
|
||||||
{
|
|
||||||
// All clients were excluded and there is no need to broadcast.
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
DataPack pack = new DataPack();
|
|
||||||
pack.WriteCell(client);
|
|
||||||
pack.WriteCell(newTotal);
|
|
||||||
|
|
||||||
for(int i = 0; i < newTotal; i++)
|
|
||||||
{
|
|
||||||
pack.WriteCell(newClients[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
RequestFrame(OnReloadEffect, pack);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnReloadEffect(DataPack pack)
|
|
||||||
{
|
|
||||||
pack.Reset();
|
|
||||||
int client = pack.ReadCell();
|
|
||||||
int newTotal = pack.ReadCell();
|
|
||||||
|
|
||||||
int[] players = new int[newTotal];
|
|
||||||
int playersNum = 0;
|
|
||||||
|
|
||||||
for(int i = 0; i < newTotal; i++)
|
|
||||||
{
|
|
||||||
int client_ = pack.ReadCell();
|
|
||||||
if(IsClientInGame(client_))
|
|
||||||
{
|
|
||||||
players[playersNum++] = client_;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CloseHandle(pack);
|
|
||||||
|
|
||||||
Handle ReloadEffect = StartMessage("ReloadEffect", players, playersNum, USERMSG_RELIABLE | USERMSG_BLOCKHOOKS);
|
|
||||||
if(GetFeatureStatus(FeatureType_Native, "GetUserMessageType") == FeatureStatus_Available && GetUserMessageType() == UM_Protobuf)
|
|
||||||
{
|
|
||||||
PbSetInt(ReloadEffect, "entidx", client);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
BfWriteShort(ReloadEffect, client);
|
|
||||||
}
|
|
||||||
|
|
||||||
EndMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Hook_AmbientSound(char sample[PLATFORM_MAX_PATH], int &entity, float &volume, int &level, int &pitch, float pos[3], int &flags, float &delay)
|
|
||||||
{
|
|
||||||
// Are we playing music?
|
|
||||||
if(!strncmp(sample, "music", 5, false) && !strncmp(sample, "#", 1, false))
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
char sEntity[16];
|
|
||||||
IntToString(EntIndexToEntRef(entity), sEntity, sizeof(sEntity));
|
|
||||||
|
|
||||||
g_MapMusic.SetString(sEntity, sample, true);
|
|
||||||
|
|
||||||
if(!g_bStopMapMusicHooked)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
switch(flags)
|
|
||||||
{
|
|
||||||
case(SND_NOFLAGS):
|
|
||||||
{
|
|
||||||
// Starting sound..
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if (!IsClientInGame(client) || g_bStopMapMusic[client])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Stop the old sound..
|
|
||||||
EmitSoundToClient(client, sample, entity, SNDCHAN_STATIC, SNDLEVEL_NONE, SND_STOPLOOPING, SNDVOL_NORMAL, SNDPITCH_NORMAL);
|
|
||||||
|
|
||||||
// Pass through the new sound..
|
|
||||||
EmitSoundToClient(client, sample, entity, SNDCHAN_STATIC, level, flags, volume, pitch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
// Nothing special going on.. Pass it through..
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if (!IsClientInGame(client) || g_bStopMapMusic[client])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
EmitSoundToClient(client, sample, entity, SNDCHAN_STATIC, level, flags, volume, pitch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Block the default sound..
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
@ -1,68 +0,0 @@
|
|||||||
"Phrases"
|
|
||||||
{
|
|
||||||
"Chat Prefix"
|
|
||||||
{
|
|
||||||
"en" "{green}[StopSound]{default}"
|
|
||||||
"ru" "{green}[StopSound]{default}"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Weapon sounds enabled"
|
|
||||||
{
|
|
||||||
"en" "Weapon sounds {green}enabled{default}!"
|
|
||||||
"ru" "Звуки стрельбы {green}включены{default}!"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Weapon sounds disabled"
|
|
||||||
{
|
|
||||||
"en" "Weapon sounds {darkred}disabled{default}!"
|
|
||||||
"ru" "Звуки стрельбы {darkred}отключены{default}!"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Map music enabled"
|
|
||||||
{
|
|
||||||
"en" "Map music {green}enabled{default}!"
|
|
||||||
"ru" "Музыка на картах {green}включена{default}!"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Map music disabled"
|
|
||||||
{
|
|
||||||
"en" "Map music {darkred}disabled{default}!"
|
|
||||||
"ru" "Музыка на картах {darkred}отключена{default}!"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Cookie Menu Stop Sounds"
|
|
||||||
{
|
|
||||||
"en" "Stop Sounds"
|
|
||||||
"ru" "Отключение звуков"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Cookie Menu Stop Sounds Title"
|
|
||||||
{
|
|
||||||
"en" "Stop Sounds Configuration"
|
|
||||||
"ru" "Настройки Отключения Звуков"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Weapon Sounds"
|
|
||||||
{
|
|
||||||
"en" "Weapon sounds"
|
|
||||||
"ru" "Звуки стрельбы"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Map Sounds"
|
|
||||||
{
|
|
||||||
"en" "Map music"
|
|
||||||
"ru" "Музыка на картах"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Disabled"
|
|
||||||
{
|
|
||||||
"en" ": Disabled"
|
|
||||||
"ru" " [Выключено]"
|
|
||||||
}
|
|
||||||
|
|
||||||
"Enabled"
|
|
||||||
{
|
|
||||||
"en" ": Enabled"
|
|
||||||
"ru" " [Включено]"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,38 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "sv_gravity fix",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Resets sv_gravity at game_end and prevents stupid admins from crashing your server.",
|
|
||||||
version = "1.1",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
ConVar g_ConVar_SvGravity;
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
g_ConVar_SvGravity = FindConVar("sv_gravity");
|
|
||||||
g_ConVar_SvGravity.AddChangeHook(OnConVarChanged);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMapEnd()
|
|
||||||
{
|
|
||||||
g_ConVar_SvGravity.IntValue = 800;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
|
||||||
{
|
|
||||||
if(convar.IntValue < 1)
|
|
||||||
{
|
|
||||||
convar.IntValue = 800;
|
|
||||||
for(int i = 0; i < 10; i++)
|
|
||||||
PrintToChatAll("Setting sv_gravity to values less than 1 will crash the server!!!");
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,206 +0,0 @@
|
|||||||
#include <sourcemod>
|
|
||||||
#include <cstrike>
|
|
||||||
|
|
||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#define MIN_PLAYERS 2
|
|
||||||
|
|
||||||
int g_iWarmup = 0;
|
|
||||||
bool g_bWarmup = false;
|
|
||||||
ConVar g_CVar_sm_warmuptime;
|
|
||||||
ConVar g_CVar_sm_warmupratio;
|
|
||||||
|
|
||||||
bool g_bRoundEnded = false;
|
|
||||||
bool g_bZombieSpawned = false;
|
|
||||||
int g_TeamChangeQueue[MAXPLAYERS + 1] = { -1, ... };
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "TeamManager",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "",
|
|
||||||
version = "1.0",
|
|
||||||
url = "https://github.com/CSSZombieEscape/sm-plugins/tree/master/TeamManager"
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
if (GetEngineVersion() == Engine_CSGO)
|
|
||||||
AddCommandListener(OnJoinTeamCommand, "joingame");
|
|
||||||
|
|
||||||
AddCommandListener(OnJoinTeamCommand, "jointeam");
|
|
||||||
HookEvent("round_start", OnRoundStart, EventHookMode_Pre);
|
|
||||||
HookEvent("round_end", OnRoundEnd, EventHookMode_PostNoCopy);
|
|
||||||
|
|
||||||
g_CVar_sm_warmuptime = CreateConVar("sm_warmuptime", "10", "Warmup timer.", 0, true, 0.0, true, 60.0);
|
|
||||||
g_CVar_sm_warmupratio = CreateConVar("sm_warmupratio", "0.60", "Ratio of connected players that need to be in game to start warmup timer.", 0, true, 0.0, true, 1.0);
|
|
||||||
|
|
||||||
AutoExecConfig(true, "plugin.TeamManager");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMapStart()
|
|
||||||
{
|
|
||||||
g_iWarmup = 0;
|
|
||||||
g_bWarmup = false;
|
|
||||||
g_bRoundEnded = false;
|
|
||||||
g_bZombieSpawned = false;
|
|
||||||
|
|
||||||
if(g_CVar_sm_warmuptime.IntValue > 0 || g_CVar_sm_warmupratio.FloatValue > 0.0)
|
|
||||||
{
|
|
||||||
g_bWarmup = true;
|
|
||||||
CreateTimer(1.0, OnWarmupTimer, 0, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnWarmupTimer(Handle timer)
|
|
||||||
{
|
|
||||||
if(g_CVar_sm_warmupratio.FloatValue > 0.0)
|
|
||||||
{
|
|
||||||
int ClientsConnected = GetClientCount(false);
|
|
||||||
int ClientsInGame = GetClientCount(true);
|
|
||||||
int ClientsNeeded = RoundToCeil(float(ClientsConnected) * g_CVar_sm_warmupratio.FloatValue);
|
|
||||||
ClientsNeeded = ClientsNeeded > MIN_PLAYERS ? ClientsNeeded : MIN_PLAYERS;
|
|
||||||
|
|
||||||
if(ClientsInGame < ClientsNeeded)
|
|
||||||
{
|
|
||||||
g_iWarmup = 0;
|
|
||||||
PrintCenterTextAll("Warmup: Waiting for %d more players to join.", ClientsNeeded - ClientsInGame);
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(g_iWarmup >= g_CVar_sm_warmuptime.IntValue)
|
|
||||||
{
|
|
||||||
g_iWarmup = 0;
|
|
||||||
g_bWarmup = false;
|
|
||||||
CS_TerminateRound(3.0, CSRoundEnd_GameStart, false);
|
|
||||||
return Plugin_Stop;
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintCenterTextAll("Warmup: %d", g_CVar_sm_warmuptime.IntValue - g_iWarmup);
|
|
||||||
g_iWarmup++;
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientDisconnect(int client)
|
|
||||||
{
|
|
||||||
g_TeamChangeQueue[client] = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnJoinTeamCommand(int client, const char[] command, int argc)
|
|
||||||
{
|
|
||||||
if(client < 1 || client >= MaxClients || !IsClientInGame(client))
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
if(StrEqual(command, "joingame", false))
|
|
||||||
{
|
|
||||||
if(GetClientTeam(client) != CS_TEAM_NONE)
|
|
||||||
return Plugin_Continue;
|
|
||||||
|
|
||||||
ShowVGUIPanel(client, "team");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
char sArg[8];
|
|
||||||
GetCmdArg(1, sArg, sizeof(sArg));
|
|
||||||
|
|
||||||
int CurrentTeam = GetClientTeam(client);
|
|
||||||
int NewTeam = StringToInt(sArg);
|
|
||||||
|
|
||||||
if(NewTeam < CS_TEAM_NONE || NewTeam > CS_TEAM_CT)
|
|
||||||
return Plugin_Handled;
|
|
||||||
|
|
||||||
if(g_bRoundEnded)
|
|
||||||
{
|
|
||||||
if(NewTeam == CS_TEAM_T || NewTeam == CS_TEAM_NONE)
|
|
||||||
NewTeam = CS_TEAM_CT;
|
|
||||||
|
|
||||||
if(NewTeam == CurrentTeam)
|
|
||||||
{
|
|
||||||
if(g_TeamChangeQueue[client] != -1)
|
|
||||||
{
|
|
||||||
g_TeamChangeQueue[client] = -1;
|
|
||||||
PrintCenterText(client, "Team change request canceled.");
|
|
||||||
}
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
g_TeamChangeQueue[client] = NewTeam;
|
|
||||||
PrintCenterText(client, "You will be placed in the selected team shortly.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!g_bZombieSpawned)
|
|
||||||
{
|
|
||||||
if(NewTeam == CS_TEAM_T || NewTeam == CS_TEAM_NONE)
|
|
||||||
NewTeam = CS_TEAM_CT;
|
|
||||||
}
|
|
||||||
else if(NewTeam == CS_TEAM_CT || NewTeam == CS_TEAM_NONE)
|
|
||||||
NewTeam = CS_TEAM_T;
|
|
||||||
|
|
||||||
if(NewTeam == CurrentTeam)
|
|
||||||
return Plugin_Handled;
|
|
||||||
|
|
||||||
ChangeClientTeam(client, NewTeam);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnRoundStart(Event event, const char[] name, bool dontBroadcast)
|
|
||||||
{
|
|
||||||
g_bRoundEnded = false;
|
|
||||||
g_bZombieSpawned = false;
|
|
||||||
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(!IsClientInGame(client))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
int CurrentTeam = GetClientTeam(client);
|
|
||||||
int NewTeam = CS_TEAM_CT;
|
|
||||||
|
|
||||||
if(g_TeamChangeQueue[client] != -1)
|
|
||||||
{
|
|
||||||
NewTeam = g_TeamChangeQueue[client];
|
|
||||||
g_TeamChangeQueue[client] = -1;
|
|
||||||
}
|
|
||||||
else if(CurrentTeam <= CS_TEAM_SPECTATOR)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(NewTeam == CurrentTeam)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(NewTeam >= CS_TEAM_T)
|
|
||||||
CS_SwitchTeam(client, NewTeam);
|
|
||||||
else
|
|
||||||
ChangeClientTeam(client, NewTeam);
|
|
||||||
|
|
||||||
if(NewTeam >= CS_TEAM_T && !IsPlayerAlive(client))
|
|
||||||
CS_RespawnPlayer(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnRoundEnd(Event event, const char[] name, bool dontBroadcast)
|
|
||||||
{
|
|
||||||
g_bRoundEnded = true;
|
|
||||||
g_bZombieSpawned = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action CS_OnTerminateRound(float &delay, CSRoundEndReason &reason)
|
|
||||||
{
|
|
||||||
if(g_bWarmup)
|
|
||||||
return Plugin_Handled;
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action ZR_OnClientInfect(int &client, int &attacker, bool &motherInfect, bool &respawnOverride, bool &respawn)
|
|
||||||
{
|
|
||||||
if(g_bWarmup)
|
|
||||||
return Plugin_Handled;
|
|
||||||
|
|
||||||
g_bZombieSpawned = true;
|
|
||||||
|
|
||||||
return Plugin_Continue;
|
|
||||||
}
|
|
@ -1,330 +0,0 @@
|
|||||||
#pragma semicolon 1
|
|
||||||
|
|
||||||
#include <sourcemod>
|
|
||||||
#include <sdktools>
|
|
||||||
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "Teleport Commands",
|
|
||||||
author = "Obus",
|
|
||||||
description = "Adds commands to teleport clients.",
|
|
||||||
version = "1.3.1",
|
|
||||||
url = "https://github.com/CSSZombieEscape/sm-plugins/blob/master/Teleport/"
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
LoadTranslations("common.phrases");
|
|
||||||
|
|
||||||
RegAdminCmd("sm_bring", Command_Bring, ADMFLAG_GENERIC, "Brings a client to your position.");
|
|
||||||
RegAdminCmd("sm_goto", Command_Goto, ADMFLAG_GENERIC, "Teleport to a client.");
|
|
||||||
RegAdminCmd("sm_send", Command_Send, ADMFLAG_GENERIC, "Send a client to another client.");
|
|
||||||
RegAdminCmd("sm_tpaim", Command_TpAim, ADMFLAG_GENERIC, "Teleport a client to your aimpoint.");
|
|
||||||
}
|
|
||||||
|
|
||||||
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 <name|#userid>");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
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_ALIVE, sTargetName, sizeof(sTargetName), bIsML)) <= 0)
|
|
||||||
{
|
|
||||||
ReplyToTargetError(client, iTargetCount);
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
float vecClientPos[3];
|
|
||||||
|
|
||||||
GetClientAbsOrigin(client, vecClientPos);
|
|
||||||
|
|
||||||
for (int i = 0; i < iTargetCount; i++)
|
|
||||||
{
|
|
||||||
TeleportEntity(iTargets[i], vecClientPos, NULL_VECTOR, NULL_VECTOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowActivity2(client, "\x01[SM] \x04", "\x01Brought \x04%s\x01", sTargetName);
|
|
||||||
|
|
||||||
if (iTargetCount > 1)
|
|
||||||
LogAction(client, -1, "\"%L\" brought \"%s\"", client, sTargetName);
|
|
||||||
else
|
|
||||||
LogAction(client, iTargets[0], "\"%L\" brought \"%L\"", client, iTargets[0]);
|
|
||||||
|
|
||||||
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 <name|#userid|@aim>");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
int iTarget;
|
|
||||||
char sTarget[32];
|
|
||||||
|
|
||||||
GetCmdArg(1, sTarget, sizeof(sTarget));
|
|
||||||
|
|
||||||
if (strcmp(sTarget, "@aim") == 0)
|
|
||||||
{
|
|
||||||
if (argc > 1)
|
|
||||||
{
|
|
||||||
char sOption[2];
|
|
||||||
|
|
||||||
GetCmdArg(2, sOption, sizeof(sOption));
|
|
||||||
|
|
||||||
if (StringToInt(sOption) <= 0)
|
|
||||||
{
|
|
||||||
float vecAimPoint[3];
|
|
||||||
|
|
||||||
if (!TracePlayerAngles(client, vecAimPoint))
|
|
||||||
{
|
|
||||||
PrintToChat(client, "[SM] Couldn't perform trace to your aimpoint.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
TeleportEntity(client, vecAimPoint, NULL_VECTOR, NULL_VECTOR);
|
|
||||||
|
|
||||||
ShowActivity3(client, "\x01[SM] \x04", "\x01Teleported to their aimpoint.");
|
|
||||||
ReplyToCommand(client, "[SM] Teleported you to your aimpoint.");
|
|
||||||
LogAction(client, -1, "\"%L\" teleported to their aimpoint", client);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int iAimTarget = GetClientAimTarget(client, true);
|
|
||||||
|
|
||||||
if (iAimTarget == -1)
|
|
||||||
{
|
|
||||||
float vecAimPoint[3];
|
|
||||||
|
|
||||||
if (!TracePlayerAngles(client, vecAimPoint))
|
|
||||||
{
|
|
||||||
PrintToChat(client, "[SM] Couldn't perform trace to your aimpoint.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
TeleportEntity(client, vecAimPoint, NULL_VECTOR, NULL_VECTOR);
|
|
||||||
|
|
||||||
ShowActivity3(client, "\x01[SM] \x04", "\x01Teleported to their aimpoint.");
|
|
||||||
ReplyToCommand(client, "[SM] Teleported you to your aimpoint.");
|
|
||||||
LogAction(client, -1, "\"%L\" teleported to their aimpoint", client);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((iTarget = FindTarget(client, sTarget)) <= 0)
|
|
||||||
return Plugin_Handled;
|
|
||||||
|
|
||||||
float vecTargetPos[3];
|
|
||||||
|
|
||||||
GetClientAbsOrigin(iTarget, vecTargetPos);
|
|
||||||
|
|
||||||
TeleportEntity(client, vecTargetPos, NULL_VECTOR, NULL_VECTOR);
|
|
||||||
|
|
||||||
ShowActivity2(client, "\x01[SM] \x04", "\x01Teleported to \x04%N\x01.", iTarget);
|
|
||||||
LogAction(client, iTarget, "\"%L\" teleported to \"%L\"", client, iTarget);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Command_Send(int client, int argc)
|
|
||||||
{
|
|
||||||
if (argc < 2)
|
|
||||||
{
|
|
||||||
PrintToChat(client, "[SM] Usage: sm_send <name|#userid> <name|#userid>");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
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") == 0)
|
|
||||||
{
|
|
||||||
if (!client)
|
|
||||||
{
|
|
||||||
ReplyToCommand(client, "[SM] Cannot use \"sm_send @aim\" from server console.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
float vecAimPoint[3];
|
|
||||||
|
|
||||||
if (!TracePlayerAngles(client, vecAimPoint))
|
|
||||||
{
|
|
||||||
PrintToChat(client, "[SM] Couldn't perform trace to your aimpoint.");
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < iTargetCount; i++)
|
|
||||||
{
|
|
||||||
TeleportEntity(iTargets[i], vecAimPoint, NULL_VECTOR, NULL_VECTOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowActivity3(client, "\x01[SM] \x04", "\x01Teleported \x04%s\x01 to their aimpoint.", sTargetName);
|
|
||||||
ReplyToCommand(client, "\x01[SM] Teleported \x04%s\x01 to your aimpoint.", sTargetName);
|
|
||||||
|
|
||||||
if (iTargetCount > 1)
|
|
||||||
LogAction(client, -1, "\"%L\" teleported target \"%s\" to their aimpoint", client, sTargetName);
|
|
||||||
else
|
|
||||||
LogAction(client, iTargets[0], "\"%L\" teleported target \"%L\" to their aimpoint", client, iTargets[0]);
|
|
||||||
|
|
||||||
return Plugin_Handled;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((iTarget = FindTarget(client, sTarget)) <= 0)
|
|
||||||
return Plugin_Handled;
|
|
||||||
|
|
||||||
float vecTargetPos[3];
|
|
||||||
|
|
||||||
GetClientAbsOrigin(iTarget, vecTargetPos);
|
|
||||||
|
|
||||||
for (int i = 0; i < iTargetCount; i++)
|
|
||||||
{
|
|
||||||
TeleportEntity(iTargets[i], vecTargetPos, NULL_VECTOR, NULL_VECTOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowActivity2(client, "\x01[SM] \x04", "\x01Teleported \x04%s\x01 to \x04%N\x01.", sTargetName, iTarget);
|
|
||||||
|
|
||||||
if (iTargetCount > 1)
|
|
||||||
LogAction(client, -1, "\"%L\" teleported target \"%s\" to \"%L\"", client, sTargetName, iTarget);
|
|
||||||
else
|
|
||||||
LogAction(client, iTargets[0], "\"%L\" teleported target \"%L\" to \"%L\"", client, iTargets[0], 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
float vecAimPoint[3];
|
|
||||||
|
|
||||||
TracePlayerAngles(client, vecAimPoint);
|
|
||||||
|
|
||||||
for (int i = 0; i < iTargetCount; i++)
|
|
||||||
{
|
|
||||||
TeleportEntity(iTargets[i], vecAimPoint, NULL_VECTOR, NULL_VECTOR);
|
|
||||||
}
|
|
||||||
|
|
||||||
ShowActivity3(client, "\x01[SM] \x04", "\x01Teleported \x04%s\x01 to their aimpoint.", sTargetName);
|
|
||||||
ReplyToCommand(client, "\x01[SM] Teleported \x04%s\x01 to your aimpoint.", sTargetName);
|
|
||||||
|
|
||||||
if (iTargetCount > 1)
|
|
||||||
LogAction(client, -1, "\"%L\" teleported \"%s\" to their aimpoint", client, sTargetName);
|
|
||||||
else
|
|
||||||
LogAction(client, iTargets[0], "\"%L\" teleported \"%L\" to their aimpoint", client, iTargets[0]);
|
|
||||||
|
|
||||||
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, TraceEntityFilter_FilterPlayers);
|
|
||||||
|
|
||||||
if (TR_DidHit(hTraceRay))
|
|
||||||
{
|
|
||||||
TR_GetEndPosition(vecResult, hTraceRay);
|
|
||||||
|
|
||||||
delete hTraceRay;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
delete hTraceRay;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
stock bool TraceEntityFilter_FilterPlayers(int entity, int contentsMask)
|
|
||||||
{
|
|
||||||
return entity > MaxClients;
|
|
||||||
}
|
|
||||||
|
|
||||||
stock void ShowActivity3(int client, const char[] tag, const char[] fmt, any ...)
|
|
||||||
{
|
|
||||||
char sFinal[255];
|
|
||||||
char sFormatted[255];
|
|
||||||
char sActivitySource[MAX_NAME_LENGTH];
|
|
||||||
|
|
||||||
FormatActivitySource(client, client, sActivitySource, sizeof(sActivitySource));
|
|
||||||
|
|
||||||
VFormat(sFormatted, sizeof(sFormatted), fmt, 4);
|
|
||||||
|
|
||||||
Format(sFinal, sizeof(sFinal), "%s%s: %s", tag, sActivitySource, sFormatted);
|
|
||||||
|
|
||||||
for (int i = 1; i <= MaxClients; i++)
|
|
||||||
{
|
|
||||||
if (!IsClientInGame(i) || IsFakeClient(i) || i == client)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
PrintToChat(i, sFinal);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,304 +0,0 @@
|
|||||||
#include <sourcemod>
|
|
||||||
#include <sdkhooks>
|
|
||||||
#include <sdktools>
|
|
||||||
|
|
||||||
#pragma semicolon 1
|
|
||||||
#pragma newdecls required
|
|
||||||
|
|
||||||
#define TIMER_INTERVAL 1.0
|
|
||||||
Handle g_hTimer = INVALID_HANDLE;
|
|
||||||
|
|
||||||
ConVar g_CVar_MaxWeapons;
|
|
||||||
ConVar g_CVar_WeaponLifetime;
|
|
||||||
|
|
||||||
int g_RealRoundStartedTime;
|
|
||||||
int g_MaxWeapons;
|
|
||||||
int g_MaxWeaponLifetime;
|
|
||||||
|
|
||||||
bool g_bEnableCSGOFix;
|
|
||||||
|
|
||||||
#define MAX_WEAPONS MAXPLAYERS
|
|
||||||
int G_WeaponArray[MAX_WEAPONS][2];
|
|
||||||
|
|
||||||
|
|
||||||
public Plugin myinfo =
|
|
||||||
{
|
|
||||||
name = "WeaponCleaner",
|
|
||||||
author = "BotoX",
|
|
||||||
description = "Clean unneeded weapons",
|
|
||||||
version = "2.2.1",
|
|
||||||
url = ""
|
|
||||||
};
|
|
||||||
|
|
||||||
public void OnPluginStart()
|
|
||||||
{
|
|
||||||
g_bEnableCSGOFix = view_as<bool>(GetEngineVersion() == Engine_CSGO);
|
|
||||||
|
|
||||||
g_CVar_MaxWeapons = CreateConVar("sm_weaponcleaner_max", "5", "The maximum amount of weapons allowed in the game.", 0, true, 0.0, true, MAX_WEAPONS - 1.0);
|
|
||||||
g_MaxWeapons = g_CVar_MaxWeapons.IntValue;
|
|
||||||
g_CVar_MaxWeapons.AddChangeHook(OnConVarChanged);
|
|
||||||
|
|
||||||
g_CVar_WeaponLifetime = CreateConVar("sm_weaponcleaner_lifetime", "15", "The maximum number of seconds a weapon is allowed in the game.", 0, true, 0.0);
|
|
||||||
g_MaxWeaponLifetime = g_CVar_WeaponLifetime.IntValue;
|
|
||||||
g_CVar_WeaponLifetime.AddChangeHook(OnConVarChanged);
|
|
||||||
|
|
||||||
HookEvent("round_start", Event_RoundStart);
|
|
||||||
|
|
||||||
AutoExecConfig(true, "plugin.WeaponCleaner");
|
|
||||||
|
|
||||||
for(int client = 1; client <= MaxClients; client++)
|
|
||||||
{
|
|
||||||
if(IsClientInGame(client))
|
|
||||||
OnClientPutInServer(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnConVarChanged(ConVar convar, const char[] oldValue, const char[] newValue)
|
|
||||||
{
|
|
||||||
if(convar == g_CVar_MaxWeapons)
|
|
||||||
{
|
|
||||||
if(StringToInt(newValue) < StringToInt(oldValue))
|
|
||||||
{
|
|
||||||
// Need to shrink list and kill items
|
|
||||||
int d = StringToInt(oldValue) - StringToInt(newValue);
|
|
||||||
|
|
||||||
// Kill items that don't have space anymore
|
|
||||||
for(int i = 0; d && i < g_MaxWeapons; i++)
|
|
||||||
{
|
|
||||||
if(!G_WeaponArray[i][0])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Kill it
|
|
||||||
if(KillWeapon(G_WeaponArray[i][0]))
|
|
||||||
{
|
|
||||||
// Move index backwards (since the list was modified by removing it)
|
|
||||||
i--;
|
|
||||||
d--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g_MaxWeapons = StringToInt(newValue);
|
|
||||||
}
|
|
||||||
else if(convar == g_CVar_WeaponLifetime)
|
|
||||||
{
|
|
||||||
g_MaxWeaponLifetime = StringToInt(newValue);
|
|
||||||
CheckWeapons();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMapStart()
|
|
||||||
{
|
|
||||||
if(g_hTimer != INVALID_HANDLE && CloseHandle(g_hTimer))
|
|
||||||
g_hTimer = INVALID_HANDLE;
|
|
||||||
|
|
||||||
g_hTimer = CreateTimer(TIMER_INTERVAL, Timer_CleanupWeapons, INVALID_HANDLE, TIMER_REPEAT);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnMapEnd()
|
|
||||||
{
|
|
||||||
if(g_hTimer != INVALID_HANDLE && CloseHandle(g_hTimer))
|
|
||||||
g_hTimer = INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientPutInServer(int client)
|
|
||||||
{
|
|
||||||
SDKHook(client, SDKHook_WeaponDropPost, OnWeaponDrop);
|
|
||||||
SDKHook(client, SDKHook_WeaponEquipPost, OnWeaponEquip);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnClientDisconnect(int client)
|
|
||||||
{
|
|
||||||
SDKUnhook(client, SDKHook_WeaponDropPost, OnWeaponDrop);
|
|
||||||
SDKUnhook(client, SDKHook_WeaponEquipPost, OnWeaponEquip);
|
|
||||||
|
|
||||||
if(!IsClientInGame(client))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Simulate dropping all equipped weapons
|
|
||||||
for(int i = 0; i < 5; i++)
|
|
||||||
{
|
|
||||||
int weapon = GetPlayerWeaponSlot(client, i);
|
|
||||||
if(weapon != -1)
|
|
||||||
OnWeaponDrop(client, weapon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnEntityCreated(int entity, const char[] classname)
|
|
||||||
{
|
|
||||||
if(IsValidEntity(entity) && strncmp(classname, "weapon_", 7) == 0)
|
|
||||||
{
|
|
||||||
SDKHook(entity, SDKHook_Spawn, OnWeaponSpawned);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnEntityDestroyed(int entity)
|
|
||||||
{
|
|
||||||
// wtf sourcemod?
|
|
||||||
if(entity == -1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
RemoveWeapon(EntIndexToEntRef(EntRefToEntIndex(entity)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnWeaponSpawned(int entity)
|
|
||||||
{
|
|
||||||
if (g_bEnableCSGOFix)
|
|
||||||
{
|
|
||||||
SDKUnhook(entity, SDKHook_Spawn, OnWeaponSpawned);
|
|
||||||
|
|
||||||
RequestFrame(OnWeaponSpawnedPost, entity);
|
|
||||||
}
|
|
||||||
else OnWeaponSpawnedPost(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void OnWeaponSpawnedPost(int entity)
|
|
||||||
{
|
|
||||||
if(!IsValidEntity(entity))
|
|
||||||
return;
|
|
||||||
|
|
||||||
int HammerID = GetEntProp(entity, Prop_Data, "m_iHammerID");
|
|
||||||
// Should not be cleaned since it's a map spawned weapon
|
|
||||||
if(HammerID)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Weapon doesn't belong to any player
|
|
||||||
if(GetEntPropEnt(entity, Prop_Data, "m_hOwnerEntity") == -1)
|
|
||||||
InsertWeapon(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnWeaponEquip(int client, int entity)
|
|
||||||
{
|
|
||||||
if(!IsValidEntity(entity))
|
|
||||||
return;
|
|
||||||
|
|
||||||
int HammerID = GetEntProp(entity, Prop_Data, "m_iHammerID");
|
|
||||||
// Should not be cleaned since it's a map spawned weapon
|
|
||||||
if(HammerID)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Weapon should not be cleaned anymore
|
|
||||||
RemoveWeapon(EntIndexToEntRef(entity));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action OnWeaponDrop(int client, int entity)
|
|
||||||
{
|
|
||||||
if(!IsValidEntity(entity))
|
|
||||||
return;
|
|
||||||
|
|
||||||
int HammerID = GetEntProp(entity, Prop_Data, "m_iHammerID");
|
|
||||||
// Should not be cleaned since it's a map spawned weapon
|
|
||||||
if(HammerID)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Kill all dropped weapons during mp_freezetime
|
|
||||||
// or if no weapons are allowed at all
|
|
||||||
if(GetTime() < g_RealRoundStartedTime || !g_MaxWeapons)
|
|
||||||
{
|
|
||||||
// Kill it
|
|
||||||
AcceptEntityInput(entity, "Kill");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Weapon should be cleaned again
|
|
||||||
InsertWeapon(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InsertWeapon(int entity)
|
|
||||||
{
|
|
||||||
if(!g_MaxWeapons)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
int entref = EntIndexToEntRef(entity);
|
|
||||||
|
|
||||||
// Try to find a free slot
|
|
||||||
for(int i = 0; i < g_MaxWeapons; i++)
|
|
||||||
{
|
|
||||||
if(G_WeaponArray[i][0])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// Found a free slot, add it here
|
|
||||||
G_WeaponArray[i][0] = entref;
|
|
||||||
G_WeaponArray[i][1] = GetTime();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// No free slot found
|
|
||||||
// Kill the first (oldest) item in the list
|
|
||||||
KillWeapon(G_WeaponArray[0][0]);
|
|
||||||
|
|
||||||
// Add new weapon to the end of the list
|
|
||||||
G_WeaponArray[g_MaxWeapons - 1][0] = entref;
|
|
||||||
G_WeaponArray[g_MaxWeapons - 1][1] = GetTime();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool RemoveWeapon(int entref)
|
|
||||||
{
|
|
||||||
// Find the Weapon
|
|
||||||
for(int i = 0; i < g_MaxWeapons; i++)
|
|
||||||
{
|
|
||||||
if(G_WeaponArray[i][0] == entref)
|
|
||||||
{
|
|
||||||
G_WeaponArray[i][0] = 0; G_WeaponArray[i][1] = 0;
|
|
||||||
|
|
||||||
// Move list items in front of this index back by one
|
|
||||||
for(int j = i + 1; j < g_MaxWeapons; j++)
|
|
||||||
{
|
|
||||||
G_WeaponArray[j - 1][0] = G_WeaponArray[j][0];
|
|
||||||
G_WeaponArray[j - 1][1] = G_WeaponArray[j][1];
|
|
||||||
}
|
|
||||||
|
|
||||||
// Reset last list item
|
|
||||||
G_WeaponArray[g_MaxWeapons - 1][0] = 0;
|
|
||||||
G_WeaponArray[g_MaxWeapons - 1][1] = 0;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CheckWeapons()
|
|
||||||
{
|
|
||||||
for(int i = 0; i < g_MaxWeapons; i++)
|
|
||||||
{
|
|
||||||
if(!G_WeaponArray[i][0])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if(g_MaxWeaponLifetime && GetTime() - G_WeaponArray[i][1] >= g_MaxWeaponLifetime)
|
|
||||||
{
|
|
||||||
// Kill it
|
|
||||||
if(KillWeapon(G_WeaponArray[i][0]))
|
|
||||||
{
|
|
||||||
// Move index backwards (since the list was modified by removing it)
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool KillWeapon(int entref)
|
|
||||||
{
|
|
||||||
if(!IsValidEntity(entref))
|
|
||||||
return RemoveWeapon(entref);
|
|
||||||
|
|
||||||
AcceptEntityInput(entref, "Kill");
|
|
||||||
|
|
||||||
return RemoveWeapon(entref);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Event_RoundStart(Event event, const char[] name, bool dontBroadcast)
|
|
||||||
{
|
|
||||||
for(int i = 0; i < MAX_WEAPONS; i++)
|
|
||||||
{
|
|
||||||
G_WeaponArray[i][0] = 0;
|
|
||||||
G_WeaponArray[i][1] = 0;
|
|
||||||
}
|
|
||||||
g_RealRoundStartedTime = GetTime() + GetConVarInt(FindConVar("mp_freezetime"));
|
|
||||||
}
|
|
||||||
|
|
||||||
public Action Timer_CleanupWeapons(Handle timer)
|
|
||||||
{
|
|
||||||
CheckWeapons();
|
|
||||||
}
|
|
@ -1,59 +0,0 @@
|
|||||||
// Custom Chat Colors is written by Dr. McKay (http://www.doctormckay.com)
|
|
||||||
// Simple Chat Colors (Redux) is written by Antithasys
|
|
||||||
// The configuration is very similar, so I've stolen Redux's documentation :P
|
|
||||||
//
|
|
||||||
// How to edit this file:
|
|
||||||
// "admin_colors" <-- Leave this alone
|
|
||||||
// { <-- Add all groups/steamids after first bracket (Leave this alone)
|
|
||||||
//
|
|
||||||
// "STEAM_0:1:1234567" <-- Here is a steamid example with a tag (don't duplicate steamids)
|
|
||||||
// {
|
|
||||||
// "namecolor" "#RRGGBB" <-- This is the color for the name (#RRGGBB in hex notation or #RRGGBBAA with alpha)
|
|
||||||
// "textcolor" "#RRGGBBAA" <-- This is the color of the text
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// "groupname" <-- This can either be a steamid for a specific player, or a group name
|
|
||||||
// { <-- Open the group
|
|
||||||
// "flag" "z" <-- This is the flag(s) assoicated with the group. This field doesn't matter if the group name is a steamid
|
|
||||||
// "tag" "[admin]" <-- This is the text for the tag
|
|
||||||
// "tagcolor" "O" <-- This is the color for the tag
|
|
||||||
// "namecolor" "G" <-- This is the color for the name
|
|
||||||
// "textcolor" "T" <-- This is the color of the text
|
|
||||||
// } <-- Close the group
|
|
||||||
// } <-- Add all groups/steamids before last bracket (Leave this alone)
|
|
||||||
//
|
|
||||||
// NOTE:
|
|
||||||
// If you don't enter a steamid then the group name does not matter, it's just for your reference.
|
|
||||||
//
|
|
||||||
// For colors, either a hex notation of a color (#RRGGBB or #RRGGBBAA) or one of the supported shortcuts (O - Olive, G - Green, T - Team) is required
|
|
||||||
//
|
|
||||||
// --------ORDER OF OPERATIONS--------
|
|
||||||
//
|
|
||||||
// The order in which you place items in the config file matters. Here is what determins what color they get:
|
|
||||||
// 1. SteamID
|
|
||||||
// If there is a steamid present, it will always override everything. If you put a steamid in twice
|
|
||||||
// then the first entry (top to bottom) will be used. (I think, just don't do it!)
|
|
||||||
// 2. Groups
|
|
||||||
// The plugin will search (top to bottom) for a postitive match for the flag string. The player' flags
|
|
||||||
// will be compared with the group flag character (NOTE: only one flag per group! "a" is okay, "ab" is NOT),
|
|
||||||
// and if the player has the flag, it will stop there.
|
|
||||||
// For example. Admins with the "ad" flags and donators with the "a" flag. If you place the "a" flag group
|
|
||||||
// above the "d" group then the admin will get the "a" colors. Order matters.
|
|
||||||
//
|
|
||||||
// ---------DO NOT EDIT ABOVE THIS LINE---------
|
|
||||||
"admin_colors"
|
|
||||||
{
|
|
||||||
"STEAM_0:1:16"
|
|
||||||
{
|
|
||||||
"tag" "[BAILOPAN] "
|
|
||||||
"tagcolor" "O"
|
|
||||||
}
|
|
||||||
"VIP"
|
|
||||||
{
|
|
||||||
"flag" "a"
|
|
||||||
"tag" "[VIP] "
|
|
||||||
"tagcolor" "#9EC34FAA"
|
|
||||||
"namecolor" "#00CCFF"
|
|
||||||
"textcolor" "#000000AA"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
"restricted_users"
|
|
||||||
{
|
|
||||||
}
|
|
@ -1,67 +0,0 @@
|
|||||||
//custom-chatcolorsreplace.cfg
|
|
||||||
|
|
||||||
"AutoReplace"
|
|
||||||
{
|
|
||||||
":lenny:" "( ͡° ͜ʖ ͡°)"
|
|
||||||
":alenny:" "{red}( {orange}͡{yellow}°{green} ͜{lightblue}ʖ {blue}͡{purple}°{white})"
|
|
||||||
":ynnel:" "{red}({orange} {yellow}͜。{green} ͡{lightblue}ʖ {blue}͜{purple}。{white}) "
|
|
||||||
":rainbow:" "{red}( ͡° ͜ʖ ͡°) {orange} ( ͡° ͜ʖ ͡°) {yellow} ( ͡° ͜ʖ ͡°) {green} ( ͡° ͜ʖ ͡°) {blue} ( ͡° ͜ʖ ͡°) {indigo} ( ͡° ͜ʖ ͡°) {violet} ( ͡° ͜ʖ ͡°)"
|
|
||||||
":feel:" "( ´_ゝ`)"
|
|
||||||
":chill:" "( ≖‿≖)"
|
|
||||||
":cute:" "(´・ω・`)"
|
|
||||||
":shrug:" "¯\_(ツ)_/¯"
|
|
||||||
":smile:" "( ・◡・)"
|
|
||||||
":sad:" "( ´A`)"
|
|
||||||
":happy:" "(´∀`)"
|
|
||||||
":3:" "( ¯3¯)"
|
|
||||||
":dunno:" "┐(´д`)┌"
|
|
||||||
":please:" "(人・_・) pleaseeee!"
|
|
||||||
":table:" "(╯°□°)╯︵ ┻━┻"
|
|
||||||
":?:" "ヽ( ゚Д゚)ノ?"
|
|
||||||
":over:" "{red}͇̿ ͇̿ ̶͇̿ι͇̿ ͇̿ ̶͇̿ι {orange}|̶̿ ̶̿ ̶̶̿̿|{violet} |̿ V ̿| |̶͇̿ ̶͇̿ {green}͇̿ |͇̿ ͇̿ ͇̿| \ ͇{indigo} / |̶͇̿ ̶͇̿ ͇̿ |̿J"
|
|
||||||
":heart:" "{aqua}❤{violet}❤{fullred}❤{lightyellow}❤{lightgreen}❤{pink}❤{orange}❤{greenyellow}❤{white}❤{violet}❤{indigo}❤{navy}❤{firebrick}❤{fuchsia}❤{lime}❤{hotpink}❤"
|
|
||||||
":america:" "{white}< ̄`ヽ、 / ̄> {red}ゝ、( ͡° ͜ʖ ͡°) ノ {blue}ゝ ┴ ┴ ノ"
|
|
||||||
|
|
||||||
":ukraine:" "{mediumblue}
|
|
||||||
███████████ {yellow}
|
|
||||||
███████████ "
|
|
||||||
|
|
||||||
":russia:" "{white}
|
|
||||||
███████████{fullblue}
|
|
||||||
███████████{fullred}
|
|
||||||
███████████"
|
|
||||||
|
|
||||||
":germany:" "{black}
|
|
||||||
███████████{fullred}
|
|
||||||
███████████{yellow}
|
|
||||||
███████████"
|
|
||||||
|
|
||||||
":poland:" "{white}
|
|
||||||
███████████{fullred}
|
|
||||||
███████████"
|
|
||||||
|
|
||||||
":austria:" "{fullred}
|
|
||||||
███████████{white}
|
|
||||||
███████████{fullred}
|
|
||||||
███████████"
|
|
||||||
|
|
||||||
":france:" "
|
|
||||||
{fullblue}██{white}██{fullred}██
|
|
||||||
{fullblue}██{white}██{fullred}██
|
|
||||||
{fullblue}██{white}██{fullred}██"
|
|
||||||
|
|
||||||
":romania:" "
|
|
||||||
{navy}██{gold}██{fullred}██
|
|
||||||
{navy}██{gold}██{fullred}██
|
|
||||||
{navy}██{gold}██{fullred}██"
|
|
||||||
|
|
||||||
":italy:" "
|
|
||||||
{darkgreen}██{white}██{fullred}██
|
|
||||||
{darkgreen}██{white}██{fullred}██
|
|
||||||
{darkgreen}██{white}██{fullred}██"
|
|
||||||
|
|
||||||
":moldova:" "
|
|
||||||
{fullblue}██{gold}██{fullred}██
|
|
||||||
{fullblue}██{gold}██{fullred}██
|
|
||||||
{fullblue}██{gold}██{fullred}██"
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,191 +0,0 @@
|
|||||||
/**
|
|
||||||
* This is the include file for Custom Chat Colors
|
|
||||||
* https://forums.alliedmods.net/showthread.php?t=186695
|
|
||||||
* To check that Custom Chat Colors is installed and running, verify that the "ccc" library exists
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined _ccc_included
|
|
||||||
#endinput
|
|
||||||
#endif
|
|
||||||
#define _ccc_included
|
|
||||||
|
|
||||||
enum CCC_ColorType {
|
|
||||||
CCC_TagColor,
|
|
||||||
CCC_NameColor,
|
|
||||||
CCC_ChatColor
|
|
||||||
};
|
|
||||||
|
|
||||||
#define COLOR_NULL -1
|
|
||||||
#define COLOR_NONE -2
|
|
||||||
#define COLOR_CGREEN -3 //0x40FF40
|
|
||||||
#define COLOR_OLIVE -4 //0x99FF99
|
|
||||||
#define COLOR_TEAM -5
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a client's color as a hexadecimal integer.
|
|
||||||
*
|
|
||||||
* @param client Client index
|
|
||||||
* @param type Color type to retreive
|
|
||||||
* @param alpha Pass a boolean variable by reference here and it will be true if the color has alpha specified or false if it doesn't (or is a stock color)
|
|
||||||
* @return Color as a hexadecimal integer (use %X in formatting to get a hexadecimal string)
|
|
||||||
*
|
|
||||||
* On error/errors: Invalid client index or client is not in game
|
|
||||||
*/
|
|
||||||
native int CCC_GetColor(int client, CCC_ColorType type, bool &alpha = false);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a client's color as a hexadecimal integer.
|
|
||||||
*
|
|
||||||
* @param client Client index
|
|
||||||
* @param type Color type to set
|
|
||||||
* @param color Integer representation of the color (use StringToInt(input, 16) to convert a hexadecimal string) or one of the color defines
|
|
||||||
* @param alpha Are you specifying a color with alpha?
|
|
||||||
* @return True if the color is updated successfully, false otherwise
|
|
||||||
*
|
|
||||||
* On error/errors: Invalid client index or client is not in game
|
|
||||||
*/
|
|
||||||
native int CCC_SetColor(int client, CCC_ColorType type, int color, bool alpha);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets a client's tag
|
|
||||||
*
|
|
||||||
* @param client Client index
|
|
||||||
* @param buffer Buffer to store the tag in
|
|
||||||
* @param maxlen Maximum buffer length
|
|
||||||
* @noreturn
|
|
||||||
*
|
|
||||||
* On error/errors: Invalid client index or client is not in game
|
|
||||||
*/
|
|
||||||
native int CCC_GetTag(int client, char[] buffer, int maxlen);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Sets a client's tag
|
|
||||||
*
|
|
||||||
* @param client Client index
|
|
||||||
* @param tag String containing the new tag
|
|
||||||
* @noreturn
|
|
||||||
*
|
|
||||||
* On error/errors: Invalid client index or client is not in game
|
|
||||||
*/
|
|
||||||
native void CCC_SetTag(int client, const char[] tag);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets a client's color to the value in the config file.
|
|
||||||
*
|
|
||||||
* @param client Client index
|
|
||||||
* @param type Color type to restore
|
|
||||||
* @noreturn
|
|
||||||
*
|
|
||||||
* On error/errors: Invalid client index or client is not in game
|
|
||||||
*/
|
|
||||||
native int CCC_ResetColor(int client, CCC_ColorType type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Resets a client's tag to the value in the config file.
|
|
||||||
*
|
|
||||||
* @param client Client index
|
|
||||||
* @noreturn
|
|
||||||
*
|
|
||||||
* On error/errors: Invalid client index or client is not in game
|
|
||||||
*/
|
|
||||||
native int CCC_ResetTag(int client);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a cilent's name is about to be colored
|
|
||||||
* DO NOT START A NEW USERMESSAGE (i.e. PrintToChat, PrintToChatAll) WITHIN THIS FORWARD
|
|
||||||
*
|
|
||||||
* @param client Client index
|
|
||||||
* @return Plugin_Handled to prevent coloring, Plugin_Continue to allow coloring
|
|
||||||
*/
|
|
||||||
//#pragma deprecated Use CCC_OnColor instead
|
|
||||||
//forward Action:CCC_OnNameColor(client);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a client's chat is about to be colored
|
|
||||||
* DO NOT START A NEW USERMESSAGE (i.e. PrintToChat, PrintToChatAll) WITHIN THIS FORWARD
|
|
||||||
*
|
|
||||||
* @param client Client index
|
|
||||||
* @return Plugin_Handled to prevent coloring, Plugin_Continue to allow coloring
|
|
||||||
*/
|
|
||||||
//#pragma deprecated Use CCC_OnColor instead
|
|
||||||
//forward Action:CCC_OnChatColor(client);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a client's name is about to be tagged
|
|
||||||
* DO NOT START A NEW USERMESSAGE (i.e. PrintToChat, PrintToChatAll) WITHIN THIS FORWARD
|
|
||||||
*
|
|
||||||
* @param client Client index
|
|
||||||
* @return Plugin_Handled to prevent tagging, Plugin_Continue to allow tagging
|
|
||||||
*/
|
|
||||||
//#pragma deprecated Use CCC_OnColor instead
|
|
||||||
//forward Action:CCC_OnTagApplied(client);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a client's name is about to be tagged
|
|
||||||
* DO NOT START A NEW USERMESSAGE (i.e. PrintToChat, PrintToChatAll) WITHIN THIS FORWARD
|
|
||||||
*
|
|
||||||
* @param client Client index
|
|
||||||
* @param message Chat message that will be printed
|
|
||||||
* @param type What type of color will be applied. If this is CCC_TagColor, it controls whether the tag will be applied at all, not whether the tag will be colored.
|
|
||||||
* @return Plugin_Handled to prevent coloring, Plugin_Continue to allow coloring
|
|
||||||
*/
|
|
||||||
//forward Action:CCC_OnColor(client, const String:message[], CCC_ColorType:type);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a message has been fully colored and will be sent, unless further plugins modify it through Simple Chat Processor
|
|
||||||
*
|
|
||||||
* @param client Recieving client index
|
|
||||||
* @param author Author client index
|
|
||||||
* @param message Message
|
|
||||||
* @return Plugin_Handled to block message, Plugin_Continue to allow message
|
|
||||||
*/
|
|
||||||
forward Action CCC_OnChatMessage(int client, int author, const char[] message);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a client's colors and tag are about to be loaded from the config file
|
|
||||||
* At this point, the client has NO COLORS
|
|
||||||
*
|
|
||||||
* @param client Client index
|
|
||||||
* @return Plugin_Handled or Plugin_Stop to prevent loading, Plugin_Continue or Plugin_Changed to allow
|
|
||||||
*/
|
|
||||||
forward Action CCC_OnUserConfigPreLoaded(int client);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a client's colors and tag have been loaded from the config file
|
|
||||||
*
|
|
||||||
* @param client Client index
|
|
||||||
* @noreturn
|
|
||||||
*/
|
|
||||||
forward void CCC_OnUserConfigLoaded(int client);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when the configuration file is reloaded with the sm_reloadccc command
|
|
||||||
*
|
|
||||||
* @noreturn
|
|
||||||
*/
|
|
||||||
forward void CCC_OnConfigReloaded();
|
|
||||||
|
|
||||||
native int CCC_UpdateIgnoredArray(bool IgnoredArray[(MAXPLAYERS + 1) * (MAXPLAYERS + 1)]);
|
|
||||||
|
|
||||||
public SharedPlugin __pl_ccc =
|
|
||||||
{
|
|
||||||
name = "ccc",
|
|
||||||
file = "custom-chatcolors.smx",
|
|
||||||
#if defined REQUIRE_PLUGIN
|
|
||||||
required = 1
|
|
||||||
#else
|
|
||||||
required = 0
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#if !defined REQUIRE_PLUGIN
|
|
||||||
public __pl_ccc_SetNTVOptional() {
|
|
||||||
MarkNativeAsOptional("CCC_GetColor");
|
|
||||||
MarkNativeAsOptional("CCC_SetColor");
|
|
||||||
MarkNativeAsOptional("CCC_GetTag");
|
|
||||||
MarkNativeAsOptional("CCC_ResetTag");
|
|
||||||
MarkNativeAsOptional("CCC_ResetColor");
|
|
||||||
MarkNativeAsOptional("CCC_ResetTag");
|
|
||||||
MarkNativeAsOptional("CCC_UpdateIgnoredArray");
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,58 +0,0 @@
|
|||||||
"Phrases"
|
|
||||||
{
|
|
||||||
"Cstrike_Chat_CT_Loc"
|
|
||||||
{
|
|
||||||
"#format" "{1:s},{2:s}"
|
|
||||||
"en" "(Counter-Terrorist) {1} : {2}"
|
|
||||||
}
|
|
||||||
"Cstrike_Chat_CT"
|
|
||||||
{
|
|
||||||
"#format" "{1:s},{2:s}"
|
|
||||||
"en" "(Counter-Terrorist) {1} : {2}"
|
|
||||||
}
|
|
||||||
"Cstrike_Chat_T_Loc"
|
|
||||||
{
|
|
||||||
"#format" "{1:s},{2:s}"
|
|
||||||
"en" "(Terrorist) {1} : {2}"
|
|
||||||
}
|
|
||||||
"Cstrike_Chat_T"
|
|
||||||
{
|
|
||||||
"#format" "{1:s},{2:s}"
|
|
||||||
"en" "(Terrorist) {1} : {2}"
|
|
||||||
}
|
|
||||||
"Cstrike_Chat_CT_Dead"
|
|
||||||
{
|
|
||||||
"#format" "{1:s},{2:s}"
|
|
||||||
"en" "*DEAD*(Counter-Terrorist) {1} : {2}"
|
|
||||||
}
|
|
||||||
"Cstrike_Chat_T_Dead"
|
|
||||||
{
|
|
||||||
"#format" "{1:s},{2:s}"
|
|
||||||
"en" "*DEAD*(Terrorist) {1} : {2}"
|
|
||||||
}
|
|
||||||
"Cstrike_Chat_Spec"
|
|
||||||
{
|
|
||||||
"#format" "{1:s},{2:s}"
|
|
||||||
"en" "(Spectator) {1} : {2}"
|
|
||||||
}
|
|
||||||
"Cstrike_Chat_All"
|
|
||||||
{
|
|
||||||
"#format" "{1:s},{2:s}"
|
|
||||||
"en" "{1} : {2}"
|
|
||||||
}
|
|
||||||
"Cstrike_Chat_AllDead"
|
|
||||||
{
|
|
||||||
"#format" "{1:s},{2:s}"
|
|
||||||
"en" "*DEAD* {1} : {2}"
|
|
||||||
}
|
|
||||||
"Cstrike_Chat_AllSpec"
|
|
||||||
{
|
|
||||||
"#format" "{1:s},{2:s}"
|
|
||||||
"en" "*SPEC* {1} : {2}"
|
|
||||||
}
|
|
||||||
"Cstrike_Chat_Me"
|
|
||||||
{
|
|
||||||
"#format" "{1:s},{2:s}"
|
|
||||||
"en" "* {1} {2}"
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,28 +0,0 @@
|
|||||||
"Games"
|
|
||||||
{
|
|
||||||
"cstrike"
|
|
||||||
{
|
|
||||||
"Offsets"
|
|
||||||
{
|
|
||||||
"GetSlot"
|
|
||||||
{
|
|
||||||
"windows" "320"
|
|
||||||
"linux" "321"
|
|
||||||
}
|
|
||||||
"BumpWeapon"
|
|
||||||
{
|
|
||||||
"windows" "397"
|
|
||||||
"linux" "398"
|
|
||||||
}
|
|
||||||
"OnPickedUp"
|
|
||||||
{
|
|
||||||
"windows" "300"
|
|
||||||
"linux" "301"
|
|
||||||
}
|
|
||||||
"CBaseButton_m_toggle_state"
|
|
||||||
{
|
|
||||||
"linux" "848"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,150 +0,0 @@
|
|||||||
#if defined _entWatch_include
|
|
||||||
#endinput
|
|
||||||
#endif
|
|
||||||
#define _entWatch_include
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a client is currently banned, if an integer variable is referenced the time of unban will be assigned to it.
|
|
||||||
*
|
|
||||||
* @param client Client index to check for ban
|
|
||||||
* @param iTimeStamp Pass an integer variable by reference and it will contain the UNIX timestamp when the player will be unbanned
|
|
||||||
* @return True if user is banned, false otherwise
|
|
||||||
*
|
|
||||||
* On error/errors: Invalid client index/client is not in game or client cookies are not yet loaded
|
|
||||||
*/
|
|
||||||
native bool:entWatch_IsClientBanned(client, &iTimeStamp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Bans a client from using special items.
|
|
||||||
*
|
|
||||||
* @param client Client index to ban
|
|
||||||
* @param IsTemporary If the ban should be temporary pass true here
|
|
||||||
* @param iLength Length of ban in minutes, pass 0 here for a permanent ban
|
|
||||||
* @return True on success, false otherwsie
|
|
||||||
*
|
|
||||||
* On error/errors: Invalid client index/client is not in game or client cookies are not yet loaded
|
|
||||||
*/
|
|
||||||
native bool:entWatch_BanClient(client, bool:bIsTemporary=false, iLength=0);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unbans a previously ebanned Client.
|
|
||||||
*
|
|
||||||
* @param client Client index to unban
|
|
||||||
* @return True on success, false otherwsie
|
|
||||||
*
|
|
||||||
* On error/errors: Invalid client index/client is not in game or client cookies are not yet loaded
|
|
||||||
*/
|
|
||||||
native bool:entWatch_UnbanClient(client);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if an entity is a special item.
|
|
||||||
*
|
|
||||||
* @param entity Entity index to check
|
|
||||||
* @return True if entity is a special item, false otherwsie
|
|
||||||
*/
|
|
||||||
native bool:entWatch_IsSpecialItem(entity);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if a client has a special item.
|
|
||||||
*
|
|
||||||
* @param client Client index to check
|
|
||||||
* @return True if client has a special item, false otherwsie
|
|
||||||
*/
|
|
||||||
native bool:entWatch_HasSpecialItem(client);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a client is e-banned by any means
|
|
||||||
*
|
|
||||||
* @param admin Admin index that issued the ban
|
|
||||||
* @param iLength Length of the ban in UNIX time
|
|
||||||
* @param client Client index that was banned
|
|
||||||
*
|
|
||||||
* @return None
|
|
||||||
*/
|
|
||||||
forward entWatch_OnClientBanned(admin, iLenght, client);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Called when a client is e-unbanned by any means
|
|
||||||
*
|
|
||||||
* @param admin Admin index that removed the ban
|
|
||||||
* @param client Client index that was unbanned
|
|
||||||
* @return None
|
|
||||||
*/
|
|
||||||
forward entWatch_OnClientUnbanned(admin, client);
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose: SMLib
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
stock Entity_GetTargetName(entity, String:buffer[], size)
|
|
||||||
{
|
|
||||||
return GetEntPropString(entity, Prop_Data, "m_iName", buffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose: SMLib
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
stock Entity_GetParentName(entity, String:buffer[], size)
|
|
||||||
{
|
|
||||||
return GetEntPropString(entity, Prop_Data, "m_iParent", buffer, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose: SMLib
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
stock Entity_GetHammerID(entity)
|
|
||||||
{
|
|
||||||
return GetEntProp(entity, Prop_Data, "m_iHammerID");
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose: SMLib
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
stock Entity_GetClassName(entity, String:buffer[], size)
|
|
||||||
{
|
|
||||||
GetEntPropString(entity, Prop_Data, "m_iClassname", buffer, size);
|
|
||||||
|
|
||||||
if (buffer[0] == '\0') {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
// Purpose: SMLib
|
|
||||||
//----------------------------------------------------------------------------------------------------
|
|
||||||
stock Entity_GetEntityFromHammerID(hammerID)
|
|
||||||
{
|
|
||||||
for (new i = 0; i < 4096; i++)
|
|
||||||
{
|
|
||||||
if (IsValidEntity(i) && Entity_GetHammerID(i) == hammerID)
|
|
||||||
{
|
|
||||||
if (IsValidEntity(i))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SharedPlugin:__pl_entWatch =
|
|
||||||
{
|
|
||||||
name = "entWatch",
|
|
||||||
file = "entWatch.smx",
|
|
||||||
#if defined REQUIRE_PLUGIN
|
|
||||||
required = 1
|
|
||||||
#else
|
|
||||||
required = 0
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
|
|
||||||
#if !defined REQUIRE_PLUGIN
|
|
||||||
public __pl_entWatch_SetNTVOptional()
|
|
||||||
{
|
|
||||||
MarkNativeAsOptional("entWatch_IsClientBanned");
|
|
||||||
MarkNativeAsOptional("entWatch_BanClient");
|
|
||||||
MarkNativeAsOptional("entWatch_UnbanClient");
|
|
||||||
MarkNativeAsOptional("entWatch_IsSpecialItem");
|
|
||||||
MarkNativeAsOptional("entWatch_HasSpecialItem");
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,47 +0,0 @@
|
|||||||
"Phrases"
|
|
||||||
{
|
|
||||||
"welcome"
|
|
||||||
{
|
|
||||||
"en" "The current map is supported by this plugin."
|
|
||||||
}
|
|
||||||
"use"
|
|
||||||
{
|
|
||||||
"en" "used"
|
|
||||||
}
|
|
||||||
"pickup"
|
|
||||||
{
|
|
||||||
"en" "has picked up"
|
|
||||||
}
|
|
||||||
"drop"
|
|
||||||
{
|
|
||||||
"en" "has dropped"
|
|
||||||
}
|
|
||||||
"death"
|
|
||||||
{
|
|
||||||
"en" "has died with"
|
|
||||||
}
|
|
||||||
"disconnect"
|
|
||||||
{
|
|
||||||
"en" "disconnected with"
|
|
||||||
}
|
|
||||||
"cookies loading"
|
|
||||||
{
|
|
||||||
"en" "Please wait. Your settings are still loading."
|
|
||||||
}
|
|
||||||
"status restricted"
|
|
||||||
{
|
|
||||||
"en" "You are currently restricted."
|
|
||||||
}
|
|
||||||
"status unrestricted"
|
|
||||||
{
|
|
||||||
"en" "You are currently unrestricted."
|
|
||||||
}
|
|
||||||
"display enabled"
|
|
||||||
{
|
|
||||||
"en" "The hud is now enabled."
|
|
||||||
}
|
|
||||||
"display disabled"
|
|
||||||
{
|
|
||||||
"en" "The hud is now disabled."
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
"Phrases"
|
|
||||||
{
|
|
||||||
"welcome"
|
|
||||||
{
|
|
||||||
"fr" "La map actuelle fonctionne avec ce plugin."
|
|
||||||
}
|
|
||||||
"use"
|
|
||||||
{
|
|
||||||
"fr" "a utilisé"
|
|
||||||
}
|
|
||||||
"pickup"
|
|
||||||
{
|
|
||||||
"fr" "a pris"
|
|
||||||
}
|
|
||||||
"drop"
|
|
||||||
{
|
|
||||||
"fr" "a jeté"
|
|
||||||
}
|
|
||||||
"death"
|
|
||||||
{
|
|
||||||
"fr" "est mort avec"
|
|
||||||
}
|
|
||||||
"disconnect"
|
|
||||||
{
|
|
||||||
"fr" "s'est deconnecté avec"
|
|
||||||
}
|
|
||||||
"cookies loading"
|
|
||||||
{
|
|
||||||
"fr" "Merci d'attendre. Vos réglages sont en cours de chargement."
|
|
||||||
}
|
|
||||||
"status restricted"
|
|
||||||
{
|
|
||||||
"fr" "Vous êtes actuellement restreint."
|
|
||||||
}
|
|
||||||
"status unrestricted"
|
|
||||||
{
|
|
||||||
"fr" "Vous n'êtes pas restreint."
|
|
||||||
}
|
|
||||||
"display enabled"
|
|
||||||
{
|
|
||||||
"fr" "Le hud est maintenant activé."
|
|
||||||
}
|
|
||||||
"display disabled"
|
|
||||||
{
|
|
||||||
"fr" "Le hud est maintenant désactivé."
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,47 +0,0 @@
|
|||||||
"Phrases"
|
|
||||||
{
|
|
||||||
"welcome"
|
|
||||||
{
|
|
||||||
"ru" "Текущая карта работы с этим плагином."
|
|
||||||
}
|
|
||||||
"use"
|
|
||||||
{
|
|
||||||
"ru" "использовал"
|
|
||||||
}
|
|
||||||
"pickup"
|
|
||||||
{
|
|
||||||
"ru" "подобрал"
|
|
||||||
}
|
|
||||||
"drop"
|
|
||||||
{
|
|
||||||
"ru" "выбросил"
|
|
||||||
}
|
|
||||||
"death"
|
|
||||||
{
|
|
||||||
"ru" "умер и сбросил"
|
|
||||||
}
|
|
||||||
"disconnect"
|
|
||||||
{
|
|
||||||
"ru" "отключился из игры с"
|
|
||||||
}
|
|
||||||
"cookies loading"
|
|
||||||
{
|
|
||||||
"ru" "Пожалуйста ждите. Ваши параметры настройки все еще загружаются."
|
|
||||||
}
|
|
||||||
"status restricted"
|
|
||||||
{
|
|
||||||
"ru" "Вам запрещено юзать спец. оружие."
|
|
||||||
}
|
|
||||||
"status unrestricted"
|
|
||||||
{
|
|
||||||
"ru" "Вам разрешено юзать спец. оружие."
|
|
||||||
}
|
|
||||||
"display enabled"
|
|
||||||
{
|
|
||||||
"ru" "Информация Hud теперь включена."
|
|
||||||
}
|
|
||||||
"display disabled"
|
|
||||||
{
|
|
||||||
"ru" "Информация Hud теперь выключена."
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user