Skip to content

Commit

Permalink
impl
Browse files Browse the repository at this point in the history
  • Loading branch information
JerryImMouse committed Aug 13, 2024
1 parent dba0ea7 commit cbecb59
Show file tree
Hide file tree
Showing 14 changed files with 436 additions and 1 deletion.
5 changes: 5 additions & 0 deletions Content.Client/Entry/EntryPoint.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Client._Jerry.DiscordAuth;
using Content.Client.Administration.Managers;
using Content.Client.Changelog;
using Content.Client.Chat.Managers;
Expand Down Expand Up @@ -72,6 +73,8 @@ public sealed class EntryPoint : GameClient
[Dependency] private readonly ContentReplayPlaybackManager _replayMan = default!;
[Dependency] private readonly DebugMonitorManager _debugMonitorManager = default!;

[Dependency] private readonly DiscordAuthManager _discordAuthManager = default!;

public override void Init()
{
ClientContentIoC.Register();
Expand Down Expand Up @@ -131,6 +134,8 @@ public override void Init()
_jobRequirements.Initialize();
_playbackMan.Initialize();

_discordAuthManager.Initialize();

//AUTOSCALING default Setup!
_configManager.SetCVar("interface.resolutionAutoScaleUpperCutoffX", 1080);
_configManager.SetCVar("interface.resolutionAutoScaleUpperCutoffY", 720);
Expand Down
2 changes: 2 additions & 0 deletions Content.Client/IoC/ClientContentIoC.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
using Content.Client._Jerry.DiscordAuth;
using Content.Client.Administration.Managers;
using Content.Client.Changelog;
using Content.Client.Chat.Managers;
Expand Down Expand Up @@ -51,6 +52,7 @@ public static void Register()
collection.Register<ISharedPlaytimeManager, JobRequirementsManager>();
collection.Register<MappingManager>();
collection.Register<DebugMonitorManager>();
collection.Register<DiscordAuthManager>(); // Jerry-Auth
}
}
}
24 changes: 24 additions & 0 deletions Content.Client/_Jerry/DiscordAuth/DiscordAuthManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Content.Shared._Jerry.DiscordAuth;
using Robust.Client.State;
using Robust.Shared.Network;

namespace Content.Client._Jerry.DiscordAuth;

public sealed class DiscordAuthManager
{
[Dependency] private readonly INetManager _net = default!;
[Dependency] private readonly IStateManager _state = default!;

public string AuthLink = default!;

public void Initialize()
{
_net.RegisterNetMessage<MsgDiscordAuthRequired>(OnDiscordAuthRequired);
}

public void OnDiscordAuthRequired(MsgDiscordAuthRequired args)
{
AuthLink = args.Link;
_state.RequestStateChange<DiscordAuthState>();
}
}
38 changes: 38 additions & 0 deletions Content.Client/_Jerry/DiscordAuth/DiscordAuthState.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System.Threading;
using Content.Client._Jerry.DiscordAuth.DiscordGui;
using Content.Shared._Jerry.DiscordAuth;
using Robust.Client.State;
using Robust.Client.UserInterface;
using Robust.Shared.Network;
using Timer = Robust.Shared.Timing.Timer;

namespace Content.Client._Jerry.DiscordAuth;

