You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

218 lines
5.6 KiB

#pragma semicolon 1
#include <sourcemod>
#define SPECMODE_NONE 0
#define SPECMODE_FIRSTPERSON 4
#define SPECMODE_3RDPERSON 5
#define SPECMODE_FREELOOK 6
#define UPDATE_INTERVAL 1.0
#define PLUGIN_VERSION "1.1.2"
new Handle:HudHintTimers[MAXPLAYERS+1];
new Handle:sm_speclist_enabled;
new Handle:sm_speclist_allowed;
new Handle:sm_speclist_adminonly;
new bool:g_Enabled;
new bool:g_AdminOnly;
public Plugin:myinfo =
{
name = "Spectator List",
author = "GoD-Tony",
description = "View who is spectating you",
version = PLUGIN_VERSION,
url = "http://www.sourcemod.net/"
};
public OnPluginStart()
{
CreateConVar("sm_speclist_version", PLUGIN_VERSION, "Spectator List Version", FCVAR_PLUGIN|FCVAR_SPONLY|FCVAR_REPLICATED|FCVAR_NOTIFY|FCVAR_DONTRECORD);
sm_speclist_enabled = CreateConVar("sm_speclist_enabled","1","Enables the spectator list for all players by default.");
sm_speclist_allowed = CreateConVar("sm_speclist_allowed","1","Allows players to enable spectator list manually when disabled by default.");
sm_speclist_adminonly = CreateConVar("sm_speclist_adminonly","0","Only admins can use the features of this plugin.");
RegConsoleCmd("sm_speclist", Command_SpecList);
HookConVarChange(sm_speclist_enabled, OnConVarChange);
HookConVarChange(sm_speclist_adminonly, OnConVarChange);
g_Enabled = GetConVarBool(sm_speclist_enabled);
g_AdminOnly = GetConVarBool(sm_speclist_adminonly);
AutoExecConfig(true, "plugin.speclist");
}
public OnConVarChange(Handle:hCvar, const String:oldValue[], const String:newValue[])
{
if (hCvar == sm_speclist_enabled)
{
g_Enabled = GetConVarBool(sm_speclist_enabled);
if (g_Enabled)
{
// Enable timers on all players in game.
for(new i = 1; i <= MaxClients; i++)
{
if (!IsClientInGame(i))
continue;
CreateHudHintTimer(i);
}
}
else
{
// Kill all of the active timers.
for(new i = 1; i <= MaxClients; i++)
KillHudHintTimer(i);
}
}
else if (hCvar == sm_speclist_adminonly)
{
g_AdminOnly = GetConVarBool(sm_speclist_adminonly);
if (g_AdminOnly)
{
// Kill all of the active timers.
for(new i = 1; i <= MaxClients; i++)
KillHudHintTimer(i);
// Enable timers on all admins in game.
for(new i = 1; i <= MaxClients; i++)
{
if (!IsClientInGame(i))
continue;
CreateHudHintTimer(i);
}
}
}
}
public OnClientPostAdminCheck(client)
{
if (g_Enabled)
CreateHudHintTimer(client);
}
public OnClientDisconnect(client)
{
KillHudHintTimer(client);
}
// Using 'sm_speclist' to toggle the spectator list per player.
public Action:Command_SpecList(client, args)
{
if (HudHintTimers[client] != INVALID_HANDLE)
{
KillHudHintTimer(client);
ReplyToCommand(client, "[SM] Spectator list disabled.");
}
else if (g_Enabled || GetConVarBool(sm_speclist_allowed))
{
CreateHudHintTimer(client);
ReplyToCommand(client, "[SM] Spectator list enabled.");
}
return Plugin_Handled;
}
public Action:Timer_UpdateHudHint(Handle:timer, any:client)
{
new iSpecModeUser = GetEntProp(client, Prop_Send, "m_iObserverMode");
new iSpecMode, iTarget, iTargetUser;
new bool:bDisplayHint = false;
decl String:szText[254];
szText[0] = '\0';
// Dealing with a client who is in the game and playing.
if (IsPlayerAlive(client))
{
for(new i = 1; i <= MaxClients; i++)
{
if (!IsClientInGame(i) || !IsClientObserver(i))
continue;
iSpecMode = GetEntProp(i, Prop_Send, "m_iObserverMode");
// The client isn't spectating any one person, so ignore them.
if (iSpecMode != SPECMODE_FIRSTPERSON && iSpecMode != SPECMODE_3RDPERSON)
continue;
// Find out who the client is spectating.
iTarget = GetEntPropEnt(i, Prop_Send, "m_hObserverTarget");
// Are they spectating our player?
if (iTarget == client)
{
Format(szText, sizeof(szText), "%s%N\n", szText, i);
bDisplayHint = true;
}
}
}
else if (iSpecModeUser == SPECMODE_FIRSTPERSON || iSpecModeUser == SPECMODE_3RDPERSON)
{
// Find out who the User is spectating.
iTargetUser = GetEntPropEnt(client, Prop_Send, "m_hObserverTarget");
if (iTargetUser > 0)
Format(szText, sizeof(szText), "Spectating %N:\n", iTargetUser);
for(new i = 1; i <= MaxClients; i++)
{
if (!IsClientInGame(i) || !IsClientObserver(i))
continue;
iSpecMode = GetEntProp(i, Prop_Send, "m_iObserverMode");
// The client isn't spectating any one person, so ignore them.
if (iSpecMode != SPECMODE_FIRSTPERSON && iSpecMode != SPECMODE_3RDPERSON)
continue;
// Find out who the client is spectating.
iTarget = GetEntPropEnt(i, Prop_Send, "m_hObserverTarget");
// Are they spectating the same player as User?
if (iTarget == iTargetUser)
Format(szText, sizeof(szText), "%s%N\n", szText, i);
}
}
/* We do this to prevent displaying a message
to a player if no one is spectating them anyway. */
if (bDisplayHint)
{
Format(szText, sizeof(szText), "Spectating %N:\n%s", client, szText);
bDisplayHint = false;
}
// Send our message
new Handle:hBuffer = StartMessageOne("KeyHintText", client);
BfWriteByte(hBuffer, 1);
BfWriteString(hBuffer, szText);
EndMessage();
return Plugin_Continue;
}
CreateHudHintTimer(client)
{
// If AdminOnly is enabled, make sure we only create timers on admins.
new AdminId:admin = GetUserAdmin(client);
if (!g_AdminOnly || (g_AdminOnly && GetAdminFlag(admin, Admin_Generic, Access_Effective)))
HudHintTimers[client] = CreateTimer(UPDATE_INTERVAL, Timer_UpdateHudHint, client, TIMER_REPEAT|TIMER_FLAG_NO_MAPCHANGE);
}
KillHudHintTimer(client)
{
if (HudHintTimers[client] != INVALID_HANDLE)
{
KillTimer(HudHintTimers[client]);
HudHintTimers[client] = INVALID_HANDLE;
}
}