Observe Client 1.2.4  [На сервере]

Плагины и дополнения / Plugins and add-ons

Модераторы: Dame-danners, Longipongeoos

Аватар пользователя
Dame-danners
Сообщений: 52
Зарегистрирован: 12 апр 2017, 17:10

Observe Client 1.2.4  [На сервере]

Сообщение Dame-danners » 21 ноя 2018, 14:30

Наблюдение за всеми игроками администратором через меню sourcemod
Исходный код

Код: Выбрать все

#include <sourcemod>
#include <sdktools>

#pragma semicolon 1

#define VERSION "1.2.4"
#define NAME "Observe Client"

#define ADMINFLAG ADMFLAG_KICK

public Plugin:myinfo =
{
   name = NAME,
   author = "WhiteWolf, puopjik, psychonic, RedSword",
   description = "Observe client when dead",
   version = VERSION,
   url = "http://www.whitewolf.us"
};

/* Credits:
   Mani - Showed me his observer code from MAP
*/

/* Globals */
new g_offObserverTarget;
new g_clientObserveTarget[MAXPLAYERS+1];
new bool:g_useSteamBans = false;

//CSGO-related
new bool:g_isCSGO;
new Handle:g_hSpec_freeze_time;
new Handle:g_hSpec_freeze_traveltime;
new Handle:g_hSpec_freeze_deathanim_time;


public OnPluginStart() {
   new Handle:conVar;
   
   CreateConVar("observe_version", VERSION, NAME, FCVAR_SPONLY|FCVAR_NOTIFY);
   
   HookEvent("player_spawn", EventPlayerSpawn);
   HookEvent("player_death", EventPlayerDeath);
   
   
   RegAdminCmd("sm_observe", CommandObserve, ADMINFLAG, "Spectate a player when dead.");
   RegAdminCmd("sm_endobserve", CommandEndObserve, ADMINFLAG, "End spectating a player.");
   
   LoadTranslations("common.phrases");
   LoadTranslations("observe.phrases");
   
   g_offObserverTarget = FindSendPropOffs("CBasePlayer", "m_hObserverTarget");
   if(g_offObserverTarget == -1) {
      SetFailState("Expected to find the offset to m_hObserverTarget, couldn't.");
   }
   
   conVar = FindConVar("sbsrc_version");
   if(conVar != INVALID_HANDLE) {
      g_useSteamBans = true;
   }
   
   decl String:szBuffer[ 8 ];
   
   GetGameFolderName(szBuffer, sizeof(szBuffer));
   
   g_isCSGO = StrEqual(szBuffer, "csgo", false);
   if (g_isCSGO)
   {
      g_hSpec_freeze_time = FindConVar("spec_freeze_time");
      g_hSpec_freeze_traveltime = FindConVar("spec_freeze_traveltime");
      g_hSpec_freeze_deathanim_time = FindConVar("spec_freeze_deathanim_time");
   }
}

/********************************************************************************
   Events
*********************************************************************************/

public Action:EventPlayerSpawn(Handle:event, const String:name[], bool:dontBroadcast) {
   /* Suggestions for improvement, or single-shot method? */
   new target = GetClientOfUserId(GetEventInt(event, "userid"));
   for(new client = 1; client <= MaxClients; client++) {
      if(g_clientObserveTarget[client] == target && (IsClientObserver(client) || !IsPlayerAlive(client))) {
         SetClientObserver(client, target, true);
         return Plugin_Handled;
      }
   }
   return Plugin_Handled;
}

public Action:EventPlayerDeath(Handle:event, const String:name[], bool:dontBroadcast) {
   
   new userId = GetEventInt(event, "userid");
   
   if (!g_isCSGO)
   {
      Timer_Death(INVALID_HANDLE, userId);
   }
   else
   {
      CreateTimer(GetConVarFloat(g_hSpec_freeze_time) +
         GetConVarFloat(g_hSpec_freeze_traveltime) +
         GetConVarFloat(g_hSpec_freeze_deathanim_time) +
         0.1, Timer_Death, userId ); //0.1 is needed; tested
   }
   
   return Plugin_Handled;
}

public Action:Timer_Death(Handle:timer, any:userId)
{
   new client = GetClientOfUserId(userId);
   
   if (g_isCSGO && client > 0 && IsClientInGame(client) && IsPlayerAlive(client))
   {
      return Plugin_Handled;//prevent late kill messages
   }
   
   //Won't be a real Timer
   if(g_clientObserveTarget[client] > 0) {
      new target = g_clientObserveTarget[client];
      if(!isValidHumanClient(target)) {
         g_clientObserveTarget[client] = 0;
         return Plugin_Handled;
      }
      
      if(IsPlayerAlive(target)) {
         SetClientObserver(client, target, true);
      }
   }
   return Plugin_Handled;
}