public sealed class DiscordAuthState : State
{
[Dependency] private readonly IUserInterfaceManager _userInterfaceManager = default!;
[Dependency] private readonly IClientNetManager _netManager = default!;

private DiscordAuthGui _gui = default!;

private readonly CancellationTokenSource _checkTimerCancel = new();

protected override void Startup()
{
_gui = new DiscordAuthGui();
_userInterfaceManager.StateRoot.AddChild(_gui);

Timer.SpawnRepeating(TimeSpan.FromSeconds(5),
() =>
{
_netManager.ClientSendMessage(new MsgDiscordAuthCheck());
},
_checkTimerCancel.Token);
}

protected override void Shutdown()
{
_userInterfaceManager.StateRoot.RemoveChild(_gui);
_checkTimerCancel.Cancel();
}
}
22 changes: 22 additions & 0 deletions Content.Client/_Jerry/DiscordAuth/DiscordGui/DiscordAuthGui.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<Control xmlns="https://spacestation14.io"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:parallax="clr-namespace:Content.Client.Parallax"
xmlns:controls="clr-namespace:Content.Client.UserInterface.Controls">
<parallax:ParallaxControl />
<Control HorizontalAlignment="Center" VerticalAlignment="Center">
<PanelContainer StyleClasses="AngleRect" />
<BoxContainer Orientation="Vertical">
<BoxContainer Orientation="Horizontal">
<Label Margin="8 0 0 0" Text="{Loc 'stalker-discord-auth-title'}"
StyleClasses="LabelHeading" VAlign="Center" />
<Button Name="QuitButton" Text="{Loc 'stalker-discord-auth-quit-btn'}"
HorizontalAlignment="Right" HorizontalExpand="True" />
</BoxContainer>
<controls:HighDivider />
<BoxContainer Orientation="Vertical" Margin="50 20 50 20">
<Label Text="{Loc 'stalker-discord-info'}" Align="Center" />
</BoxContainer>
<Button Name="AuthorizeButton" Text="Authorize" HorizontalExpand="True" StyleClasses="OpenRight" />
</BoxContainer>
</Control>
</Control>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using Robust.Client.AutoGenerated;
using Robust.Client.Console;
using Robust.Client.UserInterface;
using Robust.Client.UserInterface.Controls;
using Robust.Client.UserInterface.XAML;

namespace Content.Client._Jerry.DiscordAuth.DiscordGui;

[GenerateTypedNameReferences]
public sealed partial class DiscordAuthGui : Control
{
[Dependency] private readonly IClientConsoleHost _consoleHost = default!;
[Dependency] private readonly DiscordAuthManager _discordAuthManager = default!;

public DiscordAuthGui()
{
RobustXamlLoader.Load(this);
IoCManager.InjectDependencies(this);
LayoutContainer.SetAnchorPreset(this, LayoutContainer.LayoutPreset.Wide);

var link = _discordAuthManager.AuthLink;

QuitButton.OnPressed += _ =>
{
_consoleHost.ExecuteCommand("quit");
};

AuthorizeButton.OnPressed += _ =>
{
IoCManager.Resolve<IUriOpener>().OpenUri(link);
};
}
}
4 changes: 4 additions & 0 deletions Content.Server/Entry/EntryPoint.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Content.Server._Jerry;
using Content.Server._Jerry.Sponsors;
using Content.Server.Acz;
using Content.Server.Administration;
using Content.Server.Administration.Logs;
Expand Down Expand Up @@ -105,6 +107,8 @@ public override void Init()
IoCManager.Resolve<GhostKickManager>().Initialize();
IoCManager.Resolve<ServerInfoManager>().Initialize();
IoCManager.Resolve<ServerApi>().Initialize();
IoCManager.Resolve<DiscordAuthManager>().Initialize();
IoCManager.Resolve<SponsorsManager>().Initialize();

_voteManager.Initialize();
_updateManager.Initialize();
Expand Down
2 changes: 1 addition & 1 deletion Content.Server/GameTicking/GameTicker.Player.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private async void PlayerStatusChanged(object? sender, SessionStatusEventArgs ar

// Make the player actually join the game.
// timer time must be > tick length
Timer.Spawn(0, () => _playerManager.JoinGame(args.Session));
// Timer.Spawn(0, () => _playerManager.JoinGame(args.Session));

var record = await _dbManager.GetPlayerRecordByUserId(args.Session.UserId);
var firstConnection = record != null &&
Expand Down
5 changes: 5 additions & 0 deletions Content.Server/IoC/ServerContentIoC.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
using Content.Server._Jerry;
using Content.Server._Jerry.Sponsors;
using Content.Server.Administration;
using Content.Server.Administration.Logs;
using Content.Server.Administration.Managers;
Expand Down Expand Up @@ -68,6 +70,9 @@ public static void Register()
IoCManager.Register<JobWhitelistManager>();
IoCManager.Register<PlayerRateLimitManager>();
IoCManager.Register<MappingManager>();

IoCManager.Register<DiscordAuthManager>();
IoCManager.Register<SponsorsManager>();
}
}
}
20 changes: 20 additions & 0 deletions Content.Server/_Jerry/CCCVars/CCCVars.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
using Robust.Shared.Configuration;

