Skip to content

Commit

Permalink
Headless mode
Browse files Browse the repository at this point in the history
  • Loading branch information
LucHeart committed May 6, 2024
1 parent a17d4c4 commit 2a8cbd7
Show file tree
Hide file tree
Showing 14 changed files with 289 additions and 171 deletions.
9 changes: 9 additions & 0 deletions ShockOsc/Cli/CliOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using CommandLine;

namespace OpenShock.ShockOsc.Cli;

public sealed class CliOptions
{
[Option('h', "headless", Required = false, Default = false, HelpText = "Run the application in headless mode.")]
public bool Headless { get; set; }
}
24 changes: 24 additions & 0 deletions ShockOsc/HeadlessProgram.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
using Microsoft.Extensions.Hosting;

namespace OpenShock.ShockOsc;

public static class HeadlessProgram
{
public static IHost SetupHeadlessHost()
{
var builder = Host.CreateDefaultBuilder();
builder.ConfigureServices(services =>
{
services.AddShockOscServices();
#if WINDOWS
services.AddWindowsServices();
#endif
});

var app = builder.Build();
app.Services.StartShockOscServices(true);

return app;
}
}
145 changes: 12 additions & 133 deletions ShockOsc/MauiProgram.cs
Original file line number Diff line number Diff line change
@@ -1,40 +1,13 @@
#if WINDOWS
using System.Diagnostics;
using System.Net;
#if MAUI
using Microsoft.Maui.LifecycleEvents;
using MudBlazor.Services;
using OpenShock.SDK.CSharp.Hub;
using OpenShock.ShockOsc.Backend;
using OpenShock.ShockOsc.Config;
using OpenShock.ShockOsc.Logging;
using OpenShock.ShockOsc.OscQueryLibrary;
using OpenShock.ShockOsc.Services;
using OpenShock.ShockOsc.Utils;
using Serilog;
using MauiApp = OpenShock.ShockOsc.Ui.MauiApp;
using Rect = OpenShock.ShockOsc.Utils.Rect;


using Microsoft.UI;


#if M

#endif

namespace OpenShock.ShockOsc;

public static class MauiProgram
{
private const int WS_CAPTION = 0x00C00000;
private const int WS_BORDER = 0x00800000;
private const int WS_SYSMENU = 0x00080000;
private const int WS_SIZEBOX = 0x00040000;
private const int WS_MINIMIZEBOX = 0x00020000;
private const int WS_MAXIMIZEBOX = 0x00010000;
private const int WS_THICKFRAME = 0x00040000;


private static ShockOscConfig? _config;

public static Microsoft.Maui.Hosting.MauiApp CreateMauiApp()
Expand All @@ -43,96 +16,21 @@ public static Microsoft.Maui.Hosting.MauiApp CreateMauiApp()

// <---- Services ---->

var loggerConfiguration = new LoggerConfiguration()
.MinimumLevel.Information()
.Filter.ByExcluding(ev =>
ev.Exception is InvalidDataException a && a.Message.StartsWith("Invocation provides")).Filter
.ByExcluding(x => x.MessageTemplate.Text.StartsWith("Failed to find handler for"))
.MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Information)
.WriteTo.UiLogSink()
.WriteTo.Console(
outputTemplate: "[{Timestamp:HH:mm:ss} {Level:u3}] [{SourceContext}] {Message:lj}{NewLine}{Exception}");

// ReSharper disable once RedundantAssignment
var isDebug = Environment.GetCommandLineArgs()
.Any(x => x.Equals("--debug", StringComparison.InvariantCultureIgnoreCase));

#if DEBUG
isDebug = true;
#endif
if (isDebug)
{
Console.WriteLine("Debug mode enabled");
loggerConfiguration.MinimumLevel.Verbose();
}

Log.Logger = loggerConfiguration.CreateLogger();

builder.Services.AddSerilog(Log.Logger);

builder.Services.AddMemoryCache();

builder.Services.AddSingleton<ShockOscData>();

builder.Services.AddSingleton<ConfigManager>();

builder.Services.AddSingleton<Updater>();
builder.Services.AddSingleton<OscClient>();

builder.Services.AddSingleton<OpenShockApi>();
builder.Services.AddSingleton<OpenShockHubClient>();
builder.Services.AddSingleton<BackendHubManager>();

