using CS2_SimpleAdmin.Database; using CS2_SimpleAdminApi; using Dapper; using Microsoft.Extensions.Logging; namespace CS2_SimpleAdmin.Managers; internal class WarnManager(IDatabaseProvider? databaseProvider) { /// /// Adds a warning to a player with an optional issuer and reason. /// /// The player who is being warned. /// The player issuing the warning; null indicates console or system. /// The reason for the warning. /// Optional duration of the warning in minutes (0 means permanent). /// The identifier of the inserted warning, or null if the operation failed. public async Task WarnPlayer(PlayerInfo player, PlayerInfo? issuer, string reason, int time = 0) { if (databaseProvider == null) return null; var now = Time.ActualDateTime(); var futureTime = now.AddMinutes(time); try { await using var connection = await databaseProvider.CreateConnectionAsync(); var sql = databaseProvider.GetAddWarnQuery(true); var warnId = await connection.ExecuteScalarAsync(sql, new { playerSteamid = player.SteamId.SteamId64, playerName = player.Name, adminSteamid = issuer?.SteamId.SteamId64 ?? 0, adminName = issuer?.Name ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console", warnReason = reason, duration = time, ends = futureTime, created = now, serverid = CS2_SimpleAdmin.ServerId }); return warnId; } catch(Exception e) { return null; } } /// /// Adds a warning to a player identified by SteamID with optional issuer and reason. /// /// The SteamID64 of the player being warned. /// The player issuing the warning; null indicates console or system. /// The reason for the warning. /// Optional duration of the warning in minutes (0 means permanent). /// The identifier of the inserted warning, or null if the operation failed. public async Task AddWarnBySteamid(ulong playerSteamId, PlayerInfo? issuer, string reason, int time = 0) { if (databaseProvider == null) return null; var now = Time.ActualDateTime(); var futureTime = now.AddMinutes(time); try { await using var connection = await databaseProvider.CreateConnectionAsync(); var sql = databaseProvider.GetAddWarnQuery(false); var warnId = await connection.ExecuteScalarAsync(sql, new { playerSteamid = playerSteamId, adminSteamid = issuer?.SteamId.SteamId64 ?? 0, adminName = issuer?.Name ?? CS2_SimpleAdmin._localizer?["sa_console"] ?? "Console", warnReason = reason, duration = time, ends = futureTime, created = now, serverid = CS2_SimpleAdmin.ServerId }); return warnId; } catch { return null; } } /// /// Retrieves a list of warnings for a specific player. /// /// The player whose warnings to retrieve. /// If true, returns only active (non-expired) warnings; otherwise returns all warnings. /// A list of dynamic objects representing warnings, or an empty list if none found or on failure. public async Task> GetPlayerWarns(PlayerInfo player, bool active = true) { if (databaseProvider == null) return []; try { await using var connection = await databaseProvider.CreateConnectionAsync(); var sql = databaseProvider.GetPlayerWarnsQuery(CS2_SimpleAdmin.Instance.Config.MultiServerMode, active); var parameters = new { PlayerSteamID = player.SteamId.SteamId64, serverid = CS2_SimpleAdmin.ServerId }; var warns = await connection.QueryAsync(sql, parameters); return warns.ToList(); } catch (Exception) { return []; } } /// /// Retrieves the count of warnings for a player specified by SteamID. /// /// The SteamID64 of the player. /// If true, counts only active (non-expired) warnings; otherwise counts all warnings. /// The count of warnings as an integer, or 0 if none found or on failure. public async Task GetPlayerWarnsCount(ulong steamId, bool active = true) { if (databaseProvider == null) return 0; try { await using var connection = await databaseProvider.CreateConnectionAsync(); var sql = databaseProvider.GetPlayerWarnsCountQuery(CS2_SimpleAdmin.Instance.Config.MultiServerMode, active); var warnsCount = await connection.ExecuteScalarAsync(sql, new { PlayerSteamID = steamId, serverid = CS2_SimpleAdmin.ServerId }); return warnsCount; } catch (Exception) { return 0; } } /// /// Removes a specific warning by its identifier from a player's record. /// /// The player whose warning will be removed. /// The identifier of the warning to remove. /// A task representing the asynchronous operation. public async Task UnwarnPlayer(PlayerInfo player, int warnId) { if (databaseProvider == null) return; try { await using var connection = await databaseProvider.CreateConnectionAsync(); var sql = databaseProvider.GetUnwarnByIdQuery(CS2_SimpleAdmin.Instance.Config.MultiServerMode); await connection.ExecuteAsync(sql, new { steamid = player.SteamId.SteamId64, warnId, serverid = CS2_SimpleAdmin.ServerId }); } catch (Exception ex) { CS2_SimpleAdmin._logger?.LogCritical($"Unable to remove warn + {ex}"); } } /// /// Removes the most recent warning matching a player pattern (usually SteamID string). /// /// The pattern identifying the player whose last warning should be removed. /// A task representing the asynchronous operation. public async Task UnwarnPlayer(string playerPattern) { if (databaseProvider == null) return; try { await using var connection = await databaseProvider.CreateConnectionAsync(); var sql = databaseProvider.GetUnwarnLastQuery(CS2_SimpleAdmin.Instance.Config.MultiServerMode); await connection.ExecuteAsync(sql, new { steamid = playerPattern, serverid = CS2_SimpleAdmin.ServerId }); } catch (Exception ex) { CS2_SimpleAdmin._logger?.LogCritical("Unable to remove last warn {exception}", ex.Message); } } /// /// Expires old warnings based on the current time, removing or marking them as inactive. /// /// A task representing the asynchronous operation. public async Task ExpireOldWarns() { if (databaseProvider == null) return; try { await using var connection = await databaseProvider.CreateConnectionAsync(); var sql = databaseProvider.GetExpireWarnsQuery(CS2_SimpleAdmin.Instance.Config.MultiServerMode); await connection.ExecuteAsync(sql, new { CurrentTime = Time.ActualDateTime(), serverid = CS2_SimpleAdmin.ServerId }); } catch (Exception ex) { CS2_SimpleAdmin._logger?.LogCritical($"Unable to remove expired warns + {ex}"); } } }