namespace Content.Server._Jerry.CCCVars;
[CVarDefs]
public static class CCCVars
{
/*
* Discord OAuth2
*/

public static readonly CVarDef<string> DiscordApiUrl =
CVarDef.Create("jerry.discord_api_url", "http://127.0.0.1:2424/api", CVar.CONFIDENTIAL | CVar.SERVERONLY);

/*
* Sponsors
*/

public static readonly CVarDef<string> DiscordGuildID =
CVarDef.Create("jerry.discord_guildId", "1126278315364339712", CVar.CONFIDENTIAL | CVar.SERVERONLY);
}
121 changes: 121 additions & 0 deletions Content.Server/_Jerry/Discord/DiscordAuthManager.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
using System.Net;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading;
using System.Threading.Tasks;
using Content.Shared._Jerry.DiscordAuth;
using Lidgren.Network;
using Robust.Server.Player;
using Robust.Shared.Configuration;
using Robust.Shared.Enums;
using Robust.Shared.Network;
using Robust.Shared.Player;
using Robust.Shared.Serialization;
using Timer = Robust.Shared.Timing.Timer;

namespace Content.Server._Jerry;

public sealed class DiscordAuthManager : IPostInjectInit
{
[Dependency] private INetManager _net = default!;
[Dependency] private readonly IPlayerManager _playerManager = default!;
[Dependency] private readonly IConfigurationManager _configuration = default!;

private ISawmill _sawmill = default!;

private string _apiUrl = default!;
private string _apiKey = default!;

private readonly HttpClient _httpClient = new();
private readonly Dictionary<NetUserId, DiscordUserData> _cachedDiscordUsers = new();
public event EventHandler<ICommonSession>? PlayerVerified;

public void PostInject()
{
IoCManager.InjectDependencies(this);
}

public void Initialize()
{
_configuration.OnValueChanged(CCCVars.CCCVars.DiscordApiUrl, (value) => _apiUrl = value, true);

_sawmill = Logger.GetSawmill("discord_auth");
_net.RegisterNetMessage<MsgDiscordAuthRequired>();
_net.RegisterNetMessage<MsgDiscordAuthCheck>(OnAuthCheck);
_net.Disconnect += OnDisconnect;
_playerManager.PlayerStatusChanged += OnPlayerStatusChanged;

PlayerVerified += OnPlayerVerified;
}

private void OnPlayerVerified(object? sender, ICommonSession e)
{
Timer.Spawn(0, () => _playerManager.JoinGame(e));
}

private void OnDisconnect(object? sender, NetDisconnectedArgs e)
{
_cachedDiscordUsers.Remove(e.Channel.UserId);
}

private async void OnAuthCheck(MsgDiscordAuthCheck msg)
{
var data = await IsVerified(msg.MsgChannel.UserId);
if (data is null)
return;

var session = _playerManager.GetSessionById(msg.MsgChannel.UserId);
_cachedDiscordUsers.TryAdd(session.UserId, data);
PlayerVerified?.Invoke(this, session);
}

private async void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs args)
{
if (args.NewStatus != SessionStatus.Connected)
return;

var data = await IsVerified(args.Session.UserId);
if (data is not null)
{
_cachedDiscordUsers.TryAdd(args.Session.UserId, data);
PlayerVerified?.Invoke(this, args.Session);
return;
}

var link = await GenerateLink(args.Session.UserId);
var message = new MsgDiscordAuthRequired() {Link = link};
args.Session.Channel.SendMessage(message);
}

public async Task<DiscordUserData?> IsVerified(NetUserId userId, CancellationToken cancel = default)
{
_sawmill.Debug($"Player {userId} check Discord verification");

var requestUrl = $"{_apiUrl}/check?userid={userId}";
var response = await _httpClient.GetAsync(requestUrl, cancel);
if (!response.IsSuccessStatusCode)
return null;
var discordData = await response.Content.ReadFromJsonAsync<DiscordUserData>(cancel);
return discordData;
}

public async Task<string> GenerateLink(NetUserId userId, CancellationToken cancel = default)
{
_sawmill.Debug($"Generating link for {userId}");
var requestUrl = $"{_apiUrl}/link?userid={userId}";
var response = await _httpClient.GetAsync(requestUrl, cancel);
var link = await response.Content.ReadFromJsonAsync<DiscordLinkResponse>(cancel);
return link!.Link;
}
}

public sealed class DiscordUserData()
{
public NetUserId UserId { get; set; }
public string DiscordId { get; set; } = default!;
}

public sealed class DiscordLinkResponse()
{
public string Link { get; set; } = default!;
}
Loading

0 comments on commit cbecb59

Please sign in to comment.