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.Info;
using Content.Shared.CCVar;
using Content.Shared.Guidebook;
using Content.Shared.Info;
using Robust.Client.Console;
using Robust.Client.UserInterface.Controllers;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Configuration;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
@@ -14,21 +12,27 @@ namespace Content.Client.UserInterface.Systems.Info;
public sealed class InfoUIController : UIController, IOnStateExited<GameplayState>
{
[Dependency] private readonly IConfigurationManager _cfg = default!;
[Dependency] private readonly IClientConsoleHost _consoleHost = default!;
[Dependency] private readonly INetManager _netManager = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;
[Dependency] private readonly ILogManager _logMan = default!;
private RulesPopup? _rulesPopup;
private RulesAndInfoWindow? _infoWindow;
private ISawmill _sawmill = default!;
[ValidatePrototypeId<GuideEntryPrototype>]
private const string DefaultRuleset = "DefaultRuleset";
public ProtoId<GuideEntryPrototype> RulesEntryId = DefaultRuleset;
public override void Initialize()
{
base.Initialize();
_sawmill = _logMan.GetSawmill("rules");
_netManager.RegisterNetMessage<RulesAcceptedMessage>();
_netManager.RegisterNetMessage<ShowRulesPopupMessage>(OnShowRulesPopupMessage);
_netManager.RegisterNetMessage<SendRulesInformationMessage>(OnRulesInformationMessage);
_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);
}
@@ -84,8 +91,13 @@ public sealed class InfoUIController : UIController, IOnStateExited<GameplayStat
public GuideEntryPrototype GetCoreRuleEntry()
{
var guide = _cfg.GetCVar(CCVars.RulesFile);
var guideEntryPrototype = _prototype.Index<GuideEntryPrototype>(guide);
if (!_prototype.TryIndex(RulesEntryId, out var guideEntryPrototype))
{
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;
}

View File

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

View File

@@ -12,6 +12,10 @@ namespace Content.Server.Info;
[AdminCommand(AdminFlags.Admin)]
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 Description => "Opens the rules popup for the specified player.";
public string Help => "showrules <username> [seconds]";
@@ -25,8 +29,7 @@ public sealed class ShowRulesCommand : IConsoleCommand
case 1:
{
target = args[0];
var configurationManager = IoCManager.Resolve<IConfigurationManager>();
seconds = configurationManager.GetCVar(CCVars.RulesWaitTime);
seconds = _configuration.GetCVar(CCVars.RulesWaitTime);
break;
}
case 2:
@@ -48,15 +51,14 @@ public sealed class ShowRulesCommand : IConsoleCommand
}
var message = new ShowRulesPopupMessage { PopupTime = seconds };
if (!IoCManager.Resolve<IPlayerManager>().TryGetSessionByUsername(target, out var player))
if (!_player.TryGetSessionByUsername(target, out var player))
{
shell.WriteError("Unable to find a player with that name.");
return;
}
var netManager = IoCManager.Resolve<INetManager>();
netManager.ServerSendMessage(message, player.Channel);
var coreRules = _configuration.GetCVar(CCVars.RulesFile);
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.
/// </summary>
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;
/// <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>
public sealed class ShowRulesPopupMessage : NetMessage
public sealed class SendRulesInformationMessage : NetMessage
{
public override MsgGroups MsgGroup => MsgGroups.Command;
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)
{
PopupTime = buffer.ReadFloat();
CoreRules = buffer.ReadString();
ShouldShowRules = buffer.ReadBoolean();
}
public override void WriteToBuffer(NetOutgoingMessage buffer, IRobustSerializer serializer)
{
buffer.Write(PopupTime);
buffer.Write(CoreRules);
buffer.Write(ShouldShowRules);
}
}