Basic version for insurgency
PHP Code:
/****************************************************************************************************
Stealth Revivived
*****************************************************************************************************
*****************************************************************************************************
CHANGELOG:
0.1 - First version.
0.2 -
- Improved spectator blocking with SendProxy (If installed) - Credits to Chaosxk
- Make PTaH optional, sm_stealth_customstatus wont work in CSGO unless PTaH is installed until we find a way to rewrite status without dependencies.
- Only rewrite status if there is atleast 1 stealthed client.
- Improved late loading to account for admins already in spectator.
- Improved support for other games, Still need to do the status rewrite for other games though.
- Improved status anti-spam.
0.3 -
- Fixed variables not being reset on client disconnect.
- Added intial TF2 support (Needs further testing)
0.4 -
- Use SteamWorks or SteamTools for more accurate IP detection, If you have both installed then only SteamWorks is used.
0.5 -
- Fix console ending loop (Thanks Bara for report)
- Fix error spam in TF2 (Thanks rengo)
- Fixed TF2 disconnect reason (Thanks Drixevel)
0.6 -
- Fix more error spam scenarios (Thanks rengo)
- Correct TF2 disconnect reason.
- Misc code changes.
0.7 -
- Fixed issue with fake disconnect event breaking hud / radar.
- Improved logic inside fake event creation.
- General fixes.
0.8 -
- Fixed issue where team broadcast being disabled caused the team menu to get stuck.
- Fixed bad logic in SendProxy Callback.
- Fixed "unconnected" bug on team changes.
- Added check to make sure team event exists.
0.9 -
- Removed SendProxy (It's too problematic)
- Added a ConVar 'sm_stealthrevived_hidecheats' for cheat blocking (SetTransmit is inherently expensive thus this option can cause performance issues on some setups)
0.9.1 -
- Support PtaH 1.1.0 (fix by FIVE)
1.0.0 -
- Removed Fake Disconnect / Connect (Now it wont show any messages)
- I will attempt to fix this later but it has been very problematic, causing issues with radar, event messages showing 'Unconnected' etc.
- Remove SteamTools support - Use SteamWorks already!
- Remove Updater support.
- Fixed PTaH hook.
- Fixed 'version' in status.
- Improved SetTransmit performance when using 'sm_stealthrevived_hidecheats' by only hooking stealthed clients.
- Removed 'status' cmd interval ConVar to keep things simple.
- General fixes.
1.0.1 -
- Fix bad logic in status command hook.
*****************************************************************************************************
*****************************************************************************************************
INCLUDES
*****************************************************************************************************/
#include <sourcemod>
#include <sdktools>
#include <sdkhooks>
#include <StealthRevived>
/****************************************************************************************************
DEFINES
*****************************************************************************************************/
#define PL_VERSION "1.0.2"
#define LoopValidPlayers(%1) for(int %1 = 1; %1 <= MaxClients; %1++) if(IsValidClient(%1))
/****************************************************************************************************
ETIQUETTE.
*****************************************************************************************************/
#pragma newdecls required;
#pragma semicolon 1;
/****************************************************************************************************
PLUGIN INFO.
*****************************************************************************************************/
public Plugin myinfo = {
name = "Stealth Revived",
author = "SM9();",
description = "Just another Stealth plugin.",
version = PL_VERSION,
url = "https://github.com/SM9CC/StealthRevived"
}
bool g_bStealthed[MAXPLAYERS + 1],
g_bHooked = false;
int g_iPlayerManager = -1,
g_bLateLoad;
public void OnPluginStart() {
if (!HookEventEx("player_team", Event_PlayerTeam_Pre, EventHookMode_Pre)) {
SetFailState("player_team event does not exist on this mod, plugin disabled");
return;
}
HookEvent("player_connect", Event_PlayerConnect_Pre, EventHookMode_Pre);
HookEvent("player_disconnect", Event_PlayerDisconnect_Pre, EventHookMode_Pre);
HookEvent("player_pick_squad", Event_PlayerPickSquad_Post, EventHookMode_Post);
}
public APLRes AskPluginLoad2(Handle myself, bool late, char[] eror, int err_max) {
g_bLateLoad = late;
RegPluginLibrary("StealthRevived");
CreateNative("SR_IsClientStealthed", Native_IsClientStealthed);
return APLRes_Success;
}
public void OnMapStart() {
g_iPlayerManager = GetPlayerResourceEntity();
if (g_iPlayerManager == -1) {
SetFailState("\"GetPlayerResourceEntity\" not found!");
}
if (g_bLateLoad) {
g_bLateLoad = false;
for (int i = 1; i <= MaxClients; i++) {
if (!IsClientInGame(i) || IsFakeClient(i) || !CanGoStealth(i)) {
continue;
}
if (!g_bHooked) {
SDKHook(g_iPlayerManager, SDKHook_ThinkPost, Hook_PlayerManagerThinkPost);
g_bHooked = true;
}
}
}
}
public void OnMapEnd() {
g_bHooked = false;
}
public Action Event_PlayerTeam_Pre(Event event, const char[] name, bool dontBroadcast) {
int client;
if (!(client = GetClientOfUserId(event.GetInt("userid"))) || IsFakeClient(client)) {
return Plugin_Continue;
}
if (CanGoStealth(client)) {
event.BroadcastDisabled = true;
g_bStealthed[client] = true;
}
return Plugin_Continue;
}
public Action Event_PlayerPickSquad_Post(Event event, const char[] name, bool dontBroadcast) {
int client;
if (!(client = GetClientOfUserId(event.GetInt("userid"))) || IsFakeClient(client)) {
return Plugin_Continue;
}
if (g_bStealthed[client]) g_bStealthed[client] = false;
return Plugin_Continue;
}
//broadcast fake "joined the game." msg
public void OnClientPostAdminCheck(int client) {
if (!IsFakeClient(client)) {
if (!CanGoStealth(client)) {
PrintToChatAll("%N joined the game.", client);
}
else if (!g_bHooked) {
SDKHook(g_iPlayerManager, SDKHook_ThinkPost, Hook_PlayerManagerThinkPost);
g_bHooked = true;
}
}
}
//to block "joined the game." msg so admin sneakily joins the game :D
public Action Event_PlayerConnect_Pre(Event event, const char[] name, bool dontBroadcast) {
event.BroadcastDisabled = true;
return Plugin_Continue;
}
//block disconnect msg if client in stealth
public Action Event_PlayerDisconnect_Pre(Event event, const char[] name, bool dontBroadcast){
int client;
if (!(client = GetClientOfUserId(event.GetInt("userid"))) || IsFakeClient(client)) {
return Plugin_Continue;
}
if (g_bStealthed[client]) {
event.BroadcastDisabled = true;
g_bStealthed[client] = false;
}
return Plugin_Continue;
}
public void Hook_PlayerManagerThinkPost(int entity) {
bool changed = false;
LoopValidPlayers(client) {
if (!g_bStealthed[client]) {
continue;
}
SetEntProp(g_iPlayerManager, Prop_Send, "m_bConnected", false, _, client);
changed = true;
}
if (changed) {
ChangeEdictState(entity);
} else {
SDKUnhook(g_iPlayerManager, SDKHook_ThinkPost, Hook_PlayerManagerThinkPost);
g_bHooked = false;
}
}
stock bool IsValidClient(int client, bool ignoreBots = true) {
if (client < 1 || client > MaxClients) {
return false;
}
if (!IsClientInGame(client)) {
return false;
}
if (IsFakeClient(client) && ignoreBots) {
return false;
}
return true;
}
stock bool CanGoStealth(int client) {
return CheckCommandAccess(client, "admin_stealth", ADMFLAG_KICK);
}
public int Native_IsClientStealthed(Handle plugin, int numParams) {
int client = GetNativeCell(1);
return g_bStealthed[client];
}