Skip to content

Conversation

@Spatison
Copy link
Member

Описание PR

Я не знаю как тут будут работать баны. Проверим на ходу.


Изменения

🆑

  • add: На сервер теперь можно зайти с акаунта Симпл Станции

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 10, 2026

Walkthrough

Интегрирование контекста сервера аутентификации в слои клиента и сервера. Изменения включают обновление URL субмодуля RobustToolbox, добавление управления идентификатором сервера в игровых интерфейсах и чатах, и обновление локализации сообщений OOC для отображения информации о сервере аутентификации.

Changes

Cohort / File(s) Описание изменений
Конфигурация субмодулей
.gitmodules, RobustToolbox
Обновление URL субмодуля RobustToolbox на новый репозиторий и обновление указателя коммита
Клиентский пользовательский интерфейс администрирования
Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs, Content.Client/Administration/UI/CustomControls/PlayerListEntry.xaml.cs
Добавлены инъекции зависимостей для ISharedPlayerManager и IConfigurationManager; обновлена логика формирования отображаемого имени игрока для включения идентификатора сервера аутентификации
Серверная логика управления игроками
Content.Server/Administration/PlayerLocator.cs
Замена жестко закодированного получения auth-сервера на парсинг списка серверов из CVars.AuthServers
Интеграция контекста сервера в чат
Content.Server/Chat/Managers/ChatManager.cs
Добавлен контекст authServer при оформлении OOC и patron OOC сообщений; логика определяет идентификатор сервера на основе списка конфигурации AuthServers
Локализация сообщений чата
Resources/Locale/en-US/chat/managers/chat-manager.ftl, Resources/Locale/ru-RU/chat/managers/chat-manager.ftl
Обновлены шаблоны OOC сообщений для включения условного блока authServer с упоминанием сервера аутентификации или значением Unknown

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

Changes: Localization

Suggested reviewers

  • Remuchi
🚥 Pre-merge checks | ✅ 2 | ❌ 1
❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 14.29% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed Название PR соответствует основному изменению - интеграция Supermatter Engine с поддержкой многоAuthентификации (multiauth).
Description check ✅ Passed Описание PR связано с набором изменений и объясняет основную цель - добавление возможности входа с аккаунта Simple Station.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Fix all issues with AI agents
In @Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs:
- Around line 112-115: The displayName construction can throw a
NullReferenceException because
_playerManager.GetSessionById(info.SessionId).Channel.UserData.AuthServer may be
null; fix by retrieving the session into a local (e.g., var session =
_playerManager.GetSessionById(info.SessionId)), then null-check session,
session.Channel, session.Channel.UserData and
session.Channel.UserData.AuthServer before accessing Id (use conditional access
or explicit checks) and fall back to a safe string like "unknown" when any piece
is null; update the displayName expression in PlayerListControl.xaml.cs to use
that guarded value (mirror the null-safe pattern used in
PlayerListEntry.xaml.cs).

In @Content.Server/Administration/PlayerLocator.cs:
- Line 105:
AuthServer.FromStringList(_configurationManager.GetCVar(CVars.AuthServers)).First()
can throw InvalidOperationException for an empty/invalid list; change the call
to safely handle empties (e.g., use FirstOrDefault/null-check or check the
returned collection count) and then handle the missing server case before
accessing AuthUrl — update the usage in the method that currently reads
AuthServer.FromStringList(...).First().AuthUrl to use a safe retrieval
(FirstOrDefault), verify the result is non-null (or collection non-empty) and
provide a fallback or clear error/log message if no auth server is available.
- Line 124: The code calls
AuthServer.FromStringList(_configurationManager.GetCVar(CVars.AuthServers)).First().AuthUrl
which can throw on an empty sequence and duplicates this logic; extract this
into a private helper (e.g. GetAuthServerUrl or ResolveAuthServerUrl) that calls
AuthServer.FromStringList, checks for empty/null (use
FirstOrDefault/SingleOrDefault), returns AuthUrl or handles the missing case
(log and throw a clear exception or return null/Optional) and replace all direct
.First().AuthUrl usages with this helper to remove duplication and avoid the
exception.

