]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Players with unknown playtimes now are tagged as new players, take 2 (#35648)
authorErrant <35878406+Errant-4@users.noreply.github.com>
Wed, 5 Mar 2025 16:25:42 +0000 (17:25 +0100)
committerGitHub <noreply@github.com>
Wed, 5 Mar 2025 16:25:42 +0000 (08:25 -0800)
* your commit? our commit.

* skreee

* show joined players before lobby players; comments

* comments

* playerinfo retains playtime data after disconnect

* new connection status symbols

Content.Client/Administration/UI/Bwoink/BwoinkControl.xaml.cs
Content.Client/Administration/UI/Bwoink/BwoinkWindow.xaml.cs
Content.Server/Administration/Systems/AdminSystem.cs

index 3e05018c1085dda047a56c98256e8b3672b7f825..973f1a090b7a7b6b5ba90fb5462947ffb877dace 100644 (file)
@@ -36,6 +36,9 @@ namespace Content.Client.Administration.UI.Bwoink
             RobustXamlLoader.Load(this);
             IoCManager.InjectDependencies(this);
 
+            var newPlayerThreshold = 0;
+            _cfg.OnValueChanged(CCVars.NewPlayerThreshold, (val) => { newPlayerThreshold = val; }, true);
+
             var uiController = _ui.GetUIController<AHelpUIController>();
             if (uiController.UIHelper is not AdminAHelpUIHandler helper)
                 return;
@@ -59,9 +62,9 @@ namespace Content.Client.Administration.UI.Bwoink
                 var sb = new StringBuilder();
 
                 if (info.Connected)
-                    sb.Append('●');
+                    sb.Append(info.ActiveThisRound ? '⚫' : '◐');
                 else
-                    sb.Append(info.ActiveThisRound ? 'â\97\8b' : '·');
+                    sb.Append(info.ActiveThisRound ? 'â­\98' : '·');
 
                 sb.Append(' ');
                 if (AHelpHelper.TryGetChannel(info.SessionId, out var panel) && panel.Unread > 0)
@@ -73,10 +76,12 @@ namespace Content.Client.Administration.UI.Bwoink
                     sb.Append(' ');
                 }
 
+                // Mark antagonists with symbol
                 if (info.Antag && info.ActiveThisRound)
                     sb.Append(new Rune(0x1F5E1)); // 🗡
 
-                if (info.OverallPlaytime <= TimeSpan.FromMinutes(_cfg.GetCVar(CCVars.NewPlayerThreshold)))
+                // Mark new players with symbol
+                if (IsNewPlayer(info))
                     sb.Append(new Rune(0x23F2)); // ⏲
 
                 sb.AppendFormat("\"{0}\"", text);
@@ -84,6 +89,19 @@ namespace Content.Client.Administration.UI.Bwoink
                 return sb.ToString();
             };
 
