Misc: Move shared stuff to shared git.
This commit is contained in:
parent
d4378f6476
commit
8cdcb01100
130
AdminCheats/scripting/AdminCheats.sp
Normal file
130
AdminCheats/scripting/AdminCheats.sp
Normal file
@ -0,0 +1,130 @@
|
||||
#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);
|
||||
}
|
73
AdminIcon/scripting/AdminIcon.sp
Normal file
73
AdminIcon/scripting/AdminIcon.sp
Normal file
@ -0,0 +1,73 @@
|
||||
#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");
|
||||
}
|
493
AdvancedTargeting/scripting/AdvancedTargeting.sp
Normal file
493
AdvancedTargeting/scripting/AdvancedTargeting.sp
Normal file
@ -0,0 +1,493 @@
|
||||
#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;
|
||||
}
|
26
AdvancedTargeting/scripting/include/AdvancedTargeting.inc
Normal file
26
AdvancedTargeting/scripting/include/AdvancedTargeting.inc
Normal file
@ -0,0 +1,26 @@
|
||||
#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
|
71
AntiFlood/scripting/AntiFlood.sp
Normal file
71
AntiFlood/scripting/AntiFlood.sp
Normal file
@ -0,0 +1,71 @@
|
||||
#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;
|
||||
}
|
115
AntiJumpSpam/scripting/AntiJumpSpam.sp
Normal file
115
AntiJumpSpam/scripting/AntiJumpSpam.sp
Normal file
@ -0,0 +1,115 @@
|
||||
#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;
|
||||
}
|
79
AntiPingMask/scripting/AntiPingMask.sp
Normal file
79
AntiPingMask/scripting/AntiPingMask.sp
Normal file
@ -0,0 +1,79 @@
|
||||
#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;
|
||||
}
|
221
AutoRecorder/scripting/AutoRecorder.sp
Normal file
221
AutoRecorder/scripting/AutoRecorder.sp
Normal file
@ -0,0 +1,221 @@
|
||||
#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;
|
||||
ConVar g_hMaxLength;
|
||||
|
||||
bool g_bIsRecording = false;
|
||||
bool g_bIsManual = false;
|
||||
|
||||
int g_iStartedRecording;
|
||||
|
||||
// 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");
|
||||
g_hMaxLength = CreateConVar("sm_autorecord_maxlength", "0", "Maximum length of demos in seconds, 0 to disable", _, true, 0.0);
|
||||
|
||||
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)
|
||||
{
|
||||
int maxLength = GetConVarInt(g_hMaxLength);
|
||||
if(g_bIsRecording && maxLength > 0 && GetTime() >= g_iStartedRecording + maxLength)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
g_iStartedRecording = GetTime();
|
||||
|
||||
LogMessage("Recording to auto-%s-%s.dem", sTime, sMap);
|
||||
}
|
||||
}
|
||||
|
||||
void StopRecord()
|
||||
{
|
||||
if(GetConVarBool(g_hTvEnabled))
|
||||
{
|
||||
ServerCommand("tv_stoprecord");
|
||||
g_bIsRecording = false;
|
||||
}
|
||||
}
|
118
ConVarSuppression/scripting/ConVarSuppression.sp
Normal file
118
ConVarSuppression/scripting/ConVarSuppression.sp
Normal file
@ -0,0 +1,118 @@
|
||||
#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;
|
||||
}
|
25
Extend/gamedata/Extend.games.txt
Normal file
25
Extend/gamedata/Extend.games.txt
Normal file
@ -0,0 +1,25 @@
|
||||
"Games"
|
||||
{
|
||||
"#default"
|
||||
{
|
||||
"Addresses"
|
||||
{
|
||||
"GameOver"
|
||||
{
|
||||
"linux"
|
||||
{
|
||||
"signature" "g_fGameOver"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"Signatures"
|
||||
{
|
||||
"g_fGameOver"
|
||||
{
|
||||
"library" "server"
|
||||
"linux" "@g_fGameOver"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
387
Extend/scripting/Extend.sp
Normal file
387
Extend/scripting/Extend.sp
Normal file
@ -0,0 +1,387 @@
|
||||
#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);
|
||||
}
|
||||
}
|
||||
}
|
1377
ExtraCommands/scripting/ExtraCommands.sp
Normal file
1377
ExtraCommands/scripting/ExtraCommands.sp
Normal file
File diff suppressed because it is too large
Load Diff
47
FixAngles/scripting/FixAngles.sp
Normal file
47
FixAngles/scripting/FixAngles.sp
Normal file
@ -0,0 +1,47 @@
|
||||
#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;
|
||||
}
|
129
FixGameUI/scripting/FixGameUI.sp
Normal file
129
FixGameUI/scripting/FixGameUI.sp
Normal file
@ -0,0 +1,129 @@
|
||||
#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;
|
||||
}
|
14
FixPlayerEquip/gamedata/FixPlayerEquip.games.txt
Normal file
14
FixPlayerEquip/gamedata/FixPlayerEquip.games.txt
Normal file
@ -0,0 +1,14 @@
|
||||
"Games"
|
||||
{
|
||||
"#default"
|
||||
{
|
||||
"Signatures"
|
||||
{
|
||||
"CCSPlayer_StockPlayerAmmo"
|
||||
{
|
||||
"library" "server"
|
||||
"linux" "@_ZN9CCSPlayer15StockPlayerAmmoEP17CBaseCombatWeapon"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
112
FixPlayerEquip/scripting/FixPlayerEquip.sp
Normal file
112
FixPlayerEquip/scripting/FixPlayerEquip.sp
Normal file
@ -0,0 +1,112 @@
|
||||
#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);
|
||||
}
|
19
FixPointTeleport/gamedata/FixPointTeleport.games.txt
Normal file
19
FixPointTeleport/gamedata/FixPointTeleport.games.txt
Normal file
@ -0,0 +1,19 @@
|
||||
"Games"
|
||||
{
|
||||
"cstrike"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"Teleport"
|
||||
{
|
||||
"windows" "108"
|
||||
"linux" "109"
|
||||
}
|
||||
"FallInit"
|
||||
{
|
||||
"windows" "346"
|
||||
"linux" "347"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
101
FixPointTeleport/scripting/FixPointTeleport.sp
Normal file
101
FixPointTeleport/scripting/FixPointTeleport.sp
Normal file
@ -0,0 +1,101 @@
|
||||
#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);
|
||||
}
|
||||
}
|
44
Flashlight/scripting/Flashlight.sp
Normal file
44
Flashlight/scripting/Flashlight.sp
Normal file
@ -0,0 +1,44 @@
|
||||
#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;
|
||||
}
|
206
ForceInputs/scripting/ForceInputs.sp
Normal file
206
ForceInputs/scripting/ForceInputs.sp
Normal file
@ -0,0 +1,206 @@
|
||||
//====================================================================================================
|
||||
//
|
||||
// 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;
|
||||
}
|
20
FullUpdate/gamedata/FullUpdate.games.txt
Normal file
20
FullUpdate/gamedata/FullUpdate.games.txt
Normal file
@ -0,0 +1,20 @@
|
||||
"Games"
|
||||
{
|
||||
"#default"
|
||||
{
|
||||
"#supported"
|
||||
{
|
||||
"engine" "orangebox"
|
||||
"engine" "orangebox_valve"
|
||||
"engine" "css"
|
||||
}
|
||||
|
||||
"Offsets"
|
||||
{
|
||||
"CBaseClient::UpdateAcknowledgedFramecount"
|
||||
{
|
||||
"linux" "44"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
106
FullUpdate/scripting/FullUpdate.sp
Normal file
106
FullUpdate/scripting/FullUpdate.sp
Normal file
@ -0,0 +1,106 @@
|
||||
#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;
|
||||
}
|
24
FullUpdate/scripting/include/FullUpdate.inc
Normal file
24
FullUpdate/scripting/include/FullUpdate.inc
Normal file
@ -0,0 +1,24 @@
|
||||
#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
|
18
GlowColors/configs/GlowColors.cfg
Normal file
18
GlowColors/configs/GlowColors.cfg
Normal file
@ -0,0 +1,18 @@
|
||||
"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"
|
||||
}
|
535
GlowColors/scripting/GlowColors.sp
Normal file
535
GlowColors/scripting/GlowColors.sp
Normal file
@ -0,0 +1,535 @@
|
||||
#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));
|
||||
}
|
10
InfoMessage/configs/info_messages/test.txt
Normal file
10
InfoMessage/configs/info_messages/test.txt
Normal file
@ -0,0 +1,10 @@
|
||||
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
|
115
InfoMessage/scripting/InfoMessage.sp
Normal file
115
InfoMessage/scripting/InfoMessage.sp
Normal file
@ -0,0 +1,115 @@
|
||||
#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;
|
||||
}
|
112
KnifeAlert/scripting/KnifeAlert.sp
Normal file
112
KnifeAlert/scripting/KnifeAlert.sp
Normal file
@ -0,0 +1,112 @@
|
||||
#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]);
|
||||
}
|
||||
}
|
||||
}
|
3137
MapAdmin/configs/MapAdmin.cfg
Normal file
3137
MapAdmin/configs/MapAdmin.cfg
Normal file
File diff suppressed because it is too large
Load Diff
342
MapAdmin/scripting/MapAdmin.sp
Normal file
342
MapAdmin/scripting/MapAdmin.sp
Normal file
@ -0,0 +1,342 @@
|
||||
#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;
|
||||
}
|
21
NameFilter/configs/NameFilter.cfg
Normal file
21
NameFilter/configs/NameFilter.cfg
Normal file
@ -0,0 +1,21 @@
|
||||
"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"
|
||||
}
|
||||
}
|
350
NameFilter/scripting/NameFilter.sp
Normal file
350
NameFilter/scripting/NameFilter.sp
Normal file
@ -0,0 +1,350 @@
|
||||
#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;
|
||||
}
|
28
NapalmLagFix/gamedata/napalmlagfix.games.txt
Normal file
28
NapalmLagFix/gamedata/napalmlagfix.games.txt
Normal file
@ -0,0 +1,28 @@
|
||||
"Games"
|
||||
{
|
||||
"cstrike"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"RadiusDamage"
|
||||
{
|
||||
"windows" "68"
|
||||
"linux" "69"
|
||||
"mac" "69"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
"csgo"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"RadiusDamage"
|
||||
{
|
||||
"windows" "68"
|
||||
"linux" "69"
|
||||
"mac" "69"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
70
NapalmLagFix/scripting/NapalmLagFix.sp
Normal file
70
NapalmLagFix/scripting/NapalmLagFix.sp
Normal file
@ -0,0 +1,70 @@
|
||||
#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;
|
||||
}
|
15
NoGrenadeRinging/gamedata/NoGrenadeRinging.games.txt
Normal file
15
NoGrenadeRinging/gamedata/NoGrenadeRinging.games.txt
Normal file
@ -0,0 +1,15 @@
|
||||
"Games"
|
||||
{
|
||||
"cstrike"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"OnDamagedByExplosion"
|
||||
{
|
||||
"windows" "335"
|
||||
"linux" "336"
|
||||
"mac" "336"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
49
NoGrenadeRinging/scripting/NoGrenadeRinging.sp
Normal file
49
NoGrenadeRinging/scripting/NoGrenadeRinging.sp
Normal file
@ -0,0 +1,49 @@
|
||||
#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;
|
||||
}
|
91
NoShake/scripting/NoShake.sp
Normal file
91
NoShake/scripting/NoShake.sp
Normal file
@ -0,0 +1,91 @@
|
||||
#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;
|
||||
}
|
||||
|
339
PlayerVisibility/scripting/PlayerVisibility.sp
Normal file
339
PlayerVisibility/scripting/PlayerVisibility.sp
Normal file
@ -0,0 +1,339 @@
|
||||
#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;
|
||||
}
|
139
PointServerCommandFilter/configs/PointServerCommandFilter.cfg
Normal file
139
PointServerCommandFilter/configs/PointServerCommandFilter.cfg
Normal file
@ -0,0 +1,139 @@
|
||||
"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" {}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
// 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"
|
||||
}
|
||||
}
|
||||
}
|
592
PointServerCommandFilter/scripting/PointServerCommandFilter.sp
Normal file
592
PointServerCommandFilter/scripting/PointServerCommandFilter.sp
Normal file
@ -0,0 +1,592 @@
|
||||
#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]);
|
||||
}
|
73
QuickSwitch/scripting/QuickSwitch.sp
Normal file
73
QuickSwitch/scripting/QuickSwitch.sp
Normal file
@ -0,0 +1,73 @@
|
||||
#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;
|
||||
}
|
||||
}
|
28
RoundTime/scripting/RoundTime.sp
Normal file
28
RoundTime/scripting/RoundTime.sp
Normal file
@ -0,0 +1,28 @@
|
||||
#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);
|
||||
}
|
67
SaveLevel/configs/savelevel/ZE_FFVII_Mako_Reactor_V6_B08.cfg
Normal file
67
SaveLevel/configs/savelevel/ZE_FFVII_Mako_Reactor_V6_B08.cfg
Normal file
@ -0,0 +1,67 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
49
SaveLevel/configs/savelevel/ze_FFVII_Mako_Reactor_v1_4_1.cfg
Normal file
49
SaveLevel/configs/savelevel/ze_FFVII_Mako_Reactor_v1_4_1.cfg
Normal file
@ -0,0 +1,49 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
49
SaveLevel/configs/savelevel/ze_FFVII_Mako_Reactor_v3_1.cfg
Normal file
49
SaveLevel/configs/savelevel/ze_FFVII_Mako_Reactor_v3_1.cfg
Normal file
@ -0,0 +1,49 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
60
SaveLevel/configs/savelevel/ze_FFXII_Feywood_b3_1.cfg
Normal file
60
SaveLevel/configs/savelevel/ze_FFXII_Feywood_b3_1.cfg
Normal file
@ -0,0 +1,60 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
92
SaveLevel/configs/savelevel/ze_FFXII_Paramina_Rift_v1_3.cfg
Normal file
92
SaveLevel/configs/savelevel/ze_FFXII_Paramina_Rift_v1_3.cfg
Normal file
@ -0,0 +1,92 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
92
SaveLevel/configs/savelevel/ze_FFXII_Paramina_Rift_v1_4.cfg
Normal file
92
SaveLevel/configs/savelevel/ze_FFXII_Paramina_Rift_v1_4.cfg
Normal file
@ -0,0 +1,92 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
76
SaveLevel/configs/savelevel/ze_TESV_Skyrim_v3.cfg
Normal file
76
SaveLevel/configs/savelevel/ze_TESV_Skyrim_v3.cfg
Normal file
@ -0,0 +1,76 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
76
SaveLevel/configs/savelevel/ze_harry_potter_v1_3.cfg
Normal file
76
SaveLevel/configs/savelevel/ze_harry_potter_v1_3.cfg
Normal file
@ -0,0 +1,76 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
76
SaveLevel/configs/savelevel/ze_harry_potter_v2_1.cfg
Normal file
76
SaveLevel/configs/savelevel/ze_harry_potter_v2_1.cfg
Normal file
@ -0,0 +1,76 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
92
SaveLevel/configs/savelevel/ze_lila_panic_escape_v3_1.cfg
Normal file
92
SaveLevel/configs/savelevel/ze_lila_panic_escape_v3_1.cfg
Normal file
@ -0,0 +1,92 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
92
SaveLevel/configs/savelevel/ze_lotr_minas_tirith_v2_2fix.cfg
Normal file
92
SaveLevel/configs/savelevel/ze_lotr_minas_tirith_v2_2fix.cfg
Normal file
@ -0,0 +1,92 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
92
SaveLevel/configs/savelevel/ze_lotr_minas_tirith_v3_5.cfg
Normal file
92
SaveLevel/configs/savelevel/ze_lotr_minas_tirith_v3_5.cfg
Normal file
@ -0,0 +1,92 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
76
SaveLevel/configs/savelevel/ze_tesv_skyrim_v4fix.cfg
Normal file
76
SaveLevel/configs/savelevel/ze_tesv_skyrim_v4fix.cfg
Normal file
@ -0,0 +1,76 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
521
SaveLevel/scripting/SaveLevel.sp
Normal file
521
SaveLevel/scripting/SaveLevel.sp
Normal file
@ -0,0 +1,521 @@
|
||||
#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;
|
||||
}
|
416
SelectiveBhop/scripting/SelectiveBhop.sp
Normal file
416
SelectiveBhop/scripting/SelectiveBhop.sp
Normal file
@ -0,0 +1,416 @@
|
||||
#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;
|
||||
}
|
26
SelectiveBhop/scripting/include/SelectiveBhop.inc
Normal file
26
SelectiveBhop/scripting/include/SelectiveBhop.inc
Normal file
@ -0,0 +1,26 @@
|
||||
#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
|
150
SlopeFix/scripting/SlopeFix.sp
Normal file
150
SlopeFix/scripting/SlopeFix.sp
Normal file
@ -0,0 +1,150 @@
|
||||
#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);
|
||||
}
|
6
SprayManager/content/materials/decals/spraymanager/1.vmt
Normal file
6
SprayManager/content/materials/decals/spraymanager/1.vmt
Normal file
@ -0,0 +1,6 @@
|
||||
"LightmappedGeneric"
|
||||
{
|
||||
"$basetexture" "decals\spraymanager\1"
|
||||
"$decal" 1
|
||||
"$decalscale" 0.500000
|
||||
}
|
BIN
SprayManager/content/materials/decals/spraymanager/1.vtf
Normal file
BIN
SprayManager/content/materials/decals/spraymanager/1.vtf
Normal file
Binary file not shown.
6
SprayManager/content/materials/decals/spraymanager/2.vmt
Normal file
6
SprayManager/content/materials/decals/spraymanager/2.vmt
Normal file
@ -0,0 +1,6 @@
|
||||
"LightmappedGeneric"
|
||||
{
|
||||
"$basetexture" "decals\spraymanager\2"
|
||||
"$decal" 1
|
||||
"$decalscale" 0.500000
|
||||
}
|
BIN
SprayManager/content/materials/decals/spraymanager/2.vtf
Normal file
BIN
SprayManager/content/materials/decals/spraymanager/2.vtf
Normal file
Binary file not shown.
8
SprayManager/content/materials/decals/spraymanager/3.vmt
Normal file
8
SprayManager/content/materials/decals/spraymanager/3.vmt
Normal file
@ -0,0 +1,8 @@
|
||||
"LightmappedGeneric"
|
||||
{
|
||||
"$basetexture" "decals\spraymanager\3"
|
||||
"$translucent" "1"
|
||||
"$decal" "1"
|
||||
"$decalscale" 1.000000
|
||||
"$surfaceprop" "Default"
|
||||
}
|
BIN
SprayManager/content/materials/decals/spraymanager/3.vtf
Normal file
BIN
SprayManager/content/materials/decals/spraymanager/3.vtf
Normal file
Binary file not shown.
3201
SprayManager/scripting/SprayManager.sp
Normal file
3201
SprayManager/scripting/SprayManager.sp
Normal file
File diff suppressed because it is too large
Load Diff
45
Status/gamedata/serverfps.games.txt
Normal file
45
Status/gamedata/serverfps.games.txt
Normal file
@ -0,0 +1,45 @@
|
||||
"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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
204
Status/scripting/Status.sp
Normal file
204
Status/scripting/Status.sp
Normal file
@ -0,0 +1,204 @@
|
||||
#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);
|
||||
}
|
49
Status/scripting/include/serverfps.inc
Normal file
49
Status/scripting/include/serverfps.inc
Normal file
@ -0,0 +1,49 @@
|
||||
#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;
|
||||
}
|
693
StopSound/scripting/StopSound.sp
Normal file
693
StopSound/scripting/StopSound.sp
Normal file
@ -0,0 +1,693 @@
|
||||
#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;
|
||||
}
|
68
StopSound/translations/plugin.stopsound.phrases.txt
Normal file
68
StopSound/translations/plugin.stopsound.phrases.txt
Normal file
@ -0,0 +1,68 @@
|
||||
"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" " [Включено]"
|
||||
}
|
||||
}
|
38
SvGravityFix/scripting/SvGravityFix.sp
Normal file
38
SvGravityFix/scripting/SvGravityFix.sp
Normal file
@ -0,0 +1,38 @@
|
||||
#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!!!");
|
||||
}
|
||||
}
|
206
TeamManager/scripting/TeamManager.sp
Normal file
206
TeamManager/scripting/TeamManager.sp
Normal file
@ -0,0 +1,206 @@
|
||||
#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;
|
||||
}
|
330
Teleport/scripting/Teleport.sp
Normal file
330
Teleport/scripting/Teleport.sp
Normal file
@ -0,0 +1,330 @@
|
||||
#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);
|
||||
}
|
||||
}
|
305
WeaponCleaner/scripting/WeaponCleaner.sp
Normal file
305
WeaponCleaner/scripting/WeaponCleaner.sp
Normal file
@ -0,0 +1,305 @@
|
||||
#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;
|
||||
|
||||
#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_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)
|
||||
{
|
||||
static bool bEngineVersionIsCSGO;
|
||||
|
||||
// This hook calls twice and before entities are initialized on csgo, delay it by a frame.
|
||||
if (bEngineVersionIsCSGO || GetEngineVersion() == Engine_CSGO)
|
||||
{
|
||||
bEngineVersionIsCSGO = true;
|
||||
|
||||
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();
|
||||
}
|
59
custom-chatcolors/configs/custom-chatcolors.cfg
Normal file
59
custom-chatcolors/configs/custom-chatcolors.cfg
Normal file
@ -0,0 +1,59 @@
|
||||
// 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"
|
||||
}
|
||||
}
|
3
custom-chatcolors/configs/custom-chatcolorsbans.cfg
Normal file
3
custom-chatcolors/configs/custom-chatcolorsbans.cfg
Normal file
@ -0,0 +1,3 @@
|
||||
"restricted_users"
|
||||
{
|
||||
}
|
67
custom-chatcolors/configs/custom-chatcolorsreplace.cfg
Normal file
67
custom-chatcolors/configs/custom-chatcolorsreplace.cfg
Normal file
@ -0,0 +1,67 @@
|
||||
//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}██"
|
||||
}
|
3113
custom-chatcolors/scripting/custom-chatcolors.sp
Normal file
3113
custom-chatcolors/scripting/custom-chatcolors.sp
Normal file
File diff suppressed because it is too large
Load Diff
191
custom-chatcolors/scripting/include/ccc.inc
Normal file
191
custom-chatcolors/scripting/include/ccc.inc
Normal file
@ -0,0 +1,191 @@
|
||||
/**
|
||||
* 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
|
58
custom-chatcolors/translations/allchat.phrases.txt
Normal file
58
custom-chatcolors/translations/allchat.phrases.txt
Normal file
@ -0,0 +1,58 @@
|
||||
"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}"
|
||||
}
|
||||
}
|
28
entWatch/gamedata/plugin.entWatch.txt
Normal file
28
entWatch/gamedata/plugin.entWatch.txt
Normal file
@ -0,0 +1,28 @@
|
||||
"Games"
|
||||
{
|
||||
"cstrike"
|
||||
{
|
||||
"Offsets"
|
||||
{
|
||||
"GetSlot"
|
||||
{
|
||||
"windows" "320"
|
||||
"linux" "321"
|
||||
}
|
||||
"BumpWeapon"
|
||||
{
|
||||
"windows" "397"
|
||||
"linux" "398"
|
||||
}
|
||||
"OnPickedUp"
|
||||
{
|
||||
"windows" "300"
|
||||
"linux" "301"
|
||||
}
|
||||
"CBaseButton_m_toggle_state"
|
||||
{
|
||||
"linux" "848"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
2644
entWatch/scripting/entWatch.sp
Normal file
2644
entWatch/scripting/entWatch.sp
Normal file
File diff suppressed because it is too large
Load Diff
150
entWatch/scripting/include/entWatch.inc
Normal file
150
entWatch/scripting/include/entWatch.inc
Normal file
@ -0,0 +1,150 @@
|
||||
#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
|
47
entWatch/translations/entWatch.phrases.txt
Normal file
47
entWatch/translations/entWatch.phrases.txt
Normal file
@ -0,0 +1,47 @@
|
||||
"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."
|
||||
}
|
||||
}
|
47
entWatch/translations/fr/entWatch.phrases.txt
Normal file
47
entWatch/translations/fr/entWatch.phrases.txt
Normal file
@ -0,0 +1,47 @@
|
||||
"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é."
|
||||
}
|
||||
}
|
47
entWatch/translations/ru/entWatch.phrases.txt
Normal file
47
entWatch/translations/ru/entWatch.phrases.txt
Normal file
@ -0,0 +1,47 @@
|
||||
"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 теперь выключена."
|
||||
}
|
||||
}
|
30
includes/CSSFixes.inc
Normal file
30
includes/CSSFixes.inc
Normal file
@ -0,0 +1,30 @@
|
||||
#if defined _cssfixes_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _cssfixes_included
|
||||
|
||||
forward void OnRunThinkFunctions(bool simulating);
|
||||
forward void OnRunThinkFunctionsPost(bool simulating);
|
||||
forward Action OnBroadcastSound(int entity, char sample[PLATFORM_MAX_PATH], int clients[MAXPLAYERS], int &numClients);
|
||||
|
||||
public Extension __ext_CSSFixes =
|
||||
{
|
||||
name = "CSSFixes",
|
||||
file = "CSSFixes.ext",
|
||||
#if defined AUTOLOAD_EXTENSIONS
|
||||
autoload = 1,
|
||||
#else
|
||||
autoload = 0,
|
||||
#endif
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_EXTENSIONS
|
||||
public __ext_CSSFixes_SetNTVOptional()
|
||||
{
|
||||
}
|
||||
#endif
|
383
includes/SteamWorks.inc
Normal file
383
includes/SteamWorks.inc
Normal file
@ -0,0 +1,383 @@
|
||||
#if defined _SteamWorks_Included
|
||||
#endinput
|
||||
#endif
|
||||
#define _SteamWorks_Included
|
||||
|
||||
/* results from UserHasLicenseForApp */
|
||||
enum EUserHasLicenseForAppResult
|
||||
{
|
||||
k_EUserHasLicenseResultHasLicense = 0, // User has a license for specified app
|
||||
k_EUserHasLicenseResultDoesNotHaveLicense = 1, // User does not have a license for the specified app
|
||||
k_EUserHasLicenseResultNoAuth = 2, // User has not been authenticated
|
||||
};
|
||||
|
||||
/* General result codes */
|
||||
enum EResult
|
||||
{
|
||||
k_EResultOK = 1, // success
|
||||
k_EResultFail = 2, // generic failure
|
||||
k_EResultNoConnection = 3, // no/failed network connection
|
||||
// k_EResultNoConnectionRetry = 4, // OBSOLETE - removed
|
||||
k_EResultInvalidPassword = 5, // password/ticket is invalid
|
||||
k_EResultLoggedInElsewhere = 6, // same user logged in elsewhere
|
||||
k_EResultInvalidProtocolVer = 7, // protocol version is incorrect
|
||||
k_EResultInvalidParam = 8, // a parameter is incorrect
|
||||
k_EResultFileNotFound = 9, // file was not found
|
||||
k_EResultBusy = 10, // called method busy - action not taken
|
||||
k_EResultInvalidState = 11, // called object was in an invalid state
|
||||
k_EResultInvalidName = 12, // name is invalid
|
||||
k_EResultInvalidEmail = 13, // email is invalid
|
||||
k_EResultDuplicateName = 14, // name is not unique
|
||||
k_EResultAccessDenied = 15, // access is denied
|
||||
k_EResultTimeout = 16, // operation timed out
|
||||
k_EResultBanned = 17, // VAC2 banned
|
||||
k_EResultAccountNotFound = 18, // account not found
|
||||
k_EResultInvalidSteamID = 19, // steamID is invalid
|
||||
k_EResultServiceUnavailable = 20, // The requested service is currently unavailable
|
||||
k_EResultNotLoggedOn = 21, // The user is not logged on
|
||||
k_EResultPending = 22, // Request is pending (may be in process, or waiting on third party)
|
||||
k_EResultEncryptionFailure = 23, // Encryption or Decryption failed
|
||||
k_EResultInsufficientPrivilege = 24, // Insufficient privilege
|
||||
k_EResultLimitExceeded = 25, // Too much of a good thing
|
||||
k_EResultRevoked = 26, // Access has been revoked (used for revoked guest passes)
|
||||
k_EResultExpired = 27, // License/Guest pass the user is trying to access is expired
|
||||
k_EResultAlreadyRedeemed = 28, // Guest pass has already been redeemed by account, cannot be acked again
|
||||
k_EResultDuplicateRequest = 29, // The request is a duplicate and the action has already occurred in the past, ignored this time
|
||||
k_EResultAlreadyOwned = 30, // All the games in this guest pass redemption request are already owned by the user
|
||||
k_EResultIPNotFound = 31, // IP address not found
|
||||
k_EResultPersistFailed = 32, // failed to write change to the data store
|
||||
k_EResultLockingFailed = 33, // failed to acquire access lock for this operation
|
||||
k_EResultLogonSessionReplaced = 34,
|
||||
k_EResultConnectFailed = 35,
|
||||
k_EResultHandshakeFailed = 36,
|
||||
k_EResultIOFailure = 37,
|
||||
k_EResultRemoteDisconnect = 38,
|
||||
k_EResultShoppingCartNotFound = 39, // failed to find the shopping cart requested
|
||||
k_EResultBlocked = 40, // a user didn't allow it
|
||||
k_EResultIgnored = 41, // target is ignoring sender
|
||||
k_EResultNoMatch = 42, // nothing matching the request found
|
||||
k_EResultAccountDisabled = 43,
|
||||
k_EResultServiceReadOnly = 44, // this service is not accepting content changes right now
|
||||
k_EResultAccountNotFeatured = 45, // account doesn't have value, so this feature isn't available
|
||||
k_EResultAdministratorOK = 46, // allowed to take this action, but only because requester is admin
|
||||
k_EResultContentVersion = 47, // A Version mismatch in content transmitted within the Steam protocol.
|
||||
k_EResultTryAnotherCM = 48, // The current CM can't service the user making a request, user should try another.
|
||||
k_EResultPasswordRequiredToKickSession = 49,// You are already logged in elsewhere, this cached credential login has failed.
|
||||
k_EResultAlreadyLoggedInElsewhere = 50, // You are already logged in elsewhere, you must wait
|
||||
k_EResultSuspended = 51, // Long running operation (content download) suspended/paused
|
||||
k_EResultCancelled = 52, // Operation canceled (typically by user: content download)
|
||||
k_EResultDataCorruption = 53, // Operation canceled because data is ill formed or unrecoverable
|
||||
k_EResultDiskFull = 54, // Operation canceled - not enough disk space.
|
||||
k_EResultRemoteCallFailed = 55, // an remote call or IPC call failed
|
||||
k_EResultPasswordUnset = 56, // Password could not be verified as it's unset server side
|
||||
k_EResultExternalAccountUnlinked = 57, // External account (PSN, Facebook...) is not linked to a Steam account
|
||||
k_EResultPSNTicketInvalid = 58, // PSN ticket was invalid
|
||||
k_EResultExternalAccountAlreadyLinked = 59, // External account (PSN, Facebook...) is already linked to some other account, must explicitly request to replace/delete the link first
|
||||
k_EResultRemoteFileConflict = 60, // The sync cannot resume due to a conflict between the local and remote files
|
||||
k_EResultIllegalPassword = 61, // The requested new password is not legal
|
||||
k_EResultSameAsPreviousValue = 62, // new value is the same as the old one ( secret question and answer )
|
||||
k_EResultAccountLogonDenied = 63, // account login denied due to 2nd factor authentication failure
|
||||
k_EResultCannotUseOldPassword = 64, // The requested new password is not legal
|
||||
k_EResultInvalidLoginAuthCode = 65, // account login denied due to auth code invalid
|
||||
k_EResultAccountLogonDeniedNoMail = 66, // account login denied due to 2nd factor auth failure - and no mail has been sent
|
||||
k_EResultHardwareNotCapableOfIPT = 67, //
|
||||
k_EResultIPTInitError = 68, //
|
||||
k_EResultParentalControlRestricted = 69, // operation failed due to parental control restrictions for current user
|
||||
k_EResultFacebookQueryError = 70, // Facebook query returned an error
|
||||
k_EResultExpiredLoginAuthCode = 71, // account login denied due to auth code expired
|
||||
k_EResultIPLoginRestrictionFailed = 72,
|
||||
k_EResultAccountLockedDown = 73,
|
||||
k_EResultAccountLogonDeniedVerifiedEmailRequired = 74,
|
||||
k_EResultNoMatchingURL = 75,
|
||||
k_EResultBadResponse = 76, // parse failure, missing field, etc.
|
||||
k_EResultRequirePasswordReEntry = 77, // The user cannot complete the action until they re-enter their password
|
||||
k_EResultValueOutOfRange = 78, // the value entered is outside the acceptable range
|
||||
k_EResultUnexpectedError = 79, // something happened that we didn't expect to ever happen
|
||||
k_EResultDisabled = 80, // The requested service has been configured to be unavailable
|
||||
k_EResultInvalidCEGSubmission = 81, // The set of files submitted to the CEG server are not valid !
|
||||
k_EResultRestrictedDevice = 82, // The device being used is not allowed to perform this action
|
||||
k_EResultRegionLocked = 83, // The action could not be complete because it is region restricted
|
||||
k_EResultRateLimitExceeded = 84, // Temporary rate limit exceeded, try again later, different from k_EResultLimitExceeded which may be permanent
|
||||
k_EResultAccountLoginDeniedNeedTwoFactor = 85, // Need two-factor code to login
|
||||
k_EResultItemDeleted = 86, // The thing we're trying to access has been deleted
|
||||
k_EResultAccountLoginDeniedThrottle = 87, // login attempt failed, try to throttle response to possible attacker
|
||||
k_EResultTwoFactorCodeMismatch = 88, // two factor code mismatch
|
||||
k_EResultTwoFactorActivationCodeMismatch = 89, // activation code for two-factor didn't match
|
||||
k_EResultAccountAssociatedToMultiplePartners = 90, // account has been associated with multiple partners
|
||||
k_EResultNotModified = 91, // data not modified
|
||||
k_EResultNoMobileDevice = 92, // the account does not have a mobile device associated with it
|
||||
k_EResultTimeNotSynced = 93, // the time presented is out of range or tolerance
|
||||
k_EResultSmsCodeFailed = 94, // SMS code failure (no match, none pending, etc.)
|
||||
k_EResultAccountLimitExceeded = 95, // Too many accounts access this resource
|
||||
k_EResultAccountActivityLimitExceeded = 96, // Too many changes to this account
|
||||
k_EResultPhoneActivityLimitExceeded = 97, // Too many changes to this phone
|
||||
k_EResultRefundToWallet = 98, // Cannot refund to payment method, must use wallet
|
||||
k_EResultEmailSendFailure = 99, // Cannot send an email
|
||||
k_EResultNotSettled = 100, // Can't perform operation till payment has settled
|
||||
k_EResultNeedCaptcha = 101, // Needs to provide a valid captcha
|
||||
k_EResultGSLTDenied = 102, // a game server login token owned by this token's owner has been banned
|
||||
k_EResultGSOwnerDenied = 103, // game server owner is denied for other reason (account lock, community ban, vac ban, missing phone)
|
||||
k_EResultInvalidItemType = 104 // the type of thing we were requested to act on is invalid
|
||||
};
|
||||
|
||||
/* This enum is used in client API methods, do not re-number existing values. */
|
||||
enum EHTTPMethod
|
||||
{
|
||||
k_EHTTPMethodInvalid = 0,
|
||||
k_EHTTPMethodGET,
|
||||
k_EHTTPMethodHEAD,
|
||||
k_EHTTPMethodPOST,
|
||||
k_EHTTPMethodPUT,
|
||||
k_EHTTPMethodDELETE,
|
||||
k_EHTTPMethodOPTIONS,
|
||||
k_EHTTPMethodPATCH,
|
||||
|
||||
// The remaining HTTP methods are not yet supported, per rfc2616 section 5.1.1 only GET and HEAD are required for
|
||||
// a compliant general purpose server. We'll likely add more as we find uses for them.
|
||||
|
||||
// k_EHTTPMethodTRACE,
|
||||
// k_EHTTPMethodCONNECT
|
||||
};
|
||||
|
||||
|
||||
/* HTTP Status codes that the server can send in response to a request, see rfc2616 section 10.3 for descriptions
|
||||
of each of these. */
|
||||
enum EHTTPStatusCode
|
||||
{
|
||||
// Invalid status code (this isn't defined in HTTP, used to indicate unset in our code)
|
||||
k_EHTTPStatusCodeInvalid = 0,
|
||||
|
||||
// Informational codes
|
||||
k_EHTTPStatusCode100Continue = 100,
|
||||
k_EHTTPStatusCode101SwitchingProtocols = 101,
|
||||
|
||||
// Success codes
|
||||
k_EHTTPStatusCode200OK = 200,
|
||||
k_EHTTPStatusCode201Created = 201,
|
||||
k_EHTTPStatusCode202Accepted = 202,
|
||||
k_EHTTPStatusCode203NonAuthoritative = 203,
|
||||
k_EHTTPStatusCode204NoContent = 204,
|
||||
k_EHTTPStatusCode205ResetContent = 205,
|
||||
k_EHTTPStatusCode206PartialContent = 206,
|
||||
|
||||
// Redirection codes
|
||||
k_EHTTPStatusCode300MultipleChoices = 300,
|
||||
k_EHTTPStatusCode301MovedPermanently = 301,
|
||||
k_EHTTPStatusCode302Found = 302,
|
||||
k_EHTTPStatusCode303SeeOther = 303,
|
||||
k_EHTTPStatusCode304NotModified = 304,
|
||||
k_EHTTPStatusCode305UseProxy = 305,
|
||||
//k_EHTTPStatusCode306Unused = 306, (used in old HTTP spec, now unused in 1.1)
|
||||
k_EHTTPStatusCode307TemporaryRedirect = 307,
|
||||
|
||||
// Error codes
|
||||
k_EHTTPStatusCode400BadRequest = 400,
|
||||
k_EHTTPStatusCode401Unauthorized = 401, // You probably want 403 or something else. 401 implies you're sending a WWW-Authenticate header and the client can sent an Authorization header in response.
|
||||
k_EHTTPStatusCode402PaymentRequired = 402, // This is reserved for future HTTP specs, not really supported by clients
|
||||
k_EHTTPStatusCode403Forbidden = 403,
|
||||
k_EHTTPStatusCode404NotFound = 404,
|
||||
k_EHTTPStatusCode405MethodNotAllowed = 405,
|
||||
k_EHTTPStatusCode406NotAcceptable = 406,
|
||||
k_EHTTPStatusCode407ProxyAuthRequired = 407,
|
||||
k_EHTTPStatusCode408RequestTimeout = 408,
|
||||
k_EHTTPStatusCode409Conflict = 409,
|
||||
k_EHTTPStatusCode410Gone = 410,
|
||||
k_EHTTPStatusCode411LengthRequired = 411,
|
||||
k_EHTTPStatusCode412PreconditionFailed = 412,
|
||||
k_EHTTPStatusCode413RequestEntityTooLarge = 413,
|
||||
k_EHTTPStatusCode414RequestURITooLong = 414,
|
||||
k_EHTTPStatusCode415UnsupportedMediaType = 415,
|
||||
k_EHTTPStatusCode416RequestedRangeNotSatisfiable = 416,
|
||||
k_EHTTPStatusCode417ExpectationFailed = 417,
|
||||
k_EHTTPStatusCode4xxUnknown = 418, // 418 is reserved, so we'll use it to mean unknown
|
||||
k_EHTTPStatusCode429TooManyRequests = 429,
|
||||
|
||||
// Server error codes
|
||||
k_EHTTPStatusCode500InternalServerError = 500,
|
||||
k_EHTTPStatusCode501NotImplemented = 501,
|
||||
k_EHTTPStatusCode502BadGateway = 502,
|
||||
k_EHTTPStatusCode503ServiceUnavailable = 503,
|
||||
k_EHTTPStatusCode504GatewayTimeout = 504,
|
||||
k_EHTTPStatusCode505HTTPVersionNotSupported = 505,
|
||||
k_EHTTPStatusCode5xxUnknown = 599,
|
||||
};
|
||||
|
||||
/* list of possible return values from the ISteamGameCoordinator API */
|
||||
enum EGCResults
|
||||
{
|
||||
k_EGCResultOK = 0,
|
||||
k_EGCResultNoMessage = 1, // There is no message in the queue
|
||||
k_EGCResultBufferTooSmall = 2, // The buffer is too small for the requested message
|
||||
k_EGCResultNotLoggedOn = 3, // The client is not logged onto Steam
|
||||
k_EGCResultInvalidMessage = 4, // Something was wrong with the message being sent with SendMessage
|
||||
};
|
||||
|
||||
native bool:SteamWorks_IsVACEnabled();
|
||||
native bool:SteamWorks_GetPublicIP(ipaddr[4]);
|
||||
native SteamWorks_GetPublicIPCell();
|
||||
native bool:SteamWorks_IsLoaded();
|
||||
native bool:SteamWorks_SetGameData(const String:sData[]);
|
||||
native bool:SteamWorks_SetGameDescription(const String:sDesc[]);
|
||||
native bool:SteamWorks_SetMapName(const String:sMapName[]);
|
||||
native bool:SteamWorks_IsConnected();
|
||||
native bool:SteamWorks_SetRule(const String:sKey[], const String:sValue[]);
|
||||
native bool:SteamWorks_ClearRules();
|
||||
native bool:SteamWorks_ForceHeartbeat();
|
||||
native bool:SteamWorks_GetUserGroupStatus(client, groupid);
|
||||
native bool:SteamWorks_GetUserGroupStatusAuthID(authid, groupid);
|
||||
|
||||
native EUserHasLicenseForAppResult:SteamWorks_HasLicenseForApp(client, app);
|
||||
native EUserHasLicenseForAppResult:SteamWorks_HasLicenseForAppId(authid, app);
|
||||
native SteamWorks_GetClientSteamID(client, String:sSteamID[], length);
|
||||
|
||||
native bool:SteamWorks_RequestStatsAuthID(authid, appid);
|
||||
native bool:SteamWorks_RequestStats(client, appid);
|
||||
native bool:SteamWorks_GetStatCell(client, const String:sKey[], &value);
|
||||
native bool:SteamWorks_GetStatAuthIDCell(authid, const String:sKey[], &value);
|
||||
native bool:SteamWorks_GetStatFloat(client, const String:sKey[], &Float:value);
|
||||
native bool:SteamWorks_GetStatAuthIDFloat(authid, const String:sKey[], &Float:value);
|
||||
|
||||
native Handle:SteamWorks_CreateHTTPRequest(EHTTPMethod:method, const String:sURL[]);
|
||||
native bool:SteamWorks_SetHTTPRequestContextValue(Handle:hHandle, any:data1, any:data2=0);
|
||||
native bool:SteamWorks_SetHTTPRequestNetworkActivityTimeout(Handle:hHandle, timeout);
|
||||
native bool:SteamWorks_SetHTTPRequestHeaderValue(Handle:hHandle, const String:sName[], const String:sValue[]);
|
||||
native bool:SteamWorks_SetHTTPRequestGetOrPostParameter(Handle:hHandle, const String:sName[], const String:sValue[]);
|
||||
native bool:SteamWorks_SetHTTPRequestUserAgentInfo(Handle:hHandle, const String:sUserAgentInfo[]);
|
||||
native bool:SteamWorks_SetHTTPRequestRequiresVerifiedCertificate(Handle:hHandle, bool:bRequireVerifiedCertificate);
|
||||
native bool:SteamWorks_SetHTTPRequestAbsoluteTimeoutMS(Handle:hHandle, unMilliseconds);
|
||||
|
||||
native int:SteamWorks_CreateFake(const String:sPlayerName[]);
|
||||
native bool:SteamWorks_KickFake();
|
||||
native int:SteamWorks_CountFakes();
|
||||
native bool:SteamWorks_SetMaxPlayers(int Players);
|
||||
|
||||
funcenum SteamWorksHTTPRequestCompleted
|
||||
{
|
||||
public(Handle:hRequest, bool:bFailure, bool:bRequestSuccessful, EHTTPStatusCode:eStatusCode),
|
||||
public(Handle:hRequest, bool:bFailure, bool:bRequestSuccessful, EHTTPStatusCode:eStatusCode, any:data1),
|
||||
public(Handle:hRequest, bool:bFailure, bool:bRequestSuccessful, EHTTPStatusCode:eStatusCode, any:data1, any:data2)
|
||||
};
|
||||
|
||||
funcenum SteamWorksHTTPHeadersReceived
|
||||
{
|
||||
public(Handle:hRequest, bool:bFailure),
|
||||
public(Handle:hRequest, bool:bFailure, any:data1),
|
||||
public(Handle:hRequest, bool:bFailure, any:data1, any:data2)
|
||||
};
|
||||
|
||||
funcenum SteamWorksHTTPDataReceived
|
||||
{
|
||||
public(Handle:hRequest, bool:bFailure, offset, bytesreceived),
|
||||
public(Handle:hRequest, bool:bFailure, offset, bytesreceived, any:data1),
|
||||
public(Handle:hRequest, bool:bFailure, offset, bytesreceived, any:data1, any:data2)
|
||||
};
|
||||
|
||||
native bool:SteamWorks_SetHTTPCallbacks(Handle:hHandle, SteamWorksHTTPRequestCompleted:fCompleted = INVALID_FUNCTION, SteamWorksHTTPHeadersReceived:fHeaders = INVALID_FUNCTION, SteamWorksHTTPDataReceived:fData = INVALID_FUNCTION, Handle:hCalling = INVALID_HANDLE);
|
||||
native bool:SteamWorks_SendHTTPRequest(Handle:hRequest);
|
||||
native bool:SteamWorks_SendHTTPRequestAndStreamResponse(Handle:hRequest);
|
||||
native bool:SteamWorks_DeferHTTPRequest(Handle:hRequest);
|
||||
native bool:SteamWorks_PrioritizeHTTPRequest(Handle:hRequest);
|
||||
native bool:SteamWorks_GetHTTPResponseHeaderSize(Handle:hRequest, const String:sHeader[], &size);
|
||||
native bool:SteamWorks_GetHTTPResponseHeaderValue(Handle:hRequest, const String:sHeader[], String:sValue[], size);
|
||||
native bool:SteamWorks_GetHTTPResponseBodySize(Handle:hRequest, &size);
|
||||
native bool:SteamWorks_GetHTTPResponseBodyData(Handle:hRequest, String:sBody[], length);
|
||||
native bool:SteamWorks_GetHTTPStreamingResponseBodyData(Handle:hRequest, cOffset, String:sBody[], length);
|
||||
native bool:SteamWorks_GetHTTPDownloadProgressPct(Handle:hRequest, &Float:percent);
|
||||
native bool:SteamWorks_GetHTTPRequestWasTimedOut(Handle:hRequest, &bool:bWasTimedOut);
|
||||
native bool:SteamWorks_SetHTTPRequestRawPostBody(Handle:hRequest, const String:sContentType[], const String:sBody[], bodylen);
|
||||
|
||||
funcenum SteamWorksHTTPBodyCallback
|
||||
{
|
||||
public(const String:sData[]),
|
||||
public(const String:sData[], any:value),
|
||||
public(const data[], any:value, datalen)
|
||||
};
|
||||
|
||||
native bool:SteamWorks_GetHTTPResponseBodyCallback(Handle:hRequest, SteamWorksHTTPBodyCallback:fCallback, any:data = 0, Handle:hPlugin = INVALID_HANDLE);
|
||||
native bool:SteamWorks_WriteHTTPResponseBodyToFile(Handle:hRequest, const String:sFileName[]);
|
||||
|
||||
forward SW_OnValidateClient(ownerauthid, authid);
|
||||
forward SteamWorks_OnValidateClient(ownerauthid, authid);
|
||||
forward SteamWorks_SteamServersConnected();
|
||||
forward SteamWorks_SteamServersConnectFailure(EResult:result);
|
||||
forward SteamWorks_SteamServersDisconnected(EResult:result);
|
||||
|
||||
forward Action:SteamWorks_RestartRequested();
|
||||
forward SteamWorks_TokenRequested(String:sToken[], maxlen);
|
||||
|
||||
forward SteamWorks_OnClientGroupStatus(authid, groupid, bool:isMember, bool:isOfficer);
|
||||
|
||||
forward EGCResults:SteamWorks_GCSendMessage(unMsgType, const String:pubData[], cubData);
|
||||
forward SteamWorks_GCMsgAvailable(cubData);
|
||||
forward EGCResults:SteamWorks_GCRetrieveMessage(punMsgType, const String:pubDest[], cubDest, pcubMsgSize);
|
||||
|
||||
native EGCResults:SteamWorks_SendMessageToGC(unMsgType, const String:pubData[], cubData);
|
||||
|
||||
public Extension:__ext_SteamWorks =
|
||||
{
|
||||
name = "SteamWorks",
|
||||
file = "SteamWorks.ext",
|
||||
#if defined AUTOLOAD_EXTENSIONS
|
||||
autoload = 1,
|
||||
#else
|
||||
autoload = 0,
|
||||
#endif
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_EXTENSIONS
|
||||
public __ext_SteamWorks_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("SteamWorks_IsVACEnabled");
|
||||
MarkNativeAsOptional("SteamWorks_GetPublicIP");
|
||||
MarkNativeAsOptional("SteamWorks_GetPublicIPCell");
|
||||
MarkNativeAsOptional("SteamWorks_IsLoaded");
|
||||
MarkNativeAsOptional("SteamWorks_SetGameData");
|
||||
MarkNativeAsOptional("SteamWorks_SetGameDescription");
|
||||
MarkNativeAsOptional("SteamWorks_IsConnected");
|
||||
MarkNativeAsOptional("SteamWorks_SetRule");
|
||||
MarkNativeAsOptional("SteamWorks_ClearRules");
|
||||
MarkNativeAsOptional("SteamWorks_ForceHeartbeat");
|
||||
MarkNativeAsOptional("SteamWorks_GetUserGroupStatus");
|
||||
MarkNativeAsOptional("SteamWorks_GetUserGroupStatusAuthID");
|
||||
|
||||
MarkNativeAsOptional("SteamWorks_HasLicenseForApp");
|
||||
MarkNativeAsOptional("SteamWorks_HasLicenseForAppId");
|
||||
MarkNativeAsOptional("SteamWorks_GetClientSteamID");
|
||||
|
||||
MarkNativeAsOptional("SteamWorks_RequestStatsAuthID");
|
||||
MarkNativeAsOptional("SteamWorks_RequestStats");
|
||||
MarkNativeAsOptional("SteamWorks_GetStatCell");
|
||||
MarkNativeAsOptional("SteamWorks_GetStatAuthIDCell");
|
||||
MarkNativeAsOptional("SteamWorks_GetStatFloat");
|
||||
MarkNativeAsOptional("SteamWorks_GetStatAuthIDFloat");
|
||||
|
||||
MarkNativeAsOptional("SteamWorks_SendMessageToGC");
|
||||
|
||||
MarkNativeAsOptional("SteamWorks_CreateHTTPRequest");
|
||||
MarkNativeAsOptional("SteamWorks_SetHTTPRequestContextValue");
|
||||
MarkNativeAsOptional("SteamWorks_SetHTTPRequestNetworkActivityTimeout");
|
||||
MarkNativeAsOptional("SteamWorks_SetHTTPRequestHeaderValue");
|
||||
MarkNativeAsOptional("SteamWorks_SetHTTPRequestGetOrPostParameter");
|
||||
|
||||
MarkNativeAsOptional("SteamWorks_SetHTTPCallbacks");
|
||||
MarkNativeAsOptional("SteamWorks_SendHTTPRequest");
|
||||
MarkNativeAsOptional("SteamWorks_SendHTTPRequestAndStreamResponse");
|
||||
MarkNativeAsOptional("SteamWorks_DeferHTTPRequest");
|
||||
MarkNativeAsOptional("SteamWorks_PrioritizeHTTPRequest");
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPResponseHeaderSize");
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPResponseHeaderValue");
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPResponseBodySize");
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPResponseBodyData");
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPStreamingResponseBodyData");
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPDownloadProgressPct");
|
||||
MarkNativeAsOptional("SteamWorks_SetHTTPRequestRawPostBody");
|
||||
|
||||
MarkNativeAsOptional("SteamWorks_GetHTTPResponseBodyCallback");
|
||||
MarkNativeAsOptional("SteamWorks_WriteHTTPResponseBodyToFile");
|
||||
}
|
||||
#endif
|
42
includes/connect.inc
Normal file
42
includes/connect.inc
Normal file
@ -0,0 +1,42 @@
|
||||
#if defined _Connect_Included
|
||||
#endinput
|
||||
#endif
|
||||
#define _Connect_Included
|
||||
|
||||
enum EConnect
|
||||
{
|
||||
k_OnClientPreConnectEx_Reject = 0,
|
||||
k_OnClientPreConnectEx_Accept = 1,
|
||||
k_OnClientPreConnectEx_Async = -1
|
||||
};
|
||||
|
||||
forward EConnect OnClientPreConnectEx(const char[] sName, char sPassword[255], const char[] sIP, const char[] sSteam32ID, char sRejectReason[255]);
|
||||
|
||||
native bool ClientPreConnectEx(const char[] sSteam32ID, EConnect RetVal, char sRejectReason[255]);
|
||||
native bool SteamClientAuthenticated(const char[] sSteam32ID);
|
||||
|
||||
/**
|
||||
* Do not edit below this line!
|
||||
*/
|
||||
public Extension __ext_connect =
|
||||
{
|
||||
name = "Connect",
|
||||
file = "connect.ext",
|
||||
#if defined AUTOLOAD_EXTENSIONS
|
||||
autoload = 1,
|
||||
#else
|
||||
autoload = 0,
|
||||
#endif
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_EXTENSIONS
|
||||
public __ext_connect_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("ClientPreConnectEx");
|
||||
}
|
||||
#endif
|
485
includes/dhooks.inc
Normal file
485
includes/dhooks.inc
Normal file
@ -0,0 +1,485 @@
|
||||
#if defined _dhooks_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _dhooks_included
|
||||
|
||||
enum ObjectValueType
|
||||
{
|
||||
ObjectValueType_Int = 0,
|
||||
ObjectValueType_Bool,
|
||||
ObjectValueType_Ehandle,
|
||||
ObjectValueType_Float,
|
||||
ObjectValueType_CBaseEntityPtr,
|
||||
ObjectValueType_IntPtr,
|
||||
ObjectValueType_BoolPtr,
|
||||
ObjectValueType_EhandlePtr,
|
||||
ObjectValueType_FloatPtr,
|
||||
ObjectValueType_Vector,
|
||||
ObjectValueType_VectorPtr,
|
||||
ObjectValueType_CharPtr,
|
||||
ObjectValueType_String
|
||||
};
|
||||
|
||||
enum ListenType
|
||||
{
|
||||
ListenType_Created,
|
||||
ListenType_Deleted
|
||||
};
|
||||
|
||||
enum ReturnType
|
||||
{
|
||||
ReturnType_Unknown,
|
||||
ReturnType_Void,
|
||||
ReturnType_Int,
|
||||
ReturnType_Bool,
|
||||
ReturnType_Float,
|
||||
ReturnType_String, //Note this is a string_t
|
||||
ReturnType_StringPtr, //Note this is a string_t *
|
||||
ReturnType_CharPtr,
|
||||
ReturnType_Vector,
|
||||
ReturnType_VectorPtr,
|
||||
ReturnType_CBaseEntity,
|
||||
ReturnType_Edict
|
||||
};
|
||||
|
||||
enum HookParamType
|
||||
{
|
||||
HookParamType_Unknown,
|
||||
HookParamType_Int,
|
||||
HookParamType_Bool,
|
||||
HookParamType_Float,
|
||||
HookParamType_String, //Note this is a string_t
|
||||
HookParamType_StringPtr, //Note this is a string_t *
|
||||
HookParamType_CharPtr,
|
||||
HookParamType_VectorPtr,
|
||||
HookParamType_CBaseEntity,
|
||||
HookParamType_ObjectPtr,
|
||||
HookParamType_Edict,
|
||||
HookParamType_Object
|
||||
};
|
||||
|
||||
enum ThisPointerType
|
||||
{
|
||||
ThisPointer_Ignore,
|
||||
ThisPointer_CBaseEntity,
|
||||
ThisPointer_Address
|
||||
};
|
||||
|
||||
enum HookType
|
||||
{
|
||||
HookType_Entity,
|
||||
HookType_GameRules,
|
||||
HookType_Raw
|
||||
};
|
||||
|
||||
enum MRESReturn
|
||||
{
|
||||
MRES_ChangedHandled = -2, // Use changed values and return MRES_Handled
|
||||
MRES_ChangedOverride, // Use changed values and return MRES_Override
|
||||
MRES_Ignored, // plugin didn't take any action
|
||||
MRES_Handled, // plugin did something, but real function should still be called
|
||||
MRES_Override, // call real function, but use my return value
|
||||
MRES_Supercede // skip real function; use my return value
|
||||
};
|
||||
|
||||
enum DHookPassFlag
|
||||
{
|
||||
DHookPass_ByVal = (1<<0), /**< Passing by value */
|
||||
DHookPass_ByRef = (1<<1), /**< Passing by reference */
|
||||
DHookPass_ODTOR = (1<<2), /**< Object has a destructor */
|
||||
DHookPass_OCTOR = (1<<3), /**< Object has a constructor */
|
||||
DHookPass_OASSIGNOP = (1<<4), /**< Object has an assignment operator */
|
||||
};
|
||||
|
||||
typeset ListenCB
|
||||
{
|
||||
//Deleted
|
||||
function void (int entity);
|
||||
|
||||
//Created
|
||||
function void (int entity, const char[] classname);
|
||||
};
|
||||
|
||||
typeset DHookRemovalCB
|
||||
{
|
||||
function void (int hookid);
|
||||
};
|
||||
typeset DHookCallback
|
||||
{
|
||||
//Function Example: void Ham::Test() with this pointer ignore
|
||||
function MRESReturn ();
|
||||
|
||||
//Function Example: void Ham::Test() with this pointer passed
|
||||
function MRESReturn (int pThis);
|
||||
|
||||
//Function Example: void Ham::Test(int cake) with this pointer ignore
|
||||
function MRESReturn (Handle hParams);
|
||||
|
||||
//Function Example: void Ham::Test(int cake) with this pointer passed
|
||||
function MRESReturn (int pThis, Handle hParams);
|
||||
|
||||
//Function Example: int Ham::Test() with this pointer ignore
|
||||
function MRESReturn (Handle hReturn);
|
||||
|
||||
//Function Example: int Ham::Test() with this pointer passed
|
||||
function MRESReturn (int pThis, Handle hReturn);
|
||||
|
||||
//Function Example: int Ham::Test(int cake) with this pointer ignore
|
||||
function MRESReturn (Handle hReturn, Handle hParams);
|
||||
|
||||
//Function Example: int Ham::Test(int cake) with this pointer passed
|
||||
function MRESReturn (int pThis, Handle hReturn, Handle hParams);
|
||||
|
||||
//Address NOW
|
||||
|
||||
//Function Example: void Ham::Test() with this pointer passed
|
||||
function MRESReturn (Address pThis);
|
||||
|
||||
//Function Example: void Ham::Test(int cake) with this pointer passed
|
||||
function MRESReturn (Address pThis, Handle hParams);
|
||||
|
||||
//Function Example: int Ham::Test() with this pointer passed
|
||||
function MRESReturn (Address pThis, Handle hReturn);
|
||||
|
||||
//Function Example: int Ham::Test(int cake) with this pointer passed
|
||||
function MRESReturn (Address pThis, Handle hReturn, Handle hParams);
|
||||
|
||||
};
|
||||
|
||||
/* Adds an entity listener hook
|
||||
*
|
||||
* @param type Type of listener to add
|
||||
* @param callback Callback to use
|
||||
*
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookAddEntityListener(ListenType type, ListenCB callback);
|
||||
|
||||
/* Removes an entity listener hook
|
||||
*
|
||||
* @param type Type of listener to remove
|
||||
* @param callback Callback this listener was using
|
||||
*
|
||||
* @return True if one was removed false otherwise.
|
||||
*/
|
||||
native bool DHookRemoveEntityListener(ListenType type, ListenCB callback);
|
||||
|
||||
/* Creates a hook
|
||||
*
|
||||
* @param offset vtable offset for function to hook
|
||||
* @param hooktype Type of hook
|
||||
* @param returntype Type type of return
|
||||
* @param thistype Type of this pointer or ignore (ignore can be used if not needed)
|
||||
* @param callback Callback function
|
||||
*
|
||||
* @return Returns setup handle for the hook or INVALID_HANDLE.
|
||||
*/
|
||||
native Handle DHookCreate(int offset, HookType hooktype, ReturnType returntype, ThisPointerType thistype, DHookCallback callback);
|
||||
|
||||
/* Adds param to a hook setup
|
||||
*
|
||||
* @param setup Setup handle to add the param to.
|
||||
* @param type Param type
|
||||
* @param size Used for Objects (not Object ptr) to define the size of the object.
|
||||
* @param flag Used to change the pass type.
|
||||
*
|
||||
* @error Invalid setup handle or too many params added (request upping the max in thread)
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookAddParam(Handle setup, HookParamType type, int size=-1, DHookPassFlag flag=DHookPass_ByVal);
|
||||
//native DHookAddParam(Handle:setup, HookParamType:type);
|
||||
|
||||
/* Hook entity
|
||||
*
|
||||
* @param setup Setup handle to use to add the hook.
|
||||
* @param post True to make the hook a post hook. (If you need to change the retunr value or need the return value use a post hook! If you need to change params and return use a pre and post hook!)
|
||||
* @param entity Entity index to hook on.
|
||||
* @param removalcb Callback for when the hook is removed (Entity hooks are auto-removed on entity destroyed and will call this callback)
|
||||
*
|
||||
* @error Invalid setup handle, invalid entity or invalid hook type.
|
||||
* @return -1 on fail a hookid on success
|
||||
*/
|
||||
native int DHookEntity(Handle setup, bool post, int entity, DHookRemovalCB removalcb=INVALID_FUNCTION);
|
||||
|
||||
/* Hook gamerules
|
||||
*
|
||||
* @param setup Setup handle to use to add the hook.
|
||||
* @param post True to make the hook a post hook. (If you need to change the retunr value or need the return value use a post hook! If you need to change params and return use a pre and post hook!)
|
||||
* @param removalcb Callback for when the hook is removed (Game rules hooks are auto-removed on map end and will call this callback)
|
||||
*
|
||||
* @error Invalid setup handle, failing to get gamerules pointer or invalid hook type.
|
||||
* @return -1 on fail a hookid on success
|
||||
*/
|
||||
native int DHookGamerules(Handle setup, bool post, DHookRemovalCB removalcb=INVALID_FUNCTION);
|
||||
|
||||
/* Hook a raw pointer
|
||||
*
|
||||
* @param setup Setup handle to use to add the hook.
|
||||
* @param post True to make the hook a post hook. (If you need to change the retunr value or need the return value use a post hook! If you need to change params and return use a pre and post hook!)
|
||||
* @param addr This pointer address.
|
||||
* @param removalcb Callback for when the hook is removed (Entity hooks are auto-removed on entity destroyed and will call this callback)
|
||||
*
|
||||
* @error Invalid setup handle, invalid address or invalid hook type.
|
||||
* @return -1 on fail a hookid on success
|
||||
*/
|
||||
native int DHookRaw(Handle setup, bool post, Address addr, DHookRemovalCB removalcb=INVALID_FUNCTION);
|
||||
|
||||
/* Remove hook by hook id
|
||||
*
|
||||
* @param hookid Hook id to remove
|
||||
*
|
||||
* @return true on success false otherwise
|
||||
* @note This will not fire the removal callback!
|
||||
*/
|
||||
native bool DHookRemoveHookID(int hookid);
|
||||
|
||||
/* Get param value (Only use for: int, entity, bool or float param types)
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to get. (Example if the function has 2 params and you need the value of the first param num would be 1. 0 Will return the number of params stored)
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||
* @return value if num greater than 0. If 0 returns paramcount.
|
||||
*/
|
||||
native any DHookGetParam(Handle hParams, int num);
|
||||
|
||||
/* Get vector param value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to get. (Example if the function has 2 params and you need the value of the first param num would be 1.)
|
||||
* @param vec Vector buffer to store result.
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookGetParamVector(Handle hParams, int num, float vec[3]);
|
||||
|
||||
/* Get string param value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to get. (Example if the function has 2 params and you need the value of the first param num would be 1.)
|
||||
* @param buffer String buffer to store result
|
||||
* @param size Buffer size
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookGetParamString(Handle hParams, int num, char[] buffer, int size);
|
||||
|
||||
/* Set param value (Only use for: int, entity, bool or float param types)
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @params num Param number to set (Example if the function has 2 params and you need to set the value of the first param num would be 1.)
|
||||
* @param value Value to set it as (only pass int, bool, float or entity index)
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetParam(Handle hParams, int num, any value);
|
||||
|
||||
/* Set vector param value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @params num Param number to set (Example if the function has 2 params and you need to set the value of the first param num would be 1.)
|
||||
* @param vec Value to set vector as.
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetParamVector(Handle hParams, int num, float vec[3]);
|
||||
|
||||
/* Set string param value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @params num Param number to set (Example if the function has 2 params and you need to set the value of the first param num would be 1.)
|
||||
* @param value Value to set string as.
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetParamString(Handle hParams, int num, char[] value);
|
||||
|
||||
/* Get return value (Only use for: int, entity, bool or float return types)
|
||||
*
|
||||
* @param hReturn Handle to return structure
|
||||
*
|
||||
* @error Invalid Handle, invalid type.
|
||||
* @return Returns default value if prehook returns actual value if post hook.
|
||||
*/
|
||||
native any DHookGetReturn(Handle hReturn);
|
||||
|
||||
/* Get return vector value
|
||||
*
|
||||
* @param hReturn Handle to return structure
|
||||
* @param vec Vector buffer to store result in. (In pre hooks will be default value (0.0,0.0,0.0))
|
||||
*
|
||||
* @error Invalid Handle, invalid type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookGetReturnVector(Handle hReturn, float vec[3]);
|
||||
|
||||
/* Get return string value
|
||||
*
|
||||
* @param hReturn Handle to return structure
|
||||
* @param buffer String buffer to store result in. (In pre hooks will be default value "")
|
||||
* @param size String buffer size
|
||||
*
|
||||
* @error Invalid Handle, invalid type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookGetReturnString(Handle hReturn, char[] buffer, int size);
|
||||
|
||||
/* Set return value (Only use for: int, entity, bool or float return types)
|
||||
*
|
||||
* @param hReturn Handle to return structure
|
||||
* @param value Value to set return as
|
||||
*
|
||||
* @error Invalid Handle, invalid type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetReturn(Handle hReturn, any value);
|
||||
|
||||
/* Set return vector value
|
||||
*
|
||||
* @param hReturn Handle to return structure
|
||||
* @param vec Value to set return vector as
|
||||
*
|
||||
* @error Invalid Handle, invalid type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetReturnVector(Handle hReturn, float vec[3]);
|
||||
|
||||
/* Set return string value
|
||||
*
|
||||
* @param hReturn Handle to return structure
|
||||
* @param value Value to set return string as
|
||||
*
|
||||
* @error Invalid Handle, invalid type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetReturnString(Handle hReturn, char[] value);
|
||||
|
||||
//WE SHOULD WRAP THESE AROUND STOCKS FOR NON PTR AS WE SUPPORT BOTH WITH THESE NATIVE'S
|
||||
|
||||
/* Gets an objects variable value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to get.
|
||||
* @param offset Offset within the object to the var to get.
|
||||
* @param type Type of var it is
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||
* @return Value of the objects var. If EHANDLE type or entity returns entity index.
|
||||
*/
|
||||
native any DHookGetParamObjectPtrVar(Handle hParams, int num, int offset, ObjectValueType type);
|
||||
|
||||
/* Sets an objects variable value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to set.
|
||||
* @param offset Offset within the object to the var to set.
|
||||
* @param type Type of var it is
|
||||
* @param value The value to set the var to.
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetParamObjectPtrVar(Handle hParams, int num, int offset, ObjectValueType type, any value);
|
||||
|
||||
/* Gets an objects vector variable value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to get.
|
||||
* @param offset Offset within the object to the var to get.
|
||||
* @param type Type of var it is
|
||||
* @param buffer Buffer to store the result vector
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookGetParamObjectPtrVarVector(Handle hParams, int num, int offset, ObjectValueType type, float buffer[3]);
|
||||
|
||||
/* Sets an objects vector variable value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to set.
|
||||
* @param offset Offset within the object to the var to set.
|
||||
* @param type Type of var it is
|
||||
* @param value The value to set the vector var to.
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookSetParamObjectPtrVarVector(Handle hParams, int num, int offset, ObjectValueType type, float value[3]);
|
||||
|
||||
/* Gets an objects string variable value
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to get.
|
||||
* @param offset Offset within the object to the var to get.
|
||||
* @param type Type of var it is
|
||||
* @param buffer Buffer to store the result vector
|
||||
* @param size Size of the buffer
|
||||
*
|
||||
* @error Invalid handle. Invalid param number. Invalid param type. Invalid Object type.
|
||||
* @noreturn
|
||||
*/
|
||||
native void DHookGetParamObjectPtrString(Handle hParams, int num, int offset, ObjectValueType type, char[] buffer, int size);
|
||||
|
||||
/* Checks if a pointer param is null
|
||||
*
|
||||
* @param hParams Handle to params structure
|
||||
* @param num Param number to check.
|
||||
*
|
||||
* @error Non pointer param
|
||||
* @return True if null false otherwise.
|
||||
*/
|
||||
native bool DHookIsNullParam(Handle hParams, int num);
|
||||
|
||||
public Extension __ext_dhooks =
|
||||
{
|
||||
name = "dhooks",
|
||||
file = "dhooks.ext",
|
||||
#if defined AUTOLOAD_EXTENSIONS
|
||||
autoload = 1,
|
||||
#else
|
||||
autoload = 0,
|
||||
#endif
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_EXTENSIONS
|
||||
public __ext_dhooks_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("DHookAddEntityListener");
|
||||
MarkNativeAsOptional("DHookRemoveEntityListener");
|
||||
MarkNativeAsOptional("DHookCreate");
|
||||
MarkNativeAsOptional("DHookAddParam");
|
||||
MarkNativeAsOptional("DHookEntity");
|
||||
MarkNativeAsOptional("DHookGamerules");
|
||||
MarkNativeAsOptional("DHookRaw");
|
||||
MarkNativeAsOptional("DHookRemoveHookID");
|
||||
MarkNativeAsOptional("DHookGetParam");
|
||||
MarkNativeAsOptional("DHookGetParamVector");
|
||||
MarkNativeAsOptional("DHookGetParamString");
|
||||
MarkNativeAsOptional("DHookSetParam");
|
||||
MarkNativeAsOptional("DHookSetParamVector");
|
||||
MarkNativeAsOptional("DHookSetParamString");
|
||||
MarkNativeAsOptional("DHookGetReturn");
|
||||
MarkNativeAsOptional("DHookGetReturnVector");
|
||||
MarkNativeAsOptional("DHookGetReturnString");
|
||||
MarkNativeAsOptional("DHookSetReturn");
|
||||
MarkNativeAsOptional("DHookSetReturnVector");
|
||||
MarkNativeAsOptional("DHookSetReturnString");
|
||||
MarkNativeAsOptional("DHookGetParamObjectPtrVar");
|
||||
MarkNativeAsOptional("DHookSetParamObjectPtrVar");
|
||||
MarkNativeAsOptional("DHookGetParamObjectPtrVarVector");
|
||||
MarkNativeAsOptional("DHookSetParamObjectPtrVarVector");
|
||||
MarkNativeAsOptional("DHookIsNullParam");
|
||||
MarkNativeAsOptional("DHookGetParamObjectPtrString");
|
||||
}
|
||||
#endif
|
63
includes/outputinfo.inc
Normal file
63
includes/outputinfo.inc
Normal file
@ -0,0 +1,63 @@
|
||||
#if defined _OutputInfo_Included
|
||||
#endinput
|
||||
#endif
|
||||
#define _OutputInfo_Included
|
||||
|
||||
native int GetOutputCount(int Entity, const char[] sOutput);
|
||||
|
||||
native int GetOutputTarget(int Entity, const char[] sOutput, int Index, char[] sTarget, int MaxLen);
|
||||
native int GetOutputTargetInput(int Entity, const char[] sOutput, int Index, char[] sTargetInput, int MaxLen);
|
||||
native int GetOutputParameter(int Entity, const char[] sOutput, int Index, char[] sParameter, int MaxLen);
|
||||
native float GetOutputDelay(int Entity, const char[] sOutput, int Index);
|
||||
|
||||
native int GetOutputFormatted(int Entity, const char[] sOutput, int Index, char[] sFormatted, int MaxLen);
|
||||
|
||||
native int GetOutputValue(int Entity, const char[] sOutput);
|
||||
native float GetOutputValueFloat(int Entity, const char[] sOutput);
|
||||
native int GetOutputValueString(int Entity, const char[] sOutput, char[] sValue, int MaxLen);
|
||||
native bool GetOutputValueVector(int Entity, const char[] sOutput, float afVec[3]);
|
||||
|
||||
native int FindOutput(int Entity, const char[] sOutput, int StartIndex,
|
||||
const char[] sTarget = NULL_STRING, // or NULL_STRING to ignore
|
||||
const char[] sTargetInput = NULL_STRING, // or NULL_STRING to ignore
|
||||
const char[] sParameter = NULL_STRING, // or NULL_STRING to ignore
|
||||
float fDelay = -1.0, // or -1.0 to ignore
|
||||
int TimesToFire = 0 // or 0 to ignore
|
||||
);
|
||||
|
||||
native int DeleteOutput(int Entity, const char[] sOutput, int Index);
|
||||
native int DeleteAllOutputs(int Entity, const char[] sOutput);
|
||||
|
||||
/**
|
||||
* Do not edit below this line!
|
||||
*/
|
||||
public Extension __ext_outputinfo =
|
||||
{
|
||||
name = "OutputInfo",
|
||||
file = "outputinfo.ext",
|
||||
#if defined AUTOLOAD_EXTENSIONS
|
||||
autoload = 1,
|
||||
#else
|
||||
autoload = 0,
|
||||
#endif
|
||||
#if defined REQUIRE_EXTENSIONS
|
||||
required = 1,
|
||||
#else
|
||||
required = 0,
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_EXTENSIONS
|
||||
public __ext_outputinfo_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("GetOutputCount");
|
||||
MarkNativeAsOptional("GetOutputTarget");
|
||||
MarkNativeAsOptional("GetOutputTargetInput");
|
||||
MarkNativeAsOptional("GetOutputParameter");
|
||||
MarkNativeAsOptional("GetOutputDelay");
|
||||
MarkNativeAsOptional("GetOutputFormatted");
|
||||
MarkNativeAsOptional("FindOutput");
|
||||
MarkNativeAsOptional("DeleteOutput");
|
||||
MarkNativeAsOptional("DeleteAllOutputs");
|
||||
}
|
||||
#endif
|
67
includes/zombiereloaded.inc
Normal file
67
includes/zombiereloaded.inc
Normal file
@ -0,0 +1,67 @@
|
||||
/*
|
||||
* ============================================================================
|
||||
*
|
||||
* Zombie:Reloaded
|
||||
*
|
||||
* File: zombiereloaded.inc
|
||||
* Type: Include
|
||||
* Description: Main API include file.
|
||||
* Notes: Include this file to include the whole ZR API.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
#if defined _zr_included
|
||||
#endinput
|
||||
#endif
|
||||
#define _zr_included
|
||||
|
||||
#include <zr/infect.zr>
|
||||
#include <zr/respawn.zr>
|
||||
#include <zr/class.zr>
|
||||
|
||||
public SharedPlugin __pl_zombiereloaded =
|
||||
{
|
||||
name = "zombiereloaded",
|
||||
file = "zombiereloaded.smx",
|
||||
#if defined REQUIRE_PLUGIN
|
||||
required = 1
|
||||
#else
|
||||
required = 0
|
||||
#endif
|
||||
};
|
||||
|
||||
#if !defined REQUIRE_PLUGIN
|
||||
public void __pl_zombiereloaded_SetNTVOptional()
|
||||
{
|
||||
MarkNativeAsOptional("ZR_IsValidClassIndex");
|
||||
MarkNativeAsOptional("ZR_GetActiveClass");
|
||||
MarkNativeAsOptional("ZR_SelectClientClass");
|
||||
MarkNativeAsOptional("ZR_GetClassByName");
|
||||
MarkNativeAsOptional("ZR_GetClassDisplayName");
|
||||
|
||||
MarkNativeAsOptional("ZR_IsClientZombie");
|
||||
MarkNativeAsOptional("ZR_IsClientHuman");
|
||||
MarkNativeAsOptional("ZR_InfectClient");
|
||||
MarkNativeAsOptional("ZR_HumanClient");
|
||||
|
||||
MarkNativeAsOptional("ZR_RespawnClient");
|
||||
MarkNativeAsOptional("ZR_SetKilledByWorld");
|
||||
MarkNativeAsOptional("ZR_GetKilledByWorld");
|
||||
}
|
||||
#endif
|
127
includes/zr/class.zr.inc
Normal file
127
includes/zr/class.zr.inc
Normal file
@ -0,0 +1,127 @@
|
||||
/*
|
||||
* ============================================================================
|
||||
*
|
||||
* Zombie:Reloaded
|
||||
*
|
||||
* File: class.zr.inc
|
||||
* Type: Include
|
||||
* Description: Player class API.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* @section Internal class cache types. Specifies which class data to access.
|
||||
*/
|
||||
#define ZR_CLASS_CACHE_ORIGINAL 0 /** Original class data loaded from file. */
|
||||
#define ZR_CLASS_CACHE_MODIFIED 1 /** Default cache. Class data modified by eventual multipliers, map configs, commands, etc. */
|
||||
#define ZR_CLASS_CACHE_PLAYER 2 /** Current player class attributes. The class index parameter is used as client index when reading from this cache. */
|
||||
/**
|
||||
* @endsection
|
||||
*/
|
||||
|
||||
/**
|
||||
* Results when selecting a class for a player.
|
||||
*/
|
||||
enum ClassSelectResult
|
||||
{
|
||||
ClassSelected_NoChange, /** No class change was necessary (class already selected). */
|
||||
ClassSelected_Instant, /** Class was instantly changed. */
|
||||
ClassSelected_NextSpawn /** Class will be used next spawn. */
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a class index is valid or not.
|
||||
*
|
||||
* @param classIndex Class index to validate.
|
||||
*
|
||||
* @return True if valid, false otherwise.
|
||||
*/
|
||||
native bool ZR_IsValidClassIndex(int classIndex);
|
||||
|
||||
/**
|
||||
* Gets the currently active class index that the player is using.
|
||||
*
|
||||
* @param client The client index.
|
||||
*
|
||||
* @return The active class index.
|
||||
*/
|
||||
native bool ZR_GetActiveClass(int client);
|
||||
|
||||
/**
|
||||
* Gets the current human class index that the player is using.
|
||||
*
|
||||
* @param client The client index.
|
||||
*
|
||||
* @return The human class index.
|
||||
*/
|
||||
native bool ZR_GetHumanClass(int client);
|
||||
|
||||
/**
|
||||
* Gets the current zombie class index that the player is using.
|
||||
*
|
||||
* @param client The client index.
|
||||
*
|
||||
* @return The zombie class index.
|
||||
*/
|
||||
native bool ZR_GetZombieClass(int client);
|
||||
|
||||
/**
|
||||
* Selects a class for a player.
|
||||
*
|
||||
* Human class attribute may be instantly applied if player is alive, human and
|
||||
* instant class change is enabled. Otherwise only the selected index will be
|
||||
* updated for next spawn.
|
||||
*
|
||||
* Class selection will be saved in client cookies if enabled.
|
||||
*
|
||||
* @param client Client index.
|
||||
* @param classIndex Class index.
|
||||
* @param applyIfPossible Optional. Apply class attributes if conditions allow
|
||||
* it. Default is true.
|
||||
* @param saveIfEnabled Optional. Save class selection in client cookies if
|
||||
* enabled. Default is true.
|
||||
*
|
||||
* @return Class selection result. See enum ClassSelectResult.
|
||||
*/
|
||||
native ClassSelectResult ZR_SelectClientClass(int client, int classIndex, bool applyIfPossible = true, bool saveIfEnabled = true);
|
||||
|
||||
/**
|
||||
* Gets the class index of the class with the specified name.
|
||||
*
|
||||
* Note: This search is linear and probably won't perform well in large loops.
|
||||
*
|
||||
* @param className Class name to search for.
|
||||
* @param cacheType Optional. Specifies which class cache to read from,
|
||||
* except player cache.
|
||||
*
|
||||
* @return Class index, or -1 if none found.
|
||||
*/
|
||||
native int ZR_GetClassByName(const char[] className, int cacheType = ZR_CLASS_CACHE_MODIFIED);
|
||||
|
||||
/**
|
||||
* Gets the class name displayed in the class menu.
|
||||
*
|
||||
* @param index Index of the class in a class cache or a client index,
|
||||
* depending on the cache type specified.
|
||||
* @param buffer The destination string buffer.
|
||||
* @param maxlen The length of the destination string buffer.
|
||||
* @param cacheType Optional. Specifies which class cache to read from.
|
||||
* @return Number of cells written. -1 on error.
|
||||
*/
|
||||
native int ZR_GetClassDisplayName(int index, char[] buffer, int maxlen, int cacheType = ZR_CLASS_CACHE_MODIFIED);
|
133
includes/zr/infect.zr.inc
Normal file
133
includes/zr/infect.zr.inc
Normal file
@ -0,0 +1,133 @@
|
||||
/*
|
||||
* ============================================================================
|
||||
*
|
||||
* Zombie:Reloaded
|
||||
*
|
||||
* File: infect.zr.inc
|
||||
* Type: Include
|
||||
* Description: Infect-related natives/forwards.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Returns true if the player is a zombie, false if not.
|
||||
*
|
||||
* @param client The client index.
|
||||
*
|
||||
* @return True if zombie, false if not.
|
||||
* @error Invalid client index, not connected or not alive.
|
||||
*/
|
||||
native bool ZR_IsClientZombie(int client);
|
||||
|
||||
/**
|
||||
* Returns true if the player is a human, false if not.
|
||||
*
|
||||
* @param client The client index.
|
||||
*
|
||||
* @return True if human, false if not.
|
||||
* @error Invalid client index, not connected or not alive.
|
||||
*/
|
||||
native bool ZR_IsClientHuman(int client);
|
||||
|
||||
/**
|
||||
* Infects a player.
|
||||
*
|
||||
* Note: If the player already is a zombie, the player will be re-infected.
|
||||
*
|
||||
* @param client The client to infect.
|
||||
* @param attacker (Optional) The attacker who did the infect.
|
||||
* @param motherInfect (Optional) Infect as a mother zombie.
|
||||
* @param respawnOverride (Optional) Set to true to override respawn cvar.
|
||||
* @param respawn (Optional) Value to override with.
|
||||
*
|
||||
* @error Invalid client index, not connected or not alive.
|
||||
*/
|
||||
native int ZR_InfectClient(int client, int attacker = -1, bool motherInfect = false, bool respawnOverride = false, bool respawn = false);
|
||||
|
||||
/**
|
||||
* Turns a zombie back into a human.
|
||||
*
|
||||
* Note: If the player already is a human, this code will still run as the
|
||||
* player was a zombie.
|
||||
*
|
||||
* @param client The client to make human.
|
||||
* @param respawn Teleport client back to spawn.
|
||||
* @param protect Start spawn protection on client.
|
||||
*
|
||||
* @error Invalid client index, not connected or not alive.
|
||||
*/
|
||||
native int ZR_HumanClient(int client, bool respawn = false, bool protect = false);
|
||||
|
||||
/**
|
||||
* Called when a player is about to become a zombie.
|
||||
* Here you can modify any variable or block the infection entirely.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param attacker The the infecter. (-1 if there is no infecter)
|
||||
* @param motherInfect If the client is becoming a mother zombie.
|
||||
* @param respawnOverride True if the respawn cvar is being overridden.
|
||||
* @param respawn The value that respawn is being overridden with.
|
||||
*
|
||||
* @return Plugin_Handled to block infection. Anything else
|
||||
* (like Plugin_Continue) to allow infection.
|
||||
*/
|
||||
forward Action ZR_OnClientInfect(int &client, int &attacker, bool &motherInfect, bool &respawnOverride, bool &respawn);
|
||||
|
||||
/**
|
||||
* Called after a player has become a zombie.
|
||||
*
|
||||
* @param client The client that was infected.
|
||||
* @param attacker The the infecter. (-1 if there is no infecter)
|
||||
* @param motherInfect If the client is a mother zombie.
|
||||
* @param respawnOverride True if the respawn cvar was overridden.
|
||||
* @param respawn The value that respawn was overridden with.
|
||||
*/
|
||||
forward void ZR_OnClientInfected(int client, int attacker, bool motherInfect, bool respawnOverride, bool respawn);
|
||||
|
||||
/**
|
||||
* Called when a player is about to become a human. (Through an admin command).
|
||||
* Here you can modify any variable or block the action entirely.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param respawn True if the client was respawned, false if not.
|
||||
* @param protect True if the client spawn protected, false if not.
|
||||
*
|
||||
* @return Plugin_Handled to block infection. Anything else
|
||||
* (like Plugin_Continue) to allow acion.
|
||||
*/
|
||||
forward Action ZR_OnClientHuman(int &client, bool &respawn, bool &protect);
|
||||
|
||||
/**
|
||||
* Called after a player has become a human. (Through an admin command.)
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param respawn Whether the client was respawned.
|
||||
* @param protect Whether the client has spawn protection.
|
||||
*/
|
||||
forward void ZR_OnClientHumanPost(int client, bool respawn, bool protect);
|
||||
|
||||
/**
|
||||
* Called in ZRCreateEligibleClientList to determine if a client is eligible to become infected.
|
||||
*
|
||||
* @param client The client index.
|
||||
*
|
||||
* @return Plugin_Handled is not eligible. Anything else
|
||||
* (like Plugin_Continue) is eligible.
|
||||
*/
|
||||
forward Action ZR_OnClientMotherZombieEligible(int client);
|
95
includes/zr/respawn.zr.inc
Normal file
95
includes/zr/respawn.zr.inc
Normal file
@ -0,0 +1,95 @@
|
||||
/*
|
||||
* ============================================================================
|
||||
*
|
||||
* Zombie:Reloaded
|
||||
*
|
||||
* File: respawn.zr.inc
|
||||
* Type: Include
|
||||
* Description: Infect-related natives/forwards.
|
||||
*
|
||||
* Copyright (C) 2009-2013 Greyscale, Richard Helgeby
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ============================================================================
|
||||
*/
|
||||
|
||||
/**
|
||||
* Conditions for respawning players.
|
||||
*/
|
||||
enum ZR_RespawnCondition
|
||||
{
|
||||
ZR_Repsawn_Default = -1, /** Let ZR decide according to its settings. */
|
||||
ZR_Respawn_Human = 0, /** Respawn as a human. */
|
||||
ZR_Respawn_Zombie, /** Respawn as a zombie. */
|
||||
ZR_Respawn_ZombieIfSuicide /** Respawn as a zombie if killed by world damage. */
|
||||
}
|
||||
|
||||
/**
|
||||
* Spawns a player into the round.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param condition Optional. Set respawn condition, defaults to current
|
||||
* ZR settings. See ZR_RespawnCondition for details.
|
||||
* @error Invalid client index, not connected or already alive.
|
||||
*/
|
||||
native void ZR_RespawnClient(int client, ZR_RespawnCondition condition = ZR_Repsawn_Default);
|
||||
|
||||
/**
|
||||
* Called right before ZR is about to respawn a player.
|
||||
* Here you can modify any variable or stop the action entirely.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param condition Respawn condition. See ZR_RespawnCondition for
|
||||
* details.
|
||||
*
|
||||
* @return Plugin_Handled to block respawn.
|
||||
*/
|
||||
forward Action ZR_OnClientRespawn(int &client, ZR_RespawnCondition &condition);
|
||||
|
||||
/**
|
||||
* Called after ZR respawned a player.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param condition Current condition of the respawned player. See
|
||||
* ZR_RespawnCondition for details.
|
||||
*/
|
||||
forward void ZR_OnClientRespawned(int client, ZR_RespawnCondition condition);
|
||||
|
||||
/**
|
||||
* Set if a player died by a suicide or world damage.
|
||||
|
||||
* Note: This will change the respawn condition.
|
||||
* Note: This value is reset to default by ZR when a zombie player dies.
|
||||
*
|
||||
* @param client The client index.
|
||||
* @param suicide True to say the player suicided, false if killed by another
|
||||
* player.
|
||||
*
|
||||
* @error Invalid client index or not connected.
|
||||
*/
|
||||
native void ZR_SetKilledByWorld(int client, bool suicide);
|
||||
|
||||
/**
|
||||
* Get whether the player died by a suicide or world damage.
|
||||
*
|
||||
* Note: This value is only valid after death event, and before respawn.
|
||||
*
|
||||
* @param client The client index.
|
||||
*
|
||||
* @return True if the player died by suicide, false if killed by
|
||||
* another player.
|
||||
* @error Invalid client index or not connected.
|
||||
*/
|
||||
native bool ZR_GetKilledByWorld(int client);
|
Loading…
Reference in New Issue
Block a user