In @Content.Server/Chat/Managers/ChatManager.cs:
- Around line 253-264: The inline block comments around the authServer logic
contain a typo: change the opening marker "WD EDDIT START" to "WD EDIT START"
(matching the closing "WD EDIT END") so comment markers are consistent; update
only the comment text surrounding the AuthServer resolution/Loc.GetString call
(the lines containing "WD EDDIT START" and "WD EDIT END").
📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eccc9ce and b146a84.

📒 Files selected for processing (8)
  • .gitmodules
  • Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs
  • Content.Client/Administration/UI/CustomControls/PlayerListEntry.xaml.cs
  • Content.Server/Administration/PlayerLocator.cs
  • Content.Server/Chat/Managers/ChatManager.cs
  • Resources/Locale/en-US/chat/managers/chat-manager.ftl
  • Resources/Locale/ru-RU/chat/managers/chat-manager.ftl
  • RobustToolbox
🧰 Additional context used
🧠 Learnings (4)
📓 Common learnings
Learnt from: Lachklen
Repo: WWhiteDreamProject/wwdpublic PR: 863
File: Resources/Locale/ru-RU/_white/cards/danger.ftl:1-1
Timestamp: 2025-10-22T20:31:06.235Z
Learning: В PR по EvacPod для WWhiteDreamProject/wwdpublic: в ru-RU локализациях допустим осознанный сленг сообщества SS13 (напр., «дистры»), если он не ломает отображение и используется последовательно; не блокировать PR, предлагать необязательный follow-up (глоссарий/проверка консистентности).
Learnt from: Lachklen
Repo: WWhiteDreamProject/wwdpublic PR: 863
File: Resources/Locale/en-US/_white/cards/hobby.ftl:5-5
Timestamp: 2025-10-22T20:13:31.389Z
Learning: В PR по EvacPod для репозитория WWhiteDreamProject/wwdpublic: если опечатка в ключе локализации (например, card-ep_hobby_mashrooms) не влияет на отображение и используется последовательно, автор предпочитает не блокировать PR; вместо этого предлагать необязательный follow-up issue.
📚 Learning: 2026-01-04T20:41:27.251Z
Learnt from: Cinkafox
Repo: WWhiteDreamProject/wwdpublic PR: 1001
File: Content.Server/Database/ServerDbBase.cs:296-296
Timestamp: 2026-01-04T20:41:27.251Z
Learning: In Content.Server/Database/ServerDbBase.cs, ensure uniqueness of LoadoutName before persisting or converting the loadouts. If you convert the list to a dictionary with ToDictionary(p => p.LoadoutName), the key must be unique; otherwise handle duplicates (e.g., use ToLookup or GroupBy) to avoid runtime errors. This pattern can improve performance by eliminating extra lookups, but only apply when LoadoutName uniqueness is guaranteed by prior validation.

Applied to files:

  • Content.Server/Administration/PlayerLocator.cs
  • Content.Server/Chat/Managers/ChatManager.cs
📚 Learning: 2025-09-24T18:18:06.673Z
Learnt from: RedFoxIV
Repo: WWhiteDreamProject/wwdpublic PR: 849
File: Content.Client/_White/UserInterface/WindowTracker.cs:1-5
Timestamp: 2025-09-24T18:18:06.673Z
Learning: The WWhiteDreamProject codebase uses GlobalUsings.cs files to provide global using directives. IoCManager is available throughout Content.Client without explicit using Robust.Shared.IoC; directive due to global usings configuration. Code analysis should account for global usings when checking for missing using statements.

Applied to files:

  • Content.Server/Chat/Managers/ChatManager.cs
  • Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs
