1.7.7-alpha-connection-fix

- Fixed lag when player connecting
- Added command to force refresh ban cache (css_reloadbans)
This commit is contained in:
Dawid Bepierszcz
2025-05-21 13:11:01 +02:00
parent 676a18d9b4
commit f654d6b085
5 changed files with 64 additions and 45 deletions

View File

@@ -40,10 +40,10 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
var playerManager = new PlayerManager(); var playerManager = new PlayerManager();
Parallel.ForEach(Helper.GetValidPlayers(), 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"));

View File

@@ -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"] } },

View File

@@ -386,6 +386,16 @@ public partial class CS2_SimpleAdmin
command.ReplyToCommand("Reloaded sql admins and groups"); command.ReplyToCommand("Reloaded sql admins and groups");
} }
[CommandHelper(whoCanExecute: CommandUsage.CLIENT_AND_SERVER)]
[RequiresPermissions("@css/root")]
public void OnRelBans(CCSPlayerController? caller, CommandInfo command)
{
if (Database == null) return;
_ = Instance.CacheManager.ForceReInitializeCacheAsync();
command.ReplyToCommand("Reloaded bans");
}
public void ReloadAdmins(CCSPlayerController? caller) public void ReloadAdmins(CCSPlayerController? caller)
{ {

View File

@@ -1,7 +1,6 @@
using System.Collections.Concurrent; using System.Collections.Concurrent;
using CS2_SimpleAdmin.Models; using CS2_SimpleAdmin.Models;
using Dapper; using Dapper;
using Microsoft.Extensions.Logging;
using ZLinq; using ZLinq;
namespace CS2_SimpleAdmin.Managers; namespace CS2_SimpleAdmin.Managers;
@@ -14,16 +13,15 @@ internal class CacheManager
private DateTime _lastUpdateTime = DateTime.MinValue; private DateTime _lastUpdateTime = DateTime.MinValue;
private bool _isInitialized; private bool _isInitialized;
public async Task InitializeCacheAsync() public async Task InitializeCacheAsync()
{ {
if (CS2_SimpleAdmin.Database == null) return; if (CS2_SimpleAdmin.Database == null) return;
if (!CS2_SimpleAdmin.ServerLoaded) if (!CS2_SimpleAdmin.ServerLoaded) return;
return;
if (_isInitialized) return; if (_isInitialized) return;
_cachedIgnoredIps = [..CS2_SimpleAdmin.Instance.Config.OtherSettings.IgnoredIps]; _cachedIgnoredIps = [..CS2_SimpleAdmin.Instance.Config.OtherSettings.IgnoredIps];
try try
{ {
await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync(); await using var connection = await CS2_SimpleAdmin.Database.GetConnectionAsync();
@@ -44,21 +42,22 @@ internal class CacheManager
status AS Status, status AS Status,
updated_at AS UpdatedAt updated_at AS UpdatedAt
FROM sa_bans FROM sa_bans
"""); """);
var ipHistory = await connection.QueryAsync<(ulong steamid, string? name, string address, DateTime used_at)>( var ipHistory =
"SELECT steamid, name, address, used_at FROM sa_players_ips ORDER BY used_at DESC"); await connection.QueryAsync<(ulong steamid, string? name, string address, DateTime used_at)>(
"SELECT steamid, name, address, used_at FROM sa_players_ips ORDER BY used_at DESC");
foreach (var ban in bans) foreach (var ban in bans)
{ {
_banCache.TryAdd(ban.Id, ban); _banCache.TryAdd(ban.Id, ban);
} }
foreach (var group in ipHistory.GroupBy(x => x.steamid)) foreach (var group in ipHistory.GroupBy(x => x.steamid))
{ {
var ips = new HashSet<string>(group.Select(x => x.address)); var ips = new HashSet<string>(group.Select(x => x.address));
var lastUsed = group.Max(x => x.used_at); var lastUsed = group.Max(x => x.used_at);
var playerName = group.FirstOrDefault(x => !string.IsNullOrEmpty(x.name)).name var playerName = group.FirstOrDefault(x => !string.IsNullOrEmpty(x.name)).name
?? CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown"; ?? CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown";
_playerIpsCache[group.Key] = (ips, lastUsed, playerName); _playerIpsCache[group.Key] = (ips, lastUsed, playerName);
@@ -72,6 +71,18 @@ internal class CacheManager
Console.WriteLine(e.ToString()); 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() public async Task RefreshCacheAsync()
{ {
@@ -84,10 +95,9 @@ internal class CacheManager
var updatedBans = (await connection.QueryAsync<BanRecord>( var updatedBans = (await connection.QueryAsync<BanRecord>(
"SELECT * FROM `sa_bans` WHERE updated_at > @lastUpdate OR created > @lastUpdate ORDER BY updated_at DESC", "SELECT * FROM `sa_bans` WHERE updated_at > @lastUpdate OR created > @lastUpdate ORDER BY updated_at DESC",
new { lastUpdate = _lastUpdateTime } new { lastUpdate = _lastUpdateTime }
)).ToList(); )).ToList().AsValueEnumerable();
var ipHistory = (await connection.QueryAsync<(ulong steamid, string? name, string address, DateTime used_at)>(
var ipHistory = await connection.QueryAsync<(ulong steamid, string? name, string address, DateTime used_at)>( "SELECT steamid, name, address, used_at FROM sa_players_ips ORDER BY used_at DESC LIMIT 500")).ToList();
"SELECT steamid, name, address, used_at FROM sa_players_ips ORDER BY used_at DESC");
// foreach (var group in ipHistory.GroupBy(x => x.steamid)) // foreach (var group in ipHistory.GroupBy(x => x.steamid))
// { // {
@@ -95,13 +105,12 @@ internal class CacheManager
// var lastUsed = group.Max(x => x.used_at); // var lastUsed = group.Max(x => x.used_at);
// _playerIpsCache[group.Key] = (ips, lastUsed); // _playerIpsCache[group.Key] = (ips, lastUsed);
// } // }
var groupedData = ipHistory var groupedData = ipHistory.AsValueEnumerable()
.GroupBy(x => x.steamid) .GroupBy(x => x.steamid)
.AsParallel()
.ToList(); .ToList();
Parallel.ForEach(groupedData, group => groupedData.ForEach(group =>
{ {
var ips = new HashSet<string>( var ips = new HashSet<string>(
group.Select(x => x.address), group.Select(x => x.address),
@@ -132,7 +141,7 @@ internal class CacheManager
}); });
}); });
if (updatedBans.Count == 0) if (updatedBans.Count() == 0)
return; return;
foreach (var ban in updatedBans) foreach (var ban in updatedBans)
@@ -199,5 +208,4 @@ internal class CacheManager
return _playerIpsCache.TryGetValue(steamId, out var ipList) return _playerIpsCache.TryGetValue(steamId, out var ipList)
&& ipList.ips.Contains(ipAddress); && ipList.ips.Contains(ipAddress);
} }
} }

View File

@@ -46,33 +46,32 @@ public class PlayerManager
var steamId64 = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64; var steamId64 = CS2_SimpleAdmin.PlayersInfo[userId].SteamId.SteamId64;
var steamId = steamId64.ToString(); var steamId = steamId64.ToString();
var isBanned = CS2_SimpleAdmin.Instance.Config.OtherSettings.BanType switch
{
0 => // SteamID only check
CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(steamId, null),
_ => CS2_SimpleAdmin.Instance.Config.OtherSettings.CheckMultiAccountsByIp // SteamID and IP address check
? CS2_SimpleAdmin.Instance.CacheManager.IsPlayerOrAnyIpBanned(steamId64) // All associated IP addresses
: CS2_SimpleAdmin.Instance.CacheManager.IsPlayerBanned(steamId, ipAddress) // Only current IP address
};
if (isBanned)
{
// Kick the player if banned
Server.NextFrame(() =>
{
if (!player.UserId.HasValue) return;
Helper.KickPlayer(userId, NetworkDisconnectionReason.NETWORK_DISCONNECT_REJECT_BANNED);
});
return;
}
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 () =>
{ {
var isBanned = 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)
: 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) if (_config.OtherSettings.CheckMultiAccountsByIp && ipAddress != null)
{ {
try try