Show rules on first connection (#5715)

* Implement showing rules on first connection

* Clean up RulesManager

* Change changelog and rules unread to use CVars

* Fix missing change

* Rename InfoWindow to RulesAndInfoWindow

* Change default server.id to unknown

* Fix invalid file contents and getting CVar
This commit is contained in:
ShadowCommander
2021-12-09 14:22:49 -08:00
committed by GitHub
parent ceca68236c
commit b3a4e3f557
9 changed files with 102 additions and 17 deletions

View File

@@ -4,6 +4,8 @@ using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using Content.Shared.CCVar;
using Robust.Shared.Configuration;
using Robust.Shared.ContentPack; using Robust.Shared.ContentPack;
using Robust.Shared.IoC; using Robust.Shared.IoC;
using Robust.Shared.Serialization; using Robust.Shared.Serialization;
@@ -18,11 +20,9 @@ namespace Content.Client.Changelog
{ {
public sealed class ChangelogManager public sealed class ChangelogManager
{ {
// If you fork SS14, change this to have the changelog "last seen" date stored separately.
public const string ForkId = "Wizards";
[Dependency] private readonly IResourceManager _resource = default!; [Dependency] private readonly IResourceManager _resource = default!;
[Dependency] private readonly ISerializationManager _serialization = default!; [Dependency] private readonly ISerializationManager _serialization = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
public bool NewChangelogEntries { get; private set; } public bool NewChangelogEntries { get; private set; }
public int LastReadId { get; private set; } public int LastReadId { get; private set; }
@@ -43,7 +43,7 @@ namespace Content.Client.Changelog
NewChangelogEntries = false; NewChangelogEntries = false;
NewChangelogEntriesChanged?.Invoke(); NewChangelogEntriesChanged?.Invoke();
using var file = _resource.UserData.Create(new ResourcePath($"/changelog_last_seen_{ForkId}")); using var file = _resource.UserData.Create(new ResourcePath($"/changelog_last_seen_{_configManager.GetCVar(CCVars.ServerId)}"));
using var sw = new StreamWriter(file); using var sw = new StreamWriter(file);
sw.Write(MaxId.ToString()); sw.Write(MaxId.ToString());
@@ -61,7 +61,7 @@ namespace Content.Client.Changelog
MaxId = changelog.Max(c => c.Id); MaxId = changelog.Max(c => c.Id);
var path = new ResourcePath($"/changelog_last_seen_{ForkId}"); var path = new ResourcePath($"/changelog_last_seen_{_configManager.GetCVar(CCVars.ServerId)}");
if (_resource.UserData.Exists(path)) if (_resource.UserData.Exists(path))
{ {
LastReadId = int.Parse(_resource.UserData.ReadAllText(path)); LastReadId = int.Parse(_resource.UserData.ReadAllText(path));

View File

@@ -7,6 +7,7 @@ using Content.Client.EscapeMenu;
using Content.Client.Eui; using Content.Client.Eui;
using Content.Client.Flash; using Content.Client.Flash;
using Content.Client.HUD; using Content.Client.HUD;
using Content.Client.Info;
using Content.Client.Input; using Content.Client.Input;
using Content.Client.IoC; using Content.Client.IoC;
using Content.Client.Launcher; using Content.Client.Launcher;
@@ -113,6 +114,7 @@ namespace Content.Client.Entry
IoCManager.Resolve<IStylesheetManager>().Initialize(); IoCManager.Resolve<IStylesheetManager>().Initialize();
IoCManager.Resolve<IScreenshotHook>().Initialize(); IoCManager.Resolve<IScreenshotHook>().Initialize();
IoCManager.Resolve<ChangelogManager>().Initialize(); IoCManager.Resolve<ChangelogManager>().Initialize();
IoCManager.Resolve<RulesManager>().Initialize();
IoCManager.Resolve<ViewportManager>().Initialize(); IoCManager.Resolve<ViewportManager>().Initialize();
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);

View File

@@ -104,7 +104,7 @@ namespace Content.Client.HUD
private TopButton _buttonActionsMenu = default!; private TopButton _buttonActionsMenu = default!;
private TopButton _buttonAdminMenu = default!; private TopButton _buttonAdminMenu = default!;
private TopButton _buttonSandboxMenu = default!; private TopButton _buttonSandboxMenu = default!;
private InfoWindow _infoWindow = default!; private RulesAndInfoWindow _rulesAndInfoWindow = default!;
private TargetingDoll _targetingDoll = default!; private TargetingDoll _targetingDoll = default!;
private BoxContainer _combatPanelContainer = default!; private BoxContainer _combatPanelContainer = default!;
private BoxContainer _topNotificationContainer = default!; private BoxContainer _topNotificationContainer = default!;
@@ -301,9 +301,11 @@ namespace Content.Client.HUD
_buttonInfo.OnToggled += a => ButtonInfoOnOnToggled(); _buttonInfo.OnToggled += a => ButtonInfoOnOnToggled();
_infoWindow = new InfoWindow(); _rulesAndInfoWindow = new RulesAndInfoWindow();
_infoWindow.OnClose += () => _buttonInfo.Pressed = false; IoCManager.Resolve<RulesManager>().OpenRulesAndInfoWindow += OpenRulesAndInfoWindow;
_rulesAndInfoWindow.OnClose += () => _buttonInfo.Pressed = false;
_inputManager.SetInputCommand(ContentKeyFunctions.OpenInfo, _inputManager.SetInputCommand(ContentKeyFunctions.OpenInfo,
InputCmdHandler.FromDelegate(s => ButtonInfoOnOnToggled())); InputCmdHandler.FromDelegate(s => ButtonInfoOnOnToggled()));
@@ -428,25 +430,31 @@ namespace Content.Client.HUD
LC.SetGrowVertical(VoteContainer, LC.GrowDirection.End); LC.SetGrowVertical(VoteContainer, LC.GrowDirection.End);
} }
private void OpenRulesAndInfoWindow()
{
_rulesAndInfoWindow.OpenCentered();
_buttonInfo.Pressed = true;
}
private void ButtonInfoOnOnToggled() private void ButtonInfoOnOnToggled()
{ {
_buttonInfo.StyleClasses.Remove(TopButton.StyleClassRedTopButton); _buttonInfo.StyleClasses.Remove(TopButton.StyleClassRedTopButton);
if (_infoWindow.IsOpen) if (_rulesAndInfoWindow.IsOpen)
{ {
if (!_infoWindow.IsAtFront()) if (!_rulesAndInfoWindow.IsAtFront())
{ {
_infoWindow.MoveToFront(); _rulesAndInfoWindow.MoveToFront();
_buttonInfo.Pressed = true; _buttonInfo.Pressed = true;
} }
else else
{ {
_infoWindow.Close(); _rulesAndInfoWindow.Close();
_buttonInfo.Pressed = false; _buttonInfo.Pressed = false;
} }
} }
else else
{ {
_infoWindow.OpenCentered(); _rulesAndInfoWindow.OpenCentered();
_buttonInfo.Pressed = true; _buttonInfo.Pressed = true;
} }
} }

View File

@@ -15,13 +15,14 @@ using static Robust.Client.UserInterface.Controls.BoxContainer;
namespace Content.Client.Info namespace Content.Client.Info
{ {
public sealed class InfoWindow : SS14Window public sealed class RulesAndInfoWindow : SS14Window
{ {
[Dependency] private readonly RulesManager _rulesManager = default!;
[Dependency] private readonly IResourceCache _resourceManager = default!; [Dependency] private readonly IResourceCache _resourceManager = default!;
private OptionsMenu optionsMenu; private OptionsMenu optionsMenu;
public InfoWindow() public RulesAndInfoWindow()
{ {
IoCManager.InjectDependencies(this); IoCManager.InjectDependencies(this);
@@ -163,6 +164,13 @@ namespace Content.Client.Info
optionsMenu.OpenCentered(); optionsMenu.OpenCentered();
} }
protected override void Opened()
{
base.Opened();
_rulesManager.SaveLastReadTime();
}
private static IEnumerable<string> Lines(TextReader reader) private static IEnumerable<string> Lines(TextReader reader)
{ {
while (true) while (true)

View File

@@ -0,0 +1,55 @@
using System;
using System.Globalization;
using System.IO;
using Content.Client.HUD;
using Content.Shared.CCVar;
using Robust.Shared.Configuration;
using Robust.Shared.ContentPack;
using Robust.Shared.IoC;
using Robust.Shared.Network;
using Robust.Shared.Utility;
namespace Content.Client.Info;
public sealed class RulesManager
{
[Dependency] private readonly IClientNetManager _clientNetManager = default!;
[Dependency] private readonly IResourceManager _resource = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
public event Action? OpenRulesAndInfoWindow;
private void OnConnectStateChanged(ClientConnectionState state)
{
if (state != ClientConnectionState.Connected)
return;
var path = new ResourcePath($"/rules_last_seen_{_configManager.GetCVar(CCVars.ServerId)}");
var showRules = true;
if (_resource.UserData.Exists(path)
&& DateTime.TryParse(_resource.UserData.ReadAllText(path), null, DateTimeStyles.AssumeUniversal,
out var lastReadTime))
showRules = lastReadTime < DateTime.UtcNow - TimeSpan.FromDays(60);
else
SaveLastReadTime();
if (showRules)
OpenRulesAndInfoWindow?.Invoke();
}
/// <summary>
/// Ran when the user opens ("read") the rules, stores the new ID to disk.
/// </summary>
public void SaveLastReadTime()
{
using var file = _resource.UserData.Create(new ResourcePath($"/rules_last_seen_{_configManager.GetCVar(CCVars.ServerId)}"));
using var sw = new StreamWriter(file);
sw.Write(DateTime.UtcNow.ToUniversalTime());
}
public void Initialize()
{
_clientNetManager.ClientConnectStateChanged += OnConnectStateChanged;
}
}

View File

@@ -32,7 +32,7 @@ namespace Content.Client.Info
var uriOpener = IoCManager.Resolve<IUriOpener>(); var uriOpener = IoCManager.Resolve<IUriOpener>();
var rulesButton = new Button() { Text = Loc.GetString("server-info-rules-button") }; var rulesButton = new Button() { Text = Loc.GetString("server-info-rules-button") };
rulesButton.OnPressed += args => new InfoWindow().Open(); rulesButton.OnPressed += args => new RulesAndInfoWindow().Open();
var discordButton = new Button {Text = Loc.GetString("server-info-discord-button") }; var discordButton = new Button {Text = Loc.GetString("server-info-discord-button") };
discordButton.OnPressed += args => uriOpener.OpenUri(UILinks.Discord); discordButton.OnPressed += args => uriOpener.OpenUri(UILinks.Discord);

View File

@@ -5,6 +5,7 @@ using Content.Client.Clickable;
using Content.Client.EscapeMenu; using Content.Client.EscapeMenu;
using Content.Client.Eui; using Content.Client.Eui;
using Content.Client.HUD; using Content.Client.HUD;
using Content.Client.Info;
using Content.Client.Items.Managers; using Content.Client.Items.Managers;
using Content.Client.Module; using Content.Client.Module;
using Content.Client.Parallax.Managers; using Content.Client.Parallax.Managers;
@@ -44,6 +45,7 @@ namespace Content.Client.IoC
IoCManager.Register<EuiManager, EuiManager>(); IoCManager.Register<EuiManager, EuiManager>();
IoCManager.Register<IVoteManager, VoteManager>(); IoCManager.Register<IVoteManager, VoteManager>();
IoCManager.Register<ChangelogManager, ChangelogManager>(); IoCManager.Register<ChangelogManager, ChangelogManager>();
IoCManager.Register<RulesManager, RulesManager>();
IoCManager.Register<ViewportManager, ViewportManager>(); IoCManager.Register<ViewportManager, ViewportManager>();
} }
} }

View File

@@ -67,7 +67,7 @@ namespace Content.Client.Preferences.UI
UpdateUI(); UpdateUI();
RulesButton.OnPressed += _ => new InfoWindow().Open(); RulesButton.OnPressed += _ => new RulesAndInfoWindow().Open();
preferencesManager.OnServerDataLoaded += UpdateUI; preferencesManager.OnServerDataLoaded += UpdateUI;
} }

View File

@@ -7,6 +7,16 @@ namespace Content.Shared.CCVar
[CVarDefs] [CVarDefs]
public sealed class CCVars : CVars public sealed class CCVars : CVars
{ {
/*
* Server
*/
/// <summary>
/// Change this to have the changelog and rules "last seen" date stored separately.
/// </summary>
public static readonly CVarDef<string> ServerId =
CVarDef.Create("server.id", "unknown_server_id");
/* /*
* Ambience * Ambience
*/ */