From e141a0628671ff9830aabd54710b76155203b4ca Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Mon, 5 Jan 2026 22:20:57 +0200 Subject: [PATCH 01/24] translate comments to english, add localemanager, tweak build output --- .../sharp/locales/Ptr.Modules.MapManager.json | 66 +++++++++++++++++++ .gitignore | 2 + src/Directory.Build.props | 18 +++++ src/Ptr.Modules.MapManager/InterfaceBridge.cs | 14 ++-- src/Ptr.Modules.MapManager/MapManager.cs | 46 ++++++++++--- .../Ptr.Modules.MapManager.csproj | 1 + .../Services/ExtendService.cs | 40 ++++++++--- .../Services/MapVoteService.cs | 4 +- .../Services/NominateService.cs | 40 ++++++++--- .../Services/RtvService.cs | 54 +++++++++++++-- src/Ptr.Shared/Bridge/InterfaceBridge.cs | 6 +- .../Extensions/EntityManagerExtensions.cs | 4 +- .../Extensions/TransmitManagerExtensions.cs | 32 ++++----- .../Hooks/Abstractions/AbstractHookService.cs | 8 +-- src/Ptr.Shared/Misc/ChatMessageFormatter.cs | 5 +- src/Ptr.Shared/Types/QAngle.cs | 2 +- .../AdminTableManifest.cs | 10 +-- .../IAdmin.cs | 18 ++--- .../AdminManager.cs | 6 +- .../ICommandManager.cs | 42 ++++++------ .../CommandManager.cs | 6 +- 21 files changed, 316 insertions(+), 108 deletions(-) create mode 100644 .asset/game/sharp/locales/Ptr.Modules.MapManager.json diff --git a/.asset/game/sharp/locales/Ptr.Modules.MapManager.json b/.asset/game/sharp/locales/Ptr.Modules.MapManager.json new file mode 100644 index 0000000..40f9de8 --- /dev/null +++ b/.asset/game/sharp/locales/Ptr.Modules.MapManager.json @@ -0,0 +1,66 @@ +{ + "ptr.mapmanager.extend_map_after_x": { + "en-us": "A vote to extend the map time can only be initiated after {green}{0}{white} seconds.", + "zh-cn": "{green}{0}{white} 秒后才能发起延长地图时间投票. " + }, + "ptr.mapmanager.max_extends_reached": { + "en-us": "The maximum number of times the time can be extended has been reached.", + "zh-cn": "已到达最大可延长时间次数。" + }, + "ptr.mapmanager.you_already_voted_to_extend": { + "en-us": "You have already voted to extend the map time.", + "zh-cn": "你已经投票过延长地图时间了。" + }, + "ptr.mapmanager.extend_vote_progress": { + "en-us": "{green}{0}{white} players have voted to extend the map time, {green}{1}{white} more votes needed.", + "zh-cn": "已有 {green}{0}{white} 人投票延长地图时间,还需 {green}{1}{white} 票。" + }, + "ptr.mapmanager.extend_vote_passed": { + "en-us": "Vote passed, the map time will be extended.", + "zh-cn": "投票通过,即将延长地图持续时间。" + }, + "ptr.mapmanager.nominate_not_enough_players": { + "en-us": "At least {green}{0}{white} players are required to nominate maps.", + "zh-cn": "当前在线人数不足 {green}{0}{white} 人,无法提名地图。" + }, + "ptr.mapmanager.nominate_usage": { + "en-us": "Usage: .nominate ", + "zh-cn": "用法:.nominate <地图名>" + }, + "ptr.mapmanager.map_already_nominated": { + "en-us": "This map has already been nominated.", + "zh-cn": "该地图已经被提名过了。" + }, + "ptr.mapmanager.map_recently_played": { + "en-us": "This map was played recently and cannot be nominated.", + "zh-cn": "该地图最近已经玩过了,目前无法提名。" + }, + "ptr.mapmanager.map_not_found": { + "en-us": "Cannot find this map in the map pool.", + "zh-cn": "无法从图池中找到该地图。" + }, + "ptr.mapmanager.cannot_nominate_current_map": { + "en-us": "Cannot nominate the current map.", + "zh-cn": "不能投票正在游玩的地图。" + }, + "ptr.mapmanager.player_nominated_map": { + "en-us": "{green}{0}{white} nominated map {green}{1}{white}.", + "zh-cn": "{green}{0}{white} 提名了地图 {green}{1}{white}。" + }, + "ptr.mapmanager.rtv_after_x": { + "en-us": "A vote to change the map can only be initiated after {green}{0}{white} seconds.", + "zh-cn": "{green}{0}{white} 秒后才能发起换图投票。" + }, + "ptr.mapmanager.already_voted_rtv": { + "en-us": "You have already voted to change the map!", + "zh-cn": "你已经投票过换图了!" + }, + "ptr.mapmanager.rtv_vote_progress": { + "en-us": "{green}{0}{white} players have voted to change the map, {green}{1}{white} more votes needed.", + "zh-cn": "已有 {green}{0}{white} 人投票换图,还需 {green}{1}{white} 票。" + }, + "ptr.mapmanager.rtv_vote_passed": { + "en-us": "RTV vote passed! Map voting will start after this round ends.", + "zh-cn": "投票换图通过!将在回合结束后开始投票。" + } +} diff --git a/.gitignore b/.gitignore index 71bfba8..9b66a29 100644 --- a/.gitignore +++ b/.gitignore @@ -417,3 +417,5 @@ FodyWeavers.xsd *.msix *.msm *.msp +/.asset/game/sharp/modules +/.asset/game/sharp/shared diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 37087df..f37242f 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -4,7 +4,25 @@ 1.0 0 $(VersionPrefix).$(VersionSuffix) + + + $([System.String]::new('$(MSBuildProjectName)').EndsWith('.Shared')) + true + $([System.String]::new('$(MSBuildProjectName)').Contains('.Modules.')) + + + + + $(MSBuildThisFileDirectory)..\.asset\game\sharp\shared\$(MSBuildProjectName)\ + false + + + + $(MSBuildThisFileDirectory)..\.asset\game\sharp\modules\$(MSBuildProjectName)\ + false + + diff --git a/src/Ptr.Modules.MapManager/InterfaceBridge.cs b/src/Ptr.Modules.MapManager/InterfaceBridge.cs index 2c63d95..3a2963d 100644 --- a/src/Ptr.Modules.MapManager/InterfaceBridge.cs +++ b/src/Ptr.Modules.MapManager/InterfaceBridge.cs @@ -77,7 +77,7 @@ public InterfaceBridge(ISharedSystem sharedSystem, public string ModuleIdentity { get; init; } /// - /// 开洞,一般情况下别用! + /// Don't use it to make holes under normal circumstances! /// internal static InterfaceBridge Instance { get; private set; } = null!; @@ -99,14 +99,16 @@ public InterfaceBridge(ISharedSystem sharedSystem, public IModSharp ModSharp => _sharedSystem.GetModSharp(); /// - /// CGlobalVars* gpGlobals,没什么好说的。
- /// 注意,一定要在地图加载之后调用!不然服务器第一次加载的时候是拿不到的! + /// CGlobalVars* gpGlobals,There's not much to say。
+ /// Note that this must be called after the map is loaded!
+ /// Otherwise, it won't be available when the server loads it for the first time! ///
public IGlobalVars GlobalVars => ModSharp.GetGlobals(); /// - /// CGameRules* g_pGameRules
- /// 注意,一定要在地图加载之后调用!不然服务器第一次加载的时候是拿不到的! + /// CGameRules* g_pGameRules
+ /// Note that this must be called after the map is loaded!
+ /// Otherwise, it won't be available when the server loads it for the first time! ///
public IGameRules GameRules => ModSharp.GetGameRules(); @@ -137,7 +139,7 @@ public InterfaceBridge(ISharedSystem sharedSystem, public DateTime AllowVoteTime { get; set; } /// - /// 开洞,一般情况下别用! + /// Don't use it to make holes under normal circumstances! /// public string CurrentMapGroup { get; set; } = string.Empty; diff --git a/src/Ptr.Modules.MapManager/MapManager.cs b/src/Ptr.Modules.MapManager/MapManager.cs index 5fada73..1016674 100644 --- a/src/Ptr.Modules.MapManager/MapManager.cs +++ b/src/Ptr.Modules.MapManager/MapManager.cs @@ -5,11 +5,11 @@ using Ptr.Modules.MapManager.Hooks; using Ptr.Modules.MapManager.Services; using Ptr.Modules.MapManager.Shared; -using Ptr.Shared.Extensions; using Ptr.Shared.Hooks.Hosting; using Ptr.Shared.Hooks.Managers; using Ptr.Shared.Hosting; using Ptr.Shared.Misc; +using Sharp.Modules.LocalizerManager.Shared; using Sharp.Shared; using Sharp.Shared.Abstractions; using Sharp.Shared.Listeners; @@ -20,10 +20,11 @@ namespace Ptr.Modules.MapManager; internal class MapManager : IModSharpModule, IMapManager, IGameListener { private readonly InterfaceBridge _bridge; - private readonly IConVar? _countdownAfterChangeLevel; private readonly ILogger _logger; private readonly IServiceProvider _provider; - private readonly IConVar? _voteSuccessRatio; + private IConVar? _chatFormatPrefix; + private IConVar? _voteSuccessRatio; + private IConVar? _countdownAfterChangeLevel; public MapManager( ISharedSystem sharedSystem, @@ -34,7 +35,7 @@ public MapManager( bool hotReload) { var formatter = new ChatMessageFormatter(); - formatter.SetPrefix("{green}[地图]{white}"); + formatter.SetPrefix("{whitespace}{green}MAP{white}{whitespace}"); var bridge = new InterfaceBridge(sharedSystem, dllPath, sharpPath, version, configuration, hotReload, formatter, this); var services = new ServiceCollection(); @@ -55,12 +56,6 @@ public MapManager( _logger = sharedSystem.GetLoggerFactory().CreateLogger(); _provider = provider; - - _countdownAfterChangeLevel = _bridge.ConVarManager.CreateConVar("mapmanager_countdown_after_changelevel", 180, - "Countdown after map change (unit is sec.)"); - - _voteSuccessRatio = _bridge.ConVarManager.CreateConVar("mapmanager_vote_success_ratio", 0.6f, - "Ratio request for a success vote."); } internal int GetVoteSuccessNumberRequested() @@ -142,9 +137,27 @@ public bool Init() public void PostInit() { + // Safest place to init convars is PostInit + _chatFormatPrefix = _bridge.ConVarManager.CreateConVar("mapmanager_format_prefix", "{green}[MAP]{white}", + "Chat prefix format for map manager module."); + + // Real time prefix changes + if (_chatFormatPrefix is not null) + _bridge.ConVarManager.InstallChangeHook(_chatFormatPrefix, OnChatFormatPrefixChange); + + _countdownAfterChangeLevel = _bridge.ConVarManager.CreateConVar("mapmanager_countdown_after_changelevel", 180, + "Countdown after map change (unit is sec.)"); + + _voteSuccessRatio = _bridge.ConVarManager.CreateConVar("mapmanager_vote_success_ratio", 0.6f, + "Ratio request for a success vote."); _bridge.SharpModuleManager.RegisterSharpModuleInterface(this, IMapManager.Identity, this); } + private void OnChatFormatPrefixChange(IConVar conVar) + { + _bridge.ChatFormatter.SetPrefix(conVar.GetString()); + } + public void OnLibraryConnected(string name) { _provider.CallLibraryConnected(name, e => @@ -156,6 +169,10 @@ public void OnLibraryConnected(string name) public void OnAllModulesLoaded() { CallMapConfigLoaded(); + + var _localizerManager = _bridge.SharpModuleManager + .GetRequiredSharpModuleInterface(ILocalizerManager.Identity).Instance!; + _localizerManager.LoadLocaleFile("Ptr.Modules.MapManager"); } public void Shutdown() @@ -165,6 +182,10 @@ public void Shutdown() _provider.ShutdownAllSharpExtensions(); _bridge.Maps.Clear(); MapConfigLoaded = null; + if (_chatFormatPrefix is not null) + { + _bridge.ConVarManager.RemoveChangeHook(_chatFormatPrefix, OnChatFormatPrefixChange); + } } string IModSharpModule.DisplayName => "Ptr.Modules.MapManager"; @@ -226,6 +247,11 @@ public void ChangeLevel(IGameMap map) public void OnServerActivate() { _bridge.AllowVoteTime = DateTime.Now.AddSeconds(_countdownAfterChangeLevel?.GetInt32() ?? 180); + // On this step we already executed .cfg files + if (_chatFormatPrefix is not null) + { + _bridge.ChatFormatter.SetPrefix(_chatFormatPrefix.GetString()); + } } int IGameListener.ListenerPriority => 0; diff --git a/src/Ptr.Modules.MapManager/Ptr.Modules.MapManager.csproj b/src/Ptr.Modules.MapManager/Ptr.Modules.MapManager.csproj index 23526c3..ce1e6dc 100644 --- a/src/Ptr.Modules.MapManager/Ptr.Modules.MapManager.csproj +++ b/src/Ptr.Modules.MapManager/Ptr.Modules.MapManager.csproj @@ -10,6 +10,7 @@ + diff --git a/src/Ptr.Modules.MapManager/Services/ExtendService.cs b/src/Ptr.Modules.MapManager/Services/ExtendService.cs index b3a58d2..1ce77ab 100644 --- a/src/Ptr.Modules.MapManager/Services/ExtendService.cs +++ b/src/Ptr.Modules.MapManager/Services/ExtendService.cs @@ -2,6 +2,7 @@ using Ptr.Shared.Extensions; using Ptr.Shared.Hosting; using Sharp.Modules.CommandManager.Shared; +using Sharp.Modules.LocalizerManager.Shared; using Sharp.Shared.Definition; using Sharp.Shared.Enums; using Sharp.Shared.Listeners; @@ -16,13 +17,13 @@ internal class ExtendService : IExtendService, IClientListener, IGameListener { private readonly InterfaceBridge _bridge; private readonly IConVar? _enableExtend; - - private readonly bool[] _extClients = new bool[64]; private readonly IConVar? _extendTime; - private readonly ILogger _logger; private readonly IConVar? _maxExtCount; + private readonly bool[] _extClients = new bool[64]; + private readonly ILogger _logger; private int _extCount; private ICommandRegistry _commandRegistry = null!; + private ILocalizerManager _localizerManager = null!; public ExtendService(InterfaceBridge bridge, ILogger logger) { @@ -37,24 +38,31 @@ public ExtendService(InterfaceBridge bridge, ILogger logger) private void OnCommandExt(IGameClient client, StringCommand command) { + _localizerManager.TryGetLocalizer(client, out var _localizer); + if (_localizer is null) + { + _logger.LogWarning("Localizer not found for client {ClientSlot} when executing ext command.", + client.Slot); + return; + } var remaining = (int)(_bridge.AllowVoteTime - DateTime.Now).TotalSeconds; if (remaining > 0) { client.PrintToChat( - _bridge.ChatFormatter.Format($"{ChatColor.Green}{remaining}{ChatColor.White} 秒后才能发起延长地图时间投票。")); + _bridge.ChatFormatter.Format(_localizer.Format("ptr.mapmanager.extend_map_after_x", remaining))); return; } var maxAllowed = _maxExtCount!.GetInt32(); if (_extCount >= maxAllowed) { - client.PrintToChat(_bridge.ChatFormatter.Format("已到达最大可延长时间次数。")); + client.PrintToChat(_bridge.ChatFormatter.Format(_localizer.Format("ptr.mapmanager.max_extends_reached"))); return; } if (_extClients[client.Slot]) { - client.PrintToChat("你已经投票过延长地图时间了。"); + client.PrintToChat(_bridge.ChatFormatter.Format(_localizer.Format("ptr.mapmanager.you_already_voted_to_extend"))); return; } @@ -63,13 +71,24 @@ private void OnCommandExt(IGameClient client, StringCommand command) var request = _bridge.MapManager.GetVoteSuccessNumberRequested(); var clientGaps = request - current; client.PrintToChat( - $"已有 {ChatColor.Green}{current}{ChatColor.White} 人投票延长地图时间,还需 {ChatColor.Green}{clientGaps}{ChatColor.White} 票。"); + _bridge.ChatFormatter.Format(_localizer.Format("ptr.mapmanager.extend_vote_progress", current, clientGaps))); if (clientGaps > 0) { return; } - - _bridge.ModSharp.PrintToChatAll("投票通过,即将延长地图持续时间。"); + var allClients = _bridge.ClientManager.GetGameClients(true); + foreach (var c in allClients) + { + _localizerManager.TryGetLocalizer(client, out var _tempLocalizer); + if (_tempLocalizer is null) + { + _logger.LogWarning("Localizer not found for client {ClientSlot} when executing ext command.", + c.Slot); + continue; + } + c.PrintToChat( + _bridge.ChatFormatter.Format(_tempLocalizer.Format("ptr.mapmanager.extend_vote_passed"))); + } var timeLimit = _bridge.ConVarManager.FindConVar("mp_timelimit")!; var currentTimeLeft = timeLimit.GetFloat(); var pendingExtendTime = _extendTime?.GetFloat() ?? 15.0f; @@ -118,6 +137,9 @@ public void OnAllModulesLoaded() .GetRegistry(_bridge.ModuleIdentity); _commandRegistry.RegisterClientCommand("ext", OnCommandExt); + + _localizerManager = _bridge.SharpModuleManager + .GetRequiredSharpModuleInterface(ILocalizerManager.Identity).Instance!; } public void OnShutdown() diff --git a/src/Ptr.Modules.MapManager/Services/MapVoteService.cs b/src/Ptr.Modules.MapManager/Services/MapVoteService.cs index 0cacee5..be58879 100644 --- a/src/Ptr.Modules.MapManager/Services/MapVoteService.cs +++ b/src/Ptr.Modules.MapManager/Services/MapVoteService.cs @@ -50,7 +50,7 @@ private ECommandAction OnEndMatchVoteNextMap(IGameClient client, StringCommand c private void OnMapVoteCreated(IMapVoteCreatedForwardParams @params) { - // GetMapGroupMapList的索引是可以直接和EndMatchMapGroupVoteOptions对应的 + // The index of GetMapGroupMapList directly corresponds to EndMatchMapGroupVoteOptions if (_bridge.ModSharp.GetMapGroupMapList(_bridge.CurrentMapGroup) is not { } mapGroupElements) { _logger.LogInformation("Current map group {CurrentMapGroup} cannot retrive map list, check your map group configuration!", _bridge.CurrentMapGroup); @@ -174,7 +174,7 @@ private List SelectMapsForVote(int maxMaps = 10) private void SummaryVote() { - // GetMapGroupMapList的索引是可以直接和EndMatchMapGroupVoteOptions对应的 + // The index of GetMapGroupMapList directly corresponds to EndMatchMapGroupVoteOptions if (_bridge.ModSharp.GetMapGroupMapList(_bridge.CurrentMapGroup) is not { } mapGroupElements) { return; diff --git a/src/Ptr.Modules.MapManager/Services/NominateService.cs b/src/Ptr.Modules.MapManager/Services/NominateService.cs index 6ab8dba..07260ec 100644 --- a/src/Ptr.Modules.MapManager/Services/NominateService.cs +++ b/src/Ptr.Modules.MapManager/Services/NominateService.cs @@ -2,6 +2,7 @@ using Ptr.Shared.Extensions; using Ptr.Shared.Hosting; using Sharp.Modules.CommandManager.Shared; +using Sharp.Modules.LocalizerManager.Shared; using Sharp.Shared.Definition; using Sharp.Shared.Objects; using Sharp.Shared.Types; @@ -17,6 +18,7 @@ internal class NominateService : INominateService private readonly IConVar? _enableNominate; private readonly ILogger _logger; + private ILocalizerManager _localizerManager = null!; public NominateService(InterfaceBridge bridge, ILogger logger) { @@ -51,6 +53,9 @@ public void OnAllModulesLoaded() .Instance! .GetRegistry(_bridge.ModuleIdentity) .RegisterClientCommand("nominate", OnCommandNominate); + + _localizerManager = _bridge.SharpModuleManager + .GetRequiredSharpModuleInterface(ILocalizerManager.Identity).Instance!; } public void OnShutdown() @@ -65,51 +70,70 @@ public void OnShutdown() private void OnCommandNominate(IGameClient client, StringCommand command) { + _localizerManager.TryGetLocalizer(client, out var _localizer); + if (_localizer is null) + { + _logger.LogWarning("Localizer not found for client {ClientSlot} when executing nominate command.", + client.Slot); + return; + } + var clientsCount = _bridge.Server.GetGameClients(true, true).Count; var leastActivateNominateCount = _activateNominateMinPlayers?.GetInt32() ?? 5; if (clientsCount < leastActivateNominateCount) { client.PrintToChat(_bridge.ChatFormatter.Format( - $"当前在线人数不足 {ChatColor.Green}{leastActivateNominateCount}{ChatColor.White} 人,无法提名地图。")); + _localizer.Format("ptr.mapmanager.nominate_not_enough_players", leastActivateNominateCount))); return; } if (command.ArgCount < 1) { - client.PrintToChat(_bridge.ChatFormatter.Format("用法:.nominate <地图名>")); + client.PrintToChat(_bridge.ChatFormatter.Format(_localizer.Format("ptr.mapmanager.nominate_usage"))); return; } var map = command[1]; if (_bridge.NominatedMaps.Contains(map, StringComparer.OrdinalIgnoreCase)) { - client.PrintToChat("该地图已经被提名过了。"); + client.PrintToChat(_bridge.ChatFormatter.Format(_localizer.Format("ptr.mapmanager.map_already_nominated"))); return; } if (_bridge.PreviousGameMaps.Exists(x => x.MapName.Equals(map, StringComparison.OrdinalIgnoreCase))) { - client.PrintToChat("该地图最近已经玩过了,目前无法提名。"); + client.PrintToChat(_bridge.ChatFormatter.Format(_localizer.Format("ptr.mapmanager.map_recently_played"))); return; } if (_bridge.Maps.Exists(x => x.MapName.Equals(map, StringComparison.OrdinalIgnoreCase))) { - client.PrintToChat("无法从图池中找到该地图。"); + client.PrintToChat(_bridge.ChatFormatter.Format(_localizer.Format("ptr.mapmanager.map_not_found"))); return; } var currentMap = _bridge.GlobalVars.MapName; if (currentMap.Equals(map, StringComparison.OrdinalIgnoreCase)) { - client.PrintToChat("不能投票正在游玩的地图。"); + client.PrintToChat(_bridge.ChatFormatter.Format(_localizer.Format("ptr.mapmanager.cannot_nominate_current_map"))); return; } _bridge.NominatedMaps.Add(map); - _bridge.ModSharp.PrintToChatAll(_bridge.ChatFormatter.Format( - $"{ChatColor.Green}{client.Name}{ChatColor.White} 提名了地图 {ChatColor.Green}{map}{ChatColor.White}。")); + var allClients = _bridge.ClientManager.GetGameClients(true); + foreach (var c in allClients) + { + _localizerManager.TryGetLocalizer(c, out var _tempLocalizer); + if (_tempLocalizer is null) + { + _logger.LogWarning("Localizer not found for client {ClientSlot} when broadcasting nomination.", + c.Slot); + continue; + } + c.PrintToChat( + _bridge.ChatFormatter.Format(_tempLocalizer.Format("ptr.mapmanager.player_nominated_map", client.Name, map))); + } _logger.LogInformation("{ClientName} nominated {Map}", client.Name, map); } diff --git a/src/Ptr.Modules.MapManager/Services/RtvService.cs b/src/Ptr.Modules.MapManager/Services/RtvService.cs index 294345a..4043d18 100644 --- a/src/Ptr.Modules.MapManager/Services/RtvService.cs +++ b/src/Ptr.Modules.MapManager/Services/RtvService.cs @@ -1,6 +1,7 @@ using Microsoft.Extensions.Logging; using Ptr.Shared.Extensions; using Ptr.Shared.Hosting; +using Sharp.Modules.LocalizerManager.Shared; using Sharp.Shared.Definition; using Sharp.Shared.Enums; using Sharp.Shared.Listeners; @@ -17,6 +18,7 @@ internal class RtvService : IRtvService, IGameListener, IClientListener private readonly IConVar? _enableRtv; private readonly ILogger _logger; private readonly bool[] _rtvPlayers = new bool[64]; + private ILocalizerManager _localizerManager = null!; public RtvService(InterfaceBridge bridge, ILogger logger) { @@ -29,17 +31,25 @@ public RtvService(InterfaceBridge bridge, ILogger logger) private void AttemptRtv(IGameClient client) { + _localizerManager.TryGetLocalizer(client, out var _localizer); + if (_localizer is null) + { + _logger.LogWarning("Localizer not found for client {ClientSlot} when executing rtv command.", + client.Slot); + return; + } + var remaining = (int)(_bridge.AllowVoteTime - DateTime.Now).TotalSeconds; if (remaining > 0) { client.PrintToChat( - _bridge.ChatFormatter.Format($"{ChatColor.Green} {remaining} {ChatColor.White}秒后才能发起换图投票。")); + _bridge.ChatFormatter.Format(_localizer.Format("ptr.mapmanager.rtv_after_x", remaining))); return; } if (_rtvPlayers[client.Slot]) { - client.PrintToChat(_bridge.ChatFormatter.Format("你已经投票过换图了!")); + client.PrintToChat(_bridge.ChatFormatter.Format(_localizer.Format("ptr.mapmanager.already_voted_rtv"))); return; } @@ -47,15 +57,38 @@ private void AttemptRtv(IGameClient client) var current = _rtvPlayers.Count(rtvPlayer => rtvPlayer); var requested = _bridge.MapManager.GetVoteSuccessNumberRequested(); var clientGaps = requested - current; - _bridge.ModSharp.PrintToChatAll(_bridge.ChatFormatter.Format( - $"已有 {ChatColor.Green}{current}{ChatColor.White} 人投票换图,还需 {ChatColor.Green}{clientGaps}{ChatColor.White} 票。")); + + var allClients = _bridge.ClientManager.GetGameClients(true); + foreach (var c in allClients) + { + _localizerManager.TryGetLocalizer(c, out var _tempLocalizer); + if (_tempLocalizer is null) + { + _logger.LogWarning("Localizer not found for client {ClientSlot} when broadcasting rtv progress.", + c.Slot); + continue; + } + c.PrintToChat( + _bridge.ChatFormatter.Format(_tempLocalizer.Format("ptr.mapmanager.rtv_vote_progress", current, clientGaps))); + } if (clientGaps > 0) { return; } - _bridge.ModSharp.PrintToChatAll(_bridge.ChatFormatter.Format("投票换图通过!将在回合结束后开始投票。")); + foreach (var c in allClients) + { + _localizerManager.TryGetLocalizer(c, out var _tempLocalizer); + if (_tempLocalizer is null) + { + _logger.LogWarning("Localizer not found for client {ClientSlot} when broadcasting rtv passed.", + c.Slot); + continue; + } + c.PrintToChat( + _bridge.ChatFormatter.Format(_tempLocalizer.Format("ptr.mapmanager.rtv_vote_passed"))); + } _bridge.ModSharp.ServerCommand("mp_timelimit 0.00000001"); } @@ -83,6 +116,17 @@ public void OnInit() _bridge.ModSharp.InstallGameListener(this); } + public void OnAllModulesLoaded() + { + if (_enableRtv?.GetBool() is not true) + { + return; + } + + _localizerManager = _bridge.SharpModuleManager + .GetRequiredSharpModuleInterface(ILocalizerManager.Identity).Instance!; + } + public void OnShutdown() { if (_enableRtv?.GetBool() is not true) diff --git a/src/Ptr.Shared/Bridge/InterfaceBridge.cs b/src/Ptr.Shared/Bridge/InterfaceBridge.cs index 99e3aa4..0ca34b7 100644 --- a/src/Ptr.Shared/Bridge/InterfaceBridge.cs +++ b/src/Ptr.Shared/Bridge/InterfaceBridge.cs @@ -49,14 +49,14 @@ public InterfaceBridge(ISharedSystem sharedSystem, public IModSharp ModSharp => _sharedSystem.GetModSharp(); /// - /// CGlobalVars* gpGlobals,没什么好说的。
- /// 注意,一定要在地图加载之后调用!不然服务器第一次加载的时候是拿不到的! + /// CGlobalVars* gpGlobals.
+ /// Note: Must be called after the map is loaded! Otherwise it won't be available on the server's first load! ///
public IGlobalVars GlobalVars => ModSharp.GetGlobals(); /// /// CGameRules* g_pGameRules
- /// 注意,一定要在地图加载之后调用!不然服务器第一次加载的时候是拿不到的! + /// Note: Must be called after the map is loaded! Otherwise it won't be available on the server's first load! ///
public IGameRules GameRules => ModSharp.GetGameRules(); diff --git a/src/Ptr.Shared/Extensions/EntityManagerExtensions.cs b/src/Ptr.Shared/Extensions/EntityManagerExtensions.cs index 7dde914..6583acd 100644 --- a/src/Ptr.Shared/Extensions/EntityManagerExtensions.cs +++ b/src/Ptr.Shared/Extensions/EntityManagerExtensions.cs @@ -11,7 +11,7 @@ public static class EntityManagerExtensions extension(IEntityManager self) { /// - /// 通过PlayerSlot查找PlayerController + /// Find PlayerController by PlayerSlot /// public IPlayerController? GetPlayerController(PlayerSlot slot) { @@ -19,7 +19,7 @@ public static class EntityManagerExtensions } /// - /// 通过IGameClient查找PlayerController + /// Find PlayerController by IGameClient /// public IPlayerController? GetPlayerController(IGameClient client) { diff --git a/src/Ptr.Shared/Extensions/TransmitManagerExtensions.cs b/src/Ptr.Shared/Extensions/TransmitManagerExtensions.cs index 38d8374..796b685 100644 --- a/src/Ptr.Shared/Extensions/TransmitManagerExtensions.cs +++ b/src/Ptr.Shared/Extensions/TransmitManagerExtensions.cs @@ -11,11 +11,11 @@ public static class TransmitManagerExtensions extension(ITransmitManager self) { /// - /// 获取实体的Controller可见状态 + /// Get the entity's visibility state for a Controller /// /// Entity /// Player Controller - /// Channel, -1为读取全局状态 + /// Channel, -1 to read global state public bool GetEntityState(IBaseEntity entity, IPlayerController controller, int channel = -1) { @@ -23,11 +23,11 @@ public bool GetEntityState(IBaseEntity entity, IPlayerController controller, } /// - /// 设置实体的Controller可见状态 + /// Set the entity's visibility state for a Controller /// /// Entity /// Player Controller - /// 是否可见 + /// Whether visible /// Channel public bool SetEntityState(IBaseEntity entity, IPlayerController controller, bool transmit, int channel) @@ -36,7 +36,7 @@ public bool SetEntityState(IBaseEntity entity, IPlayerController controller, } /// - /// 获取实体是否被Block + /// Get whether the entity is blocked /// public bool GetEntityBlock(IBaseEntity entity) { @@ -44,7 +44,7 @@ public bool GetEntityBlock(IBaseEntity entity) } /// - /// 设置实体Block State + /// Set entity block state /// public bool SetEntityBlock(IBaseEntity entity, bool state) { @@ -52,7 +52,7 @@ public bool SetEntityBlock(IBaseEntity entity, bool state) } /// - /// 获取Hook中的实体Owner + /// Get the entity's owner in the hook /// /// -2 = NoHook | -1 = Null | other = Entity Index public int GetEntityOwner(IBaseEntity entity) @@ -61,19 +61,19 @@ public int GetEntityOwner(IBaseEntity entity) } /// - /// 设置Hook中的实体Owner + /// Set the entity's owner in the hook /// - /// 实体 - /// Owner实体的 + /// Entity + /// Owner entity public bool SetEntityOwner(IBaseEntity entity, IBaseEntity owner) { return self.SetEntityOwner(entity.Index, owner.Index); } /// - /// TempEnt的状态 + /// Get TempEnt state /// - /// TE类型 + /// TE type /// IGameClient public bool GetTempEntState(BlockTempEntType type, IGameClient client) { @@ -81,11 +81,11 @@ public bool GetTempEntState(BlockTempEntType type, IGameClient client) } /// - /// 设置TempEnt的状态 + /// Set TempEnt state /// - /// TE类型 + /// TE type /// IGameClient - /// 可见状态 + /// Visibility state public void SetTempEntState(BlockTempEntType type, IGameClient client, bool state) { @@ -93,7 +93,7 @@ public void SetTempEntState(BlockTempEntType type, IGameClient client, } /// - /// 重置接受者的所有实体状态 + /// Reset all entity states for the receiver /// /// receiver controller public void ClearReceiverState(IPlayerController receiver) diff --git a/src/Ptr.Shared/Hooks/Abstractions/AbstractHookService.cs b/src/Ptr.Shared/Hooks/Abstractions/AbstractHookService.cs index 1cdb1b4..4bbf647 100644 --- a/src/Ptr.Shared/Hooks/Abstractions/AbstractHookService.cs +++ b/src/Ptr.Shared/Hooks/Abstractions/AbstractHookService.cs @@ -15,12 +15,12 @@ namespace Ptr.Shared.Hooks.Abstractions; internal interface IHookService where TParams : class, IFunctionParams { /// - /// 泛播给其他的订户 + /// Broadcast to other subscribers /// - /// Hook参数 - /// Hook的返回值 (如果是void, 直接写int就好) + /// Hook parameters + /// Hook return value (if void, just use int) /// - /// 封装了Hook操作和Hook的返回值 + /// Encapsulates the hook action and hook return value HookReturnValue InvokeHookPre(TParams @params); void InvokeHookPost(TParams @params, HookReturnValue @return); diff --git a/src/Ptr.Shared/Misc/ChatMessageFormatter.cs b/src/Ptr.Shared/Misc/ChatMessageFormatter.cs index c21956a..5d75365 100644 --- a/src/Ptr.Shared/Misc/ChatMessageFormatter.cs +++ b/src/Ptr.Shared/Misc/ChatMessageFormatter.cs @@ -49,7 +49,10 @@ internal static class ChatMessageFormatterExtensions { "{blue}", ChatColor.Blue }, { "{darkblue}", ChatColor.DarkBlue }, { "{purple}", ChatColor.Purple }, - { "{lightred}", ChatColor.LightRed } + { "{lightred}", ChatColor.LightRed }, + { "{muted}", ChatColor.Muted }, + { "{head}", ChatColor.Head }, + { "{whitespace}", "\u00A0" } }; extension(string self) diff --git a/src/Ptr.Shared/Types/QAngle.cs b/src/Ptr.Shared/Types/QAngle.cs index 7d1a383..3754198 100644 --- a/src/Ptr.Shared/Types/QAngle.cs +++ b/src/Ptr.Shared/Types/QAngle.cs @@ -154,7 +154,7 @@ public float LengthSqr() } /// - /// 常规化 + /// Normalize /// public void Normalize() { diff --git a/src/Sharp.Modules.AdminManager.Shared/AdminTableManifest.cs b/src/Sharp.Modules.AdminManager.Shared/AdminTableManifest.cs index 918d2c0..7f1c8a4 100644 --- a/src/Sharp.Modules.AdminManager.Shared/AdminTableManifest.cs +++ b/src/Sharp.Modules.AdminManager.Shared/AdminTableManifest.cs @@ -16,24 +16,24 @@ namespace Sharp.Modules.AdminManager.Shared; "users": [ { "user_id": "u100", - // 权限数组:@开头表示继承角色,其他表示直接权限 + // Permission array: @ prefix means inherit from role, others are direct permissions "permissions": ["@global_root", "!pluginB:slay"] - // 解析后:global_root的所有权限(*) + 直接拒绝pluginB:slay + // Resolved: all permissions from global_root (*) + directly deny pluginB:slay }, { "user_id": "u104", "permissions": ["@pluginA_admin", "@pluginB_kicker"] - // 解析后:pluginA:*(插件A所有) + pluginB:kick(插件B踢人) + // Resolved: pluginA:* (all of plugin A) + pluginB:kick (plugin B kick) }, { "user_id": "u105", "permissions": ["pluginA:getWeapon", "!pluginA:fetchItems"] - // 解析后:仅直接允许getWeapon + 直接拒绝fetchItems(不继承任何角色) + // Resolved: only directly allow getWeapon + directly deny fetchItems (no role inheritance) }, { "user_id": "u106", "permissions": ["@pluginA_admin", "pluginB:slay"] - // 解析后:pluginA:*(来自角色) + 直接允许pluginB:slay + // Resolved: pluginA:* (from role) + directly allow pluginB:slay } ] }*/ diff --git a/src/Sharp.Modules.AdminManager.Shared/IAdmin.cs b/src/Sharp.Modules.AdminManager.Shared/IAdmin.cs index 86c6594..9e65a82 100644 --- a/src/Sharp.Modules.AdminManager.Shared/IAdmin.cs +++ b/src/Sharp.Modules.AdminManager.Shared/IAdmin.cs @@ -24,7 +24,7 @@ namespace Sharp.Modules.AdminManager.Shared; public interface IAdmin { /// - /// 管理员名字 + /// Admin name /// string Name { get; } @@ -34,33 +34,33 @@ public interface IAdmin SteamID Identity { get; } /// - /// 权限级别 + /// Immunity level /// byte Immunity { get; } /// - /// 权限 + /// Permissions /// IReadOnlySet Permissions { get; } /// - /// 是否拥有权限 + /// Check if has permission /// - /// 权限字段 + /// Permission field /// bool HasPermission(string permission); /// - /// 添加权限 + /// Add permission /// - /// 权限字段 + /// Permission field /// bool AddPermission(string permission); /// - /// 删除权限 + /// Remove permission /// - /// 权限字段 + /// Permission field /// bool RemovePermission(string permission); } \ No newline at end of file diff --git a/src/Sharp.Modules.AdminManager/AdminManager.cs b/src/Sharp.Modules.AdminManager/AdminManager.cs index dd00e05..56baa44 100644 --- a/src/Sharp.Modules.AdminManager/AdminManager.cs +++ b/src/Sharp.Modules.AdminManager/AdminManager.cs @@ -12,8 +12,8 @@ namespace Sharp.Modules.AdminManager; // https://www.doubao.com/thread/wc0f1c5cae120c2bb -// 核心目的是集中管理员注册机制,让所有管理员的注册逻辑都走同一个。 -// 由此,复杂是不可避免的:因为这里涉及到二级key。 +// The core purpose is to centralize the admin registration mechanism, making all admin registration logic go through the same path. +// Therefore, complexity is unavoidable: because this involves secondary keys. using PermissionCollectionDictionary = Dictionary< string, // Collection key @@ -42,7 +42,7 @@ private readonly Dictionary< string, // module identity RolesDictionary> _roles = new(StringComparer.OrdinalIgnoreCase); - // 这个无视所有插件的,这个是统一的,这个只是用来方便内部调用的,跟外部无关。 + // This ignores all plugins, it's unified, it's only used for convenient internal calls, unrelated to external usage. private readonly HashSet _allConcretePermissions = new(StringComparer.OrdinalIgnoreCase); // Centralized admin storage - all admins from all modules diff --git a/src/Sharp.Modules.CommandManager.Shared/ICommandManager.cs b/src/Sharp.Modules.CommandManager.Shared/ICommandManager.cs index e85aa84..7661519 100644 --- a/src/Sharp.Modules.CommandManager.Shared/ICommandManager.cs +++ b/src/Sharp.Modules.CommandManager.Shared/ICommandManager.cs @@ -19,40 +19,40 @@ public interface ICommandManager public interface ICommandRegistry { /// - /// 注册用户指令。
- /// 该指令可被如下途径调用:
- /// 1. 聊天栏中输入 .{该指令内容},例:.ztele。
- /// (注:你可以将.换成!或/,它们都是一样的。)
- /// 2. 客户端控制台,你必须添加`ms_`前缀,例:ms_ztele。
- /// 此函数注册的指令无法被服务端控制台调用。 + /// Register a client command.
+ /// This command can be invoked by:
+ /// 1. Typing .{command} in chat, e.g., .ztele.
+ /// (Note: You can use ! or / instead of ., they are equivalent.)
+ /// 2. Client console, you must add the `ms_` prefix, e.g., ms_ztele.
+ /// Commands registered with this function cannot be called from the server console. ///
- /// 指令,你可以不添加ms_前缀,注册的时候会给你自动加上。你也可以加上,这个不影响。但是如果你是ms_ms_这种,那我们爱莫能助。 + /// The command, you don't need to add the ms_ prefix, it will be added automatically during registration. You can also add it yourself, this doesn't matter. But if you use ms_ms_, we can't help you. /// void RegisterClientCommand(string command, Action call); /// - /// 创建一个控制台指令。
- /// 该指令只会在服务端控制台生效。 + /// Create a server console command.
+ /// This command only works in the server console. ///
/// - /// 是否要添加ms_前缀?默认添加。 + /// Whether to add ms_ prefix? Default is true. /// /// void RegisterServerCommand(string command, Action call, string description = "", bool addPrefix = true); /// - /// 创建一个控制台指令。
- /// 该指令只会在服务端控制台生效。 + /// Create a server console command.
+ /// This command only works in the server console. ///
/// - /// 是否要添加ms_前缀?默认添加。 + /// Whether to add ms_ prefix? Default is true. /// /// void RegisterServerCommand(string command, Action call, string description = "", bool addPrefix = true); /// - /// 注册一个「通用」指令:客户端聊天栏,客户端控制台,服务端控制台均可使用。
- /// 一定会添加ms_标签,请注意 + /// Register a "generic" command: can be used from client chat, client console, and server console.
+ /// Will always add the ms_ prefix, please note. ///
/// /// @@ -60,18 +60,18 @@ public interface ICommandRegistry void RegisterGenericCommand(string command, Action call, string description = ""); /// - /// 创建一个控制台指令。
- /// 该指令只会在客户端控制台和服务端控制台生效。
+ /// Create a console command.
+ /// This command only works in client console and server console.
///
/// /// - /// 是否添加ms_前缀?默认添加。 + /// Whether to add ms_ prefix? Default is true. void RegisterConsoleCommand(string command, Action callback, bool addPrefix = true); /// - /// 监听指令。
- /// 一般来说,该函数只用于监听客户端控制台内输入的指令,如player_ping。
- /// 可自行参阅函数调用。 + /// Listen for a command.
+ /// Generally, this function is only used to listen for commands entered in the client console, such as player_ping.
+ /// Refer to function calls for details. ///
/// /// diff --git a/src/Sharp.Modules.CommandManager/CommandManager.cs b/src/Sharp.Modules.CommandManager/CommandManager.cs index 351c48c..530036c 100644 --- a/src/Sharp.Modules.CommandManager/CommandManager.cs +++ b/src/Sharp.Modules.CommandManager/CommandManager.cs @@ -91,7 +91,7 @@ public bool IsCommandExists(string command) } /// - /// 获取经过ms_装饰后的指令,这个一般只有服务端控制台指令需要 + /// Get the command decorated with ms_ prefix, this is generally only needed for server console commands /// /// /// @@ -112,7 +112,7 @@ public string GetAddPrefixCommand(string originalCommand, bool addPrefix = true) } /// - /// 判断是否有ms_前缀 + /// Check if the command has ms_ prefix /// /// /// @@ -122,7 +122,7 @@ public bool HasPrefix(string command) } /// - /// 获取移除ms_装饰后的指令,这个一般只有游戏内指令需要 + /// Get the command with ms_ prefix removed, this is generally only needed for in-game commands /// /// /// From 5839d533eb13123af7ccdb3b85db005cf02a7f41 Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Mon, 5 Jan 2026 22:27:23 +0200 Subject: [PATCH 02/24] fix applygamessettings hook --- src/Directory.Build.props | 2 ++ src/Ptr.Modules.MapManager/MapManager.cs | 11 ++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index f37242f..af58c6d 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -9,6 +9,8 @@ $([System.String]::new('$(MSBuildProjectName)').EndsWith('.Shared')) true $([System.String]::new('$(MSBuildProjectName)').Contains('.Modules.')) + + true diff --git a/src/Ptr.Modules.MapManager/MapManager.cs b/src/Ptr.Modules.MapManager/MapManager.cs index 1016674..0242777 100644 --- a/src/Ptr.Modules.MapManager/MapManager.cs +++ b/src/Ptr.Modules.MapManager/MapManager.cs @@ -51,7 +51,6 @@ public MapManager( services.AddLogging(x => x.ClearProviders()); var provider = services.BuildServiceProvider(); - provider.UseHook(); _bridge = provider.GetRequiredService(); _logger = sharedSystem.GetLoggerFactory().CreateLogger(); @@ -128,10 +127,6 @@ public bool Init() { InitConfig(); - _provider.LoadAllSharpExtensions(); - _provider.InitNativeHooks(); - _provider.CallInit(e => { _logger.LogError(e, "An error occurred when initializing modules"); }); - return true; } @@ -168,11 +163,17 @@ public void OnLibraryConnected(string name) public void OnAllModulesLoaded() { + _provider.LoadAllSharpExtensions(); + _provider.InitNativeHooks(); + _provider.CallInit(e => { _logger.LogError(e, "An error occurred when initializing modules"); }); + _provider.UseHook(); + CallMapConfigLoaded(); var _localizerManager = _bridge.SharpModuleManager .GetRequiredSharpModuleInterface(ILocalizerManager.Identity).Instance!; _localizerManager.LoadLocaleFile("Ptr.Modules.MapManager"); + } public void Shutdown() From 98cef8bf06d98703276b98649e2766d0f1a7f3f0 Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Mon, 5 Jan 2026 22:33:19 +0200 Subject: [PATCH 03/24] translation for all languages --- .../sharp/locales/Ptr.Modules.MapManager.json | 464 +++++++++++++++++- 1 file changed, 448 insertions(+), 16 deletions(-) diff --git a/.asset/game/sharp/locales/Ptr.Modules.MapManager.json b/.asset/game/sharp/locales/Ptr.Modules.MapManager.json index 40f9de8..8c8614f 100644 --- a/.asset/game/sharp/locales/Ptr.Modules.MapManager.json +++ b/.asset/game/sharp/locales/Ptr.Modules.MapManager.json @@ -1,66 +1,498 @@ { "ptr.mapmanager.extend_map_after_x": { "en-us": "A vote to extend the map time can only be initiated after {green}{0}{white} seconds.", - "zh-cn": "{green}{0}{white} 秒后才能发起延长地图时间投票. " + "zh-cn": "{green}{0}{white} 秒后才能发起延长地图时间投票.", + "zh-tw": "{green}{0}{white} 秒後才能發起延長地圖時間投票。", + "pt-br": "Uma votacao para estender o tempo do mapa so pode ser iniciada apos {green}{0}{white} segundos.", + "bg-bg": "Гласуване за удължаване на времето на картата може да бъде започнато след {green}{0}{white} секунди.", + "cs-cz": "Hlasovani o prodlouzeni casu mapy lze zahajit az po {green}{0}{white} sekundach.", + "da-dk": "En afstemning om at forlaenge kortets tid kan forst startes efter {green}{0}{white} sekunder.", + "nl-nl": "Een stemming om de maptijd te verlengen kan pas worden gestart na {green}{0}{white} seconden.", + "fi-fi": "Aanestys kartan ajan jatkamisesta voidaan aloittaa vasta {green}{0}{white} sekunnin kuluttua.", + "fr-fr": "Un vote pour prolonger le temps de la carte ne peut etre lance qu'apres {green}{0}{white} secondes.", + "de-de": "Eine Abstimmung zur Verlangerung der Kartenzeit kann erst nach {green}{0}{white} Sekunden gestartet werden.", + "el-gr": "Μια ψηφοφορια για παραταση του χρονου του χαρτη μπορει να ξεκινησει μετα απο {green}{0}{white} δευτερολεπτα.", + "hu-hu": "A palya idejének meghosszabbitasara vonatkozo szavazas csak {green}{0}{white} masodperc utan inditható.", + "id-id": "Pemungutan suara untuk memperpanjang waktu peta hanya dapat dimulai setelah {green}{0}{white} detik.", + "it-it": "Una votazione per estendere il tempo della mappa puo essere avviata solo dopo {green}{0}{white} secondi.", + "ja-jp": "マップ時間延長の投票は {green}{0}{white} 秒後にのみ開始できます。", + "ko-kr": "맵 시간 연장 투표는 {green}{0}{white}초 후에만 시작할 수 있습니다.", + "es-419": "Una votacion para extender el tiempo del mapa solo puede iniciarse despues de {green}{0}{white} segundos.", + "nb-no": "En avstemning for a forlenge karttiden kan bare startes etter {green}{0}{white} sekunder.", + "pl-pl": "Glosowanie nad przedluzeniem czasu mapy mozna rozpoczac dopiero po {green}{0}{white} sekundach.", + "pt-pt": "Uma votacao para prolongar o tempo do mapa so pode ser iniciada apos {green}{0}{white} segundos.", + "ro-ro": "Un vot pentru prelungirea timpului hartii poate fi initiat doar dupa {green}{0}{white} secunde.", + "ru-ru": "Голосование за продление времени карты можно начать только через {green}{0}{white} секунд.", + "es-es": "Una votacion para extender el tiempo del mapa solo puede iniciarse despues de {green}{0}{white} segundos.", + "sv-se": "En omrostning for att forlanga karttiden kan bara startas efter {green}{0}{white} sekunder.", + "th-th": "การโหวตขยายเวลาแผนที่สามารถเริ่มได้หลังจาก {green}{0}{white} วินาที", + "tr-tr": "Harita suresini uzatmak icin oylama ancak {green}{0}{white} saniye sonra baslatilabilir.", + "uk-ua": "Голосування за продовження часу карти можна розпочати лише через {green}{0}{white} секунд.", + "vi-vn": "Cuoc bo phieu gia han thoi gian ban do chi co the bat dau sau {green}{0}{white} giay." }, "ptr.mapmanager.max_extends_reached": { "en-us": "The maximum number of times the time can be extended has been reached.", - "zh-cn": "已到达最大可延长时间次数。" + "zh-cn": "已到达最大可延长时间次数。", + "zh-tw": "已達到最大可延長時間次數。", + "pt-br": "O numero maximo de vezes que o tempo pode ser estendido foi atingido.", + "bg-bg": "Достигнат е максималният брой пъти, в които времето може да бъде удължено.", + "cs-cz": "Bylo dosazeno maximalniho poctu prodlouzeni casu.", + "da-dk": "Det maksimale antal gange tiden kan forlaenges er naet.", + "nl-nl": "Het maximale aantal keren dat de tijd kan worden verlengd is bereikt.", + "fi-fi": "Ajan jatkamisen enimmaismaara on saavutettu.", + "fr-fr": "Le nombre maximum de prolongations du temps a ete atteint.", + "de-de": "Die maximale Anzahl an Zeitverlangerungen wurde erreicht.", + "el-gr": "Εχει επιτευχθει ο μεγιστος αριθμος παρατασεων χρονου.", + "hu-hu": "Elerte a maximalis idomeghosszabbitasok szamat.", + "id-id": "Jumlah maksimum perpanjangan waktu telah tercapai.", + "it-it": "E stato raggiunto il numero massimo di estensioni del tempo.", + "ja-jp": "時間延長の最大回数に達しました。", + "ko-kr": "시간 연장 최대 횟수에 도달했습니다.", + "es-419": "Se ha alcanzado el numero maximo de extensiones de tiempo.", + "nb-no": "Maksimalt antall tidsforlengelser er nadd.", + "pl-pl": "Osiagnieto maksymalna liczbe przedluzen czasu.", + "pt-pt": "O numero maximo de prolongamentos de tempo foi atingido.", + "ro-ro": "A fost atins numarul maxim de prelungiri ale timpului.", + "ru-ru": "Достигнуто максимальное количество продлений времени.", + "es-es": "Se ha alcanzado el numero maximo de extensiones de tiempo.", + "sv-se": "Det maximala antalet tidsforlangningar har uppnatts.", + "th-th": "ถึงจำนวนครั้งสูงสุดที่สามารถขยายเวลาได้แล้ว", + "tr-tr": "Maksimum sure uzatma sayisina ulasildi.", + "uk-ua": "Досягнуто максимальну кількість продовжень часу.", + "vi-vn": "Da dat so lan gia han thoi gian toi da." }, "ptr.mapmanager.you_already_voted_to_extend": { "en-us": "You have already voted to extend the map time.", - "zh-cn": "你已经投票过延长地图时间了。" + "zh-cn": "你已经投票过延长地图时间了。", + "zh-tw": "你已經投票過延長地圖時間了。", + "pt-br": "Voce ja votou para estender o tempo do mapa.", + "bg-bg": "Вече сте гласували за удължаване на времето на картата.", + "cs-cz": "Jiz jste hlasovali pro prodlouzeni casu mapy.", + "da-dk": "Du har allerede stemt for at forlaenge kortets tid.", + "nl-nl": "Je hebt al gestemd om de maptijd te verlengen.", + "fi-fi": "Olet jo aanestanyt kartan ajan jatkamisesta.", + "fr-fr": "Vous avez deja vote pour prolonger le temps de la carte.", + "de-de": "Du hast bereits fur die Verlangerung der Kartenzeit gestimmt.", + "el-gr": "Εχετε ηδη ψηφισει για παραταση του χρονου του χαρτη.", + "hu-hu": "Mar szavaztal a palya idejének meghosszabbitasara.", + "id-id": "Anda sudah memberikan suara untuk memperpanjang waktu peta.", + "it-it": "Hai gia votato per estendere il tempo della mappa.", + "ja-jp": "マップ時間延長に既に投票済みです。", + "ko-kr": "이미 맵 시간 연장에 투표하셨습니다.", + "es-419": "Ya has votado para extender el tiempo del mapa.", + "nb-no": "Du har allerede stemt for a forlenge karttiden.", + "pl-pl": "Juz glosowaes za przedluzeniem czasu mapy.", + "pt-pt": "Ja votou para prolongar o tempo do mapa.", + "ro-ro": "Ai votat deja pentru prelungirea timpului hartii.", + "ru-ru": "Вы уже голосовали за продление времени карты.", + "es-es": "Ya has votado para extender el tiempo del mapa.", + "sv-se": "Du har redan rostat for att forlanga karttiden.", + "th-th": "คุณได้โหวตขยายเวลาแผนที่ไปแล้ว", + "tr-tr": "Harita suresini uzatmak icin zaten oy kullandiniz.", + "uk-ua": "Ви вже голосували за продовження часу карти.", + "vi-vn": "Ban da bo phieu gia han thoi gian ban do roi." }, "ptr.mapmanager.extend_vote_progress": { "en-us": "{green}{0}{white} players have voted to extend the map time, {green}{1}{white} more votes needed.", - "zh-cn": "已有 {green}{0}{white} 人投票延长地图时间,还需 {green}{1}{white} 票。" + "zh-cn": "已有 {green}{0}{white} 人投票延长地图时间,还需 {green}{1}{white} 票。", + "zh-tw": "已有 {green}{0}{white} 人投票延長地圖時間,還需 {green}{1}{white} 票。", + "pt-br": "{green}{0}{white} jogadores votaram para estender o tempo do mapa, {green}{1}{white} votos a mais necessarios.", + "bg-bg": "{green}{0}{white} играчи гласуваха за удължаване на времето, необходими са още {green}{1}{white} гласа.", + "cs-cz": "{green}{0}{white} hracu hlasovalo pro prodlouzeni casu mapy, potreba jeste {green}{1}{white} hlasu.", + "da-dk": "{green}{0}{white} spillere har stemt for at forlaenge kortets tid, {green}{1}{white} flere stemmer nodvendige.", + "nl-nl": "{green}{0}{white} spelers hebben gestemd om de maptijd te verlengen, nog {green}{1}{white} stemmen nodig.", + "fi-fi": "{green}{0}{white} pelaajaa on aanestanyt ajan jatkamisesta, {green}{1}{white} aanta viela tarvitaan.", + "fr-fr": "{green}{0}{white} joueurs ont vote pour prolonger le temps, {green}{1}{white} votes supplementaires requis.", + "de-de": "{green}{0}{white} Spieler haben fur die Zeitverlangerung gestimmt, {green}{1}{white} weitere Stimmen benotigt.", + "el-gr": "{green}{0}{white} παικτες ψηφισαν για παραταση χρονου, χρειαζονται ακομη {green}{1}{white} ψηφοι.", + "hu-hu": "{green}{0}{white} jatekos szavazott az idomeghosszabbitasra, meg {green}{1}{white} szavazat szukseges.", + "id-id": "{green}{0}{white} pemain telah memilih untuk memperpanjang waktu, {green}{1}{white} suara lagi diperlukan.", + "it-it": "{green}{0}{white} giocatori hanno votato per estendere il tempo, servono altri {green}{1}{white} voti.", + "ja-jp": "{green}{0}{white} 人が時間延長に投票しました。あと {green}{1}{white} 票必要です。", + "ko-kr": "{green}{0}{white}명이 시간 연장에 투표했습니다. {green}{1}{white}표 더 필요합니다.", + "es-419": "{green}{0}{white} jugadores han votado para extender el tiempo, se necesitan {green}{1}{white} votos mas.", + "nb-no": "{green}{0}{white} spillere har stemt for a forlenge tiden, {green}{1}{white} flere stemmer trengs.", + "pl-pl": "{green}{0}{white} graczy zaglosowalo za przedluzeniem czasu, potrzeba jeszcze {green}{1}{white} glosow.", + "pt-pt": "{green}{0}{white} jogadores votaram para prolongar o tempo, necessarios mais {green}{1}{white} votos.", + "ro-ro": "{green}{0}{white} jucatori au votat pentru prelungirea timpului, mai sunt necesare {green}{1}{white} voturi.", + "ru-ru": "{green}{0}{white} игроков проголосовало за продление времени, нужно ещё {green}{1}{white} голосов.", + "es-es": "{green}{0}{white} jugadores han votado para extender el tiempo, se necesitan {green}{1}{white} votos mas.", + "sv-se": "{green}{0}{white} spelare har rostat for att forlanga tiden, {green}{1}{white} fler roster behovs.", + "th-th": "{green}{0}{white} ผู้เล่นโหวตขยายเวลาแล้ว ต้องการอีก {green}{1}{white} โหวต", + "tr-tr": "{green}{0}{white} oyuncu sure uzatmak icin oy kullandi, {green}{1}{white} oy daha gerekli.", + "uk-ua": "{green}{0}{white} гравців проголосували за продовження часу, потрібно ще {green}{1}{white} голосів.", + "vi-vn": "{green}{0}{white} nguoi choi da bo phieu gia han thoi gian, can them {green}{1}{white} phieu nua." }, "ptr.mapmanager.extend_vote_passed": { "en-us": "Vote passed, the map time will be extended.", - "zh-cn": "投票通过,即将延长地图持续时间。" + "zh-cn": "投票通过,即将延长地图持续时间。", + "zh-tw": "投票通過,即將延長地圖持續時間。", + "pt-br": "Votacao aprovada, o tempo do mapa sera estendido.", + "bg-bg": "Гласуването премина, времето на картата ще бъде удължено.", + "cs-cz": "Hlasovani proslo, cas mapy bude prodlouzen.", + "da-dk": "Afstemningen er godkendt, kortets tid vil blive forlaenget.", + "nl-nl": "Stemming geslaagd, de maptijd wordt verlengd.", + "fi-fi": "Aanestys hyvaksytty, kartan aikaa jatketaan.", + "fr-fr": "Vote approuve, le temps de la carte sera prolonge.", + "de-de": "Abstimmung erfolgreich, die Kartenzeit wird verlangert.", + "el-gr": "Η ψηφοφορια περασε, ο χρονος του χαρτη θα παραταθει.", + "hu-hu": "Szavazas elfogadva, a palya ideje meghosszabbitasra kerul.", + "id-id": "Pemungutan suara berhasil, waktu peta akan diperpanjang.", + "it-it": "Votazione approvata, il tempo della mappa sara esteso.", + "ja-jp": "投票が可決されました。マップ時間が延長されます。", + "ko-kr": "투표가 통과되었습니다. 맵 시간이 연장됩니다.", + "es-419": "Votacion aprobada, el tiempo del mapa sera extendido.", + "nb-no": "Avstemningen ble godkjent, karttiden vil bli forlenget.", + "pl-pl": "Glosowanie przeszlo, czas mapy zostanie przedluzony.", + "pt-pt": "Votacao aprovada, o tempo do mapa sera prolongado.", + "ro-ro": "Votul a trecut, timpul hartii va fi prelungit.", + "ru-ru": "Голосование прошло, время карты будет продлено.", + "es-es": "Votacion aprobada, el tiempo del mapa sera extendido.", + "sv-se": "Omrostningen godkandes, karttiden kommer att forlangas.", + "th-th": "โหวตผ่าน เวลาแผนที่จะถูกขยาย", + "tr-tr": "Oylama gecti, harita suresi uzatilacak.", + "uk-ua": "Голосування пройшло, час карти буде продовжено.", + "vi-vn": "Bo phieu thanh cong, thoi gian ban do se duoc gia han." }, "ptr.mapmanager.nominate_not_enough_players": { "en-us": "At least {green}{0}{white} players are required to nominate maps.", - "zh-cn": "当前在线人数不足 {green}{0}{white} 人,无法提名地图。" + "zh-cn": "当前在线人数不足 {green}{0}{white} 人,无法提名地图。", + "zh-tw": "當前在線人數不足 {green}{0}{white} 人,無法提名地圖。", + "pt-br": "Sao necessarios pelo menos {green}{0}{white} jogadores para nomear mapas.", + "bg-bg": "Необходими са поне {green}{0}{white} играчи за номиниране на карти.", + "cs-cz": "Pro nominaci map je potreba alespon {green}{0}{white} hracu.", + "da-dk": "Der kraeves mindst {green}{0}{white} spillere for at nominere kort.", + "nl-nl": "Er zijn minimaal {green}{0}{white} spelers nodig om maps te nomineren.", + "fi-fi": "Karttojen ehdottamiseen tarvitaan vahintaan {green}{0}{white} pelaajaa.", + "fr-fr": "Au moins {green}{0}{white} joueurs sont requis pour nominer des cartes.", + "de-de": "Mindestens {green}{0}{white} Spieler werden benotigt, um Karten zu nominieren.", + "el-gr": "Απαιτουνται τουλαχιστον {green}{0}{white} παικτες για να προτεινετε χαρτες.", + "hu-hu": "Legalabb {green}{0}{white} jatekos szukseges a palyak jelolesehez.", + "id-id": "Diperlukan setidaknya {green}{0}{white} pemain untuk menominasikan peta.", + "it-it": "Sono necessari almeno {green}{0}{white} giocatori per nominare mappe.", + "ja-jp": "マップをノミネートするには少なくとも {green}{0}{white} 人のプレイヤーが必要です。", + "ko-kr": "맵 추천에는 최소 {green}{0}{white}명의 플레이어가 필요합니다.", + "es-419": "Se requieren al menos {green}{0}{white} jugadores para nominar mapas.", + "nb-no": "Minst {green}{0}{white} spillere kreves for a nominere kart.", + "pl-pl": "Do nominowania map wymaganych jest co najmniej {green}{0}{white} graczy.", + "pt-pt": "Sao necessarios pelo menos {green}{0}{white} jogadores para nomear mapas.", + "ro-ro": "Sunt necesari cel putin {green}{0}{white} jucatori pentru a nominaliza harti.", + "ru-ru": "Для номинации карт требуется минимум {green}{0}{white} игроков.", + "es-es": "Se requieren al menos {green}{0}{white} jugadores para nominar mapas.", + "sv-se": "Minst {green}{0}{white} spelare kravs for att nominera kartor.", + "th-th": "ต้องมีผู้เล่นอย่างน้อย {green}{0}{white} คนเพื่อเสนอชื่อแผนที่", + "tr-tr": "Harita aday gostermek icin en az {green}{0}{white} oyuncu gereklidir.", + "uk-ua": "Для номінації карт потрібно мінімум {green}{0}{white} гравців.", + "vi-vn": "Can it nhat {green}{0}{white} nguoi choi de de cu ban do." }, "ptr.mapmanager.nominate_usage": { "en-us": "Usage: .nominate ", - "zh-cn": "用法:.nominate <地图名>" + "zh-cn": "用法:.nominate <地图名>", + "zh-tw": "用法:.nominate <地圖名>", + "pt-br": "Uso: .nominate ", + "bg-bg": "Употреба: .nominate <име на картата>", + "cs-cz": "Pouziti: .nominate ", + "da-dk": "Brug: .nominate ", + "nl-nl": "Gebruik: .nominate ", + "fi-fi": "Kaytto: .nominate ", + "fr-fr": "Utilisation: .nominate ", + "de-de": "Verwendung: .nominate ", + "el-gr": "Χρηση: .nominate <ονομα χαρτη>", + "hu-hu": "Hasznalat: .nominate ", + "id-id": "Penggunaan: .nominate ", + "it-it": "Uso: .nominate ", + "ja-jp": "使用法: .nominate <マップ名>", + "ko-kr": "사용법: .nominate <맵 이름>", + "es-419": "Uso: .nominate ", + "nb-no": "Bruk: .nominate ", + "pl-pl": "Uzycie: .nominate ", + "pt-pt": "Utilizacao: .nominate ", + "ro-ro": "Utilizare: .nominate ", + "ru-ru": "Использование: .nominate <название карты>", + "es-es": "Uso: .nominate ", + "sv-se": "Anvandning: .nominate ", + "th-th": "วิธีใช้: .nominate <ชื่อแผนที่>", + "tr-tr": "Kullanim: .nominate ", + "uk-ua": "Використання: .nominate <назва карти>", + "vi-vn": "Cach dung: .nominate " }, "ptr.mapmanager.map_already_nominated": { "en-us": "This map has already been nominated.", - "zh-cn": "该地图已经被提名过了。" + "zh-cn": "该地图已经被提名过了。", + "zh-tw": "該地圖已經被提名過了。", + "pt-br": "Este mapa ja foi nomeado.", + "bg-bg": "Тази карта вече е номинирана.", + "cs-cz": "Tato mapa jiz byla nominovana.", + "da-dk": "Dette kort er allerede nomineret.", + "nl-nl": "Deze map is al genomineerd.", + "fi-fi": "Tama kartta on jo ehdotettu.", + "fr-fr": "Cette carte a deja ete nominee.", + "de-de": "Diese Karte wurde bereits nominiert.", + "el-gr": "Αυτος ο χαρτης εχει ηδη προταθει.", + "hu-hu": "Ez a palya mar jelolve lett.", + "id-id": "Peta ini sudah dinominasikan.", + "it-it": "Questa mappa e gia stata nominata.", + "ja-jp": "このマップは既にノミネートされています。", + "ko-kr": "이 맵은 이미 추천되었습니다.", + "es-419": "Este mapa ya ha sido nominado.", + "nb-no": "Dette kartet er allerede nominert.", + "pl-pl": "Ta mapa zostala juz nominowana.", + "pt-pt": "Este mapa ja foi nomeado.", + "ro-ro": "Aceasta harta a fost deja nominalizata.", + "ru-ru": "Эта карта уже номинирована.", + "es-es": "Este mapa ya ha sido nominado.", + "sv-se": "Denna karta har redan nominerats.", + "th-th": "แผนที่นี้ถูกเสนอชื่อไปแล้ว", + "tr-tr": "Bu harita zaten aday gosterildi.", + "uk-ua": "Ця карта вже номінована.", + "vi-vn": "Ban do nay da duoc de cu." }, "ptr.mapmanager.map_recently_played": { "en-us": "This map was played recently and cannot be nominated.", - "zh-cn": "该地图最近已经玩过了,目前无法提名。" + "zh-cn": "该地图最近已经玩过了,目前无法提名。", + "zh-tw": "該地圖最近已經玩過了,目前無法提名。", + "pt-br": "Este mapa foi jogado recentemente e nao pode ser nomeado.", + "bg-bg": "Тази карта беше играна наскоро и не може да бъде номинирана.", + "cs-cz": "Tato mapa byla nedavno hrana a nelze ji nominovat.", + "da-dk": "Dette kort blev spillet for nylig og kan ikke nomineres.", + "nl-nl": "Deze map is recent gespeeld en kan niet worden genomineerd.", + "fi-fi": "Tata karttaa pelattiin aiemmin eika sita voi ehdottaa.", + "fr-fr": "Cette carte a ete jouee recemment et ne peut pas etre nominee.", + "de-de": "Diese Karte wurde kurzlich gespielt und kann nicht nominiert werden.", + "el-gr": "Αυτος ο χαρτης παιχτηκε προσφατα και δεν μπορει να προταθει.", + "hu-hu": "Ezt a palyat nemreg jatszottak es nem jelolheto.", + "id-id": "Peta ini baru saja dimainkan dan tidak dapat dinominasikan.", + "it-it": "Questa mappa e stata giocata di recente e non puo essere nominata.", + "ja-jp": "このマップは最近プレイされたためノミネートできません。", + "ko-kr": "이 맵은 최근에 플레이되어 추천할 수 없습니다.", + "es-419": "Este mapa se jugo recientemente y no puede ser nominado.", + "nb-no": "Dette kartet ble spilt nylig og kan ikke nomineres.", + "pl-pl": "Ta mapa byla niedawno grana i nie moze byc nominowana.", + "pt-pt": "Este mapa foi jogado recentemente e nao pode ser nomeado.", + "ro-ro": "Aceasta harta a fost jucata recent si nu poate fi nominalizata.", + "ru-ru": "Эта карта недавно игралась и не может быть номинирована.", + "es-es": "Este mapa se jugo recientemente y no puede ser nominado.", + "sv-se": "Denna karta spelades nyligen och kan inte nomineras.", + "th-th": "แผนที่นี้เพิ่งถูกเล่นไปและไม่สามารถเสนอชื่อได้", + "tr-tr": "Bu harita yakin zamanda oynandi ve aday gosterilemez.", + "uk-ua": "Ця карта нещодавно грали і не може бути номінована.", + "vi-vn": "Ban do nay vua duoc choi gan day va khong the de cu." }, "ptr.mapmanager.map_not_found": { "en-us": "Cannot find this map in the map pool.", - "zh-cn": "无法从图池中找到该地图。" + "zh-cn": "无法从图池中找到该地图。", + "zh-tw": "無法從圖池中找到該地圖。", + "pt-br": "Nao foi possivel encontrar este mapa no pool de mapas.", + "bg-bg": "Не може да се намери тази карта в списъка с карти.", + "cs-cz": "Tuto mapu nelze najit v poolu map.", + "da-dk": "Kan ikke finde dette kort i kortpuljen.", + "nl-nl": "Kan deze map niet vinden in de mappool.", + "fi-fi": "Karttaa ei loydy karttavalikoimasta.", + "fr-fr": "Impossible de trouver cette carte dans la liste des cartes.", + "de-de": "Diese Karte kann im Kartenpool nicht gefunden werden.", + "el-gr": "Δεν μπορει να βρεθει αυτος ο χαρτης στο pool χαρτων.", + "hu-hu": "Nem talalhato ez a palya a palyakeszletben.", + "id-id": "Tidak dapat menemukan peta ini di pool peta.", + "it-it": "Impossibile trovare questa mappa nel pool delle mappe.", + "ja-jp": "このマップはマッププールに見つかりません。", + "ko-kr": "맵 풀에서 이 맵을 찾을 수 없습니다.", + "es-419": "No se puede encontrar este mapa en el pool de mapas.", + "nb-no": "Kan ikke finne dette kartet i kartpoolen.", + "pl-pl": "Nie mozna znalezc tej mapy w puli map.", + "pt-pt": "Nao foi possivel encontrar este mapa no conjunto de mapas.", + "ro-ro": "Nu se poate gasi aceasta harta in pool-ul de harti.", + "ru-ru": "Не удается найти эту карту в пуле карт.", + "es-es": "No se puede encontrar este mapa en el grupo de mapas.", + "sv-se": "Kan inte hitta denna karta i kartpoolen.", + "th-th": "ไม่พบแผนที่นี้ในกลุ่มแผนที่", + "tr-tr": "Bu harita harita havuzunda bulunamiyor.", + "uk-ua": "Не вдається знайти цю карту в пулі карт.", + "vi-vn": "Khong the tim thay ban do nay trong danh sach ban do." }, "ptr.mapmanager.cannot_nominate_current_map": { "en-us": "Cannot nominate the current map.", - "zh-cn": "不能投票正在游玩的地图。" + "zh-cn": "不能投票正在游玩的地图。", + "zh-tw": "不能投票正在遊玩的地圖。", + "pt-br": "Nao e possivel nomear o mapa atual.", + "bg-bg": "Не може да се номинира текущата карта.", + "cs-cz": "Nelze nominovat aktualni mapu.", + "da-dk": "Kan ikke nominere det aktuelle kort.", + "nl-nl": "Kan de huidige map niet nomineren.", + "fi-fi": "Nykyista karttaa ei voi ehdottaa.", + "fr-fr": "Impossible de nominer la carte actuelle.", + "de-de": "Die aktuelle Karte kann nicht nominiert werden.", + "el-gr": "Δεν μπορειτε να προτεινετε τον τρεχοντα χαρτη.", + "hu-hu": "A jelenlegi palya nem jelolheto.", + "id-id": "Tidak dapat menominasikan peta saat ini.", + "it-it": "Non e possibile nominare la mappa attuale.", + "ja-jp": "現在のマップはノミネートできません。", + "ko-kr": "현재 맵은 추천할 수 없습니다.", + "es-419": "No se puede nominar el mapa actual.", + "nb-no": "Kan ikke nominere det gjeldende kartet.", + "pl-pl": "Nie mozna nominowac obecnej mapy.", + "pt-pt": "Nao e possivel nomear o mapa atual.", + "ro-ro": "Nu se poate nominaliza harta curenta.", + "ru-ru": "Нельзя номинировать текущую карту.", + "es-es": "No se puede nominar el mapa actual.", + "sv-se": "Kan inte nominera den aktuella kartan.", + "th-th": "ไม่สามารถเสนอชื่อแผนที่ปัจจุบันได้", + "tr-tr": "Mevcut harita aday gosterilemez.", + "uk-ua": "Не можна номінувати поточну карту.", + "vi-vn": "Khong the de cu ban do hien tai." }, "ptr.mapmanager.player_nominated_map": { "en-us": "{green}{0}{white} nominated map {green}{1}{white}.", - "zh-cn": "{green}{0}{white} 提名了地图 {green}{1}{white}。" + "zh-cn": "{green}{0}{white} 提名了地图 {green}{1}{white}。", + "zh-tw": "{green}{0}{white} 提名了地圖 {green}{1}{white}。", + "pt-br": "{green}{0}{white} nomeou o mapa {green}{1}{white}.", + "bg-bg": "{green}{0}{white} номинира карта {green}{1}{white}.", + "cs-cz": "{green}{0}{white} nominoval mapu {green}{1}{white}.", + "da-dk": "{green}{0}{white} nominerede kortet {green}{1}{white}.", + "nl-nl": "{green}{0}{white} nomineerde map {green}{1}{white}.", + "fi-fi": "{green}{0}{white} ehdotti karttaa {green}{1}{white}.", + "fr-fr": "{green}{0}{white} a nomine la carte {green}{1}{white}.", + "de-de": "{green}{0}{white} hat die Karte {green}{1}{white} nominiert.", + "el-gr": "Ο {green}{0}{white} προτεινε τον χαρτη {green}{1}{white}.", + "hu-hu": "{green}{0}{white} jelolte a {green}{1}{white} palyat.", + "id-id": "{green}{0}{white} menominasikan peta {green}{1}{white}.", + "it-it": "{green}{0}{white} ha nominato la mappa {green}{1}{white}.", + "ja-jp": "{green}{0}{white} がマップ {green}{1}{white} をノミネートしました。", + "ko-kr": "{green}{0}{white}님이 맵 {green}{1}{white}을(를) 추천했습니다.", + "es-419": "{green}{0}{white} nomino el mapa {green}{1}{white}.", + "nb-no": "{green}{0}{white} nominerte kartet {green}{1}{white}.", + "pl-pl": "{green}{0}{white} nominowal mape {green}{1}{white}.", + "pt-pt": "{green}{0}{white} nomeou o mapa {green}{1}{white}.", + "ro-ro": "{green}{0}{white} a nominalizat harta {green}{1}{white}.", + "ru-ru": "{green}{0}{white} номинировал карту {green}{1}{white}.", + "es-es": "{green}{0}{white} nomino el mapa {green}{1}{white}.", + "sv-se": "{green}{0}{white} nominerade kartan {green}{1}{white}.", + "th-th": "{green}{0}{white} เสนอชื่อแผนที่ {green}{1}{white}", + "tr-tr": "{green}{0}{white} haritayi aday gosterdi: {green}{1}{white}.", + "uk-ua": "{green}{0}{white} номінував карту {green}{1}{white}.", + "vi-vn": "{green}{0}{white} da de cu ban do {green}{1}{white}." }, "ptr.mapmanager.rtv_after_x": { "en-us": "A vote to change the map can only be initiated after {green}{0}{white} seconds.", - "zh-cn": "{green}{0}{white} 秒后才能发起换图投票。" + "zh-cn": "{green}{0}{white} 秒后才能发起换图投票。", + "zh-tw": "{green}{0}{white} 秒後才能發起換圖投票。", + "pt-br": "Uma votacao para mudar o mapa so pode ser iniciada apos {green}{0}{white} segundos.", + "bg-bg": "Гласуване за смяна на картата може да бъде започнато след {green}{0}{white} секунди.", + "cs-cz": "Hlasovani o zmene mapy lze zahajit az po {green}{0}{white} sekundach.", + "da-dk": "En afstemning om at skifte kort kan forst startes efter {green}{0}{white} sekunder.", + "nl-nl": "Een stemming om de map te wijzigen kan pas worden gestart na {green}{0}{white} seconden.", + "fi-fi": "Aanestys kartan vaihtamisesta voidaan aloittaa vasta {green}{0}{white} sekunnin kuluttua.", + "fr-fr": "Un vote pour changer de carte ne peut etre lance qu'apres {green}{0}{white} secondes.", + "de-de": "Eine Abstimmung zum Kartenwechsel kann erst nach {green}{0}{white} Sekunden gestartet werden.", + "el-gr": "Μια ψηφοφορια για αλλαγη χαρτη μπορει να ξεκινησει μετα απο {green}{0}{white} δευτερολεπτα.", + "hu-hu": "A palyavaltas szavazas csak {green}{0}{white} masodperc utan inditható.", + "id-id": "Pemungutan suara untuk mengubah peta hanya dapat dimulai setelah {green}{0}{white} detik.", + "it-it": "Una votazione per cambiare mappa puo essere avviata solo dopo {green}{0}{white} secondi.", + "ja-jp": "マップ変更の投票は {green}{0}{white} 秒後にのみ開始できます。", + "ko-kr": "맵 변경 투표는 {green}{0}{white}초 후에만 시작할 수 있습니다.", + "es-419": "Una votacion para cambiar el mapa solo puede iniciarse despues de {green}{0}{white} segundos.", + "nb-no": "En avstemning for a bytte kart kan bare startes etter {green}{0}{white} sekunder.", + "pl-pl": "Glosowanie nad zmiana mapy mozna rozpoczac dopiero po {green}{0}{white} sekundach.", + "pt-pt": "Uma votacao para mudar o mapa so pode ser iniciada apos {green}{0}{white} segundos.", + "ro-ro": "Un vot pentru schimbarea hartii poate fi initiat doar dupa {green}{0}{white} secunde.", + "ru-ru": "Голосование за смену карты можно начать только через {green}{0}{white} секунд.", + "es-es": "Una votacion para cambiar el mapa solo puede iniciarse despues de {green}{0}{white} segundos.", + "sv-se": "En omrostning for att byta karta kan bara startas efter {green}{0}{white} sekunder.", + "th-th": "การโหวตเปลี่ยนแผนที่สามารถเริ่มได้หลังจาก {green}{0}{white} วินาที", + "tr-tr": "Harita degistirmek icin oylama ancak {green}{0}{white} saniye sonra baslatilabilir.", + "uk-ua": "Голосування за зміну карти можна розпочати лише через {green}{0}{white} секунд.", + "vi-vn": "Cuoc bo phieu thay doi ban do chi co the bat dau sau {green}{0}{white} giay." }, "ptr.mapmanager.already_voted_rtv": { "en-us": "You have already voted to change the map!", - "zh-cn": "你已经投票过换图了!" + "zh-cn": "你已经投票过换图了!", + "zh-tw": "你已經投票過換圖了!", + "pt-br": "Voce ja votou para mudar o mapa!", + "bg-bg": "Вече сте гласували за смяна на картата!", + "cs-cz": "Jiz jste hlasovali pro zmenu mapy!", + "da-dk": "Du har allerede stemt for at skifte kort!", + "nl-nl": "Je hebt al gestemd om de map te wijzigen!", + "fi-fi": "Olet jo aanestanyt kartan vaihtamisesta!", + "fr-fr": "Vous avez deja vote pour changer de carte!", + "de-de": "Du hast bereits fur einen Kartenwechsel gestimmt!", + "el-gr": "Εχετε ηδη ψηφισει για αλλαγη χαρτη!", + "hu-hu": "Mar szavaztal a palyavaltasra!", + "id-id": "Anda sudah memberikan suara untuk mengubah peta!", + "it-it": "Hai gia votato per cambiare mappa!", + "ja-jp": "マップ変更に既に投票済みです!", + "ko-kr": "이미 맵 변경에 투표하셨습니다!", + "es-419": "Ya has votado para cambiar el mapa!", + "nb-no": "Du har allerede stemt for a bytte kart!", + "pl-pl": "Juz glosowaes za zmiana mapy!", + "pt-pt": "Ja votou para mudar o mapa!", + "ro-ro": "Ai votat deja pentru schimbarea hartii!", + "ru-ru": "Вы уже голосовали за смену карты!", + "es-es": "Ya has votado para cambiar el mapa!", + "sv-se": "Du har redan rostat for att byta karta!", + "th-th": "คุณได้โหวตเปลี่ยนแผนที่ไปแล้ว!", + "tr-tr": "Harita degistirmek icin zaten oy kullandiniz!", + "uk-ua": "Ви вже голосували за зміну карти!", + "vi-vn": "Ban da bo phieu thay doi ban do roi!" }, "ptr.mapmanager.rtv_vote_progress": { "en-us": "{green}{0}{white} players have voted to change the map, {green}{1}{white} more votes needed.", - "zh-cn": "已有 {green}{0}{white} 人投票换图,还需 {green}{1}{white} 票。" + "zh-cn": "已有 {green}{0}{white} 人投票换图,还需 {green}{1}{white} 票。", + "zh-tw": "已有 {green}{0}{white} 人投票換圖,還需 {green}{1}{white} 票。", + "pt-br": "{green}{0}{white} jogadores votaram para mudar o mapa, {green}{1}{white} votos a mais necessarios.", + "bg-bg": "{green}{0}{white} играчи гласуваха за смяна на картата, необходими са още {green}{1}{white} гласа.", + "cs-cz": "{green}{0}{white} hracu hlasovalo pro zmenu mapy, potreba jeste {green}{1}{white} hlasu.", + "da-dk": "{green}{0}{white} spillere har stemt for at skifte kort, {green}{1}{white} flere stemmer nodvendige.", + "nl-nl": "{green}{0}{white} spelers hebben gestemd om de map te wijzigen, nog {green}{1}{white} stemmen nodig.", + "fi-fi": "{green}{0}{white} pelaajaa on aanestanyt kartan vaihtamisesta, {green}{1}{white} aanta viela tarvitaan.", + "fr-fr": "{green}{0}{white} joueurs ont vote pour changer de carte, {green}{1}{white} votes supplementaires requis.", + "de-de": "{green}{0}{white} Spieler haben fur einen Kartenwechsel gestimmt, {green}{1}{white} weitere Stimmen benotigt.", + "el-gr": "{green}{0}{white} παικτες ψηφισαν για αλλαγη χαρτη, χρειαζονται ακομη {green}{1}{white} ψηφοι.", + "hu-hu": "{green}{0}{white} jatekos szavazott a palyavaltasra, meg {green}{1}{white} szavazat szukseges.", + "id-id": "{green}{0}{white} pemain telah memilih untuk mengubah peta, {green}{1}{white} suara lagi diperlukan.", + "it-it": "{green}{0}{white} giocatori hanno votato per cambiare mappa, servono altri {green}{1}{white} voti.", + "ja-jp": "{green}{0}{white} 人がマップ変更に投票しました。あと {green}{1}{white} 票必要です。", + "ko-kr": "{green}{0}{white}명이 맵 변경에 투표했습니다. {green}{1}{white}표 더 필요합니다.", + "es-419": "{green}{0}{white} jugadores han votado para cambiar el mapa, se necesitan {green}{1}{white} votos mas.", + "nb-no": "{green}{0}{white} spillere har stemt for a bytte kart, {green}{1}{white} flere stemmer trengs.", + "pl-pl": "{green}{0}{white} graczy zaglosowalo za zmiana mapy, potrzeba jeszcze {green}{1}{white} glosow.", + "pt-pt": "{green}{0}{white} jogadores votaram para mudar o mapa, necessarios mais {green}{1}{white} votos.", + "ro-ro": "{green}{0}{white} jucatori au votat pentru schimbarea hartii, mai sunt necesare {green}{1}{white} voturi.", + "ru-ru": "{green}{0}{white} игроков проголосовало за смену карты, нужно ещё {green}{1}{white} голосов.", + "es-es": "{green}{0}{white} jugadores han votado para cambiar el mapa, se necesitan {green}{1}{white} votos mas.", + "sv-se": "{green}{0}{white} spelare har rostat for att byta karta, {green}{1}{white} fler roster behovs.", + "th-th": "{green}{0}{white} ผู้เล่นโหวตเปลี่ยนแผนที่แล้ว ต้องการอีก {green}{1}{white} โหวต", + "tr-tr": "{green}{0}{white} oyuncu harita degistirmek icin oy kullandi, {green}{1}{white} oy daha gerekli.", + "uk-ua": "{green}{0}{white} гравців проголосували за зміну карти, потрібно ще {green}{1}{white} голосів.", + "vi-vn": "{green}{0}{white} nguoi choi da bo phieu thay doi ban do, can them {green}{1}{white} phieu nua." }, "ptr.mapmanager.rtv_vote_passed": { "en-us": "RTV vote passed! Map voting will start after this round ends.", - "zh-cn": "投票换图通过!将在回合结束后开始投票。" + "zh-cn": "投票换图通过!将在回合结束后开始投票。", + "zh-tw": "投票換圖通過!將在回合結束後開始投票。", + "pt-br": "Votacao RTV aprovada! A votacao de mapas comecara apos o fim desta rodada.", + "bg-bg": "RTV гласуването премина! Гласуването за карта ще започне след края на рунда.", + "cs-cz": "RTV hlasovani proslo! Hlasovani o mape zacne po skonceni tohoto kola.", + "da-dk": "RTV-afstemningen er godkendt! Kortafstemning starter efter denne runde.", + "nl-nl": "RTV-stemming geslaagd! Map stemming begint na deze ronde.", + "fi-fi": "RTV-aanestys hyvaksytty! Kartta-aanestys alkaa kierroksen jalkeen.", + "fr-fr": "Vote RTV approuve! Le vote de carte commencera apres cette manche.", + "de-de": "RTV-Abstimmung erfolgreich! Kartenabstimmung beginnt nach dieser Runde.", + "el-gr": "Η ψηφοφορια RTV περασε! Η ψηφοφορια χαρτη θα ξεκινησει μετα το τελος του γυρου.", + "hu-hu": "RTV szavazas elfogadva! A palyaszavazas a kor vegen kezdodik.", + "id-id": "Pemungutan suara RTV berhasil! Pemungutan suara peta akan dimulai setelah ronde ini berakhir.", + "it-it": "Votazione RTV approvata! La votazione della mappa iniziera dopo questo round.", + "ja-jp": "RTV投票が可決されました!ラウンド終了後にマップ投票が始まります。", + "ko-kr": "RTV 투표가 통과되었습니다! 이 라운드가 끝나면 맵 투표가 시작됩니다.", + "es-419": "Votacion RTV aprobada! La votacion de mapas comenzara al final de esta ronda.", + "nb-no": "RTV-avstemningen ble godkjent! Kartavstemning starter etter denne runden.", + "pl-pl": "Glosowanie RTV przeszlo! Glosowanie na mape rozpocznie sie po tej rundzie.", + "pt-pt": "Votacao RTV aprovada! A votacao de mapas comecara apos esta ronda.", + "ro-ro": "Votul RTV a trecut! Votarea hartii va incepe dupa aceasta runda.", + "ru-ru": "Голосование RTV прошло! Голосование за карту начнётся после этого раунда.", + "es-es": "Votacion RTV aprobada! La votacion de mapas comenzara al final de esta ronda.", + "sv-se": "RTV-omrostningen godkandes! Kartomrostning borjar efter denna runda.", + "th-th": "โหวต RTV ผ่าน! การโหวตแผนที่จะเริ่มหลังจบรอบนี้", + "tr-tr": "RTV oylamasi gecti! Harita oylamasi bu tur bittikten sonra baslayacak.", + "uk-ua": "Голосування RTV пройшло! Голосування за карту почнеться після цього раунду.", + "vi-vn": "Bo phieu RTV thanh cong! Bo phieu ban do se bat dau sau khi ket thuc vong nay." } } From 3362470f1215b90c22f8b2afeb5e8204f6090f59 Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Mon, 5 Jan 2026 22:39:25 +0200 Subject: [PATCH 04/24] fix usage of convars that is not being initiated on that step --- .../Services/ExtendService.cs | 18 ++++++------- .../Services/NominateService.cs | 27 +++++++------------ 2 files changed, 17 insertions(+), 28 deletions(-) diff --git a/src/Ptr.Modules.MapManager/Services/ExtendService.cs b/src/Ptr.Modules.MapManager/Services/ExtendService.cs index 1ce77ab..3ab9192 100644 --- a/src/Ptr.Modules.MapManager/Services/ExtendService.cs +++ b/src/Ptr.Modules.MapManager/Services/ExtendService.cs @@ -38,6 +38,14 @@ public ExtendService(InterfaceBridge bridge, ILogger logger) private void OnCommandExt(IGameClient client, StringCommand command) { + if (_enableExtend?.GetBool() is not true) + { + return; + } + if (_localizerManager is null) + { + throw new InvalidOperationException("LocalizerManager is not initialized."); + } _localizerManager.TryGetLocalizer(client, out var _localizer); if (_localizer is null) { @@ -127,11 +135,6 @@ public void OnInit() public void OnAllModulesLoaded() { - if (_enableExtend?.GetBool() is not true) - { - return; - } - _commandRegistry = _bridge.SharpModuleManager .GetRequiredSharpModuleInterface(ICommandManager.Identity).Instance! .GetRegistry(_bridge.ModuleIdentity); @@ -144,11 +147,6 @@ public void OnAllModulesLoaded() public void OnShutdown() { - if (_enableExtend?.GetBool() is not true) - { - return; - } - ResetExtCount(); ResetClientsExt(); } diff --git a/src/Ptr.Modules.MapManager/Services/NominateService.cs b/src/Ptr.Modules.MapManager/Services/NominateService.cs index 07260ec..c70abfe 100644 --- a/src/Ptr.Modules.MapManager/Services/NominateService.cs +++ b/src/Ptr.Modules.MapManager/Services/NominateService.cs @@ -32,21 +32,11 @@ public NominateService(InterfaceBridge bridge, ILogger logger) public void OnInit() { - if (_enableNominate?.GetBool() is true) - { - return; - } - - _logger.LogInformation("Nomination is disabled."); + _logger.LogInformation("Nomination is enabled."); } public void OnAllModulesLoaded() { - if (_enableNominate?.GetBool() is not true) - { - return; - } - _bridge .SharpModuleManager .GetRequiredSharpModuleInterface(ICommandManager.Identity) @@ -54,22 +44,23 @@ public void OnAllModulesLoaded() .GetRegistry(_bridge.ModuleIdentity) .RegisterClientCommand("nominate", OnCommandNominate); - _localizerManager = _bridge.SharpModuleManager - .GetRequiredSharpModuleInterface(ILocalizerManager.Identity).Instance!; } public void OnShutdown() { - if (_enableNominate?.GetBool() is not true) - { - return; - } - _bridge.NominatedMaps.Clear(); } private void OnCommandNominate(IGameClient client, StringCommand command) { + if (_enableNominate?.GetBool() is not true) + { + return; + } + if (_localizerManager is null) + { + throw new InvalidOperationException("LocalizerManager is not initialized."); + } _localizerManager.TryGetLocalizer(client, out var _localizer); if (_localizer is null) { From c968cf4f040f4f078f8b6298408df17579a13546 Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Mon, 5 Jan 2026 22:39:39 +0200 Subject: [PATCH 05/24] fix usage of convars that is not being initiated on that step --- .../Services/RtvService.cs | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/Ptr.Modules.MapManager/Services/RtvService.cs b/src/Ptr.Modules.MapManager/Services/RtvService.cs index 4043d18..b29ce47 100644 --- a/src/Ptr.Modules.MapManager/Services/RtvService.cs +++ b/src/Ptr.Modules.MapManager/Services/RtvService.cs @@ -31,6 +31,14 @@ public RtvService(InterfaceBridge bridge, ILogger logger) private void AttemptRtv(IGameClient client) { + if (_enableRtv?.GetBool() is not true) + { + return; + } + if (_localizerManager is null) + { + throw new InvalidOperationException("LocalizerManager is not initialized."); + } _localizerManager.TryGetLocalizer(client, out var _localizer); if (_localizer is null) { @@ -118,23 +126,12 @@ public void OnInit() public void OnAllModulesLoaded() { - if (_enableRtv?.GetBool() is not true) - { - return; - } - _localizerManager = _bridge.SharpModuleManager .GetRequiredSharpModuleInterface(ILocalizerManager.Identity).Instance!; } public void OnShutdown() { - if (_enableRtv?.GetBool() is not true) - { - _logger.LogInformation("RTV is disabled, skip shutdown."); - return; - } - _bridge.ModSharp.RemoveGameListener(this); _bridge.ClientManager.RemoveClientListener(this); ResetRtvState(); From ae1f4434b796e23343af45849371aac0576d911c Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Mon, 5 Jan 2026 22:47:21 +0200 Subject: [PATCH 06/24] fix CallAllModulesLoaded --- src/Ptr.Modules.MapManager/MapManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ptr.Modules.MapManager/MapManager.cs b/src/Ptr.Modules.MapManager/MapManager.cs index 0242777..4b7f89e 100644 --- a/src/Ptr.Modules.MapManager/MapManager.cs +++ b/src/Ptr.Modules.MapManager/MapManager.cs @@ -165,7 +165,7 @@ public void OnAllModulesLoaded() { _provider.LoadAllSharpExtensions(); _provider.InitNativeHooks(); - _provider.CallInit(e => { _logger.LogError(e, "An error occurred when initializing modules"); }); + _provider.CallAllModulesLoaded(e => { _logger.LogError(e, "An error occurred when initializing modules"); }); _provider.UseHook(); CallMapConfigLoaded(); From 0c172ddad796cafc6be46e25c9aa925b86c86cc3 Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Mon, 5 Jan 2026 23:06:17 +0200 Subject: [PATCH 07/24] tweak calls --- src/Ptr.Modules.MapManager/MapManager.cs | 1 + .../Services/ExtendService.cs | 27 ++++++++++--------- .../Services/RtvService.cs | 21 +++++++-------- 3 files changed, 24 insertions(+), 25 deletions(-) diff --git a/src/Ptr.Modules.MapManager/MapManager.cs b/src/Ptr.Modules.MapManager/MapManager.cs index 4b7f89e..732b279 100644 --- a/src/Ptr.Modules.MapManager/MapManager.cs +++ b/src/Ptr.Modules.MapManager/MapManager.cs @@ -126,6 +126,7 @@ private void CallMapConfigLoaded() public bool Init() { InitConfig(); + _provider.CallInit(e => { _logger.LogError(e, "An error occurred when initializing modules"); }); return true; } diff --git a/src/Ptr.Modules.MapManager/Services/ExtendService.cs b/src/Ptr.Modules.MapManager/Services/ExtendService.cs index 3ab9192..839a453 100644 --- a/src/Ptr.Modules.MapManager/Services/ExtendService.cs +++ b/src/Ptr.Modules.MapManager/Services/ExtendService.cs @@ -16,9 +16,9 @@ internal interface IExtendService : IModule; internal class ExtendService : IExtendService, IClientListener, IGameListener { private readonly InterfaceBridge _bridge; - private readonly IConVar? _enableExtend; - private readonly IConVar? _extendTime; - private readonly IConVar? _maxExtCount; + private IConVar? _enableExtend = null!; + private IConVar? _extendTime = null!; + private IConVar? _maxExtCount = null!; private readonly bool[] _extClients = new bool[64]; private readonly ILogger _logger; private int _extCount; @@ -29,11 +29,7 @@ public ExtendService(InterfaceBridge bridge, ILogger logger) { _bridge = bridge; _logger = logger; - _enableExtend = _bridge.ConVarManager.CreateConVar("mapmanager_enable_extend", true, "Enable ext"); - _maxExtCount = _bridge.ConVarManager.CreateConVar("mapmanager_max_extend_count", 3, - "Maximum allowed extend map time limit count."); - _extendTime = - _bridge.ConVarManager.CreateConVar("mapmanager_ext_time", 15, "The extend applies for time limit."); + } private void OnCommandExt(IGameClient client, StringCommand command) @@ -122,13 +118,18 @@ private void ResetExtCount() } #region IModule - + public void OnPostInit() + { + _enableExtend = _bridge!.ConVarManager.CreateConVar("mapmanager_enable_extend", true, "Enable ext"); + _maxExtCount = _bridge!.ConVarManager.CreateConVar("mapmanager_max_extend_count", 3, + "Maximum allowed extend map time limit count."); + _extendTime = + _bridge!.ConVarManager.CreateConVar("mapmanager_ext_time", 15, "The extend applies for time limit."); + } public void OnInit() { - if (_enableExtend?.GetBool() is true) - { - return; - } + _bridge.ModSharp.InstallGameListener(this); + _bridge.ClientManager.InstallClientListener(this); _logger.LogInformation("Ext is disabled."); } diff --git a/src/Ptr.Modules.MapManager/Services/RtvService.cs b/src/Ptr.Modules.MapManager/Services/RtvService.cs index b29ce47..e4b158f 100644 --- a/src/Ptr.Modules.MapManager/Services/RtvService.cs +++ b/src/Ptr.Modules.MapManager/Services/RtvService.cs @@ -15,7 +15,7 @@ internal class RtvService : IRtvService, IGameListener, IClientListener { private readonly InterfaceBridge _bridge; - private readonly IConVar? _enableRtv; + private IConVar? _enableRtv = null!; private readonly ILogger _logger; private readonly bool[] _rtvPlayers = new bool[64]; private ILocalizerManager _localizerManager = null!; @@ -24,15 +24,13 @@ public RtvService(InterfaceBridge bridge, ILogger logger) { _bridge = bridge; _logger = logger; - - - _enableRtv = _bridge.ConVarManager.CreateConVar("mapmanager_enable_rtv", true, "Enable RTV"); } private void AttemptRtv(IGameClient client) { if (_enableRtv?.GetBool() is not true) { + _logger.LogInformation("RTV is disabled, skip RTV attempt."); return; } if (_localizerManager is null) @@ -111,17 +109,14 @@ private void ResetClientRtvState(IGameClient client) } #region IModule - public void OnInit() { - if (_enableRtv?.GetBool() is not true) - { - _logger.LogInformation("RTV is disabled, skip initialization."); - return; - } - - _bridge.ClientManager.InstallClientListener(this); _bridge.ModSharp.InstallGameListener(this); + _bridge.ClientManager.InstallClientListener(this); + } + public void OnPostInit() + { + _enableRtv = _bridge.ConVarManager.CreateConVar("mapmanager_enable_rtv", true, "Enable RTV"); } public void OnAllModulesLoaded() @@ -166,8 +161,10 @@ public void OnClientDisconnected(IGameClient client, NetworkDisconnectionReason public ECommandAction OnClientSayCommand(IGameClient client, bool teamOnly, bool isCommand, string commandName, string message) { + _logger.LogInformation("Client {ClientSlot} said: {Message}", client.Slot, message); if (message.Split().ElementAtOrDefault(0)?.Equals("rtv", StringComparison.OrdinalIgnoreCase) is true) { + _logger.LogInformation("Client {ClientSlot} is attempting to RTV.", client.Slot); AttemptRtv(client); } From d5aa888f8c959708c263c47a83017ce28913d097 Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Mon, 5 Jan 2026 23:16:01 +0200 Subject: [PATCH 08/24] fix translations, fix init/postinit invocations --- .../sharp/locales/Ptr.Modules.MapManager.json | 348 +++++++++--------- src/Ptr.Modules.MapManager/MapManager.cs | 1 + .../Services/ExtendService.cs | 6 +- .../Services/NominateService.cs | 17 +- .../Services/RtvService.cs | 9 +- 5 files changed, 195 insertions(+), 186 deletions(-) diff --git a/.asset/game/sharp/locales/Ptr.Modules.MapManager.json b/.asset/game/sharp/locales/Ptr.Modules.MapManager.json index 8c8614f..b6dc5c3 100644 --- a/.asset/game/sharp/locales/Ptr.Modules.MapManager.json +++ b/.asset/game/sharp/locales/Ptr.Modules.MapManager.json @@ -1,34 +1,34 @@ { "ptr.mapmanager.extend_map_after_x": { - "en-us": "A vote to extend the map time can only be initiated after {green}{0}{white} seconds.", - "zh-cn": "{green}{0}{white} 秒后才能发起延长地图时间投票.", - "zh-tw": "{green}{0}{white} 秒後才能發起延長地圖時間投票。", - "pt-br": "Uma votacao para estender o tempo do mapa so pode ser iniciada apos {green}{0}{white} segundos.", - "bg-bg": "Гласуване за удължаване на времето на картата може да бъде започнато след {green}{0}{white} секунди.", - "cs-cz": "Hlasovani o prodlouzeni casu mapy lze zahajit az po {green}{0}{white} sekundach.", - "da-dk": "En afstemning om at forlaenge kortets tid kan forst startes efter {green}{0}{white} sekunder.", - "nl-nl": "Een stemming om de maptijd te verlengen kan pas worden gestart na {green}{0}{white} seconden.", - "fi-fi": "Aanestys kartan ajan jatkamisesta voidaan aloittaa vasta {green}{0}{white} sekunnin kuluttua.", - "fr-fr": "Un vote pour prolonger le temps de la carte ne peut etre lance qu'apres {green}{0}{white} secondes.", - "de-de": "Eine Abstimmung zur Verlangerung der Kartenzeit kann erst nach {green}{0}{white} Sekunden gestartet werden.", - "el-gr": "Μια ψηφοφορια για παραταση του χρονου του χαρτη μπορει να ξεκινησει μετα απο {green}{0}{white} δευτερολεπτα.", - "hu-hu": "A palya idejének meghosszabbitasara vonatkozo szavazas csak {green}{0}{white} masodperc utan inditható.", - "id-id": "Pemungutan suara untuk memperpanjang waktu peta hanya dapat dimulai setelah {green}{0}{white} detik.", - "it-it": "Una votazione per estendere il tempo della mappa puo essere avviata solo dopo {green}{0}{white} secondi.", - "ja-jp": "マップ時間延長の投票は {green}{0}{white} 秒後にのみ開始できます。", - "ko-kr": "맵 시간 연장 투표는 {green}{0}{white}초 후에만 시작할 수 있습니다.", - "es-419": "Una votacion para extender el tiempo del mapa solo puede iniciarse despues de {green}{0}{white} segundos.", - "nb-no": "En avstemning for a forlenge karttiden kan bare startes etter {green}{0}{white} sekunder.", - "pl-pl": "Glosowanie nad przedluzeniem czasu mapy mozna rozpoczac dopiero po {green}{0}{white} sekundach.", - "pt-pt": "Uma votacao para prolongar o tempo do mapa so pode ser iniciada apos {green}{0}{white} segundos.", - "ro-ro": "Un vot pentru prelungirea timpului hartii poate fi initiat doar dupa {green}{0}{white} secunde.", - "ru-ru": "Голосование за продление времени карты можно начать только через {green}{0}{white} секунд.", - "es-es": "Una votacion para extender el tiempo del mapa solo puede iniciarse despues de {green}{0}{white} segundos.", - "sv-se": "En omrostning for att forlanga karttiden kan bara startas efter {green}{0}{white} sekunder.", - "th-th": "การโหวตขยายเวลาแผนที่สามารถเริ่มได้หลังจาก {green}{0}{white} วินาที", - "tr-tr": "Harita suresini uzatmak icin oylama ancak {green}{0}{white} saniye sonra baslatilabilir.", - "uk-ua": "Голосування за продовження часу карти можна розпочати лише через {green}{0}{white} секунд.", - "vi-vn": "Cuoc bo phieu gia han thoi gian ban do chi co the bat dau sau {green}{0}{white} giay." + "en-us": "A vote to extend the map time can only be initiated after {{green}}{0}{{white}} seconds.", + "zh-cn": "{{green}}{0}{{white}} 秒后才能发起延长地图时间投票.", + "zh-tw": "{{green}}{0}{{white}} 秒後才能發起延長地圖時間投票。", + "pt-br": "Uma votacao para estender o tempo do mapa so pode ser iniciada apos {{green}}{0}{{white}} segundos.", + "bg-bg": "Гласуване за удължаване на времето на картата може да бъде започнато след {{green}}{0}{{white}} секунди.", + "cs-cz": "Hlasovani o prodlouzeni casu mapy lze zahajit az po {{green}}{0}{{white}} sekundach.", + "da-dk": "En afstemning om at forlaenge kortets tid kan forst startes efter {{green}}{0}{{white}} sekunder.", + "nl-nl": "Een stemming om de maptijd te verlengen kan pas worden gestart na {{green}}{0}{{white}} seconden.", + "fi-fi": "Aanestys kartan ajan jatkamisesta voidaan aloittaa vasta {{green}}{0}{{white}} sekunnin kuluttua.", + "fr-fr": "Un vote pour prolonger le temps de la carte ne peut etre lance qu'apres {{green}}{0}{{white}} secondes.", + "de-de": "Eine Abstimmung zur Verlangerung der Kartenzeit kann erst nach {{green}}{0}{{white}} Sekunden gestartet werden.", + "el-gr": "Μια ψηφοφορια για παραταση του χρονου του χαρτη μπορει να ξεκινησει μετα απο {{green}}{0}{{white}} δευτερολεπτα.", + "hu-hu": "A palya idejének meghosszabbitasara vonatkozo szavazas csak {{green}}{0}{{white}} masodperc utan inditható.", + "id-id": "Pemungutan suara untuk memperpanjang waktu peta hanya dapat dimulai setelah {{green}}{0}{{white}} detik.", + "it-it": "Una votazione per estendere il tempo della mappa puo essere avviata solo dopo {{green}}{0}{{white}} secondi.", + "ja-jp": "マップ時間延長の投票は {{green}}{0}{{white}} 秒後にのみ開始できます。", + "ko-kr": "맵 시간 연장 투표는 {{green}}{0}{{white}}초 후에만 시작할 수 있습니다.", + "es-419": "Una votacion para extender el tiempo del mapa solo puede iniciarse despues de {{green}}{0}{{white}} segundos.", + "nb-no": "En avstemning for a forlenge karttiden kan bare startes etter {{green}}{0}{{white}} sekunder.", + "pl-pl": "Glosowanie nad przedluzeniem czasu mapy mozna rozpoczac dopiero po {{green}}{0}{{white}} sekundach.", + "pt-pt": "Uma votacao para prolongar o tempo do mapa so pode ser iniciada apos {{green}}{0}{{white}} segundos.", + "ro-ro": "Un vot pentru prelungirea timpului hartii poate fi initiat doar dupa {{green}}{0}{{white}} secunde.", + "ru-ru": "Голосование за продление времени карты можно начать только через {{green}}{0}{{white}} секунд.", + "es-es": "Una votacion para extender el tiempo del mapa solo puede iniciarse despues de {{green}}{0}{{white}} segundos.", + "sv-se": "En omrostning for att forlanga karttiden kan bara startas efter {{green}}{0}{{white}} sekunder.", + "th-th": "การโหวตขยายเวลาแผนที่สามารถเริ่มได้หลังจาก {{green}}{0}{{white}} วินาที", + "tr-tr": "Harita suresini uzatmak icin oylama ancak {{green}}{0}{{white}} saniye sonra baslatilabilir.", + "uk-ua": "Голосування за продовження часу карти можна розпочати лише через {{green}}{0}{{white}} секунд.", + "vi-vn": "Cuoc bo phieu gia han thoi gian ban do chi co the bat dau sau {{green}}{0}{{white}} giay." }, "ptr.mapmanager.max_extends_reached": { "en-us": "The maximum number of times the time can be extended has been reached.", @@ -93,35 +93,35 @@ "vi-vn": "Ban da bo phieu gia han thoi gian ban do roi." }, "ptr.mapmanager.extend_vote_progress": { - "en-us": "{green}{0}{white} players have voted to extend the map time, {green}{1}{white} more votes needed.", - "zh-cn": "已有 {green}{0}{white} 人投票延长地图时间,还需 {green}{1}{white} 票。", - "zh-tw": "已有 {green}{0}{white} 人投票延長地圖時間,還需 {green}{1}{white} 票。", - "pt-br": "{green}{0}{white} jogadores votaram para estender o tempo do mapa, {green}{1}{white} votos a mais necessarios.", - "bg-bg": "{green}{0}{white} играчи гласуваха за удължаване на времето, необходими са още {green}{1}{white} гласа.", - "cs-cz": "{green}{0}{white} hracu hlasovalo pro prodlouzeni casu mapy, potreba jeste {green}{1}{white} hlasu.", - "da-dk": "{green}{0}{white} spillere har stemt for at forlaenge kortets tid, {green}{1}{white} flere stemmer nodvendige.", - "nl-nl": "{green}{0}{white} spelers hebben gestemd om de maptijd te verlengen, nog {green}{1}{white} stemmen nodig.", - "fi-fi": "{green}{0}{white} pelaajaa on aanestanyt ajan jatkamisesta, {green}{1}{white} aanta viela tarvitaan.", - "fr-fr": "{green}{0}{white} joueurs ont vote pour prolonger le temps, {green}{1}{white} votes supplementaires requis.", - "de-de": "{green}{0}{white} Spieler haben fur die Zeitverlangerung gestimmt, {green}{1}{white} weitere Stimmen benotigt.", - "el-gr": "{green}{0}{white} παικτες ψηφισαν για παραταση χρονου, χρειαζονται ακομη {green}{1}{white} ψηφοι.", - "hu-hu": "{green}{0}{white} jatekos szavazott az idomeghosszabbitasra, meg {green}{1}{white} szavazat szukseges.", - "id-id": "{green}{0}{white} pemain telah memilih untuk memperpanjang waktu, {green}{1}{white} suara lagi diperlukan.", - "it-it": "{green}{0}{white} giocatori hanno votato per estendere il tempo, servono altri {green}{1}{white} voti.", - "ja-jp": "{green}{0}{white} 人が時間延長に投票しました。あと {green}{1}{white} 票必要です。", - "ko-kr": "{green}{0}{white}명이 시간 연장에 투표했습니다. {green}{1}{white}표 더 필요합니다.", - "es-419": "{green}{0}{white} jugadores han votado para extender el tiempo, se necesitan {green}{1}{white} votos mas.", - "nb-no": "{green}{0}{white} spillere har stemt for a forlenge tiden, {green}{1}{white} flere stemmer trengs.", - "pl-pl": "{green}{0}{white} graczy zaglosowalo za przedluzeniem czasu, potrzeba jeszcze {green}{1}{white} glosow.", - "pt-pt": "{green}{0}{white} jogadores votaram para prolongar o tempo, necessarios mais {green}{1}{white} votos.", - "ro-ro": "{green}{0}{white} jucatori au votat pentru prelungirea timpului, mai sunt necesare {green}{1}{white} voturi.", - "ru-ru": "{green}{0}{white} игроков проголосовало за продление времени, нужно ещё {green}{1}{white} голосов.", - "es-es": "{green}{0}{white} jugadores han votado para extender el tiempo, se necesitan {green}{1}{white} votos mas.", - "sv-se": "{green}{0}{white} spelare har rostat for att forlanga tiden, {green}{1}{white} fler roster behovs.", - "th-th": "{green}{0}{white} ผู้เล่นโหวตขยายเวลาแล้ว ต้องการอีก {green}{1}{white} โหวต", - "tr-tr": "{green}{0}{white} oyuncu sure uzatmak icin oy kullandi, {green}{1}{white} oy daha gerekli.", - "uk-ua": "{green}{0}{white} гравців проголосували за продовження часу, потрібно ще {green}{1}{white} голосів.", - "vi-vn": "{green}{0}{white} nguoi choi da bo phieu gia han thoi gian, can them {green}{1}{white} phieu nua." + "en-us": "{{green}}{0}{{white}} players have voted to extend the map time, {{green}}{1}{{white}} more votes needed.", + "zh-cn": "已有 {{green}}{0}{{white}} 人投票延长地图时间,还需 {{green}}{1}{{white}} 票。", + "zh-tw": "已有 {{green}}{0}{{white}} 人投票延長地圖時間,還需 {{green}}{1}{{white}} 票。", + "pt-br": "{{green}}{0}{{white}} jogadores votaram para estender o tempo do mapa, {{green}}{1}{{white}} votos a mais necessarios.", + "bg-bg": "{{green}}{0}{{white}} играчи гласуваха за удължаване на времето, необходими са още {{green}}{1}{{white}} гласа.", + "cs-cz": "{{green}}{0}{{white}} hracu hlasovalo pro prodlouzeni casu mapy, potreba jeste {{green}}{1}{{white}} hlasu.", + "da-dk": "{{green}}{0}{{white}} spillere har stemt for at forlaenge kortets tid, {{green}}{1}{{white}} flere stemmer nodvendige.", + "nl-nl": "{{green}}{0}{{white}} spelers hebben gestemd om de maptijd te verlengen, nog {{green}}{1}{{white}} stemmen nodig.", + "fi-fi": "{{green}}{0}{{white}} pelaajaa on aanestanyt ajan jatkamisesta, {{green}}{1}{{white}} aanta viela tarvitaan.", + "fr-fr": "{{green}}{0}{{white}} joueurs ont vote pour prolonger le temps, {{green}}{1}{{white}} votes supplementaires requis.", + "de-de": "{{green}}{0}{{white}} Spieler haben fur die Zeitverlangerung gestimmt, {{green}}{1}{{white}} weitere Stimmen benotigt.", + "el-gr": "{{green}}{0}{{white}} παικτες ψηφισαν για παραταση χρονου, χρειαζονται ακομη {{green}}{1}{{white}} ψηφοι.", + "hu-hu": "{{green}}{0}{{white}} jatekos szavazott az idomeghosszabbitasra, meg {{green}}{1}{{white}} szavazat szukseges.", + "id-id": "{{green}}{0}{{white}} pemain telah memilih untuk memperpanjang waktu, {{green}}{1}{{white}} suara lagi diperlukan.", + "it-it": "{{green}}{0}{{white}} giocatori hanno votato per estendere il tempo, servono altri {{green}}{1}{{white}} voti.", + "ja-jp": "{{green}}{0}{{white}} 人が時間延長に投票しました。あと {{green}}{1}{{white}} 票必要です。", + "ko-kr": "{{green}}{0}{{white}}명이 시간 연장에 투표했습니다. {{green}}{1}{{white}}표 더 필요합니다.", + "es-419": "{{green}}{0}{{white}} jugadores han votado para extender el tiempo, se necesitan {{green}}{1}{{white}} votos mas.", + "nb-no": "{{green}}{0}{{white}} spillere har stemt for a forlenge tiden, {{green}}{1}{{white}} flere stemmer trengs.", + "pl-pl": "{{green}}{0}{{white}} graczy zaglosowalo za przedluzeniem czasu, potrzeba jeszcze {{green}}{1}{{white}} glosow.", + "pt-pt": "{{green}}{0}{{white}} jogadores votaram para prolongar o tempo, necessarios mais {{green}}{1}{{white}} votos.", + "ro-ro": "{{green}}{0}{{white}} jucatori au votat pentru prelungirea timpului, mai sunt necesare {{green}}{1}{{white}} voturi.", + "ru-ru": "{{green}}{0}{{white}} игроков проголосовало за продление времени, нужно ещё {{green}}{1}{{white}} голосов.", + "es-es": "{{green}}{0}{{white}} jugadores han votado para extender el tiempo, se necesitan {{green}}{1}{{white}} votos mas.", + "sv-se": "{{green}}{0}{{white}} spelare har rostat for att forlanga tiden, {{green}}{1}{{white}} fler roster behovs.", + "th-th": "{{green}}{0}{{white}} ผู้เล่นโหวตขยายเวลาแล้ว ต้องการอีก {{green}}{1}{{white}} โหวต", + "tr-tr": "{{green}}{0}{{white}} oyuncu sure uzatmak icin oy kullandi, {{green}}{1}{{white}} oy daha gerekli.", + "uk-ua": "{{green}}{0}{{white}} гравців проголосували за продовження часу, потрібно ще {{green}}{1}{{white}} голосів.", + "vi-vn": "{{green}}{0}{{white}} nguoi choi da bo phieu gia han thoi gian, can them {{green}}{1}{{white}} phieu nua." }, "ptr.mapmanager.extend_vote_passed": { "en-us": "Vote passed, the map time will be extended.", @@ -155,35 +155,35 @@ "vi-vn": "Bo phieu thanh cong, thoi gian ban do se duoc gia han." }, "ptr.mapmanager.nominate_not_enough_players": { - "en-us": "At least {green}{0}{white} players are required to nominate maps.", - "zh-cn": "当前在线人数不足 {green}{0}{white} 人,无法提名地图。", - "zh-tw": "當前在線人數不足 {green}{0}{white} 人,無法提名地圖。", - "pt-br": "Sao necessarios pelo menos {green}{0}{white} jogadores para nomear mapas.", - "bg-bg": "Необходими са поне {green}{0}{white} играчи за номиниране на карти.", - "cs-cz": "Pro nominaci map je potreba alespon {green}{0}{white} hracu.", - "da-dk": "Der kraeves mindst {green}{0}{white} spillere for at nominere kort.", - "nl-nl": "Er zijn minimaal {green}{0}{white} spelers nodig om maps te nomineren.", - "fi-fi": "Karttojen ehdottamiseen tarvitaan vahintaan {green}{0}{white} pelaajaa.", - "fr-fr": "Au moins {green}{0}{white} joueurs sont requis pour nominer des cartes.", - "de-de": "Mindestens {green}{0}{white} Spieler werden benotigt, um Karten zu nominieren.", - "el-gr": "Απαιτουνται τουλαχιστον {green}{0}{white} παικτες για να προτεινετε χαρτες.", - "hu-hu": "Legalabb {green}{0}{white} jatekos szukseges a palyak jelolesehez.", - "id-id": "Diperlukan setidaknya {green}{0}{white} pemain untuk menominasikan peta.", - "it-it": "Sono necessari almeno {green}{0}{white} giocatori per nominare mappe.", - "ja-jp": "マップをノミネートするには少なくとも {green}{0}{white} 人のプレイヤーが必要です。", - "ko-kr": "맵 추천에는 최소 {green}{0}{white}명의 플레이어가 필요합니다.", - "es-419": "Se requieren al menos {green}{0}{white} jugadores para nominar mapas.", - "nb-no": "Minst {green}{0}{white} spillere kreves for a nominere kart.", - "pl-pl": "Do nominowania map wymaganych jest co najmniej {green}{0}{white} graczy.", - "pt-pt": "Sao necessarios pelo menos {green}{0}{white} jogadores para nomear mapas.", - "ro-ro": "Sunt necesari cel putin {green}{0}{white} jucatori pentru a nominaliza harti.", - "ru-ru": "Для номинации карт требуется минимум {green}{0}{white} игроков.", - "es-es": "Se requieren al menos {green}{0}{white} jugadores para nominar mapas.", - "sv-se": "Minst {green}{0}{white} spelare kravs for att nominera kartor.", - "th-th": "ต้องมีผู้เล่นอย่างน้อย {green}{0}{white} คนเพื่อเสนอชื่อแผนที่", - "tr-tr": "Harita aday gostermek icin en az {green}{0}{white} oyuncu gereklidir.", - "uk-ua": "Для номінації карт потрібно мінімум {green}{0}{white} гравців.", - "vi-vn": "Can it nhat {green}{0}{white} nguoi choi de de cu ban do." + "en-us": "At least {{green}}{0}{{white}} players are required to nominate maps.", + "zh-cn": "当前在线人数不足 {{green}}{0}{{white}} 人,无法提名地图。", + "zh-tw": "當前在線人數不足 {{green}}{0}{{white}} 人,無法提名地圖。", + "pt-br": "Sao necessarios pelo menos {{green}}{0}{{white}} jogadores para nomear mapas.", + "bg-bg": "Необходими са поне {{green}}{0}{{white}} играчи за номиниране на карти.", + "cs-cz": "Pro nominaci map je potreba alespon {{green}}{0}{{white}} hracu.", + "da-dk": "Der kraeves mindst {{green}}{0}{{white}} spillere for at nominere kort.", + "nl-nl": "Er zijn minimaal {{green}}{0}{{white}} spelers nodig om maps te nomineren.", + "fi-fi": "Karttojen ehdottamiseen tarvitaan vahintaan {{green}}{0}{{white}} pelaajaa.", + "fr-fr": "Au moins {{green}}{0}{{white}} joueurs sont requis pour nominer des cartes.", + "de-de": "Mindestens {{green}}{0}{{white}} Spieler werden benotigt, um Karten zu nominieren.", + "el-gr": "Απαιτουνται τουλαχιστον {{green}}{0}{{white}} παικτες για να προτεινετε χαρτες.", + "hu-hu": "Legalabb {{green}}{0}{{white}} jatekos szukseges a palyak jelolesehez.", + "id-id": "Diperlukan setidaknya {{green}}{0}{{white}} pemain untuk menominasikan peta.", + "it-it": "Sono necessari almeno {{green}}{0}{{white}} giocatori per nominare mappe.", + "ja-jp": "マップをノミネートするには少なくとも {{green}}{0}{{white}} 人のプレイヤーが必要です。", + "ko-kr": "맵 추천에는 최소 {{green}}{0}{{white}}명의 플레이어가 필요합니다.", + "es-419": "Se requieren al menos {{green}}{0}{{white}} jugadores para nominar mapas.", + "nb-no": "Minst {{green}}{0}{{white}} spillere kreves for a nominere kart.", + "pl-pl": "Do nominowania map wymaganych jest co najmniej {{green}}{0}{{white}} graczy.", + "pt-pt": "Sao necessarios pelo menos {{green}}{0}{{white}} jogadores para nomear mapas.", + "ro-ro": "Sunt necesari cel putin {{green}}{0}{{white}} jucatori pentru a nominaliza harti.", + "ru-ru": "Для номинации карт требуется минимум {{green}}{0}{{white}} игроков.", + "es-es": "Se requieren al menos {{green}}{0}{{white}} jugadores para nominar mapas.", + "sv-se": "Minst {{green}}{0}{{white}} spelare kravs for att nominera kartor.", + "th-th": "ต้องมีผู้เล่นอย่างน้อย {{green}}{0}{{white}} คนเพื่อเสนอชื่อแผนที่", + "tr-tr": "Harita aday gostermek icin en az {{green}}{0}{{white}} oyuncu gereklidir.", + "uk-ua": "Для номінації карт потрібно мінімум {{green}}{0}{{white}} гравців.", + "vi-vn": "Can it nhat {{green}}{0}{{white}} nguoi choi de de cu ban do." }, "ptr.mapmanager.nominate_usage": { "en-us": "Usage: .nominate ", @@ -341,66 +341,66 @@ "vi-vn": "Khong the de cu ban do hien tai." }, "ptr.mapmanager.player_nominated_map": { - "en-us": "{green}{0}{white} nominated map {green}{1}{white}.", - "zh-cn": "{green}{0}{white} 提名了地图 {green}{1}{white}。", - "zh-tw": "{green}{0}{white} 提名了地圖 {green}{1}{white}。", - "pt-br": "{green}{0}{white} nomeou o mapa {green}{1}{white}.", - "bg-bg": "{green}{0}{white} номинира карта {green}{1}{white}.", - "cs-cz": "{green}{0}{white} nominoval mapu {green}{1}{white}.", - "da-dk": "{green}{0}{white} nominerede kortet {green}{1}{white}.", - "nl-nl": "{green}{0}{white} nomineerde map {green}{1}{white}.", - "fi-fi": "{green}{0}{white} ehdotti karttaa {green}{1}{white}.", - "fr-fr": "{green}{0}{white} a nomine la carte {green}{1}{white}.", - "de-de": "{green}{0}{white} hat die Karte {green}{1}{white} nominiert.", - "el-gr": "Ο {green}{0}{white} προτεινε τον χαρτη {green}{1}{white}.", - "hu-hu": "{green}{0}{white} jelolte a {green}{1}{white} palyat.", - "id-id": "{green}{0}{white} menominasikan peta {green}{1}{white}.", - "it-it": "{green}{0}{white} ha nominato la mappa {green}{1}{white}.", - "ja-jp": "{green}{0}{white} がマップ {green}{1}{white} をノミネートしました。", - "ko-kr": "{green}{0}{white}님이 맵 {green}{1}{white}을(를) 추천했습니다.", - "es-419": "{green}{0}{white} nomino el mapa {green}{1}{white}.", - "nb-no": "{green}{0}{white} nominerte kartet {green}{1}{white}.", - "pl-pl": "{green}{0}{white} nominowal mape {green}{1}{white}.", - "pt-pt": "{green}{0}{white} nomeou o mapa {green}{1}{white}.", - "ro-ro": "{green}{0}{white} a nominalizat harta {green}{1}{white}.", - "ru-ru": "{green}{0}{white} номинировал карту {green}{1}{white}.", - "es-es": "{green}{0}{white} nomino el mapa {green}{1}{white}.", - "sv-se": "{green}{0}{white} nominerade kartan {green}{1}{white}.", - "th-th": "{green}{0}{white} เสนอชื่อแผนที่ {green}{1}{white}", - "tr-tr": "{green}{0}{white} haritayi aday gosterdi: {green}{1}{white}.", - "uk-ua": "{green}{0}{white} номінував карту {green}{1}{white}.", - "vi-vn": "{green}{0}{white} da de cu ban do {green}{1}{white}." + "en-us": "{{green}}{0}{{white}} nominated map {{green}}{1}{{white}}.", + "zh-cn": "{{green}}{0}{{white}} 提名了地图 {{green}}{1}{{white}}。", + "zh-tw": "{{green}}{0}{{white}} 提名了地圖 {{green}}{1}{{white}}。", + "pt-br": "{{green}}{0}{{white}} nomeou o mapa {{green}}{1}{{white}}.", + "bg-bg": "{{green}}{0}{{white}} номинира карта {{green}}{1}{{white}}.", + "cs-cz": "{{green}}{0}{{white}} nominoval mapu {{green}}{1}{{white}}.", + "da-dk": "{{green}}{0}{{white}} nominerede kortet {{green}}{1}{{white}}.", + "nl-nl": "{{green}}{0}{{white}} nomineerde map {{green}}{1}{{white}}.", + "fi-fi": "{{green}}{0}{{white}} ehdotti karttaa {{green}}{1}{{white}}.", + "fr-fr": "{{green}}{0}{{white}} a nomine la carte {{green}}{1}{{white}}.", + "de-de": "{{green}}{0}{{white}} hat die Karte {{green}}{1}{{white}} nominiert.", + "el-gr": "Ο {{green}}{0}{{white}} προτεινε τον χαρτη {{green}}{1}{{white}}.", + "hu-hu": "{{green}}{0}{{white}} jelolte a {{green}}{1}{{white}} palyat.", + "id-id": "{{green}}{0}{{white}} menominasikan peta {{green}}{1}{{white}}.", + "it-it": "{{green}}{0}{{white}} ha nominato la mappa {{green}}{1}{{white}}.", + "ja-jp": "{{green}}{0}{{white}} がマップ {{green}}{1}{{white}} をノミネートしました。", + "ko-kr": "{{green}}{0}{{white}}님이 맵 {{green}}{1}{{white}}을(를) 추천했습니다.", + "es-419": "{{green}}{0}{{white}} nomino el mapa {{green}}{1}{{white}}.", + "nb-no": "{{green}}{0}{{white}} nominerte kartet {{green}}{1}{{white}}.", + "pl-pl": "{{green}}{0}{{white}} nominowal mape {{green}}{1}{{white}}.", + "pt-pt": "{{green}}{0}{{white}} nomeou o mapa {{green}}{1}{{white}}.", + "ro-ro": "{{green}}{0}{{white}} a nominalizat harta {{green}}{1}{{white}}.", + "ru-ru": "{{green}}{0}{{white}} номинировал карту {{green}}{1}{{white}}.", + "es-es": "{{green}}{0}{{white}} nomino el mapa {{green}}{1}{{white}}.", + "sv-se": "{{green}}{0}{{white}} nominerade kartan {{green}}{1}{{white}}.", + "th-th": "{{green}}{0}{{white}} เสนอชื่อแผนที่ {{green}}{1}{{white}}", + "tr-tr": "{{green}}{0}{{white}} haritayi aday gosterdi: {{green}}{1}{{white}}.", + "uk-ua": "{{green}}{0}{{white}} номінував карту {{green}}{1}{{white}}.", + "vi-vn": "{{green}}{0}{{white}} da de cu ban do {{green}}{1}{{white}}." }, "ptr.mapmanager.rtv_after_x": { - "en-us": "A vote to change the map can only be initiated after {green}{0}{white} seconds.", - "zh-cn": "{green}{0}{white} 秒后才能发起换图投票。", - "zh-tw": "{green}{0}{white} 秒後才能發起換圖投票。", - "pt-br": "Uma votacao para mudar o mapa so pode ser iniciada apos {green}{0}{white} segundos.", - "bg-bg": "Гласуване за смяна на картата може да бъде започнато след {green}{0}{white} секунди.", - "cs-cz": "Hlasovani o zmene mapy lze zahajit az po {green}{0}{white} sekundach.", - "da-dk": "En afstemning om at skifte kort kan forst startes efter {green}{0}{white} sekunder.", - "nl-nl": "Een stemming om de map te wijzigen kan pas worden gestart na {green}{0}{white} seconden.", - "fi-fi": "Aanestys kartan vaihtamisesta voidaan aloittaa vasta {green}{0}{white} sekunnin kuluttua.", - "fr-fr": "Un vote pour changer de carte ne peut etre lance qu'apres {green}{0}{white} secondes.", - "de-de": "Eine Abstimmung zum Kartenwechsel kann erst nach {green}{0}{white} Sekunden gestartet werden.", - "el-gr": "Μια ψηφοφορια για αλλαγη χαρτη μπορει να ξεκινησει μετα απο {green}{0}{white} δευτερολεπτα.", - "hu-hu": "A palyavaltas szavazas csak {green}{0}{white} masodperc utan inditható.", - "id-id": "Pemungutan suara untuk mengubah peta hanya dapat dimulai setelah {green}{0}{white} detik.", - "it-it": "Una votazione per cambiare mappa puo essere avviata solo dopo {green}{0}{white} secondi.", - "ja-jp": "マップ変更の投票は {green}{0}{white} 秒後にのみ開始できます。", - "ko-kr": "맵 변경 투표는 {green}{0}{white}초 후에만 시작할 수 있습니다.", - "es-419": "Una votacion para cambiar el mapa solo puede iniciarse despues de {green}{0}{white} segundos.", - "nb-no": "En avstemning for a bytte kart kan bare startes etter {green}{0}{white} sekunder.", - "pl-pl": "Glosowanie nad zmiana mapy mozna rozpoczac dopiero po {green}{0}{white} sekundach.", - "pt-pt": "Uma votacao para mudar o mapa so pode ser iniciada apos {green}{0}{white} segundos.", - "ro-ro": "Un vot pentru schimbarea hartii poate fi initiat doar dupa {green}{0}{white} secunde.", - "ru-ru": "Голосование за смену карты можно начать только через {green}{0}{white} секунд.", - "es-es": "Una votacion para cambiar el mapa solo puede iniciarse despues de {green}{0}{white} segundos.", - "sv-se": "En omrostning for att byta karta kan bara startas efter {green}{0}{white} sekunder.", - "th-th": "การโหวตเปลี่ยนแผนที่สามารถเริ่มได้หลังจาก {green}{0}{white} วินาที", - "tr-tr": "Harita degistirmek icin oylama ancak {green}{0}{white} saniye sonra baslatilabilir.", - "uk-ua": "Голосування за зміну карти можна розпочати лише через {green}{0}{white} секунд.", - "vi-vn": "Cuoc bo phieu thay doi ban do chi co the bat dau sau {green}{0}{white} giay." + "en-us": "A vote to change the map can only be initiated after {{green}}{0}{{white}} seconds.", + "zh-cn": "{{green}}{0}{{white}} 秒后才能发起换图投票。", + "zh-tw": "{{green}}{0}{{white}} 秒後才能發起換圖投票。", + "pt-br": "Uma votacao para mudar o mapa so pode ser iniciada apos {{green}}{0}{{white}} segundos.", + "bg-bg": "Гласуване за смяна на картата може да бъде започнато след {{green}}{0}{{white}} секунди.", + "cs-cz": "Hlasovani o zmene mapy lze zahajit az po {{green}}{0}{{white}} sekundach.", + "da-dk": "En afstemning om at skifte kort kan forst startes efter {{green}}{0}{{white}} sekunder.", + "nl-nl": "Een stemming om de map te wijzigen kan pas worden gestart na {{green}}{0}{{white}} seconden.", + "fi-fi": "Aanestys kartan vaihtamisesta voidaan aloittaa vasta {{green}}{0}{{white}} sekunnin kuluttua.", + "fr-fr": "Un vote pour changer de carte ne peut etre lance qu'apres {{green}}{0}{{white}} secondes.", + "de-de": "Eine Abstimmung zum Kartenwechsel kann erst nach {{green}}{0}{{white}} Sekunden gestartet werden.", + "el-gr": "Μια ψηφοφορια για αλλαγη χαρτη μπορει να ξεκινησει μετα απο {{green}}{0}{{white}} δευτερολεπτα.", + "hu-hu": "A palyavaltas szavazas csak {{green}}{0}{{white}} masodperc utan inditható.", + "id-id": "Pemungutan suara untuk mengubah peta hanya dapat dimulai setelah {{green}}{0}{{white}} detik.", + "it-it": "Una votazione per cambiare mappa puo essere avviata solo dopo {{green}}{0}{{white}} secondi.", + "ja-jp": "マップ変更の投票は {{green}}{0}{{white}} 秒後にのみ開始できます。", + "ko-kr": "맵 변경 투표는 {{green}}{0}{{white}}초 후에만 시작할 수 있습니다.", + "es-419": "Una votacion para cambiar el mapa solo puede iniciarse despues de {{green}}{0}{{white}} segundos.", + "nb-no": "En avstemning for a bytte kart kan bare startes etter {{green}}{0}{{white}} sekunder.", + "pl-pl": "Glosowanie nad zmiana mapy mozna rozpoczac dopiero po {{green}}{0}{{white}} sekundach.", + "pt-pt": "Uma votacao para mudar o mapa so pode ser iniciada apos {{green}}{0}{{white}} segundos.", + "ro-ro": "Un vot pentru schimbarea hartii poate fi initiat doar dupa {{green}}{0}{{white}} secunde.", + "ru-ru": "Голосование за смену карты можно начать только через {{green}}{0}{{white}} секунд.", + "es-es": "Una votacion para cambiar el mapa solo puede iniciarse despues de {{green}}{0}{{white}} segundos.", + "sv-se": "En omrostning for att byta karta kan bara startas efter {{green}}{0}{{white}} sekunder.", + "th-th": "การโหวตเปลี่ยนแผนที่สามารถเริ่มได้หลังจาก {{green}}{0}{{white}} วินาที", + "tr-tr": "Harita degistirmek icin oylama ancak {{green}}{0}{{white}} saniye sonra baslatilabilir.", + "uk-ua": "Голосування за зміну карти можна розпочати лише через {{green}}{0}{{white}} секунд.", + "vi-vn": "Cuoc bo phieu thay doi ban do chi co the bat dau sau {{green}}{0}{{white}} giay." }, "ptr.mapmanager.already_voted_rtv": { "en-us": "You have already voted to change the map!", @@ -434,35 +434,35 @@ "vi-vn": "Ban da bo phieu thay doi ban do roi!" }, "ptr.mapmanager.rtv_vote_progress": { - "en-us": "{green}{0}{white} players have voted to change the map, {green}{1}{white} more votes needed.", - "zh-cn": "已有 {green}{0}{white} 人投票换图,还需 {green}{1}{white} 票。", - "zh-tw": "已有 {green}{0}{white} 人投票換圖,還需 {green}{1}{white} 票。", - "pt-br": "{green}{0}{white} jogadores votaram para mudar o mapa, {green}{1}{white} votos a mais necessarios.", - "bg-bg": "{green}{0}{white} играчи гласуваха за смяна на картата, необходими са още {green}{1}{white} гласа.", - "cs-cz": "{green}{0}{white} hracu hlasovalo pro zmenu mapy, potreba jeste {green}{1}{white} hlasu.", - "da-dk": "{green}{0}{white} spillere har stemt for at skifte kort, {green}{1}{white} flere stemmer nodvendige.", - "nl-nl": "{green}{0}{white} spelers hebben gestemd om de map te wijzigen, nog {green}{1}{white} stemmen nodig.", - "fi-fi": "{green}{0}{white} pelaajaa on aanestanyt kartan vaihtamisesta, {green}{1}{white} aanta viela tarvitaan.", - "fr-fr": "{green}{0}{white} joueurs ont vote pour changer de carte, {green}{1}{white} votes supplementaires requis.", - "de-de": "{green}{0}{white} Spieler haben fur einen Kartenwechsel gestimmt, {green}{1}{white} weitere Stimmen benotigt.", - "el-gr": "{green}{0}{white} παικτες ψηφισαν για αλλαγη χαρτη, χρειαζονται ακομη {green}{1}{white} ψηφοι.", - "hu-hu": "{green}{0}{white} jatekos szavazott a palyavaltasra, meg {green}{1}{white} szavazat szukseges.", - "id-id": "{green}{0}{white} pemain telah memilih untuk mengubah peta, {green}{1}{white} suara lagi diperlukan.", - "it-it": "{green}{0}{white} giocatori hanno votato per cambiare mappa, servono altri {green}{1}{white} voti.", - "ja-jp": "{green}{0}{white} 人がマップ変更に投票しました。あと {green}{1}{white} 票必要です。", - "ko-kr": "{green}{0}{white}명이 맵 변경에 투표했습니다. {green}{1}{white}표 더 필요합니다.", - "es-419": "{green}{0}{white} jugadores han votado para cambiar el mapa, se necesitan {green}{1}{white} votos mas.", - "nb-no": "{green}{0}{white} spillere har stemt for a bytte kart, {green}{1}{white} flere stemmer trengs.", - "pl-pl": "{green}{0}{white} graczy zaglosowalo za zmiana mapy, potrzeba jeszcze {green}{1}{white} glosow.", - "pt-pt": "{green}{0}{white} jogadores votaram para mudar o mapa, necessarios mais {green}{1}{white} votos.", - "ro-ro": "{green}{0}{white} jucatori au votat pentru schimbarea hartii, mai sunt necesare {green}{1}{white} voturi.", - "ru-ru": "{green}{0}{white} игроков проголосовало за смену карты, нужно ещё {green}{1}{white} голосов.", - "es-es": "{green}{0}{white} jugadores han votado para cambiar el mapa, se necesitan {green}{1}{white} votos mas.", - "sv-se": "{green}{0}{white} spelare har rostat for att byta karta, {green}{1}{white} fler roster behovs.", - "th-th": "{green}{0}{white} ผู้เล่นโหวตเปลี่ยนแผนที่แล้ว ต้องการอีก {green}{1}{white} โหวต", - "tr-tr": "{green}{0}{white} oyuncu harita degistirmek icin oy kullandi, {green}{1}{white} oy daha gerekli.", - "uk-ua": "{green}{0}{white} гравців проголосували за зміну карти, потрібно ще {green}{1}{white} голосів.", - "vi-vn": "{green}{0}{white} nguoi choi da bo phieu thay doi ban do, can them {green}{1}{white} phieu nua." + "en-us": "{{green}}{0}{{white}} players have voted to change the map, {{green}}{1}{{white}} more votes needed.", + "zh-cn": "已有 {{green}}{0}{{white}} 人投票换图,还需 {{green}}{1}{{white}} 票。", + "zh-tw": "已有 {{green}}{0}{{white}} 人投票換圖,還需 {{green}}{1}{{white}} 票。", + "pt-br": "{{green}}{0}{{white}} jogadores votaram para mudar o mapa, {{green}}{1}{{white}} votos a mais necessarios.", + "bg-bg": "{{green}}{0}{{white}} играчи гласуваха за смяна на картата, необходими са още {{green}}{1}{{white}} гласа.", + "cs-cz": "{{green}}{0}{{white}} hracu hlasovalo pro zmenu mapy, potreba jeste {{green}}{1}{{white}} hlasu.", + "da-dk": "{{green}}{0}{{white}} spillere har stemt for at skifte kort, {{green}}{1}{{white}} flere stemmer nodvendige.", + "nl-nl": "{{green}}{0}{{white}} spelers hebben gestemd om de map te wijzigen, nog {{green}}{1}{{white}} stemmen nodig.", + "fi-fi": "{{green}}{0}{{white}} pelaajaa on aanestanyt kartan vaihtamisesta, {{green}}{1}{{white}} aanta viela tarvitaan.", + "fr-fr": "{{green}}{0}{{white}} joueurs ont vote pour changer de carte, {{green}}{1}{{white}} votes supplementaires requis.", + "de-de": "{{green}}{0}{{white}} Spieler haben fur einen Kartenwechsel gestimmt, {{green}}{1}{{white}} weitere Stimmen benotigt.", + "el-gr": "{{green}}{0}{{white}} παικτες ψηφισαν για αλλαγη χαρτη, χρειαζονται ακομη {{green}}{1}{{white}} ψηφοι.", + "hu-hu": "{{green}}{0}{{white}} jatekos szavazott a palyavaltasra, meg {{green}}{1}{{white}} szavazat szukseges.", + "id-id": "{{green}}{0}{{white}} pemain telah memilih untuk mengubah peta, {{green}}{1}{{white}} suara lagi diperlukan.", + "it-it": "{{green}}{0}{{white}} giocatori hanno votato per cambiare mappa, servono altri {{green}}{1}{{white}} voti.", + "ja-jp": "{{green}}{0}{{white}} 人がマップ変更に投票しました。あと {{green}}{1}{{white}} 票必要です。", + "ko-kr": "{{green}}{0}{{white}}명이 맵 변경에 투표했습니다. {{green}}{1}{{white}}표 더 필요합니다.", + "es-419": "{{green}}{0}{{white}} jugadores han votado para cambiar el mapa, se necesitan {{green}}{1}{{white}} votos mas.", + "nb-no": "{{green}}{0}{{white}} spillere har stemt for a bytte kart, {{green}}{1}{{white}} flere stemmer trengs.", + "pl-pl": "{{green}}{0}{{white}} graczy zaglosowalo za zmiana mapy, potrzeba jeszcze {{green}}{1}{{white}} glosow.", + "pt-pt": "{{green}}{0}{{white}} jogadores votaram para mudar o mapa, necessarios mais {{green}}{1}{{white}} votos.", + "ro-ro": "{{green}}{0}{{white}} jucatori au votat pentru schimbarea hartii, mai sunt necesare {{green}}{1}{{white}} voturi.", + "ru-ru": "{{green}}{0}{{white}} игроков проголосовало за смену карты, нужно ещё {{green}}{1}{{white}} голосов.", + "es-es": "{{green}}{0}{{white}} jugadores han votado para cambiar el mapa, se necesitan {{green}}{1}{{white}} votos mas.", + "sv-se": "{{green}}{0}{{white}} spelare har rostat for att byta karta, {{green}}{1}{{white}} fler roster behovs.", + "th-th": "{{green}}{0}{{white}} ผู้เล่นโหวตเปลี่ยนแผนที่แล้ว ต้องการอีก {{green}}{1}{{white}} โหวต", + "tr-tr": "{{green}}{0}{{white}} oyuncu harita degistirmek icin oy kullandi, {{green}}{1}{{white}} oy daha gerekli.", + "uk-ua": "{{green}}{0}{{white}} гравців проголосували за зміну карти, потрібно ще {{green}}{1}{{white}} голосів.", + "vi-vn": "{{green}}{0}{{white}} nguoi choi da bo phieu thay doi ban do, can them {{green}}{1}{{white}} phieu nua." }, "ptr.mapmanager.rtv_vote_passed": { "en-us": "RTV vote passed! Map voting will start after this round ends.", diff --git a/src/Ptr.Modules.MapManager/MapManager.cs b/src/Ptr.Modules.MapManager/MapManager.cs index 732b279..c4de6ec 100644 --- a/src/Ptr.Modules.MapManager/MapManager.cs +++ b/src/Ptr.Modules.MapManager/MapManager.cs @@ -146,6 +146,7 @@ public void PostInit() _voteSuccessRatio = _bridge.ConVarManager.CreateConVar("mapmanager_vote_success_ratio", 0.6f, "Ratio request for a success vote."); + _provider.CallPostInit(e => { _logger.LogError(e, "An error occurred when initializing modules"); }); _bridge.SharpModuleManager.RegisterSharpModuleInterface(this, IMapManager.Identity, this); } diff --git a/src/Ptr.Modules.MapManager/Services/ExtendService.cs b/src/Ptr.Modules.MapManager/Services/ExtendService.cs index 839a453..86ea5b8 100644 --- a/src/Ptr.Modules.MapManager/Services/ExtendService.cs +++ b/src/Ptr.Modules.MapManager/Services/ExtendService.cs @@ -120,11 +120,11 @@ private void ResetExtCount() #region IModule public void OnPostInit() { - _enableExtend = _bridge!.ConVarManager.CreateConVar("mapmanager_enable_extend", true, "Enable ext"); + _enableExtend = _bridge!.ConVarManager.CreateConVar("mapmanager_enable_extend", true, "Enable ext", ConVarFlags.Release); _maxExtCount = _bridge!.ConVarManager.CreateConVar("mapmanager_max_extend_count", 3, - "Maximum allowed extend map time limit count."); + "Maximum allowed extend map time limit count.", ConVarFlags.Release); _extendTime = - _bridge!.ConVarManager.CreateConVar("mapmanager_ext_time", 15, "The extend applies for time limit."); + _bridge!.ConVarManager.CreateConVar("mapmanager_ext_time", 15, "The extend applies for time limit.", ConVarFlags.Release); } public void OnInit() { diff --git a/src/Ptr.Modules.MapManager/Services/NominateService.cs b/src/Ptr.Modules.MapManager/Services/NominateService.cs index c70abfe..99f7ba2 100644 --- a/src/Ptr.Modules.MapManager/Services/NominateService.cs +++ b/src/Ptr.Modules.MapManager/Services/NominateService.cs @@ -4,6 +4,7 @@ using Sharp.Modules.CommandManager.Shared; using Sharp.Modules.LocalizerManager.Shared; using Sharp.Shared.Definition; +using Sharp.Shared.Enums; using Sharp.Shared.Objects; using Sharp.Shared.Types; @@ -13,10 +14,11 @@ internal interface INominateService : IModule; internal class NominateService : INominateService { - private readonly IConVar? _activateNominateMinPlayers; private readonly InterfaceBridge _bridge; - private readonly IConVar? _enableNominate; + private IConVar? _enableNominate; + private IConVar? _activateNominateMinPlayers; + private readonly ILogger _logger; private ILocalizerManager _localizerManager = null!; @@ -24,10 +26,6 @@ public NominateService(InterfaceBridge bridge, ILogger logger) { _bridge = bridge; _logger = logger; - - _enableNominate = _bridge.ConVarManager.CreateConVar("mapmanager_enable_nominate", true, "Enable nominate"); - _activateNominateMinPlayers = _bridge.ConVarManager.CreateConVar("mapmanager_activate_nominate_min_players", 5, - "minimal players count to activate nominate."); } public void OnInit() @@ -35,6 +33,13 @@ public void OnInit() _logger.LogInformation("Nomination is enabled."); } + public void OnPostInit() + { + _enableNominate = _bridge.ConVarManager.CreateConVar("mapmanager_enable_nominate", true, "Enable nominate", ConVarFlags.Release); + _activateNominateMinPlayers = _bridge.ConVarManager.CreateConVar("mapmanager_activate_nominate_min_players", 5, + "minimal players count to activate nominate.", ConVarFlags.Release); + } + public void OnAllModulesLoaded() { _bridge diff --git a/src/Ptr.Modules.MapManager/Services/RtvService.cs b/src/Ptr.Modules.MapManager/Services/RtvService.cs index e4b158f..d338ca9 100644 --- a/src/Ptr.Modules.MapManager/Services/RtvService.cs +++ b/src/Ptr.Modules.MapManager/Services/RtvService.cs @@ -28,6 +28,11 @@ public RtvService(InterfaceBridge bridge, ILogger logger) private void AttemptRtv(IGameClient client) { + if (_enableRtv is null) + { + _logger.LogWarning("RTV ConVar is not initialized."); + return; + } if (_enableRtv?.GetBool() is not true) { _logger.LogInformation("RTV is disabled, skip RTV attempt."); @@ -116,7 +121,7 @@ public void OnInit() } public void OnPostInit() { - _enableRtv = _bridge.ConVarManager.CreateConVar("mapmanager_enable_rtv", true, "Enable RTV"); + _enableRtv = _bridge.ConVarManager.CreateConVar("mapmanager_enable_rtv", true, "Enable RTV", ConVarFlags.Release); } public void OnAllModulesLoaded() @@ -161,10 +166,8 @@ public void OnClientDisconnected(IGameClient client, NetworkDisconnectionReason public ECommandAction OnClientSayCommand(IGameClient client, bool teamOnly, bool isCommand, string commandName, string message) { - _logger.LogInformation("Client {ClientSlot} said: {Message}", client.Slot, message); if (message.Split().ElementAtOrDefault(0)?.Equals("rtv", StringComparison.OrdinalIgnoreCase) is true) { - _logger.LogInformation("Client {ClientSlot} is attempting to RTV.", client.Slot); AttemptRtv(client); } From c5ae09f3fda565e109151123df8ee7b8522c8a23 Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Mon, 5 Jan 2026 23:39:34 +0200 Subject: [PATCH 09/24] tweak formatter --- .../sharp/locales/Ptr.Modules.MapManager.json | 348 +++++++++--------- src/Ptr.Modules.MapManager/MapManager.cs | 6 +- 2 files changed, 178 insertions(+), 176 deletions(-) diff --git a/.asset/game/sharp/locales/Ptr.Modules.MapManager.json b/.asset/game/sharp/locales/Ptr.Modules.MapManager.json index b6dc5c3..c3a070f 100644 --- a/.asset/game/sharp/locales/Ptr.Modules.MapManager.json +++ b/.asset/game/sharp/locales/Ptr.Modules.MapManager.json @@ -1,34 +1,34 @@ { "ptr.mapmanager.extend_map_after_x": { - "en-us": "A vote to extend the map time can only be initiated after {{green}}{0}{{white}} seconds.", - "zh-cn": "{{green}}{0}{{white}} 秒后才能发起延长地图时间投票.", - "zh-tw": "{{green}}{0}{{white}} 秒後才能發起延長地圖時間投票。", - "pt-br": "Uma votacao para estender o tempo do mapa so pode ser iniciada apos {{green}}{0}{{white}} segundos.", - "bg-bg": "Гласуване за удължаване на времето на картата може да бъде започнато след {{green}}{0}{{white}} секунди.", - "cs-cz": "Hlasovani o prodlouzeni casu mapy lze zahajit az po {{green}}{0}{{white}} sekundach.", - "da-dk": "En afstemning om at forlaenge kortets tid kan forst startes efter {{green}}{0}{{white}} sekunder.", - "nl-nl": "Een stemming om de maptijd te verlengen kan pas worden gestart na {{green}}{0}{{white}} seconden.", - "fi-fi": "Aanestys kartan ajan jatkamisesta voidaan aloittaa vasta {{green}}{0}{{white}} sekunnin kuluttua.", - "fr-fr": "Un vote pour prolonger le temps de la carte ne peut etre lance qu'apres {{green}}{0}{{white}} secondes.", - "de-de": "Eine Abstimmung zur Verlangerung der Kartenzeit kann erst nach {{green}}{0}{{white}} Sekunden gestartet werden.", - "el-gr": "Μια ψηφοφορια για παραταση του χρονου του χαρτη μπορει να ξεκινησει μετα απο {{green}}{0}{{white}} δευτερολεπτα.", - "hu-hu": "A palya idejének meghosszabbitasara vonatkozo szavazas csak {{green}}{0}{{white}} masodperc utan inditható.", - "id-id": "Pemungutan suara untuk memperpanjang waktu peta hanya dapat dimulai setelah {{green}}{0}{{white}} detik.", - "it-it": "Una votazione per estendere il tempo della mappa puo essere avviata solo dopo {{green}}{0}{{white}} secondi.", - "ja-jp": "マップ時間延長の投票は {{green}}{0}{{white}} 秒後にのみ開始できます。", - "ko-kr": "맵 시간 연장 투표는 {{green}}{0}{{white}}초 후에만 시작할 수 있습니다.", - "es-419": "Una votacion para extender el tiempo del mapa solo puede iniciarse despues de {{green}}{0}{{white}} segundos.", - "nb-no": "En avstemning for a forlenge karttiden kan bare startes etter {{green}}{0}{{white}} sekunder.", - "pl-pl": "Glosowanie nad przedluzeniem czasu mapy mozna rozpoczac dopiero po {{green}}{0}{{white}} sekundach.", - "pt-pt": "Uma votacao para prolongar o tempo do mapa so pode ser iniciada apos {{green}}{0}{{white}} segundos.", - "ro-ro": "Un vot pentru prelungirea timpului hartii poate fi initiat doar dupa {{green}}{0}{{white}} secunde.", - "ru-ru": "Голосование за продление времени карты можно начать только через {{green}}{0}{{white}} секунд.", - "es-es": "Una votacion para extender el tiempo del mapa solo puede iniciarse despues de {{green}}{0}{{white}} segundos.", - "sv-se": "En omrostning for att forlanga karttiden kan bara startas efter {{green}}{0}{{white}} sekunder.", - "th-th": "การโหวตขยายเวลาแผนที่สามารถเริ่มได้หลังจาก {{green}}{0}{{white}} วินาที", - "tr-tr": "Harita suresini uzatmak icin oylama ancak {{green}}{0}{{white}} saniye sonra baslatilabilir.", - "uk-ua": "Голосування за продовження часу карти можна розпочати лише через {{green}}{0}{{white}} секунд.", - "vi-vn": "Cuoc bo phieu gia han thoi gian ban do chi co the bat dau sau {{green}}{0}{{white}} giay." + "en-us": "A vote to extend the map time can only be initiated after {{green}}{0}{{muted}} seconds.", + "zh-cn": "{{green}}{0}{{muted}} 秒后才能发起延长地图时间投票.", + "zh-tw": "{{green}}{0}{{muted}} 秒後才能發起延長地圖時間投票。", + "pt-br": "Uma votacao para estender o tempo do mapa so pode ser iniciada apos {{green}}{0}{{muted}} segundos.", + "bg-bg": "Гласуване за удължаване на времето на картата може да бъде започнато след {{green}}{0}{{muted}} секунди.", + "cs-cz": "Hlasovani o prodlouzeni casu mapy lze zahajit az po {{green}}{0}{{muted}} sekundach.", + "da-dk": "En afstemning om at forlaenge kortets tid kan forst startes efter {{green}}{0}{{muted}} sekunder.", + "nl-nl": "Een stemming om de maptijd te verlengen kan pas worden gestart na {{green}}{0}{{muted}} seconden.", + "fi-fi": "Aanestys kartan ajan jatkamisesta voidaan aloittaa vasta {{green}}{0}{{muted}} sekunnin kuluttua.", + "fr-fr": "Un vote pour prolonger le temps de la carte ne peut etre lance qu'apres {{green}}{0}{{muted}} secondes.", + "de-de": "Eine Abstimmung zur Verlangerung der Kartenzeit kann erst nach {{green}}{0}{{muted}} Sekunden gestartet werden.", + "el-gr": "Μια ψηφοφορια για παραταση του χρονου του χαρτη μπορει να ξεκινησει μετα απο {{green}}{0}{{muted}} δευτερολεπτα.", + "hu-hu": "A palya idejének meghosszabbitasara vonatkozo szavazas csak {{green}}{0}{{muted}} masodperc utan inditható.", + "id-id": "Pemungutan suara untuk memperpanjang waktu peta hanya dapat dimulai setelah {{green}}{0}{{muted}} detik.", + "it-it": "Una votazione per estendere il tempo della mappa puo essere avviata solo dopo {{green}}{0}{{muted}} secondi.", + "ja-jp": "マップ時間延長の投票は {{green}}{0}{{muted}} 秒後にのみ開始できます。", + "ko-kr": "맵 시간 연장 투표는 {{green}}{0}{{muted}}초 후에만 시작할 수 있습니다.", + "es-419": "Una votacion para extender el tiempo del mapa solo puede iniciarse despues de {{green}}{0}{{muted}} segundos.", + "nb-no": "En avstemning for a forlenge karttiden kan bare startes etter {{green}}{0}{{muted}} sekunder.", + "pl-pl": "Glosowanie nad przedluzeniem czasu mapy mozna rozpoczac dopiero po {{green}}{0}{{muted}} sekundach.", + "pt-pt": "Uma votacao para prolongar o tempo do mapa so pode ser iniciada apos {{green}}{0}{{muted}} segundos.", + "ro-ro": "Un vot pentru prelungirea timpului hartii poate fi initiat doar dupa {{green}}{0}{{muted}} secunde.", + "ru-ru": "Голосование за продление времени карты можно начать только через {{green}}{0}{{muted}} секунд.", + "es-es": "Una votacion para extender el tiempo del mapa solo puede iniciarse despues de {{green}}{0}{{muted}} segundos.", + "sv-se": "En omrostning for att forlanga karttiden kan bara startas efter {{green}}{0}{{muted}} sekunder.", + "th-th": "การโหวตขยายเวลาแผนที่สามารถเริ่มได้หลังจาก {{green}}{0}{{muted}} วินาที", + "tr-tr": "Harita suresini uzatmak icin oylama ancak {{green}}{0}{{muted}} saniye sonra baslatilabilir.", + "uk-ua": "Голосування за продовження часу карти можна розпочати лише через {{green}}{0}{{muted}} секунд.", + "vi-vn": "Cuoc bo phieu gia han thoi gian ban do chi co the bat dau sau {{green}}{0}{{muted}} giay." }, "ptr.mapmanager.max_extends_reached": { "en-us": "The maximum number of times the time can be extended has been reached.", @@ -93,35 +93,35 @@ "vi-vn": "Ban da bo phieu gia han thoi gian ban do roi." }, "ptr.mapmanager.extend_vote_progress": { - "en-us": "{{green}}{0}{{white}} players have voted to extend the map time, {{green}}{1}{{white}} more votes needed.", - "zh-cn": "已有 {{green}}{0}{{white}} 人投票延长地图时间,还需 {{green}}{1}{{white}} 票。", - "zh-tw": "已有 {{green}}{0}{{white}} 人投票延長地圖時間,還需 {{green}}{1}{{white}} 票。", - "pt-br": "{{green}}{0}{{white}} jogadores votaram para estender o tempo do mapa, {{green}}{1}{{white}} votos a mais necessarios.", - "bg-bg": "{{green}}{0}{{white}} играчи гласуваха за удължаване на времето, необходими са още {{green}}{1}{{white}} гласа.", - "cs-cz": "{{green}}{0}{{white}} hracu hlasovalo pro prodlouzeni casu mapy, potreba jeste {{green}}{1}{{white}} hlasu.", - "da-dk": "{{green}}{0}{{white}} spillere har stemt for at forlaenge kortets tid, {{green}}{1}{{white}} flere stemmer nodvendige.", - "nl-nl": "{{green}}{0}{{white}} spelers hebben gestemd om de maptijd te verlengen, nog {{green}}{1}{{white}} stemmen nodig.", - "fi-fi": "{{green}}{0}{{white}} pelaajaa on aanestanyt ajan jatkamisesta, {{green}}{1}{{white}} aanta viela tarvitaan.", - "fr-fr": "{{green}}{0}{{white}} joueurs ont vote pour prolonger le temps, {{green}}{1}{{white}} votes supplementaires requis.", - "de-de": "{{green}}{0}{{white}} Spieler haben fur die Zeitverlangerung gestimmt, {{green}}{1}{{white}} weitere Stimmen benotigt.", - "el-gr": "{{green}}{0}{{white}} παικτες ψηφισαν για παραταση χρονου, χρειαζονται ακομη {{green}}{1}{{white}} ψηφοι.", - "hu-hu": "{{green}}{0}{{white}} jatekos szavazott az idomeghosszabbitasra, meg {{green}}{1}{{white}} szavazat szukseges.", - "id-id": "{{green}}{0}{{white}} pemain telah memilih untuk memperpanjang waktu, {{green}}{1}{{white}} suara lagi diperlukan.", - "it-it": "{{green}}{0}{{white}} giocatori hanno votato per estendere il tempo, servono altri {{green}}{1}{{white}} voti.", - "ja-jp": "{{green}}{0}{{white}} 人が時間延長に投票しました。あと {{green}}{1}{{white}} 票必要です。", - "ko-kr": "{{green}}{0}{{white}}명이 시간 연장에 투표했습니다. {{green}}{1}{{white}}표 더 필요합니다.", - "es-419": "{{green}}{0}{{white}} jugadores han votado para extender el tiempo, se necesitan {{green}}{1}{{white}} votos mas.", - "nb-no": "{{green}}{0}{{white}} spillere har stemt for a forlenge tiden, {{green}}{1}{{white}} flere stemmer trengs.", - "pl-pl": "{{green}}{0}{{white}} graczy zaglosowalo za przedluzeniem czasu, potrzeba jeszcze {{green}}{1}{{white}} glosow.", - "pt-pt": "{{green}}{0}{{white}} jogadores votaram para prolongar o tempo, necessarios mais {{green}}{1}{{white}} votos.", - "ro-ro": "{{green}}{0}{{white}} jucatori au votat pentru prelungirea timpului, mai sunt necesare {{green}}{1}{{white}} voturi.", - "ru-ru": "{{green}}{0}{{white}} игроков проголосовало за продление времени, нужно ещё {{green}}{1}{{white}} голосов.", - "es-es": "{{green}}{0}{{white}} jugadores han votado para extender el tiempo, se necesitan {{green}}{1}{{white}} votos mas.", - "sv-se": "{{green}}{0}{{white}} spelare har rostat for att forlanga tiden, {{green}}{1}{{white}} fler roster behovs.", - "th-th": "{{green}}{0}{{white}} ผู้เล่นโหวตขยายเวลาแล้ว ต้องการอีก {{green}}{1}{{white}} โหวต", - "tr-tr": "{{green}}{0}{{white}} oyuncu sure uzatmak icin oy kullandi, {{green}}{1}{{white}} oy daha gerekli.", - "uk-ua": "{{green}}{0}{{white}} гравців проголосували за продовження часу, потрібно ще {{green}}{1}{{white}} голосів.", - "vi-vn": "{{green}}{0}{{white}} nguoi choi da bo phieu gia han thoi gian, can them {{green}}{1}{{white}} phieu nua." + "en-us": "{{green}}{0}{{muted}} players have voted to extend the map time, {{green}}{1}{{muted}} more votes needed.", + "zh-cn": "已有 {{green}}{0}{{muted}} 人投票延长地图时间,还需 {{green}}{1}{{muted}} 票。", + "zh-tw": "已有 {{green}}{0}{{muted}} 人投票延長地圖時間,還需 {{green}}{1}{{muted}} 票。", + "pt-br": "{{green}}{0}{{muted}} jogadores votaram para estender o tempo do mapa, {{green}}{1}{{muted}} votos a mais necessarios.", + "bg-bg": "{{green}}{0}{{muted}} играчи гласуваха за удължаване на времето, необходими са още {{green}}{1}{{muted}} гласа.", + "cs-cz": "{{green}}{0}{{muted}} hracu hlasovalo pro prodlouzeni casu mapy, potreba jeste {{green}}{1}{{muted}} hlasu.", + "da-dk": "{{green}}{0}{{muted}} spillere har stemt for at forlaenge kortets tid, {{green}}{1}{{muted}} flere stemmer nodvendige.", + "nl-nl": "{{green}}{0}{{muted}} spelers hebben gestemd om de maptijd te verlengen, nog {{green}}{1}{{muted}} stemmen nodig.", + "fi-fi": "{{green}}{0}{{muted}} pelaajaa on aanestanyt ajan jatkamisesta, {{green}}{1}{{muted}} aanta viela tarvitaan.", + "fr-fr": "{{green}}{0}{{muted}} joueurs ont vote pour prolonger le temps, {{green}}{1}{{muted}} votes supplementaires requis.", + "de-de": "{{green}}{0}{{muted}} Spieler haben fur die Zeitverlangerung gestimmt, {{green}}{1}{{muted}} weitere Stimmen benotigt.", + "el-gr": "{{green}}{0}{{muted}} παικτες ψηφισαν για παραταση χρονου, χρειαζονται ακομη {{green}}{1}{{muted}} ψηφοι.", + "hu-hu": "{{green}}{0}{{muted}} jatekos szavazott az idomeghosszabbitasra, meg {{green}}{1}{{muted}} szavazat szukseges.", + "id-id": "{{green}}{0}{{muted}} pemain telah memilih untuk memperpanjang waktu, {{green}}{1}{{muted}} suara lagi diperlukan.", + "it-it": "{{green}}{0}{{muted}} giocatori hanno votato per estendere il tempo, servono altri {{green}}{1}{{muted}} voti.", + "ja-jp": "{{green}}{0}{{muted}} 人が時間延長に投票しました。あと {{green}}{1}{{muted}} 票必要です。", + "ko-kr": "{{green}}{0}{{muted}}명이 시간 연장에 투표했습니다. {{green}}{1}{{muted}}표 더 필요합니다.", + "es-419": "{{green}}{0}{{muted}} jugadores han votado para extender el tiempo, se necesitan {{green}}{1}{{muted}} votos mas.", + "nb-no": "{{green}}{0}{{muted}} spillere har stemt for a forlenge tiden, {{green}}{1}{{muted}} flere stemmer trengs.", + "pl-pl": "{{green}}{0}{{muted}} graczy zaglosowalo za przedluzeniem czasu, potrzeba jeszcze {{green}}{1}{{muted}} glosow.", + "pt-pt": "{{green}}{0}{{muted}} jogadores votaram para prolongar o tempo, necessarios mais {{green}}{1}{{muted}} votos.", + "ro-ro": "{{green}}{0}{{muted}} jucatori au votat pentru prelungirea timpului, mai sunt necesare {{green}}{1}{{muted}} voturi.", + "ru-ru": "{{green}}{0}{{muted}} игроков проголосовало за продление времени, нужно ещё {{green}}{1}{{muted}} голосов.", + "es-es": "{{green}}{0}{{muted}} jugadores han votado para extender el tiempo, se necesitan {{green}}{1}{{muted}} votos mas.", + "sv-se": "{{green}}{0}{{muted}} spelare har rostat for att forlanga tiden, {{green}}{1}{{muted}} fler roster behovs.", + "th-th": "{{green}}{0}{{muted}} ผู้เล่นโหวตขยายเวลาแล้ว ต้องการอีก {{green}}{1}{{muted}} โหวต", + "tr-tr": "{{green}}{0}{{muted}} oyuncu sure uzatmak icin oy kullandi, {{green}}{1}{{muted}} oy daha gerekli.", + "uk-ua": "{{green}}{0}{{muted}} гравців проголосували за продовження часу, потрібно ще {{green}}{1}{{muted}} голосів.", + "vi-vn": "{{green}}{0}{{muted}} nguoi choi da bo phieu gia han thoi gian, can them {{green}}{1}{{muted}} phieu nua." }, "ptr.mapmanager.extend_vote_passed": { "en-us": "Vote passed, the map time will be extended.", @@ -155,35 +155,35 @@ "vi-vn": "Bo phieu thanh cong, thoi gian ban do se duoc gia han." }, "ptr.mapmanager.nominate_not_enough_players": { - "en-us": "At least {{green}}{0}{{white}} players are required to nominate maps.", - "zh-cn": "当前在线人数不足 {{green}}{0}{{white}} 人,无法提名地图。", - "zh-tw": "當前在線人數不足 {{green}}{0}{{white}} 人,無法提名地圖。", - "pt-br": "Sao necessarios pelo menos {{green}}{0}{{white}} jogadores para nomear mapas.", - "bg-bg": "Необходими са поне {{green}}{0}{{white}} играчи за номиниране на карти.", - "cs-cz": "Pro nominaci map je potreba alespon {{green}}{0}{{white}} hracu.", - "da-dk": "Der kraeves mindst {{green}}{0}{{white}} spillere for at nominere kort.", - "nl-nl": "Er zijn minimaal {{green}}{0}{{white}} spelers nodig om maps te nomineren.", - "fi-fi": "Karttojen ehdottamiseen tarvitaan vahintaan {{green}}{0}{{white}} pelaajaa.", - "fr-fr": "Au moins {{green}}{0}{{white}} joueurs sont requis pour nominer des cartes.", - "de-de": "Mindestens {{green}}{0}{{white}} Spieler werden benotigt, um Karten zu nominieren.", - "el-gr": "Απαιτουνται τουλαχιστον {{green}}{0}{{white}} παικτες για να προτεινετε χαρτες.", - "hu-hu": "Legalabb {{green}}{0}{{white}} jatekos szukseges a palyak jelolesehez.", - "id-id": "Diperlukan setidaknya {{green}}{0}{{white}} pemain untuk menominasikan peta.", - "it-it": "Sono necessari almeno {{green}}{0}{{white}} giocatori per nominare mappe.", - "ja-jp": "マップをノミネートするには少なくとも {{green}}{0}{{white}} 人のプレイヤーが必要です。", - "ko-kr": "맵 추천에는 최소 {{green}}{0}{{white}}명의 플레이어가 필요합니다.", - "es-419": "Se requieren al menos {{green}}{0}{{white}} jugadores para nominar mapas.", - "nb-no": "Minst {{green}}{0}{{white}} spillere kreves for a nominere kart.", - "pl-pl": "Do nominowania map wymaganych jest co najmniej {{green}}{0}{{white}} graczy.", - "pt-pt": "Sao necessarios pelo menos {{green}}{0}{{white}} jogadores para nomear mapas.", - "ro-ro": "Sunt necesari cel putin {{green}}{0}{{white}} jucatori pentru a nominaliza harti.", - "ru-ru": "Для номинации карт требуется минимум {{green}}{0}{{white}} игроков.", - "es-es": "Se requieren al menos {{green}}{0}{{white}} jugadores para nominar mapas.", - "sv-se": "Minst {{green}}{0}{{white}} spelare kravs for att nominera kartor.", - "th-th": "ต้องมีผู้เล่นอย่างน้อย {{green}}{0}{{white}} คนเพื่อเสนอชื่อแผนที่", - "tr-tr": "Harita aday gostermek icin en az {{green}}{0}{{white}} oyuncu gereklidir.", - "uk-ua": "Для номінації карт потрібно мінімум {{green}}{0}{{white}} гравців.", - "vi-vn": "Can it nhat {{green}}{0}{{white}} nguoi choi de de cu ban do." + "en-us": "At least {{green}}{0}{{muted}} players are required to nominate maps.", + "zh-cn": "当前在线人数不足 {{green}}{0}{{muted}} 人,无法提名地图。", + "zh-tw": "當前在線人數不足 {{green}}{0}{{muted}} 人,無法提名地圖。", + "pt-br": "Sao necessarios pelo menos {{green}}{0}{{muted}} jogadores para nomear mapas.", + "bg-bg": "Необходими са поне {{green}}{0}{{muted}} играчи за номиниране на карти.", + "cs-cz": "Pro nominaci map je potreba alespon {{green}}{0}{{muted}} hracu.", + "da-dk": "Der kraeves mindst {{green}}{0}{{muted}} spillere for at nominere kort.", + "nl-nl": "Er zijn minimaal {{green}}{0}{{muted}} spelers nodig om maps te nomineren.", + "fi-fi": "Karttojen ehdottamiseen tarvitaan vahintaan {{green}}{0}{{muted}} pelaajaa.", + "fr-fr": "Au moins {{green}}{0}{{muted}} joueurs sont requis pour nominer des cartes.", + "de-de": "Mindestens {{green}}{0}{{muted}} Spieler werden benotigt, um Karten zu nominieren.", + "el-gr": "Απαιτουνται τουλαχιστον {{green}}{0}{{muted}} παικτες για να προτεινετε χαρτες.", + "hu-hu": "Legalabb {{green}}{0}{{muted}} jatekos szukseges a palyak jelolesehez.", + "id-id": "Diperlukan setidaknya {{green}}{0}{{muted}} pemain untuk menominasikan peta.", + "it-it": "Sono necessari almeno {{green}}{0}{{muted}} giocatori per nominare mappe.", + "ja-jp": "マップをノミネートするには少なくとも {{green}}{0}{{muted}} 人のプレイヤーが必要です。", + "ko-kr": "맵 추천에는 최소 {{green}}{0}{{muted}}명의 플레이어가 필요합니다.", + "es-419": "Se requieren al menos {{green}}{0}{{muted}} jugadores para nominar mapas.", + "nb-no": "Minst {{green}}{0}{{muted}} spillere kreves for a nominere kart.", + "pl-pl": "Do nominowania map wymaganych jest co najmniej {{green}}{0}{{muted}} graczy.", + "pt-pt": "Sao necessarios pelo menos {{green}}{0}{{muted}} jogadores para nomear mapas.", + "ro-ro": "Sunt necesari cel putin {{green}}{0}{{muted}} jucatori pentru a nominaliza harti.", + "ru-ru": "Для номинации карт требуется минимум {{green}}{0}{{muted}} игроков.", + "es-es": "Se requieren al menos {{green}}{0}{{muted}} jugadores para nominar mapas.", + "sv-se": "Minst {{green}}{0}{{muted}} spelare kravs for att nominera kartor.", + "th-th": "ต้องมีผู้เล่นอย่างน้อย {{green}}{0}{{muted}} คนเพื่อเสนอชื่อแผนที่", + "tr-tr": "Harita aday gostermek icin en az {{green}}{0}{{muted}} oyuncu gereklidir.", + "uk-ua": "Для номінації карт потрібно мінімум {{green}}{0}{{muted}} гравців.", + "vi-vn": "Can it nhat {{green}}{0}{{muted}} nguoi choi de de cu ban do." }, "ptr.mapmanager.nominate_usage": { "en-us": "Usage: .nominate ", @@ -341,66 +341,66 @@ "vi-vn": "Khong the de cu ban do hien tai." }, "ptr.mapmanager.player_nominated_map": { - "en-us": "{{green}}{0}{{white}} nominated map {{green}}{1}{{white}}.", - "zh-cn": "{{green}}{0}{{white}} 提名了地图 {{green}}{1}{{white}}。", - "zh-tw": "{{green}}{0}{{white}} 提名了地圖 {{green}}{1}{{white}}。", - "pt-br": "{{green}}{0}{{white}} nomeou o mapa {{green}}{1}{{white}}.", - "bg-bg": "{{green}}{0}{{white}} номинира карта {{green}}{1}{{white}}.", - "cs-cz": "{{green}}{0}{{white}} nominoval mapu {{green}}{1}{{white}}.", - "da-dk": "{{green}}{0}{{white}} nominerede kortet {{green}}{1}{{white}}.", - "nl-nl": "{{green}}{0}{{white}} nomineerde map {{green}}{1}{{white}}.", - "fi-fi": "{{green}}{0}{{white}} ehdotti karttaa {{green}}{1}{{white}}.", - "fr-fr": "{{green}}{0}{{white}} a nomine la carte {{green}}{1}{{white}}.", - "de-de": "{{green}}{0}{{white}} hat die Karte {{green}}{1}{{white}} nominiert.", - "el-gr": "Ο {{green}}{0}{{white}} προτεινε τον χαρτη {{green}}{1}{{white}}.", - "hu-hu": "{{green}}{0}{{white}} jelolte a {{green}}{1}{{white}} palyat.", - "id-id": "{{green}}{0}{{white}} menominasikan peta {{green}}{1}{{white}}.", - "it-it": "{{green}}{0}{{white}} ha nominato la mappa {{green}}{1}{{white}}.", - "ja-jp": "{{green}}{0}{{white}} がマップ {{green}}{1}{{white}} をノミネートしました。", - "ko-kr": "{{green}}{0}{{white}}님이 맵 {{green}}{1}{{white}}을(를) 추천했습니다.", - "es-419": "{{green}}{0}{{white}} nomino el mapa {{green}}{1}{{white}}.", - "nb-no": "{{green}}{0}{{white}} nominerte kartet {{green}}{1}{{white}}.", - "pl-pl": "{{green}}{0}{{white}} nominowal mape {{green}}{1}{{white}}.", - "pt-pt": "{{green}}{0}{{white}} nomeou o mapa {{green}}{1}{{white}}.", - "ro-ro": "{{green}}{0}{{white}} a nominalizat harta {{green}}{1}{{white}}.", - "ru-ru": "{{green}}{0}{{white}} номинировал карту {{green}}{1}{{white}}.", - "es-es": "{{green}}{0}{{white}} nomino el mapa {{green}}{1}{{white}}.", - "sv-se": "{{green}}{0}{{white}} nominerade kartan {{green}}{1}{{white}}.", - "th-th": "{{green}}{0}{{white}} เสนอชื่อแผนที่ {{green}}{1}{{white}}", - "tr-tr": "{{green}}{0}{{white}} haritayi aday gosterdi: {{green}}{1}{{white}}.", - "uk-ua": "{{green}}{0}{{white}} номінував карту {{green}}{1}{{white}}.", - "vi-vn": "{{green}}{0}{{white}} da de cu ban do {{green}}{1}{{white}}." + "en-us": "{{green}}{0}{{muted}} nominated map {{green}}{1}{{muted}}.", + "zh-cn": "{{green}}{0}{{muted}} 提名了地图 {{green}}{1}{{muted}}。", + "zh-tw": "{{green}}{0}{{muted}} 提名了地圖 {{green}}{1}{{muted}}。", + "pt-br": "{{green}}{0}{{muted}} nomeou o mapa {{green}}{1}{{muted}}.", + "bg-bg": "{{green}}{0}{{muted}} номинира карта {{green}}{1}{{muted}}.", + "cs-cz": "{{green}}{0}{{muted}} nominoval mapu {{green}}{1}{{muted}}.", + "da-dk": "{{green}}{0}{{muted}} nominerede kortet {{green}}{1}{{muted}}.", + "nl-nl": "{{green}}{0}{{muted}} nomineerde map {{green}}{1}{{muted}}.", + "fi-fi": "{{green}}{0}{{muted}} ehdotti karttaa {{green}}{1}{{muted}}.", + "fr-fr": "{{green}}{0}{{muted}} a nomine la carte {{green}}{1}{{muted}}.", + "de-de": "{{green}}{0}{{muted}} hat die Karte {{green}}{1}{{muted}} nominiert.", + "el-gr": "Ο {{green}}{0}{{muted}} προτεινε τον χαρτη {{green}}{1}{{muted}}.", + "hu-hu": "{{green}}{0}{{muted}} jelolte a {{green}}{1}{{muted}} palyat.", + "id-id": "{{green}}{0}{{muted}} menominasikan peta {{green}}{1}{{muted}}.", + "it-it": "{{green}}{0}{{muted}} ha nominato la mappa {{green}}{1}{{muted}}.", + "ja-jp": "{{green}}{0}{{muted}} がマップ {{green}}{1}{{muted}} をノミネートしました。", + "ko-kr": "{{green}}{0}{{muted}}님이 맵 {{green}}{1}{{muted}}을(를) 추천했습니다.", + "es-419": "{{green}}{0}{{muted}} nomino el mapa {{green}}{1}{{muted}}.", + "nb-no": "{{green}}{0}{{muted}} nominerte kartet {{green}}{1}{{muted}}.", + "pl-pl": "{{green}}{0}{{muted}} nominowal mape {{green}}{1}{{muted}}.", + "pt-pt": "{{green}}{0}{{muted}} nomeou o mapa {{green}}{1}{{muted}}.", + "ro-ro": "{{green}}{0}{{muted}} a nominalizat harta {{green}}{1}{{muted}}.", + "ru-ru": "{{green}}{0}{{muted}} номинировал карту {{green}}{1}{{muted}}.", + "es-es": "{{green}}{0}{{muted}} nomino el mapa {{green}}{1}{{muted}}.", + "sv-se": "{{green}}{0}{{muted}} nominerade kartan {{green}}{1}{{muted}}.", + "th-th": "{{green}}{0}{{muted}} เสนอชื่อแผนที่ {{green}}{1}{{muted}}", + "tr-tr": "{{green}}{0}{{muted}} haritayi aday gosterdi: {{green}}{1}{{muted}}.", + "uk-ua": "{{green}}{0}{{muted}} номінував карту {{green}}{1}{{muted}}.", + "vi-vn": "{{green}}{0}{{muted}} da de cu ban do {{green}}{1}{{muted}}." }, "ptr.mapmanager.rtv_after_x": { - "en-us": "A vote to change the map can only be initiated after {{green}}{0}{{white}} seconds.", - "zh-cn": "{{green}}{0}{{white}} 秒后才能发起换图投票。", - "zh-tw": "{{green}}{0}{{white}} 秒後才能發起換圖投票。", - "pt-br": "Uma votacao para mudar o mapa so pode ser iniciada apos {{green}}{0}{{white}} segundos.", - "bg-bg": "Гласуване за смяна на картата може да бъде започнато след {{green}}{0}{{white}} секунди.", - "cs-cz": "Hlasovani o zmene mapy lze zahajit az po {{green}}{0}{{white}} sekundach.", - "da-dk": "En afstemning om at skifte kort kan forst startes efter {{green}}{0}{{white}} sekunder.", - "nl-nl": "Een stemming om de map te wijzigen kan pas worden gestart na {{green}}{0}{{white}} seconden.", - "fi-fi": "Aanestys kartan vaihtamisesta voidaan aloittaa vasta {{green}}{0}{{white}} sekunnin kuluttua.", - "fr-fr": "Un vote pour changer de carte ne peut etre lance qu'apres {{green}}{0}{{white}} secondes.", - "de-de": "Eine Abstimmung zum Kartenwechsel kann erst nach {{green}}{0}{{white}} Sekunden gestartet werden.", - "el-gr": "Μια ψηφοφορια για αλλαγη χαρτη μπορει να ξεκινησει μετα απο {{green}}{0}{{white}} δευτερολεπτα.", - "hu-hu": "A palyavaltas szavazas csak {{green}}{0}{{white}} masodperc utan inditható.", - "id-id": "Pemungutan suara untuk mengubah peta hanya dapat dimulai setelah {{green}}{0}{{white}} detik.", - "it-it": "Una votazione per cambiare mappa puo essere avviata solo dopo {{green}}{0}{{white}} secondi.", - "ja-jp": "マップ変更の投票は {{green}}{0}{{white}} 秒後にのみ開始できます。", - "ko-kr": "맵 변경 투표는 {{green}}{0}{{white}}초 후에만 시작할 수 있습니다.", - "es-419": "Una votacion para cambiar el mapa solo puede iniciarse despues de {{green}}{0}{{white}} segundos.", - "nb-no": "En avstemning for a bytte kart kan bare startes etter {{green}}{0}{{white}} sekunder.", - "pl-pl": "Glosowanie nad zmiana mapy mozna rozpoczac dopiero po {{green}}{0}{{white}} sekundach.", - "pt-pt": "Uma votacao para mudar o mapa so pode ser iniciada apos {{green}}{0}{{white}} segundos.", - "ro-ro": "Un vot pentru schimbarea hartii poate fi initiat doar dupa {{green}}{0}{{white}} secunde.", - "ru-ru": "Голосование за смену карты можно начать только через {{green}}{0}{{white}} секунд.", - "es-es": "Una votacion para cambiar el mapa solo puede iniciarse despues de {{green}}{0}{{white}} segundos.", - "sv-se": "En omrostning for att byta karta kan bara startas efter {{green}}{0}{{white}} sekunder.", - "th-th": "การโหวตเปลี่ยนแผนที่สามารถเริ่มได้หลังจาก {{green}}{0}{{white}} วินาที", - "tr-tr": "Harita degistirmek icin oylama ancak {{green}}{0}{{white}} saniye sonra baslatilabilir.", - "uk-ua": "Голосування за зміну карти можна розпочати лише через {{green}}{0}{{white}} секунд.", - "vi-vn": "Cuoc bo phieu thay doi ban do chi co the bat dau sau {{green}}{0}{{white}} giay." + "en-us": "A vote to change the map can only be initiated after {{green}}{0}{{muted}} seconds.", + "zh-cn": "{{green}}{0}{{muted}} 秒后才能发起换图投票。", + "zh-tw": "{{green}}{0}{{muted}} 秒後才能發起換圖投票。", + "pt-br": "Uma votacao para mudar o mapa so pode ser iniciada apos {{green}}{0}{{muted}} segundos.", + "bg-bg": "Гласуване за смяна на картата може да бъде започнато след {{green}}{0}{{muted}} секунди.", + "cs-cz": "Hlasovani o zmene mapy lze zahajit az po {{green}}{0}{{muted}} sekundach.", + "da-dk": "En afstemning om at skifte kort kan forst startes efter {{green}}{0}{{muted}} sekunder.", + "nl-nl": "Een stemming om de map te wijzigen kan pas worden gestart na {{green}}{0}{{muted}} seconden.", + "fi-fi": "Aanestys kartan vaihtamisesta voidaan aloittaa vasta {{green}}{0}{{muted}} sekunnin kuluttua.", + "fr-fr": "Un vote pour changer de carte ne peut etre lance qu'apres {{green}}{0}{{muted}} secondes.", + "de-de": "Eine Abstimmung zum Kartenwechsel kann erst nach {{green}}{0}{{muted}} Sekunden gestartet werden.", + "el-gr": "Μια ψηφοφορια για αλλαγη χαρτη μπορει να ξεκινησει μετα απο {{green}}{0}{{muted}} δευτερολεπτα.", + "hu-hu": "A palyavaltas szavazas csak {{green}}{0}{{muted}} masodperc utan inditható.", + "id-id": "Pemungutan suara untuk mengubah peta hanya dapat dimulai setelah {{green}}{0}{{muted}} detik.", + "it-it": "Una votazione per cambiare mappa puo essere avviata solo dopo {{green}}{0}{{muted}} secondi.", + "ja-jp": "マップ変更の投票は {{green}}{0}{{muted}} 秒後にのみ開始できます。", + "ko-kr": "맵 변경 투표는 {{green}}{0}{{muted}}초 후에만 시작할 수 있습니다.", + "es-419": "Una votacion para cambiar el mapa solo puede iniciarse despues de {{green}}{0}{{muted}} segundos.", + "nb-no": "En avstemning for a bytte kart kan bare startes etter {{green}}{0}{{muted}} sekunder.", + "pl-pl": "Glosowanie nad zmiana mapy mozna rozpoczac dopiero po {{green}}{0}{{muted}} sekundach.", + "pt-pt": "Uma votacao para mudar o mapa so pode ser iniciada apos {{green}}{0}{{muted}} segundos.", + "ro-ro": "Un vot pentru schimbarea hartii poate fi initiat doar dupa {{green}}{0}{{muted}} secunde.", + "ru-ru": "Голосование за смену карты можно начать только через {{green}}{0}{{muted}} секунд.", + "es-es": "Una votacion para cambiar el mapa solo puede iniciarse despues de {{green}}{0}{{muted}} segundos.", + "sv-se": "En omrostning for att byta karta kan bara startas efter {{green}}{0}{{muted}} sekunder.", + "th-th": "การโหวตเปลี่ยนแผนที่สามารถเริ่มได้หลังจาก {{green}}{0}{{muted}} วินาที", + "tr-tr": "Harita degistirmek icin oylama ancak {{green}}{0}{{muted}} saniye sonra baslatilabilir.", + "uk-ua": "Голосування за зміну карти можна розпочати лише через {{green}}{0}{{muted}} секунд.", + "vi-vn": "Cuoc bo phieu thay doi ban do chi co the bat dau sau {{green}}{0}{{muted}} giay." }, "ptr.mapmanager.already_voted_rtv": { "en-us": "You have already voted to change the map!", @@ -434,35 +434,35 @@ "vi-vn": "Ban da bo phieu thay doi ban do roi!" }, "ptr.mapmanager.rtv_vote_progress": { - "en-us": "{{green}}{0}{{white}} players have voted to change the map, {{green}}{1}{{white}} more votes needed.", - "zh-cn": "已有 {{green}}{0}{{white}} 人投票换图,还需 {{green}}{1}{{white}} 票。", - "zh-tw": "已有 {{green}}{0}{{white}} 人投票換圖,還需 {{green}}{1}{{white}} 票。", - "pt-br": "{{green}}{0}{{white}} jogadores votaram para mudar o mapa, {{green}}{1}{{white}} votos a mais necessarios.", - "bg-bg": "{{green}}{0}{{white}} играчи гласуваха за смяна на картата, необходими са още {{green}}{1}{{white}} гласа.", - "cs-cz": "{{green}}{0}{{white}} hracu hlasovalo pro zmenu mapy, potreba jeste {{green}}{1}{{white}} hlasu.", - "da-dk": "{{green}}{0}{{white}} spillere har stemt for at skifte kort, {{green}}{1}{{white}} flere stemmer nodvendige.", - "nl-nl": "{{green}}{0}{{white}} spelers hebben gestemd om de map te wijzigen, nog {{green}}{1}{{white}} stemmen nodig.", - "fi-fi": "{{green}}{0}{{white}} pelaajaa on aanestanyt kartan vaihtamisesta, {{green}}{1}{{white}} aanta viela tarvitaan.", - "fr-fr": "{{green}}{0}{{white}} joueurs ont vote pour changer de carte, {{green}}{1}{{white}} votes supplementaires requis.", - "de-de": "{{green}}{0}{{white}} Spieler haben fur einen Kartenwechsel gestimmt, {{green}}{1}{{white}} weitere Stimmen benotigt.", - "el-gr": "{{green}}{0}{{white}} παικτες ψηφισαν για αλλαγη χαρτη, χρειαζονται ακομη {{green}}{1}{{white}} ψηφοι.", - "hu-hu": "{{green}}{0}{{white}} jatekos szavazott a palyavaltasra, meg {{green}}{1}{{white}} szavazat szukseges.", - "id-id": "{{green}}{0}{{white}} pemain telah memilih untuk mengubah peta, {{green}}{1}{{white}} suara lagi diperlukan.", - "it-it": "{{green}}{0}{{white}} giocatori hanno votato per cambiare mappa, servono altri {{green}}{1}{{white}} voti.", - "ja-jp": "{{green}}{0}{{white}} 人がマップ変更に投票しました。あと {{green}}{1}{{white}} 票必要です。", - "ko-kr": "{{green}}{0}{{white}}명이 맵 변경에 투표했습니다. {{green}}{1}{{white}}표 더 필요합니다.", - "es-419": "{{green}}{0}{{white}} jugadores han votado para cambiar el mapa, se necesitan {{green}}{1}{{white}} votos mas.", - "nb-no": "{{green}}{0}{{white}} spillere har stemt for a bytte kart, {{green}}{1}{{white}} flere stemmer trengs.", - "pl-pl": "{{green}}{0}{{white}} graczy zaglosowalo za zmiana mapy, potrzeba jeszcze {{green}}{1}{{white}} glosow.", - "pt-pt": "{{green}}{0}{{white}} jogadores votaram para mudar o mapa, necessarios mais {{green}}{1}{{white}} votos.", - "ro-ro": "{{green}}{0}{{white}} jucatori au votat pentru schimbarea hartii, mai sunt necesare {{green}}{1}{{white}} voturi.", - "ru-ru": "{{green}}{0}{{white}} игроков проголосовало за смену карты, нужно ещё {{green}}{1}{{white}} голосов.", - "es-es": "{{green}}{0}{{white}} jugadores han votado para cambiar el mapa, se necesitan {{green}}{1}{{white}} votos mas.", - "sv-se": "{{green}}{0}{{white}} spelare har rostat for att byta karta, {{green}}{1}{{white}} fler roster behovs.", - "th-th": "{{green}}{0}{{white}} ผู้เล่นโหวตเปลี่ยนแผนที่แล้ว ต้องการอีก {{green}}{1}{{white}} โหวต", - "tr-tr": "{{green}}{0}{{white}} oyuncu harita degistirmek icin oy kullandi, {{green}}{1}{{white}} oy daha gerekli.", - "uk-ua": "{{green}}{0}{{white}} гравців проголосували за зміну карти, потрібно ще {{green}}{1}{{white}} голосів.", - "vi-vn": "{{green}}{0}{{white}} nguoi choi da bo phieu thay doi ban do, can them {{green}}{1}{{white}} phieu nua." + "en-us": "{{green}}{0}{{muted}} players have voted to change the map, {{green}}{1}{{muted}} more votes needed.", + "zh-cn": "已有 {{green}}{0}{{muted}} 人投票换图,还需 {{green}}{1}{{muted}} 票。", + "zh-tw": "已有 {{green}}{0}{{muted}} 人投票換圖,還需 {{green}}{1}{{muted}} 票。", + "pt-br": "{{green}}{0}{{muted}} jogadores votaram para mudar o mapa, {{green}}{1}{{muted}} votos a mais necessarios.", + "bg-bg": "{{green}}{0}{{muted}} играчи гласуваха за смяна на картата, необходими са още {{green}}{1}{{muted}} гласа.", + "cs-cz": "{{green}}{0}{{muted}} hracu hlasovalo pro zmenu mapy, potreba jeste {{green}}{1}{{muted}} hlasu.", + "da-dk": "{{green}}{0}{{muted}} spillere har stemt for at skifte kort, {{green}}{1}{{muted}} flere stemmer nodvendige.", + "nl-nl": "{{green}}{0}{{muted}} spelers hebben gestemd om de map te wijzigen, nog {{green}}{1}{{muted}} stemmen nodig.", + "fi-fi": "{{green}}{0}{{muted}} pelaajaa on aanestanyt kartan vaihtamisesta, {{green}}{1}{{muted}} aanta viela tarvitaan.", + "fr-fr": "{{green}}{0}{{muted}} joueurs ont vote pour changer de carte, {{green}}{1}{{muted}} votes supplementaires requis.", + "de-de": "{{green}}{0}{{muted}} Spieler haben fur einen Kartenwechsel gestimmt, {{green}}{1}{{muted}} weitere Stimmen benotigt.", + "el-gr": "{{green}}{0}{{muted}} παικτες ψηφισαν για αλλαγη χαρτη, χρειαζονται ακομη {{green}}{1}{{muted}} ψηφοι.", + "hu-hu": "{{green}}{0}{{muted}} jatekos szavazott a palyavaltasra, meg {{green}}{1}{{muted}} szavazat szukseges.", + "id-id": "{{green}}{0}{{muted}} pemain telah memilih untuk mengubah peta, {{green}}{1}{{muted}} suara lagi diperlukan.", + "it-it": "{{green}}{0}{{muted}} giocatori hanno votato per cambiare mappa, servono altri {{green}}{1}{{muted}} voti.", + "ja-jp": "{{green}}{0}{{muted}} 人がマップ変更に投票しました。あと {{green}}{1}{{muted}} 票必要です。", + "ko-kr": "{{green}}{0}{{muted}}명이 맵 변경에 투표했습니다. {{green}}{1}{{muted}}표 더 필요합니다.", + "es-419": "{{green}}{0}{{muted}} jugadores han votado para cambiar el mapa, se necesitan {{green}}{1}{{muted}} votos mas.", + "nb-no": "{{green}}{0}{{muted}} spillere har stemt for a bytte kart, {{green}}{1}{{muted}} flere stemmer trengs.", + "pl-pl": "{{green}}{0}{{muted}} graczy zaglosowalo za zmiana mapy, potrzeba jeszcze {{green}}{1}{{muted}} glosow.", + "pt-pt": "{{green}}{0}{{muted}} jogadores votaram para mudar o mapa, necessarios mais {{green}}{1}{{muted}} votos.", + "ro-ro": "{{green}}{0}{{muted}} jucatori au votat pentru schimbarea hartii, mai sunt necesare {{green}}{1}{{muted}} voturi.", + "ru-ru": "{{green}}{0}{{muted}} игроков проголосовало за смену карты, нужно ещё {{green}}{1}{{muted}} голосов.", + "es-es": "{{green}}{0}{{muted}} jugadores han votado para cambiar el mapa, se necesitan {{green}}{1}{{muted}} votos mas.", + "sv-se": "{{green}}{0}{{muted}} spelare har rostat for att byta karta, {{green}}{1}{{muted}} fler roster behovs.", + "th-th": "{{green}}{0}{{muted}} ผู้เล่นโหวตเปลี่ยนแผนที่แล้ว ต้องการอีก {{green}}{1}{{muted}} โหวต", + "tr-tr": "{{green}}{0}{{muted}} oyuncu harita degistirmek icin oy kullandi, {{green}}{1}{{muted}} oy daha gerekli.", + "uk-ua": "{{green}}{0}{{muted}} гравців проголосували за зміну карти, потрібно ще {{green}}{1}{{muted}} голосів.", + "vi-vn": "{{green}}{0}{{muted}} nguoi choi da bo phieu thay doi ban do, can them {{green}}{1}{{muted}} phieu nua." }, "ptr.mapmanager.rtv_vote_passed": { "en-us": "RTV vote passed! Map voting will start after this round ends.", diff --git a/src/Ptr.Modules.MapManager/MapManager.cs b/src/Ptr.Modules.MapManager/MapManager.cs index c4de6ec..bb3d97f 100644 --- a/src/Ptr.Modules.MapManager/MapManager.cs +++ b/src/Ptr.Modules.MapManager/MapManager.cs @@ -35,7 +35,6 @@ public MapManager( bool hotReload) { var formatter = new ChatMessageFormatter(); - formatter.SetPrefix("{whitespace}{green}MAP{white}{whitespace}"); var bridge = new InterfaceBridge(sharedSystem, dllPath, sharpPath, version, configuration, hotReload, formatter, this); var services = new ServiceCollection(); @@ -134,12 +133,15 @@ public bool Init() public void PostInit() { // Safest place to init convars is PostInit - _chatFormatPrefix = _bridge.ConVarManager.CreateConVar("mapmanager_format_prefix", "{green}[MAP]{white}", + _chatFormatPrefix = _bridge.ConVarManager.CreateConVar("mapmanager_format_prefix", "{whitespace}{green}[RED]{whitespace}{{white}", "Chat prefix format for map manager module."); // Real time prefix changes if (_chatFormatPrefix is not null) + { + _bridge.ChatFormatter.SetPrefix(_chatFormatPrefix.GetString()); _bridge.ConVarManager.InstallChangeHook(_chatFormatPrefix, OnChatFormatPrefixChange); + } _countdownAfterChangeLevel = _bridge.ConVarManager.CreateConVar("mapmanager_countdown_after_changelevel", 180, "Countdown after map change (unit is sec.)"); From d5bf6a5a5433d8ccdb775ddc51bbdf00a64a9ce1 Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Mon, 5 Jan 2026 23:43:07 +0200 Subject: [PATCH 10/24] tweak default prefix --- src/Ptr.Modules.MapManager/MapManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ptr.Modules.MapManager/MapManager.cs b/src/Ptr.Modules.MapManager/MapManager.cs index bb3d97f..ef72057 100644 --- a/src/Ptr.Modules.MapManager/MapManager.cs +++ b/src/Ptr.Modules.MapManager/MapManager.cs @@ -133,7 +133,7 @@ public bool Init() public void PostInit() { // Safest place to init convars is PostInit - _chatFormatPrefix = _bridge.ConVarManager.CreateConVar("mapmanager_format_prefix", "{whitespace}{green}[RED]{whitespace}{{white}", + _chatFormatPrefix = _bridge.ConVarManager.CreateConVar("mapmanager_format_prefix", "{whitespace}{red}MapVote{whitespace}{muted}", "Chat prefix format for map manager module."); // Real time prefix changes From 23ce204b153e47dfb3fdd837cbdf43e6693bde70 Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Tue, 6 Jan 2026 00:05:06 +0200 Subject: [PATCH 11/24] fix module name --- src/Ptr.Modules.MapManager/InterfaceBridge.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ptr.Modules.MapManager/InterfaceBridge.cs b/src/Ptr.Modules.MapManager/InterfaceBridge.cs index 3a2963d..50f53d1 100644 --- a/src/Ptr.Modules.MapManager/InterfaceBridge.cs +++ b/src/Ptr.Modules.MapManager/InterfaceBridge.cs @@ -69,7 +69,7 @@ public InterfaceBridge(ISharedSystem sharedSystem, CoreConfiguration = coreConfiguration; IsHotReload = hotReload; ChatFormatter = formatter; - ModuleIdentity = Path.GetFileName(dllPath); + ModuleIdentity = Path.GetFileNameWithoutExtension(dllPath); Instance = this; } From 4066b299db88010a5b2ca53ad477f26afa2d7347 Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Tue, 6 Jan 2026 00:08:34 +0200 Subject: [PATCH 12/24] add _localizerManager to nominate --- src/Ptr.Modules.MapManager/Services/ExtendService.cs | 3 ++- src/Ptr.Modules.MapManager/Services/NominateService.cs | 8 ++++++++ src/Ptr.Modules.MapManager/Services/RtvService.cs | 3 ++- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/Ptr.Modules.MapManager/Services/ExtendService.cs b/src/Ptr.Modules.MapManager/Services/ExtendService.cs index 86ea5b8..0068b9f 100644 --- a/src/Ptr.Modules.MapManager/Services/ExtendService.cs +++ b/src/Ptr.Modules.MapManager/Services/ExtendService.cs @@ -143,7 +143,8 @@ public void OnAllModulesLoaded() _commandRegistry.RegisterClientCommand("ext", OnCommandExt); _localizerManager = _bridge.SharpModuleManager - .GetRequiredSharpModuleInterface(ILocalizerManager.Identity).Instance!; + .GetRequiredSharpModuleInterface(ILocalizerManager.Identity) + .Instance!; } public void OnShutdown() diff --git a/src/Ptr.Modules.MapManager/Services/NominateService.cs b/src/Ptr.Modules.MapManager/Services/NominateService.cs index 99f7ba2..231bc1b 100644 --- a/src/Ptr.Modules.MapManager/Services/NominateService.cs +++ b/src/Ptr.Modules.MapManager/Services/NominateService.cs @@ -49,6 +49,9 @@ public void OnAllModulesLoaded() .GetRegistry(_bridge.ModuleIdentity) .RegisterClientCommand("nominate", OnCommandNominate); + _localizerManager = _bridge.SharpModuleManager + .GetRequiredSharpModuleInterface(ILocalizerManager.Identity) + .Instance!; } public void OnShutdown() @@ -58,6 +61,11 @@ public void OnShutdown() private void OnCommandNominate(IGameClient client, StringCommand command) { + if (_enableNominate is null) + { + _logger.LogWarning("Enabled Nominate ConVar is not initialized."); + return; + } if (_enableNominate?.GetBool() is not true) { return; diff --git a/src/Ptr.Modules.MapManager/Services/RtvService.cs b/src/Ptr.Modules.MapManager/Services/RtvService.cs index d338ca9..c7fd207 100644 --- a/src/Ptr.Modules.MapManager/Services/RtvService.cs +++ b/src/Ptr.Modules.MapManager/Services/RtvService.cs @@ -127,7 +127,8 @@ public void OnPostInit() public void OnAllModulesLoaded() { _localizerManager = _bridge.SharpModuleManager - .GetRequiredSharpModuleInterface(ILocalizerManager.Identity).Instance!; + .GetRequiredSharpModuleInterface(ILocalizerManager.Identity) + .Instance!; } public void OnShutdown() From 7994f0c12ccf5760df41d57ac080c0147336a0bc Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Tue, 6 Jan 2026 11:05:46 +0200 Subject: [PATCH 13/24] revert changes for adminmanager, commandmanager --- .../AdminTableManifest.cs | 10 ++--- .../AdminManager.cs | 6 +-- .../ICommandManager.cs | 42 +++++++++---------- .../CommandManager.cs | 6 +-- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/Sharp.Modules.AdminManager.Shared/AdminTableManifest.cs b/src/Sharp.Modules.AdminManager.Shared/AdminTableManifest.cs index 7f1c8a4..918d2c0 100644 --- a/src/Sharp.Modules.AdminManager.Shared/AdminTableManifest.cs +++ b/src/Sharp.Modules.AdminManager.Shared/AdminTableManifest.cs @@ -16,24 +16,24 @@ namespace Sharp.Modules.AdminManager.Shared; "users": [ { "user_id": "u100", - // Permission array: @ prefix means inherit from role, others are direct permissions + // 权限数组:@开头表示继承角色,其他表示直接权限 "permissions": ["@global_root", "!pluginB:slay"] - // Resolved: all permissions from global_root (*) + directly deny pluginB:slay + // 解析后:global_root的所有权限(*) + 直接拒绝pluginB:slay }, { "user_id": "u104", "permissions": ["@pluginA_admin", "@pluginB_kicker"] - // Resolved: pluginA:* (all of plugin A) + pluginB:kick (plugin B kick) + // 解析后:pluginA:*(插件A所有) + pluginB:kick(插件B踢人) }, { "user_id": "u105", "permissions": ["pluginA:getWeapon", "!pluginA:fetchItems"] - // Resolved: only directly allow getWeapon + directly deny fetchItems (no role inheritance) + // 解析后:仅直接允许getWeapon + 直接拒绝fetchItems(不继承任何角色) }, { "user_id": "u106", "permissions": ["@pluginA_admin", "pluginB:slay"] - // Resolved: pluginA:* (from role) + directly allow pluginB:slay + // 解析后:pluginA:*(来自角色) + 直接允许pluginB:slay } ] }*/ diff --git a/src/Sharp.Modules.AdminManager/AdminManager.cs b/src/Sharp.Modules.AdminManager/AdminManager.cs index 56baa44..dd00e05 100644 --- a/src/Sharp.Modules.AdminManager/AdminManager.cs +++ b/src/Sharp.Modules.AdminManager/AdminManager.cs @@ -12,8 +12,8 @@ namespace Sharp.Modules.AdminManager; // https://www.doubao.com/thread/wc0f1c5cae120c2bb -// The core purpose is to centralize the admin registration mechanism, making all admin registration logic go through the same path. -// Therefore, complexity is unavoidable: because this involves secondary keys. +// 核心目的是集中管理员注册机制,让所有管理员的注册逻辑都走同一个。 +// 由此,复杂是不可避免的:因为这里涉及到二级key。 using PermissionCollectionDictionary = Dictionary< string, // Collection key @@ -42,7 +42,7 @@ private readonly Dictionary< string, // module identity RolesDictionary> _roles = new(StringComparer.OrdinalIgnoreCase); - // This ignores all plugins, it's unified, it's only used for convenient internal calls, unrelated to external usage. + // 这个无视所有插件的,这个是统一的,这个只是用来方便内部调用的,跟外部无关。 private readonly HashSet _allConcretePermissions = new(StringComparer.OrdinalIgnoreCase); // Centralized admin storage - all admins from all modules diff --git a/src/Sharp.Modules.CommandManager.Shared/ICommandManager.cs b/src/Sharp.Modules.CommandManager.Shared/ICommandManager.cs index 7661519..e85aa84 100644 --- a/src/Sharp.Modules.CommandManager.Shared/ICommandManager.cs +++ b/src/Sharp.Modules.CommandManager.Shared/ICommandManager.cs @@ -19,40 +19,40 @@ public interface ICommandManager public interface ICommandRegistry { /// - /// Register a client command.
- /// This command can be invoked by:
- /// 1. Typing .{command} in chat, e.g., .ztele.
- /// (Note: You can use ! or / instead of ., they are equivalent.)
- /// 2. Client console, you must add the `ms_` prefix, e.g., ms_ztele.
- /// Commands registered with this function cannot be called from the server console. + /// 注册用户指令。
+ /// 该指令可被如下途径调用:
+ /// 1. 聊天栏中输入 .{该指令内容},例:.ztele。
+ /// (注:你可以将.换成!或/,它们都是一样的。)
+ /// 2. 客户端控制台,你必须添加`ms_`前缀,例:ms_ztele。
+ /// 此函数注册的指令无法被服务端控制台调用。 ///
- /// The command, you don't need to add the ms_ prefix, it will be added automatically during registration. You can also add it yourself, this doesn't matter. But if you use ms_ms_, we can't help you. + /// 指令,你可以不添加ms_前缀,注册的时候会给你自动加上。你也可以加上,这个不影响。但是如果你是ms_ms_这种,那我们爱莫能助。 /// void RegisterClientCommand(string command, Action call); /// - /// Create a server console command.
- /// This command only works in the server console. + /// 创建一个控制台指令。
+ /// 该指令只会在服务端控制台生效。 ///
/// - /// Whether to add ms_ prefix? Default is true. + /// 是否要添加ms_前缀?默认添加。 /// /// void RegisterServerCommand(string command, Action call, string description = "", bool addPrefix = true); /// - /// Create a server console command.
- /// This command only works in the server console. + /// 创建一个控制台指令。
+ /// 该指令只会在服务端控制台生效。 ///
/// - /// Whether to add ms_ prefix? Default is true. + /// 是否要添加ms_前缀?默认添加。 /// /// void RegisterServerCommand(string command, Action call, string description = "", bool addPrefix = true); /// - /// Register a "generic" command: can be used from client chat, client console, and server console.
- /// Will always add the ms_ prefix, please note. + /// 注册一个「通用」指令:客户端聊天栏,客户端控制台,服务端控制台均可使用。
+ /// 一定会添加ms_标签,请注意 ///
/// /// @@ -60,18 +60,18 @@ public interface ICommandRegistry void RegisterGenericCommand(string command, Action call, string description = ""); /// - /// Create a console command.
- /// This command only works in client console and server console.
+ /// 创建一个控制台指令。
+ /// 该指令只会在客户端控制台和服务端控制台生效。
///
/// /// - /// Whether to add ms_ prefix? Default is true. + /// 是否添加ms_前缀?默认添加。 void RegisterConsoleCommand(string command, Action callback, bool addPrefix = true); /// - /// Listen for a command.
- /// Generally, this function is only used to listen for commands entered in the client console, such as player_ping.
- /// Refer to function calls for details. + /// 监听指令。
+ /// 一般来说,该函数只用于监听客户端控制台内输入的指令,如player_ping。
+ /// 可自行参阅函数调用。 ///
/// /// diff --git a/src/Sharp.Modules.CommandManager/CommandManager.cs b/src/Sharp.Modules.CommandManager/CommandManager.cs index 530036c..351c48c 100644 --- a/src/Sharp.Modules.CommandManager/CommandManager.cs +++ b/src/Sharp.Modules.CommandManager/CommandManager.cs @@ -91,7 +91,7 @@ public bool IsCommandExists(string command) } /// - /// Get the command decorated with ms_ prefix, this is generally only needed for server console commands + /// 获取经过ms_装饰后的指令,这个一般只有服务端控制台指令需要 /// /// /// @@ -112,7 +112,7 @@ public string GetAddPrefixCommand(string originalCommand, bool addPrefix = true) } /// - /// Check if the command has ms_ prefix + /// 判断是否有ms_前缀 /// /// /// @@ -122,7 +122,7 @@ public bool HasPrefix(string command) } /// - /// Get the command with ms_ prefix removed, this is generally only needed for in-game commands + /// 获取移除ms_装饰后的指令,这个一般只有游戏内指令需要 /// /// /// From 1eac9d7616d1694eca1caa5663a2be719621254f Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Tue, 6 Jan 2026 11:06:19 +0200 Subject: [PATCH 14/24] UseHook-> InitNativeHooks --- src/Ptr.Modules.MapManager/MapManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Ptr.Modules.MapManager/MapManager.cs b/src/Ptr.Modules.MapManager/MapManager.cs index ef72057..3aa810f 100644 --- a/src/Ptr.Modules.MapManager/MapManager.cs +++ b/src/Ptr.Modules.MapManager/MapManager.cs @@ -168,9 +168,9 @@ public void OnLibraryConnected(string name) public void OnAllModulesLoaded() { _provider.LoadAllSharpExtensions(); + _provider.UseHook(); _provider.InitNativeHooks(); _provider.CallAllModulesLoaded(e => { _logger.LogError(e, "An error occurred when initializing modules"); }); - _provider.UseHook(); CallMapConfigLoaded(); From e73cb3aff88c3d334ba2936811af71957ebda6c3 Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Tue, 6 Jan 2026 11:07:22 +0200 Subject: [PATCH 15/24] revert changes for IAdmin translations --- .../IAdmin.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/Sharp.Modules.AdminManager.Shared/IAdmin.cs b/src/Sharp.Modules.AdminManager.Shared/IAdmin.cs index 9e65a82..86c6594 100644 --- a/src/Sharp.Modules.AdminManager.Shared/IAdmin.cs +++ b/src/Sharp.Modules.AdminManager.Shared/IAdmin.cs @@ -24,7 +24,7 @@ namespace Sharp.Modules.AdminManager.Shared; public interface IAdmin { /// - /// Admin name + /// 管理员名字 /// string Name { get; } @@ -34,33 +34,33 @@ public interface IAdmin SteamID Identity { get; } /// - /// Immunity level + /// 权限级别 /// byte Immunity { get; } /// - /// Permissions + /// 权限 /// IReadOnlySet Permissions { get; } /// - /// Check if has permission + /// 是否拥有权限 /// - /// Permission field + /// 权限字段 /// bool HasPermission(string permission); /// - /// Add permission + /// 添加权限 /// - /// Permission field + /// 权限字段 /// bool AddPermission(string permission); /// - /// Remove permission + /// 删除权限 /// - /// Permission field + /// 权限字段 /// bool RemovePermission(string permission); } \ No newline at end of file From 70c231df4569a36e52bd98f6374bc6e2dbe04910 Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Tue, 6 Jan 2026 11:07:59 +0200 Subject: [PATCH 16/24] update interfacebrige translations --- src/Ptr.Modules.MapManager/InterfaceBridge.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ptr.Modules.MapManager/InterfaceBridge.cs b/src/Ptr.Modules.MapManager/InterfaceBridge.cs index 50f53d1..feacafb 100644 --- a/src/Ptr.Modules.MapManager/InterfaceBridge.cs +++ b/src/Ptr.Modules.MapManager/InterfaceBridge.cs @@ -77,7 +77,7 @@ public InterfaceBridge(ISharedSystem sharedSystem, public string ModuleIdentity { get; init; } /// - /// Don't use it to make holes under normal circumstances! + /// Don't use it under normal circumstances! /// internal static InterfaceBridge Instance { get; private set; } = null!; @@ -139,7 +139,7 @@ public InterfaceBridge(ISharedSystem sharedSystem, public DateTime AllowVoteTime { get; set; } /// - /// Don't use it to make holes under normal circumstances! + /// Don't use it under normal circumstances! /// public string CurrentMapGroup { get; set; } = string.Empty; From 78b2d697f024d1516a4394bcf0607444212e1fb3 Mon Sep 17 00:00:00 2001 From: Lukas Urbonas Date: Tue, 6 Jan 2026 11:16:11 +0200 Subject: [PATCH 17/24] make convars as readonly --- .../Services/ExtendService.cs | 25 ++++++++----------- .../Services/NominateService.cs | 25 ++++++------------- .../Services/RtvService.cs | 16 +++--------- 3 files changed, 20 insertions(+), 46 deletions(-) diff --git a/src/Ptr.Modules.MapManager/Services/ExtendService.cs b/src/Ptr.Modules.MapManager/Services/ExtendService.cs index 0068b9f..e7e53cf 100644 --- a/src/Ptr.Modules.MapManager/Services/ExtendService.cs +++ b/src/Ptr.Modules.MapManager/Services/ExtendService.cs @@ -16,9 +16,9 @@ internal interface IExtendService : IModule; internal class ExtendService : IExtendService, IClientListener, IGameListener { private readonly InterfaceBridge _bridge; - private IConVar? _enableExtend = null!; - private IConVar? _extendTime = null!; - private IConVar? _maxExtCount = null!; + private readonly IConVar _enableExtend; + private readonly IConVar _extendTime; + private readonly IConVar _maxExtCount; private readonly bool[] _extClients = new bool[64]; private readonly ILogger _logger; private int _extCount; @@ -29,12 +29,15 @@ public ExtendService(InterfaceBridge bridge, ILogger logger) { _bridge = bridge; _logger = logger; - + _enableExtend = _bridge.ConVarManager.CreateConVar("mapmanager_enable_extend", true, "Enable map extensions command", ConVarFlags.Release)!; + _maxExtCount = _bridge.ConVarManager.CreateConVar("mapmanager_max_extend_count", 3, + "Maximum allowed extend map time limit count.", ConVarFlags.Release)!; + _extendTime = _bridge.ConVarManager.CreateConVar("mapmanager_ext_time", 15, "The extend applies for time limit.", ConVarFlags.Release)!; } private void OnCommandExt(IGameClient client, StringCommand command) { - if (_enableExtend?.GetBool() is not true) + if (_enableExtend.GetBool() is not true) { return; } @@ -57,7 +60,7 @@ private void OnCommandExt(IGameClient client, StringCommand command) return; } - var maxAllowed = _maxExtCount!.GetInt32(); + var maxAllowed = _maxExtCount.GetInt32(); if (_extCount >= maxAllowed) { client.PrintToChat(_bridge.ChatFormatter.Format(_localizer.Format("ptr.mapmanager.max_extends_reached"))); @@ -95,7 +98,7 @@ private void OnCommandExt(IGameClient client, StringCommand command) } var timeLimit = _bridge.ConVarManager.FindConVar("mp_timelimit")!; var currentTimeLeft = timeLimit.GetFloat(); - var pendingExtendTime = _extendTime?.GetFloat() ?? 15.0f; + var pendingExtendTime = _extendTime.GetFloat(); var nextTimeLeft = currentTimeLeft + pendingExtendTime; timeLimit.Set($"{nextTimeLeft}"); _extCount++; @@ -118,14 +121,6 @@ private void ResetExtCount() } #region IModule - public void OnPostInit() - { - _enableExtend = _bridge!.ConVarManager.CreateConVar("mapmanager_enable_extend", true, "Enable ext", ConVarFlags.Release); - _maxExtCount = _bridge!.ConVarManager.CreateConVar("mapmanager_max_extend_count", 3, - "Maximum allowed extend map time limit count.", ConVarFlags.Release); - _extendTime = - _bridge!.ConVarManager.CreateConVar("mapmanager_ext_time", 15, "The extend applies for time limit.", ConVarFlags.Release); - } public void OnInit() { _bridge.ModSharp.InstallGameListener(this); diff --git a/src/Ptr.Modules.MapManager/Services/NominateService.cs b/src/Ptr.Modules.MapManager/Services/NominateService.cs index 231bc1b..4560ea0 100644 --- a/src/Ptr.Modules.MapManager/Services/NominateService.cs +++ b/src/Ptr.Modules.MapManager/Services/NominateService.cs @@ -15,10 +15,8 @@ internal interface INominateService : IModule; internal class NominateService : INominateService { private readonly InterfaceBridge _bridge; - - private IConVar? _enableNominate; - private IConVar? _activateNominateMinPlayers; - + private readonly IConVar _enableNominate; + private readonly IConVar _activateNominateMinPlayers; private readonly ILogger _logger; private ILocalizerManager _localizerManager = null!; @@ -26,6 +24,9 @@ public NominateService(InterfaceBridge bridge, ILogger logger) { _bridge = bridge; _logger = logger; + _enableNominate = _bridge.ConVarManager.CreateConVar("mapmanager_enable_nominate", true, "Enable nominate command", ConVarFlags.Release)!; + _activateNominateMinPlayers = _bridge.ConVarManager.CreateConVar("mapmanager_activate_nominate_min_players", 5, + "minimal players count to activate nominate.", ConVarFlags.Release)!; } public void OnInit() @@ -33,13 +34,6 @@ public void OnInit() _logger.LogInformation("Nomination is enabled."); } - public void OnPostInit() - { - _enableNominate = _bridge.ConVarManager.CreateConVar("mapmanager_enable_nominate", true, "Enable nominate", ConVarFlags.Release); - _activateNominateMinPlayers = _bridge.ConVarManager.CreateConVar("mapmanager_activate_nominate_min_players", 5, - "minimal players count to activate nominate.", ConVarFlags.Release); - } - public void OnAllModulesLoaded() { _bridge @@ -61,12 +55,7 @@ public void OnShutdown() private void OnCommandNominate(IGameClient client, StringCommand command) { - if (_enableNominate is null) - { - _logger.LogWarning("Enabled Nominate ConVar is not initialized."); - return; - } - if (_enableNominate?.GetBool() is not true) + if (_enableNominate.GetBool() is not true) { return; } @@ -83,7 +72,7 @@ private void OnCommandNominate(IGameClient client, StringCommand command) } var clientsCount = _bridge.Server.GetGameClients(true, true).Count; - var leastActivateNominateCount = _activateNominateMinPlayers?.GetInt32() ?? 5; + var leastActivateNominateCount = _activateNominateMinPlayers.GetInt32(); if (clientsCount < leastActivateNominateCount) { diff --git a/src/Ptr.Modules.MapManager/Services/RtvService.cs b/src/Ptr.Modules.MapManager/Services/RtvService.cs index c7fd207..d0b214d 100644 --- a/src/Ptr.Modules.MapManager/Services/RtvService.cs +++ b/src/Ptr.Modules.MapManager/Services/RtvService.cs @@ -14,8 +14,7 @@ internal interface IRtvService : IModule; internal class RtvService : IRtvService, IGameListener, IClientListener { private readonly InterfaceBridge _bridge; - - private IConVar? _enableRtv = null!; + private readonly IConVar _enableRtv; private readonly ILogger _logger; private readonly bool[] _rtvPlayers = new bool[64]; private ILocalizerManager _localizerManager = null!; @@ -24,16 +23,12 @@ public RtvService(InterfaceBridge bridge, ILogger logger) { _bridge = bridge; _logger = logger; + _enableRtv = _bridge.ConVarManager.CreateConVar("mapmanager_enable_rtv", true, "Enable RTV", ConVarFlags.Release)!; } private void AttemptRtv(IGameClient client) { - if (_enableRtv is null) - { - _logger.LogWarning("RTV ConVar is not initialized."); - return; - } - if (_enableRtv?.GetBool() is not true) + if (_enableRtv.GetBool() is not true) { _logger.LogInformation("RTV is disabled, skip RTV attempt."); return; @@ -119,11 +114,6 @@ public void OnInit() _bridge.ModSharp.InstallGameListener(this); _bridge.ClientManager.InstallClientListener(this); } - public void OnPostInit() - { - _enableRtv = _bridge.ConVarManager.CreateConVar("mapmanager_enable_rtv", true, "Enable RTV", ConVarFlags.Release); - } - public void OnAllModulesLoaded() { _localizerManager = _bridge.SharpModuleManager From 823c826eb9e0d3e72f20f873792f431f5cee4785 Mon Sep 17 00:00:00 2001 From: Lukas Date: Wed, 7 Jan 2026 12:05:18 +0200 Subject: [PATCH 18/24] revert GetFileName --- src/Ptr.Modules.MapManager/InterfaceBridge.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Ptr.Modules.MapManager/InterfaceBridge.cs b/src/Ptr.Modules.MapManager/InterfaceBridge.cs index feacafb..c8ba523 100644 --- a/src/Ptr.Modules.MapManager/InterfaceBridge.cs +++ b/src/Ptr.Modules.MapManager/InterfaceBridge.cs @@ -69,7 +69,7 @@ public InterfaceBridge(ISharedSystem sharedSystem, CoreConfiguration = coreConfiguration; IsHotReload = hotReload; ChatFormatter = formatter; - ModuleIdentity = Path.GetFileNameWithoutExtension(dllPath); + ModuleIdentity = Path.GetFileName(dllPath); Instance = this; } @@ -144,4 +144,4 @@ public InterfaceBridge(ISharedSystem sharedSystem, public string CurrentMapGroup { get; set; } = string.Empty; //public ICommandRegistry CommandRegistry { get; set; } = null!; -} \ No newline at end of file +} From e6efb8aa30741e372eafc81f4a68b9e02d8cf536 Mon Sep 17 00:00:00 2001 From: Lukas Date: Wed, 7 Jan 2026 12:05:58 +0200 Subject: [PATCH 19/24] Clean up Directory.Build.props by removing conditions Removed shared and module project conditions and output paths. --- src/Directory.Build.props | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index af58c6d..9ade38b 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -4,29 +4,10 @@ 1.0 0 $(VersionPrefix).$(VersionSuffix) - - - $([System.String]::new('$(MSBuildProjectName)').EndsWith('.Shared')) - true - $([System.String]::new('$(MSBuildProjectName)').Contains('.Modules.')) - - true - - - - - $(MSBuildThisFileDirectory)..\.asset\game\sharp\shared\$(MSBuildProjectName)\ - false - - - - - $(MSBuildThisFileDirectory)..\.asset\game\sharp\modules\$(MSBuildProjectName)\ - false - \ No newline at end of file + From abe16f5ea3aebfc2b0e6085bdde850c39bab398c Mon Sep 17 00:00:00 2001 From: Lukas Date: Wed, 7 Jan 2026 12:06:16 +0200 Subject: [PATCH 20/24] Update .gitignore --- .gitignore | 2 -- 1 file changed, 2 deletions(-) diff --git a/.gitignore b/.gitignore index 9b66a29..71bfba8 100644 --- a/.gitignore +++ b/.gitignore @@ -417,5 +417,3 @@ FodyWeavers.xsd *.msix *.msm *.msp -/.asset/game/sharp/modules -/.asset/game/sharp/shared From 0fa64a48c67526c1a05e8bef72c9b6d43ad2ee7f Mon Sep 17 00:00:00 2001 From: Lukas Date: Wed, 7 Jan 2026 12:08:03 +0200 Subject: [PATCH 21/24] Fix formatting in Directory.Build.props --- src/Directory.Build.props | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 9ade38b..d00a34a 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -5,7 +5,6 @@ 0 $(VersionPrefix).$(VersionSuffix) - From d93fbcc267d48e1efce4fbb85178f86988a03d41 Mon Sep 17 00:00:00 2001 From: Lukas Date: Wed, 7 Jan 2026 12:11:28 +0200 Subject: [PATCH 22/24] Add check to skip fake clients in ExtendService Skip processing for fake clients in ExtendService. --- src/Ptr.Modules.MapManager/Services/ExtendService.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Ptr.Modules.MapManager/Services/ExtendService.cs b/src/Ptr.Modules.MapManager/Services/ExtendService.cs index e7e53cf..8a1a366 100644 --- a/src/Ptr.Modules.MapManager/Services/ExtendService.cs +++ b/src/Ptr.Modules.MapManager/Services/ExtendService.cs @@ -86,6 +86,10 @@ private void OnCommandExt(IGameClient client, StringCommand command) var allClients = _bridge.ClientManager.GetGameClients(true); foreach (var c in allClients) { + if (c.IsFakeClient) + { + continue; + } _localizerManager.TryGetLocalizer(client, out var _tempLocalizer); if (_tempLocalizer is null) { @@ -179,4 +183,4 @@ public void OnGameDeactivate() int IGameListener.ListenerVersion => IGameListener.ApiVersion; #endregion -} \ No newline at end of file +} From 943044506ea03eb5122516b623bf06288f66dc32 Mon Sep 17 00:00:00 2001 From: Lukas Date: Wed, 7 Jan 2026 12:11:54 +0200 Subject: [PATCH 23/24] Filter out fake clients in nomination process Skip fake clients when broadcasting nominations. --- src/Ptr.Modules.MapManager/Services/NominateService.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Ptr.Modules.MapManager/Services/NominateService.cs b/src/Ptr.Modules.MapManager/Services/NominateService.cs index 4560ea0..bedf341 100644 --- a/src/Ptr.Modules.MapManager/Services/NominateService.cs +++ b/src/Ptr.Modules.MapManager/Services/NominateService.cs @@ -117,6 +117,10 @@ private void OnCommandNominate(IGameClient client, StringCommand command) var allClients = _bridge.ClientManager.GetGameClients(true); foreach (var c in allClients) { + if (c.IsFakeClient) + { + continue; + } _localizerManager.TryGetLocalizer(c, out var _tempLocalizer); if (_tempLocalizer is null) { @@ -130,4 +134,4 @@ private void OnCommandNominate(IGameClient client, StringCommand command) _logger.LogInformation("{ClientName} nominated {Map}", client.Name, map); } -} \ No newline at end of file +} From 9d78d9ec6377f8b34622551bb367db536cb79011 Mon Sep 17 00:00:00 2001 From: Lukas Date: Wed, 7 Jan 2026 12:12:19 +0200 Subject: [PATCH 24/24] Skip processing for fake clients in RtvService --- src/Ptr.Modules.MapManager/Services/RtvService.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/Ptr.Modules.MapManager/Services/RtvService.cs b/src/Ptr.Modules.MapManager/Services/RtvService.cs index d0b214d..b3948db 100644 --- a/src/Ptr.Modules.MapManager/Services/RtvService.cs +++ b/src/Ptr.Modules.MapManager/Services/RtvService.cs @@ -85,6 +85,10 @@ private void AttemptRtv(IGameClient client) foreach (var c in allClients) { + if (c.IsFakeClient) + { + continue; + } _localizerManager.TryGetLocalizer(c, out var _tempLocalizer); if (_tempLocalizer is null) { @@ -170,4 +174,4 @@ public ECommandAction OnClientSayCommand(IGameClient client, bool teamOnly, bool int IClientListener.ListenerVersion => IClientListener.ApiVersion; #endregion -} \ No newline at end of file +}