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.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));
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)
|
||||||
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 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);
|
||||||
|
|||||||
@@ -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>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user