dobrograd-13-06-2022/garrysmod/addons/admin-sg/lua/modules/sh_player.lua
Jonny_Bro (Nikita) e4d5311906 first commit
2023-11-16 15:01:19 +05:00

423 lines
12 KiB
Lua

--[[
© 2017 Thriving Ventures Limited do not share, re-distribute or modify
without permission of its author (gustaf@thrivingventures.com).
]]
--- ## Shared
-- Player manipulation.
-- @module serverguard.player
serverguard.player = serverguard.player or {};
--- Sets a player's rank.
-- @player player The player to set the rank of.
-- @string rank The unique ID of the rank to set as.
-- @bool[opt] length Amount of time (in seconds) after which the rank will be taken away from the player.
-- @bool[opt] bSaveless Whether or not to save the player's rank. Defaults to false;
-- @treturn bool Whether or not the operation was successful.
function serverguard.player:SetRank(player, rank, length, bSaveless)
local rankData = serverguard.ranks:GetRank(rank);
if (!rankData) then
ErrorNoHalt("Error: (SetRank) Attempted to set non-existent rank to player '"..tostring(rank).."'.\n"..debug.traceback().."\n");
return false;
end;
if (isstring(player) and string.SteamID(player)) then
local queryObj = serverguard.mysql:Select("serverguard_users");
queryObj:Where("steam_id", player);
queryObj:Limit(1);
queryObj:Callback(function(result, status, lastID)
if (istable(result) and #result > 0) then
local updateObj = serverguard.mysql:Update("serverguard_users");
updateObj:Update("rank", rank);
updateObj:Where("steam_id", player);
updateObj:Execute();
else
local insertObj = serverguard.mysql:Insert("serverguard_users");
insertObj:Insert("name", "Unknown");
insertObj:Insert("rank", rank);
insertObj:Insert("steam_id", player);
insertObj:Insert("last_played", os.time());
insertObj:Insert("data",
serverguard.von.serialize(
{
groupExpire = ((length != nil and tonumber(length) != nil and length > 0) and os.time() + math.ceil(tonumber(length))) or 0
}
)
);
insertObj:Execute();
end;
end);
queryObj:Execute();
return true;
end;
if (!IsValid(player)) then
ErrorNoHalt("Error: (SetRank) Attempted to set rank to non-existent player.\n"..debug.traceback().."\n");
return false;
end;
player.sg_incognito = nil;
player:SetNetVar("serverguard_rank", rank);
player:SetUserGroup(rank);
if timer.Exists("serverguard.timer.RemoveRank_" .. player:UniqueID()) then
timer.Remove("serverguard.timer.RemoveRank_" .. player:UniqueID());
end;
if (length != nil and tonumber(length) != nil and length > 0) then
serverguard.player:SetData(player, "groupExpire", os.time() + math.ceil(tonumber(length)));
timer.Create("serverguard.timer.RemoveRank_" .. player:UniqueID(), math.ceil(tonumber(length)), 1, function()
if (IsValid(player)) then
serverguard.player:SetRank(player, "user", 0);
end;
end);
else
serverguard.player:SetData(player, "groupExpire", false);
end
if (!bSaveless) then
serverguard.ranks:SavePlayerRank(player, rankData.unique);
end;
if (SERVER) then
timer.Simple(FrameTime() * 32, function()
hook.Run('octolib.updateNetVars', player)
serverguard.netstream.Start(player, "sgSetPlayerRank", true);
end);
end;
return true;
end;
--- Gets the player's rank unique ID. Defaults to "user" if it doesn't exist.
-- @player player The player to get the rank of.
-- @treturn string The rank's unique ID.
function serverguard.player:GetRank(player)
result = "user";
if (IsValid(player) and player:IsPlayer()) then
result = player:GetNetVar("serverguard_rank", "user");
elseif (util.IsConsole(player)) then
result = "founder";
end;
return result;
end;
--- Sets a player's immunity level.
-- @player player The player to set the immunity of.
-- @number immunity The new immunity level to set.
function serverguard.player:SetImmunity(player, immunity)
player:SetNetVar("serverguard_immunity", immunity);
end;
--- Sets a player's ban limit.
-- @player player The player to set the ban limit of.
-- @number limit The new ban limit to set.
function serverguard.player:SetBanLimit(player, limit)
player:SetNetVar("serverguard_banlimit", limit);
end;
--- Sets a player's targetable rank.
-- @player player The player to set the targetable rank of.
-- @number immunity The new targetable rank to set.
function serverguard.player:SetTargetableRank(player, immunity)
player:SetNetVar("serverguard_targetable_rank", immunity);
end;
--- Gets a player's immunity level. Defaults to 0 if the immunity is not set.
-- @player player The player to get the immunity of.
-- @treturn number The immunity level of the player.
function serverguard.player:GetImmunity(player)
if (IsValid(player)) then
return player:GetNetVar("serverguard_immunity", 0);
else
return 100;
end;
end;
--- Gets a player's ban length.
-- @player player The player to get the banlimit of.
-- @number length The ban limit to get.
function serverguard.player:GetBanLimit(player)
if (IsValid(player)) then
return player:GetNetVar("serverguard_banlimit", 0);
end
end;
--- Gets a player's targetable rank. Defaults to 0 if the immunity is not set.
-- @player player The player to get the targetable rank of.
-- @treturn number The targetable rank of the player.
function serverguard.player:GetTargetableRank(player)
if (IsValid(player)) then
return player:GetNetVar("serverguard_targetable_rank", 0);
else
return 100;
end;
end;
--- Returns whether or not the player has a better targetable level than the immunity specified.
-- @player player The player to check the targetable rank of.
-- @number immunity The immunity level to check with.
-- @treturn bool Whether or not the player has a better immunity.
function serverguard.player:HasBetterImmunity(player, immunity)
return self:GetTargetableRank(player) >= immunity;
end;
--- Returns whether or not the player has a better targetable level than the target's immunity level.
-- @player player The player to check the targetable rank of.
-- @player target The target to check with.
-- @treturn bool Whether or not the player has a better immunity.
function serverguard.player:CanTarget(player, target)
return self:GetTargetableRank(player) >= serverguard.player:GetImmunity(target);
end;
--- Gets a player's name. Will return with the orignal name in if player.SteamName is defined.
function serverguard.player:GetName(pPlayer)
if (util.IsConsole(pPlayer)) then
return "Console";
elseif (isplayer(pPlayer)) then
local playerName = pPlayer:Name();
if (pPlayer.SteamName) then
playerName = "(" .. pPlayer:SteamName() .. ") " .. playerName;
end;
return playerName;
else
return "Unknown";
end;
end;
--- Sets up the spectate routine for the given player. Strips weapons, makes invisible,
-- disables collision, etc.
-- @player player The player to set up the spectate mode for.
-- @number mode The spectate mode to use.
function serverguard.player:SetupSpectate(player, mode)
if (!player.sg_spectateData) then
local weapons = player:GetWeapons();
player.sg_spectateData = {};
player.sg_spectateData.weapons = {};
player.sg_spectateData.position = player:GetPos();
player.sg_spectateData.team = player:Team();
for k, v in pairs(weapons) do
table.insert(player.sg_spectateData.weapons, v:GetClass());
end;
end;
player:StripWeapons();
player:SetTeam(TEAM_SPECTATOR);
player:Spectate(mode);
player:SpectateEntity(NULL);
player:SetCollisionGroup(COLLISION_GROUP_WORLD);
if (mode == OBS_MODE_ROAMING) then
player:SetMoveType(MOVETYPE_NOCLIP);
else
player:SetMoveType(MOVETYPE_OBSERVER);
if (IsValid(player.spectateTarget)) then
player:SpectateEntity(player.spectateTarget);
end;
end;
if (!player.spectatorMode) then
player.spectatorMode = 1;
end;
player.sg_spectating = true;
end;
--- Stops a player from spectating. Returns all of their stuff to normal; weapons,
-- collision, etc.
-- @player player The player to make stop spectating.
function serverguard.player:StopSpectate(player)
player:SetTeam(player.sg_spectateData.team);
player:Spectate(OBS_MODE_NONE);
player:SetMoveType(MOVETYPE_WALK);
player:SpectateEntity(NULL);
player:SetCollisionGroup(COLLISION_GROUP_PLAYER);
player:Spawn();
player:SetPos(player.sg_spectateData.position);
for k, v in pairs(player.sg_spectateData.weapons) do
player:Give(v);
end;
player.sg_spectating = nil;
player.sg_spectateData = nil;
end;
--- Gets the target player that the given player is spectating.
-- @player player The spectating player.
-- @bool[opt] decrease Whether or not to get the next/previous player.
-- @treturn player The spectated player.
function serverguard.player:GetSpectatorTarget(pPlayer, decrease)
if (isentity(decrease)) then
pPlayer.spectatorIndex = pPlayer.spectatorIndex or 1;
return decrease;
end
local players = player.GetAll();
for i = 1, #players do
if (v == pPlayer) then
table.remove(players, i);
break;
end;
end;
pPlayer.spectatorIndex = pPlayer.spectatorIndex or 0;
pPlayer.spectatorIndex = decrease and pPlayer.spectatorIndex - 1 or pPlayer.spectatorIndex + 1;
if (pPlayer.spectatorIndex > #players) then
pPlayer.spectatorIndex = 1;
elseif (pPlayer.spectatorIndex < 1) then
pPlayer.spectatorIndex = #players;
end;
return players[player.spectatorIndex];
end;
--- Makes a player spectate the set target.
-- @player player The player to put into spectate mode.
-- @bool[opt] decrease Whether to get the next/previous target.
function serverguard.player:SpectateTarget(player, decrease)
local target = self:GetSpectatorTarget(player, decrease);
player:SpectateEntity(target);
player.spectateTarget = target;
end;
--- Changes a player's spectator mode.
-- @player player The player to change the mode of.
-- @bool[opt] decrease Whether to get the next/previous target.
function serverguard.player:ChangeSpectatorMode(player, decrease)
local spectatorModes = {
OBS_MODE_ROAMING,
OBS_MODE_CHASE,
OBS_MODE_IN_EYE
};
player.spectatorMode = decrease and player.spectatorMode - 1 or player.spectatorMode + 1;
if (player.spectatorMode > #spectatorModes) then
player.spectatorMode = 1;
elseif (player.spectatorMode < 1) then
player.spectatorMode = #spectatorModes;
end;
local mode = spectatorModes[player.spectatorMode];
self:SetupSpectate(player, mode);
end;
if (CLIENT) then
serverguard.netstream.Hook("sgSetPlayerRank", function(data)
serverguard.menu:Rebuild();
end);
end;
--- Gets whether or not the player has the given permission.
-- @player player The player to check the permissions of.
-- @string identifier The name of the permission. This can also be a table of string to check for multiple permissions.
-- @treturn bool Whether or not the player has the given permission.
function serverguard.player:HasPermission(player, identifier)
if (self:GetRank(player) == "founder") then
return true;
end;
local permissionTable = serverguard.ranks:GetData(
self:GetRank(player), "Permissions"
);
if (permissionTable) then
local identype = type(identifier)
if (identype == "string") then
return permissionTable[identifier] or false;
end
if (identype == "table") then
for k, v in pairs(identifier) do
if (isstring(v) and permissionTable[v]) then
return true;
end;
end;
end;
end;
return false;
end;
do
local playerMeta = FindMetaTable("Player");
playerMeta.sgIsAdmin = playerMeta.sgIsAdmin or playerMeta.IsAdmin;
playerMeta.sgIsSuperAdmin = playerMeta.sgIsSuperAdmin or playerMeta.IsSuperAdmin;
playerMeta.sgIsUserGroup = playerMeta.sgIsUserGroup or playerMeta.IsUserGroup;
--
-- Override IsAdmin to check serverguard rank.
--
function playerMeta:IsAdmin()
if (self:IsSuperAdmin() or serverguard.player:HasPermission(self, "Admin")) then
return true;
end;
return self:sgIsAdmin();
end;
--
-- Override IsSuperAdmin to check serverguard rank.
--
function playerMeta:IsSuperAdmin()
if (serverguard.player:HasPermission(self, "Superadmin")) then
return true;
end;
return self:sgIsSuperAdmin();
end;
--
-- Override IsUserGroup to check serverguard rank.
--
function playerMeta:IsUserGroup(name)
if (serverguard.player:GetRank(self) == name) then
return true;
end;
return self:sgIsUserGroup(name)
end;
--
-- Override GetUserGroup to check serverguard rank.
--
function playerMeta:GetUserGroup()
return serverguard.player:GetRank(self);
end;
--
-- Override Ban to use serverguard ban.
--
function playerMeta:Ban(length, bKick, reason)
reason = reason or "No Reason";
serverguard:BanPlayer(nil, self, length, reason, bKick);
end;
end;