mirror of
https://github.com/daffyyyy/CS2-SimpleAdmin.git
synced 2026-09-27 20:17:04 +02:00
upstream ~ v1.7.7-alpha
This commit is contained in:
commit
c586dd700c
43 changed files with 928 additions and 337 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -4,5 +4,6 @@ obj/
|
||||||
.git
|
.git
|
||||||
.vscode/
|
.vscode/
|
||||||
.idea/
|
.idea/
|
||||||
|
Modules/CS2-SimpleAdmin_PlayTimeModule
|
||||||
CS2-SimpleAdmin.sln.DotSettings.user
|
CS2-SimpleAdmin.sln.DotSettings.user
|
||||||
Modules/CS2-SimpleAdmin_ExampleModule/CS2-SimpleAdmin_ExampleModule.sln.DotSettings.user
|
Modules/CS2-SimpleAdmin_ExampleModule/CS2-SimpleAdmin_ExampleModule.sln.DotSettings.user
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
|
||||||
public override string ModuleName => "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)");
|
public override string ModuleName => "CS2-SimpleAdmin" + (Helper.IsDebugBuild ? " (DEBUG)" : " (RELEASE)");
|
||||||
public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)";
|
public override string ModuleDescription => "Simple admin plugin for Counter-Strike 2 :)";
|
||||||
public override string ModuleAuthor => "daffyy & Dliix66";
|
public override string ModuleAuthor => "daffyy & Dliix66";
|
||||||
public override string ModuleVersion => "1.7.5a";
|
public override string ModuleVersion => "1.7.7-alpha";
|
||||||
|
|
||||||
public override void Load(bool hotReload)
|
public override void Load(bool hotReload)
|
||||||
{
|
{
|
||||||
|
|
@ -31,6 +31,8 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
|
||||||
{
|
{
|
||||||
ServerLoaded = false;
|
ServerLoaded = false;
|
||||||
_serverLoading = false;
|
_serverLoading = false;
|
||||||
|
|
||||||
|
CacheManager = new CacheManager();
|
||||||
OnGameServerSteamAPIActivated();
|
OnGameServerSteamAPIActivated();
|
||||||
OnMapStart(string.Empty);
|
OnMapStart(string.Empty);
|
||||||
|
|
||||||
|
|
@ -40,10 +42,10 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
|
||||||
|
|
||||||
var playerManager = new PlayerManager();
|
var playerManager = new PlayerManager();
|
||||||
|
|
||||||
Helper.GetValidPlayers().ForEach(player =>
|
foreach (var player in Helper.GetValidPlayers())
|
||||||
{
|
{
|
||||||
playerManager.LoadPlayerData(player);
|
playerManager.LoadPlayerData(player);
|
||||||
});
|
};
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_cBasePlayerControllerSetPawnFunc = new MemoryFunctionVoid<CBasePlayerController, CCSPlayerPawn, bool, bool>(GameData.GetSignature("CBasePlayerController_SetPawn"));
|
_cBasePlayerControllerSetPawnFunc = new MemoryFunctionVoid<CBasePlayerController, CCSPlayerPawn, bool, bool>(GameData.GetSignature("CBasePlayerController_SetPawn"));
|
||||||
|
|
@ -58,7 +60,7 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
|
||||||
|
|
||||||
public override void OnAllPluginsLoaded(bool hotReload)
|
public override void OnAllPluginsLoaded(bool hotReload)
|
||||||
{
|
{
|
||||||
AddTimer(3.0f, () => ReloadAdmins(null));
|
AddTimer(5.0f, () => ReloadAdmins(null));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
@ -151,4 +153,10 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
|
||||||
command.ReplyToCommand($"Multiple targets found for \"{command.GetArg(1)}\".");
|
command.ReplyToCommand($"Multiple targets found for \"{command.GetArg(1)}\".");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void Unload(bool hotReload)
|
||||||
|
{
|
||||||
|
CacheManager?.Dispose();
|
||||||
|
CacheManager = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -10,10 +10,11 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.305" />
|
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.318" />
|
||||||
<PackageReference Include="Dapper" Version="2.1.66" />
|
<PackageReference Include="Dapper" Version="2.1.66" />
|
||||||
<PackageReference Include="MySqlConnector" Version="2.4.0" />
|
<PackageReference Include="MySqlConnector" Version="2.4.0" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="*" />
|
<PackageReference Include="Newtonsoft.Json" Version="*" />
|
||||||
|
<PackageReference Include="ZLinq" Version="1.4.6" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
@ -25,6 +26,12 @@
|
||||||
<None Update="Database\Migrations\010_CreateWarnsTable.sql">
|
<None Update="Database\Migrations\010_CreateWarnsTable.sql">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
<None Update="Database\Migrations\012_AddUpdatedAtColumnToSaBansTable.sql">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Database\Migrations\013_AddNameColumnToSaPlayerIpsTable.sql">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,7 @@ public static class RegisterCommands
|
||||||
new CommandMapping("css_addgroup", CS2_SimpleAdmin.Instance.OnAddGroup),
|
new CommandMapping("css_addgroup", CS2_SimpleAdmin.Instance.OnAddGroup),
|
||||||
new CommandMapping("css_delgroup", CS2_SimpleAdmin.Instance.OnDelGroupCommand),
|
new CommandMapping("css_delgroup", CS2_SimpleAdmin.Instance.OnDelGroupCommand),
|
||||||
new CommandMapping("css_reloadadmins", CS2_SimpleAdmin.Instance.OnRelAdminCommand),
|
new CommandMapping("css_reloadadmins", CS2_SimpleAdmin.Instance.OnRelAdminCommand),
|
||||||
|
new CommandMapping("css_reloadbans", CS2_SimpleAdmin.Instance.OnRelBans),
|
||||||
new CommandMapping("css_hide", CS2_SimpleAdmin.Instance.OnHideCommand),
|
new CommandMapping("css_hide", CS2_SimpleAdmin.Instance.OnHideCommand),
|
||||||
new CommandMapping("css_hidecomms", CS2_SimpleAdmin.Instance.OnHideCommsCommand),
|
new CommandMapping("css_hidecomms", CS2_SimpleAdmin.Instance.OnHideCommsCommand),
|
||||||
new CommandMapping("css_who", CS2_SimpleAdmin.Instance.OnWhoCommand),
|
new CommandMapping("css_who", CS2_SimpleAdmin.Instance.OnWhoCommand),
|
||||||
|
|
@ -122,6 +123,7 @@ public static class RegisterCommands
|
||||||
{ "css_addgroup", new Command { Aliases = ["css_addgroup"] } },
|
{ "css_addgroup", new Command { Aliases = ["css_addgroup"] } },
|
||||||
{ "css_delgroup", new Command { Aliases = ["css_delgroup"] } },
|
{ "css_delgroup", new Command { Aliases = ["css_delgroup"] } },
|
||||||
{ "css_reloadadmins", new Command { Aliases = ["css_reloadadmins"] } },
|
{ "css_reloadadmins", new Command { Aliases = ["css_reloadadmins"] } },
|
||||||
|
{ "css_reloadbans", new Command { Aliases = ["css_reloadbans"] } },
|
||||||
{ "css_hide", new Command { Aliases = ["css_hide", "css_stealth"] } },
|
{ "css_hide", new Command { Aliases = ["css_hide", "css_stealth"] } },
|
||||||
{ "css_hidecomms", new Command { Aliases = ["css_hidecomms"] } },
|
{ "css_hidecomms", new Command { Aliases = ["css_hidecomms"] } },
|
||||||
{ "css_who", new Command { Aliases = ["css_who"] } },
|
{ "css_who", new Command { Aliases = ["css_who"] } },
|
||||||
|
|
|
||||||
|
|
@ -73,12 +73,6 @@ public partial class CS2_SimpleAdmin
|
||||||
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Ban, reason, time, penaltyId);
|
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Ban, reason, time, penaltyId);
|
||||||
});
|
});
|
||||||
|
|
||||||
// Update banned players list
|
|
||||||
if (playerInfo.IpAddress != null && !BannedPlayers.Contains(playerInfo.IpAddress))
|
|
||||||
BannedPlayers.Add(playerInfo.IpAddress);
|
|
||||||
if (!BannedPlayers.Contains(player.SteamID.ToString()))
|
|
||||||
BannedPlayers.Add(player.SteamID.ToString());
|
|
||||||
|
|
||||||
// Determine message keys and arguments based on ban time
|
// Determine message keys and arguments based on ban time
|
||||||
var (messageKey, activityMessageKey, centerArgs, adminActivityArgs) = time == 0
|
var (messageKey, activityMessageKey, centerArgs, adminActivityArgs) = time == 0
|
||||||
? ("sa_player_ban_message_perm", "sa_admin_ban_message_perm",
|
? ("sa_player_ban_message_perm", "sa_admin_ban_message_perm",
|
||||||
|
|
@ -129,8 +123,7 @@ public partial class CS2_SimpleAdmin
|
||||||
|
|
||||||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
||||||
|
|
||||||
var matches = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString());
|
var player = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString());
|
||||||
var player = matches.Count == 1 ? matches.FirstOrDefault() : null;
|
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
{
|
{
|
||||||
|
|
@ -184,8 +177,7 @@ public partial class CS2_SimpleAdmin
|
||||||
? PlayersInfo[caller.UserId.Value]
|
? PlayersInfo[caller.UserId.Value]
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
var matches = Helper.GetPlayerFromSteamid64(steamid);
|
var player = Helper.GetPlayerFromSteamid64(steamid);
|
||||||
var player = matches.Count == 1 ? matches.FirstOrDefault() : null;
|
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
{
|
{
|
||||||
|
|
@ -247,8 +239,7 @@ public partial class CS2_SimpleAdmin
|
||||||
? PlayersInfo[caller.UserId.Value]
|
? PlayersInfo[caller.UserId.Value]
|
||||||
: null;
|
: null;
|
||||||
|
|
||||||
var matches = Helper.GetPlayerFromIp(ipAddress);
|
var player = Helper.GetPlayerFromIp(ipAddress);
|
||||||
var player = matches.Count == 1 ? matches.FirstOrDefault() : null;
|
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
{
|
{
|
||||||
|
|
@ -366,10 +357,10 @@ public partial class CS2_SimpleAdmin
|
||||||
: (_localizer?["sa_console"] ?? "Console");
|
: (_localizer?["sa_console"] ?? "Console");
|
||||||
|
|
||||||
// Freeze player pawn if alive
|
// Freeze player pawn if alive
|
||||||
if (player.PawnIsAlive)
|
if (player.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE)
|
||||||
{
|
{
|
||||||
player.Pawn.Value?.Freeze();
|
player.PlayerPawn?.Value?.Freeze();
|
||||||
AddTimer(5.0f, () => player.Pawn.Value?.Unfreeze(), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
AddTimer(5.0f, () => player.PlayerPawn?.Value?.Unfreeze(), CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get player and admin information
|
// Get player and admin information
|
||||||
|
|
@ -442,8 +433,7 @@ public partial class CS2_SimpleAdmin
|
||||||
|
|
||||||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
||||||
|
|
||||||
var matches = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString());
|
var player = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString());
|
||||||
var player = matches.Count == 1 ? matches.FirstOrDefault() : null;
|
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,6 @@ public partial class CS2_SimpleAdmin
|
||||||
var utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
var utf8String = Encoding.UTF8.GetString(utf8BytesString);
|
||||||
|
|
||||||
Helper.LogCommand(caller, command);
|
Helper.LogCommand(caller, command);
|
||||||
|
|
||||||
Helper.PrintToCenterAll(utf8String.ReplaceColorTags());
|
Helper.PrintToCenterAll(utf8String.ReplaceColorTags());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -387,19 +387,20 @@ public partial class CS2_SimpleAdmin
|
||||||
command.ReplyToCommand("Reloaded sql admins and groups");
|
command.ReplyToCommand("Reloaded sql admins and groups");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ReloadAdmins(CCSPlayerController? caller)
|
[CommandHelper(whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||||
|
[RequiresPermissions("@css/root")]
|
||||||
|
public void OnRelBans(CCSPlayerController? caller, CommandInfo command)
|
||||||
{
|
{
|
||||||
if (Database == null) return;
|
if (Database == null) return;
|
||||||
|
|
||||||
for (var index = 0; index < PermissionManager.AdminCache.Keys.ToList().Count; index++)
|
_ = Instance.CacheManager?.ForceReInitializeCacheAsync();
|
||||||
{
|
command.ReplyToCommand("Reloaded bans");
|
||||||
var steamId = PermissionManager.AdminCache.Keys.ToList()[index];
|
|
||||||
if (!PermissionManager.AdminCache.TryRemove(steamId, out _)) continue;
|
|
||||||
|
|
||||||
AdminManager.ClearPlayerPermissions(steamId);
|
|
||||||
AdminManager.RemovePlayerAdminData(steamId);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ReloadAdmins(CCSPlayerController? caller)
|
||||||
|
{
|
||||||
|
if (Database == null) return;
|
||||||
|
|
||||||
if(!Config.IsCSSPanel)
|
if(!Config.IsCSSPanel)
|
||||||
{
|
{
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
|
|
@ -413,11 +414,11 @@ public partial class CS2_SimpleAdmin
|
||||||
await Server.NextWorldUpdateAsync(() =>
|
await Server.NextWorldUpdateAsync(() =>
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(adminsFile))
|
if (!string.IsNullOrEmpty(adminsFile))
|
||||||
AddTimer(1.8f, () => AdminManager.LoadAdminData(ModuleDirectory + "/data/admins.json"));
|
AddTimer(1.3f, () => AdminManager.LoadAdminData(ModuleDirectory + "/data/admins.json"));
|
||||||
if (!string.IsNullOrEmpty(groupsFile))
|
if (!string.IsNullOrEmpty(groupsFile))
|
||||||
AddTimer(2.5f, () => AdminManager.LoadAdminGroups(ModuleDirectory + "/data/groups.json"));
|
AddTimer(2.5f, () => AdminManager.LoadAdminGroups(ModuleDirectory + "/data/groups.json"));
|
||||||
if (!string.IsNullOrEmpty(adminsFile))
|
if (!string.IsNullOrEmpty(adminsFile))
|
||||||
AddTimer(3.0f, () => AdminManager.LoadAdminData(ModuleDirectory + "/data/admins.json"));
|
AddTimer(3.5f, () => AdminManager.LoadAdminData(ModuleDirectory + "/data/admins.json"));
|
||||||
|
|
||||||
_logger?.LogInformation("Loaded admins!");
|
_logger?.LogInformation("Loaded admins!");
|
||||||
});
|
});
|
||||||
|
|
@ -445,8 +446,8 @@ public partial class CS2_SimpleAdmin
|
||||||
{
|
{
|
||||||
Server.ExecuteCommand("sv_disable_teamselect_menu 1");
|
Server.ExecuteCommand("sv_disable_teamselect_menu 1");
|
||||||
|
|
||||||
if (caller.PlayerPawn.Value != null && caller.PawnIsAlive)
|
if (caller.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE)
|
||||||
caller.PlayerPawn.Value.CommitSuicide(true, false);
|
caller.PlayerPawn.Value?.CommitSuicide(true, false);
|
||||||
|
|
||||||
AddTimer(1.0f, () => { Server.NextFrame(() => caller.ChangeTeam(CsTeam.Spectator)); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
AddTimer(1.0f, () => { Server.NextFrame(() => caller.ChangeTeam(CsTeam.Spectator)); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||||
AddTimer(1.4f, () => { Server.NextFrame(() => caller.ChangeTeam(CsTeam.None)); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
AddTimer(1.4f, () => { Server.NextFrame(() => caller.ChangeTeam(CsTeam.None)); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
|
||||||
|
|
@ -520,6 +521,10 @@ public partial class CS2_SimpleAdmin
|
||||||
printMethod($"• Total Mutes: \"{playerInfo.TotalMutes}\"");
|
printMethod($"• Total Mutes: \"{playerInfo.TotalMutes}\"");
|
||||||
printMethod($"• Total Silences: \"{playerInfo.TotalSilences}\"");
|
printMethod($"• Total Silences: \"{playerInfo.TotalSilences}\"");
|
||||||
printMethod($"• Total Warns: \"{playerInfo.TotalWarns}\"");
|
printMethod($"• Total Warns: \"{playerInfo.TotalWarns}\"");
|
||||||
|
|
||||||
|
var chunkedAccounts = playerInfo.AccountsAssociated.ChunkBy(3).ToList();
|
||||||
|
foreach (var chunk in chunkedAccounts)
|
||||||
|
printMethod($"• Associated Accounts: \"{string.Join(", ", chunk.Select(a => $"{a.PlayerName} ({a.SteamId})"))}\"");
|
||||||
}
|
}
|
||||||
|
|
||||||
printMethod($"--------- END INFO ABOUT \"{player.PlayerName}\" ---------");
|
printMethod($"--------- END INFO ABOUT \"{player.PlayerName}\" ---------");
|
||||||
|
|
@ -661,7 +666,6 @@ public partial class CS2_SimpleAdmin
|
||||||
Helper.LogCommand(caller, command);
|
Helper.LogCommand(caller, command);
|
||||||
|
|
||||||
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsBot: false }).ToList();
|
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsBot: false }).ToList();
|
||||||
|
|
||||||
if (playersToTarget.Count > 1)
|
if (playersToTarget.Count > 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -719,20 +723,20 @@ public partial class CS2_SimpleAdmin
|
||||||
if (caller != null)
|
if (caller != null)
|
||||||
{
|
{
|
||||||
caller.PrintToConsole("--------- PLAYER LIST ---------");
|
caller.PrintToConsole("--------- PLAYER LIST ---------");
|
||||||
playersToTarget.ForEach(player =>
|
foreach (var player in playersToTarget)
|
||||||
{
|
{
|
||||||
caller.PrintToConsole(
|
caller.PrintToConsole(
|
||||||
$"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{(AdminManager.PlayerHasPermissions(new SteamID(caller.SteamID), "@css/showip") ? player.IpAddress?.Split(":")[0] : "Unknown")}\" SteamID64: \"{player.SteamID}\")");
|
$"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{(AdminManager.PlayerHasPermissions(new SteamID(caller.SteamID), "@css/showip") ? player.IpAddress?.Split(":")[0] : "Unknown")}\" SteamID64: \"{player.SteamID}\")");
|
||||||
});
|
};
|
||||||
caller.PrintToConsole("--------- END PLAYER LIST ---------");
|
caller.PrintToConsole("--------- END PLAYER LIST ---------");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Server.PrintToConsole("--------- PLAYER LIST ---------");
|
Server.PrintToConsole("--------- PLAYER LIST ---------");
|
||||||
playersToTarget.ForEach(player =>
|
foreach (var player in playersToTarget)
|
||||||
{
|
{
|
||||||
Server.PrintToConsole($"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.SteamID}\")");
|
Server.PrintToConsole($"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.SteamID}\")");
|
||||||
});
|
};
|
||||||
Server.PrintToConsole("--------- END PLAYER LIST ---------");
|
Server.PrintToConsole("--------- END PLAYER LIST ---------");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -800,6 +804,8 @@ public partial class CS2_SimpleAdmin
|
||||||
Kick(caller, player, reason, callerName, command);
|
Kick(caller, player, reason, callerName, command);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Kick(CCSPlayerController? caller, CCSPlayerController player, string? reason = "Unknown", string? callerName = null, CommandInfo? command = null)
|
public void Kick(CCSPlayerController? caller, CCSPlayerController player, string? reason = "Unknown", string? callerName = null, CommandInfo? command = null)
|
||||||
|
|
@ -839,8 +845,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command and send Discord notification
|
// Log the command and send Discord notification
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_kick {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {reason}");
|
Helper.LogCommand(caller, $"css_kick {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {reason}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
|
|
||||||
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Kick, reason, -1, null);
|
SimpleAdminApi?.OnPlayerPenaltiedEvent(playerInfo, adminInfo, PenaltyType.Kick, reason, -1, null);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -114,8 +114,7 @@ public partial class CS2_SimpleAdmin
|
||||||
|
|
||||||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
||||||
|
|
||||||
var matches = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString());
|
var player = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString());
|
||||||
var player = matches.Count == 1 ? matches.FirstOrDefault() : null;
|
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
{
|
{
|
||||||
|
|
@ -173,8 +172,7 @@ public partial class CS2_SimpleAdmin
|
||||||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
||||||
|
|
||||||
// Attempt to match player based on SteamID
|
// Attempt to match player based on SteamID
|
||||||
var matches = Helper.GetPlayerFromSteamid64(steamid);
|
var player = Helper.GetPlayerFromSteamid64(steamid);
|
||||||
var player = matches.Count == 1 ? matches.FirstOrDefault() : null;
|
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
{
|
{
|
||||||
|
|
@ -230,8 +228,7 @@ public partial class CS2_SimpleAdmin
|
||||||
// Check if pattern is a valid SteamID64
|
// Check if pattern is a valid SteamID64
|
||||||
if (Helper.ValidateSteamId(pattern, out var steamId) && steamId != null)
|
if (Helper.ValidateSteamId(pattern, out var steamId) && steamId != null)
|
||||||
{
|
{
|
||||||
var matches = Helper.GetPlayerFromSteamid64(steamId.SteamId64.ToString());
|
var player = Helper.GetPlayerFromSteamid64(steamId.SteamId64.ToString());
|
||||||
var player = matches.Count == 1 ? matches.FirstOrDefault() : null;
|
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
{
|
{
|
||||||
|
|
@ -407,8 +404,7 @@ public partial class CS2_SimpleAdmin
|
||||||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
||||||
|
|
||||||
// Attempt to match player based on SteamID
|
// Attempt to match player based on SteamID
|
||||||
var matches = Helper.GetPlayerFromSteamid64(steamid);
|
var player = Helper.GetPlayerFromSteamid64(steamid);
|
||||||
var player = matches.Count == 1 ? matches.FirstOrDefault() : null;
|
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
{
|
{
|
||||||
|
|
@ -448,8 +444,7 @@ public partial class CS2_SimpleAdmin
|
||||||
|
|
||||||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
||||||
|
|
||||||
var matches = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString());
|
var player = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString());
|
||||||
var player = matches.Count == 1 ? matches.FirstOrDefault() : null;
|
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
{
|
{
|
||||||
|
|
@ -499,8 +494,7 @@ public partial class CS2_SimpleAdmin
|
||||||
// Check if pattern is a valid SteamID64
|
// Check if pattern is a valid SteamID64
|
||||||
if (Helper.ValidateSteamId(pattern, out var steamId) && steamId != null)
|
if (Helper.ValidateSteamId(pattern, out var steamId) && steamId != null)
|
||||||
{
|
{
|
||||||
var matches = Helper.GetPlayerFromSteamid64(steamId.SteamId64.ToString());
|
var player = Helper.GetPlayerFromSteamid64(steamId.SteamId64.ToString());
|
||||||
var player = matches.Count == 1 ? matches.FirstOrDefault() : null;
|
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
{
|
{
|
||||||
|
|
@ -681,8 +675,7 @@ public partial class CS2_SimpleAdmin
|
||||||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
||||||
|
|
||||||
// Attempt to match player based on SteamID
|
// Attempt to match player based on SteamID
|
||||||
var matches = Helper.GetPlayerFromSteamid64(steamid);
|
var player = Helper.GetPlayerFromSteamid64(steamid);
|
||||||
var player = matches.Count == 1 ? matches.FirstOrDefault() : null;
|
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
{
|
{
|
||||||
|
|
@ -722,8 +715,7 @@ public partial class CS2_SimpleAdmin
|
||||||
|
|
||||||
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
var adminInfo = caller != null && caller.UserId.HasValue ? PlayersInfo[caller.UserId.Value] : null;
|
||||||
|
|
||||||
var matches = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString());
|
var player = Helper.GetPlayerFromSteamid64(steamid.SteamId64.ToString());
|
||||||
var player = matches.Count == 1 ? matches.FirstOrDefault() : null;
|
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
{
|
{
|
||||||
|
|
@ -773,8 +765,7 @@ public partial class CS2_SimpleAdmin
|
||||||
// Check if pattern is a valid SteamID64
|
// Check if pattern is a valid SteamID64
|
||||||
if (Helper.ValidateSteamId(pattern, out var steamId) && steamId != null)
|
if (Helper.ValidateSteamId(pattern, out var steamId) && steamId != null)
|
||||||
{
|
{
|
||||||
var matches = Helper.GetPlayerFromSteamid64(steamId.SteamId64.ToString());
|
var player = Helper.GetPlayerFromSteamid64(steamId.SteamId64.ToString());
|
||||||
var player = matches.Count == 1 ? matches.FirstOrDefault() : null;
|
|
||||||
|
|
||||||
if (player != null && player.IsValid)
|
if (player != null && player.IsValid)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ public partial class CS2_SimpleAdmin
|
||||||
if (targets == null) return;
|
if (targets == null) return;
|
||||||
var playersToTarget = targets.Players.Where(player =>
|
var playersToTarget = targets.Players.Where(player =>
|
||||||
player.IsValid &&
|
player.IsValid &&
|
||||||
player is { PawnIsAlive: true, IsHLTV: false, Connected: PlayerConnectedState.PlayerConnected }).ToList();
|
player is { IsHLTV: false, Connected: PlayerConnectedState.PlayerConnected, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||||
|
|
||||||
playersToTarget.ForEach(player =>
|
playersToTarget.ForEach(player =>
|
||||||
{
|
{
|
||||||
|
|
@ -27,6 +27,8 @@ public partial class CS2_SimpleAdmin
|
||||||
NoClip(caller, player, callerName);
|
NoClip(caller, player, callerName);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void NoClip(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null)
|
internal static void NoClip(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null)
|
||||||
|
|
@ -53,14 +55,8 @@ public partial class CS2_SimpleAdmin
|
||||||
|
|
||||||
// Log the command
|
// Log the command
|
||||||
if (command == null)
|
if (command == null)
|
||||||
{
|
|
||||||
Helper.LogCommand(caller, $"css_noclip {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
Helper.LogCommand(caller, $"css_noclip {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[RequiresPermissions("@css/cheats")]
|
[RequiresPermissions("@css/cheats")]
|
||||||
[CommandHelper(minArgs: 1, usage: "<#userid or name>", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
[CommandHelper(minArgs: 1, usage: "<#userid or name>", whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
|
||||||
|
|
@ -70,7 +66,7 @@ public partial class CS2_SimpleAdmin
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
if (targets == null) return;
|
if (targets == null) return;
|
||||||
|
|
||||||
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { PawnIsAlive: true, IsHLTV: false }).ToList();
|
var playersToTarget = targets.Players.Where(player => player.IsValid && player is {IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||||
|
|
||||||
playersToTarget.ForEach(player =>
|
playersToTarget.ForEach(player =>
|
||||||
{
|
{
|
||||||
|
|
@ -82,6 +78,8 @@ public partial class CS2_SimpleAdmin
|
||||||
God(caller, player, command);
|
God(caller, player, command);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void God(CCSPlayerController? caller, CCSPlayerController player, CommandInfo? command = null)
|
internal static void God(CCSPlayerController? caller, CCSPlayerController player, CommandInfo? command = null)
|
||||||
|
|
@ -100,8 +98,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command
|
// Log the command
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_god {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
Helper.LogCommand(caller, $"css_god {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
|
|
||||||
// Determine message key and arguments for the god mode notification
|
// Determine message key and arguments for the god mode notification
|
||||||
var (activityMessageKey, adminActivityArgs) =
|
var (activityMessageKey, adminActivityArgs) =
|
||||||
|
|
@ -124,7 +120,7 @@ public partial class CS2_SimpleAdmin
|
||||||
|
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
if (targets == null) return;
|
if (targets == null) return;
|
||||||
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, PawnIsAlive: true, IsHLTV: false }).ToList();
|
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||||
|
|
||||||
playersToTarget.ForEach(player =>
|
playersToTarget.ForEach(player =>
|
||||||
{
|
{
|
||||||
|
|
@ -133,6 +129,8 @@ public partial class CS2_SimpleAdmin
|
||||||
Freeze(caller, player, time, callerName, command);
|
Freeze(caller, player, time, callerName, command);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
[CommandHelper(1, "<#userid or name> [size]")]
|
[CommandHelper(1, "<#userid or name> [size]")]
|
||||||
|
|
@ -144,7 +142,7 @@ public partial class CS2_SimpleAdmin
|
||||||
|
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
if (targets == null) return;
|
if (targets == null) return;
|
||||||
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, PawnIsAlive: true, IsHLTV: false }).ToList();
|
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||||
|
|
||||||
playersToTarget.ForEach(player =>
|
playersToTarget.ForEach(player =>
|
||||||
{
|
{
|
||||||
|
|
@ -206,8 +204,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command and send Discord notification
|
// Log the command and send Discord notification
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_freeze {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {time}");
|
Helper.LogCommand(caller, $"css_freeze {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {time}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[CommandHelper(1, "<#userid or name>")]
|
[CommandHelper(1, "<#userid or name>")]
|
||||||
|
|
@ -218,12 +214,14 @@ public partial class CS2_SimpleAdmin
|
||||||
|
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
if (targets == null) return;
|
if (targets == null) return;
|
||||||
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, PawnIsAlive: true, IsHLTV: false }).ToList();
|
var playersToTarget = targets.Players.Where(player => player is { IsValid: true, IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||||
|
|
||||||
playersToTarget.ForEach(player =>
|
playersToTarget.ForEach(player =>
|
||||||
{
|
{
|
||||||
Unfreeze(caller, player, callerName, command);
|
Unfreeze(caller, player, callerName, command);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Unfreeze(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null)
|
internal static void Unfreeze(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null)
|
||||||
|
|
@ -251,7 +249,5 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command and send Discord notification
|
// Log the command and send Discord notification
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_unfreeze {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
Helper.LogCommand(caller, $"css_unfreeze {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -22,12 +22,14 @@ public partial class CS2_SimpleAdmin
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
if (targets == null) return;
|
if (targets == null) return;
|
||||||
|
|
||||||
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { PawnIsAlive: true, IsHLTV: false }).ToList();
|
var playersToTarget = targets.Players.Where(player => player.IsValid && player is {IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||||
|
|
||||||
playersToTarget.ForEach(player =>
|
playersToTarget.ForEach(player =>
|
||||||
{
|
{
|
||||||
Slay(caller, player, callerName, command);
|
Slay(caller, player, callerName, command);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Slay(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null)
|
internal static void Slay(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null)
|
||||||
|
|
@ -55,8 +57,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command and send Discord notification
|
// Log the command and send Discord notification
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_slay {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
Helper.LogCommand(caller, $"css_slay {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[RequiresPermissions("@css/cheats")]
|
[RequiresPermissions("@css/cheats")]
|
||||||
|
|
@ -67,7 +67,7 @@ public partial class CS2_SimpleAdmin
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
if (targets == null) return;
|
if (targets == null) return;
|
||||||
|
|
||||||
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { PawnIsAlive: true, IsHLTV: false }).ToList();
|
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||||
var weaponName = command.GetArg(2);
|
var weaponName = command.GetArg(2);
|
||||||
|
|
||||||
// check if item is typed
|
// check if item is typed
|
||||||
|
|
@ -94,6 +94,8 @@ public partial class CS2_SimpleAdmin
|
||||||
|
|
||||||
GiveWeapon(caller, player, weaponName, callerName, command);
|
GiveWeapon(caller, player, weaponName, callerName, command);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void GiveWeapon(CCSPlayerController? caller, CCSPlayerController player, string weaponName, string? callerName = null, CommandInfo? command = null)
|
private static void GiveWeapon(CCSPlayerController? caller, CCSPlayerController player, string weaponName, string? callerName = null, CommandInfo? command = null)
|
||||||
|
|
@ -122,8 +124,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command
|
// Log the command
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_giveweapon {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {weaponName}");
|
Helper.LogCommand(caller, $"css_giveweapon {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {weaponName}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
|
|
||||||
// Determine message keys and arguments for the weapon give notification
|
// Determine message keys and arguments for the weapon give notification
|
||||||
var (activityMessageKey, adminActivityArgs) =
|
var (activityMessageKey, adminActivityArgs) =
|
||||||
|
|
@ -150,8 +150,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command
|
// Log the command
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_giveweapon {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {weapon.ToString()}");
|
Helper.LogCommand(caller, $"css_giveweapon {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {weapon.ToString()}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
|
|
||||||
// Determine message keys and arguments for the weapon give notification
|
// Determine message keys and arguments for the weapon give notification
|
||||||
var (activityMessageKey, adminActivityArgs) =
|
var (activityMessageKey, adminActivityArgs) =
|
||||||
|
|
@ -173,7 +171,7 @@ public partial class CS2_SimpleAdmin
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
if (targets == null) return;
|
if (targets == null) return;
|
||||||
|
|
||||||
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { PawnIsAlive: true, IsHLTV: false }).ToList();
|
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||||
|
|
||||||
playersToTarget.ForEach(player =>
|
playersToTarget.ForEach(player =>
|
||||||
{
|
{
|
||||||
|
|
@ -182,6 +180,8 @@ public partial class CS2_SimpleAdmin
|
||||||
StripWeapons(caller, player, callerName, command);
|
StripWeapons(caller, player, callerName, command);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void StripWeapons(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null)
|
internal static void StripWeapons(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null)
|
||||||
|
|
@ -192,7 +192,7 @@ public partial class CS2_SimpleAdmin
|
||||||
callerName ??= caller != null ? caller.PlayerName : _localizer?["sa_console"] ?? "Console";
|
callerName ??= caller != null ? caller.PlayerName : _localizer?["sa_console"] ?? "Console";
|
||||||
|
|
||||||
// Check if player is valid, alive, and connected
|
// Check if player is valid, alive, and connected
|
||||||
if (!player.IsValid || !player.PawnIsAlive || player.Connected != PlayerConnectedState.PlayerConnected)
|
if (!player.IsValid || player.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE || player.Connected != PlayerConnectedState.PlayerConnected)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Strip weapons from the player
|
// Strip weapons from the player
|
||||||
|
|
@ -201,8 +201,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command
|
// Log the command
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_strip {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
Helper.LogCommand(caller, $"css_strip {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
|
|
||||||
// Determine message keys and arguments for the weapon strip notification
|
// Determine message keys and arguments for the weapon strip notification
|
||||||
var (activityMessageKey, adminActivityArgs) =
|
var (activityMessageKey, adminActivityArgs) =
|
||||||
|
|
@ -225,7 +223,7 @@ public partial class CS2_SimpleAdmin
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
if (targets == null) return;
|
if (targets == null) return;
|
||||||
|
|
||||||
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { PawnIsAlive: true, IsHLTV: false }).ToList();
|
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||||
|
|
||||||
playersToTarget.ForEach(player =>
|
playersToTarget.ForEach(player =>
|
||||||
{
|
{
|
||||||
|
|
@ -234,6 +232,8 @@ public partial class CS2_SimpleAdmin
|
||||||
SetHp(caller, player, health, command);
|
SetHp(caller, player, health, command);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetHp(CCSPlayerController? caller, CCSPlayerController player, int health, CommandInfo? command = null)
|
internal static void SetHp(CCSPlayerController? caller, CCSPlayerController player, int health, CommandInfo? command = null)
|
||||||
|
|
@ -250,8 +250,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command
|
// Log the command
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_hp {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {health}");
|
Helper.LogCommand(caller, $"css_hp {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {health}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
|
|
||||||
// Determine message keys and arguments for the HP set notification
|
// Determine message keys and arguments for the HP set notification
|
||||||
var (activityMessageKey, adminActivityArgs) =
|
var (activityMessageKey, adminActivityArgs) =
|
||||||
|
|
@ -274,7 +272,7 @@ public partial class CS2_SimpleAdmin
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
if (targets == null) return;
|
if (targets == null) return;
|
||||||
|
|
||||||
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { PawnIsAlive: true, IsHLTV: false }).ToList();
|
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||||
|
|
||||||
playersToTarget.ForEach(player =>
|
playersToTarget.ForEach(player =>
|
||||||
{
|
{
|
||||||
|
|
@ -286,6 +284,8 @@ public partial class CS2_SimpleAdmin
|
||||||
SetSpeed(caller, player, speed, command);
|
SetSpeed(caller, player, speed, command);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetSpeed(CCSPlayerController? caller, CCSPlayerController player, float speed, CommandInfo? command = null)
|
internal static void SetSpeed(CCSPlayerController? caller, CCSPlayerController player, float speed, CommandInfo? command = null)
|
||||||
|
|
@ -306,8 +306,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command
|
// Log the command
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_speed {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {speed}");
|
Helper.LogCommand(caller, $"css_speed {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {speed}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
|
|
||||||
// Determine message keys and arguments for the speed set notification
|
// Determine message keys and arguments for the speed set notification
|
||||||
var (activityMessageKey, adminActivityArgs) =
|
var (activityMessageKey, adminActivityArgs) =
|
||||||
|
|
@ -330,7 +328,7 @@ public partial class CS2_SimpleAdmin
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
if (targets == null) return;
|
if (targets == null) return;
|
||||||
|
|
||||||
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { PawnIsAlive: true, IsHLTV: false }).ToList();
|
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||||
|
|
||||||
playersToTarget.ForEach(player =>
|
playersToTarget.ForEach(player =>
|
||||||
{
|
{
|
||||||
|
|
@ -342,6 +340,8 @@ public partial class CS2_SimpleAdmin
|
||||||
SetGravity(caller, player, gravity, command);
|
SetGravity(caller, player, gravity, command);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetGravity(CCSPlayerController? caller, CCSPlayerController player, float gravity, CommandInfo? command = null)
|
internal static void SetGravity(CCSPlayerController? caller, CCSPlayerController player, float gravity, CommandInfo? command = null)
|
||||||
|
|
@ -362,8 +362,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command
|
// Log the command
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_gravity {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {gravity}");
|
Helper.LogCommand(caller, $"css_gravity {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {gravity}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
|
|
||||||
// Determine message keys and arguments for the gravity set notification
|
// Determine message keys and arguments for the gravity set notification
|
||||||
var (activityMessageKey, adminActivityArgs) =
|
var (activityMessageKey, adminActivityArgs) =
|
||||||
|
|
@ -387,7 +385,7 @@ public partial class CS2_SimpleAdmin
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
if (targets == null) return;
|
if (targets == null) return;
|
||||||
|
|
||||||
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { PawnIsAlive: true, IsHLTV: false }).ToList();
|
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||||
|
|
||||||
playersToTarget.ForEach(player =>
|
playersToTarget.ForEach(player =>
|
||||||
{
|
{
|
||||||
|
|
@ -399,6 +397,8 @@ public partial class CS2_SimpleAdmin
|
||||||
SetMoney(caller, player, money, command);
|
SetMoney(caller, player, money, command);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void SetMoney(CCSPlayerController? caller, CCSPlayerController player, int money, CommandInfo? command = null)
|
internal static void SetMoney(CCSPlayerController? caller, CCSPlayerController player, int money, CommandInfo? command = null)
|
||||||
|
|
@ -414,8 +414,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command
|
// Log the command
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_money {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {money}");
|
Helper.LogCommand(caller, $"css_money {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {money}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
|
|
||||||
// Determine message keys and arguments for the money set notification
|
// Determine message keys and arguments for the money set notification
|
||||||
var (activityMessageKey, adminActivityArgs) =
|
var (activityMessageKey, adminActivityArgs) =
|
||||||
|
|
@ -438,7 +436,7 @@ public partial class CS2_SimpleAdmin
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
if (targets == null) return;
|
if (targets == null) return;
|
||||||
|
|
||||||
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { PawnIsAlive: true, IsHLTV: false }).ToList();
|
var playersToTarget = targets.Players.Where(player => player.IsValid && player is { IsHLTV: false, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).ToList();
|
||||||
|
|
||||||
if (command.ArgCount >= 2)
|
if (command.ArgCount >= 2)
|
||||||
{
|
{
|
||||||
|
|
@ -455,6 +453,8 @@ public partial class CS2_SimpleAdmin
|
||||||
Slap(caller, player, damage, command);
|
Slap(caller, player, damage, command);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Slap(CCSPlayerController? caller, CCSPlayerController player, int damage, CommandInfo? command = null)
|
internal static void Slap(CCSPlayerController? caller, CCSPlayerController player, int damage, CommandInfo? command = null)
|
||||||
|
|
@ -470,8 +470,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command
|
// Log the command
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_slap {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {damage}");
|
Helper.LogCommand(caller, $"css_slap {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)} {damage}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
|
|
||||||
// Determine message key and arguments for the slap notification
|
// Determine message key and arguments for the slap notification
|
||||||
var (activityMessageKey, adminActivityArgs) =
|
var (activityMessageKey, adminActivityArgs) =
|
||||||
|
|
@ -532,6 +530,8 @@ public partial class CS2_SimpleAdmin
|
||||||
{
|
{
|
||||||
ChangeTeam(caller, player, _teamName, teamNum, kill, command);
|
ChangeTeam(caller, player, _teamName, teamNum, kill, command);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void ChangeTeam(CCSPlayerController? caller, CCSPlayerController player, string teamName, CsTeam teamNum, bool kill, CommandInfo? command = null)
|
internal static void ChangeTeam(CCSPlayerController? caller, CCSPlayerController player, string teamName, CsTeam teamNum, bool kill, CommandInfo? command = null)
|
||||||
|
|
@ -549,7 +549,7 @@ public partial class CS2_SimpleAdmin
|
||||||
// Change team based on the provided teamName and conditions
|
// Change team based on the provided teamName and conditions
|
||||||
if (!teamName.Equals("swap", StringComparison.OrdinalIgnoreCase))
|
if (!teamName.Equals("swap", StringComparison.OrdinalIgnoreCase))
|
||||||
{
|
{
|
||||||
if (player.PawnIsAlive && teamNum != CsTeam.Spectator && !kill && Instance.Config.OtherSettings.TeamSwitchType == 1)
|
if (player.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && teamNum != CsTeam.Spectator && !kill && Instance.Config.OtherSettings.TeamSwitchType == 1)
|
||||||
player.SwitchTeam(teamNum);
|
player.SwitchTeam(teamNum);
|
||||||
else
|
else
|
||||||
player.ChangeTeam(teamNum);
|
player.ChangeTeam(teamNum);
|
||||||
|
|
@ -560,7 +560,7 @@ public partial class CS2_SimpleAdmin
|
||||||
{
|
{
|
||||||
var _teamNum = (CsTeam)player.TeamNum == CsTeam.Terrorist ? CsTeam.CounterTerrorist : CsTeam.Terrorist;
|
var _teamNum = (CsTeam)player.TeamNum == CsTeam.Terrorist ? CsTeam.CounterTerrorist : CsTeam.Terrorist;
|
||||||
teamName = _teamNum == CsTeam.Terrorist ? "TT" : "CT";
|
teamName = _teamNum == CsTeam.Terrorist ? "TT" : "CT";
|
||||||
if (player.PawnIsAlive && !kill && Instance.Config.OtherSettings.TeamSwitchType == 1)
|
if (player.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE && !kill && Instance.Config.OtherSettings.TeamSwitchType == 1)
|
||||||
player.SwitchTeam(_teamNum);
|
player.SwitchTeam(_teamNum);
|
||||||
else
|
else
|
||||||
player.ChangeTeam(_teamNum);
|
player.ChangeTeam(_teamNum);
|
||||||
|
|
@ -570,8 +570,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command
|
// Log the command
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_team {player.PlayerName} {teamName}");
|
Helper.LogCommand(caller, $"css_team {player.PlayerName} {teamName}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
|
|
||||||
// Determine message key and arguments for the team change notification
|
// Determine message key and arguments for the team change notification
|
||||||
var activityMessageKey = "sa_admin_team_message";
|
var activityMessageKey = "sa_admin_team_message";
|
||||||
|
|
@ -698,6 +696,8 @@ public partial class CS2_SimpleAdmin
|
||||||
Respawn(caller, player, callerName, command);
|
Respawn(caller, player, callerName, command);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Helper.LogCommand(caller, command);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void Respawn(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null)
|
internal static void Respawn(CCSPlayerController? caller, CCSPlayerController player, string? callerName = null, CommandInfo? command = null)
|
||||||
|
|
@ -722,8 +722,6 @@ public partial class CS2_SimpleAdmin
|
||||||
// Log the command
|
// Log the command
|
||||||
if (command == null)
|
if (command == null)
|
||||||
Helper.LogCommand(caller, $"css_respawn {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
Helper.LogCommand(caller, $"css_respawn {(string.IsNullOrEmpty(player.PlayerName) ? player.SteamID.ToString() : player.PlayerName)}");
|
||||||
else
|
|
||||||
Helper.LogCommand(caller, command);
|
|
||||||
|
|
||||||
// Determine message key and arguments for the respawn notification
|
// Determine message key and arguments for the respawn notification
|
||||||
var activityMessageKey = "sa_admin_respawn_message";
|
var activityMessageKey = "sa_admin_respawn_message";
|
||||||
|
|
@ -740,7 +738,7 @@ public partial class CS2_SimpleAdmin
|
||||||
public void OnGotoCommand(CCSPlayerController? caller, CommandInfo command)
|
public void OnGotoCommand(CCSPlayerController? caller, CommandInfo command)
|
||||||
{
|
{
|
||||||
// Check if the caller is valid and has a live pawn
|
// Check if the caller is valid and has a live pawn
|
||||||
if (caller == null || !caller.PawnIsAlive) return;
|
if (caller == null || caller.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE) return;
|
||||||
|
|
||||||
// Get the target players
|
// Get the target players
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
|
|
@ -754,7 +752,7 @@ public partial class CS2_SimpleAdmin
|
||||||
Helper.LogCommand(caller, command);
|
Helper.LogCommand(caller, command);
|
||||||
|
|
||||||
// Process each player to teleport
|
// Process each player to teleport
|
||||||
foreach (var player in playersToTarget.Where(player => player is { Connected: PlayerConnectedState.PlayerConnected, PawnIsAlive: true }).Where(caller.CanTarget))
|
foreach (var player in playersToTarget.Where(player => player is { Connected: PlayerConnectedState.PlayerConnected, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).Where(caller.CanTarget))
|
||||||
{
|
{
|
||||||
if (caller.PlayerPawn.Value == null || player.PlayerPawn.Value == null)
|
if (caller.PlayerPawn.Value == null || player.PlayerPawn.Value == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -778,7 +776,7 @@ public partial class CS2_SimpleAdmin
|
||||||
// Set a timer to toggle collision back after 4 seconds
|
// Set a timer to toggle collision back after 4 seconds
|
||||||
AddTimer(4, () =>
|
AddTimer(4, () =>
|
||||||
{
|
{
|
||||||
if (!caller.IsValid || !caller.PawnIsAlive)
|
if (!caller.IsValid || caller.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
caller.PlayerPawn.Value.Collision.CollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_PLAYER;
|
caller.PlayerPawn.Value.Collision.CollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_PLAYER;
|
||||||
|
|
@ -811,7 +809,8 @@ public partial class CS2_SimpleAdmin
|
||||||
public void OnBringCommand(CCSPlayerController? caller, CommandInfo command)
|
public void OnBringCommand(CCSPlayerController? caller, CommandInfo command)
|
||||||
{
|
{
|
||||||
// Check if the caller is valid and has a live pawn
|
// Check if the caller is valid and has a live pawn
|
||||||
if (caller == null || !caller.PawnIsAlive) return;
|
if (caller == null || caller.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE)
|
||||||
|
return;
|
||||||
|
|
||||||
// Get the target players
|
// Get the target players
|
||||||
var targets = GetTarget(command);
|
var targets = GetTarget(command);
|
||||||
|
|
@ -825,7 +824,7 @@ public partial class CS2_SimpleAdmin
|
||||||
Helper.LogCommand(caller, command);
|
Helper.LogCommand(caller, command);
|
||||||
|
|
||||||
// Process each player to teleport
|
// Process each player to teleport
|
||||||
foreach (var player in playersToTarget.Where(player => player is { Connected: PlayerConnectedState.PlayerConnected, PawnIsAlive: true }).Where(caller.CanTarget))
|
foreach (var player in playersToTarget.Where(player => player is { Connected: PlayerConnectedState.PlayerConnected, PlayerPawn.Value.LifeState: (int)LifeState_t.LIFE_ALIVE }).Where(caller.CanTarget))
|
||||||
{
|
{
|
||||||
if (caller.PlayerPawn.Value == null || player.PlayerPawn.Value == null)
|
if (caller.PlayerPawn.Value == null || player.PlayerPawn.Value == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -849,7 +848,7 @@ public partial class CS2_SimpleAdmin
|
||||||
// Set a timer to toggle collision back after 4 seconds
|
// Set a timer to toggle collision back after 4 seconds
|
||||||
AddTimer(4, () =>
|
AddTimer(4, () =>
|
||||||
{
|
{
|
||||||
if (!player.IsValid || !player.PawnIsAlive)
|
if (!player.IsValid || player.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
caller.PlayerPawn.Value.Collision.CollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_PLAYER;
|
caller.PlayerPawn.Value.Collision.CollisionGroup = (byte)CollisionGroup.COLLISION_GROUP_PLAYER;
|
||||||
|
|
|
||||||
|
|
@ -89,6 +89,17 @@ public class Discord
|
||||||
new DiscordPenaltySetting { Name = "Footer", Value = "" },
|
new DiscordPenaltySetting { Name = "Footer", Value = "" },
|
||||||
new DiscordPenaltySetting { Name = "Time", Value = "{relative}" },
|
new DiscordPenaltySetting { Name = "Time", Value = "{relative}" },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
[JsonPropertyName("DiscordAssociatedAccountsSettings")]
|
||||||
|
public DiscordPenaltySetting[] DiscordAssociatedAccountsSettings { get; set; } =
|
||||||
|
[
|
||||||
|
new DiscordPenaltySetting { Name = "Color", Value = "" },
|
||||||
|
new DiscordPenaltySetting { Name = "Webhook", Value = "" },
|
||||||
|
new DiscordPenaltySetting { Name = "ThumbnailUrl", Value = "" },
|
||||||
|
new DiscordPenaltySetting { Name = "ImageUrl", Value = "" },
|
||||||
|
new DiscordPenaltySetting { Name = "Footer", Value = "" },
|
||||||
|
new DiscordPenaltySetting { Name = "Time", Value = "{relative}" },
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ChatLog
|
public class ChatLog
|
||||||
|
|
@ -247,7 +258,10 @@ public class OtherSettings
|
||||||
public List<string> AdditionalCommandsToLog { get; set; } = new();
|
public List<string> AdditionalCommandsToLog { get; set; } = new();
|
||||||
|
|
||||||
[JsonPropertyName("HideStealthPlayersFromSpecList")]
|
[JsonPropertyName("HideStealthPlayersFromSpecList")]
|
||||||
public bool HideStealthPlayersFromSpecList {get; set; } = false;
|
public bool HideStealthPlayersFromSpecList { get; set; } = false;
|
||||||
|
|
||||||
|
[JsonPropertyName("IgnoredIps")]
|
||||||
|
public List<string> IgnoredIps { get; set; } = new();
|
||||||
}
|
}
|
||||||
|
|
||||||
public class CS2_SimpleAdminConfig : BasePluginConfig
|
public class CS2_SimpleAdminConfig : BasePluginConfig
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
ALTER TABLE `sa_bans` ADD COLUMN `updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP AFTER `status`;
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
UPDATE `sa_players_ips` SET `address` = INET_ATON(address);
|
||||||
|
ALTER TABLE `sa_players_ips` CHANGE `address` `address` INT UNSIGNED NOT NULL;
|
||||||
|
ALTER TABLE `sa_players_ips` ADD `name` VARCHAR(64) NULL DEFAULT NULL AFTER `steamid`;
|
||||||
|
ALTER TABLE `sa_players_ips` ADD INDEX(`used_at`);
|
||||||
|
|
@ -150,13 +150,21 @@ public partial class CS2_SimpleAdmin
|
||||||
if (player.UserId.HasValue)
|
if (player.UserId.HasValue)
|
||||||
PlayersInfo.TryRemove(player.UserId.Value, out _);
|
PlayersInfo.TryRemove(player.UserId.Value, out _);
|
||||||
|
|
||||||
var authorizedSteamId = player.AuthorizedSteamID;
|
if (!PermissionManager.AdminCache.TryGetValue(steamId, out var data)
|
||||||
if (authorizedSteamId == null || !PermissionManager.AdminCache.TryGetValue(authorizedSteamId,
|
|| !(data.ExpirationTime <= Time.ActualDateTime()))
|
||||||
out var expirationTime)
|
{
|
||||||
|| !(expirationTime <= Time.ActualDateTime())) return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
|
}
|
||||||
|
|
||||||
AdminManager.ClearPlayerPermissions(authorizedSteamId);
|
AdminManager.RemovePlayerPermissions(steamId, PermissionManager.AdminCache[steamId].Flags.ToArray());
|
||||||
AdminManager.RemovePlayerAdminData(authorizedSteamId);
|
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;
|
return HookResult.Continue;
|
||||||
}
|
}
|
||||||
|
|
@ -172,7 +180,10 @@ public partial class CS2_SimpleAdmin
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
Logger.LogCritical("[OnClientConnect]");
|
Logger.LogCritical("[OnClientConnect]");
|
||||||
#endif
|
#endif
|
||||||
if (!CS2_SimpleAdmin.BannedPlayers.Contains(ipaddress.Split(":")[0]))
|
if (Config.OtherSettings.BanType == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (Instance.CacheManager != null && !Instance.CacheManager.IsPlayerBanned(null, ipaddress.Split(":")[0]))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Server.NextFrame((() =>
|
Server.NextFrame((() =>
|
||||||
|
|
@ -263,12 +274,25 @@ public partial class CS2_SimpleAdmin
|
||||||
!PlayerPenaltyManager.IsPenalized(author.Slot, PenaltyType.Silence, out endDateTime))
|
!PlayerPenaltyManager.IsPenalized(author.Slot, PenaltyType.Silence, out endDateTime))
|
||||||
return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
|
|
||||||
if (_localizer != null && endDateTime is not null)
|
var message = um.ReadString("param2");
|
||||||
|
|
||||||
|
if (_localizer == null || endDateTime is null) return HookResult.Continue;
|
||||||
|
|
||||||
|
if (CoreConfig.PublicChatTrigger.Concat(CoreConfig.SilentChatTrigger).Any(trigger => message.StartsWith(trigger)))
|
||||||
|
{
|
||||||
|
foreach (var recipient in um.Recipients)
|
||||||
|
{
|
||||||
|
if (recipient == author)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
um.Recipients.Remove(recipient);
|
||||||
|
}
|
||||||
|
|
||||||
|
return HookResult.Continue;
|
||||||
|
}
|
||||||
|
|
||||||
author.SendLocalizedMessage(_localizer, "sa_player_penalty_chat_active", endDateTime.Value.ToString("g", author.GetLanguage()));
|
author.SendLocalizedMessage(_localizer, "sa_player_penalty_chat_active", endDateTime.Value.ToString("g", author.GetLanguage()));
|
||||||
return HookResult.Stop;
|
return HookResult.Stop;
|
||||||
|
|
||||||
// um.Recipients.Clear();
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private HookResult ComamndListenerHandler(CCSPlayerController? player, CommandInfo info)
|
private HookResult ComamndListenerHandler(CCSPlayerController? player, CommandInfo info)
|
||||||
|
|
@ -448,9 +472,9 @@ public partial class CS2_SimpleAdmin
|
||||||
private void OnMapStart(string mapName)
|
private void OnMapStart(string mapName)
|
||||||
{
|
{
|
||||||
if (Config.OtherSettings.ReloadAdminsEveryMapChange && ServerLoaded && ServerId != null)
|
if (Config.OtherSettings.ReloadAdminsEveryMapChange && ServerLoaded && ServerId != null)
|
||||||
AddTimer(3.0f, () => ReloadAdmins(null));
|
AddTimer(5.0f, () => ReloadAdmins(null));
|
||||||
|
|
||||||
AddTimer(1.0f, () => new ServerManager().CheckHibernationStatus());
|
AddTimer(1.0f, () => ServerManager.CheckHibernationStatus());
|
||||||
|
|
||||||
// AddTimer(34, () =>
|
// AddTimer(34, () =>
|
||||||
// {
|
// {
|
||||||
|
|
@ -471,10 +495,9 @@ public partial class CS2_SimpleAdmin
|
||||||
{
|
{
|
||||||
var player = @event.Userid;
|
var player = @event.Userid;
|
||||||
|
|
||||||
if (player is null || @event.Attacker is null || !player.PawnIsAlive || player.PlayerPawn.Value == null)
|
if (player is null || @event.Attacker is null || player.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE || player.PlayerPawn.Value == null)
|
||||||
return HookResult.Continue;
|
return HookResult.Continue;
|
||||||
|
|
||||||
|
|
||||||
if (SpeedPlayers.TryGetValue(player.Slot, out var speedPlayer))
|
if (SpeedPlayers.TryGetValue(player.Slot, out var speedPlayer))
|
||||||
AddTimer(0.15f, () => player.SetSpeed(speedPlayer));
|
AddTimer(0.15f, () => player.SetSpeed(speedPlayer));
|
||||||
|
|
||||||
|
|
|
||||||
12
CS2-SimpleAdmin/Extensions/EnumerableExtensions.cs
Normal file
12
CS2-SimpleAdmin/Extensions/EnumerableExtensions.cs
Normal file
|
|
@ -0,0 +1,12 @@
|
||||||
|
namespace CS2_SimpleAdmin;
|
||||||
|
|
||||||
|
public static class EnumerableExtensions
|
||||||
|
{
|
||||||
|
public static IEnumerable<IEnumerable<T>> ChunkBy<T>(this IEnumerable<T> source, int chunkSize)
|
||||||
|
{
|
||||||
|
return source
|
||||||
|
.Select((x, i) => new { Index = i, Value = x })
|
||||||
|
.GroupBy(x => x.Index / chunkSize)
|
||||||
|
.Select(x => x.Select(v => v.Value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -73,7 +73,7 @@ public static class PlayerExtensions
|
||||||
public static void SetHp(this CCSPlayerController? controller, int health = 100)
|
public static void SetHp(this CCSPlayerController? controller, int health = 100)
|
||||||
{
|
{
|
||||||
if (controller == null) return;
|
if (controller == null) return;
|
||||||
if ((health <= 0 || !controller.PawnIsAlive || controller.PlayerPawn.Value == null)) return;
|
if (health <= 0 || controller.PlayerPawn.Value == null || controller.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE) return;
|
||||||
|
|
||||||
controller.PlayerPawn.Value.Health = health;
|
controller.PlayerPawn.Value.Health = health;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ using CounterStrikeSharp.API.Core.Plugin.Host;
|
||||||
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
using CounterStrikeSharp.API.Modules.Entities.Constants;
|
||||||
using CS2_SimpleAdmin.Managers;
|
using CS2_SimpleAdmin.Managers;
|
||||||
using MenuManager;
|
using MenuManager;
|
||||||
|
using ZLinq;
|
||||||
|
|
||||||
namespace CS2_SimpleAdmin;
|
namespace CS2_SimpleAdmin;
|
||||||
|
|
||||||
|
|
@ -78,34 +79,30 @@ internal static class Helper
|
||||||
return Utilities.GetPlayers().FindAll(x => x.PlayerName.Equals(name, StringComparison.OrdinalIgnoreCase));
|
return Utilities.GetPlayers().FindAll(x => x.PlayerName.Equals(name, StringComparison.OrdinalIgnoreCase));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<CCSPlayerController> GetPlayerFromSteamid64(string steamid)
|
public static CCSPlayerController? GetPlayerFromSteamid64(string steamid)
|
||||||
{
|
{
|
||||||
return GetValidPlayers().FindAll(x =>
|
return GetValidPlayers().FirstOrDefault(x => x.SteamID.ToString().Equals(steamid, StringComparison.OrdinalIgnoreCase));
|
||||||
x.SteamID.ToString().Equals(steamid, StringComparison.OrdinalIgnoreCase)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<CCSPlayerController> GetPlayerFromIp(string ipAddress)
|
public static CCSPlayerController? GetPlayerFromIp(string ipAddress)
|
||||||
{
|
{
|
||||||
return GetValidPlayers().FindAll(x =>
|
return GetValidPlayers().FirstOrDefault(x => x.IpAddress != null && x.IpAddress.Split(":")[0].Equals(ipAddress));
|
||||||
x.IpAddress != null &&
|
|
||||||
x.IpAddress.Split(":")[0].Equals(ipAddress)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<CCSPlayerController> GetValidPlayers()
|
public static List<CCSPlayerController> GetValidPlayers()
|
||||||
{
|
{
|
||||||
return Utilities.GetPlayers().FindAll(p => p is
|
return Utilities.GetPlayers().AsValueEnumerable()
|
||||||
{ IsValid: true, IsBot: false, Connected: PlayerConnectedState.PlayerConnected });
|
.Where(p => p is { IsValid: true, IsBot: false, Connected: PlayerConnectedState.PlayerConnected })
|
||||||
|
.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<CCSPlayerController?> GetValidPlayersWithBots()
|
public static List<CCSPlayerController> GetValidPlayersWithBots()
|
||||||
{
|
{
|
||||||
return Utilities.GetPlayers().FindAll(p =>
|
return Utilities.GetPlayers().AsValueEnumerable()
|
||||||
p is { IsValid: true, IsBot: false, IsHLTV: false } or { IsValid: true, IsBot: true, IsHLTV: false }
|
.Where(p => p is { IsValid: true, IsHLTV: false, Connected: PlayerConnectedState.PlayerConnected }).ToList();
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// public static bool IsValidSteamId64(string input)
|
// public static bool IsValidSteamId64(string input)
|
||||||
// {
|
// {
|
||||||
// const string pattern = @"^\d{17}$";
|
// const string pattern = @"^\d{17}$";
|
||||||
|
|
@ -699,7 +696,6 @@ internal static class Helper
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
// Log or handle the exception
|
|
||||||
Console.WriteLine(ex);
|
Console.WriteLine(ex);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -827,6 +823,7 @@ internal static class Helper
|
||||||
|
|
||||||
return pluginManager;
|
return pluginManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class PluginInfo
|
public static class PluginInfo
|
||||||
|
|
@ -1000,3 +997,35 @@ public static class WeaponHelper
|
||||||
return filteredWeapons; // Return all relevant matches for the partial input
|
return filteredWeapons; // Return all relevant matches for the partial input
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class IpHelper
|
||||||
|
{
|
||||||
|
public static uint IpToUint(string ipAddress)
|
||||||
|
{
|
||||||
|
return (uint)BitConverter.ToInt32(System.Net.IPAddress.Parse(ipAddress).GetAddressBytes().Reverse().ToArray(),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryConvertIpToUint(string ipString, out uint ipUint)
|
||||||
|
{
|
||||||
|
ipUint = 0;
|
||||||
|
if (string.IsNullOrWhiteSpace(ipString))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!System.Net.IPAddress.TryParse(ipString, out var ipAddress))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var bytes = ipAddress.GetAddressBytes();
|
||||||
|
if (bytes.Length != 4)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
ipUint = IpToUint(ipString);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string UintToIp(uint ipAddress)
|
||||||
|
{
|
||||||
|
var bytes = BitConverter.GetBytes(ipAddress).Reverse().ToArray();
|
||||||
|
return new System.Net.IPAddress(bytes).ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -145,7 +145,7 @@ internal class BanManager(Database.Database? database)
|
||||||
{
|
{
|
||||||
string sql;
|
string sql;
|
||||||
|
|
||||||
if (CS2_SimpleAdmin.Instance.Config.OtherSettings.CheckMultiAccountsByIp)
|
if (CS2_SimpleAdmin.Instance.Config.OtherSettings.CheckMultiAccountsByIp && !CS2_SimpleAdmin.Instance.Config.OtherSettings.IgnoredIps.Contains(player.IpAddress))
|
||||||
{
|
{
|
||||||
sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode ? """
|
sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode ? """
|
||||||
SELECT COALESCE((
|
SELECT COALESCE((
|
||||||
|
|
@ -232,7 +232,8 @@ internal class BanManager(Database.Database? database)
|
||||||
{
|
{
|
||||||
PlayerSteamID = player.SteamId.SteamId64.ToString(),
|
PlayerSteamID = player.SteamId.SteamId64.ToString(),
|
||||||
PlayerIP = CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType == 0 ||
|
PlayerIP = CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType == 0 ||
|
||||||
string.IsNullOrEmpty(player.IpAddress)
|
string.IsNullOrEmpty(player.IpAddress) ||
|
||||||
|
CS2_SimpleAdmin.Instance.Config.OtherSettings.IgnoredIps.Contains(player.IpAddress)
|
||||||
? null
|
? null
|
||||||
: player.IpAddress,
|
: player.IpAddress,
|
||||||
PlayerName = !string.IsNullOrEmpty(player.Name) ? player.Name : string.Empty,
|
PlayerName = !string.IsNullOrEmpty(player.Name) ? player.Name : string.Empty,
|
||||||
|
|
@ -393,7 +394,7 @@ internal class BanManager(Database.Database? database)
|
||||||
{
|
{
|
||||||
SteamIDs = steamIds,
|
SteamIDs = steamIds,
|
||||||
IpAddresses = checkIpBans ? ipAddresses : [],
|
IpAddresses = checkIpBans ? ipAddresses : [],
|
||||||
ServerId = CS2_SimpleAdmin.ServerId
|
CS2_SimpleAdmin.ServerId
|
||||||
});
|
});
|
||||||
|
|
||||||
var valueTuples = bannedPlayers.ToList();
|
var valueTuples = bannedPlayers.ToList();
|
||||||
|
|
|
||||||
397
CS2-SimpleAdmin/Managers/CacheManager.cs
Normal file
397
CS2-SimpleAdmin/Managers/CacheManager.cs
Normal file
|
|
@ -0,0 +1,397 @@
|
||||||
|
using System.Collections.Concurrent;
|
||||||
|
using CS2_SimpleAdmin.Models;
|
||||||
|
using Dapper;
|
||||||
|
using ZLinq;
|
||||||
|
|
||||||
|
namespace CS2_SimpleAdmin.Managers;
|
||||||
|
|
||||||
|
internal class CacheManager: IDisposable
|
||||||
|
{
|
||||||
|
private readonly ConcurrentDictionary<int, BanRecord> _banCache = [];
|
||||||
|
private readonly ConcurrentDictionary<string, List<BanRecord>> _steamIdIndex = [];
|
||||||
|
private readonly ConcurrentDictionary<uint, List<BanRecord>> _ipIndex = [];
|
||||||
|
|
||||||
|
private readonly ConcurrentDictionary<ulong, HashSet<IpRecord>> _playerIpsCache = [];
|
||||||
|
private HashSet<uint> _cachedIgnoredIps = [];
|
||||||
|
|
||||||
|
private DateTime _lastUpdateTime = DateTime.MinValue;
|
||||||
|
private bool _isInitialized;
|
||||||
|
private bool _disposed;
|
||||||
|
|
||||||
|
public async Task InitializeCacheAsync()
|
||||||
|
{
|
||||||
|
if (CS2_SimpleAdmin.Database == null) return;
|
||||||
|
if (!CS2_SimpleAdmin.ServerLoaded) return;
|
||||||
|
if (_isInitialized) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Clear();
|
||||||
|
_cachedIgnoredIps = new HashSet<uint>(
|
||||||
|
CS2_SimpleAdmin.Instance.Config.OtherSettings.IgnoredIps
|
||||||
|
.Select(IpHelper.IpToUint));
|
||||||
|
|
||||||
|
await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync();
|
||||||
|
List<BanRecord> bans;
|
||||||
|
|
||||||
|
if (CS2_SimpleAdmin.Instance.Config.MultiServerMode)
|
||||||
|
{
|
||||||
|
bans = (await connection.QueryAsync<BanRecord>(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
id AS Id,
|
||||||
|
player_steamid AS PlayerSteamId,
|
||||||
|
player_ip AS PlayerIp,
|
||||||
|
status AS Status
|
||||||
|
FROM sa_bans
|
||||||
|
""")).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bans = (await connection.QueryAsync<BanRecord>(
|
||||||
|
"""
|
||||||
|
SELECT
|
||||||
|
id AS Id,
|
||||||
|
player_steamid AS PlayerSteamId,
|
||||||
|
player_ip AS PlayerIp,
|
||||||
|
status AS Status
|
||||||
|
FROM sa_bans
|
||||||
|
WHERE server_id = @serverId
|
||||||
|
""", new {serverId = CS2_SimpleAdmin.ServerId})).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
var ipHistory =
|
||||||
|
await connection.QueryAsync<(ulong steamid, string? name, uint address, DateTime used_at)>(
|
||||||
|
"SELECT steamid, name, address, used_at FROM sa_players_ips ORDER BY used_at DESC");
|
||||||
|
|
||||||
|
foreach (var ban in bans)
|
||||||
|
{
|
||||||
|
_banCache.TryAdd(ban.Id, ban);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var group in ipHistory.AsValueEnumerable().GroupBy(x => x.steamid))
|
||||||
|
{
|
||||||
|
var ipSet = new HashSet<IpRecord>(
|
||||||
|
group
|
||||||
|
.GroupBy(x => x.address)
|
||||||
|
.Select(g =>
|
||||||
|
{
|
||||||
|
var latest = g.MaxBy(x => x.used_at);
|
||||||
|
return new IpRecord(
|
||||||
|
g.Key,
|
||||||
|
latest.used_at,
|
||||||
|
!string.IsNullOrEmpty(latest.name)
|
||||||
|
? latest.name
|
||||||
|
: CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown"
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
new IpRecordComparer()
|
||||||
|
);
|
||||||
|
|
||||||
|
_playerIpsCache.AddOrUpdate(
|
||||||
|
group.Key,
|
||||||
|
_ => ipSet,
|
||||||
|
(_, existingSet) =>
|
||||||
|
{
|
||||||
|
foreach (var ip in ipSet)
|
||||||
|
{
|
||||||
|
existingSet.Remove(ip);
|
||||||
|
existingSet.Add(ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
return existingSet;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
RebuildIndexes();
|
||||||
|
|
||||||
|
_lastUpdateTime = DateTime.Now.AddSeconds(-1);
|
||||||
|
_isInitialized = true;
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Console.WriteLine(e.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ForceReInitializeCacheAsync()
|
||||||
|
{
|
||||||
|
_isInitialized = false;
|
||||||
|
|
||||||
|
_banCache.Clear();
|
||||||
|
_playerIpsCache.Clear();
|
||||||
|
_cachedIgnoredIps.Clear();
|
||||||
|
_lastUpdateTime = DateTime.MinValue;
|
||||||
|
|
||||||
|
await InitializeCacheAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task RefreshCacheAsync()
|
||||||
|
{
|
||||||
|
if (CS2_SimpleAdmin.Database == null) return;
|
||||||
|
if (!_isInitialized) return;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync();
|
||||||
|
List<BanRecord> updatedBans;
|
||||||
|
|
||||||
|
var allIds = (await connection.QueryAsync<int>("SELECT id FROM sa_bans")).ToHashSet();
|
||||||
|
|
||||||
|
if (CS2_SimpleAdmin.Instance.Config.MultiServerMode)
|
||||||
|
{
|
||||||
|
updatedBans = (await connection.QueryAsync<BanRecord>(
|
||||||
|
"""
|
||||||
|
SELECT id AS Id,
|
||||||
|
player_steamid AS PlayerSteamId,
|
||||||
|
player_ip AS PlayerIp,
|
||||||
|
status AS Status
|
||||||
|
FROM `sa_bans` WHERE updated_at > @lastUpdate OR created > @lastUpdate ORDER BY updated_at DESC
|
||||||
|
""",
|
||||||
|
new { lastUpdate = _lastUpdateTime }
|
||||||
|
)).ToList();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
updatedBans = (await connection.QueryAsync<BanRecord>(
|
||||||
|
"""
|
||||||
|
SELECT id AS Id,
|
||||||
|
player_steamid AS PlayerSteamId,
|
||||||
|
player_ip AS PlayerIp,
|
||||||
|
status AS Status
|
||||||
|
FROM `sa_bans` WHERE (updated_at > @lastUpdate OR created > @lastUpdate) AND server_id = @serverId ORDER BY updated_at DESC
|
||||||
|
""",
|
||||||
|
new { lastUpdate = _lastUpdateTime, serverId = CS2_SimpleAdmin.ServerId }
|
||||||
|
)).ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var id in _banCache.Keys)
|
||||||
|
{
|
||||||
|
if (allIds.Contains(id) || !_banCache.TryRemove(id, out var ban)) continue;
|
||||||
|
|
||||||
|
// Remove from steamIdIndex
|
||||||
|
if (!string.IsNullOrWhiteSpace(ban.PlayerSteamId) &&
|
||||||
|
_steamIdIndex.TryGetValue(ban.PlayerSteamId, out var steamBans))
|
||||||
|
{
|
||||||
|
steamBans.RemoveAll(b => b.Id == id);
|
||||||
|
if (steamBans.Count == 0)
|
||||||
|
_steamIdIndex.TryRemove(ban.PlayerSteamId, out _);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove from ipIndex
|
||||||
|
if (!string.IsNullOrWhiteSpace(ban.PlayerIp) &&
|
||||||
|
IpHelper.TryConvertIpToUint(ban.PlayerIp, out var ipUInt) &&
|
||||||
|
_ipIndex.TryGetValue(ipUInt, out var ipBans))
|
||||||
|
{
|
||||||
|
ipBans.RemoveAll(b => b.Id == id);
|
||||||
|
if (ipBans.Count == 0)
|
||||||
|
_ipIndex.TryRemove(ipUInt, out _);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var ipHistory = (await connection.QueryAsync<(ulong steamid, string? name, uint address, DateTime used_at)>(
|
||||||
|
"SELECT steamid, name, address, used_at FROM sa_players_ips WHERE used_at >= @lastUpdate ORDER BY used_at DESC LIMIT 300", new {lastUpdate = _lastUpdateTime})).ToList();
|
||||||
|
|
||||||
|
foreach (var group in ipHistory.AsValueEnumerable().GroupBy(x => x.steamid))
|
||||||
|
{
|
||||||
|
var ipSet = new HashSet<IpRecord>(
|
||||||
|
group
|
||||||
|
.GroupBy(x => x.address)
|
||||||
|
.Select(g =>
|
||||||
|
{
|
||||||
|
var latest = g.MaxBy(x => x.used_at);
|
||||||
|
return new IpRecord(
|
||||||
|
g.Key,
|
||||||
|
latest.used_at,
|
||||||
|
!string.IsNullOrEmpty(latest.name)
|
||||||
|
? latest.name
|
||||||
|
: CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown"
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
new IpRecordComparer()
|
||||||
|
);
|
||||||
|
|
||||||
|
_playerIpsCache.AddOrUpdate(
|
||||||
|
group.Key,
|
||||||
|
_ => ipSet,
|
||||||
|
(_, existingSet) =>
|
||||||
|
{
|
||||||
|
foreach (var newEntry in ipSet)
|
||||||
|
{
|
||||||
|
existingSet.Remove(newEntry);
|
||||||
|
existingSet.Add(newEntry);
|
||||||
|
}
|
||||||
|
return existingSet;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (updatedBans.Count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
foreach (var ban in updatedBans)
|
||||||
|
{
|
||||||
|
_banCache.AddOrUpdate(ban.Id, ban, (_, _) => ban);
|
||||||
|
}
|
||||||
|
|
||||||
|
RebuildIndexes();
|
||||||
|
_lastUpdateTime = DateTime.Now.AddSeconds(-1);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
// ignored
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RebuildIndexes()
|
||||||
|
{
|
||||||
|
_steamIdIndex.Clear();
|
||||||
|
_ipIndex.Clear();
|
||||||
|
|
||||||
|
foreach (var ban in _banCache.Values)
|
||||||
|
{
|
||||||
|
if (ban.Status != "ACTIVE")
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!string.IsNullOrWhiteSpace(ban.PlayerSteamId))
|
||||||
|
{
|
||||||
|
var steamId = ban.PlayerSteamId;
|
||||||
|
_steamIdIndex.AddOrUpdate(
|
||||||
|
steamId,
|
||||||
|
key => [ban],
|
||||||
|
(key, list) =>
|
||||||
|
{
|
||||||
|
list.Add(ban);
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ban.PlayerIp != null &&
|
||||||
|
IpHelper.TryConvertIpToUint(ban.PlayerIp, out var ipUInt))
|
||||||
|
{
|
||||||
|
_ipIndex.AddOrUpdate(
|
||||||
|
ipUInt,
|
||||||
|
key => [ban],
|
||||||
|
(key, list) =>
|
||||||
|
{
|
||||||
|
list.Add(ban);
|
||||||
|
return list;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<BanRecord> GetAllBans() => _banCache.Values.ToList();
|
||||||
|
public List<BanRecord> GetActiveBans() => _banCache.Values.Where(b => b.Status == "ACTIVE").ToList();
|
||||||
|
public List<BanRecord> GetPlayerBansBySteamId(string steamId) => _steamIdIndex.TryGetValue(steamId, out var bans) ? bans : [];
|
||||||
|
public List<(ulong SteamId, DateTime UsedAt, string PlayerName)> GetAccountsByIp(string ipAddress)
|
||||||
|
{
|
||||||
|
var ipAsUint = IpHelper.IpToUint(ipAddress);
|
||||||
|
|
||||||
|
return _playerIpsCache.AsValueEnumerable()
|
||||||
|
.SelectMany(kvp => kvp.Value
|
||||||
|
.Where(entry => entry.Ip == ipAsUint)
|
||||||
|
.Select(entry => (kvp.Key, entry.UsedAt, entry.PlayerName)))
|
||||||
|
.ToList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool IsIpBanned(string ipAddress)
|
||||||
|
{
|
||||||
|
if (CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType == 0) return false;
|
||||||
|
var ipUInt = IpHelper.IpToUint(ipAddress);
|
||||||
|
return !_cachedIgnoredIps.Contains(ipUInt) && _ipIndex.ContainsKey(ipUInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public bool IsPlayerBanned(string? steamId, string? ipAddress)
|
||||||
|
{
|
||||||
|
if (steamId != null && _steamIdIndex.ContainsKey(steamId))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType == 0) return false;
|
||||||
|
|
||||||
|
if (ipAddress == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!IpHelper.TryConvertIpToUint(ipAddress, out var ipUInt))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !_cachedIgnoredIps.Contains(ipUInt) &&
|
||||||
|
_ipIndex.ContainsKey(ipUInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsPlayerOrAnyIpBanned(ulong steamId, string? ipAddress)
|
||||||
|
{
|
||||||
|
var steamIdStr = steamId.ToString();
|
||||||
|
|
||||||
|
if (_steamIdIndex.ContainsKey(steamIdStr))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType == 0) return false;
|
||||||
|
|
||||||
|
if (!_playerIpsCache.TryGetValue(steamId, out var ipData))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
var now = DateTime.Now;
|
||||||
|
var cutoff = now.AddDays(-7);
|
||||||
|
|
||||||
|
if (ipAddress != null)
|
||||||
|
{
|
||||||
|
var ipAsUint = IpHelper.IpToUint(ipAddress);
|
||||||
|
|
||||||
|
if (!_cachedIgnoredIps.Contains(ipAsUint))
|
||||||
|
{
|
||||||
|
ipData.Add(new IpRecord(
|
||||||
|
ipAsUint,
|
||||||
|
now.AddSeconds(-2), // artificially recent
|
||||||
|
CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var ipRecord in ipData)
|
||||||
|
{
|
||||||
|
if (ipRecord.UsedAt < cutoff || _cachedIgnoredIps.Contains(ipRecord.Ip))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (_ipIndex.ContainsKey(ipRecord.Ip))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool HasIpForPlayer(ulong steamId, string ipAddress)
|
||||||
|
{
|
||||||
|
if (string.IsNullOrWhiteSpace(ipAddress))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return _playerIpsCache.TryGetValue(steamId, out var ipData)
|
||||||
|
&& ipData.Any(x => x.Ip == IpHelper.IpToUint(ipAddress));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Clear()
|
||||||
|
{
|
||||||
|
_steamIdIndex.Clear();
|
||||||
|
_ipIndex.Clear();
|
||||||
|
|
||||||
|
_banCache.Clear();
|
||||||
|
_playerIpsCache.Clear();
|
||||||
|
_cachedIgnoredIps.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_disposed) return;
|
||||||
|
Clear();
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class IpRecordComparer : IEqualityComparer<IpRecord>
|
||||||
|
{
|
||||||
|
public bool Equals(IpRecord x, IpRecord y)
|
||||||
|
=> x.Ip == y.Ip;
|
||||||
|
|
||||||
|
public int GetHashCode(IpRecord obj)
|
||||||
|
=> obj.Ip.GetHashCode();
|
||||||
|
}
|
||||||
|
|
@ -187,13 +187,13 @@ internal class MuteManager(Database.Database? database)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task CheckOnlineModeMutes(List<(string? IpAddress, ulong SteamID, int? UserId, int Slot)> players)
|
public async Task CheckOnlineModeMutes(List<(ulong SteamID, int? UserId, int Slot)> players)
|
||||||
{
|
{
|
||||||
if (database == null) return;
|
if (database == null) return;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var batchSize = 10;
|
const int batchSize = 20;
|
||||||
await using var connection = await database.GetConnectionAsync();
|
await using var connection = await database.GetConnectionAsync();
|
||||||
|
|
||||||
var sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode
|
var sql = CS2_SimpleAdmin.Instance.Config.MultiServerMode
|
||||||
|
|
@ -205,7 +205,7 @@ internal class MuteManager(Database.Database? database)
|
||||||
var batch = players.Skip(i).Take(batchSize);
|
var batch = players.Skip(i).Take(batchSize);
|
||||||
var parametersList = new List<object>();
|
var parametersList = new List<object>();
|
||||||
|
|
||||||
foreach (var (_, steamId, _, _) in batch)
|
foreach (var (steamId, _, _) in batch)
|
||||||
{
|
{
|
||||||
parametersList.Add(new { PlayerSteamID = steamId, serverid = CS2_SimpleAdmin.ServerId });
|
parametersList.Add(new { PlayerSteamID = steamId, serverid = CS2_SimpleAdmin.ServerId });
|
||||||
}
|
}
|
||||||
|
|
@ -218,7 +218,7 @@ internal class MuteManager(Database.Database? database)
|
||||||
: "SELECT * FROM `sa_mutes` WHERE player_steamid = @PlayerSteamID AND passed >= duration AND duration > 0 AND status = 'ACTIVE' AND server_id = @serverid";
|
: "SELECT * FROM `sa_mutes` WHERE player_steamid = @PlayerSteamID AND passed >= duration AND duration > 0 AND status = 'ACTIVE' AND server_id = @serverid";
|
||||||
|
|
||||||
|
|
||||||
foreach (var (_, steamId, _, slot) in players)
|
foreach (var (steamId, _, slot) in players)
|
||||||
{
|
{
|
||||||
var muteRecords = await connection.QueryAsync(sql, new { PlayerSteamID = steamId, serverid = CS2_SimpleAdmin.ServerId });
|
var muteRecords = await connection.QueryAsync(sql, new { PlayerSteamID = steamId, serverid = CS2_SimpleAdmin.ServerId });
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ using Microsoft.Extensions.Logging;
|
||||||
using MySqlConnector;
|
using MySqlConnector;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
|
using CounterStrikeSharp.API.Modules.Admin;
|
||||||
|
|
||||||
namespace CS2_SimpleAdmin.Managers;
|
namespace CS2_SimpleAdmin.Managers;
|
||||||
|
|
||||||
|
|
@ -13,7 +14,8 @@ public class PermissionManager(Database.Database? database)
|
||||||
{
|
{
|
||||||
// Unused for now
|
// Unused for now
|
||||||
//public static readonly ConcurrentDictionary<string, ConcurrentBag<string>> _adminCache = new ConcurrentDictionary<string, ConcurrentBag<string>>();
|
//public static readonly ConcurrentDictionary<string, ConcurrentBag<string>> _adminCache = new ConcurrentDictionary<string, ConcurrentBag<string>>();
|
||||||
public static readonly ConcurrentDictionary<SteamID, DateTime?> AdminCache = new();
|
// public static readonly ConcurrentDictionary<SteamID, DateTime?> AdminCache = new();
|
||||||
|
public static readonly ConcurrentDictionary<SteamID, (DateTime? ExpirationTime, List<string> Flags)> AdminCache = new();
|
||||||
|
|
||||||
// Get the relevant server groups from the sa_servers_groups table by searching if the serverId is in the servers set column
|
// Get the relevant server groups from the sa_servers_groups table by searching if the serverId is in the servers set column
|
||||||
public async Task<List<string>> GetServerGroups()
|
public async Task<List<string>> GetServerGroups()
|
||||||
|
|
@ -236,7 +238,7 @@ public class PermissionManager(Database.Database? database)
|
||||||
{
|
{
|
||||||
if (!AdminCache.ContainsKey(steamId))
|
if (!AdminCache.ContainsKey(steamId))
|
||||||
{
|
{
|
||||||
AdminCache.TryAdd(steamId, ends);
|
AdminCache.TryAdd(steamId, (ends, flags));
|
||||||
//_adminCacheTimestamps.Add(steamId, ends);
|
//_adminCacheTimestamps.Add(steamId, ends);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -400,7 +402,7 @@ public class PermissionManager(Database.Database? database)
|
||||||
.GroupBy(player => player.name) // Group by player name
|
.GroupBy(player => player.name) // Group by player name
|
||||||
.ToDictionary(
|
.ToDictionary(
|
||||||
group => group.Key, // Use the player name as the key
|
group => group.Key, // Use the player name as the key
|
||||||
group =>
|
object (group) =>
|
||||||
{
|
{
|
||||||
// Consolidate data for players with the same name
|
// Consolidate data for players with the same name
|
||||||
var consolidatedData = group.Aggregate(
|
var consolidatedData = group.Aggregate(
|
||||||
|
|
@ -432,16 +434,76 @@ public class PermissionManager(Database.Database? database)
|
||||||
return acc;
|
return acc;
|
||||||
});
|
});
|
||||||
|
|
||||||
foreach (var player in group)
|
Server.NextFrameAsync(() =>
|
||||||
{
|
{
|
||||||
SteamID.TryParse(player.identity, out var steamId);
|
var keysToRemove = new List<SteamID>();
|
||||||
if (steamId != null && !AdminCache.ContainsKey(steamId))
|
|
||||||
|
foreach (var steamId in AdminCache.Keys.ToList())
|
||||||
{
|
{
|
||||||
AdminCache.TryAdd(steamId, player.ends);
|
var data = AdminManager.GetPlayerAdminData(steamId);
|
||||||
}
|
if (data != null)
|
||||||
|
{
|
||||||
|
var flagsArray = AdminCache[steamId].Flags.ToArray();
|
||||||
|
AdminManager.RemovePlayerPermissions(steamId, flagsArray);
|
||||||
|
AdminManager.RemovePlayerFromGroup(steamId, true, flagsArray);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object)consolidatedData;
|
keysToRemove.Add(steamId);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var steamId in keysToRemove)
|
||||||
|
{
|
||||||
|
if (!AdminCache.TryRemove(steamId, out _)) continue;
|
||||||
|
|
||||||
|
var data = AdminManager.GetPlayerAdminData(steamId);
|
||||||
|
if (data == null) continue;
|
||||||
|
if (data.Flags.Count != 0 && data.Groups.Count != 0) continue;
|
||||||
|
|
||||||
|
AdminManager.ClearPlayerPermissions(steamId);
|
||||||
|
AdminManager.RemovePlayerAdminData(steamId);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var player in group)
|
||||||
|
{
|
||||||
|
if (SteamID.TryParse(player.identity, out var steamId) && steamId != null)
|
||||||
|
{
|
||||||
|
AdminCache.TryAdd(steamId, (player.ends, player.flags));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Server.NextFrameAsync(() =>
|
||||||
|
// {
|
||||||
|
// for (var index = 0; index < AdminCache.Keys.ToList().Count; index++)
|
||||||
|
// {
|
||||||
|
// var steamId = AdminCache.Keys.ToList()[index];
|
||||||
|
//
|
||||||
|
// var data = AdminManager.GetPlayerAdminData(steamId);
|
||||||
|
// if (data != null)
|
||||||
|
// {
|
||||||
|
// AdminManager.RemovePlayerPermissions(steamId, AdminCache[steamId].Flags.ToArray());
|
||||||
|
// AdminManager.RemovePlayerFromGroup(steamId, true, AdminCache[steamId].Flags.ToArray());
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// if (!AdminCache.TryRemove(steamId, out _)) continue;
|
||||||
|
//
|
||||||
|
// if (data == null) continue;
|
||||||
|
// if (data.Flags.ToList().Count != 0 && data.Groups.ToList().Count != 0)
|
||||||
|
// continue;
|
||||||
|
//
|
||||||
|
// AdminManager.ClearPlayerPermissions(steamId);
|
||||||
|
// AdminManager.RemovePlayerAdminData(steamId);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// foreach (var player in group)
|
||||||
|
// {
|
||||||
|
// SteamID.TryParse(player.identity, out var steamId);
|
||||||
|
// if (steamId == null) continue;
|
||||||
|
// AdminCache.TryAdd(steamId, (player.ends, player.flags));
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
return consolidatedData;
|
||||||
});
|
});
|
||||||
|
|
||||||
var json = JsonConvert.SerializeObject(jsonData, Formatting.Indented);
|
var json = JsonConvert.SerializeObject(jsonData, Formatting.Indented);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ using CounterStrikeSharp.API.ValveConstants.Protobuf;
|
||||||
using CS2_SimpleAdminApi;
|
using CS2_SimpleAdminApi;
|
||||||
using Dapper;
|
using Dapper;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
using ZLinq;
|
||||||
|
|
||||||
namespace CS2_SimpleAdmin.Managers;
|
namespace CS2_SimpleAdmin.Managers;
|
||||||
|
|
||||||
|
|
@ -26,10 +27,10 @@ public class PlayerManager
|
||||||
}
|
}
|
||||||
|
|
||||||
var ipAddress = player.IpAddress?.Split(":")[0];
|
var ipAddress = player.IpAddress?.Split(":")[0];
|
||||||
|
|
||||||
CS2_SimpleAdmin.PlayersInfo[player.UserId.Value] =
|
CS2_SimpleAdmin.PlayersInfo[player.UserId.Value] =
|
||||||
new PlayerInfo(player.UserId.Value, player.Slot, new SteamID(player.SteamID), player.PlayerName, ipAddress);
|
new PlayerInfo(player.UserId.Value, player.Slot, new SteamID(player.SteamID), player.PlayerName, ipAddress);
|
||||||
|
|
||||||
|
|
||||||
// if (!player.UserId.HasValue)
|
// if (!player.UserId.HasValue)
|
||||||
// {
|
// {
|
||||||
// Helper.KickPlayer(player, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_INVALIDCONNECTION);
|
// Helper.KickPlayer(player, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_INVALIDCONNECTION);
|
||||||
|
|
@ -37,31 +38,69 @@ public class PlayerManager
|
||||||
// }
|
// }
|
||||||
|
|
||||||
var userId = player.UserId.Value;
|
var userId = player.UserId.Value;
|
||||||
|
if (!CS2_SimpleAdmin.PlayersInfo.ContainsKey(userId))
|
||||||
// Check if the player's IP or SteamID is in the bannedPlayers list
|
|
||||||
if (_config.OtherSettings.BanType > 0 && CS2_SimpleAdmin.BannedPlayers.Contains(ipAddress) ||
|
|
||||||
CS2_SimpleAdmin.BannedPlayers.Contains(player.SteamID.ToString()))
|
|
||||||
{
|
{
|
||||||
// Kick the player if banned
|
Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_INVALIDCONNECTION);
|
||||||
Helper.KickPlayer(player.UserId.Value, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var steamId64 = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64;
|
||||||
|
var steamId = steamId64.ToString();
|
||||||
|
|
||||||
if (CS2_SimpleAdmin.Database == null) return;
|
if (CS2_SimpleAdmin.Database == null) return;
|
||||||
|
|
||||||
// Perform asynchronous database operations within a single method
|
// Perform asynchronous database operations within a single method
|
||||||
Task.Run(async () =>
|
Task.Run(async () =>
|
||||||
{
|
{
|
||||||
if (_config.OtherSettings.CheckMultiAccountsByIp)
|
var isBanned = CS2_SimpleAdmin.Instance.CacheManager != null && CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType switch
|
||||||
|
{
|
||||||
|
0 => CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(steamId, null),
|
||||||
|
_ => CS2_SimpleAdmin.Instance.Config.OtherSettings.CheckMultiAccountsByIp
|
||||||
|
? CS2_SimpleAdmin.Instance.CacheManager.IsPlayerOrAnyIpBanned(steamId64, ipAddress)
|
||||||
|
: CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(steamId, ipAddress)
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isBanned)
|
||||||
|
{
|
||||||
|
// Kick the player if banned
|
||||||
|
await Server.NextFrameAsync(() =>
|
||||||
|
{
|
||||||
|
if (!player.UserId.HasValue) return;
|
||||||
|
Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED);
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_config.OtherSettings.CheckMultiAccountsByIp && ipAddress != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
{
|
||||||
|
if (CS2_SimpleAdmin.Instance.CacheManager != null && CS2_SimpleAdmin.Instance.CacheManager.HasIpForPlayer(
|
||||||
|
CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64, ipAddress))
|
||||||
{
|
{
|
||||||
await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync();
|
await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync();
|
||||||
const string selectQuery = "SELECT COUNT(*) FROM `sa_players_ips` WHERE steamid = @SteamID AND address = @IPAddress;";
|
|
||||||
|
const string updateQuery = """
|
||||||
|
UPDATE `sa_players_ips`
|
||||||
|
SET used_at = CURRENT_TIMESTAMP
|
||||||
|
WHERE steamid = @SteamID AND address = @IPAddress;
|
||||||
|
""";
|
||||||
|
await connection.ExecuteAsync(updateQuery, new
|
||||||
|
{
|
||||||
|
SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64,
|
||||||
|
IPAddress = IpHelper.IpToUint(ipAddress)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync();
|
||||||
|
|
||||||
|
const string selectQuery =
|
||||||
|
"SELECT COUNT(*) FROM `sa_players_ips` WHERE steamid = @SteamID AND address = @IPAddress;";
|
||||||
var recordExists = await connection.ExecuteScalarAsync<int>(selectQuery, new
|
var recordExists = await connection.ExecuteScalarAsync<int>(selectQuery, new
|
||||||
{
|
{
|
||||||
SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64,
|
SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64,
|
||||||
IPAddress = ipAddress
|
IPAddress = IpHelper.IpToUint(ipAddress)
|
||||||
});
|
});
|
||||||
|
|
||||||
if (recordExists > 0)
|
if (recordExists > 0)
|
||||||
|
|
@ -74,7 +113,7 @@ public class PlayerManager
|
||||||
await connection.ExecuteAsync(updateQuery, new
|
await connection.ExecuteAsync(updateQuery, new
|
||||||
{
|
{
|
||||||
SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64,
|
SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64,
|
||||||
IPAddress = ipAddress
|
IPAddress = IpHelper.IpToUint(ipAddress)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -86,55 +125,31 @@ public class PlayerManager
|
||||||
await connection.ExecuteAsync(insertQuery, new
|
await connection.ExecuteAsync(insertQuery, new
|
||||||
{
|
{
|
||||||
SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64,
|
SteamID = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64,
|
||||||
IPAddress = ipAddress
|
IPAddress = IpHelper.IpToUint(ipAddress)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
CS2_SimpleAdmin._logger?.LogError(
|
CS2_SimpleAdmin._logger?.LogError(
|
||||||
$"Unable to save ip address for {CS2_SimpleAdmin.PlayersInfo[userId].Name} ({ipAddress}) {ex.Message}");
|
$"Unable to save ip address for {CS2_SimpleAdmin.PlayersInfo[userId].Name} ({ipAddress}) {ex.Message}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get all accounts associated to the player (ip address)
|
||||||
|
CS2_SimpleAdmin.PlayersInfo[userId].AccountsAssociated =
|
||||||
|
CS2_SimpleAdmin.Instance.CacheManager?.GetAccountsByIp(ipAddress).AsValueEnumerable().Select(x => (x.SteamId, x.PlayerName)).ToList() ?? [];
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!CS2_SimpleAdmin.PlayersInfo.ContainsKey(userId))
|
// var isBanned = CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType == 0
|
||||||
{
|
// ? CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(
|
||||||
await Server.NextFrameAsync(() => Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_INVALIDCONNECTION));
|
// CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64.ToString(), null)
|
||||||
}
|
// : CS2_SimpleAdmin.Instance.Config.OtherSettings.CheckMultiAccountsByIp
|
||||||
|
// ? CS2_SimpleAdmin.Instance.CacheManager.IsPlayerOrAnyIpBanned(CS2_SimpleAdmin
|
||||||
// Check if the player is banned
|
// .PlayersInfo[userId].SteamId.SteamId64)
|
||||||
var isBanned = await CS2_SimpleAdmin.Instance.BanManager.IsPlayerBanned(CS2_SimpleAdmin.PlayersInfo[userId]);
|
// : CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64.ToString(), ipAddress);
|
||||||
|
|
||||||
if (isBanned)
|
|
||||||
{
|
|
||||||
// Add player's IP and SteamID to bannedPlayers list if not already present
|
|
||||||
if (_config.OtherSettings.BanType > 0 && ipAddress != null &&
|
|
||||||
!CS2_SimpleAdmin.BannedPlayers.Contains(ipAddress))
|
|
||||||
{
|
|
||||||
CS2_SimpleAdmin.BannedPlayers.Add(ipAddress);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!CS2_SimpleAdmin.BannedPlayers.Contains(CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64.ToString()))
|
|
||||||
{
|
|
||||||
CS2_SimpleAdmin.BannedPlayers.Add(CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64.ToString());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Kick the player if banned
|
|
||||||
await Server.NextFrameAsync(() =>
|
|
||||||
{
|
|
||||||
var victim = Utilities.GetPlayerFromUserid(userId);
|
|
||||||
if (victim == null || !victim.UserId.HasValue) return;
|
|
||||||
|
|
||||||
if (CS2_SimpleAdmin.UnlockedCommands && _config.BanIDBan)
|
|
||||||
Server.ExecuteCommand($"banid 1 {userId}");
|
|
||||||
|
|
||||||
Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED);
|
|
||||||
});
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fullConnect || !fullConnect) // Temp skip
|
if (fullConnect || !fullConnect) // Temp skip
|
||||||
{
|
{
|
||||||
|
|
@ -142,8 +157,7 @@ public class PlayerManager
|
||||||
var (totalMutes, totalGags, totalSilences) =
|
var (totalMutes, totalGags, totalSilences) =
|
||||||
await CS2_SimpleAdmin.Instance.MuteManager.GetPlayerMutes(CS2_SimpleAdmin.PlayersInfo[userId]);
|
await CS2_SimpleAdmin.Instance.MuteManager.GetPlayerMutes(CS2_SimpleAdmin.PlayersInfo[userId]);
|
||||||
|
|
||||||
CS2_SimpleAdmin.PlayersInfo[userId].TotalBans =
|
CS2_SimpleAdmin.PlayersInfo[userId].TotalBans = CS2_SimpleAdmin.Instance.CacheManager?.GetPlayerBansBySteamId(CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64.ToString()).Count ?? 0;
|
||||||
await CS2_SimpleAdmin.Instance.BanManager.GetPlayerBans(CS2_SimpleAdmin.PlayersInfo[userId]);
|
|
||||||
CS2_SimpleAdmin.PlayersInfo[userId].TotalMutes = totalMutes;
|
CS2_SimpleAdmin.PlayersInfo[userId].TotalMutes = totalMutes;
|
||||||
CS2_SimpleAdmin.PlayersInfo[userId].TotalGags = totalGags;
|
CS2_SimpleAdmin.PlayersInfo[userId].TotalGags = totalGags;
|
||||||
CS2_SimpleAdmin.PlayersInfo[userId].TotalSilences = totalSilences;
|
CS2_SimpleAdmin.PlayersInfo[userId].TotalSilences = totalSilences;
|
||||||
|
|
@ -192,6 +206,8 @@ public class PlayerManager
|
||||||
|
|
||||||
if (CS2_SimpleAdmin.Instance.Config.OtherSettings.NotifyPenaltiesToAdminOnConnect && fullConnect)
|
if (CS2_SimpleAdmin.Instance.Config.OtherSettings.NotifyPenaltiesToAdminOnConnect && fullConnect)
|
||||||
{
|
{
|
||||||
|
var associatedAcccountsChunks = CS2_SimpleAdmin.PlayersInfo[userId].AccountsAssociated.ChunkBy(5).ToList();
|
||||||
|
|
||||||
await Server.NextFrameAsync(() =>
|
await Server.NextFrameAsync(() =>
|
||||||
{
|
{
|
||||||
foreach (var admin in Helper.GetValidPlayers()
|
foreach (var admin in Helper.GetValidPlayers()
|
||||||
|
|
@ -199,9 +215,8 @@ public class PlayerManager
|
||||||
AdminManager.PlayerHasPermissions(new SteamID(p.SteamID), "@css/ban")) &&
|
AdminManager.PlayerHasPermissions(new SteamID(p.SteamID), "@css/ban")) &&
|
||||||
p.Connected == PlayerConnectedState.PlayerConnected && !CS2_SimpleAdmin.AdminDisabledJoinComms.Contains(p.SteamID)))
|
p.Connected == PlayerConnectedState.PlayerConnected && !CS2_SimpleAdmin.AdminDisabledJoinComms.Contains(p.SteamID)))
|
||||||
{
|
{
|
||||||
if (CS2_SimpleAdmin._localizer != null && admin != player
|
if (CS2_SimpleAdmin._localizer != null && admin != player)
|
||||||
&& (CS2_SimpleAdmin.PlayersInfo[userId].TotalBans > 0 || CS2_SimpleAdmin.PlayersInfo[userId].TotalGags > 0 || CS2_SimpleAdmin.PlayersInfo[userId].TotalMutes > 0 || CS2_SimpleAdmin.PlayersInfo[userId].TotalSilences > 0 || CS2_SimpleAdmin.PlayersInfo[userId].TotalWarns > 0)
|
{
|
||||||
)
|
|
||||||
admin.SendLocalizedMessage(CS2_SimpleAdmin._localizer, "sa_admin_penalty_info",
|
admin.SendLocalizedMessage(CS2_SimpleAdmin._localizer, "sa_admin_penalty_info",
|
||||||
player.PlayerName,
|
player.PlayerName,
|
||||||
CS2_SimpleAdmin.PlayersInfo[userId].TotalBans,
|
CS2_SimpleAdmin.PlayersInfo[userId].TotalBans,
|
||||||
|
|
@ -210,6 +225,16 @@ public class PlayerManager
|
||||||
CS2_SimpleAdmin.PlayersInfo[userId].TotalSilences,
|
CS2_SimpleAdmin.PlayersInfo[userId].TotalSilences,
|
||||||
CS2_SimpleAdmin.PlayersInfo[userId].TotalWarns
|
CS2_SimpleAdmin.PlayersInfo[userId].TotalWarns
|
||||||
);
|
);
|
||||||
|
|
||||||
|
foreach (var chunk in associatedAcccountsChunks)
|
||||||
|
{
|
||||||
|
admin.SendLocalizedMessage(CS2_SimpleAdmin._localizer, "sa_admin_associated_accounts",
|
||||||
|
player.PlayerName,
|
||||||
|
string.Join(", ",
|
||||||
|
chunk.Select(a => $"{a.PlayerName} ({a.SteamId})"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -232,12 +257,9 @@ public class PlayerManager
|
||||||
{
|
{
|
||||||
if (CS2_SimpleAdmin.GravityPlayers.Count <= 0) return;
|
if (CS2_SimpleAdmin.GravityPlayers.Count <= 0) return;
|
||||||
|
|
||||||
foreach (var value in CS2_SimpleAdmin.GravityPlayers)
|
foreach (var value in CS2_SimpleAdmin.GravityPlayers.Where(value => value.Key is
|
||||||
|
{ IsValid: true, Connected: PlayerConnectedState.PlayerConnected } || value.Key.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE))
|
||||||
{
|
{
|
||||||
if (value.Key is not
|
|
||||||
{ IsValid: true, Connected: PlayerConnectedState.PlayerConnected, PawnIsAlive: true })
|
|
||||||
continue;
|
|
||||||
|
|
||||||
value.Key.SetGravity(value.Value);
|
value.Key.SetGravity(value.Value);
|
||||||
}
|
}
|
||||||
}, TimerFlags.REPEAT);
|
}, TimerFlags.REPEAT);
|
||||||
|
|
@ -250,79 +272,70 @@ public class PlayerManager
|
||||||
if (CS2_SimpleAdmin.Database == null)
|
if (CS2_SimpleAdmin.Database == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var players = Helper.GetValidPlayers();
|
var tempPlayers = Helper.GetValidPlayers()
|
||||||
var onlinePlayers = new List<(string? IpAddress, ulong SteamID, int? UserId, int Slot)>();
|
.Select(p => new
|
||||||
// var onlinePlayers = players
|
|
||||||
// .Where(player => player.IpAddress != null)
|
|
||||||
// .Select(player => (player.IpAddress, player.SteamID, player.UserId, player.Slot))
|
|
||||||
// .ToList();
|
|
||||||
|
|
||||||
foreach (var player in players)
|
|
||||||
{
|
{
|
||||||
if (player.IpAddress != null)
|
p.SteamID, p.IpAddress, p.UserId, p.Slot,
|
||||||
onlinePlayers.Add((player.IpAddress, player.SteamID, player.UserId, player.Slot));
|
})
|
||||||
}
|
.ToList();
|
||||||
|
|
||||||
|
_ = Task.Run(async () =>
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var expireTasks = new[]
|
var expireTasks = new Task[]
|
||||||
{
|
{
|
||||||
CS2_SimpleAdmin.Instance.BanManager.ExpireOldBans(),
|
CS2_SimpleAdmin.Instance.BanManager.ExpireOldBans(),
|
||||||
CS2_SimpleAdmin.Instance.MuteManager.ExpireOldMutes(),
|
CS2_SimpleAdmin.Instance.MuteManager.ExpireOldMutes(),
|
||||||
CS2_SimpleAdmin.Instance.WarnManager.ExpireOldWarns(),
|
CS2_SimpleAdmin.Instance.WarnManager.ExpireOldWarns(),
|
||||||
|
CS2_SimpleAdmin.Instance.CacheManager?.RefreshCacheAsync() ?? Task.CompletedTask,
|
||||||
CS2_SimpleAdmin.Instance.PermissionManager.DeleteOldAdmins()
|
CS2_SimpleAdmin.Instance.PermissionManager.DeleteOldAdmins()
|
||||||
};
|
};
|
||||||
|
|
||||||
Task.WhenAll(expireTasks).ContinueWith(t =>
|
await Task.WhenAll(expireTasks);
|
||||||
{
|
|
||||||
if (t is not { IsFaulted: true, Exception: not null }) return;
|
|
||||||
|
|
||||||
foreach (var ex in t.Exception.InnerExceptions)
|
|
||||||
{
|
|
||||||
CS2_SimpleAdmin._logger?.LogError($"Error expiring penalties: {ex.Message}");
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
CS2_SimpleAdmin._logger?.LogError("Unexpected error: {exception}", ex.Message);
|
CS2_SimpleAdmin._logger?.LogError($"Error processing players timer tasks: {ex.Message}");
|
||||||
|
|
||||||
|
if (ex is AggregateException aggregate)
|
||||||
|
{
|
||||||
|
foreach (var inner in aggregate.InnerExceptions)
|
||||||
|
{
|
||||||
|
CS2_SimpleAdmin._logger?.LogError($"Inner exception: {inner.Message}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CS2_SimpleAdmin.BannedPlayers.Clear();
|
var bannedPlayers = tempPlayers.AsValueEnumerable()
|
||||||
|
.Where(player =>
|
||||||
|
{
|
||||||
|
return CS2_SimpleAdmin.Instance.CacheManager != null && CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType switch
|
||||||
|
{
|
||||||
|
0 => CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(player.SteamID.ToString(), null),
|
||||||
|
_ =>
|
||||||
|
CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(player.SteamID.ToString(), player.IpAddress?.Split(":")[0])
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.ToList();
|
||||||
|
|
||||||
if (onlinePlayers.Count > 0)
|
foreach (var player in bannedPlayers)
|
||||||
{
|
{
|
||||||
try
|
if (player.UserId.HasValue)
|
||||||
{
|
await Server.NextFrameAsync(() => Helper.KickPlayer((int)player.UserId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED));
|
||||||
Task.Run(async () =>
|
}
|
||||||
{
|
|
||||||
await CS2_SimpleAdmin.Instance.BanManager.CheckOnlinePlayers(onlinePlayers);
|
|
||||||
|
|
||||||
|
var onlinePlayers = tempPlayers.AsValueEnumerable().Select(player => (player.SteamID, player.UserId, player.Slot)).ToList();
|
||||||
|
if (tempPlayers.Count == 0 || onlinePlayers.Count == 0) return;
|
||||||
if (_config.OtherSettings.TimeMode == 0)
|
if (_config.OtherSettings.TimeMode == 0)
|
||||||
{
|
{
|
||||||
await CS2_SimpleAdmin.Instance.MuteManager.CheckOnlineModeMutes(onlinePlayers);
|
await CS2_SimpleAdmin.Instance.MuteManager.CheckOnlineModeMutes(onlinePlayers);
|
||||||
}
|
}
|
||||||
}).ContinueWith(t =>
|
|
||||||
{
|
|
||||||
if (t is not { IsFaulted: true, Exception: not null }) return;
|
|
||||||
|
|
||||||
foreach (var ex in t.Exception.InnerExceptions)
|
|
||||||
{
|
|
||||||
CS2_SimpleAdmin._logger?.LogError($"Error checking online players: {ex.Message}");
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
}
|
|
||||||
catch (Exception ex)
|
|
||||||
{
|
|
||||||
CS2_SimpleAdmin._logger?.LogError($"Unexpected error: {ex.Message}");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (onlinePlayers.Count <= 0) return;
|
|
||||||
|
|
||||||
{
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
var players = Helper.GetValidPlayers();
|
||||||
var penalizedSlots = players
|
var penalizedSlots = players
|
||||||
.Where(player => PlayerPenaltyManager.IsSlotInPenalties(player.Slot))
|
.Where(player => PlayerPenaltyManager.IsSlotInPenalties(player.Slot))
|
||||||
.Select(player => new
|
.Select(player => new
|
||||||
|
|
@ -350,8 +363,7 @@ public class PlayerManager
|
||||||
{
|
{
|
||||||
CS2_SimpleAdmin._logger?.LogError($"Unable to remove old penalties: {ex.Message}");
|
CS2_SimpleAdmin._logger?.LogError($"Unable to remove old penalties: {ex.Message}");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.REPEAT);
|
}, TimerFlags.REPEAT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -9,9 +9,9 @@ public class ServerManager
|
||||||
{
|
{
|
||||||
private int _getIpTryCount;
|
private int _getIpTryCount;
|
||||||
|
|
||||||
public void CheckHibernationStatus()
|
public static void CheckHibernationStatus()
|
||||||
{
|
{
|
||||||
ConVar? convar = ConVar.Find("sv_hibernate_when_empty");
|
var convar = ConVar.Find("sv_hibernate_when_empty");
|
||||||
|
|
||||||
if (convar == null || !convar.GetPrimitiveValue<bool>())
|
if (convar == null || !convar.GetPrimitiveValue<bool>())
|
||||||
return;
|
return;
|
||||||
|
|
@ -96,12 +96,16 @@ public class ServerManager
|
||||||
|
|
||||||
CS2_SimpleAdmin.ServerId = serverId;
|
CS2_SimpleAdmin.ServerId = serverId;
|
||||||
|
|
||||||
|
CS2_SimpleAdmin._logger?.LogInformation("Loaded server with ip {ip}", ipAddress);
|
||||||
|
|
||||||
if (CS2_SimpleAdmin.ServerId != null)
|
if (CS2_SimpleAdmin.ServerId != null)
|
||||||
{
|
{
|
||||||
await Server.NextWorldUpdateAsync(() => CS2_SimpleAdmin.Instance.ReloadAdmins(null));
|
await Server.NextWorldUpdateAsync(() => CS2_SimpleAdmin.Instance.ReloadAdmins(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
CS2_SimpleAdmin.ServerLoaded = true;
|
CS2_SimpleAdmin.ServerLoaded = true;
|
||||||
|
if (CS2_SimpleAdmin.Instance.CacheManager != null)
|
||||||
|
await CS2_SimpleAdmin.Instance.CacheManager.InitializeCacheAsync();
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,12 @@ public static class PlayersMenu
|
||||||
|
|
||||||
public static void OpenAliveMenu(CCSPlayerController admin, string menuName, Action<CCSPlayerController, CCSPlayerController> onSelectAction, Func<CCSPlayerController, bool>? enableFilter = null)
|
public static void OpenAliveMenu(CCSPlayerController admin, string menuName, Action<CCSPlayerController, CCSPlayerController> onSelectAction, Func<CCSPlayerController, bool>? enableFilter = null)
|
||||||
{
|
{
|
||||||
OpenMenu(admin, menuName, onSelectAction, p => p.PawnIsAlive);
|
OpenMenu(admin, menuName, onSelectAction, p => p.PlayerPawn?.Value?.LifeState == (int)LifeState_t.LIFE_ALIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OpenDeadMenu(CCSPlayerController admin, string menuName, Action<CCSPlayerController?, CCSPlayerController> onSelectAction, Func<CCSPlayerController, bool>? enableFilter = null)
|
public static void OpenDeadMenu(CCSPlayerController admin, string menuName, Action<CCSPlayerController?, CCSPlayerController> onSelectAction, Func<CCSPlayerController, bool>? enableFilter = null)
|
||||||
{
|
{
|
||||||
OpenMenu(admin, menuName, onSelectAction, p => p.PawnIsAlive == false);
|
OpenMenu(admin, menuName, onSelectAction, p => p.PlayerPawn?.Value?.LifeState != (int)LifeState_t.LIFE_ALIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void OpenMenu(CCSPlayerController admin, string menuName, Action<CCSPlayerController, CCSPlayerController> onSelectAction, Func<CCSPlayerController, bool>? enableFilter = null)
|
public static void OpenMenu(CCSPlayerController admin, string menuName, Action<CCSPlayerController, CCSPlayerController> onSelectAction, Func<CCSPlayerController, bool>? enableFilter = null)
|
||||||
|
|
|
||||||
18
CS2-SimpleAdmin/Models/BanRecord.cs
Normal file
18
CS2-SimpleAdmin/Models/BanRecord.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
using System.ComponentModel.DataAnnotations.Schema;
|
||||||
|
|
||||||
|
namespace CS2_SimpleAdmin.Models;
|
||||||
|
|
||||||
|
public record BanRecord
|
||||||
|
{
|
||||||
|
[Column("id")]
|
||||||
|
public int Id { get; set; }
|
||||||
|
|
||||||
|
[Column("player_steamid")]
|
||||||
|
public string? PlayerSteamId { get; set; }
|
||||||
|
|
||||||
|
[Column("player_ip")]
|
||||||
|
public string? PlayerIp { get; set; }
|
||||||
|
|
||||||
|
[Column("status")]
|
||||||
|
public string Status { get; set; }
|
||||||
|
}
|
||||||
3
CS2-SimpleAdmin/Models/IpRecord.cs
Normal file
3
CS2-SimpleAdmin/Models/IpRecord.cs
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
namespace CS2_SimpleAdmin.Models;
|
||||||
|
|
||||||
|
public readonly record struct IpRecord(uint Ip, DateTime UsedAt, string PlayerName);
|
||||||
|
|
@ -1 +1 @@
|
||||||
1.7.5a
|
1.7.7-alpha
|
||||||
|
|
@ -32,14 +32,13 @@ public partial class CS2_SimpleAdmin
|
||||||
// Command and Server Settings
|
// Command and Server Settings
|
||||||
public static readonly bool UnlockedCommands = CoreConfig.UnlockConCommands;
|
public static readonly bool UnlockedCommands = CoreConfig.UnlockConCommands;
|
||||||
internal static string IpAddress = string.Empty;
|
internal static string IpAddress = string.Empty;
|
||||||
public static bool ServerLoaded;
|
internal static bool ServerLoaded;
|
||||||
public static int? ServerId = null;
|
internal static int? ServerId = null;
|
||||||
internal static readonly HashSet<ulong> AdminDisabledJoinComms = [];
|
internal static readonly HashSet<ulong> AdminDisabledJoinComms = [];
|
||||||
|
|
||||||
// Player Management
|
// Player Management
|
||||||
private static readonly HashSet<int> GodPlayers = [];
|
private static readonly HashSet<int> GodPlayers = [];
|
||||||
internal static readonly HashSet<int> SilentPlayers = [];
|
internal static readonly HashSet<int> SilentPlayers = [];
|
||||||
internal static readonly ConcurrentBag<string?> BannedPlayers = [];
|
|
||||||
internal static readonly Dictionary<ulong, string> RenamedPlayers = [];
|
internal static readonly Dictionary<ulong, string> RenamedPlayers = [];
|
||||||
internal static readonly ConcurrentDictionary<int, PlayerInfo> PlayersInfo = [];
|
internal static readonly ConcurrentDictionary<int, PlayerInfo> PlayersInfo = [];
|
||||||
private static readonly List<DisconnectedPlayer> DisconnectedPlayers = [];
|
private static readonly List<DisconnectedPlayer> DisconnectedPlayers = [];
|
||||||
|
|
@ -69,6 +68,7 @@ public partial class CS2_SimpleAdmin
|
||||||
internal BanManager BanManager = new(Database);
|
internal BanManager BanManager = new(Database);
|
||||||
internal MuteManager MuteManager = new(Database);
|
internal MuteManager MuteManager = new(Database);
|
||||||
internal WarnManager WarnManager = new(Database);
|
internal WarnManager WarnManager = new(Database);
|
||||||
|
internal CacheManager? CacheManager = new();
|
||||||
internal ChatManager ChatManager = new();
|
internal ChatManager ChatManager = new();
|
||||||
|
|
||||||
static string firstMessage = "";
|
static string firstMessage = "";
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
"sa_player_penalty_info": "===========================\nعقوبات اللاعبين لـ {lightred}{0}{default},\nعدد الحظر: {lightred}{1}{default}, عدد الصمت: {lightred}{2}{default}, عدد الكتم: {lightred}{3}{default}, عدد السكوت: {lightred}{4}{default}, عدد التحذيرات: {lightred}{5}{default}\nالعقوبات النشطة:\n{6}\nالتحذيرات النشطة:\n{7}\n===========================",
|
"sa_player_penalty_info": "===========================\nعقوبات اللاعبين لـ {lightred}{0}{default},\nعدد الحظر: {lightred}{1}{default}, عدد الصمت: {lightred}{2}{default}, عدد الكتم: {lightred}{3}{default}, عدد السكوت: {lightred}{4}{default}, عدد التحذيرات: {lightred}{5}{default}\nالعقوبات النشطة:\n{6}\nالتحذيرات النشطة:\n{7}\n===========================",
|
||||||
"sa_admin_penalty_info": "{grey}عقوبات اللاعبين لـ {lightred}{0}{grey}, حظر: {lightred}{1}{grey}, صمت: {lightred}{2}{grey}, كتم: {lightred}{3}{grey}, سكوت: {lightred}{4}{grey}, تحذيرات: {lightred}{5}",
|
"sa_admin_penalty_info": "{grey}عقوبات اللاعبين لـ {lightred}{0}{grey}, حظر: {lightred}{1}{grey}, صمت: {lightred}{2}{grey}, كتم: {lightred}{3}{grey}, سكوت: {lightred}{4}{grey}, تحذيرات: {lightred}{5}",
|
||||||
|
"sa_admin_associated_accounts": "{grey}الحسابات المرتبطة باللاعب {lightred}{0}{grey}: {1}",
|
||||||
"sa_player_ban_message_time": "تم حظرك لمدة {lightred}{0}{default} لمدة {lightred}{1}{default} دقيقة من قبل {lightred}{2}{default}!",
|
"sa_player_ban_message_time": "تم حظرك لمدة {lightred}{0}{default} لمدة {lightred}{1}{default} دقيقة من قبل {lightred}{2}{default}!",
|
||||||
"sa_player_ban_message_perm": "تم حظرك بشكل دائم لمدة {lightred}{0}{default} من قبل {lightred}{1}{default}!",
|
"sa_player_ban_message_perm": "تم حظرك بشكل دائم لمدة {lightred}{0}{default} من قبل {lightred}{1}{default}!",
|
||||||
"sa_player_kick_message": "تم طردك لمدة {lightred}{0}{default} من قبل {lightred}{1}{default}!",
|
"sa_player_kick_message": "تم طردك لمدة {lightred}{0}{default} من قبل {lightred}{1}{default}!",
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
"sa_player_penalty_info": "===========================\nSpielerstrafe für {lightred}{0}{default},\nAnzahl der Sperren: {lightred}{1}{default}, Anzahl der Mundtot: {lightred}{2}{default}, Anzahl der Stummschaltungen: {lightred}{3}{default}, Anzahl der Stille: {lightred}{4}{default}, Anzahl der Warnungen: {lightred}{5}{default}\nAktive Strafen:\n{6}\nAktive Warnungen:\n{7}\n===========================",
|
"sa_player_penalty_info": "===========================\nSpielerstrafe für {lightred}{0}{default},\nAnzahl der Sperren: {lightred}{1}{default}, Anzahl der Mundtot: {lightred}{2}{default}, Anzahl der Stummschaltungen: {lightred}{3}{default}, Anzahl der Stille: {lightred}{4}{default}, Anzahl der Warnungen: {lightred}{5}{default}\nAktive Strafen:\n{6}\nAktive Warnungen:\n{7}\n===========================",
|
||||||
"sa_admin_penalty_info": "{grey}Spielerstrafe für {lightred}{0}{grey}, Sperren: {lightred}{1}{grey}, Mundtot: {lightred}{2}{grey}, Stummschaltungen: {lightred}{3}{grey}, Stille: {lightred}{4}{grey}, Warnungen: {lightred}{5}",
|
"sa_admin_penalty_info": "{grey}Spielerstrafe für {lightred}{0}{grey}, Sperren: {lightred}{1}{grey}, Mundtot: {lightred}{2}{grey}, Stummschaltungen: {lightred}{3}{grey}, Stille: {lightred}{4}{grey}, Warnungen: {lightred}{5}",
|
||||||
|
"sa_admin_associated_accounts": "{grey}Verknüpfte Konten des Spielers {lightred}{0}{grey}: {1}",
|
||||||
"sa_player_ban_message_time": "Du wurdest wegen {lightred}{0}{default} für {lightred}{1}{default} Minuten von {lightred}{2}{default} gebannt!",
|
"sa_player_ban_message_time": "Du wurdest wegen {lightred}{0}{default} für {lightred}{1}{default} Minuten von {lightred}{2}{default} gebannt!",
|
||||||
"sa_player_ban_message_perm": "Du wurdest wegen {lightred}{0}{default} von {lightred}{1}{default} permanent gebannt!",
|
"sa_player_ban_message_perm": "Du wurdest wegen {lightred}{0}{default} von {lightred}{1}{default} permanent gebannt!",
|
||||||
"sa_player_kick_message": "Du wurdest wegen {lightred}{0}{default} von {lightred}{1}{default} gekickt!",
|
"sa_player_kick_message": "Du wurdest wegen {lightred}{0}{default} von {lightred}{1}{default} gekickt!",
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
"sa_player_penalty_info": "===========================\nPlayer penalties for {lightred}{0}{default},\nNumber of bans: {lightred}{1}{default}, Number of gags: {lightred}{2}{default}, Number of mutes: {lightred}{3}{default}, Number of silences: {lightred}{4}{default}, Number of warnings: {lightred}{5}{default}\nActive penalties:\n{6}\nActive warnings:\n{7}\n===========================",
|
"sa_player_penalty_info": "===========================\nPlayer penalties for {lightred}{0}{default},\nNumber of bans: {lightred}{1}{default}, Number of gags: {lightred}{2}{default}, Number of mutes: {lightred}{3}{default}, Number of silences: {lightred}{4}{default}, Number of warnings: {lightred}{5}{default}\nActive penalties:\n{6}\nActive warnings:\n{7}\n===========================",
|
||||||
"sa_admin_penalty_info": "{grey}Player penalties for {lightred}{0}{grey}, Bans: {lightred}{1}{grey}, Gags: {lightred}{2}{grey}, Mutes: {lightred}{3}{grey}, Silences: {lightred}{4}{grey}, Warns: {lightred}{5}",
|
"sa_admin_penalty_info": "{grey}Player penalties for {lightred}{0}{grey}, Bans: {lightred}{1}{grey}, Gags: {lightred}{2}{grey}, Mutes: {lightred}{3}{grey}, Silences: {lightred}{4}{grey}, Warns: {lightred}{5}",
|
||||||
|
"sa_admin_associated_accounts": "{grey}Associated accounts of player {lightred}{0}{grey}: {1}",
|
||||||
"sa_player_ban_message_time": "You have been banned for {lightred}{0}{default} for {lightred}{1}{default} minutes by {lightred}{2}{default}!",
|
"sa_player_ban_message_time": "You have been banned for {lightred}{0}{default} for {lightred}{1}{default} minutes by {lightred}{2}{default}!",
|
||||||
"sa_player_ban_message_perm": "You have been banned permanently for {lightred}{0}{default} by {lightred}{1}{default}!",
|
"sa_player_ban_message_perm": "You have been banned permanently for {lightred}{0}{default} by {lightred}{1}{default}!",
|
||||||
"sa_player_kick_message": "You have been kicked for {lightred}{0}{default} by {lightred}{1}{default}!",
|
"sa_player_kick_message": "You have been kicked for {lightred}{0}{default} by {lightred}{1}{default}!",
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
"sa_player_penalty_info": "===========================\nPenalizaciones del jugador para {lightred}{0}{default},\nNúmero de prohibiciones: {lightred}{1}{default}, Número de boqueos: {lightred}{2}{default}, Número de silenciamientos: {lightred}{3}{default}, Número de silencios: {lightred}{4}{default}, Número de advertencias: {lightred}{5}{default}\nPenalizaciones activas:\n{6}\nAdvertencias activas:\n{7}\n===========================",
|
"sa_player_penalty_info": "===========================\nPenalizaciones del jugador para {lightred}{0}{default},\nNúmero de prohibiciones: {lightred}{1}{default}, Número de boqueos: {lightred}{2}{default}, Número de silenciamientos: {lightred}{3}{default}, Número de silencios: {lightred}{4}{default}, Número de advertencias: {lightred}{5}{default}\nPenalizaciones activas:\n{6}\nAdvertencias activas:\n{7}\n===========================",
|
||||||
"sa_admin_penalty_info": "{grey}Penalizaciones del jugador para {lightred}{0}{grey}, Prohibiciones: {lightred}{1}{grey}, Boqueos: {lightred}{2}{grey}, Silenciamientos: {lightred}{3}{grey}, Silencios: {lightred}{4}{grey}, Advertencias: {lightred}{5}",
|
"sa_admin_penalty_info": "{grey}Penalizaciones del jugador para {lightred}{0}{grey}, Prohibiciones: {lightred}{1}{grey}, Boqueos: {lightred}{2}{grey}, Silenciamientos: {lightred}{3}{grey}, Silencios: {lightred}{4}{grey}, Advertencias: {lightred}{5}",
|
||||||
|
"sa_admin_associated_accounts": "{grey}Cuentas asociadas del jugador {lightred}{0}{grey}: {1}",
|
||||||
"sa_player_ban_message_time": "Has sido baneado por {lightred}{0}{default} durante {lightred}{1}{default} minutos por {lightred}{2}{default}!",
|
"sa_player_ban_message_time": "Has sido baneado por {lightred}{0}{default} durante {lightred}{1}{default} minutos por {lightred}{2}{default}!",
|
||||||
"sa_player_ban_message_perm": "Has sido baneado permanentemente por {lightred}{0}{default} por {lightred}{1}{default}!",
|
"sa_player_ban_message_perm": "Has sido baneado permanentemente por {lightred}{0}{default} por {lightred}{1}{default}!",
|
||||||
"sa_player_kick_message": "Has sido expulsado por {lightred}{0}{default} durante {lightred}{1}{default}!",
|
"sa_player_kick_message": "Has sido expulsado por {lightred}{0}{default} durante {lightred}{1}{default}!",
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
"sa_player_penalty_info": "===========================\nتنبیهات بازیکن برای {lightred}{0}{default},\nتعداد مسدودیتها: {lightred}{1}{default}, تعداد سکوتها: {lightred}{2}{default}, تعداد بیصدا کردنها: {lightred}{3}{default}, تعداد سکوتها: {lightred}{4}{default}, تعداد هشدارها: {lightred}{5}{default}\nتنبیهات فعال:\n{6}\nهشدارهای فعال:\n{7}\n===========================",
|
"sa_player_penalty_info": "===========================\nتنبیهات بازیکن برای {lightred}{0}{default},\nتعداد مسدودیتها: {lightred}{1}{default}, تعداد سکوتها: {lightred}{2}{default}, تعداد بیصدا کردنها: {lightred}{3}{default}, تعداد سکوتها: {lightred}{4}{default}, تعداد هشدارها: {lightred}{5}{default}\nتنبیهات فعال:\n{6}\nهشدارهای فعال:\n{7}\n===========================",
|
||||||
"sa_admin_penalty_info": "{grey}تنبیهات بازیکن برای {lightred}{0}{grey}, مسدودیتها: {lightred}{1}{grey}, سکوتها: {lightred}{2}{grey}, بیصدا کردنها: {lightred}{3}{grey}, سکوتها: {lightred}{4}{grey}, هشدارها: {lightred}{5}",
|
"sa_admin_penalty_info": "{grey}تنبیهات بازیکن برای {lightred}{0}{grey}, مسدودیتها: {lightred}{1}{grey}, سکوتها: {lightred}{2}{grey}, بیصدا کردنها: {lightred}{3}{grey}, سکوتها: {lightred}{4}{grey}, هشدارها: {lightred}{5}",
|
||||||
|
"sa_admin_associated_accounts": "{grey}حسابهای مرتبط با بازیکن {lightred}{0}{grey}: {1}",
|
||||||
"sa_player_ban_message_time": "شما توسط {lightred}{2}{default} برای {lightred}{1}{default} دقیقه به دلیل {lightred}{0}{default} مسدود شدهاید!",
|
"sa_player_ban_message_time": "شما توسط {lightred}{2}{default} برای {lightred}{1}{default} دقیقه به دلیل {lightred}{0}{default} مسدود شدهاید!",
|
||||||
"sa_player_ban_message_perm": "شما توسط {lightred}{1}{default} به دلیل {lightred}{0}{default} برای همیشه مسدود شدهاید!",
|
"sa_player_ban_message_perm": "شما توسط {lightred}{1}{default} به دلیل {lightred}{0}{default} برای همیشه مسدود شدهاید!",
|
||||||
"sa_player_kick_message": "شما توسط {lightred}{1}{default} به دلیل {lightred}{0}{default} اخراج شدهاید!",
|
"sa_player_kick_message": "شما توسط {lightred}{1}{default} به دلیل {lightred}{0}{default} اخراج شدهاید!",
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
"sa_player_penalty_info": "===========================\nPénalités du joueur pour {lightred}{0}{default},\nNombre de bannissements: {lightred}{1}{default}, Nombre de gag: {lightred}{2}{default}, Nombre de mutes: {lightred}{3}{default}, Nombre de silences: {lightred}{4}{default}, Nombre d’avertissements: {lightred}{5}{default}\nPénalités actives:\n{6}\nAvertissements actifs:\n{7}\n===========================",
|
"sa_player_penalty_info": "===========================\nPénalités du joueur pour {lightred}{0}{default},\nNombre de bannissements: {lightred}{1}{default}, Nombre de gag: {lightred}{2}{default}, Nombre de mutes: {lightred}{3}{default}, Nombre de silences: {lightred}{4}{default}, Nombre d’avertissements: {lightred}{5}{default}\nPénalités actives:\n{6}\nAvertissements actifs:\n{7}\n===========================",
|
||||||
"sa_admin_penalty_info": "{grey}Pénalités du joueur pour {lightred}{0}{grey}, Bannissements: {lightred}{1}{grey}, Gags: {lightred}{2}{grey}, Mutes: {lightred}{3}{grey}, Silences: {lightred}{4}{grey}, Avertissements: {lightred}{5}",
|
"sa_admin_penalty_info": "{grey}Pénalités du joueur pour {lightred}{0}{grey}, Bannissements: {lightred}{1}{grey}, Gags: {lightred}{2}{grey}, Mutes: {lightred}{3}{grey}, Silences: {lightred}{4}{grey}, Avertissements: {lightred}{5}",
|
||||||
|
"sa_admin_associated_accounts": "{grey}Comptes associés du joueur {lightred}{0}{grey} : {1}",
|
||||||
"sa_player_ban_message_time": "Vous avez été banni pour {lightred}{0}{default} pendant {lightred}{1}{default} minutes par {lightred}{2}{default}!",
|
"sa_player_ban_message_time": "Vous avez été banni pour {lightred}{0}{default} pendant {lightred}{1}{default} minutes par {lightred}{2}{default}!",
|
||||||
"sa_player_ban_message_perm": "Vous avez été banni définitivement pour {lightred}{0}{default} par {lightred}{1}{default}!",
|
"sa_player_ban_message_perm": "Vous avez été banni définitivement pour {lightred}{0}{default} par {lightred}{1}{default}!",
|
||||||
"sa_player_kick_message": "Vous avez été expulsé pour {lightred}{0}{default} par {lightred}{1}{default}!",
|
"sa_player_kick_message": "Vous avez été expulsé pour {lightred}{0}{default} par {lightred}{1}{default}!",
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
"sa_player_penalty_info": "===========================\nSpēlētāja sods priekš {lightred}{0}{default},\nAizliegumu skaits: {lightred}{1}{default}, Klusumu skaits: {lightred}{2}{default}, Izslēgšanas skaits: {lightred}{3}{default}, Klusēšanas skaits: {lightred}{4}{default}, Brīdinājumu skaits: {lightred}{5}{default}\nAktīvie sodi:\n{6}\nAktīvie brīdinājumi:\n{7}\n===========================",
|
"sa_player_penalty_info": "===========================\nSpēlētāja sods priekš {lightred}{0}{default},\nAizliegumu skaits: {lightred}{1}{default}, Klusumu skaits: {lightred}{2}{default}, Izslēgšanas skaits: {lightred}{3}{default}, Klusēšanas skaits: {lightred}{4}{default}, Brīdinājumu skaits: {lightred}{5}{default}\nAktīvie sodi:\n{6}\nAktīvie brīdinājumi:\n{7}\n===========================",
|
||||||
"sa_admin_penalty_info": "{grey}Spēlētāja sods priekš {lightred}{0}{grey}, Aizliegumi: {lightred}{1}{grey}, Klusumi: {lightred}{2}{grey}, Izslēgšana: {lightred}{3}{grey}, Klusēšana: {lightred}{4}{grey}, Brīdinājumi: {lightred}{5}",
|
"sa_admin_penalty_info": "{grey}Spēlētāja sods priekš {lightred}{0}{grey}, Aizliegumi: {lightred}{1}{grey}, Klusumi: {lightred}{2}{grey}, Izslēgšana: {lightred}{3}{grey}, Klusēšana: {lightred}{4}{grey}, Brīdinājumi: {lightred}{5}",
|
||||||
|
"sa_admin_associated_accounts": "{grey}Spēlētāja {lightred}{0}{grey} saistītie konti: {1}",
|
||||||
"sa_player_ban_message_time": "Tu esi nobanots uz {lightred}{0}{default} uz {lightred}{1}{default} minūtēm, iemesls: {lightred}{2}{default}!",
|
"sa_player_ban_message_time": "Tu esi nobanots uz {lightred}{0}{default} uz {lightred}{1}{default} minūtēm, iemesls: {lightred}{2}{default}!",
|
||||||
"sa_player_ban_message_perm": "Tevis bans ir uz mūžu, iemesls: {lightred}{0}{default}, Admins: {lightred}{1}{default}!",
|
"sa_player_ban_message_perm": "Tevis bans ir uz mūžu, iemesls: {lightred}{0}{default}, Admins: {lightred}{1}{default}!",
|
||||||
"sa_player_kick_message": "Tu esi izmests, iemesls: {lightred}{0}{default}, Admins: {lightred}{1}{default}!",
|
"sa_player_kick_message": "Tu esi izmests, iemesls: {lightred}{0}{default}, Admins: {lightred}{1}{default}!",
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
"sa_player_penalty_info": "===========================\nBlokady gracza {lightred}{0}{default},\nIlość banów: {lightred}{1}{default}, Ilość zakneblowań: {lightred}{2}{default}, Ilość wyciszeń: {lightred}{3}{default}, Ilość uciszeń: {lightred}{4}{default}Ilość ostrzeżeń: {lightred}{5}{default}\nAktywne blokady:\n{6}\nAktywne ostrzeżenia:\n{7}\n===========================",
|
"sa_player_penalty_info": "===========================\nBlokady gracza {lightred}{0}{default},\nIlość banów: {lightred}{1}{default}, Ilość zakneblowań: {lightred}{2}{default}, Ilość wyciszeń: {lightred}{3}{default}, Ilość uciszeń: {lightred}{4}{default}Ilość ostrzeżeń: {lightred}{5}{default}\nAktywne blokady:\n{6}\nAktywne ostrzeżenia:\n{7}\n===========================",
|
||||||
"sa_admin_penalty_info": "{grey}Blokady gracza {lightred}{0}{grey} - bany: {lightred}{1}{grey}, zakneblowania: {lightred}{2}{grey}, wyciszenia: {lightred}{3}{grey}, uciszenia: {lightred}{4}{grey}, ostrzeżenia: {lightred}{5}",
|
"sa_admin_penalty_info": "{grey}Blokady gracza {lightred}{0}{grey} - bany: {lightred}{1}{grey}, zakneblowania: {lightred}{2}{grey}, wyciszenia: {lightred}{3}{grey}, uciszenia: {lightred}{4}{grey}, ostrzeżenia: {lightred}{5}",
|
||||||
|
"sa_admin_associated_accounts": "{grey}Powiązane konta gracza {lightred}{0}{grey}: {1}",
|
||||||
"sa_player_ban_message_time": "Zostałeś zbanowany za {lightred}{0}{default} na {lightred}{1}{default} minut przez {lightred}{2}{default}!",
|
"sa_player_ban_message_time": "Zostałeś zbanowany za {lightred}{0}{default} na {lightred}{1}{default} minut przez {lightred}{2}{default}!",
|
||||||
"sa_player_ban_message_perm": "Zostałeś zbanowany na zawsze za {lightred}{0}{default} przez {lightred}{1}{default}!",
|
"sa_player_ban_message_perm": "Zostałeś zbanowany na zawsze za {lightred}{0}{default} przez {lightred}{1}{default}!",
|
||||||
"sa_player_kick_message": "Zostałeś wyrzucony za {lightred}{0}{default} przez {lightred}{1}{default}!",
|
"sa_player_kick_message": "Zostałeś wyrzucony za {lightred}{0}{default} przez {lightred}{1}{default}!",
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
"sa_player_penalty_info": "===========================\nPenalidades do jogador para {lightred}{0}{default},\nNúmero de banimentos: {lightred}{1}{default}, Número de gags: {lightred}{2}{default}, Número de mutes: {lightred}{3}{default}, Número de silêncios: {lightred}{4}{default}, Número de avisos: {lightred}{5}{default}\nPenalidades ativas:\n{6}\nAvisos ativos:\n{7}\n===========================",
|
"sa_player_penalty_info": "===========================\nPenalidades do jogador para {lightred}{0}{default},\nNúmero de banimentos: {lightred}{1}{default}, Número de gags: {lightred}{2}{default}, Número de mutes: {lightred}{3}{default}, Número de silêncios: {lightred}{4}{default}, Número de avisos: {lightred}{5}{default}\nPenalidades ativas:\n{6}\nAvisos ativos:\n{7}\n===========================",
|
||||||
"sa_admin_penalty_info": "{grey}Penalidades do jogador para {lightred}{0}{grey}, Banimentos: {lightred}{1}{grey}, Gags: {lightred}{2}{grey}, Mutes: {lightred}{3}{grey}, Silêncios: {lightred}{4}{grey}, Avisos: {lightred}{5}",
|
"sa_admin_penalty_info": "{grey}Penalidades do jogador para {lightred}{0}{grey}, Banimentos: {lightred}{1}{grey}, Gags: {lightred}{2}{grey}, Mutes: {lightred}{3}{grey}, Silêncios: {lightred}{4}{grey}, Avisos: {lightred}{5}",
|
||||||
|
"sa_admin_associated_accounts": "{grey}Contas associadas do jogador {lightred}{0}{grey}: {1}",
|
||||||
"sa_player_ban_message_time": "Você foi banido por {lightred}{0}{default} por {lightred}{1}{default} minutos por {lightred}{2}{default}!",
|
"sa_player_ban_message_time": "Você foi banido por {lightred}{0}{default} por {lightred}{1}{default} minutos por {lightred}{2}{default}!",
|
||||||
"sa_player_ban_message_perm": "Você foi banido permanentemente por {lightred}{0}{default} por {lightred}{1}{default}!",
|
"sa_player_ban_message_perm": "Você foi banido permanentemente por {lightred}{0}{default} por {lightred}{1}{default}!",
|
||||||
"sa_player_kick_message": "Você foi expulso por {lightred}{0}{default} por {lightred}{1}{default}!",
|
"sa_player_kick_message": "Você foi expulso por {lightred}{0}{default} por {lightred}{1}{default}!",
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
"sa_player_penalty_info": "===========================\nPenalidades do jogador para {lightred}{0}{default},\nNúmero de banimentos: {lightred}{1}{default}, Número de gags: {lightred}{2}{default}, Número de mutes: {lightred}{3}{default}, Número de silêncios: {lightred}{4}{default}, Número de avisos: {lightred}{5}{default}\nPenalidades ativas:\n{6}\nAvisos ativos:\n{7}\n===========================",
|
"sa_player_penalty_info": "===========================\nPenalidades do jogador para {lightred}{0}{default},\nNúmero de banimentos: {lightred}{1}{default}, Número de gags: {lightred}{2}{default}, Número de mutes: {lightred}{3}{default}, Número de silêncios: {lightred}{4}{default}, Número de avisos: {lightred}{5}{default}\nPenalidades ativas:\n{6}\nAvisos ativos:\n{7}\n===========================",
|
||||||
"sa_admin_penalty_info": "{grey}Penalidades do jogador para {lightred}{0}{grey}, Banimentos: {lightred}{1}{grey}, Gags: {lightred}{2}{grey}, Mutes: {lightred}{3}{grey}, Silêncios: {lightred}{4}{grey}, Avisos: {lightred}{5}",
|
"sa_admin_penalty_info": "{grey}Penalidades do jogador para {lightred}{0}{grey}, Banimentos: {lightred}{1}{grey}, Gags: {lightred}{2}{grey}, Mutes: {lightred}{3}{grey}, Silêncios: {lightred}{4}{grey}, Avisos: {lightred}{5}",
|
||||||
|
"sa_admin_associated_accounts": "{grey}Contas associadas do jogador {lightred}{0}{grey}: {1}",
|
||||||
"sa_player_ban_message_time": "Foste banido pelo administrador {lightred}{0}{default} durante {lightred}{1}{default} minutos. Motivo: {lightred}{2}{default}!",
|
"sa_player_ban_message_time": "Foste banido pelo administrador {lightred}{0}{default} durante {lightred}{1}{default} minutos. Motivo: {lightred}{2}{default}!",
|
||||||
"sa_player_ban_message_perm": "Foste banido permanentemente pelo administrador {lightred}{0}{default}. Motivo: {lightred}{1}{default}!",
|
"sa_player_ban_message_perm": "Foste banido permanentemente pelo administrador {lightred}{0}{default}. Motivo: {lightred}{1}{default}!",
|
||||||
"sa_player_kick_message": "Foste expulso pelo administrador {lightred}{0}{default}. Motivo: {lightred}{1}{default}!",
|
"sa_player_kick_message": "Foste expulso pelo administrador {lightred}{0}{default}. Motivo: {lightred}{1}{default}!",
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
"sa_player_penalty_info": "===========================\nШтрафы игрока для {lightred}{0}{default},\nКоличество банов: {lightred}{1}{default}, Количество гэгов: {lightred}{2}{default}, Количество мутов: {lightred}{3}{default}, Количество тишин: {lightred}{4}{default}, Количество предупреждений: {lightred}{5}{default}\nАктивные штрафы:\n{6}\nАктивные предупреждения:\n{7}\n===========================",
|
"sa_player_penalty_info": "===========================\nШтрафы игрока для {lightred}{0}{default},\nКоличество банов: {lightred}{1}{default}, Количество гэгов: {lightred}{2}{default}, Количество мутов: {lightred}{3}{default}, Количество тишин: {lightred}{4}{default}, Количество предупреждений: {lightred}{5}{default}\nАктивные штрафы:\n{6}\nАктивные предупреждения:\n{7}\n===========================",
|
||||||
"sa_admin_penalty_info": "{grey}Штрафы игрока для {lightred}{0}{grey}, Баны: {lightred}{1}{grey}, Гэги: {lightred}{2}{grey}, Муты: {lightred}{3}{grey}, Тишины: {lightred}{4}{grey}, Предупреждения: {lightred}{5}",
|
"sa_admin_penalty_info": "{grey}Штрафы игрока для {lightred}{0}{grey}, Баны: {lightred}{1}{grey}, Гэги: {lightred}{2}{grey}, Муты: {lightred}{3}{grey}, Тишины: {lightred}{4}{grey}, Предупреждения: {lightred}{5}",
|
||||||
|
"sa_admin_associated_accounts": "{grey}Связанные аккаунты игрока {lightred}{0}{grey}: {1}",
|
||||||
"sa_player_ban_message_time": "Вы были забанены по причине {lightred}{0}{default} на {lightred}{1}{default} минут(ы) администратором {lightred}{2}{default}!",
|
"sa_player_ban_message_time": "Вы были забанены по причине {lightred}{0}{default} на {lightred}{1}{default} минут(ы) администратором {lightred}{2}{default}!",
|
||||||
"sa_player_ban_message_perm": "Вас забанили навсегда по причине {lightred}{0}{default} администратором {lightred}{1}{default}!",
|
"sa_player_ban_message_perm": "Вас забанили навсегда по причине {lightred}{0}{default} администратором {lightred}{1}{default}!",
|
||||||
"sa_player_kick_message": "Вы были выгнаны {lightred}{0}{default} администратором {lightred}{1}{default}!",
|
"sa_player_kick_message": "Вы были выгнаны {lightred}{0}{default} администратором {lightred}{1}{default}!",
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@
|
||||||
|
|
||||||
"sa_player_penalty_info": "===========================\nOyuncunun cezaları {lightred}{0}{default} için,\nBan sayısı: {lightred}{1}{default}, Gag sayısı: {lightred}{2}{default}, Mute sayısı: {lightred}{3}{default}, Sessizlik sayısı: {lightred}{4}{default}, Uyarı sayısı: {lightred}{5}{default}\nAktif cezalar:\n{6}\nAktif uyarılar:\n{7}\n===========================",
|
"sa_player_penalty_info": "===========================\nOyuncunun cezaları {lightred}{0}{default} için,\nBan sayısı: {lightred}{1}{default}, Gag sayısı: {lightred}{2}{default}, Mute sayısı: {lightred}{3}{default}, Sessizlik sayısı: {lightred}{4}{default}, Uyarı sayısı: {lightred}{5}{default}\nAktif cezalar:\n{6}\nAktif uyarılar:\n{7}\n===========================",
|
||||||
"sa_admin_penalty_info": "{grey}Oyuncunun cezaları {lightred}{0}{grey}, Banlar: {lightred}{1}{grey}, Gaglar: {lightred}{2}{grey}, Mute'lar: {lightred}{3}{grey}, Sessizlikler: {lightred}{4}{grey}, Uyarılar: {lightred}{5}",
|
"sa_admin_penalty_info": "{grey}Oyuncunun cezaları {lightred}{0}{grey}, Banlar: {lightred}{1}{grey}, Gaglar: {lightred}{2}{grey}, Mute'lar: {lightred}{3}{grey}, Sessizlikler: {lightred}{4}{grey}, Uyarılar: {lightred}{5}",
|
||||||
|
"sa_admin_associated_accounts": "{grey}{lightred}{0}{grey} oyuncusunun bağlı hesapları: {1}",
|
||||||
"sa_player_ban_message_time": "Senaryo nedeniyle {lightred}{0}{default} dakika boyunca {lightred}{1}{default} tarafından yasaklandınız!",
|
"sa_player_ban_message_time": "Senaryo nedeniyle {lightred}{0}{default} dakika boyunca {lightred}{1}{default} tarafından yasaklandınız!",
|
||||||
"sa_player_ban_message_perm": "Senaryo nedeniyle kalıcı olarak {lightred}{0}{default} tarafından yasaklandınız!",
|
"sa_player_ban_message_perm": "Senaryo nedeniyle kalıcı olarak {lightred}{0}{default} tarafından yasaklandınız!",
|
||||||
"sa_player_kick_message": "Senaryo nedeniyle {lightred}{0}{default} tarafından atıldınız!",
|
"sa_player_kick_message": "Senaryo nedeniyle {lightred}{0}{default} tarafından atıldınız!",
|
||||||
|
|
|
||||||
|
|
@ -76,6 +76,7 @@
|
||||||
|
|
||||||
"sa_player_penalty_info": "===========================\n玩家 {lightred}{0}{default} 的处罚信息,\n禁止次数: {lightred}{1}{default}, 禁言次数: {lightred}{2}{default}, 静音次数: {lightred}{3}{default}, 沉默次数: {lightred}{4}{default}, 警告次数: {lightred}{5}{default}\n活跃的处罚:\n{6}\n活跃的警告:\n{7}\n===========================",
|
"sa_player_penalty_info": "===========================\n玩家 {lightred}{0}{default} 的处罚信息,\n禁止次数: {lightred}{1}{default}, 禁言次数: {lightred}{2}{default}, 静音次数: {lightred}{3}{default}, 沉默次数: {lightred}{4}{default}, 警告次数: {lightred}{5}{default}\n活跃的处罚:\n{6}\n活跃的警告:\n{7}\n===========================",
|
||||||
"sa_admin_penalty_info": "{grey}玩家 {lightred}{0}{grey} 的处罚信息, 禁止: {lightred}{1}{grey}, 禁言: {lightred}{2}{grey}, 静音: {lightred}{3}{grey}, 沉默: {lightred}{4}{grey}, 警告: {lightred}{5}",
|
"sa_admin_penalty_info": "{grey}玩家 {lightred}{0}{grey} 的处罚信息, 禁止: {lightred}{1}{grey}, 禁言: {lightred}{2}{grey}, 静音: {lightred}{3}{grey}, 沉默: {lightred}{4}{grey}, 警告: {lightred}{5}",
|
||||||
|
"sa_admin_associated_accounts": "{grey}玩家 {lightred}{0}{grey} 的关联账户:{1}",
|
||||||
"sa_player_ban_message_time": "您已被 {lightred}{0}{default} 因 {lightred}{2}{default} 禁止 {lightred}{1}{default} 分钟!",
|
"sa_player_ban_message_time": "您已被 {lightred}{0}{default} 因 {lightred}{2}{default} 禁止 {lightred}{1}{default} 分钟!",
|
||||||
"sa_player_ban_message_perm": "您已被 {lightred}{0}{default} 因 {lightred}{1}{default} 永久禁止!",
|
"sa_player_ban_message_perm": "您已被 {lightred}{0}{default} 因 {lightred}{1}{default} 永久禁止!",
|
||||||
"sa_player_kick_message": "您已被 {lightred}{0}{default} 因 {lightred}{1}{default} 踢出!",
|
"sa_player_kick_message": "您已被 {lightred}{0}{default} 因 {lightred}{1}{default} 踢出!",
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.305" />
|
<PackageReference Include="CounterStrikeSharp.API" Version="1.0.318" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ public class PlayerInfo(
|
||||||
public int TotalSilences { get; set; } = totalSilences;
|
public int TotalSilences { get; set; } = totalSilences;
|
||||||
public int TotalWarns { get; set; } = totalWarns;
|
public int TotalWarns { get; set; } = totalWarns;
|
||||||
public bool WaitingForKick { get; set; } = false;
|
public bool WaitingForKick { get; set; } = false;
|
||||||
|
public List<(ulong SteamId, string PlayerName)> AccountsAssociated { get; set; } = [];
|
||||||
public DiePosition? DiePosition { get; set; }
|
public DiePosition? DiePosition { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue