diff --git a/CS2-SimpleAdmin/Commands/basecommands.cs b/CS2-SimpleAdmin/Commands/basecommands.cs index 88b935b..4dc7517 100644 --- a/CS2-SimpleAdmin/Commands/basecommands.cs +++ b/CS2-SimpleAdmin/Commands/basecommands.cs @@ -509,6 +509,10 @@ public partial class CS2_SimpleAdmin printMethod($"• Total Mutes: \"{playerInfo.TotalMutes}\""); printMethod($"• Total Silences: \"{playerInfo.TotalSilences}\""); 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}\" ---------"); diff --git a/CS2-SimpleAdmin/Config.cs b/CS2-SimpleAdmin/Config.cs index 76b8f30..3b7e041 100644 --- a/CS2-SimpleAdmin/Config.cs +++ b/CS2-SimpleAdmin/Config.cs @@ -89,6 +89,17 @@ public class Discord new DiscordPenaltySetting { Name = "Footer", Value = "" }, 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 CustomServerCommandData diff --git a/CS2-SimpleAdmin/Extensions/EnumerableExtensions.cs b/CS2-SimpleAdmin/Extensions/EnumerableExtensions.cs new file mode 100644 index 0000000..1cf052f --- /dev/null +++ b/CS2-SimpleAdmin/Extensions/EnumerableExtensions.cs @@ -0,0 +1,12 @@ +namespace CS2_SimpleAdmin; + +public static class EnumerableExtensions +{ + public static IEnumerable> ChunkBy(this IEnumerable 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)); + } +} \ No newline at end of file diff --git a/CS2-SimpleAdmin/Helper.cs b/CS2-SimpleAdmin/Helper.cs index e62ba7d..479fcf9 100644 --- a/CS2-SimpleAdmin/Helper.cs +++ b/CS2-SimpleAdmin/Helper.cs @@ -669,12 +669,11 @@ internal static class Helper } catch (Exception ex) { - // Log or handle the exception Console.WriteLine(ex); } }); } - + private static string GenerateMessageDiscord(string message) { var hostname = ConVar.Find("hostname")?.StringValue ?? CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown"; diff --git a/CS2-SimpleAdmin/Managers/CacheManager.cs b/CS2-SimpleAdmin/Managers/CacheManager.cs index 009635b..90d9254 100644 --- a/CS2-SimpleAdmin/Managers/CacheManager.cs +++ b/CS2-SimpleAdmin/Managers/CacheManager.cs @@ -2,14 +2,15 @@ using System.Collections.Concurrent; using CS2_SimpleAdmin.Models; using Dapper; using Microsoft.Extensions.Logging; +using ZLinq; namespace CS2_SimpleAdmin.Managers; internal class CacheManager { private readonly ConcurrentDictionary _banCache = new(); - private readonly ConcurrentDictionary ips, DateTime used_at)> _playerIpsCache = new(); - private readonly HashSet _cachedIgnoredIps = [..CS2_SimpleAdmin.Instance.Config.OtherSettings.IgnoredIps]; + private readonly ConcurrentDictionary ips, DateTime usedAt, string playerName)> _playerIpsCache = new(); + private HashSet _cachedIgnoredIps; private DateTime _lastUpdateTime = DateTime.MinValue; private bool _isInitialized; @@ -20,6 +21,8 @@ internal class CacheManager if (!CS2_SimpleAdmin.ServerLoaded) return; if (_isInitialized) return; + + _cachedIgnoredIps = [..CS2_SimpleAdmin.Instance.Config.OtherSettings.IgnoredIps]; try { @@ -42,8 +45,8 @@ internal class CacheManager updated_at AS UpdatedAt FROM sa_bans """); - var ipHistory = await connection.QueryAsync<(ulong steamid, string address, DateTime used_at)>( - "SELECT steamid, address, used_at FROM sa_players_ips"); + 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"); foreach (var ban in bans) @@ -55,7 +58,10 @@ internal class CacheManager { var ips = new HashSet(group.Select(x => x.address)); var lastUsed = group.Max(x => x.used_at); - _playerIpsCache[group.Key] = (ips, lastUsed); + var playerName = group.FirstOrDefault(x => !string.IsNullOrEmpty(x.name)).name + ?? CS2_SimpleAdmin._localizer?["sa_unknown"] ?? "Unknown"; + + _playerIpsCache[group.Key] = (ips, lastUsed, playerName); } _lastUpdateTime = DateTime.Now; @@ -80,8 +86,8 @@ internal class CacheManager new { lastUpdate = _lastUpdateTime } )).ToList(); - var ipHistory = await connection.QueryAsync<(ulong steamid, string address, DateTime used_at)>( - "SELECT steamid, address, used_at FROM sa_players_ips"); + 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"); // foreach (var group in ipHistory.GroupBy(x => x.steamid)) // { @@ -90,20 +96,39 @@ internal class CacheManager // _playerIpsCache[group.Key] = (ips, lastUsed); // } - var groupedData = ipHistory.GroupBy(x => x.steamid).ToList(); + var groupedData = ipHistory + .GroupBy(x => x.steamid) + .AsParallel() + .ToList(); + Parallel.ForEach(groupedData, group => { - var ips = new HashSet(group.Select(x => x.address)); - var lastUsed = group.Max(x => x.used_at); + var ips = new HashSet( + group.Select(x => x.address), + StringComparer.OrdinalIgnoreCase + ); + var lastUsed = group.Max(x => x.used_at); + var playerName = group + .OrderByDescending(x => x.used_at) // Prefer newer records + .Select(x => x.name) + .FirstOrDefault(name => !string.IsNullOrEmpty(name)) + ?? CS2_SimpleAdmin._localizer?["sa_unknown"] + ?? "Unknown"; + _playerIpsCache.AddOrUpdate( group.Key, - _ => (ips, lastUsed), + // Add new entry + _ => (ips, lastUsed, playerName), + // Update existing (_, existing) => { - existing.ips.UnionWith(ips); - return (existing.ips, - lastUsed > existing.used_at ? lastUsed : existing.used_at); + existing.ips.UnionWith(ips); + return ( + existing.ips, + lastUsed > existing.usedAt ? lastUsed : existing.usedAt, + string.IsNullOrEmpty(existing.playerName) ? playerName : existing.playerName + ); }); }); @@ -126,7 +151,13 @@ internal class CacheManager public List GetAllBans() => _banCache.Values.ToList(); public List GetActiveBans() => _banCache.Values.Where(b => b.Status == "ACTIVE").ToList(); public List GetPlayerBansBySteamId(string steamId) => _banCache.Values.Where(b => b.PlayerSteamId == steamId).ToList(); - + public List<(ulong SteamId, string PlayerName)> GetAccountsByIp(string ipAddress) + { + return _playerIpsCache.AsValueEnumerable() + .Where(kvp => kvp.Value.ips.Contains(ipAddress)) + .Select(kvp => (kvp.Key, kvp.Value.playerName)) + .ToList(); + } private bool IsIpBanned(string ipAddress) { diff --git a/CS2-SimpleAdmin/Managers/PlayerManager.cs b/CS2-SimpleAdmin/Managers/PlayerManager.cs index 8923df3..19d7288 100644 --- a/CS2-SimpleAdmin/Managers/PlayerManager.cs +++ b/CS2-SimpleAdmin/Managers/PlayerManager.cs @@ -137,6 +137,10 @@ public class PlayerManager CS2_SimpleAdmin._logger?.LogError( $"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); } try @@ -204,6 +208,8 @@ public class PlayerManager if (CS2_SimpleAdmin.Instance.Config.OtherSettings.NotifyPenaltiesToAdminOnConnect && fullConnect) { + var associatedAcccountsChunks = CS2_SimpleAdmin.PlayersInfo[userId].AccountsAssociated.ChunkBy(5).ToList(); + await Server.NextFrameAsync(() => { foreach (var admin in Helper.GetValidPlayers() @@ -212,6 +218,7 @@ public class PlayerManager p.Connected == PlayerConnectedState.PlayerConnected && !CS2_SimpleAdmin.AdminDisabledJoinComms.Contains(p.SteamID))) { if (CS2_SimpleAdmin._localizer != null && admin != player) + { admin.SendLocalizedMessage(CS2_SimpleAdmin._localizer, "sa_admin_penalty_info", player.PlayerName, CS2_SimpleAdmin.PlayersInfo[userId].TotalBans, @@ -220,6 +227,16 @@ public class PlayerManager CS2_SimpleAdmin.PlayersInfo[userId].TotalSilences, 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})")) + ); + } + } } }); } diff --git a/CS2-SimpleAdmin/lang/ar.json b/CS2-SimpleAdmin/lang/ar.json index 8128946..9a35b90 100644 --- a/CS2-SimpleAdmin/lang/ar.json +++ b/CS2-SimpleAdmin/lang/ar.json @@ -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_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_perm": "تم حظرك بشكل دائم لمدة {lightred}{0}{default} من قبل {lightred}{1}{default}!", "sa_player_kick_message": "تم طردك لمدة {lightred}{0}{default} من قبل {lightred}{1}{default}!", diff --git a/CS2-SimpleAdmin/lang/de.json b/CS2-SimpleAdmin/lang/de.json index 697b59d..a58b49f 100644 --- a/CS2-SimpleAdmin/lang/de.json +++ b/CS2-SimpleAdmin/lang/de.json @@ -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_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_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!", diff --git a/CS2-SimpleAdmin/lang/en.json b/CS2-SimpleAdmin/lang/en.json index 8715040..b3d87cf 100644 --- a/CS2-SimpleAdmin/lang/en.json +++ b/CS2-SimpleAdmin/lang/en.json @@ -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_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_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}!", diff --git a/CS2-SimpleAdmin/lang/es.json b/CS2-SimpleAdmin/lang/es.json index de36db1..525bd3d 100644 --- a/CS2-SimpleAdmin/lang/es.json +++ b/CS2-SimpleAdmin/lang/es.json @@ -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_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_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}!", diff --git a/CS2-SimpleAdmin/lang/fa.json b/CS2-SimpleAdmin/lang/fa.json index 738e265..20ba95a 100644 --- a/CS2-SimpleAdmin/lang/fa.json +++ b/CS2-SimpleAdmin/lang/fa.json @@ -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_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_perm": "شما توسط {lightred}{1}{default} به دلیل {lightred}{0}{default} برای همیشه مسدود شده‌اید!", "sa_player_kick_message": "شما توسط {lightred}{1}{default} به دلیل {lightred}{0}{default} اخراج شده‌اید!", diff --git a/CS2-SimpleAdmin/lang/fr.json b/CS2-SimpleAdmin/lang/fr.json index 1cc7e5c..303ae38 100644 --- a/CS2-SimpleAdmin/lang/fr.json +++ b/CS2-SimpleAdmin/lang/fr.json @@ -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_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_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}!", diff --git a/CS2-SimpleAdmin/lang/lv.json b/CS2-SimpleAdmin/lang/lv.json index 324dfc9..70f4678 100644 --- a/CS2-SimpleAdmin/lang/lv.json +++ b/CS2-SimpleAdmin/lang/lv.json @@ -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_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_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}!", diff --git a/CS2-SimpleAdmin/lang/pl.json b/CS2-SimpleAdmin/lang/pl.json index b436f69..c7f7bbf 100644 --- a/CS2-SimpleAdmin/lang/pl.json +++ b/CS2-SimpleAdmin/lang/pl.json @@ -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_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_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}!", diff --git a/CS2-SimpleAdmin/lang/pt-BR.json b/CS2-SimpleAdmin/lang/pt-BR.json index 17c6977..ed6d9ba 100644 --- a/CS2-SimpleAdmin/lang/pt-BR.json +++ b/CS2-SimpleAdmin/lang/pt-BR.json @@ -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_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_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}!", diff --git a/CS2-SimpleAdmin/lang/pt-PT.json b/CS2-SimpleAdmin/lang/pt-PT.json index 04838f2..3ec755c 100644 --- a/CS2-SimpleAdmin/lang/pt-PT.json +++ b/CS2-SimpleAdmin/lang/pt-PT.json @@ -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_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_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}!", diff --git a/CS2-SimpleAdmin/lang/ru.json b/CS2-SimpleAdmin/lang/ru.json index 9339a63..7418422 100644 --- a/CS2-SimpleAdmin/lang/ru.json +++ b/CS2-SimpleAdmin/lang/ru.json @@ -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_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_perm": "Вас забанили навсегда по причине {lightred}{0}{default} администратором {lightred}{1}{default}!", "sa_player_kick_message": "Вы были выгнаны {lightred}{0}{default} администратором {lightred}{1}{default}!", diff --git a/CS2-SimpleAdmin/lang/tr.json b/CS2-SimpleAdmin/lang/tr.json index 89c8790..08e7cb4 100644 --- a/CS2-SimpleAdmin/lang/tr.json +++ b/CS2-SimpleAdmin/lang/tr.json @@ -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_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_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!", diff --git a/CS2-SimpleAdmin/lang/zh-Hans.json b/CS2-SimpleAdmin/lang/zh-Hans.json index 72ca4e3..53ac6d0 100644 --- a/CS2-SimpleAdmin/lang/zh-Hans.json +++ b/CS2-SimpleAdmin/lang/zh-Hans.json @@ -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_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_perm": "您已被 {lightred}{0}{default} 因 {lightred}{1}{default} 永久禁止!", "sa_player_kick_message": "您已被 {lightred}{0}{default} 因 {lightred}{1}{default} 踢出!", diff --git a/CS2-SimpleAdminApi/PlayerInfo.cs b/CS2-SimpleAdminApi/PlayerInfo.cs index f367ed7..b492322 100644 --- a/CS2-SimpleAdminApi/PlayerInfo.cs +++ b/CS2-SimpleAdminApi/PlayerInfo.cs @@ -26,6 +26,7 @@ public class PlayerInfo( public int TotalSilences { get; set; } = totalSilences; public int TotalWarns { get; set; } = totalWarns; public bool WaitingForKick { get; set; } = false; + public List<(ulong SteamId, string PlayerName)> AccountsAssociated { get; set; } = []; public DiePosition? DiePosition { get; set; } }