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:
@@ -4,6 +4,8 @@ using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Content.Shared.CCVar;
|
||||
using Robust.Shared.Configuration;
|
||||
using Robust.Shared.ContentPack;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Serialization;
|
||||
@@ -18,11 +20,9 @@ namespace Content.Client.Changelog
|
||||
{
|
||||
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 ISerializationManager _serialization = default!;
|
||||
[Dependency] private readonly IConfigurationManager _configManager = default!;
|
||||
|
||||
public bool NewChangelogEntries { get; private set; }
|
||||
public int LastReadId { get; private set; }
|
||||
@@ -43,7 +43,7 @@ namespace Content.Client.Changelog
|
||||
NewChangelogEntries = false;
|
||||
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);
|
||||
|
||||
sw.Write(MaxId.ToString());
|
||||
@@ -61,7 +61,7 @@ namespace Content.Client.Changelog
|
||||
|
||||
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))
|
||||
{
|
||||
LastReadId = int.Parse(_resource.UserData.ReadAllText(path));
|
||||
|
||||
@@ -7,6 +7,7 @@ using Content.Client.EscapeMenu;
|
||||
using Content.Client.Eui;
|
||||
using Content.Client.Flash;
|
||||
using Content.Client.HUD;
|
||||
using Content.Client.Info;
|
||||
using Content.Client.Input;
|
||||
using Content.Client.IoC;
|
||||
using Content.Client.Launcher;
|
||||
@@ -113,6 +114,7 @@ namespace Content.Client.Entry
|
||||
IoCManager.Resolve<IStylesheetManager>().Initialize();
|
||||
IoCManager.Resolve<IScreenshotHook>().Initialize();
|
||||
IoCManager.Resolve<ChangelogManager>().Initialize();
|
||||
IoCManager.Resolve<RulesManager>().Initialize();
|
||||
IoCManager.Resolve<ViewportManager>().Initialize();
|
||||
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
@@ -104,7 +104,7 @@ namespace Content.Client.HUD
|
||||
private TopButton _buttonActionsMenu = default!;
|
||||
private TopButton _buttonAdminMenu = default!;
|
||||
private TopButton _buttonSandboxMenu = default!;
|
||||
private InfoWindow _infoWindow = default!;
|
||||
private RulesAndInfoWindow _rulesAndInfoWindow = default!;
|
||||
private TargetingDoll _targetingDoll = default!;
|
||||
private BoxContainer _combatPanelContainer = default!;
|
||||
private BoxContainer _topNotificationContainer = default!;
|
||||
@@ -301,9 +301,11 @@ namespace Content.Client.HUD
|
||||
|
||||
_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,
|
||||
InputCmdHandler.FromDelegate(s => ButtonInfoOnOnToggled()));
|
||||
@@ -428,25 +430,31 @@ namespace Content.Client.HUD
|
||||
LC.SetGrowVertical(VoteContainer, LC.GrowDirection.End);
|
||||
}
|
||||
|
||||
private void OpenRulesAndInfoWindow()
|
||||
{
|
||||
_rulesAndInfoWindow.OpenCentered();
|
||||
_buttonInfo.Pressed = true;
|
||||
}
|
||||
|
||||
private void ButtonInfoOnOnToggled()
|
||||
{
|
||||
_buttonInfo.StyleClasses.Remove(TopButton.StyleClassRedTopButton);
|
||||
if (_infoWindow.IsOpen)
|
||||
if (_rulesAndInfoWindow.IsOpen)
|
||||
{
|
||||
if (!_infoWindow.IsAtFront())
|
||||
if (!_rulesAndInfoWindow.IsAtFront())
|
||||
{
|
||||
_infoWindow.MoveToFront();
|
||||
_rulesAndInfoWindow.MoveToFront();
|
||||
_buttonInfo.Pressed = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
_infoWindow.Close();
|
||||
_rulesAndInfoWindow.Close();
|
||||
_buttonInfo.Pressed = false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_infoWindow.OpenCentered();
|
||||
_rulesAndInfoWindow.OpenCentered();
|
||||
_buttonInfo.Pressed = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,13 +15,14 @@ using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||
|
||||
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!;
|
||||
|
||||
private OptionsMenu optionsMenu;
|
||||
|
||||
public InfoWindow()
|
||||
public RulesAndInfoWindow()
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
|
||||
@@ -163,6 +164,13 @@ namespace Content.Client.Info
|
||||
optionsMenu.OpenCentered();
|
||||
}
|
||||
|
||||
protected override void Opened()
|
||||
{
|
||||
base.Opened();
|
||||
|
||||
_rulesManager.SaveLastReadTime();
|
||||
}
|
||||
|
||||
private static IEnumerable<string> Lines(TextReader reader)
|
||||
{
|
||||
while (true)
|
||||
55
Content.Client/Info/RulesManager.cs
Normal file
55
Content.Client/Info/RulesManager.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@ namespace Content.Client.Info
|
||||
var uriOpener = IoCManager.Resolve<IUriOpener>();
|
||||
|
||||
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") };
|
||||
discordButton.OnPressed += args => uriOpener.OpenUri(UILinks.Discord);
|
||||
|
||||
@@ -5,6 +5,7 @@ using Content.Client.Clickable;
|
||||
using Content.Client.EscapeMenu;
|
||||
using Content.Client.Eui;
|
||||
using Content.Client.HUD;
|
||||
using Content.Client.Info;
|
||||
using Content.Client.Items.Managers;
|
||||
using Content.Client.Module;
|
||||
using Content.Client.Parallax.Managers;
|
||||
@@ -44,6 +45,7 @@ namespace Content.Client.IoC
|
||||
IoCManager.Register<EuiManager, EuiManager>();
|
||||
IoCManager.Register<IVoteManager, VoteManager>();
|
||||
IoCManager.Register<ChangelogManager, ChangelogManager>();
|
||||
IoCManager.Register<RulesManager, RulesManager>();
|
||||
IoCManager.Register<ViewportManager, ViewportManager>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,7 +67,7 @@ namespace Content.Client.Preferences.UI
|
||||
|
||||
UpdateUI();
|
||||
|
||||
RulesButton.OnPressed += _ => new InfoWindow().Open();
|
||||
RulesButton.OnPressed += _ => new RulesAndInfoWindow().Open();
|
||||
preferencesManager.OnServerDataLoaded += UpdateUI;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,16 @@ namespace Content.Shared.CCVar
|
||||
[CVarDefs]
|
||||
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
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user