- Groups support now NULL value as `server_id` (global group)
- Added json output for `css_players`  (Panel request)
- AdminSQLManager Refactor
This commit is contained in:
Dawid Bepierszcz
2024-05-01 22:46:04 +02:00
parent ebf9e06bcd
commit c25d3c4bda
7 changed files with 103 additions and 111 deletions

3
.gitignore vendored
View File

@@ -2,4 +2,5 @@ bin/
obj/ obj/
.vs/ .vs/
.git .git
.vscode/ .vscode/
.idea/

View File

@@ -22,7 +22,6 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
private static readonly ConcurrentBag<int> SilentPlayers = []; private static readonly ConcurrentBag<int> SilentPlayers = [];
private static readonly ConcurrentBag<string> BannedPlayers = []; private static readonly ConcurrentBag<string> BannedPlayers = [];
private static bool _tagsDetected; private static bool _tagsDetected;
private static bool _adminsLoaded;
public static bool VoteInProgress = false; public static bool VoteInProgress = false;
public static int? ServerId = null; public static int? ServerId = null;
@@ -38,7 +37,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.4.3a"; public override string ModuleVersion => "1.4.3b";
public CS2_SimpleAdminConfig Config { get; set; } = new(); public CS2_SimpleAdminConfig Config { get; set; } = new();
@@ -58,7 +57,6 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
public void OnConfigParsed(CS2_SimpleAdminConfig config) public void OnConfigParsed(CS2_SimpleAdminConfig config)
{ {
if (config.DatabaseHost.Length < 1 || config.DatabaseName.Length < 1 || config.DatabaseUser.Length < 1) if (config.DatabaseHost.Length < 1 || config.DatabaseName.Length < 1 || config.DatabaseUser.Length < 1)
{ {
throw new Exception("[CS2-SimpleAdmin] You need to setup Database credentials in config!"); throw new Exception("[CS2-SimpleAdmin] You need to setup Database credentials in config!");
@@ -66,7 +64,6 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
Instance = this; Instance = this;
_logger = Logger; _logger = Logger;
MySqlConnectionStringBuilder builder = new() MySqlConnectionStringBuilder builder = new()
{ {
@@ -92,38 +89,6 @@ public partial class CS2_SimpleAdmin : BasePlugin, IPluginConfig<CS2_SimpleAdmin
Task.Run(() => _database.DatabaseMigration()); Task.Run(() => _database.DatabaseMigration());
/*
Task.Run(async () =>
{
try
{
using MySqlConnection connection = await _database.GetConnectionAsync();
using MySqlTransaction transaction = await connection.BeginTransactionAsync();
try
{
string sqlFilePath = ModuleDirectory + "/Database/database_setup.sql";
string sql = await File.ReadAllTextAsync(sqlFilePath);
await connection.QueryAsync(sql, transaction: transaction);
await transaction.CommitAsync();
Console.WriteLine("[CS2-SimpleAdmin] Connected to database!");
}
catch (Exception)
{
await transaction.RollbackAsync();
throw;
}
}
catch (Exception ex)
{
Logger.LogError($"Unable to connect to the database: {ex.Message}");
throw;
}
});
*/
Config = config; Config = config;
Helper.UpdateConfig(config); Helper.UpdateConfig(config);

View File

@@ -10,6 +10,7 @@ using CounterStrikeSharp.API.Modules.Utils;
using CS2_SimpleAdmin.Menus; using CS2_SimpleAdmin.Menus;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using System.Text; using System.Text;
using Newtonsoft.Json;
namespace CS2_SimpleAdmin namespace CS2_SimpleAdmin
{ {
@@ -127,7 +128,7 @@ namespace CS2_SimpleAdmin
public static void AddAdmin(CCSPlayerController? caller, string steamid, string name, string flags, int immunity, int time = 0, bool globalAdmin = false, CommandInfo? command = null) public static void AddAdmin(CCSPlayerController? caller, string steamid, string name, string flags, int immunity, int time = 0, bool globalAdmin = false, CommandInfo? command = null)
{ {
if (_database == null) return; if (_database == null) return;
AdminSQLManager adminManager = new(_database); PermissionManager adminManager = new(_database);
var flagsList = flags.Split(',').Select(flag => flag.Trim()).ToList(); var flagsList = flags.Split(',').Select(flag => flag.Trim()).ToList();
_ = adminManager.AddAdminBySteamId(steamid, name, flagsList, immunity, time, globalAdmin); _ = adminManager.AddAdminBySteamId(steamid, name, flagsList, immunity, time, globalAdmin);
@@ -167,16 +168,16 @@ namespace CS2_SimpleAdmin
public void RemoveAdmin(CCSPlayerController? caller, string steamid, bool globalDelete = false, CommandInfo? command = null) public void RemoveAdmin(CCSPlayerController? caller, string steamid, bool globalDelete = false, CommandInfo? command = null)
{ {
if (_database == null) return; if (_database == null) return;
AdminSQLManager adminManager = new(_database); PermissionManager adminManager = new(_database);
_ = adminManager.DeleteAdminBySteamId(steamid, globalDelete); _ = adminManager.DeleteAdminBySteamId(steamid, globalDelete);
AddTimer(2, () => AddTimer(2, () =>
{ {
if (string.IsNullOrEmpty(steamid) || !SteamID.TryParse(steamid, out var steamId) || if (string.IsNullOrEmpty(steamid) || !SteamID.TryParse(steamid, out var steamId) ||
steamId == null) return; steamId == null) return;
if (AdminSQLManager.AdminCache.ContainsKey(steamId)) if (PermissionManager.AdminCache.ContainsKey(steamId))
{ {
AdminSQLManager.AdminCache.TryRemove(steamId, out _); PermissionManager.AdminCache.TryRemove(steamId, out _);
} }
AdminManager.ClearPlayerPermissions(steamId); AdminManager.ClearPlayerPermissions(steamId);
@@ -218,17 +219,18 @@ namespace CS2_SimpleAdmin
var groupName = command.GetArg(1); var groupName = command.GetArg(1);
var flags = command.GetArg(2); var flags = command.GetArg(2);
int.TryParse(command.GetArg(3), out var immunity); int.TryParse(command.GetArg(3), out var immunity);
var globalGroup = command.GetArg(4).ToLower().Equals("-g");
AddGroup(caller, groupName, flags, immunity, command); AddGroup(caller, groupName, flags, immunity, globalGroup, command);
} }
private static void AddGroup(CCSPlayerController? caller, string name, string flags, int immunity, CommandInfo? command = null) private static void AddGroup(CCSPlayerController? caller, string name, string flags, int immunity, bool globalGroup, CommandInfo? command = null)
{ {
if (_database == null) return; if (_database == null) return;
AdminSQLManager adminManager = new(_database); PermissionManager adminManager = new(_database);
var flagsList = flags.Split(',').Select(flag => flag.Trim()).ToList(); var flagsList = flags.Split(',').Select(flag => flag.Trim()).ToList();
_ = adminManager.AddGroup(name, flagsList, immunity); _ = adminManager.AddGroup(name, flagsList, immunity, globalGroup);
if (command != null) if (command != null)
Helper.SendDiscordLogMessage(caller, command, DiscordWebhookClientLog, _localizer); Helper.SendDiscordLogMessage(caller, command, DiscordWebhookClientLog, _localizer);
@@ -264,7 +266,7 @@ namespace CS2_SimpleAdmin
private void RemoveGroup(CCSPlayerController? caller, string name, CommandInfo? command = null) private void RemoveGroup(CCSPlayerController? caller, string name, CommandInfo? command = null)
{ {
if (_database == null) return; if (_database == null) return;
AdminSQLManager adminManager = new(_database); PermissionManager adminManager = new(_database);
_ = adminManager.DeleteGroup(name); _ = adminManager.DeleteGroup(name);
AddTimer(2, () => AddTimer(2, () =>
@@ -301,16 +303,16 @@ namespace CS2_SimpleAdmin
{ {
if (_database == null) return; if (_database == null) return;
for (var index = 0; index < AdminSQLManager.AdminCache.Keys.ToList().Count; index++) for (var index = 0; index < PermissionManager.AdminCache.Keys.ToList().Count; index++)
{ {
var steamId = AdminSQLManager.AdminCache.Keys.ToList()[index]; var steamId = PermissionManager.AdminCache.Keys.ToList()[index];
if (!AdminSQLManager.AdminCache.TryRemove(steamId, out _)) continue; if (!PermissionManager.AdminCache.TryRemove(steamId, out _)) continue;
AdminManager.ClearPlayerPermissions(steamId); AdminManager.ClearPlayerPermissions(steamId);
AdminManager.RemovePlayerAdminData(steamId); AdminManager.RemovePlayerAdminData(steamId);
} }
AdminSQLManager adminManager = new(_database); PermissionManager adminManager = new(_database);
Task.Run(async () => Task.Run(async () =>
{ {
@@ -321,7 +323,6 @@ namespace CS2_SimpleAdmin
AdminManager.LoadAdminGroups(ModuleDirectory + "/data/groups.json"); AdminManager.LoadAdminGroups(ModuleDirectory + "/data/groups.json");
}); });
//_ = _adminManager.GiveAllGroupsFlags(); //_ = _adminManager.GiveAllGroupsFlags();
//_ = _adminManager.GiveAllFlags(); //_ = _adminManager.GiveAllFlags();
} }
@@ -429,25 +430,59 @@ namespace CS2_SimpleAdmin
public void OnPlayersCommand(CCSPlayerController? caller, CommandInfo command) public void OnPlayersCommand(CCSPlayerController? caller, CommandInfo command)
{ {
var playersToTarget = Helper.GetValidPlayers(); var playersToTarget = Helper.GetValidPlayers();
var isJson = command.GetArg(1).ToLower().Equals("-json");
if (caller != null) if (!isJson)
{ {
caller.PrintToConsole($"--------- PLAYER LIST ---------"); if (caller != null)
playersToTarget.ForEach(player =>
{ {
caller.PrintToConsole( caller.PrintToConsole($"--------- PLAYER LIST ---------");
$"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.SteamID}\")"); playersToTarget.ForEach(player =>
}); {
caller.PrintToConsole($"--------- END PLAYER LIST ---------"); caller.PrintToConsole(
$"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.SteamID}\")");
});
caller.PrintToConsole($"--------- END PLAYER LIST ---------");
}
else
{
Server.PrintToConsole($"--------- PLAYER LIST ---------");
playersToTarget.ForEach(player =>
{
Server.PrintToConsole($"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.SteamID}\")");
});
Server.PrintToConsole($"--------- END PLAYER LIST ---------");
}
} }
else else
{ {
Server.PrintToConsole($"--------- PLAYER LIST ---------"); var playersJson = JsonConvert.SerializeObject(playersToTarget.Select((CCSPlayerController player) =>
playersToTarget.ForEach(player =>
{ {
Server.PrintToConsole($"• [#{player.UserId}] \"{player.PlayerName}\" (IP Address: \"{player.IpAddress?.Split(":")[0]}\" SteamID64: \"{player.SteamID}\")"); var matchStats = player.ActionTrackingServices?.MatchStats;
});
Server.PrintToConsole($"--------- END PLAYER LIST ---------"); return new
{
UserId = player.UserId,
Name = player.PlayerName,
SteamId = player.SteamID.ToString(),
IpAddress = player.IpAddress?.Split(":")[0] ?? "Unknown",
Ping = player.Ping,
AdminData = AdminManager.GetPlayerAdminData(player),
Stats = new
{
Score = player.Score,
Kills = matchStats?.Kills ?? 0,
Deaths = matchStats?.Deaths ?? 0,
Assists = matchStats?.Assists,
MVPs = player.MVPs
}
};
}));
if (caller != null)
caller.PrintToConsole(playersJson);
else
Server.PrintToConsole(playersJson);
} }
} }

View File

@@ -0,0 +1 @@
ALTER TABLE `sa_groups_servers` CHANGE `server_id` `server_id` INT(11) NULL;

View File

@@ -13,8 +13,6 @@ namespace CS2_SimpleAdmin;
public partial class CS2_SimpleAdmin public partial class CS2_SimpleAdmin
{ {
private static readonly HashSet<int> LoadedPlayers = [];
private void RegisterEvents() private void RegisterEvents()
{ {
RegisterListener<Listeners.OnMapStart>(OnMapStart); RegisterListener<Listeners.OnMapStart>(OnMapStart);
@@ -38,11 +36,6 @@ public partial class CS2_SimpleAdmin
return HookResult.Continue; return HookResult.Continue;
} }
if (!LoadedPlayers.Contains(player.Slot))
{
return HookResult.Continue;
}
#if DEBUG #if DEBUG
Logger.LogCritical("[OnClientDisconnect] After Check"); Logger.LogCritical("[OnClientDisconnect] After Check");
#endif #endif
@@ -65,15 +58,13 @@ public partial class CS2_SimpleAdmin
RemoveFromConcurrentBag(GodPlayers, player.Slot); RemoveFromConcurrentBag(GodPlayers, player.Slot);
} }
SteamID? authorizedSteamId = player.AuthorizedSteamID; var authorizedSteamId = player.AuthorizedSteamID;
if (authorizedSteamId != null && AdminSQLManager.AdminCache.TryGetValue(authorizedSteamId, out var expirationTime) if (authorizedSteamId == null || !PermissionManager.AdminCache.TryGetValue(authorizedSteamId,
&& expirationTime <= DateTime.Now) out var expirationTime)
{ || !(expirationTime <= DateTime.Now)) return HookResult.Continue;
AdminManager.ClearPlayerPermissions(authorizedSteamId);
AdminManager.RemovePlayerAdminData(authorizedSteamId); AdminManager.ClearPlayerPermissions(authorizedSteamId);
} AdminManager.RemovePlayerAdminData(authorizedSteamId);
LoadedPlayers.Remove(player.Slot);
return HookResult.Continue; return HookResult.Continue;
} }
@@ -200,9 +191,6 @@ public partial class CS2_SimpleAdmin
} }
}); });
// Add player to loadedPlayers
LoadedPlayers.Add(player.Slot);
return HookResult.Continue; return HookResult.Continue;
} }
@@ -276,8 +264,7 @@ public partial class CS2_SimpleAdmin
{ {
_tagsDetected = true; _tagsDetected = true;
} }
_adminsLoaded = false;
GodPlayers.Clear(); GodPlayers.Clear();
SilentPlayers.Clear(); SilentPlayers.Clear();
@@ -299,7 +286,7 @@ public partial class CS2_SimpleAdmin
Task.Run(async () => Task.Run(async () =>
{ {
AdminSQLManager adminManager = new(_database); PermissionManager adminManager = new(_database);
BanManager banManager = new(_database, Config); BanManager banManager = new(_database, Config);
MuteManager muteManager = new(_database); MuteManager muteManager = new(_database);
@@ -353,7 +340,7 @@ public partial class CS2_SimpleAdmin
Task.Run(async () => Task.Run(async () =>
{ {
AdminSQLManager adminManager = new(_database); PermissionManager adminManager = new(_database);
try try
{ {
await using var connection = await _database.GetConnectionAsync(); await using var connection = await _database.GetConnectionAsync();
@@ -403,18 +390,10 @@ public partial class CS2_SimpleAdmin
//await _adminManager.GiveAllGroupsFlags(); //await _adminManager.GiveAllGroupsFlags();
//await _adminManager.GiveAllFlags(); //await _adminManager.GiveAllFlags();
if (_adminsLoaded)
return;
await adminManager.CrateGroupsJsonFile();
await adminManager.CreateAdminsJsonFile();
await Server.NextFrameAsync(() => { await Server.NextFrameAsync(() => {
AdminManager.LoadAdminData(ModuleDirectory + "/data/admins.json"); ReloadAdmins(null);
AdminManager.LoadAdminGroups(ModuleDirectory + "/data/groups.json");
}); });
_adminsLoaded = true;
}); });
}, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE); }, CounterStrikeSharp.API.Modules.Timers.TimerFlags.STOP_ON_MAPCHANGE);
} }

View File

@@ -4,10 +4,12 @@ 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;
using CounterStrikeSharp.API.Modules.Admin;
namespace CS2_SimpleAdmin; namespace CS2_SimpleAdmin;
public class AdminSQLManager(Database.Database database) 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>>();
@@ -209,7 +211,7 @@ public class AdminSQLManager(Database.Database database)
await using MySqlConnection connection = await database.GetConnectionAsync(); await using MySqlConnection connection = await database.GetConnectionAsync();
try try
{ {
var sql = "SELECT group_id FROM sa_groups_servers WHERE server_id = @serverid"; var sql = "SELECT group_id FROM sa_groups_servers WHERE (server_id = @serverid OR server_id IS NULL)";
var groupDataSql = connection.Query<int>(sql, new { serverid = CS2_SimpleAdmin.ServerId }).ToList(); var groupDataSql = connection.Query<int>(sql, new { serverid = CS2_SimpleAdmin.ServerId }).ToList();
sql = """ sql = """
@@ -217,7 +219,7 @@ public class AdminSQLManager(Database.Database database)
FROM sa_groups_flags f FROM sa_groups_flags f
JOIN sa_groups_servers g ON f.group_id = g.group_id JOIN sa_groups_servers g ON f.group_id = g.group_id
JOIN sa_groups sg ON sg.id = g.group_id JOIN sa_groups sg ON sg.id = g.group_id
WHERE g.server_id = @serverid WHERE (g.server_id = @serverid OR server_id IS NULL)
"""; """;
var groupData = connection.Query(sql, new { serverid = CS2_SimpleAdmin.ServerId }).ToList(); var groupData = connection.Query(sql, new { serverid = CS2_SimpleAdmin.ServerId }).ToList();
@@ -360,8 +362,8 @@ public class AdminSQLManager(Database.Database database)
{ {
player.identity, player.identity,
player.immunity, player.immunity,
flags = player.flags.Where(flag => flag.StartsWith("@")).ToList(), flags = player.flags.Where(flag => flag.StartsWith($"@")).ToList(),
groups = player.flags.Where(flag => flag.StartsWith("#")).ToList() groups = player.flags.Where(flag => flag.StartsWith($"#")).ToList()
} }
}; };
}) })
@@ -439,8 +441,8 @@ public class AdminSQLManager(Database.Database database)
} }
} }
var insertFlagsSql = "INSERT INTO `sa_admins_flags` (`admin_id`, `flag`) " + const string insertFlagsSql = "INSERT INTO `sa_admins_flags` (`admin_id`, `flag`) " +
"VALUES (@adminId, @flag)"; "VALUES (@adminId, @flag)";
await connection.ExecuteAsync(insertFlagsSql, new await connection.ExecuteAsync(insertFlagsSql, new
{ {
@@ -448,6 +450,11 @@ public class AdminSQLManager(Database.Database database)
flag flag
}); });
} }
await Server.NextFrameAsync(() =>
{
CS2_SimpleAdmin.Instance.ReloadAdmins(null);
});
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -455,7 +462,7 @@ public class AdminSQLManager(Database.Database database)
} }
} }
public async Task AddGroup(string groupName, List<string> flagsList, int immunity = 0) public async Task AddGroup(string groupName, List<string> flagsList, int immunity = 0, bool globalGroup = false)
{ {
if (string.IsNullOrEmpty(groupName) || flagsList.Count == 0) return; if (string.IsNullOrEmpty(groupName) || flagsList.Count == 0) return;
@@ -463,8 +470,8 @@ public class AdminSQLManager(Database.Database database)
try try
{ {
// Insert group into sa_groups table // Insert group into sa_groups table
var insertGroup = "INSERT INTO `sa_groups` (`name`, `immunity`) " + const string insertGroup = "INSERT INTO `sa_groups` (`name`, `immunity`) " +
"VALUES (@groupName, @immunity); SELECT LAST_INSERT_ID();"; "VALUES (@groupName, @immunity); SELECT LAST_INSERT_ID();";
var groupId = await connection.ExecuteScalarAsync<int>(insertGroup, new var groupId = await connection.ExecuteScalarAsync<int>(insertGroup, new
{ {
groupName, groupName,
@@ -484,12 +491,16 @@ public class AdminSQLManager(Database.Database database)
}); });
} }
var insertGroupServer = "INSERT INTO `sa_groups_servers` (`group_id`, `server_id`) " + const string insertGroupServer = "INSERT INTO `sa_groups_servers` (`group_id`, `server_id`) " +
"VALUES (@groupId, @server_id)"; "VALUES (@groupId, @server_id)";
if (CS2_SimpleAdmin.ServerId != null)
await connection.ExecuteAsync(insertGroupServer, new { groupId, server_id = globalGroup ? null : CS2_SimpleAdmin.ServerId });
await Server.NextFrameAsync(() =>
{ {
await connection.ExecuteAsync(insertGroupServer, new { groupId, server_id = CS2_SimpleAdmin.ServerId }); CS2_SimpleAdmin.Instance.ReloadAdmins(null);
} });
} }
catch (Exception ex) catch (Exception ex)
{ {

View File

@@ -1 +1 @@
1.4.3a 1.4.3b