📚 Learning: 2025-09-03T16:17:01.745Z
Learnt from: Cinkafox
Repo: WWhiteDreamProject/wwdpublic PR: 827
File: Content.Client/_White/UI/Controls/Knob.cs:28-28
Timestamp: 2025-09-03T16:17:01.745Z
Learning: In this codebase with Robust UI, base Control does not expose a Disabled property; Disabled exists on specific widgets like BaseButton. Do not flag shadowing for user-defined Disabled on custom controls such as Content.Client/_White/UI/Controls/Knob.cs.

Applied to files:

  • Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (5)
  • GitHub Check: Test Packaging
  • GitHub Check: YAML map schema validator
  • GitHub Check: YAML Linter
  • GitHub Check: build (ubuntu-latest)
  • GitHub Check: build (ubuntu-latest)
🔇 Additional comments (5)
RobustToolbox (1)

1-1: Убедитесь что обновление SubModule протестировано, особенно функциональность ban-системы.

Обновление указателя субмодуля (до текущей HEAD/master ветки Simple-Station/SupermatterEngine) является критичным для новой функциональности мультиаутентификации. Учитывая что автор выразил неуверенность в работе банов, необходимо провести тщательное тестирование интеграции:

  • Корректная работа multiauth функциональности со всеми identifiers
  • Проверка ban-системы при использовании нескольких auth-серверов
  • Валидация ISharedPlayerManager и CVars.AuthServers в новой версии
  • OOC сообщения с authServer информацией
Resources/Locale/en-US/chat/managers/chat-manager.ftl (1)

43-50: LGTM!

Шаблоны локализации корректно обновлены для поддержки условного отображения сервера аутентификации. Синтаксис Fluent корректен, и логика соответствует серверным изменениям в ChatManager.cs.

Resources/Locale/ru-RU/chat/managers/chat-manager.ftl (1)

40-47: LGTM!

Русская локализация корректно обновлена и соответствует английской версии. Синтаксис Fluent и логика условного отображения сервера аутентификации идентичны.

Content.Server/Chat/Managers/ChatManager.cs (1)

273-280: LGTM!

Добавление authServer к patron OOC wrap сообщению выполнено корректно. Переиспользование ранее определённой переменной authServer обеспечивает консистентность.

.gitmodules (1)

1-4: Файл .gitmodules не содержит изменений в этом PR. Текущее состояние субмодуля (указание на Simple-Station/SupermatterEngine) уже установлено в репозитории и не изменяется данным коммитом.

Likely an incorrect or invalid review comment.

Comment on lines +112 to +115
// WD EDIT START
var displayName = $"{info.CharacterName} ({info.Username}@{AuthServer.GetServerFromCVarListByUrl(_config,
_playerManager.GetSessionById(info.SessionId).Channel.UserData.AuthServer)?.Id})";
// WD EDIT END
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Потенциальное NullReferenceException при получении сессии (аналогично PlayerListEntry).

Та же проблема, что и в PlayerListEntry.xaml.cs — цепочка вызовов _playerManager.GetSessionById(...).Channel.UserData.AuthServer может выбросить исключение.

🛠️ Предлагаемое исправление
-            var displayName = $"{info.CharacterName} ({info.Username}@{AuthServer.GetServerFromCVarListByUrl(_config,
-                _playerManager.GetSessionById(info.SessionId).Channel.UserData.AuthServer)?.Id})";
+            var serverId = "Unknown";
+            if (_playerManager.TryGetSessionById(info.SessionId, out var session))
+            {
+                serverId = AuthServer.GetServerFromCVarListByUrl(_config, session.Channel.UserData.AuthServer)?.Id ?? "Unknown";
+            }
+            var displayName = $"{info.CharacterName} ({info.Username}@{serverId})";
🤖 Prompt for AI Agents
In @Content.Client/Administration/UI/CustomControls/PlayerListControl.xaml.cs
around lines 112 - 115, The displayName construction can throw a
NullReferenceException because
_playerManager.GetSessionById(info.SessionId).Channel.UserData.AuthServer may be
null; fix by retrieving the session into a local (e.g., var session =
_playerManager.GetSessionById(info.SessionId)), then null-check session,
session.Channel, session.Channel.UserData and
session.Channel.UserData.AuthServer before accessing Id (use conditional access
or explicit checks) and fall back to a safe string like "unknown" when any piece
is null; update the displayName expression in PlayerListControl.xaml.cs to use
that guarded value (mirror the null-safe pattern used in
PlayerListEntry.xaml.cs).

