Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions Content.Client/Info/AgeGate.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Control xmlns="https://spacestation14.io"
xmlns:parallax="clr-namespace:Content.Client.Parallax"
xmlns:info="clr-namespace:Content.Client.Info"
VerticalExpand="True" HorizontalExpand="True"
MouseFilter="Stop">
<parallax:ParallaxControl SpeedX="20"/>
<Control VerticalExpand="True"
MaxWidth="600"
MaxHeight="200">
<PanelContainer StyleClasses="windowPanel" />
<BoxContainer Orientation="Vertical" SeparationOverride="10" Margin="10 10 5 10" >
<Label Text="{Loc 'agegate-instructions'}" />

<BoxContainer Orientation="Horizontal" >
<LineEdit Name="DobDayLineEdit" PlaceHolder="{Loc 'datepicker-day'}" Margin="4 4" MinWidth="38" />
<OptionButton Name="DobMonthOptionButton" Margin="4 4" MinWidth="120" />
<LineEdit Name="DobYearLineEdit" PlaceHolder="{Loc 'datepicker-year'}" Margin="4 4" MinWidth="55" />
</BoxContainer>

<Control VerticalExpand="True" />

<Label Text="{Loc 'agegate-data-privacy'}" StyleClasses="WindowFooterText" />

<BoxContainer Orientation="Horizontal">
<Button Name="AcceptButton"
Disabled="True"
Text="Submit" />
<Button Name="QuitButton"
StyleClasses="Caution"
Text="{Loc 'ui-escape-quit'}" />
</BoxContainer>
</BoxContainer>
</Control>
</Control>
90 changes: 90 additions & 0 deletions Content.Client/Info/AgeGate.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
using Robust.Client.AutoGenerated;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;

namespace Content.Client.Info;

[GenerateTypedNameReferences]
public sealed partial class AgeGate : Control
{
public int MinimumAgeInYears = 18;

public event Action? OnQuitPressed;
public event Action? OnAgeGatePassed;
public event Action? OnAgeGateGated;

/// <summary>
/// The date currently selected by the input, or null if it's not a valid date.
/// </summary>
public DateTime? SelectedDate = null;

public AgeGate()
{
RobustXamlLoader.Load(this);

AcceptButton.OnPressed += OnAcceptButtonPressed;
QuitButton.OnPressed += OnQuitButtonPressed;

DobMonthOptionButton.AddItem(Loc.GetString("datepicker-month"), 0);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this entire DoB selector needs to be leapyear aware (yeaaaa i knowwwww.... time is a pain.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the issue with leapyears? I'm using DateTime which should be leapyear aware.

for (var i = 1; i <= 12; i++)
{
DobMonthOptionButton.AddItem(Loc.GetString($"month-{i}"), i);
}

DobDayLineEdit.OnTextChanged += _ => UpdateInput();
DobYearLineEdit.OnTextChanged += _ => UpdateInput();
DobMonthOptionButton.OnItemSelected += args => {
if (args.Id != 0)
{
DobMonthOptionButton.SelectId(args.Id);
}
UpdateInput();
};

}

private void UpdateInput()
{
var monthNum = DobMonthOptionButton.SelectedId;
if (uint.TryParse(DobYearLineEdit.Text, out uint year)
&& uint.TryParse(DobDayLineEdit.Text, out uint day)
&& monthNum != 0
&& DateTime.TryParse($"{year}-{monthNum:00}-{day:00}", null, System.Globalization.DateTimeStyles.RoundtripKind, out var date))
{
SelectedDate = date;
AcceptButton.Disabled = false;
}
else
{
SelectedDate = null;
AcceptButton.Disabled = true;
}
}

private void OnQuitButtonPressed(BaseButton.ButtonEventArgs obj)
{
OnQuitPressed?.Invoke();
}

private void OnAcceptButtonPressed(BaseButton.ButtonEventArgs obj)
{
if (SelectedDate is null)
return;

var today = DateTime.Today;
int yearDiff = today.Year - SelectedDate.Value.Year;
int age = SelectedDate.Value.Date > today.AddYears(-yearDiff)
? yearDiff - 1
: yearDiff;

if (age < MinimumAgeInYears)
{
OnAgeGateGated?.Invoke();
}
else
{
OnAgeGatePassed?.Invoke();
}
}
}
64 changes: 64 additions & 0 deletions Content.Client/UserInterface/Systems/Info/AgeGateUiController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
using Content.Client.Info;
using Content.Shared.Info;
using Robust.Client.Console;
using Robust.Client.UserInterface.Controllers;
using Robust.Client.UserInterface.Controls;
using Robust.Shared.Network;
using Robust.Shared.Prototypes;

namespace Content.Client.UserInterface.Systems.Info;

/// <summary>
/// This controller is responsible for showing the Age Gate UI when the client recieves the ShowAgeGateMessage,
/// and for sending the AgeGateSubmittedMessage when the player clicks the Submit button.
/// </summary>
public sealed class AgeGateUiController : UIController
{
[Dependency] private readonly IClientConsoleHost _consoleHost = default!;
[Dependency] private readonly INetManager _netManager = default!;
[Dependency] private readonly IPrototypeManager _prototype = default!;

private AgeGate? _ageGatePopup;

protected override string SawmillName => "age_gate";

public override void Initialize()
{
base.Initialize();

_netManager.RegisterNetMessage<ShowAgeGateMessage>(OnShowAgeGateMessage);
}

private void OnShowAgeGateMessage(ShowAgeGateMessage message)
{
_ageGatePopup = new AgeGate();

_ageGatePopup.OnAgeGatePassed += OnAgeGatePassed;
_ageGatePopup.OnAgeGateGated += OnAgeGateGated;
_ageGatePopup.OnQuitPressed += OnQuitPressed;

UIManager.WindowRoot.AddChild(_ageGatePopup);
LayoutContainer.SetAnchorPreset(_ageGatePopup, LayoutContainer.LayoutPreset.Wide);
}

private void OnQuitPressed()
{
_consoleHost.ExecuteCommand("quit");
}

private void OnAgeGatePassed()
{
_netManager.ClientSendMessage(new AgeGateSubmittedMessage { IsAboveRequiredAge = true });
_ageGatePopup?.Orphan();
_ageGatePopup = null;
}

private void OnAgeGateGated()
{
_netManager.ClientSendMessage(new AgeGateSubmittedMessage { IsAboveRequiredAge = false });
_ageGatePopup?.Orphan();
_ageGatePopup = null;

// Wait for the server to ban us...
}
}
1 change: 1 addition & 0 deletions Content.IntegrationTests/PoolManager.Cvars.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ private static readonly (string cvar, string value)[] TestCvars =
(CCVars.InteractionRateLimitCount.Name, "9999999"),
(CCVars.InteractionRateLimitPeriod.Name, "0.1"),
(CCVars.MovementMobPushing.Name, "false"),
(CCVars.PreJoinOrder.Name, ""),
};

public static async Task SetupCVars(RobustIntegrationTest.IntegrationInstance instance, PoolSettings settings)
Expand Down
Loading
Loading