+            // <summary>
+            // Returns true if the player's overall playtime is under the set threshold
+            // </summary>
+            bool IsNewPlayer(PlayerInfo info)
+            {
+                // Don't show every disconnected player as new, don't show 0-minute players as new if threshold is
+                if (newPlayerThreshold <= 0 || info.OverallPlaytime is null && !info.Connected)
+                    return false;
+
+                return (info.OverallPlaytime is null
+                        || info.OverallPlaytime < TimeSpan.FromMinutes(newPlayerThreshold));
+            }
+
             ChannelSelector.Comparison = (a, b) =>
             {
                 var ach = AHelpHelper.EnsurePanel(a.SessionId);
@@ -93,31 +111,37 @@ namespace Content.Client.Administration.UI.Bwoink
                 if (a.IsPinned != b.IsPinned)
                     return a.IsPinned ? -1 : 1;
 
-                // First, sort by unread. Any chat with unread messages appears first.
+                // Then, any chat with unread messages.
                 var aUnread = ach.Unread > 0;
                 var bUnread = bch.Unread > 0;
                 if (aUnread != bUnread)
                     return aUnread ? -1 : 1;
 
-                // Sort by recent messages during the current round.
+                // Then, any chat with recent messages from the current round
                 var aRecent = a.ActiveThisRound && ach.LastMessage != DateTime.MinValue;
                 var bRecent = b.ActiveThisRound && bch.LastMessage != DateTime.MinValue;
                 if (aRecent != bRecent)
                     return aRecent ? -1 : 1;
 
-                // Next, sort by connection status. Any disconnected players are grouped towards the end.
+                // Sort by connection status. Disconnected players will be last.
                 if (a.Connected != b.Connected)
                     return a.Connected ? -1 : 1;
 
-                // Sort connected players by New Player status, then by Antag status
+                // Sort connected players by whether they have joined the round, then by New Player status, then by Antag status
                 if (a.Connected && b.Connected)
                 {
-                    var aNewPlayer = a.OverallPlaytime <= TimeSpan.FromMinutes(_cfg.GetCVar(CCVars.NewPlayerThreshold));
-                    var bNewPlayer = b.OverallPlaytime <= TimeSpan.FromMinutes(_cfg.GetCVar(CCVars.NewPlayerThreshold));
+                    var aNewPlayer = IsNewPlayer(a);
+                    var bNewPlayer = IsNewPlayer(b);
+
+                    //  Players who have joined the round will be listed before players in the lobby
+                    if (a.ActiveThisRound != b.ActiveThisRound)
+                        return a.ActiveThisRound ? -1 : 1;
 
+                    //  Within both the joined group and lobby group, new players will be grouped and listed first
                     if (aNewPlayer != bNewPlayer)
                         return aNewPlayer ? -1 : 1;
 
+                    //  Within all four previous groups, antagonists will be listed first.
                     if (a.Antag != b.Antag)
                         return a.Antag ? -1 : 1;
                 }
index e8653843c742b944d172b869cc2afe33bfb93835..e6cd4942a69ff18d18e077e23227ab3bfe2df64a 100644 (file)
@@ -22,12 +22,9 @@ namespace Content.Client.Administration.UI.Bwoink
                     return;
                 }
 
-                Title = $"{sel.CharacterName} / {sel.Username}";
+                Title = $"{sel.CharacterName} / {sel.Username} | {Loc.GetString("generic-playtime-title")}: ";
 
-                if (sel.OverallPlaytime != null)
-                {
-                    Title += $" | {Loc.GetString("generic-playtime-title")}: {sel.PlaytimeString}";
-                }
+                Title += sel.OverallPlaytime != null ? sel.PlaytimeString : Loc.GetString("generic-unknown-title");
             };
 
             OnOpen += () =>
index c1b08437deb99c09d46c96477ddb82f81d3559ba..7d50730456f4b8b8b47e880e840000b03242eac4 100644 (file)
@@ -222,6 +222,7 @@ public sealed class AdminSystem : EntitySystem
         var entityName = string.Empty;
         var identityName = string.Empty;
 
+        // Visible (identity) name can be different from real name
         if (session?.AttachedEntity != null)
         {
             entityName = EntityManager.GetComponent<MetaDataComponent>(session.AttachedEntity.Value).EntityName;
@@ -230,6 +231,7 @@ public sealed class AdminSystem : EntitySystem
 
         var antag = false;
 
+        // Starting role, antagonist status and role type
         RoleTypePrototype roleType = new();
         var startingRole = string.Empty;
         if (_minds.TryGetMind(session, out var mindId, out var mindComp))
@@ -243,8 +245,13 @@ public sealed class AdminSystem : EntitySystem
             startingRole = _jobs.MindTryGetJobName(mindId);
         }
 
+        // Connection status and playtime
         var connected = session != null && session.Status is SessionStatus.Connected or SessionStatus.InGame;
-        TimeSpan? overallPlaytime = null;
+
+        // Start with the last available playtime data
+        var cachedInfo = GetCachedPlayerInfo(data.UserId);
+        var overallPlaytime = cachedInfo?.OverallPlaytime;
+        // Overwrite with current playtime data, unless it's null (such as if the player just disconnected)
         if (session != null &&
             _playTime.TryGetTrackerTimes(session, out var playTimes) &&
             playTimes.TryGetValue(PlayTimeTrackingShared.TrackerOverall, out var playTime))