mirror of
https://github.com/daffyyyy/CS2-SimpleAdmin.git
synced 2026-09-27 20:17:04 +02:00
Refactor database layer and add module/plugin improvements
Reworked the database layer to support both MySQL and SQLite via new provider classes and migration scripts for each backend. Updated the build workflow to support building and packaging additional modules, including StealthModule and BanSoundModule, and improved artifact handling. Refactored command registration to allow dynamic registration/unregistration and improved API event handling. Updated dependencies, project structure, and configuration checks for better reliability and extensibility. Added new language files, updated versioning, and removed obsolete files.
**⚠️ Warning: SQLite support is currently experimental.
Using this version requires reconfiguration of your database settings!
Plugin now uses UTC time. Please adjust your configurations accordingly!
**
This commit is contained in:
parent
b97426313b
commit
5701455de0
111 changed files with 5387 additions and 2871 deletions
|
|
@ -2,14 +2,15 @@
|
|||
using CounterStrikeSharp.API.Modules.Entities;
|
||||
using Dapper;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using MySqlConnector;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Text.Json;
|
||||
using CounterStrikeSharp.API.Modules.Admin;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using CS2_SimpleAdmin.Database;
|
||||
|
||||
namespace CS2_SimpleAdmin.Managers;
|
||||
|
||||
public class PermissionManager(Database.Database? database)
|
||||
public class PermissionManager(IDatabaseProvider? databaseProvider)
|
||||
{
|
||||
// Unused for now
|
||||
//public static readonly ConcurrentDictionary<string, ConcurrentBag<string>> _adminCache = new ConcurrentDictionary<string, ConcurrentBag<string>>();
|
||||
|
|
@ -59,59 +60,65 @@ public class PermissionManager(Database.Database? database)
|
|||
}
|
||||
*/
|
||||
|
||||
private async Task<List<(string, string, List<string>, int, DateTime?)>> GetAllPlayersFlags()
|
||||
/// <summary>
|
||||
/// Retrieves all players' flags and associated data asynchronously.
|
||||
/// </summary>
|
||||
/// <returns>A list of tuples containing player SteamID, name, flags, immunity, and expiration time.</returns>
|
||||
private async Task<List<(ulong, string ,List<string>, int, DateTime?)>> GetAllPlayersFlags()
|
||||
{
|
||||
if (database == null) return [];
|
||||
if (databaseProvider == null)
|
||||
return new List<(ulong, string, List<string>, int, DateTime?)>();
|
||||
|
||||
var now = Time.ActualDateTime();
|
||||
var now = Time.ActualDateTime();
|
||||
|
||||
try
|
||||
{
|
||||
await using var connection = await database.GetConnectionAsync();
|
||||
try
|
||||
{
|
||||
await using var connection = await databaseProvider.CreateConnectionAsync();
|
||||
var sql = databaseProvider.GetAdminsQuery();
|
||||
var admins = (await connection.QueryAsync(sql, new { CurrentTime = now, serverid = CS2_SimpleAdmin.ServerId })).ToList();
|
||||
|
||||
const string sql = """
|
||||
SELECT sa_admins.player_steamid, sa_admins.player_name, sa_admins_flags.flag, sa_admins.immunity, sa_admins.ends
|
||||
FROM sa_admins_flags
|
||||
JOIN sa_admins ON sa_admins_flags.admin_id = sa_admins.id
|
||||
WHERE (sa_admins.ends IS NULL OR sa_admins.ends > @CurrentTime)
|
||||
AND (sa_admins.server_id IS NULL OR sa_admins.server_id = @serverid)
|
||||
ORDER BY sa_admins.player_steamid
|
||||
""";
|
||||
var groupedPlayers = admins
|
||||
.GroupBy(r => new { playerSteamId = r.player_steamid, playerName = r.player_name, r.immunity, r.ends })
|
||||
.Select(g =>
|
||||
{
|
||||
ulong steamId = g.Key.playerSteamId switch
|
||||
{
|
||||
long l => (ulong)l,
|
||||
int i => (ulong)i,
|
||||
string s when ulong.TryParse(s, out var parsed) => parsed,
|
||||
_ => 0UL
|
||||
};
|
||||
|
||||
var admins = (await connection.QueryAsync(sql, new { CurrentTime = now, serverid = CS2_SimpleAdmin.ServerId })).ToList();
|
||||
int immunity = g.Key.immunity switch
|
||||
{
|
||||
int i => i,
|
||||
string s when int.TryParse(s, out var parsed) => parsed,
|
||||
_ => 0
|
||||
};
|
||||
|
||||
// Group by player_steamid and aggregate the flags
|
||||
var groupedPlayers = admins
|
||||
.GroupBy(r => new { r.player_steamid, r.player_name, r.immunity, r.ends })
|
||||
.Select(g => (
|
||||
PlayerSteamId: (string)g.Key.player_steamid,
|
||||
PlayerName: (string)g.Key.player_name,
|
||||
Flags: g.Select(r => (string)r.flag).Distinct().ToList(),
|
||||
Immunity: g.Key.immunity is int i ? i : int.TryParse((string)g.Key.immunity, out var immunity) ? immunity : 0,
|
||||
Ends: g.Key.ends is DateTime dateTime ? dateTime : (DateTime?)null
|
||||
))
|
||||
.ToList();
|
||||
DateTime? ends = g.Key.ends as DateTime?;
|
||||
|
||||
|
||||
// foreach (var player in groupedPlayers)
|
||||
// {
|
||||
// Console.WriteLine($"Player SteamID: {player.PlayerSteamId}, Name: {player.PlayerName}, Flags: {string.Join(", ", player.Flags)}, Immunity: {player.Immunity}, Ends: {player.Ends}");
|
||||
// }
|
||||
|
||||
List<(string, string, List<string>, int, DateTime?)> filteredFlagsWithImmunity = [];
|
||||
string playerName = g.Key.playerName as string ?? string.Empty;
|
||||
|
||||
// Add the grouped players to the list
|
||||
filteredFlagsWithImmunity.AddRange(groupedPlayers);
|
||||
// tutaj zakładamy, że Dapper zwraca już string (nie dynamic)
|
||||
var flags = g.Select(r => r.flag as string ?? string.Empty)
|
||||
.Distinct()
|
||||
.ToList();
|
||||
|
||||
return filteredFlagsWithImmunity;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CS2_SimpleAdmin._logger?.LogError("Unable to load admins from database! {exception}", ex.Message);
|
||||
return [];
|
||||
}
|
||||
return (steamId, playerName, flags, immunity, ends);
|
||||
})
|
||||
.ToList();
|
||||
|
||||
return groupedPlayers;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CS2_SimpleAdmin._logger?.LogError("Unable to load admins from database! {exception}", ex.Message);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
public async Task<Dictionary<int, Tuple<List<string>, List<Tuple<string, DateTime?>>, int>>> GetAllGroupsFlags()
|
||||
{
|
||||
|
|
@ -177,33 +184,29 @@ public class PermissionManager(Database.Database? database)
|
|||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves all groups' data including flags and immunity asynchronously.
|
||||
/// </summary>
|
||||
/// <returns>A dictionary with group names as keys and tuples of flags and immunity as values.</returns>
|
||||
private async Task<Dictionary<string, (List<string>, int)>> GetAllGroupsData()
|
||||
{
|
||||
if (database == null) return [];
|
||||
if (databaseProvider == null) return [];
|
||||
|
||||
await using MySqlConnection connection = await database.GetConnectionAsync();
|
||||
await using var connection = await databaseProvider.CreateConnectionAsync();
|
||||
;
|
||||
try
|
||||
{
|
||||
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();
|
||||
|
||||
sql = """
|
||||
SELECT g.group_id, sg.name AS group_name, sg.immunity, f.flag
|
||||
FROM sa_groups_flags f
|
||||
JOIN sa_groups_servers g ON f.group_id = g.group_id
|
||||
JOIN sa_groups sg ON sg.id = g.group_id
|
||||
WHERE (g.server_id = @serverid OR server_id IS NULL)
|
||||
""";
|
||||
// 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 sql = databaseProvider.GetGroupsQuery();
|
||||
var groupData = connection.Query(sql, new { serverid = CS2_SimpleAdmin.ServerId }).ToList();
|
||||
|
||||
if (groupDataSql.Count == 0 || groupData.Count == 0)
|
||||
if (groupData.Count == 0)
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
var groupInfoDictionary = new Dictionary<string, (List<string>, int)>();
|
||||
|
||||
foreach (var row in groupData)
|
||||
{
|
||||
var groupName = (string)row.group_name;
|
||||
|
|
@ -231,10 +234,13 @@ public class PermissionManager(Database.Database? database)
|
|||
return [];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a JSON file containing groups data asynchronously.
|
||||
/// </summary>
|
||||
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
|
||||
public async Task CrateGroupsJsonFile()
|
||||
{
|
||||
var groupsData = await GetAllGroupsData();
|
||||
|
||||
var jsonData = new Dictionary<string, object>();
|
||||
|
||||
foreach (var kvp in groupsData)
|
||||
|
|
@ -248,7 +254,13 @@ public class PermissionManager(Database.Database? database)
|
|||
jsonData[kvp.Key] = groupData;
|
||||
}
|
||||
|
||||
var json = JsonConvert.SerializeObject(jsonData, Formatting.Indented);
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
};
|
||||
|
||||
var json = JsonSerializer.Serialize(jsonData, options);
|
||||
var filePath = Path.Combine(CS2_SimpleAdmin.Instance.ModuleDirectory, "data", "groups.json");
|
||||
await File.WriteAllTextAsync(filePath, json);
|
||||
}
|
||||
|
|
@ -313,11 +325,15 @@ public class PermissionManager(Database.Database? database)
|
|||
}
|
||||
*/
|
||||
|
||||
/// <summary>
|
||||
/// Creates a JSON file containing admins data asynchronously.
|
||||
/// </summary>
|
||||
[UnconditionalSuppressMessage("Trimming", "IL2026:Members annotated with 'RequiresUnreferencedCodeAttribute' require dynamic access otherwise can break functionality when trimming application code", Justification = "<Pending>")]
|
||||
public async Task CreateAdminsJsonFile()
|
||||
{
|
||||
List<(string identity, string name, List<string> flags, int immunity, DateTime? ends)> allPlayers = await GetAllPlayersFlags();
|
||||
List<(ulong identity, string name, List<string> flags, int immunity, DateTime? ends)> allPlayers = await GetAllPlayersFlags();
|
||||
var validPlayers = allPlayers
|
||||
.Where(player => SteamID.TryParse(player.identity, out _))
|
||||
.Where(player => SteamID.TryParse(player.identity.ToString(), out _))
|
||||
.ToList();
|
||||
|
||||
// foreach (var player in allPlayers)
|
||||
|
|
@ -335,10 +351,10 @@ public class PermissionManager(Database.Database? database)
|
|||
var jsonData = validPlayers
|
||||
.GroupBy(player => player.name) // Group by player name
|
||||
.ToDictionary(
|
||||
group => group.Key, // Use the player name as the key
|
||||
group => group.Key, // Use the player name as key
|
||||
object (group) =>
|
||||
{
|
||||
// Consolidate data for players with the same name
|
||||
// Consolidate data for players with same name
|
||||
var consolidatedData = group.Aggregate(
|
||||
new
|
||||
{
|
||||
|
|
@ -349,16 +365,16 @@ public class PermissionManager(Database.Database? database)
|
|||
},
|
||||
(acc, player) =>
|
||||
{
|
||||
// Merge identities and use the latest or first non-null identity
|
||||
if (string.IsNullOrEmpty(acc.identity) && !string.IsNullOrEmpty(player.identity))
|
||||
// Merge identities
|
||||
if (string.IsNullOrEmpty(acc.identity) && !string.IsNullOrEmpty(player.identity.ToString()))
|
||||
{
|
||||
acc = acc with { identity = player.identity };
|
||||
acc = acc with { identity = player.identity.ToString() };
|
||||
}
|
||||
|
||||
// Combine immunities by taking the maximum value
|
||||
// Combine immunities by maximum value
|
||||
acc = acc with { immunity = Math.Max(acc.immunity, player.immunity) };
|
||||
|
||||
// Combine flags and groups, ensuring no duplicates
|
||||
// Combine flags and groups
|
||||
acc = acc with
|
||||
{
|
||||
flags = acc.flags.Concat(player.flags.Where(flag => flag.StartsWith($"@"))).Distinct().ToList(),
|
||||
|
|
@ -368,7 +384,7 @@ public class PermissionManager(Database.Database? database)
|
|||
return acc;
|
||||
});
|
||||
|
||||
Server.NextFrameAsync(() =>
|
||||
Server.NextWorldUpdate(() =>
|
||||
{
|
||||
var keysToRemove = new List<SteamID>();
|
||||
|
||||
|
|
@ -399,7 +415,7 @@ public class PermissionManager(Database.Database? database)
|
|||
|
||||
foreach (var player in group)
|
||||
{
|
||||
if (SteamID.TryParse(player.identity, out var steamId) && steamId != null)
|
||||
if (SteamID.TryParse(player.identity.ToString(), out var steamId) && steamId != null)
|
||||
{
|
||||
AdminCache.TryAdd(steamId, (player.ends, player.flags));
|
||||
}
|
||||
|
|
@ -440,7 +456,13 @@ public class PermissionManager(Database.Database? database)
|
|||
return consolidatedData;
|
||||
});
|
||||
|
||||
var json = JsonConvert.SerializeObject(jsonData, Formatting.Indented);
|
||||
var options = new JsonSerializerOptions
|
||||
{
|
||||
WriteIndented = true,
|
||||
PropertyNamingPolicy = JsonNamingPolicy.CamelCase
|
||||
};
|
||||
|
||||
var json = JsonSerializer.Serialize(jsonData, options);
|
||||
var filePath = Path.Combine(CS2_SimpleAdmin.Instance.ModuleDirectory, "data", "admins.json");
|
||||
|
||||
await File.WriteAllTextAsync(filePath, json);
|
||||
|
|
@ -448,32 +470,42 @@ public class PermissionManager(Database.Database? database)
|
|||
//await File.WriteAllTextAsync(CS2_SimpleAdmin.Instance.ModuleDirectory + "/data/admins.json", json);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes an admin by their SteamID from the database asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="playerSteamId">The SteamID of the admin to delete.</param>
|
||||
/// <param name="globalDelete">Whether to delete the admin globally or only for the current server.</param>
|
||||
public async Task DeleteAdminBySteamId(string playerSteamId, bool globalDelete = false)
|
||||
{
|
||||
if (database == null) return;
|
||||
if (databaseProvider == null) return;
|
||||
if (string.IsNullOrEmpty(playerSteamId)) return;
|
||||
|
||||
//_adminCache.TryRemove(playerSteamId, out _);
|
||||
|
||||
try
|
||||
{
|
||||
await using var connection = await database.GetConnectionAsync();
|
||||
|
||||
var sql = globalDelete
|
||||
? "DELETE FROM sa_admins WHERE player_steamid = @PlayerSteamID"
|
||||
: "DELETE FROM sa_admins WHERE player_steamid = @PlayerSteamID AND server_id = @ServerId";
|
||||
|
||||
await using var connection = await databaseProvider.CreateConnectionAsync();
|
||||
var sql = databaseProvider.GetDeleteAdminQuery(globalDelete);
|
||||
await connection.ExecuteAsync(sql, new { PlayerSteamID = playerSteamId, CS2_SimpleAdmin.ServerId });
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
CS2_SimpleAdmin._logger?.LogError(ex.ToString());
|
||||
CS2_SimpleAdmin._logger?.LogError(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new admin with specified details asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="playerSteamId">SteamID of the admin.</param>
|
||||
/// <param name="playerName">Name of the admin.</param>
|
||||
/// <param name="flagsList">List of flags assigned to the admin.</param>
|
||||
/// <param name="immunity">Immunity level.</param>
|
||||
/// <param name="time">Duration in minutes for admin expiration; 0 means permanent.</param>
|
||||
/// <param name="globalAdmin">Whether the admin is global or server-specific.</param>
|
||||
public async Task AddAdminBySteamId(string playerSteamId, string playerName, List<string> flagsList, int immunity = 0, int time = 0, bool globalAdmin = false)
|
||||
{
|
||||
if (database == null) return;
|
||||
if (databaseProvider == null) return;
|
||||
|
||||
if (string.IsNullOrEmpty(playerSteamId) || flagsList.Count == 0) return;
|
||||
|
||||
|
|
@ -487,12 +519,10 @@ public class PermissionManager(Database.Database? database)
|
|||
|
||||
try
|
||||
{
|
||||
await using var connection = await database.GetConnectionAsync();
|
||||
await using var connection = await databaseProvider.CreateConnectionAsync();
|
||||
|
||||
// Insert admin into sa_admins table
|
||||
const string insertAdminSql = "INSERT INTO `sa_admins` (`player_steamid`, `player_name`, `immunity`, `ends`, `created`, `server_id`) " +
|
||||
"VALUES (@playerSteamid, @playerName, @immunity, @ends, @created, @serverid); SELECT LAST_INSERT_ID();";
|
||||
|
||||
var insertAdminSql = databaseProvider.GetAddAdminQuery();
|
||||
var adminId = await connection.ExecuteScalarAsync<int>(insertAdminSql, new
|
||||
{
|
||||
playerSteamId,
|
||||
|
|
@ -506,36 +536,26 @@ public class PermissionManager(Database.Database? database)
|
|||
// Insert flags into sa_admins_flags table
|
||||
foreach (var flag in flagsList)
|
||||
{
|
||||
if (flag.StartsWith($"#"))
|
||||
{
|
||||
// const string sql = "SELECT id FROM `sa_groups` WHERE name = @groupName";
|
||||
// var groupId = await connection.QuerySingleOrDefaultAsync<int?>(sql, new { groupName = flag });
|
||||
|
||||
const string sql = """
|
||||
SELECT sgs.group_id
|
||||
FROM sa_groups_servers sgs
|
||||
JOIN sa_groups sg ON sgs.group_id = sg.id
|
||||
WHERE sg.name = @groupName
|
||||
ORDER BY (sgs.server_id = @serverId) DESC, sgs.server_id ASC
|
||||
LIMIT 1
|
||||
""";
|
||||
|
||||
var groupId = await connection.QuerySingleOrDefaultAsync<int?>(sql, new { groupName = flag, CS2_SimpleAdmin.ServerId });
|
||||
|
||||
if (groupId != null)
|
||||
{
|
||||
const string updateAdminGroup = "UPDATE `sa_admins` SET group_id = @groupId WHERE id = @adminId";
|
||||
await connection.ExecuteAsync(updateAdminGroup, new
|
||||
{
|
||||
groupId,
|
||||
adminId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const string insertFlagsSql = "INSERT INTO `sa_admins_flags` (`admin_id`, `flag`) " +
|
||||
"VALUES (@adminId, @flag)";
|
||||
// if (flag.StartsWith($"#"))
|
||||
// {
|
||||
// // const string sql = "SELECT id FROM `sa_groups` WHERE name = @groupName";
|
||||
// // var groupId = await connection.QuerySingleOrDefaultAsync<int?>(sql, new { groupName = flag });
|
||||
//
|
||||
// var sql = databaseProvider.GetGroupIdByNameQuery();
|
||||
// var groupId = await connection.QuerySingleOrDefaultAsync<int?>(sql, new { groupName = flag, CS2_SimpleAdmin.ServerId });
|
||||
//
|
||||
// if (groupId != null)
|
||||
// {
|
||||
// var updateAdminGroup = "UPDATE `sa_admins` SET group_id = @groupId WHERE id = @adminId";
|
||||
// await connection.ExecuteAsync(updateAdminGroup, new
|
||||
// {
|
||||
// groupId,
|
||||
// adminId
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
var insertFlagsSql = databaseProvider.GetAddAdminFlagsQuery();
|
||||
await connection.ExecuteAsync(insertFlagsSql, new
|
||||
{
|
||||
adminId,
|
||||
|
|
@ -554,18 +574,24 @@ public class PermissionManager(Database.Database? database)
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new group with flags and immunity asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="groupName">Name of the group.</param>
|
||||
/// <param name="flagsList">List of flags assigned to the group.</param>
|
||||
/// <param name="immunity">Immunity level of the group.</param>
|
||||
/// <param name="globalGroup">Whether the group is global or server-specific.</param>
|
||||
public async Task AddGroup(string groupName, List<string> flagsList, int immunity = 0, bool globalGroup = false)
|
||||
{
|
||||
if (database == null) return;
|
||||
if (databaseProvider == null) return;
|
||||
|
||||
if (string.IsNullOrEmpty(groupName) || flagsList.Count == 0) return;
|
||||
|
||||
await using var connection = await database.GetConnectionAsync();
|
||||
await using var connection = await databaseProvider.CreateConnectionAsync();
|
||||
try
|
||||
{
|
||||
// Insert group into sa_groups table
|
||||
const string insertGroup = "INSERT INTO `sa_groups` (`name`, `immunity`) " +
|
||||
"VALUES (@groupName, @immunity); SELECT LAST_INSERT_ID();";
|
||||
var insertGroup = databaseProvider.GetAddGroupQuery();
|
||||
var groupId = await connection.ExecuteScalarAsync<int>(insertGroup, new
|
||||
{
|
||||
groupName,
|
||||
|
|
@ -575,8 +601,7 @@ public class PermissionManager(Database.Database? database)
|
|||
// Insert flags into sa_groups_flags table
|
||||
foreach (var flag in flagsList)
|
||||
{
|
||||
const string insertFlagsSql = "INSERT INTO `sa_groups_flags` (`group_id`, `flag`) " +
|
||||
"VALUES (@groupId, @flag)";
|
||||
var insertFlagsSql = databaseProvider.GetAddGroupFlagsQuery();
|
||||
|
||||
await connection.ExecuteAsync(insertFlagsSql, new
|
||||
{
|
||||
|
|
@ -585,11 +610,8 @@ public class PermissionManager(Database.Database? database)
|
|||
});
|
||||
}
|
||||
|
||||
const string insertGroupServer = "INSERT INTO `sa_groups_servers` (`group_id`, `server_id`) " +
|
||||
"VALUES (@groupId, @server_id)";
|
||||
|
||||
var insertGroupServer = databaseProvider.GetAddGroupServerQuery();
|
||||
await connection.ExecuteAsync(insertGroupServer, new { groupId, server_id = globalGroup ? null : CS2_SimpleAdmin.ServerId });
|
||||
|
||||
await Server.NextWorldUpdateAsync(() =>
|
||||
{
|
||||
CS2_SimpleAdmin.Instance.ReloadAdmins(null);
|
||||
|
|
@ -602,16 +624,20 @@ public class PermissionManager(Database.Database? database)
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a group by name asynchronously.
|
||||
/// </summary>
|
||||
/// <param name="groupName">Name of the group to delete.</param>
|
||||
public async Task DeleteGroup(string groupName)
|
||||
{
|
||||
if (database == null) return;
|
||||
if (databaseProvider == null) return;
|
||||
|
||||
if (string.IsNullOrEmpty(groupName)) return;
|
||||
|
||||
await using var connection = await database.GetConnectionAsync();
|
||||
await using var connection = await databaseProvider.CreateConnectionAsync();
|
||||
try
|
||||
{
|
||||
const string sql = "DELETE FROM `sa_groups` WHERE name = @groupName";
|
||||
var sql = databaseProvider.GetDeleteGroupQuery();
|
||||
await connection.ExecuteAsync(sql, new { groupName });
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
|
@ -620,15 +646,18 @@ public class PermissionManager(Database.Database? database)
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes admins whose permissions have expired asynchronously.
|
||||
/// </summary>
|
||||
public async Task DeleteOldAdmins()
|
||||
{
|
||||
if (database == null) return;
|
||||
if (databaseProvider == null) return;
|
||||
|
||||
try
|
||||
{
|
||||
await using var connection = await database.GetConnectionAsync();
|
||||
await using var connection = await databaseProvider.CreateConnectionAsync();
|
||||
|
||||
const string sql = "DELETE FROM sa_admins WHERE ends IS NOT NULL AND ends <= @CurrentTime";
|
||||
var sql = databaseProvider.GetDeleteOldAdminsQuery();
|
||||
await connection.ExecuteAsync(sql, new { CurrentTime = Time.ActualDateTime() });
|
||||
}
|
||||
catch (Exception)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue