Fixes the ShowRulesCommand and the client not syncing rules correctly (#28752)

This commit is contained in:
AJCM-git
2024-06-15 00:41:25 -04:00
committed by GitHub
parent 2953e87f1c
commit c339773b5f
5 changed files with 50 additions and 27 deletions

View File

@@ -1,12 +1,10 @@
using Content.Client.Gameplay; using Content.Client.Gameplay;
using Content.Client.Info; using Content.Client.Info;
using Content.Shared.CCVar;
using Content.Shared.Guidebook; using Content.Shared.Guidebook;
using Content.Shared.Info; using Content.Shared.Info;
using Robust.Client.Console; using Robust.Client.Console;
using Robust.Client.UserInterface.Controllers; using Robust.Client.UserInterface.Controllers;
using Robust.Client.UserInterface.Controls; using Robust.Client.UserInterface.Controls;
using Robust.Shared.Configuration;
using Robust.Shared.Network; using Robust.Shared.Network;
using Robust.Shared.Prototypes; using Robust.Shared.Prototypes;
@@ -14,21 +12,27 @@ namespace Content.Client.UserInterface.Systems.Info;
public sealed class InfoUIController : UIController, IOnStateExited<GameplayState> public sealed class InfoUIController : UIController, IOnStateExited<GameplayState>
{ {
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IClientConsoleHost _consoleHost = default!; [Dependency] private readonly IClientConsoleHost _consoleHost = default!;
[Dependency] private readonly INetManager _netManager = default!; [Dependency] private readonly INetManager _netManager = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!; [Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly ILogManager _logMan = default!;
private RulesPopup? _rulesPopup; private RulesPopup? _rulesPopup;
private RulesAndInfoWindow? _infoWindow; private RulesAndInfoWindow? _infoWindow;
private ISawmill _sawmill = default!;
[ValidatePrototypeId<GuideEntryPrototype>]
private const string DefaultRuleset = "DefaultRuleset";
public ProtoId<GuideEntryPrototype> RulesEntryId = DefaultRuleset;
public override void Initialize() public override void Initialize()
{ {
base.Initialize(); base.Initialize();
_sawmill = _logMan.GetSawmill("rules");
_netManager.RegisterNetMessage<RulesAcceptedMessage>(); _netManager.RegisterNetMessage<RulesAcceptedMessage>();
_netManager.RegisterNetMessage<ShowRulesPopupMessage>(OnShowRulesPopupMessage); _netManager.RegisterNetMessage<SendRulesInformationMessage>(OnRulesInformationMessage);
_consoleHost.RegisterCommand("fuckrules", _consoleHost.RegisterCommand("fuckrules",
"", "",
@@ -39,8 +43,11 @@ public sealed class InfoUIController : UIController, IOnStateExited<GameplayStat
}); });
} }
private void OnShowRulesPopupMessage(ShowRulesPopupMessage message) private void OnRulesInformationMessage(SendRulesInformationMessage message)
{ {
RulesEntryId = message.CoreRules;
if (message.ShouldShowRules)
ShowRules(message.PopupTime); ShowRules(message.PopupTime);
} }
@@ -84,8 +91,13 @@ public sealed class InfoUIController : UIController, IOnStateExited<GameplayStat
public GuideEntryPrototype GetCoreRuleEntry() public GuideEntryPrototype GetCoreRuleEntry()
{ {
var guide = _cfg.GetCVar(CCVars.RulesFile); if (!_prototype.TryIndex(RulesEntryId, out var guideEntryPrototype))
var guideEntryPrototype = _prototype.Index<GuideEntryPrototype>(guide); {
guideEntryPrototype = _prototype.Index<GuideEntryPrototype>(DefaultRuleset);
_sawmill.Error($"Couldn't find the following prototype: {RulesEntryId}. Falling back to {DefaultRuleset}, please check that the server has the rules set up correctly");
return guideEntryPrototype;
}
return guideEntryPrototype; return guideEntryPrototype;
} }

View File

@@ -18,22 +18,25 @@ public sealed class RulesManager
public void Initialize() public void Initialize()
{ {
_netManager.Connected += OnConnected; _netManager.Connected += OnConnected;
_netManager.RegisterNetMessage<ShowRulesPopupMessage>(); _netManager.RegisterNetMessage<SendRulesInformationMessage>();
_netManager.RegisterNetMessage<RulesAcceptedMessage>(OnRulesAccepted); _netManager.RegisterNetMessage<RulesAcceptedMessage>(OnRulesAccepted);
} }
private async void OnConnected(object? sender, NetChannelArgs e) private async void OnConnected(object? sender, NetChannelArgs e)
{ {
if (IPAddress.IsLoopback(e.Channel.RemoteEndPoint.Address) && _cfg.GetCVar(CCVars.RulesExemptLocal)) var isLocalhost = IPAddress.IsLoopback(e.Channel.RemoteEndPoint.Address) &&
return; _cfg.GetCVar(CCVars.RulesExemptLocal);
var lastRead = await _dbManager.GetLastReadRules(e.Channel.UserId); var lastRead = await _dbManager.GetLastReadRules(e.Channel.UserId);
if (lastRead > LastValidReadTime) var hasCooldown = lastRead > LastValidReadTime;
return;
var message = new ShowRulesPopupMessage(); var showRulesMessage = new SendRulesInformationMessage
message.PopupTime = _cfg.GetCVar(CCVars.RulesWaitTime); {
_netManager.ServerSendMessage(message, e.Channel); PopupTime = _cfg.GetCVar(CCVars.RulesWaitTime),
CoreRules = _cfg.GetCVar(CCVars.RulesFile),
ShouldShowRules = !isLocalhost && !hasCooldown
};
_netManager.ServerSendMessage(showRulesMessage, e.Channel);
} }
private async void OnRulesAccepted(RulesAcceptedMessage message) private async void OnRulesAccepted(RulesAcceptedMessage message)

View File

@@ -12,6 +12,10 @@ namespace Content.Server.Info;
[AdminCommand(AdminFlags.Admin)] [AdminCommand(AdminFlags.Admin)]
public sealed class ShowRulesCommand : IConsoleCommand public sealed class ShowRulesCommand : IConsoleCommand
{ {
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly IConfigurationManager _configuration = default!;
[Dependency] private readonly IPlayerManager _player = default!;
public string Command => "showrules"; public string Command => "showrules";
public string Description => "Opens the rules popup for the specified player."; public string Description => "Opens the rules popup for the specified player.";
public string Help => "showrules <username> [seconds]"; public string Help => "showrules <username> [seconds]";
@@ -25,8 +29,7 @@ public sealed class ShowRulesCommand : IConsoleCommand
case 1: case 1:
{ {
target = args[0]; target = args[0];
var configurationManager = IoCManager.Resolve<IConfigurationManager>(); seconds = _configuration.GetCVar(CCVars.RulesWaitTime);
seconds = configurationManager.GetCVar(CCVars.RulesWaitTime);
break; break;
} }
case 2: case 2:
@@ -48,15 +51,14 @@ public sealed class ShowRulesCommand : IConsoleCommand
} }
var message = new ShowRulesPopupMessage { PopupTime = seconds }; if (!_player.TryGetSessionByUsername(target, out var player))
if (!IoCManager.Resolve<IPlayerManager>().TryGetSessionByUsername(target, out var player))
{ {
shell.WriteError("Unable to find a player with that name."); shell.WriteError("Unable to find a player with that name.");
return; return;
} }
var netManager = IoCManager.Resolve<INetManager>(); var coreRules = _configuration.GetCVar(CCVars.RulesFile);
netManager.ServerSendMessage(message, player.Channel); var message = new SendRulesInformationMessage { PopupTime = seconds, CoreRules = coreRules, ShouldShowRules = true};
_net.ServerSendMessage(message, player.Channel);
} }
} }