Comment on lines +51 to +56
// WD EDIT START
PlayerEntryLabel.Text = overrideText?.Invoke(
info,
$"{info.CharacterName} ({info.Username}@{AuthServer.GetServerFromCVarListByUrl(_config,
_playerManager.GetSessionById(info.SessionId).Channel.UserData.AuthServer)?.Id})") ?? $"{info.CharacterName} ({info.Username})";
// WD EDIT END
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Потенциальное NullReferenceException при получении сессии.

Цепочка вызовов _playerManager.GetSessionById(info.SessionId).Channel.UserData.AuthServer может выбросить исключение, если сессия не найдена или отсутствует.

Рассмотрите добавление null-проверок или использование TryGetSessionById:

🛠️ Предлагаемое исправление
-        PlayerEntryLabel.Text = overrideText?.Invoke(
-                info,
-                $"{info.CharacterName} ({info.Username}@{AuthServer.GetServerFromCVarListByUrl(_config,
-                    _playerManager.GetSessionById(info.SessionId).Channel.UserData.AuthServer)?.Id})") ?? $"{info.CharacterName} ({info.Username})";
+        var serverId = "Unknown";
+        if (_playerManager.TryGetSessionById(info.SessionId, out var session))
+        {
+            serverId = AuthServer.GetServerFromCVarListByUrl(_config, session.Channel.UserData.AuthServer)?.Id ?? "Unknown";
+        }
+        var displayName = $"{info.CharacterName} ({info.Username}@{serverId})";
+        PlayerEntryLabel.Text = overrideText?.Invoke(info, displayName) ?? $"{info.CharacterName} ({info.Username})";


// If all else fails, ask the auth server.
var authServer = _configurationManager.GetCVar(CVars.AuthServer);
var authServer = AuthServer.FromStringList(_configurationManager.GetCVar(CVars.AuthServers)).First().AuthUrl; // WD EDIT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Потенциальное исключение при пустом списке серверов аутентификации.

Вызов .First() на пустой последовательности выбросит InvalidOperationException. Если CVars.AuthServers пуст или не содержит валидных записей, это приведёт к сбою.

🛠️ Предлагаемое исправление
-            var authServer = AuthServer.FromStringList(_configurationManager.GetCVar(CVars.AuthServers)).First().AuthUrl; // WD EDIT
+            var authServers = AuthServer.FromStringList(_configurationManager.GetCVar(CVars.AuthServers));
+            var authServer = authServers.FirstOrDefault()?.AuthUrl
+                ?? throw new InvalidOperationException("No auth servers configured in CVars.AuthServers"); // WD EDIT
🤖 Prompt for AI Agents
In @Content.Server/Administration/PlayerLocator.cs at line 105,
AuthServer.FromStringList(_configurationManager.GetCVar(CVars.AuthServers)).First()
can throw InvalidOperationException for an empty/invalid list; change the call
to safely handle empties (e.g., use FirstOrDefault/null-check or check the
returned collection count) and then handle the missing server case before
accessing AuthUrl — update the usage in the method that currently reads
AuthServer.FromStringList(...).First().AuthUrl to use a safe retrieval
(FirstOrDefault), verify the result is non-null (or collection non-empty) and
provide a fallback or clear error/log message if no auth server is available.


// If all else fails, ask the auth server.
var authServer = _configurationManager.GetCVar(CVars.AuthServer);
var authServer = AuthServer.FromStringList(_configurationManager.GetCVar(CVars.AuthServers)).First().AuthUrl; // WD EDIT
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Дублирование проблемы с .First() — то же самое исключение возможно здесь.

Аналогичная проблема с вызовом .First() без проверки на пустую последовательность. Рассмотрите вынос логики получения auth server URL в отдельный приватный метод для устранения дублирования.

