diff --git a/Content.Client/Administration/ClientAdminManager.cs b/Content.Client/Administration/ClientAdminManager.cs
index 7ef0f31169..0f66a2df98 100644
--- a/Content.Client/Administration/ClientAdminManager.cs
+++ b/Content.Client/Administration/ClientAdminManager.cs
@@ -21,6 +21,11 @@ namespace Content.Client.Administration
public event Action? AdminStatusUpdated;
+ public bool IsActive()
+ {
+ return _adminData?.Active ?? false;
+ }
+
public bool HasFlag(AdminFlags flag)
{
return _adminData?.HasFlag(flag) ?? false;
diff --git a/Content.Client/Administration/IClientAdminManager.cs b/Content.Client/Administration/IClientAdminManager.cs
index e675e3f378..ed04f1d7e0 100644
--- a/Content.Client/Administration/IClientAdminManager.cs
+++ b/Content.Client/Administration/IClientAdminManager.cs
@@ -15,6 +15,12 @@ namespace Content.Client.Administration
///
event Action AdminStatusUpdated;
+ ///
+ /// Checks whether the local player is an admin.
+ ///
+ /// true if the local player is an admin, false otherwise even if they are deadminned.
+ bool IsActive();
+
///
/// Checks whether the local player has an admin flag.
///
diff --git a/Content.Client/State/GameScreen.cs b/Content.Client/State/GameScreen.cs
index eaeaa3fcff..dbbc4a2ab3 100644
--- a/Content.Client/State/GameScreen.cs
+++ b/Content.Client/State/GameScreen.cs
@@ -1,11 +1,14 @@
+using Content.Client.Administration;
using Content.Client.Chat;
using Content.Client.Interfaces.Chat;
using Content.Client.UserInterface;
using Content.Client.Voting;
+using Content.Shared;
using Content.Shared.Input;
using Robust.Client.Input;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
+using Robust.Shared.Configuration;
using Robust.Shared.Input.Binding;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
@@ -20,9 +23,14 @@ namespace Content.Client.State
[Dependency] private readonly IInputManager _inputManager = default!;
[Dependency] private readonly IChatManager _chatManager = default!;
[Dependency] private readonly IVoteManager _voteManager = default!;
+ [Dependency] private readonly IConfigurationManager _configurationManager = default!;
+ [Dependency] private readonly IClientAdminManager _adminManager = default!;
[ViewVariables] private ChatBox _gameChat;
+ private bool _oocEnabled;
+ private bool _adminOocEnabled;
+
public override void Startup()
{
base.Startup();
@@ -42,13 +50,17 @@ namespace Content.Client.State
_gameChat.Input.PlaceHolder = Loc.GetString("Say something! [ for OOC");
_inputManager.SetInputCommand(ContentKeyFunctions.FocusChat,
- InputCmdHandler.FromDelegate(s => FocusChat(_gameChat)));
+ InputCmdHandler.FromDelegate(_ => FocusChat(_gameChat)));
_inputManager.SetInputCommand(ContentKeyFunctions.FocusOOC,
- InputCmdHandler.FromDelegate(s => FocusOOC(_gameChat)));
+ InputCmdHandler.FromDelegate(_ => FocusOOC(_gameChat)));
_inputManager.SetInputCommand(ContentKeyFunctions.FocusAdminChat,
- InputCmdHandler.FromDelegate(s => FocusAdminChat(_gameChat)));
+ InputCmdHandler.FromDelegate(_ => FocusAdminChat(_gameChat)));
+
+ _configurationManager.OnValueChanged(CCVars.OocEnabled, OnOocEnabledChanged, true);
+ _configurationManager.OnValueChanged(CCVars.AdminOocEnabled, OnAdminOocEnabledChanged, true);
+ _adminManager.AdminStatusUpdated += OnAdminStatusUpdated;
}
public override void Shutdown()
@@ -59,6 +71,37 @@ namespace Content.Client.State
_gameHud.RootControl.Orphan();
}
+ private void OnOocEnabledChanged(bool val)
+ {
+ _oocEnabled = val;
+
+ if (_adminManager.IsActive())
+ {
+ return;
+ }
+
+ _gameChat.Input.PlaceHolder = Loc.GetString(_oocEnabled ? "Say something! [ for OOC" : "Say something!");
+ }
+
+ private void OnAdminOocEnabledChanged(bool val)
+ {
+ _adminOocEnabled = val;
+
+ if (!_adminManager.IsActive())
+ {
+ return;
+ }
+
+ _gameChat.Input.PlaceHolder = Loc.GetString(_adminOocEnabled ? "Say something! [ for OOC" : "Say something!");
+ }
+
+ private void OnAdminStatusUpdated()
+ {
+ _gameChat.Input.PlaceHolder = _adminManager.IsActive()
+ ? Loc.GetString(_adminOocEnabled ? "Say something! [ for OOC" : "Say something!")
+ : Loc.GetString(_oocEnabled ? "Say something! [ for OOC" : "Say something!");
+ }
+
internal static void FocusChat(ChatBox chat)
{
if (chat == null || chat.UserInterfaceManager.KeyboardFocused != null)
diff --git a/Content.Server/Administration/AdminManager.cs b/Content.Server/Administration/AdminManager.cs
index f1d9540017..7085525d2f 100644
--- a/Content.Server/Administration/AdminManager.cs
+++ b/Content.Server/Administration/AdminManager.cs
@@ -53,6 +53,11 @@ namespace Content.Server.Administration
private readonly HashSet _anyCommands = new();
private readonly Dictionary _adminCommands = new();
+ public bool IsAdmin(IPlayerSession session, bool includeDeAdmin = false)
+ {
+ return GetAdminData(session, includeDeAdmin) != null;
+ }
+
public AdminData? GetAdminData(IPlayerSession session, bool includeDeAdmin = false)
{
if (_admins.TryGetValue(session, out var reg) && (reg.Data.Active || includeDeAdmin))
diff --git a/Content.Server/Administration/IAdminManager.cs b/Content.Server/Administration/IAdminManager.cs
index cb7ba4b71d..e6fcd62667 100644
--- a/Content.Server/Administration/IAdminManager.cs
+++ b/Content.Server/Administration/IAdminManager.cs
@@ -25,12 +25,22 @@ namespace Content.Server.Administration
///
IEnumerable ActiveAdmins { get; }
+ ///
+ /// Checks if a player is an admin.
+ ///
+ /// The player to check.
+ ///
+ /// Whether to return admin data for admins that are current de-adminned.
+ ///
+ /// true if the player is an admin, false otherwise.
+ bool IsAdmin(IPlayerSession session, bool includeDeAdmin = false);
+
///
/// Gets the admin data for a player, if they are an admin.
///
/// The player to get admin data for.
///
- /// Whether to return admin data for admins that are current de-adminned.
+ /// Whether to return admin data for admins that are current de-adminned.
///
/// if the player is not an admin.
AdminData? GetAdminData(IPlayerSession session, bool includeDeAdmin = false);
diff --git a/Content.Server/Chat/ChatManager.cs b/Content.Server/Chat/ChatManager.cs
index 4a7d558bee..9a107d1568 100644
--- a/Content.Server/Chat/ChatManager.cs
+++ b/Content.Server/Chat/ChatManager.cs
@@ -8,6 +8,7 @@ using Content.Server.GameObjects.Components.Observer;
using Content.Server.GameObjects.EntitySystems;
using Content.Server.Interfaces;
using Content.Server.Interfaces.Chat;
+using Content.Shared;
using Content.Shared.Administration;
using Content.Shared.Chat;
using Content.Shared.GameObjects.Components.Inventory;
@@ -15,6 +16,7 @@ using Content.Shared.GameObjects.EntitySystems.ActionBlocker;
using Content.Shared.Interfaces;
using Robust.Server.GameObjects;
using Robust.Server.Player;
+using Robust.Shared.Configuration;
using Robust.Shared.GameObjects;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
@@ -29,10 +31,17 @@ namespace Content.Server.Chat
///
internal sealed class ChatManager : IChatManager
{
+ [Dependency] private readonly IServerNetManager _netManager = default!;
+ [Dependency] private readonly IPlayerManager _playerManager = default!;
+ [Dependency] private readonly IMoMMILink _mommiLink = default!;
+ [Dependency] private readonly IAdminManager _adminManager = default!;
+ [Dependency] private readonly IServerPreferencesManager _preferencesManager = default!;
+ [Dependency] private readonly IConfigurationManager _configurationManager = default!;
+
///
/// The maximum length a player-sent message can be sent
///
- public int MaxMessageLength = 1000;
+ public const int MaxMessageLength = 1000;
private const int VoiceRange = 7; // how far voice goes in world units
@@ -43,12 +52,8 @@ namespace Content.Server.Chat
//TODO: make prio based?
private List _chatTransformHandlers;
-
- [Dependency] private readonly IServerNetManager _netManager = default!;
- [Dependency] private readonly IPlayerManager _playerManager = default!;
- [Dependency] private readonly IMoMMILink _mommiLink = default!;
- [Dependency] private readonly IAdminManager _adminManager = default!;
- [Dependency] private readonly IServerPreferencesManager _preferencesManager = default!;
+ private bool _oocEnabled = true;
+ private bool _adminOocEnabled = true;
public void Initialize()
{
@@ -61,6 +66,21 @@ namespace Content.Server.Chat
_netManager.ServerSendToAll(msg);
_chatTransformHandlers = new List();
+
+ _configurationManager.OnValueChanged(CCVars.OocEnabled, OnOocEnabledChanged, true);
+ _configurationManager.OnValueChanged(CCVars.AdminOocEnabled, OnAdminOocEnabledChanged, true);
+ }
+
+ private void OnOocEnabledChanged(bool val)
+ {
+ _oocEnabled = val;
+ DispatchServerAnnouncement(val ? "OOC chat has been enabled." : "OOC chat has been disabled.");
+ }
+
+ private void OnAdminOocEnabledChanged(bool val)
+ {
+ _adminOocEnabled = val;
+ DispatchServerAnnouncement(val ? "Admin OOC chat has been enabled." : "Admin OOC chat has been disabled.");
}
public void DispatchServerAnnouncement(string message)
@@ -166,15 +186,17 @@ namespace Content.Server.Chat
}
// Check if entity is a player
- IPlayerSession playerSession = source.GetComponent().playerSession;
+ if (!source.TryGetComponent(out IActorComponent actor))
+ {
+ return;
+ }
// Check if message exceeds the character limit
- if (playerSession != null)
- if (action.Length > MaxMessageLength)
- {
- DispatchServerMessage(playerSession, Loc.GetString(MaxLengthExceededMessage, MaxMessageLength));
- return;
- }
+ if (actor.playerSession != null && action.Length > MaxMessageLength)
+ {
+ DispatchServerMessage(actor.playerSession, Loc.GetString(MaxLengthExceededMessage, MaxMessageLength));
+ return;
+ }
var pos = source.Transform.Coordinates;
var clients = _playerManager.GetPlayersInRange(pos, VoiceRange).Select(p => p.ConnectedClient);
@@ -189,6 +211,18 @@ namespace Content.Server.Chat
public void SendOOC(IPlayerSession player, string message)
{
+ if (_adminManager.IsAdmin(player))
+ {
+ if (!_adminOocEnabled)
+ {
+ return;
+ }
+ }
+ else if (!_oocEnabled)
+ {
+ return;
+ }
+
// Check if message exceeds the character limit
if (message.Length > MaxMessageLength)
{
@@ -202,7 +236,7 @@ namespace Content.Server.Chat
msg.MessageWrap = $"OOC: {player.Name}: {{0}}";
if (_adminManager.HasAdminFlag(player, AdminFlags.Admin))
{
- var prefs = _preferencesManager.GetPreferences((player.UserId));
+ var prefs = _preferencesManager.GetPreferences(player.UserId);
msg.MessageColorOverride = prefs.AdminOOCColor;
}
//TODO: player.Name color, this will need to change the structure of the MsgChatMessage
diff --git a/Content.Shared/CCVars.cs b/Content.Shared/CCVars.cs
index c37c01cb99..522b7c791f 100644
--- a/Content.Shared/CCVars.cs
+++ b/Content.Shared/CCVars.cs
@@ -252,5 +252,14 @@ namespace Content.Shared
*/
public static readonly CVarDef BrandingSteam = CVarDef.Create("branding.steam", false, CVar.CLIENTONLY);
+
+ /*
+ * OOC
+ */
+
+ public static readonly CVarDef OocEnabled = CVarDef.Create("ooc.enabled", true, CVar.NOTIFY);
+
+ public static readonly CVarDef AdminOocEnabled =
+ CVarDef.Create("ooc.enabled_admin", true, CVar.NOTIFY);
}
}