View File

@@ -1856,7 +1856,7 @@ namespace Content.Shared.CCVar
/// Don't show rules to localhost/loopback interface. /// Don't show rules to localhost/loopback interface.
/// </summary> /// </summary>
public static readonly CVarDef<bool> RulesExemptLocal = public static readonly CVarDef<bool> RulesExemptLocal =
CVarDef.Create("rules.exempt_local", false, CVar.SERVERONLY); CVarDef.Create("rules.exempt_local", true, CVar.SERVERONLY);
/* /*

View File

@@ -5,22 +5,28 @@ using Robust.Shared.Serialization;
namespace Content.Shared.Info; namespace Content.Shared.Info;
/// <summary> /// <summary>
/// Sent by the server to show the rules to the client instantly. /// Sent by the server when the client connects to sync the client rules and displaying a popup with them if necessitated.
/// </summary> /// </summary>
public sealed class ShowRulesPopupMessage : NetMessage public sealed class SendRulesInformationMessage : NetMessage
{ {
public override MsgGroups MsgGroup => MsgGroups.Command; public override MsgGroups MsgGroup => MsgGroups.Command;
public float PopupTime { get; set; } public float PopupTime { get; set; }
public string CoreRules { get; set; } = string.Empty;
public bool ShouldShowRules { get; set; }
public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer) public override void ReadFromBuffer(NetIncomingMessage buffer, IRobustSerializer serializer)
{ {
PopupTime = buffer.ReadFloat(); PopupTime = buffer.ReadFloat();
CoreRules = buffer.ReadString();
ShouldShowRules = buffer.ReadBoolean();
} }
public override void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer serializer) public override void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer serializer)
{ {
buffer.Write(PopupTime); buffer.Write(PopupTime);
buffer.Write(CoreRules);
buffer.Write(ShouldShowRules);
} }
} }