♻️ Предлагаемый рефакторинг — вынести в отдельный метод
+    private string GetPrimaryAuthServerUrl()
+    {
+        var authServers = AuthServer.FromStringList(_configurationManager.GetCVar(CVars.AuthServers));
+        return authServers.FirstOrDefault()?.AuthUrl
+            ?? throw new InvalidOperationException("No auth servers configured");
+    }

Затем использовать:

-            var authServer = AuthServer.FromStringList(_configurationManager.GetCVar(CVars.AuthServers)).First().AuthUrl; // WD EDIT
+            var authServer = GetPrimaryAuthServerUrl(); // WD EDIT
🤖 Prompt for AI Agents
In @Content.Server/Administration/PlayerLocator.cs at line 124, The code calls
AuthServer.FromStringList(_configurationManager.GetCVar(CVars.AuthServers)).First().AuthUrl
which can throw on an empty sequence and duplicates this logic; extract this
into a private helper (e.g. GetAuthServerUrl or ResolveAuthServerUrl) that calls
AuthServer.FromStringList, checks for empty/null (use
FirstOrDefault/SingleOrDefault), returns AuthUrl or handles the missing case
(log and throw a clear exception or return null/Optional) and replace all direct
.First().AuthUrl usages with this helper to remove duplication and avoid the
exception.

Comment on lines +253 to +264
// WD EDDIT START
var authServer = player.AuthType == LoginType.LoggedIn
? AuthServer.FromStringList(_configurationManager.GetCVar(CVars.AuthServers))
.FirstOrDefault(x => x.AuthUrl.ToString() == player.Channel.UserData.AuthServer)
?.Id ?? "Unknown"
: "Unknown";
var wrappedMessage = Loc.GetString(
"chat-manager-send-ooc-wrap-message",
("playerName", $"{player.Name}"),
("authServer", authServer),
("message", FormattedMessage.EscapeText(message)));
// WD EDIT END
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Логика определения authServer корректна, но есть опечатка в комментарии.

Реализация с использованием FirstOrDefault и ?? "Unknown" обеспечивает правильную обработку случаев, когда сервер не найден. Однако, на строке 253 опечатка: WD EDDIT вместо WD EDIT.

🔧 Исправление опечатки
-        // WD EDDIT START
+        // WD EDIT START
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// WD EDDIT START
var authServer = player.AuthType == LoginType.LoggedIn
? AuthServer.FromStringList(_configurationManager.GetCVar(CVars.AuthServers))
.FirstOrDefault(x => x.AuthUrl.ToString() == player.Channel.UserData.AuthServer)
?.Id ?? "Unknown"
: "Unknown";
var wrappedMessage = Loc.GetString(
"chat-manager-send-ooc-wrap-message",
("playerName", $"{player.Name}"),
("authServer", authServer),
("message", FormattedMessage.EscapeText(message)));
// WD EDIT END
// WD EDIT START
var authServer = player.AuthType == LoginType.LoggedIn
? AuthServer.FromStringList(_configurationManager.GetCVar(CVars.AuthServers))
.FirstOrDefault(x => x.AuthUrl.ToString() == player.Channel.UserData.AuthServer)
?.Id ?? "Unknown"
: "Unknown";
var wrappedMessage = Loc.GetString(
"chat-manager-send-ooc-wrap-message",
("playerName", $"{player.Name}"),
("authServer", authServer),
("message", FormattedMessage.EscapeText(message)));
// WD EDIT END
🤖 Prompt for AI Agents
In @Content.Server/Chat/Managers/ChatManager.cs around lines 253 - 264, The
inline block comments around the authServer logic contain a typo: change the
opening marker "WD EDDIT START" to "WD EDIT START" (matching the closing "WD
EDIT END") so comment markers are consistent; update only the comment text
surrounding the AuthServer resolution/Loc.GetString call (the lines containing
"WD EDDIT START" and "WD EDIT END").

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant