From be4c4b076e23c73946f9f8777c5c65340baacec5 Mon Sep 17 00:00:00 2001 From: Suvorov Pavel Date: Wed, 4 Mar 2026 16:04:06 +0700 Subject: [PATCH 1/2] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=B4=D0=BB=D1=8F=20=D0=92=D0=9B-=D0=B8=D0=B3?= =?UTF-8?q?=D1=80=D0=BE=D0=BA=D0=BE=D0=B2=20=D0=BE=D1=82=D0=BA=D1=80=D1=8B?= =?UTF-8?q?=D1=82=D0=B8=D0=B5=20=D0=B2=D1=81=D0=B5=D1=85=20=D1=80=D0=BE?= =?UTF-8?q?=D0=BB=D0=B5=D0=B9=20=D0=B8=20=D0=B4=D0=B5=D0=BD=D1=8C=D0=B3?= =?UTF-8?q?=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Lobby/ClientPreferencesManager.cs | 13 ++++++++++ .../JobRequirementsManager.cs | 2 +- .../PlayTimeTrackingSystem.cs | 12 ++++++++- .../Managers/ServerPreferencesManager.cs | 26 +++++++++++++++++-- Content.Shared/CCVar/CCVars.Game.cs | 8 +++++- Resources/ConfigPresets/Forge/corvax.toml | 1 + 6 files changed, 57 insertions(+), 5 deletions(-) diff --git a/Content.Client/Lobby/ClientPreferencesManager.cs b/Content.Client/Lobby/ClientPreferencesManager.cs index 4bd760e7869..24e21b2d8aa 100644 --- a/Content.Client/Lobby/ClientPreferencesManager.cs +++ b/Content.Client/Lobby/ClientPreferencesManager.cs @@ -1,11 +1,13 @@ using System.Linq; using Content.Shared._Mono.Company; +using Content.Shared.CCVar; using Content.Shared.Preferences; using Robust.Client; using Robust.Client.Player; using Robust.Shared.Network; using Robust.Shared.Utility; using Robust.Shared.Prototypes; +using Robust.Shared.Configuration; namespace Content.Client.Lobby { @@ -19,6 +21,8 @@ public sealed class ClientPreferencesManager : IClientPreferencesManager [Dependency] private readonly IClientNetManager _netManager = default!; [Dependency] private readonly IBaseClient _baseClient = default!; [Dependency] private readonly IPlayerManager _playerManager = default!; + [Dependency] private readonly IConfigurationManager _cfg = default!; // Forge-Change + [Dependency] private readonly Players.PlayTimeTracking.JobRequirementsManager _jobRequirements = default!; // Forge-Change public event Action? OnServerDataLoaded; @@ -73,6 +77,15 @@ public void UpdateCharacter(ICharacterProfile profile, int slot) { profile = humanoidProfile.WithCompany("None"); } + + // Forge-Change-Start: apply whitelisted starting balance on client for new characters so UI matches server + if (_jobRequirements.IsWhitelisted() && + humanoidProfile.BankBalance == HumanoidCharacterProfile.DefaultBalance) + { + var startingBalance = _cfg.GetCVar(CCVars.GameWhitelistedStartingBalance); + profile = humanoidProfile.WithBankBalance(startingBalance); + } + // Forge-Change-End } profile.EnsureValid(_playerManager.LocalSession!, collection); diff --git a/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs b/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs index e82aae21ba6..92925c47c79 100644 --- a/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs +++ b/Content.Client/Players/PlayTimeTracking/JobRequirementsManager.cs @@ -145,7 +145,7 @@ public bool CheckRoleRequirements(HashSet? requirements, Humanoi { reason = null; - if (requirements == null || !_cfg.GetCVar(CCVars.GameRoleTimers)) + if (requirements == null || !_cfg.GetCVar(CCVars.GameRoleTimers) || _whitelisted) // Forge-Change: bypass client-side role timers for globally whitelisted players return true; var reasons = new List(); diff --git a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs index 5fd737267f0..8d0f855256f 100644 --- a/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs +++ b/Content.Server/Players/PlayTimeTracking/PlayTimeTrackingSystem.cs @@ -195,6 +195,10 @@ public bool IsAllowed(ICommonSession player, string role) !_cfg.GetCVar(CCVars.GameRoleTimers)) return true; + var isWhitelisted = player.ContentData()?.Whitelisted ?? false; // Forge-Change: bypass role timers for globally whitelisted players + if (isWhitelisted) + return true; // Forge-Change + if (!_tracking.TryGetTrackerTimes(player, out var playTimes)) { Log.Error($"Unable to check playtimes {Environment.StackTrace}"); @@ -210,6 +214,10 @@ public HashSet> GetDisallowedJobs(ICommonSession player) if (!_cfg.GetCVar(CCVars.GameRoleTimers)) return roles; + var isWhitelisted = player.ContentData()?.Whitelisted ?? false; // Forge-Change: globally whitelisted players ignore disallowed-jobs timer checks + if (isWhitelisted) + return roles; // Forge-Change + if (!_tracking.TryGetTrackerTimes(player, out var playTimes)) { Log.Error($"Unable to check playtimes {Environment.StackTrace}"); @@ -237,9 +245,11 @@ public void RemoveDisallowedJobs(NetUserId userId, List> j Log.Error($"Playtimes weren't ready yet for {player} on roundstart!"); playTimes ??= new Dictionary(); } - var isWhitelisted = player.ContentData()?.Whitelisted ?? false; // DeltaV - Whitelist requirement + if (isWhitelisted) + return; // Forge-Change: do not filter jobs by playtime for globally whitelisted players + for (var i = 0; i < jobs.Count; i++) { if (_prototypes.TryIndex(jobs[i], out var job) diff --git a/Content.Server/Preferences/Managers/ServerPreferencesManager.cs b/Content.Server/Preferences/Managers/ServerPreferencesManager.cs index f6859e2f87d..fa68c9bdfe6 100644 --- a/Content.Server/Preferences/Managers/ServerPreferencesManager.cs +++ b/Content.Server/Preferences/Managers/ServerPreferencesManager.cs @@ -103,9 +103,20 @@ public async Task SetProfile(NetUserId userId, int slot, ICharacterProfile profi var curPrefs = prefsData.Prefs!; var session = _playerManager.GetSessionById(userId); - profile.EnsureValid(session, _dependencies); + // Forge-Change-Start: set increased starting bank balance for new globally whitelisted characters + if (profile is HumanoidCharacterProfile humanoidProfile && !curPrefs.Characters.ContainsKey(slot)) + { + var whitelisted = await _db.GetWhitelistStatusAsync(userId); + if (whitelisted) + { + var startingBalance = _cfg.GetCVar(CCVars.GameWhitelistedStartingBalance); + profile = humanoidProfile.WithBankBalance(startingBalance); + } + } + // Forge-Change-End + var profiles = new Dictionary(curPrefs.Characters) { @@ -288,7 +299,18 @@ private async Task GetOrCreatePreferencesAsync(NetUserId user var prefs = await _db.GetPlayerPreferencesAsync(userId, cancel); if (prefs is null) { - return await _db.InitPrefsAsync(userId, HumanoidCharacterProfile.Random(), cancel); + var profile = HumanoidCharacterProfile.Random(); + + // Forge-Change-Start: give higher initial balance to first character of globally whitelisted players + var whitelisted = await _db.GetWhitelistStatusAsync(userId); + if (whitelisted) + { + var startingBalance = _cfg.GetCVar(CCVars.GameWhitelistedStartingBalance); + profile = profile.WithBankBalance(startingBalance); + } + // Forge-Change-End + + return await _db.InitPrefsAsync(userId, profile, cancel); } return prefs; diff --git a/Content.Shared/CCVar/CCVars.Game.cs b/Content.Shared/CCVar/CCVars.Game.cs index ac5f9936208..534e24f662f 100644 --- a/Content.Shared/CCVar/CCVars.Game.cs +++ b/Content.Shared/CCVar/CCVars.Game.cs @@ -1,4 +1,4 @@ -using Content.Shared.Roles; +using Content.Shared.Roles; using Robust.Shared.Configuration; namespace Content.Shared.CCVar; @@ -131,6 +131,12 @@ public static readonly CVarDef public static readonly CVarDef GameRoleWhitelist = CVarDef.Create("game.role_whitelist", true, CVar.SERVER | CVar.REPLICATED); + /// + /// Forge-Change: starting bank balance for globally whitelisted players' new characters. + /// + public static readonly CVarDef + GameWhitelistedStartingBalance = CVarDef.Create("game.whitelisted_starting_balance", 100_000, CVar.SERVER | CVar.REPLICATED); + /// /// Whether or not disconnecting inside of a cryopod should remove the character or just store them until they reconnect. /// diff --git a/Resources/ConfigPresets/Forge/corvax.toml b/Resources/ConfigPresets/Forge/corvax.toml index be90d3ccb08..1531a073218 100644 --- a/Resources/ConfigPresets/Forge/corvax.toml +++ b/Resources/ConfigPresets/Forge/corvax.toml @@ -21,6 +21,7 @@ debug_coordinates_admin_only = true cryo_sleep_rejoining = true role_timer_override = "" role_whitelist = true +whitelisted_starting_balance = 100000 [shuttle] auto_call_time = 360 From 847dce58f058b13b62ea59860b1e36a3805bb88d Mon Sep 17 00:00:00 2001 From: Suvorov Pavel Date: Wed, 4 Mar 2026 17:06:13 +0700 Subject: [PATCH 2/2] =?UTF-8?q?=D0=9D=D1=83=20=D0=B8=20=D0=BD=D0=B5=D0=BC?= =?UTF-8?q?=D0=BD=D0=BE=D0=B3=D0=BE=20=D0=BF=D0=BE=D1=84=D0=B8=D0=BA=D1=81?= =?UTF-8?q?=D0=B8=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Lobby/ClientPreferencesManager.cs | 29 ++++++++++++------- .../Managers/ServerPreferencesManager.cs | 4 ++- 2 files changed, 21 insertions(+), 12 deletions(-) diff --git a/Content.Client/Lobby/ClientPreferencesManager.cs b/Content.Client/Lobby/ClientPreferencesManager.cs index 24e21b2d8aa..936256d6a57 100644 --- a/Content.Client/Lobby/ClientPreferencesManager.cs +++ b/Content.Client/Lobby/ClientPreferencesManager.cs @@ -70,21 +70,18 @@ public void UpdateCharacter(ICharacterProfile profile, int slot) // Verify company exists if this is a humanoid profile if (profile is HumanoidCharacterProfile humanoidProfile) { + // Forge-Change-Start + var humanoid = humanoidProfile; + var protoManager = IoCManager.Resolve(); - if (!string.IsNullOrEmpty(humanoidProfile.Company) && - humanoidProfile.Company != "None" && - !protoManager.HasIndex(humanoidProfile.Company)) + if (!string.IsNullOrEmpty(humanoid.Company) && + humanoid.Company != "None" && + !protoManager.HasIndex(humanoid.Company)) { - profile = humanoidProfile.WithCompany("None"); + humanoid = humanoid.WithCompany("None"); } - // Forge-Change-Start: apply whitelisted starting balance on client for new characters so UI matches server - if (_jobRequirements.IsWhitelisted() && - humanoidProfile.BankBalance == HumanoidCharacterProfile.DefaultBalance) - { - var startingBalance = _cfg.GetCVar(CCVars.GameWhitelistedStartingBalance); - profile = humanoidProfile.WithBankBalance(startingBalance); - } + profile = humanoid; // Forge-Change-End } @@ -101,6 +98,16 @@ public void UpdateCharacter(ICharacterProfile profile, int slot) public void CreateCharacter(ICharacterProfile profile) { + // Forge-Change-Start: apply whitelisted starting balance for brand new characters so UI matches server + if (profile is HumanoidCharacterProfile humanoidProfile && + _jobRequirements.IsWhitelisted() && + humanoidProfile.BankBalance == HumanoidCharacterProfile.DefaultBalance) + { + var startingBalance = _cfg.GetCVar(CCVars.GameWhitelistedStartingBalance); + profile = humanoidProfile.WithBankBalance(startingBalance); + } + // Forge-Change-End + var characters = new Dictionary(Preferences.Characters); var lowest = Enumerable.Range(0, Settings.MaxCharacterSlots) .Except(characters.Keys) diff --git a/Content.Server/Preferences/Managers/ServerPreferencesManager.cs b/Content.Server/Preferences/Managers/ServerPreferencesManager.cs index fa68c9bdfe6..21159925f48 100644 --- a/Content.Server/Preferences/Managers/ServerPreferencesManager.cs +++ b/Content.Server/Preferences/Managers/ServerPreferencesManager.cs @@ -106,7 +106,9 @@ public async Task SetProfile(NetUserId userId, int slot, ICharacterProfile profi profile.EnsureValid(session, _dependencies); // Forge-Change-Start: set increased starting bank balance for new globally whitelisted characters - if (profile is HumanoidCharacterProfile humanoidProfile && !curPrefs.Characters.ContainsKey(slot)) + if (profile is HumanoidCharacterProfile humanoidProfile && + !curPrefs.Characters.ContainsKey(slot) && + humanoidProfile.BankBalance == HumanoidCharacterProfile.DefaultBalance) { var whitelisted = await _db.GetWhitelistStatusAsync(userId); if (whitelisted)