diff --git a/.github/workflows/build-installer.yml b/.github/workflows/build-installer.yml
index 1efa046..d1b71e5 100644
--- a/.github/workflows/build-installer.yml
+++ b/.github/workflows/build-installer.yml
@@ -38,7 +38,7 @@ jobs:
- name: Test
run: dotnet test --no-restore --verbosity normal Lanpartyseating.Desktop.Tests --configuration Release
- name: Build
- run: dotnet build LanpartySeating.Desktop.Installer/LanpartySeating.Desktop.Installer.wixproj --configuration Release --property:Version=1.0.21 /p:InstallerPlatform=${{ matrix.arch }}
+ run: dotnet build LanpartySeating.Desktop.Installer/LanpartySeating.Desktop.Installer.wixproj --configuration Release --property:Version=1.0.22 /p:InstallerPlatform=${{ matrix.arch }}
- name: Upload artifact
uses: actions/upload-artifact@v3
with:
diff --git a/LanpartySeating.Desktop.Installer/Lanpartyseating.Desktop.Installer.wxs b/LanpartySeating.Desktop.Installer/Lanpartyseating.Desktop.Installer.wxs
index d58f54d..764c795 100644
--- a/LanpartySeating.Desktop.Installer/Lanpartyseating.Desktop.Installer.wxs
+++ b/LanpartySeating.Desktop.Installer/Lanpartyseating.Desktop.Installer.wxs
@@ -35,26 +35,12 @@
-
+
-
-
-
-
-
-
+
+
+
+
diff --git a/Lanpartyseating.Desktop.Tests/UtilsTests.cs b/Lanpartyseating.Desktop.Tests/UtilsTests.cs
index 0f725b3..a452d96 100644
--- a/Lanpartyseating.Desktop.Tests/UtilsTests.cs
+++ b/Lanpartyseating.Desktop.Tests/UtilsTests.cs
@@ -1,11 +1,13 @@
using Lanpartyseating.Desktop.Business;
+using Lanpartyseating.Desktop.Config;
+using Microsoft.Extensions.Options;
namespace Lanpartyseating.Desktop.Tests;
public class UtilsTests
{
- private readonly Utils _utils = new();
-
+ private readonly Utils _utils = new(Options.Create(new DebugOptions()));
+
[Theory]
[InlineData("LAN-GAMING-01", 1, true)]
[InlineData("LAN-GAMING-01", 2, false)]
@@ -19,4 +21,23 @@ public void Test_When_ForThisStationCalled_Then_MatchingStationNumberAndHostname
// Assert
Assert.Equal(expectedResult, result);
}
+
+ [Theory]
+ [InlineData("LAN-GAMING-01", 1, true)]
+ [InlineData("LAN-GAMING-01", 2, true)]
+ [InlineData("LAN-GAMING-1", 1, true)]
+ [InlineData("LAN-GAMING-70", 70, true)]
+ public void Test_When_ForThisStationCalled_And_ReactToAllStationsEnabled_Then_ReturnTrue(string hostname, int stationNumber, bool expectedResult)
+ {
+ // Create servicecollection with debug options true
+ var utils = new Utils(Options.Create(new DebugOptions { ReactToAllStations = true }));
+
+ // Act
+ var result = utils.ForThisStation(stationNumber, hostname);
+
+ // Assert
+ Assert.Equal(expectedResult, result);
+ }
+
+
}
\ No newline at end of file
diff --git a/Lanpartyseating.Desktop.sln.DotSettings.user b/Lanpartyseating.Desktop.sln.DotSettings.user
index a612518..e107ede 100644
--- a/Lanpartyseating.Desktop.sln.DotSettings.user
+++ b/Lanpartyseating.Desktop.sln.DotSettings.user
@@ -1,11 +1,6 @@
- <SessionState ContinuousTestingMode="0" IsActive="True" Name="Test_When_ForThisStationCalled_Then_MatchingStationNumberAndHostnameReturnTrue" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
+ <SessionState ContinuousTestingMode="0" IsActive="True" Name="UtilsTests" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
<TestAncestor>
- <TestId>xUnit::8B549C98-F78C-422A-8C26-E1D7A0881CAD::net8.0-windows::Lanpartyseating.Desktop.Tests.UtilsTests.Test_When_ForThisStationCalled_Then_MatchingStationNumberAndHostnameReturnTrue</TestId>
- </TestAncestor>
-</SessionState>
- <SessionState ContinuousTestingMode="0" Name="Test_When_ForThisStationCalled_Then_MatchingStationNumberAndHostnameReturnTrue #2" xmlns="urn:schemas-jetbrains-com:jetbrains-ut-session">
- <TestAncestor>
- <TestId>xUnit::8B549C98-F78C-422A-8C26-E1D7A0881CAD::net8.0-windows::Lanpartyseating.Desktop.Tests.UtilsTests.Test_When_ForThisStationCalled_Then_MatchingStationNumberAndHostnameReturnTrue</TestId>
+ <TestId>xUnit::8B549C98-F78C-422A-8C26-E1D7A0881CAD::net8.0-windows::Lanpartyseating.Desktop.Tests.UtilsTests</TestId>
</TestAncestor>
</SessionState>
\ No newline at end of file
diff --git a/Lanpartyseating.Desktop/Business/Callbacks.cs b/Lanpartyseating.Desktop/Business/Callbacks.cs
index 9819aae..7cd6aaa 100644
--- a/Lanpartyseating.Desktop/Business/Callbacks.cs
+++ b/Lanpartyseating.Desktop/Business/Callbacks.cs
@@ -1,10 +1,5 @@
-using System.Diagnostics;
-using System.Runtime.InteropServices;
-using Lanpartyseating.Desktop.Config;
-using Lanpartyseating.Desktop.Contracts;
+using Lanpartyseating.Desktop.Contracts;
using Microsoft.Extensions.Logging;
-using Microsoft.Extensions.Options;
-using Microsoft.Win32;
using Message = Phoenix.Message;
namespace Lanpartyseating.Desktop.Business;
@@ -13,23 +8,28 @@ public class Callbacks
{
private readonly ILogger _logger;
private readonly Utils _utils;
- private readonly SeatingOptions _options;
+ private readonly ISessionManager _sessionManager;
+ private readonly Timekeeper _timekeeper;
- public Callbacks(ILogger logger, IOptions options, Utils utils)
+ public Callbacks(ILogger logger,
+ Utils utils,
+ ISessionManager sessionManager,
+ Timekeeper timekeeper)
{
_logger = logger;
_utils = utils;
- _options = options.Value;
+ _sessionManager = sessionManager;
+ _timekeeper = timekeeper;
}
public void NewReservation(Message payload)
{
- var payloadObject = payload.Payload.Unbox();
+ var newReservation = payload.Payload.Unbox();
- _logger.LogInformation($"New reservation created for station #{payloadObject.StationNumber}");
- if (!_utils.ForThisStation(payloadObject.StationNumber, Environment.MachineName)) return;
+ _logger.LogInformation($"New reservation created for station #{newReservation.StationNumber}");
+ if (!_utils.ForThisStation(newReservation.StationNumber, Environment.MachineName)) return;
- _utils.LoginInteractiveSession(_options.GamerAccountUsername, _options.GamerAccountPassword);
+ _timekeeper.StartSession(newReservation.Start, newReservation.End);
}
public void TournamentStart(Message payload)
@@ -39,7 +39,7 @@ public void TournamentStart(Message payload)
_logger.LogInformation($"Tournament started for station #{payloadObject.StationNumber}");
if (!_utils.ForThisStation(payloadObject.StationNumber, Environment.MachineName)) return;
- _utils.LoginInteractiveSession(_options.TournamentAccountUsername, _options.TournamentAccountPassword);
+ _sessionManager.SignInTournamentAccount();
}
public void CancelReservation(Message payload)
@@ -49,6 +49,16 @@ public void CancelReservation(Message payload)
_logger.LogInformation($"Reservation cancelled for station #{payloadObject.StationNumber}");
if (!_utils.ForThisStation(payloadObject.StationNumber, Environment.MachineName)) return;
- _utils.LogoffInteractiveSession();
+ _timekeeper.EndSession();
+ }
+
+ public void ExtendReservation(Message payload)
+ {
+ var extendReservation = payload.Payload.Unbox();
+
+ _logger.LogInformation($"Reservation extended for station #{extendReservation.StationNumber}");
+ if (!_utils.ForThisStation(extendReservation.StationNumber, Environment.MachineName)) return;
+
+ _timekeeper.ExtendSession(extendReservation.End);
}
}
\ No newline at end of file
diff --git a/Lanpartyseating.Desktop/Business/DummySessionManager.cs b/Lanpartyseating.Desktop/Business/DummySessionManager.cs
new file mode 100644
index 0000000..8102da6
--- /dev/null
+++ b/Lanpartyseating.Desktop/Business/DummySessionManager.cs
@@ -0,0 +1,29 @@
+using Microsoft.Extensions.Logging;
+
+namespace Lanpartyseating.Desktop.Business;
+
+public class DummySessionManager : ISessionManager
+{
+ private readonly ILogger _logger;
+
+ public DummySessionManager(ILogger logger)
+ {
+ _logger = logger;
+ _logger.LogInformation("The dummy session manager is in use");
+ }
+
+ public void SignInGamerAccount()
+ {
+ _logger.LogInformation("The client would have logged in an interactive session for the gamer account now");
+ }
+
+ public void SignInTournamentAccount()
+ {
+ _logger.LogInformation("The client would have logged in an interactive session for the tournament account now");
+ }
+
+ public void SignOut()
+ {
+ _logger.LogInformation("The client would have logged out an the current interactive session now");
+ }
+}
\ No newline at end of file
diff --git a/Lanpartyseating.Desktop/Business/ISessionManager.cs b/Lanpartyseating.Desktop/Business/ISessionManager.cs
new file mode 100644
index 0000000..f3ba091
--- /dev/null
+++ b/Lanpartyseating.Desktop/Business/ISessionManager.cs
@@ -0,0 +1,8 @@
+namespace Lanpartyseating.Desktop.Business;
+
+public interface ISessionManager
+{
+ public void SignInGamerAccount();
+ public void SignInTournamentAccount();
+ public void SignOut();
+}
\ No newline at end of file
diff --git a/Lanpartyseating.Desktop/Business/PhoenixChannelReactorService.cs b/Lanpartyseating.Desktop/Business/PhoenixChannelReactorService.cs
index 86d2bd1..8c4bdf6 100644
--- a/Lanpartyseating.Desktop/Business/PhoenixChannelReactorService.cs
+++ b/Lanpartyseating.Desktop/Business/PhoenixChannelReactorService.cs
@@ -20,6 +20,7 @@ public PhoenixChannelReactorService(IOptions options, Callbacks
_desktopChannel.On("new_reservation", callbacks.NewReservation);
_desktopChannel.On("cancel_reservation", callbacks.CancelReservation);
_desktopChannel.On("tournament_start", callbacks.TournamentStart);
+ _desktopChannel.On("extend_reservation", callbacks.ExtendReservation);
}
public void Connect()
diff --git a/Lanpartyseating.Desktop/Business/Timekeeper.cs b/Lanpartyseating.Desktop/Business/Timekeeper.cs
new file mode 100644
index 0000000..03ba27d
--- /dev/null
+++ b/Lanpartyseating.Desktop/Business/Timekeeper.cs
@@ -0,0 +1,99 @@
+using Microsoft.Extensions.Logging;
+
+namespace Lanpartyseating.Desktop.Business;
+
+using System;
+using System.Threading;
+
+public class Timekeeper : IDisposable
+{
+ private readonly ILogger _logger;
+ private readonly ISessionManager _sessionManager;
+ private Timer _timer;
+ private DateTimeOffset _sessionEndTime;
+ private readonly object _lock = new();
+
+ public Timekeeper(ILogger logger, ISessionManager sessionManager)
+ {
+ _logger = logger;
+ _sessionManager = sessionManager;
+ _timer = new Timer(SessionEnded, null, Timeout.Infinite, Timeout.Infinite);
+ }
+
+ public void StartSession(DateTimeOffset startTime, DateTimeOffset endTime)
+ {
+ lock (_lock)
+ {
+ if (endTime <= startTime)
+ {
+ throw new ArgumentException("End time must be later than start time.");
+ }
+
+ if (endTime <= DateTimeOffset.UtcNow)
+ {
+ throw new ArgumentException("End time must be in the future.");
+ }
+
+ _sessionEndTime = endTime;
+ var duration = endTime - DateTimeOffset.UtcNow;
+
+ // If the start time is in the future, delay the timer start
+ if (startTime > DateTimeOffset.UtcNow)
+ {
+ _timer.Change(startTime - DateTimeOffset.UtcNow, Timeout.InfiniteTimeSpan);
+ }
+ else
+ {
+ _timer.Change(duration, Timeout.InfiniteTimeSpan);
+ }
+
+ _logger.LogInformation($"Session started. Will end at {endTime}.");
+ _sessionManager.SignInGamerAccount();
+ }
+ }
+
+ public void ExtendSession(DateTimeOffset newEndTime)
+ {
+ lock (_lock)
+ {
+ if (newEndTime <= DateTimeOffset.UtcNow)
+ {
+ throw new ArgumentException("New end time must be in the future.");
+ }
+
+ if (newEndTime > _sessionEndTime)
+ {
+ _sessionEndTime = newEndTime;
+ var duration = newEndTime - DateTimeOffset.UtcNow;
+ _timer.Change(duration, Timeout.InfiniteTimeSpan);
+ _logger.LogInformation($"Session extended. New end time: {newEndTime}.");
+ }
+ else
+ {
+ _logger.LogInformation("New end time must be later than the current end time.");
+ }
+ }
+ }
+
+ public void EndSession()
+ {
+ lock (_lock)
+ {
+ _timer.Change(Timeout.InfiniteTimeSpan, Timeout.InfiniteTimeSpan);
+ _sessionEndTime = DateTimeOffset.MinValue;
+ _logger.LogInformation("Session forcibly ended.");
+ _sessionManager.SignOut();
+ }
+ }
+
+ private void SessionEnded(object state)
+ {
+ _logger.LogInformation("Session ended.");
+ _sessionManager.SignOut();
+ }
+
+ public void Dispose()
+ {
+ _timer?.Dispose();
+ }
+}
\ No newline at end of file
diff --git a/Lanpartyseating.Desktop/Business/Utils.cs b/Lanpartyseating.Desktop/Business/Utils.cs
index 687b002..d84978b 100644
--- a/Lanpartyseating.Desktop/Business/Utils.cs
+++ b/Lanpartyseating.Desktop/Business/Utils.cs
@@ -1,56 +1,29 @@
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
+using Lanpartyseating.Desktop.Config;
+using Microsoft.Extensions.Options;
using Microsoft.Win32;
namespace Lanpartyseating.Desktop.Business;
public class Utils
{
-
- [DllImport("wtsapi32.dll", SetLastError = true)]
- [return:MarshalAs(UnmanagedType.Bool)]
- private static extern bool WTSLogoffSession(IntPtr hServer, int sessionId, bool bWait);
+ private readonly IOptions _debugOptions;
- [DllImport("Kernel32.dll", SetLastError = true)]
- [return:MarshalAs(UnmanagedType.U4)]
- private static extern int WTSGetActiveConsoleSessionId();
-
- public void LoginInteractiveSession(string username, string password)
+ public Utils(IOptions debugOptions)
{
- var winlogonRegPath = @"Software\Microsoft\Windows NT\CurrentVersion\Winlogon";
-
- // Enable autologon
- Registry.SetValue($@"HKEY_LOCAL_MACHINE\{winlogonRegPath}", "AutoAdminLogon", 1, RegistryValueKind.DWord);
-
- // Don't autologon as soon as the session is logged out
- Registry.SetValue($@"HKEY_LOCAL_MACHINE\{winlogonRegPath}", "ForceAutoLogon", 0, RegistryValueKind.DWord);
-
- // Set autologon username
- Registry.SetValue($@"HKEY_LOCAL_MACHINE\{winlogonRegPath}", "DefaultUserName", username, RegistryValueKind.String);
-
- // Set autologon password
- Registry.SetValue($@"HKEY_LOCAL_MACHINE\{winlogonRegPath}", "DefaultPassword", password, RegistryValueKind.String);
-
- // Trigger autologon on next winlogon start
- Registry.LocalMachine.DeleteSubKeyTree($@"{winlogonRegPath}\AutoLogonChecked", false);
-
- // Kill winlogon
- var processes = Process.GetProcessesByName("winlogon");
- foreach (var process in processes)
- {
- process.Kill();
- }
+ _debugOptions = debugOptions;
}
- public void LogoffInteractiveSession()
- {
- var sessionId = WTSGetActiveConsoleSessionId();
- WTSLogoffSession(IntPtr.Zero, sessionId, false);
- }
public bool ForThisStation(int stationNumber, string hostname)
{
+ if (_debugOptions.Value.ReactToAllStations)
+ {
+ return true;
+ }
+
var regex = new Regex(@"^LAN-GAMING-(\d+)$");
var match = regex.Match(hostname);
if (!match.Success)
diff --git a/Lanpartyseating.Desktop/Business/WindowsSessionManager.cs b/Lanpartyseating.Desktop/Business/WindowsSessionManager.cs
new file mode 100644
index 0000000..1a4f7fb
--- /dev/null
+++ b/Lanpartyseating.Desktop/Business/WindowsSessionManager.cs
@@ -0,0 +1,72 @@
+using System.Diagnostics;
+using System.Runtime.InteropServices;
+using Lanpartyseating.Desktop.Config;
+using Microsoft.Extensions.Options;
+using Microsoft.Win32;
+
+namespace Lanpartyseating.Desktop.Business;
+
+public class WindowsSessionManager : ISessionManager
+{
+ private readonly SeatingOptions _options;
+
+ public WindowsSessionManager(IOptions options)
+ {
+ _options = options.Value;
+ }
+ public void SignInGamerAccount()
+ {
+ LoginInteractiveSession(_options.GamerAccountUsername, _options.GamerAccountPassword);
+ }
+
+ public void SignInTournamentAccount()
+ {
+ LoginInteractiveSession(_options.TournamentAccountUsername, _options.TournamentAccountPassword);
+ }
+
+ public void SignOut()
+ {
+ LogoffInteractiveSession();
+ }
+
+ [DllImport("wtsapi32.dll", SetLastError = true)]
+ [return:MarshalAs(UnmanagedType.Bool)]
+ private static extern bool WTSLogoffSession(IntPtr hServer, int sessionId, bool bWait);
+
+ [DllImport("Kernel32.dll", SetLastError = true)]
+ [return:MarshalAs(UnmanagedType.U4)]
+ private static extern int WTSGetActiveConsoleSessionId();
+
+ internal void LoginInteractiveSession(string username, string password)
+ {
+ var winlogonRegPath = @"Software\Microsoft\Windows NT\CurrentVersion\Winlogon";
+
+ // Enable autologon
+ Registry.SetValue($@"HKEY_LOCAL_MACHINE\{winlogonRegPath}", "AutoAdminLogon", 1, RegistryValueKind.DWord);
+
+ // Don't autologon as soon as the session is logged out
+ Registry.SetValue($@"HKEY_LOCAL_MACHINE\{winlogonRegPath}", "ForceAutoLogon", 0, RegistryValueKind.DWord);
+
+ // Set autologon username
+ Registry.SetValue($@"HKEY_LOCAL_MACHINE\{winlogonRegPath}", "DefaultUserName", username, RegistryValueKind.String);
+
+ // Set autologon password
+ Registry.SetValue($@"HKEY_LOCAL_MACHINE\{winlogonRegPath}", "DefaultPassword", password, RegistryValueKind.String);
+
+ // Trigger autologon on next winlogon start
+ Registry.LocalMachine.DeleteSubKeyTree($@"{winlogonRegPath}\AutoLogonChecked", false);
+
+ // Kill winlogon
+ var processes = Process.GetProcessesByName("winlogon");
+ foreach (var process in processes)
+ {
+ process.Kill();
+ }
+ }
+
+ internal void LogoffInteractiveSession()
+ {
+ var sessionId = WTSGetActiveConsoleSessionId();
+ WTSLogoffSession(IntPtr.Zero, sessionId, false);
+ }
+}
\ No newline at end of file
diff --git a/Lanpartyseating.Desktop/Config/DebugOptions.cs b/Lanpartyseating.Desktop/Config/DebugOptions.cs
new file mode 100644
index 0000000..d83e885
--- /dev/null
+++ b/Lanpartyseating.Desktop/Config/DebugOptions.cs
@@ -0,0 +1,7 @@
+namespace Lanpartyseating.Desktop.Config;
+
+public class DebugOptions
+{
+ public bool ReactToAllStations { get; set; }
+ public bool UseDummySessionManager { get; set; }
+}
\ No newline at end of file
diff --git a/Lanpartyseating.Desktop/Config/SeatingOptions.cs b/Lanpartyseating.Desktop/Config/SeatingOptions.cs
index 0d49e31..b2c4b32 100644
--- a/Lanpartyseating.Desktop/Config/SeatingOptions.cs
+++ b/Lanpartyseating.Desktop/Config/SeatingOptions.cs
@@ -1,10 +1,17 @@
-namespace Lanpartyseating.Desktop.Config;
+using System.ComponentModel.DataAnnotations;
+
+namespace Lanpartyseating.Desktop.Config;
public class SeatingOptions
{
- public string WebsocketEndpoint { get; set; }
- public string GamerAccountUsername { get; set; }
- public string GamerAccountPassword { get; set; }
- public string TournamentAccountUsername { get; set; }
- public string TournamentAccountPassword { get; set; }
+ [Required]
+ public required string WebsocketEndpoint { get; set; }
+ [Required]
+ public required string GamerAccountUsername { get; set; }
+ [Required(AllowEmptyStrings = true)]
+ public required string GamerAccountPassword { get; set; }
+ [Required]
+ public required string TournamentAccountUsername { get; set; }
+ [Required(AllowEmptyStrings = true)]
+ public required string TournamentAccountPassword { get; set; }
}
\ No newline at end of file
diff --git a/Lanpartyseating.Desktop/Contracts/ExtendReservation.cs b/Lanpartyseating.Desktop/Contracts/ExtendReservation.cs
new file mode 100644
index 0000000..1b781cd
--- /dev/null
+++ b/Lanpartyseating.Desktop/Contracts/ExtendReservation.cs
@@ -0,0 +1,13 @@
+using Newtonsoft.Json;
+
+namespace Lanpartyseating.Desktop.Contracts;
+
+public class ExtendReservation
+{
+ [JsonProperty("station_number")]
+ public int StationNumber { get; init; }
+ [JsonProperty("start_date")]
+ public DateTimeOffset Start { get; init; }
+ [JsonProperty("end_date")]
+ public DateTimeOffset End { get; init; }
+}
\ No newline at end of file
diff --git a/Lanpartyseating.Desktop/Contracts/NewReservation.cs b/Lanpartyseating.Desktop/Contracts/NewReservation.cs
index f4b55a8..a904fdb 100644
--- a/Lanpartyseating.Desktop/Contracts/NewReservation.cs
+++ b/Lanpartyseating.Desktop/Contracts/NewReservation.cs
@@ -6,4 +6,8 @@ public class NewReservation
{
[JsonProperty("station_number")]
public int StationNumber { get; init; }
+ [JsonProperty("start_date")]
+ public DateTimeOffset Start { get; init; }
+ [JsonProperty("end_date")]
+ public DateTimeOffset End { get; init; }
}
\ No newline at end of file
diff --git a/Lanpartyseating.Desktop/Lanpartyseating.Desktop.csproj b/Lanpartyseating.Desktop/Lanpartyseating.Desktop.csproj
index 6a4b6cb..c431dd6 100644
--- a/Lanpartyseating.Desktop/Lanpartyseating.Desktop.csproj
+++ b/Lanpartyseating.Desktop/Lanpartyseating.Desktop.csproj
@@ -10,6 +10,7 @@
+
@@ -19,7 +20,7 @@
-
+
Always
diff --git a/Lanpartyseating.Desktop/Program.cs b/Lanpartyseating.Desktop/Program.cs
index 898b0c7..66e36c6 100644
--- a/Lanpartyseating.Desktop/Program.cs
+++ b/Lanpartyseating.Desktop/Program.cs
@@ -4,6 +4,8 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Options;
+
namespace Lanpartyseating.Desktop;
[UsedImplicitly]
@@ -26,10 +28,22 @@ static void Main(string[] args)
options.ServiceName = "Lanparty Seating";
});
services.AddOptions()
+ .ValidateDataAnnotations()
.BindConfiguration("Seating");
+ services.AddOptions()
+ .BindConfiguration("Debug");
services.AddSingleton();
services.AddSingleton();
+ if (services.BuildServiceProvider().GetRequiredService>().Value.UseDummySessionManager)
+ {
+ services.AddSingleton();
+ }
+ else
+ {
+ services.AddSingleton();
+ }
services.AddSingleton();
+ services.AddSingleton();
services.AddHostedService();
})
.Build();
diff --git a/Lanpartyseating.Desktop/appsettings.Development.json b/Lanpartyseating.Desktop/appsettings.Development.json
index b62a5a6..31e0e5e 100644
--- a/Lanpartyseating.Desktop/appsettings.Development.json
+++ b/Lanpartyseating.Desktop/appsettings.Development.json
@@ -5,6 +5,10 @@
"Microsoft.Hosting.Lifetime": "Information"
}
},
+ "Debug": {
+ "ReactToAllStations": true,
+ "UseDummySessionManager": true
+ },
"Seating": {
"WebsocketEndpoint": "ws://localhost:4000/desktop",
"GamerAccountUsername": "gamer",
diff --git a/Lanpartyseating.Desktop/appsettings.json b/Lanpartyseating.Desktop/appsettings.Production.json
similarity index 100%
rename from Lanpartyseating.Desktop/appsettings.json
rename to Lanpartyseating.Desktop/appsettings.Production.json
diff --git a/README.md b/README.md
index 0402e53..35ede5b 100644
--- a/README.md
+++ b/README.md
@@ -13,7 +13,7 @@ Lanpartyseating.Desktop is designed to evolve over time.
## Features
-The core features planned for Lanpartyseating.Desktop include:
+The core features of Lanpartyseating.Desktop include:
1. **Automatic User Login/Logout:** The client will automatically log users in at the start of gaming sessions and log
them out at the end, simplifying the user experience and improving security.
@@ -34,15 +34,20 @@ executable or in the `C:\ProgramData\Lanparty Seating` directory.
The following settings are available:
-| Setting | Description |
-|------------------------------|----------------------------------------------------------------|
-| `Seating.WebsocketEndpoint` | The `lanparty-seating` WebSocket endpoint to connect to. |
-| `Seating.GamerUsername` | The username of the gamer account to use for automatic login. |
-| `Seating.GamerPassword` | The password of the gamer account to use for automatic login. |
-| `Seating.TournamentUsername` | The username of the tournament account to use for tournaments. |
-| `Seating.TournamentPassword` | The password of the tournament account to use for tournaments. |
+> [!WARNING]
+> The `Debug` settings should only be used to facilitate development of the software. Enabling them in production will cause the software to malfunction.
-An example configuration file can be found in the repo at `Lanpartyseating.Desktop/appsettings.json`.
+| Setting | Description |
+|-------------------------------------|--------------------------------------------------------------------------------------------------------------|
+| `Debug.ReactToAllStations` | Set to `true` to process stations events regardless of if they are destined for the current station. |
+| `Debug.UseDummySessionManager` | Set to `true` to simply log descriptive messages instead of logging in and out of windows sessions for real. |
+| `Seating.WebsocketEndpoint` | The `lanparty-seating` WebSocket endpoint to connect to. |
+| `Seating.GamerAccountUsername` | The username of the gamer account to use for automatic login. |
+| `Seating.GamerAccountPassword` | The password of the gamer account to use for automatic login. |
+| `Seating.TournamentAccountUsername` | The username of the tournament account to use for tournaments. |
+| `Seating.TournamentAccountPassword` | The password of the tournament account to use for tournaments. |
+
+An example configuration file can be found in the repo at `Lanpartyseating.Desktop/appsettings.Production.json`.
### Phoenix.Channel