public OnClientDisconnect(client) {
   new String:clientName[MAX_NAME_LENGTH];
   GetClientName(client, clientName, MAX_NAME_LENGTH);
   
   g_clientObserveTarget[client] = 0;
   for(new i = 1; i <= MaxClients; i++) {
      if(g_clientObserveTarget[i] == client) {
         g_clientObserveTarget[i] = 0;
         if (IsClientInGame(i) && IsClientConnected(i)) {
            PrintToChat(i, "%t", "Target Left", clientName);
         }
      }
   }
}

/********************************************************************************
   Commands
*********************************************************************************/

public Action:CommandEndObserve(client, args) {
   g_clientObserveTarget[client] = 0;
   PrintToChat(client, "%t", "End Observe");
   return Plugin_Handled;
}

public Action:CommandObserve(client, args) {
   if(GetCmdArgs() < 1) {
      ReplyToCommand(client, "Usage: sm_observe <name or #userid>");
      return Plugin_Handled;
   }
   
   decl String:targetName[MAX_NAME_LENGTH], String:targetSteamID[MAX_NAME_LENGTH];
   
   GetCmdArg(1, targetName, sizeof(targetName)); //get username part from arguments
   
   new targetClient = FindTarget(client, targetName, false, false);
   if(targetClient == -1) {
      PrintToChat(client, "%t", "Unknown Target");
      return Plugin_Handled;
   }
   
   GetClientName(targetClient, targetName, sizeof(targetName));
   GetClientAuthString(targetClient, targetSteamID, sizeof(targetSteamID));
   g_clientObserveTarget[client] = targetClient;
   
   if(IsClientObserver(client) || !IsPlayerAlive(client)) {
      if(!SetClientObserver(client, targetClient, true)) {
         PrintToChat(client, "%t", "Observe Failed", targetName);
      }
   } else {
      PrintToChat(client, "%t", "Observe on Spec", targetName, targetSteamID);
   }
   
   return Plugin_Handled;
}

/********************************************************************************
   Helper Methods
*********************************************************************************/

public bool:isValidHumanClient(client) {
   if(client > 0 && IsClientInGame(client) && IsClientConnected(client)) {
      return true;
   }
   return false;
}
      
public bool:SetClientObserver(client, target, bool:sendMessage) {
   if(!isValidHumanClient(client) || !isValidHumanClient(target)) {
      return false;
   }
   
   SetEntDataEnt2(client, g_offObserverTarget, target, true);
   
   if(sendMessage) {
      SendClientObserveMessage(client, target);
   }
   
   if(g_useSteamBans) {
      ClientCommand(client, "sb_status");
   }
      
   return true; //we assume it went through, else SM would throw a native error and we wouldn't get here anyway
}

public SendClientObserveMessage(client, target) {
   decl String:targetName[MAX_NAME_LENGTH], String:targetSteamID[65];
   GetClientName(target, targetName, MAX_NAME_LENGTH);
   GetClientAuthString(target, targetSteamID, 65);
   PrintToChat(client, "%t", "Observing", targetName, targetSteamID);
}

Команды:

Код: Выбрать все

sm_observe <playername> - указать игрока
sm_endobserve - отмена наблюдения

Добавление в Super Menu's:

Код: Выбрать все

"Commands"
{
"Меню наблюдения"
{
"Начать наблюдение"
{
"admin" "sm_kick"
"cmd" "sm_observe #1"
"execute" "player"
"1"
{
"type" "groupplayer"
"method" "name"
"title" "Наблюдать за:"
}
}
"Закончить наблюдение"
{
"cmd" "sm_endobserve"
"admin" "sm_kick"
"execute" "player"
}
}
}

Установка:
Скопировать файл observe.smx в директорию cstrike/addons/sourcemod/plugins/
Скопировать файл observe.sp в директорию addons/sourcemod/scripting
Скопировать файл observe.phrases.txt в директорию cstrike/addons/sourcemod/translations/
Скопировать файл adminmenu_custom.txt в директорию addons/sourcemod/configs
Вложения
observe.zip
(9.06 KiB) Загружено 64 раз

Вернуться в «SourceMod»

Кто сейчас на форуме

Количество пользователей, которые сейчас просматривают этот форум: нет зарегистрированных пользователей и 1 гость