Track rule reading in database, don't show popup locally (#7278)

This commit is contained in:
DrSmugleaf
2022-03-26 20:16:57 +01:00
committed by GitHub
parent 19d8824951
commit ca0fb3c6a2
13 changed files with 2302 additions and 53 deletions

View File

@@ -2,8 +2,6 @@ using Content.Client.EscapeMenu.UI;
using Robust.Client.ResourceManagement;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.CustomControls;
using Robust.Shared.IoC;
using Robust.Shared.Localization;
namespace Content.Client.Info
{
@@ -62,12 +60,5 @@ namespace Content.Client.Info
info.InfoContainer.AddChild(new InfoSection(title,
_resourceManager.ContentFileReadAllText($"/Server Info/{path}"), markup));
}
protected override void Opened()
{
base.Opened();
_rulesManager.SaveLastReadTime();
}
}
}

View File

@@ -1,5 +1,3 @@
using System;
using System.Globalization;
using Content.Client.Lobby;
using Content.Client.Viewport;
using Content.Shared.CCVar;
@@ -8,28 +6,33 @@ using Robust.Client.Console;
using Robust.Client.State;
using Robust.Client.UserInterface;
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 : SharedRulesManager
{
[Dependency] private readonly IResourceManager _resource = default!;
[Dependency] private readonly IConfigurationManager _configManager = default!;
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
[Dependency] private readonly IStateManager _stateManager = default!;
[Dependency] private readonly IClientConsoleHost _consoleHost = default!;
[Dependency] private readonly INetManager _netManager = default!;
private bool _shouldShowRules;
public void Initialize()
{
_netManager.RegisterNetMessage<ShouldShowRulesPopupMessage>(OnShouldShowRules);
_netManager.RegisterNetMessage<ShowRulesPopupMessage>(OnShowRulesPopupMessage);
_netManager.RegisterNetMessage<RulesAcceptedMessage>();
_stateManager.OnStateChanged += OnStateChanged;
}
private void OnShouldShowRules(ShouldShowRulesPopupMessage message)
{
_shouldShowRules = true;
}
private void OnShowRulesPopupMessage(ShowRulesPopupMessage message)
{
ShowRules(message.PopupTime);
@@ -39,32 +42,15 @@ public sealed class RulesManager : SharedRulesManager
{
if (args.NewState is not (GameScreen or LobbyState))
return;
_stateManager.OnStateChanged -= OnStateChanged;
var path = new ResourcePath($"/rules_last_seen_{_configManager.GetCVar(CCVars.ServerId)}");
var showRules = true;
if (_resource.UserData.TryReadAllText(path, out var lastReadTimeText)
&& DateTime.TryParse(lastReadTimeText, null, DateTimeStyles.AssumeUniversal, out var lastReadTime))
showRules = lastReadTime < DateTime.UtcNow - TimeSpan.FromDays(60);
else
SaveLastReadTime();
if (!showRules)
if (!_shouldShowRules)
return;
_shouldShowRules = false;
ShowRules(_configManager.GetCVar(CCVars.RulesWaitTime));
}
/// <summary>
/// Ran when the user opens ("read") the rules, stores the new ID to disk.
/// </summary>
public void SaveLastReadTime()
{
using var sw = _resource.UserData.OpenWriteText(new ResourcePath($"/rules_last_seen_{_configManager.GetCVar(CCVars.ServerId)}"));
sw.Write(DateTime.UtcNow.ToUniversalTime());
}
private void ShowRules(float time)
{
var rulesPopup = new RulesPopup
@@ -83,6 +69,7 @@ public sealed class RulesManager : SharedRulesManager
private void OnAcceptPressed()
{
SaveLastReadTime();
var message = _netManager.CreateNetMessage<RulesAcceptedMessage>();
_netManager.ClientSendMessage(message);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
#nullable disable
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Content.Server.Database.Migrations.Postgres
{
public partial class PlayerReadRules : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "last_read_rules",
table: "player",
type: "timestamp with time zone",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "last_read_rules",
table: "player");
}
}
}

View File

@@ -387,6 +387,10 @@ namespace Content.Server.Database.Migrations.Postgres
.HasColumnType("timestamp with time zone")
.HasColumnName("first_seen_time");
b.Property<DateTime?>("LastReadRules")
.HasColumnType("timestamp with time zone")
.HasColumnName("last_read_rules");
b.Property<IPAddress>("LastSeenAddress")
.IsRequired()
.HasColumnType("inet")

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,26 @@
#nullable disable
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace Content.Server.Database.Migrations.Sqlite
{
public partial class PlayerReadRules : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<DateTime>(
name: "last_read_rules",
table: "player",
type: "TEXT",
nullable: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "last_read_rules",
table: "player");
}
}
}

View File

@@ -355,6 +355,10 @@ namespace Content.Server.Database.Migrations.Sqlite
.HasColumnType("TEXT")
.HasColumnName("first_seen_time");
b.Property<DateTime?>("LastReadRules")
.HasColumnType("TEXT")
.HasColumnName("last_read_rules");
b.Property<string>("LastSeenAddress")
.IsRequired()
.HasColumnType("TEXT")

View File

@@ -249,6 +249,8 @@ namespace Content.Server.Database
// Data that changes with each round
public List<Round> Rounds { get; set; } = null!;
public List<AdminLogPlayer> AdminLogs { get; set; } = null!;
public DateTime? LastReadRules { get; set; }
}
[Table("whitelist")]

View File