builder.Services.AddSingleton<LiveControlManager>();

builder.Services.AddSingleton<OscHandler>();

builder.Services.AddSingleton(provider =>
{
var config = provider.GetRequiredService<ConfigManager>();
var listenAddress = config.Config.Osc.QuestSupport ? IPAddress.Any : IPAddress.Loopback;
return new OscQueryServer("ShockOsc", listenAddress, config);
});

builder.Services.AddSingleton<Services.ShockOsc>();
builder.Services.AddSingleton<UnderscoreConfig>();

builder.Services.AddShockOscServices();

#if WINDOWS
builder.Services.AddWindowsServices();

builder.ConfigureLifecycleEvents(lifecycleBuilder =>
{
lifecycleBuilder.AddWindows(windowsLifecycleBuilder =>
{
windowsLifecycleBuilder.OnWindowCreated(window =>
{
//use Microsoft.UI.Windowing functions for window
var handle = WinRT.Interop.WindowNative.GetWindowHandle(window);
var id = Microsoft.UI.Win32Interop.GetWindowIdFromWindow(handle);
var id = Win32Interop.GetWindowIdFromWindow(handle);
var appWindow = Microsoft.UI.Windowing.AppWindow.GetFromWindowId(id);
// var style = WindowUtils.GetWindowLongPtrA(handle, (int)WindowLongFlags.GWL_STYLE);
//
// style &= ~WS_CAPTION; // Remove the title bar
// style |= WS_THICKFRAME; // Add thick frame for resizing
//
// WindowUtils.SetWindowLongPtrA(handle, (int)WindowLongFlags.GWL_STYLE, style);
//
// var reff = new Rect();
// WindowUtils.AdjustWindowRectEx(ref reff, style, false, 0);
// reff.top = 6000;
// reff.left *= -1;
//
// var margins = new Margins
// {
// cxLeftWidth = 0,
// cxRightWidth = 0,
// cyTopHeight = 0,
// cyBottomHeight = 0
// };
//
// WindowUtils.DwmExtendFrameIntoClientArea(handle, ref margins);
//
// WindowUtils.SetWindowPos(handle, 0, 0, 0, 0, 0x0040 | 0x0002 | 0x0001 | 0x0020);
//
//When user execute the closing method, we can push a display alert. If user click Yes, close this application, if click the cancel, display alert will dismiss.
appWindow.Closing += async (s, e) =>
{
Expand All @@ -155,39 +53,20 @@ public static Microsoft.Maui.Hosting.MauiApp CreateMauiApp()
});
});
});


builder.Services.AddSingleton<ITrayService, WindowsTrayService>();

builder.Services.AddSingleton<StatusHandler>();

builder.Services.AddMudServices();
builder.Services.AddMauiBlazorWebView();
#endif

// <---- App ---->

builder
.UseMauiApp<MauiApp>()
.ConfigureFonts(fonts => { fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular"); });


#if DEBUG
builder.Services.AddBlazorWebViewDeveloperTools();
#endif


var app = builder.Build();

_config = app.Services.GetRequiredService<ConfigManager>().Config;

app.Services.GetService<ITrayService>()?.Initialize();

// <---- Warmup ---->
app.Services.GetRequiredService<Services.ShockOsc>();
app.Services.GetRequiredService<OscQueryServer>().Start();

var updater = app.Services.GetRequiredService<Updater>();
OsTask.Run(updater.CheckUpdate);

app.Services.StartShockOscServices(false);

return app;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
namespace OpenShock.ShockOsc.Linux;
namespace OpenShock.ShockOsc.Platforms.Linux;
#if !WINDOWS
public static class LinuxApp
public static class LinuxEntryPoint
{
public static void Main(string[] args)
{
Expand Down
5 changes: 3 additions & 2 deletions ShockOsc/Platforms/Windows/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@

#if WINDOWS

// To learn more about WinUI, the WinUI project structure,
// and more about our project templates, see: http://aka.ms/winui-project-info.
#if WINDOWS

using Microsoft.Windows.AppLifecycle;
namespace OpenShock.ShockOsc.Platforms.Windows;

/// <summary>
Expand Down
56 changes: 56 additions & 0 deletions ShockOsc/Platforms/Windows/WindowsEntryPoint.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#if WINDOWS
using System.Runtime.InteropServices;
using CommandLine;
using Microsoft.Extensions.Hosting;
using Microsoft.UI.Dispatching;
using OpenShock.ShockOsc.Cli;
using OpenShock.ShockOsc.Services;
using OpenShock.ShockOsc.Utils;
using WinRT;
using Application = Microsoft.UI.Xaml.Application;

namespace OpenShock.ShockOsc.Platforms.Windows;

public static class WindowsEntryPoint
{
[DefaultDllImportSearchPaths(DllImportSearchPath.SafeDirectories)]
[DllImport("Microsoft.ui.xaml.dll")]
private static extern void XamlCheckProcessRequirements();

[STAThread]
private static void Main(string[] args)
{
var parsed = Parser.Default.ParseArguments<CliOptions>(args);
parsed.WithParsed(Start);
parsed.WithNotParsed(errors =>
{
errors.Output();
Environment.Exit(1);
});
}

private static void Start(CliOptions config)
{
if (config.Headless)
{
Console.WriteLine("Running in headless mode.");

var host = HeadlessProgram.SetupHeadlessHost();
OsTask.Run(host.Services.GetRequiredService<AuthService>().Authenticate);
host.Run();

return;
}

XamlCheckProcessRequirements();
ComWrappersSupport.InitializeComWrappers();
Application.Start(delegate
{
var context = new DispatcherQueueSynchronizationContext(DispatcherQueue.GetForCurrentThread());
SynchronizationContext.SetSynchronizationContext(context);
// ReSharper disable once ObjectCreationAsStatement
new App();
});
}
}
#endif
13 changes: 13 additions & 0 deletions ShockOsc/Platforms/Windows/WindowsServices.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#if WINDOWS
using OpenShock.ShockOsc.Services;

namespace OpenShock.ShockOsc;

public static class WindowsServices
{
public static void AddWindowsServices(this IServiceCollection services)
{
services.AddSingleton<ITrayService, WindowsTrayService>();
}
}
#endif
6 changes: 5 additions & 1 deletion ShockOsc/Platforms/Windows/WindowsTrayService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,14 @@ public void Initialize()
menu.Items.Add(new ToolStripSeparator());
menu.Items.Add("Restart", null, Restart);
menu.Items.Add("Quit ShockOSC", null, OnQuitClick);

tray.ContextMenuStrip = menu;

tray.Click += OnMainClick;
menu.Opened += async (sender, args) =>
{
var aa = menu;
};

tray.Visible = true;
}
Expand Down
7 changes: 6 additions & 1 deletion ShockOsc/Properties/launchSettings.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
{
"profiles": {
"Windows Machine": {
"ShockOsc": {
"commandName": "Project",
"nativeDebugging": false
},
"ShockOscHeadless": {
"commandName": "Project",
"nativeDebugging": false,
"commandLineArgs": "--headless"
}
}
}
36 changes: 36 additions & 0 deletions ShockOsc/Services/AuthService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using Microsoft.Extensions.Logging;
using OpenShock.SDK.CSharp.Hub;
using OpenShock.ShockOsc.Backend;

namespace OpenShock.ShockOsc.Services;

public sealed class AuthService
{
private readonly ILogger<AuthService> _logger;
private readonly BackendHubManager _backendHubManager;
private readonly OpenShockHubClient _hubClient;
private readonly LiveControlManager _liveControlManager;
private readonly OpenShockApi _apiClient;

public AuthService(ILogger<AuthService> logger, BackendHubManager backendHubManager, OpenShockHubClient hubClient, LiveControlManager liveControlManager, OpenShockApi apiClient)
{
_logger = logger;
_backendHubManager = backendHubManager;
_hubClient = hubClient;
_liveControlManager = liveControlManager;
_apiClient = apiClient;
}

public async Task Authenticate()
{
_logger.LogInformation("Setting up live client");
await _backendHubManager.SetupLiveClient();
_logger.LogInformation("Starting live client");
await _hubClient.StartAsync();

_logger.LogInformation("Refreshing shockers");
await _apiClient.RefreshShockers();

await _liveControlManager.RefreshConnections();
}
}
Loading

0 comments on commit 2a8cbd7

Please sign in to comment.