Banned players are let in long enough to be told the ban's reason and time left, then kicked after KickTime, instead of only seeing "Your client is not allowed to join this server"; they can't chat, talk or join a team meanwhile. New permission @css/bypassipban (players or groups, implied by @css/root) skips IP and shared-IP bans, leaving only bans on their own SteamID, on join and in the periodic check. Moving to spectators no longer unhides a hidden admin; only joining T or CT does.
558 lines
No EOL
20 KiB
C#
558 lines
No EOL
20 KiB
C#
using System.Numerics;
|
|
using CounterStrikeSharp.API;
|
|
using CounterStrikeSharp.API.Core;
|
|
using CounterStrikeSharp.API.Core.Attributes.Registration;
|
|
using CounterStrikeSharp.API.Modules.Commands;
|
|
using CounterStrikeSharp.API.Modules.Entities;
|
|
using CS2_SimpleAdmin.Managers;
|
|
using CS2_SimpleAdmin.Models;
|
|
using CS2_SimpleAdminApi;
|
|
using Microsoft.Extensions.Logging;
|
|
using System.Text;
|
|
using CounterStrikeSharp.API.Core.Translations;
|
|
using CounterStrikeSharp.API.Modules.Admin;
|
|
using CounterStrikeSharp.API.Modules.UserMessages;
|
|
|
|
namespace CS2_SimpleAdmin;
|
|
|
|
public partial class CS2_SimpleAdmin
|
|
{
|
|
private bool _serverLoading;
|
|
|
|
private void RegisterEvents()
|
|
{
|
|
RegisterListener<Listeners.OnMapStart>(OnMapStart);
|
|
// RegisterListener<Listeners.OnClientConnect>(OnClientConnect);
|
|
// RegisterListener<Listeners.OnClientConnect>(OnClientConnect);
|
|
RegisterListener<Listeners.OnClientConnected>(OnClientConnected);
|
|
RegisterListener<Listeners.OnGameServerSteamAPIActivated>(OnGameServerSteamAPIActivated);
|
|
if (Config.OtherSettings.UserMessageGagChatType)
|
|
HookUserMessage(118, HookUmChat);
|
|
|
|
AddCommandListener(null, ComamndListenerHandler);
|
|
// AddCommandListener("callvote", OnCommandCallVote);
|
|
// AddCommandListener("say", OnCommandSay);
|
|
// AddCommandListener("say_team", OnCommandTeamSay);
|
|
}
|
|
|
|
private void UnregisterEvents()
|
|
{
|
|
RemoveListener<Listeners.OnMapStart>(OnMapStart);
|
|
RemoveListener<Listeners.OnClientConnect>(OnClientConnect);
|
|
RemoveListener<Listeners.OnClientConnected>(OnClientConnected);
|
|
RemoveListener<Listeners.OnGameServerSteamAPIActivated>(OnGameServerSteamAPIActivated);
|
|
if (Config.OtherSettings.UserMessageGagChatType)
|
|
UnhookUserMessage(118, HookUmChat);
|
|
|
|
RemoveCommandListener(null!, ComamndListenerHandler, HookMode.Pre);
|
|
// AddCommandListener("callvote", OnCommandCallVote);
|
|
// AddCommandListener("say", OnCommandSay);
|
|
// AddCommandListener("say_team", OnCommandTeamSay);
|
|
}
|
|
|
|
|
|
// private HookResult OnCommandCallVote(CCSPlayerController? caller, CommandInfo info)
|
|
// {
|
|
// var voteType = info.GetArg(1).ToLower();
|
|
//
|
|
// if (voteType != "kick")
|
|
// return HookResult.Continue;
|
|
//
|
|
// var target = int.TryParse(info.GetArg(2), out var userId)
|
|
// ? Utilities.GetPlayerFromUserid(userId)
|
|
// : null;
|
|
//
|
|
// if (target == null || !target.IsValid || target.Connected != PlayerConnectedState.PlayerConnected)
|
|
// return HookResult.Continue;
|
|
//
|
|
// return !AdminManager.CanPlayerTarget(caller, target) ? HookResult.Stop : HookResult.Continue;
|
|
// }
|
|
|
|
private void OnGameServerSteamAPIActivated()
|
|
{
|
|
if (ServerLoaded || _serverLoading)
|
|
return;
|
|
|
|
_serverLoading = true;
|
|
new ServerManager().LoadServerData();
|
|
}
|
|
|
|
[GameEventHandler]
|
|
public HookResult OnClientDisconnect(EventPlayerDisconnect @event, GameEventInfo info)
|
|
{
|
|
if (@event.Reason is 149 or 6)
|
|
info.DontBroadcast = true;
|
|
|
|
var player = @event.Userid;
|
|
|
|
#if DEBUG
|
|
Logger.LogCritical("[OnClientDisconnect] Before");
|
|
#endif
|
|
|
|
if (player == null || !player.IsValid || player.IsHLTV)
|
|
return HookResult.Continue;
|
|
|
|
CachedPlayers.Remove(player);
|
|
BotPlayers.Remove(player);
|
|
SilentPlayers.Remove(player.Slot);
|
|
PendingBanKicks.Remove(player.Slot);
|
|
|
|
if (player.IsBot)
|
|
{
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
#if DEBUG
|
|
Logger.LogCritical("[OnClientDisconnect] After Check");
|
|
#endif
|
|
try
|
|
{
|
|
if (DisconnectedPlayers.Count >= Config.OtherSettings.DisconnectedPlayersHistoryCount)
|
|
DisconnectedPlayers.RemoveAt(0);
|
|
|
|
var steamId = new SteamID(player.SteamID);
|
|
var disconnectedPlayer = DisconnectedPlayers.FirstOrDefault(p => p.SteamId == steamId);
|
|
|
|
if (disconnectedPlayer != null)
|
|
{
|
|
disconnectedPlayer.Name = player.PlayerName;
|
|
disconnectedPlayer.IpAddress = player.IpAddress?.Split(":")[0];
|
|
disconnectedPlayer.DisconnectTime = Time.ActualDateTime();
|
|
}
|
|
else
|
|
{
|
|
DisconnectedPlayers.Add(new DisconnectedPlayer(steamId, player.PlayerName,
|
|
player.IpAddress?.Split(":")[0], Time.ActualDateTime()));
|
|
}
|
|
|
|
PlayerPenaltyManager.RemoveAllPenalties(player.Slot);
|
|
|
|
if (player.UserId.HasValue)
|
|
PlayersInfo.TryRemove(player.SteamID, out _);
|
|
|
|
if (!PermissionManager.AdminCache.TryGetValue(steamId, out var data)
|
|
|| !(data.ExpirationTime <= Time.ActualDateTime()))
|
|
{
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
AdminManager.RemovePlayerPermissions(steamId, PermissionManager.AdminCache[steamId].Flags.ToArray());
|
|
AdminManager.RemovePlayerFromGroup(steamId, true, PermissionManager.AdminCache[steamId].Flags.ToArray());
|
|
var adminData = AdminManager.GetPlayerAdminData(steamId);
|
|
|
|
if (adminData == null || data.Flags.ToList().Count != 0 && adminData.Groups.ToList().Count != 0)
|
|
return HookResult.Continue;
|
|
|
|
AdminManager.ClearPlayerPermissions(steamId);
|
|
AdminManager.RemovePlayerAdminData(steamId);
|
|
|
|
return HookResult.Continue;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
Logger.LogError($"An error occurred in OnClientDisconnect: {ex.Message}");
|
|
return HookResult.Continue;
|
|
}
|
|
}
|
|
|
|
private void OnClientConnect(int playerslot, string name, string ipAddress)
|
|
{
|
|
#if DEBUG
|
|
Logger.LogCritical("[OnClientConnect]");
|
|
#endif
|
|
|
|
var player = Utilities.GetPlayerFromSlot(playerslot);
|
|
if (player == null || !player.IsValid || player.IsBot)
|
|
return;
|
|
|
|
PlayerManager.LoadPlayerData(player);
|
|
}
|
|
|
|
private void OnClientConnected(int playerslot)
|
|
{
|
|
#if DEBUG
|
|
Logger.LogCritical("[OnClientConnected]");
|
|
#endif
|
|
|
|
var player = Utilities.GetPlayerFromSlot(playerslot);
|
|
if (player == null || !player.IsValid || player.IsBot)
|
|
return;
|
|
|
|
if (!CachedPlayers.Contains(player))
|
|
CachedPlayers.Add(player);
|
|
|
|
PlayerManager.LoadPlayerData(player);
|
|
}
|
|
|
|
// private void OnClientConnect(int playerslot, string name, string ipaddress)
|
|
// {
|
|
// #if DEBUG
|
|
// Logger.LogCritical("[OnClientConnect]");
|
|
// #endif
|
|
// if (Config.OtherSettings.BanType == 0)
|
|
// return;
|
|
//
|
|
// if (Instance.CacheManager != null && !Instance.CacheManager.IsPlayerBanned(null, ipaddress.Split(":")[0]))
|
|
// return;
|
|
//
|
|
// var testPlayer = Utilities.GetPlayerFromSlot(playerslot);
|
|
// if (testPlayer == null)
|
|
// return;
|
|
// Logger.LogInformation($"Gracz {testPlayer.PlayerName} ({testPlayer.SteamID.ToString()}) Czas: {DateTime.Now}");
|
|
//
|
|
// Server.NextFrame((() =>
|
|
// {
|
|
// var player = Utilities.GetPlayerFromSlot(playerslot);
|
|
// if (player == null || !player.IsValid || player.IsBot)
|
|
// return;
|
|
//
|
|
// Helper.KickPlayer(player, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED);
|
|
// }));
|
|
//
|
|
// // Server.NextFrame(() =>
|
|
// // {
|
|
// // var player = Utilities.GetPlayerFromSlot(playerslot);
|
|
// //
|
|
// // if (player == null || !player.IsValid || player.IsBot)
|
|
// // return;
|
|
// //
|
|
// // new PlayerManager().LoadPlayerData(player);
|
|
// // });
|
|
// }
|
|
|
|
[GameEventHandler]
|
|
public HookResult OnPlayerFullConnect(EventPlayerConnectFull @event, GameEventInfo info)
|
|
{
|
|
#if DEBUG
|
|
Logger.LogCritical("[OnPlayerFullConnect]");
|
|
#endif
|
|
|
|
var player = @event.Userid;
|
|
|
|
if (player == null || !player.IsValid)
|
|
return HookResult.Continue;
|
|
|
|
if (player is { IsBot: true, IsHLTV: false })
|
|
{
|
|
BotPlayers.Add(player);
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
PlayerManager.LoadPlayerData(player, true);
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
[GameEventHandler]
|
|
public HookResult OnRoundStart(EventRoundStart @event, GameEventInfo info)
|
|
{
|
|
#if DEBUG
|
|
Logger.LogCritical("[OnRoundStart]");
|
|
#endif
|
|
|
|
foreach (var player in PlayersInfo.Values)
|
|
{
|
|
player.DiePosition = null;
|
|
}
|
|
|
|
AddTimer(0.5f, () =>
|
|
{
|
|
foreach (var list in RenamedPlayers)
|
|
{
|
|
var player = Utilities.GetPlayerFromSteamId(list.Key);
|
|
|
|
if (player == null || !player.IsValid || player.Connected != PlayerConnectedState.Connected)
|
|
continue;
|
|
|
|
if (player.PlayerName.Equals(list.Value))
|
|
continue;
|
|
|
|
player.Rename(list.Value);
|
|
}
|
|
});
|
|
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
private HookResult HookUmChat(UserMessage um)
|
|
{
|
|
var author = Utilities.GetPlayerFromIndex(um.ReadInt("entityindex"));
|
|
if (author == null || !author.IsValid || author.IsBot)
|
|
return HookResult.Continue;
|
|
|
|
if (!PlayerPenaltyManager.IsPenalized(author.Slot, PenaltyType.Gag, out DateTime? endDateTime) &&
|
|
!PlayerPenaltyManager.IsPenalized(author.Slot, PenaltyType.Silence, out endDateTime))
|
|
return HookResult.Continue;
|
|
|
|
if (_localizer == null || endDateTime == null)
|
|
return HookResult.Continue;
|
|
|
|
var message = um.ReadString("param2");
|
|
var triggers = CoreConfig.PublicChatTrigger.Concat(CoreConfig.SilentChatTrigger);
|
|
if (!triggers.Any(trigger => message.StartsWith(trigger))) return HookResult.Stop;
|
|
|
|
for (var i = um.Recipients.Count - 1; i >= 0; i--)
|
|
{
|
|
if (um.Recipients[i] != author)
|
|
{
|
|
um.Recipients.RemoveAt(i);
|
|
}
|
|
}
|
|
|
|
return HookResult.Continue;
|
|
|
|
// author.SendLocalizedMessage(_localizer, "sa_player_penalty_chat_active", endDateTime.Value.ToString("g", author.GetLanguage()));
|
|
}
|
|
|
|
private HookResult ComamndListenerHandler(CCSPlayerController? player, CommandInfo info)
|
|
{
|
|
if (player == null || !player.IsValid || player.IsBot)
|
|
return HookResult.Continue;
|
|
|
|
var command = info.GetArg(0).ToLower();
|
|
|
|
// zio: a banned player waiting to be kicked can't talk or join a team.
|
|
if (PendingBanKicks.Contains(player.Slot) && (command.Contains("say") || command == "jointeam"))
|
|
return HookResult.Stop;
|
|
|
|
if (Config.OtherSettings.AdditionalCommandsToLog.Contains(command))
|
|
Helper.LogCommand(player, info);
|
|
|
|
switch (command)
|
|
{
|
|
case "css_admins_reload":
|
|
AddTimer(1.0f, () => ReloadAdmins(null));
|
|
return HookResult.Continue;
|
|
case "callvote":
|
|
{
|
|
var voteType = info.GetArg(1).ToLower();
|
|
|
|
if (voteType != "kick")
|
|
return HookResult.Continue;
|
|
|
|
var target = int.TryParse(info.GetArg(2), out var userId)
|
|
? Utilities.GetPlayerFromUserid(userId)
|
|
: null;
|
|
|
|
if (target == null || !target.IsValid || target.Connected != PlayerConnectedState.Connected)
|
|
return HookResult.Continue;
|
|
|
|
return !player.CanTarget(target) ? HookResult.Stop : HookResult.Continue;
|
|
}
|
|
}
|
|
|
|
if (!command.Contains("say"))
|
|
return HookResult.Continue;
|
|
|
|
if (info.GetArg(1).Length == 0)
|
|
return HookResult.Stop;
|
|
|
|
var triggers = CoreConfig.PublicChatTrigger.Concat(CoreConfig.SilentChatTrigger);
|
|
if (triggers.Any(trigger => info.GetArg(1).StartsWith(trigger)))
|
|
{
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
// zio: gagged players can still reach staff with @ in team chat, handled below.
|
|
var staffChat = command == "say_team" && info.GetArg(1).StartsWith('@');
|
|
// if (!Config.OtherSettings.UserMessageGagChatType)
|
|
// {
|
|
if (!staffChat && (PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Gag, out DateTime? endDateTime) ||
|
|
PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence, out endDateTime)))
|
|
{
|
|
if (_localizer != null && endDateTime is not null)
|
|
SendChatPenaltyMessage(player, endDateTime.Value);
|
|
return HookResult.Stop;
|
|
}
|
|
// }
|
|
|
|
if (AdminManager.PlayerHasPermissions(new SteamID(player.SteamID), "@css/chat") && command == "say" && info.GetArg(1).StartsWith($"@"))
|
|
{
|
|
player.ExecuteClientCommandFromServer($"css_say {info.GetArg(1).Remove(0, 1)}");
|
|
return HookResult.Stop;
|
|
}
|
|
|
|
if (command != "say_team" || !info.GetArg(1).StartsWith($"@")) return HookResult.Continue;
|
|
|
|
StringBuilder sb = new();
|
|
if (AdminManager.PlayerHasPermissions(new SteamID(player.SteamID), "@css/chat"))
|
|
{
|
|
sb.Append(_localizer!["sa_adminchat_template_admin", player.PlayerName, info.GetArg(1).Remove(0, 1)]);
|
|
foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid && p is { IsBot: false, IsHLTV: false } && AdminManager.PlayerHasPermissions(new SteamID(p.SteamID), "@css/chat")))
|
|
{
|
|
p.PrintToChat(sb.ToString());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sb.Append(_localizer!["sa_adminchat_template_player", player.PlayerName, info.GetArg(1).Remove(0, 1)]);
|
|
player.PrintToChat(sb.ToString());
|
|
foreach (var p in Utilities.GetPlayers().Where(p => p is { IsValid: true, IsBot: false, IsHLTV: false } && AdminManager.PlayerHasPermissions(new SteamID(p.SteamID), "@css/chat")))
|
|
{
|
|
p.PrintToChat(sb.ToString());
|
|
}
|
|
}
|
|
|
|
return HookResult.Stop;
|
|
}
|
|
|
|
// zio: says how long the gag (or silence) has left and why, in place of its end date.
|
|
private void SendChatPenaltyMessage(CCSPlayerController player, DateTime endDateTime)
|
|
{
|
|
var type = PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Gag, out var gagEnd) && gagEnd == endDateTime
|
|
? PenaltyType.Gag
|
|
: PenaltyType.Silence;
|
|
var (remaining, reason) = PlayerPenaltyManager.GetPenaltyDetails(player.Slot, type, endDateTime);
|
|
var kind = type == PenaltyType.Gag ? "gag" : "silence";
|
|
using (new WithTemporaryCulture(player.GetLanguage()))
|
|
{
|
|
if (string.IsNullOrWhiteSpace(reason))
|
|
reason = _localizer!["sa_player_penalty_no_reason"];
|
|
if (remaining is null)
|
|
player.SendLocalizedMessage(_localizer, $"sa_player_penalty_{kind}_active_perm", reason);
|
|
else
|
|
player.SendLocalizedMessage(_localizer, $"sa_player_penalty_{kind}_active", Helper.FormatRemaining(remaining.Value), reason);
|
|
}
|
|
}
|
|
|
|
/*public HookResult OnCommandSay(CCSPlayerController? player, CommandInfo info)
|
|
{
|
|
if (player == null || !player.IsValid || player.IsBot)
|
|
return HookResult.Continue;
|
|
|
|
if (info.GetArg(1).StartsWith($"/")
|
|
|| info.GetArg(1).StartsWith($"!"))
|
|
return HookResult.Continue;
|
|
|
|
if (info.GetArg(1).Length == 0)
|
|
return HookResult.Handled;
|
|
|
|
if (PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Gag) || PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence))
|
|
return HookResult.Handled;
|
|
|
|
return HookResult.Continue;
|
|
}*/
|
|
|
|
public HookResult OnCommandTeamSay(CCSPlayerController? player, CommandInfo info)
|
|
{
|
|
if (player == null || !player.IsValid || player.IsBot)
|
|
return HookResult.Continue;
|
|
|
|
if (info.GetArg(1).StartsWith($"/")
|
|
|| info.GetArg(1).StartsWith($"!"))
|
|
return HookResult.Continue;
|
|
|
|
if (info.GetArg(1).Length == 0)
|
|
return HookResult.Handled;
|
|
|
|
if (PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Gag, out _) || PlayerPenaltyManager.IsPenalized(player.Slot, PenaltyType.Silence, out _))
|
|
return HookResult.Stop;
|
|
|
|
if (!info.GetArg(1).StartsWith($"@")) return HookResult.Continue;
|
|
|
|
StringBuilder sb = new();
|
|
|
|
if (AdminManager.PlayerHasPermissions(new SteamID(player.SteamID), "@css/chat"))
|
|
{
|
|
sb.Append(_localizer!["sa_adminchat_template_admin", player.PlayerName, info.GetArg(1).Remove(0, 1)]);
|
|
foreach (var p in Utilities.GetPlayers().Where(p => p.IsValid && p is { IsBot: false, IsHLTV: false } && AdminManager.PlayerHasPermissions(new SteamID(p.SteamID), "@css/chat")))
|
|
{
|
|
p.PrintToChat(sb.ToString());
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sb.Append(_localizer!["sa_adminchat_template_player", player.PlayerName, info.GetArg(1).Remove(0, 1)]);
|
|
player.PrintToChat(sb.ToString());
|
|
foreach (var p in Utilities.GetPlayers().Where(p => p is { IsValid: true, IsBot: false, IsHLTV: false } && AdminManager.PlayerHasPermissions(new SteamID(p.SteamID), "@css/chat")))
|
|
{
|
|
p.PrintToChat(sb.ToString());
|
|
}
|
|
}
|
|
|
|
return HookResult.Handled;
|
|
}
|
|
|
|
private void OnMapStart(string mapName)
|
|
{
|
|
if (Config.OtherSettings.ReloadAdminsEveryMapChange && ServerLoaded && ServerId != null)
|
|
ReloadAdmins(null);
|
|
|
|
AddTimer(1.0f, ServerManager.CheckHibernationStatus);
|
|
|
|
if (!ServerLoaded || ServerId == null)
|
|
AddTimer(1.5f, OnGameServerSteamAPIActivated);
|
|
|
|
// AddTimer(34, () =>
|
|
// {
|
|
// if (!ServerLoaded)
|
|
// OnGameServerSteamAPIActivated();
|
|
// });
|
|
|
|
SilentPlayers.Clear();
|
|
|
|
PlayerPenaltyManager.RemoveAllPenalties();
|
|
}
|
|
|
|
[GameEventHandler]
|
|
public HookResult OnPlayerDeath(EventPlayerDeath @event, GameEventInfo info)
|
|
{
|
|
var player = @event.Userid;
|
|
|
|
if (player?.UserId == null || !player.IsValid || player.IsHLTV ||
|
|
player.Connected != PlayerConnectedState.Connected || !PlayersInfo.ContainsKey(player.SteamID) ||
|
|
@event.Attacker == null)
|
|
return HookResult.Continue;
|
|
|
|
var playerPosition = player.PlayerPawn.Value?.AbsOrigin;
|
|
var playerRotation = player.PlayerPawn.Value?.AbsRotation;
|
|
PlayersInfo[player.SteamID].DiePosition = new DiePosition(
|
|
new Vector3(
|
|
playerPosition?.X ?? 0,
|
|
playerPosition?.Y ?? 0,
|
|
playerPosition?.Z ?? 0
|
|
),
|
|
new Vector3(
|
|
playerRotation?.X ?? 0,
|
|
playerRotation?.Y ?? 0,
|
|
playerRotation?.Z ?? 0
|
|
)
|
|
);
|
|
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
[GameEventHandler(HookMode.Pre)]
|
|
public HookResult OnPlayerTeam(EventPlayerTeam @event, GameEventInfo info)
|
|
{
|
|
var player = @event.Userid;
|
|
if (player == null || !player.IsValid || player.IsBot || !SilentPlayers.Contains(player.Slot))
|
|
return HookResult.Continue;
|
|
|
|
// zio: only joining T or CT unhides. Moving to spectators doesn't, so a plugin can take a
|
|
// hidden admin there (e.g. to close the team select screen) and keep them hidden.
|
|
if (@event is not { Oldteam: <= 1, Team: >= 2 }) return HookResult.Continue;
|
|
|
|
SilentPlayers.Remove(player.Slot);
|
|
SimpleAdminApi?.OnAdminToggleSilentEvent(player.Slot, false);
|
|
|
|
return HookResult.Continue;
|
|
}
|
|
|
|
[GameEventHandler]
|
|
public HookResult OnPlayerInfo(EventPlayerInfo @event, GameEventInfo _)
|
|
{
|
|
var player = @event.Userid;
|
|
|
|
if (player is null || !player.IsValid || player.IsBot)
|
|
return HookResult.Continue;
|
|
|
|
if (!RenamedPlayers.TryGetValue(player.SteamID, out var name)) return HookResult.Continue;
|
|
|
|
if (player.PlayerName.Equals(name))
|
|
return HookResult.Continue;
|
|
|
|
player.Rename(name);
|
|
|
|
return HookResult.Continue;
|
|
}
|
|
} |