@@ -1,5 +1,3 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Linq;
using System.Net;
@@ -10,13 +8,9 @@ using Content.Server.Administration.Logs;
using Content.Shared.Administration.Logs;
using Content.Shared.CharacterAppearance;
using Content.Shared.Preferences;
using Content.Shared.Species;
using Microsoft.EntityFrameworkCore;
using Robust.Shared.Enums;
using Robust.Shared.IoC;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;
using Robust.Shared.Utility;
namespace Content.Server.Database
@@ -774,6 +768,30 @@ namespace Content.Server.Database
await db.DbContext.SaveChangesAsync();
}
public async Task<DateTime?> GetLastReadRules(NetUserId player)
{
await using var db = await GetDb();
return await db.DbContext.Player
.Where(dbPlayer => dbPlayer.UserId == player)
.Select(dbPlayer => dbPlayer.LastReadRules)
.SingleOrDefaultAsync();
}
public async Task SetLastReadRules(NetUserId player, DateTime date)
{
await using var db = await GetDb();
var dbPlayer = await db.DbContext.Player.Where(dbPlayer => dbPlayer.UserId == player).SingleOrDefaultAsync();
if (dbPlayer == null)
{
return;
}
dbPlayer.LastReadRules = date;
await db.DbContext.SaveChangesAsync();
}
#endregion
#region Uploaded Resources Logs

View File

@@ -1,6 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Collections.Immutable;
using System.IO;
using System.Net;
using System.Text.Json;
@@ -16,9 +14,6 @@ using Microsoft.Extensions.Logging;
using Npgsql;
using Robust.Shared.Configuration;
using Robust.Shared.ContentPack;
using Robust.Shared.IoC;
using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.Network;
using LogLevel = Robust.Shared.Log.LogLevel;
using MSLogLevel = Microsoft.Extensions.Logging.LogLevel;
@@ -193,6 +188,13 @@ namespace Content.Server.Database
Task PurgeUploadedResourceLogAsync(int days);
#endregion
#region Rules
Task<DateTime?> GetLastReadRules(NetUserId player);
Task SetLastReadRules(NetUserId player, DateTime time);
#endregion
}
public sealed class ServerDbManager : IServerDbManager
@@ -473,6 +475,16 @@ namespace Content.Server.Database
return _db.PurgeUploadedResourceLogAsync(days);
}
public Task<DateTime?> GetLastReadRules(NetUserId player)
{
return _db.GetLastReadRules(player);
}
public Task SetLastReadRules(NetUserId player, DateTime time)
{
return _db.SetLastReadRules(player, time);
}
private DbContextOptions<PostgresServerDbContext> CreatePostgresOptions()
{
var host = _cfg.GetCVar(CCVars.DatabasePgHost);

View File

@@ -1,15 +1,45 @@
using Content.Shared.Info;
using Robust.Shared.IoC;
using System.Net;
using Content.Server.Database;
using Content.Shared.Info;
using Robust.Shared.Network;
namespace Content.Server.Info;
public sealed class RulesManager : SharedRulesManager
{
[Dependency] private readonly IServerDbManager _dbManager = default!;
[Dependency] private readonly INetManager _netManager = default!;
private static DateTime LastValidReadTime => DateTime.UtcNow - TimeSpan.FromDays(60);
public void Initialize()
{
_netManager.RegisterNetMessage<ShouldShowRulesPopupMessage>();
_netManager.RegisterNetMessage<ShowRulesPopupMessage>();
_netManager.RegisterNetMessage<RulesAcceptedMessage>(OnRulesAccepted);
_netManager.Connected += OnConnected;
}
private async void OnConnected(object? sender, NetChannelArgs e)
{
if (IPAddress.IsLoopback(e.Channel.RemoteEndPoint.Address))
{
return;
}
var lastRead = await _dbManager.GetLastReadRules(e.Channel.UserId);
if (lastRead > LastValidReadTime)
{
return;
}
var message = _netManager.CreateNetMessage<ShouldShowRulesPopupMessage>();
_netManager.ServerSendMessage(message, e.Channel);
}
private async void OnRulesAccepted(RulesAcceptedMessage message)
{
var date = DateTime.UtcNow;
await _dbManager.SetLastReadRules(message.MsgChannel.UserId, date);
}
}

View File

@@ -1,12 +1,13 @@
using JetBrains.Annotations;
using Lidgren.Network;
using Lidgren.Network;
using Robust.Shared.Network;
namespace Content.Shared.Info;
public abstract class SharedRulesManager
{
[UsedImplicitly]
/// <summary>
/// Sent by the server to show the rules to the client instantly.
/// </summary>
public sealed class ShowRulesPopupMessage : NetMessage
{
public override MsgGroups MsgGroup => MsgGroups.Command;
@@ -23,4 +24,36 @@ public abstract class SharedRulesManager
buffer.Write(PopupTime);
}
}
/// <summary>
/// Sent by the server when the client needs to display the rules on join.
/// </summary>
public sealed class ShouldShowRulesPopupMessage : NetMessage
{
public override MsgGroups MsgGroup => MsgGroups.Command;
public override void ReadFromBuffer(NetIncomingMessage buffer)
{
}
public override void WriteToBuffer(NetOutgoingMessage buffer)
{
}
}
/// <summary>
/// Sent by the client when it has accepted the rules.
/// </summary>
public sealed class RulesAcceptedMessage : NetMessage
{
public override MsgGroups MsgGroup => MsgGroups.Command;
public override void ReadFromBuffer(NetIncomingMessage buffer)
{
}
public override void WriteToBuffer(NetOutgoingMessage buffer)
{
}
}
}