Skip to content

Commit

Permalink
Complete rewrite in avalonia, uses nativeaot for compiling the binary.
Browse files Browse the repository at this point in the history
  • Loading branch information
SylveonDeko committed Oct 20, 2024
1 parent 30a6e7b commit fb1f815
Show file tree
Hide file tree
Showing 37 changed files with 1,270 additions and 4,704 deletions.
4 changes: 3 additions & 1 deletion PresenceClient/PresenceClient-CLI/ConsoleOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,10 @@ public class ConsoleOptions

[Value(0, MetaName = "IP", Required = true, HelpText = "The IP address of your device")]
public string Ip { get; set; }

public IPAddress ParsedIp { get; set; }

[Value(1, MetaName = "Client ID", Required = true, HelpText = "The Client ID of your Discord Rich Presence application")]
[Value(1, MetaName = "Client ID", Required = true,
HelpText = "The Client ID of your Discord Rich Presence application")]
public ulong ClientId { get; set; }
}
29 changes: 15 additions & 14 deletions PresenceClient/PresenceClient-CLI/PresenceClient-CLI.csproj
Original file line number Diff line number Diff line change
@@ -1,20 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<RootNamespace>PresenceClient_CLI</RootNamespace>
<ApplicationIcon>Icon.ico</ApplicationIcon>
<LangVersion>latestmajor</LangVersion>
</PropertyGroup>
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<RootNamespace>PresenceClient_CLI</RootNamespace>
<ApplicationIcon>Icon.ico</ApplicationIcon>
<LangVersion>latestmajor</LangVersion>
<PublishAot>true</PublishAot>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.9.1" />
<PackageReference Include="DiscordRichPresence" Version="1.0.175" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.9.1"/>
<PackageReference Include="DiscordRichPresence" Version="1.2.1.24"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\PresenceCommon\PresenceCommon.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\PresenceCommon\PresenceCommon.csproj"/>
</ItemGroup>

</Project>
150 changes: 83 additions & 67 deletions PresenceClient/PresenceClient-CLI/Program.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
using System;
using System.Net;
using System.Net.Sockets;
using System.Timers;
using System.Threading;
using System.Threading.Tasks;
using CommandLine;
using DiscordRPC;
using PresenceCommon;
Expand All @@ -11,29 +12,33 @@ namespace PresenceClient_CLI;

internal class Program
{
private static Timer _timer;
private static Socket _client;
private static string _lastProgramName = string.Empty;
private static Timestamps _time;
private static DiscordRpcClient _rpc;
private static ConsoleOptions _arguments;
private static CancellationTokenSource _cts;

private static int Main(string[] args)
private static async Task<int> Main(string[] args)
{
AppDomain.CurrentDomain.ProcessExit += CurrentDomain_ProcessExit;
Parser.Default.ParseArguments<ConsoleOptions>(args)
.WithParsed(arguments =>
{
if (!IPAddress.TryParse(arguments.Ip, out var iPAddress))
{
Console.WriteLine("Invalid IP");
Environment.Exit(1);
}
arguments.ParsedIp = iPAddress;
_rpc = new DiscordRpcClient(arguments.ClientId.ToString());
_arguments = arguments;
})
.WithNotParsed(_ => Environment.Exit(1));
_cts = new CancellationTokenSource();

var parseResult = Parser.Default.ParseArguments<ConsoleOptions>(args);
if (parseResult.Tag == ParserResultType.NotParsed)
{
return 1;
}

_arguments = ((Parsed<ConsoleOptions>)parseResult).Value;
if (!IPAddress.TryParse(_arguments.Ip, out var iPAddress))
{
Console.WriteLine("Invalid IP");
return 1;
}

_arguments.ParsedIp = iPAddress;
_rpc = new DiscordRpcClient(_arguments.ClientId.ToString());

if (!_rpc.Initialize())
{
Expand All @@ -43,55 +48,61 @@ private static int Main(string[] args)

var localEndPoint = new IPEndPoint(_arguments.ParsedIp, 0xCAFE);

_timer = new Timer
{
Interval = 15000,
Enabled = false,
};
_timer.Elapsed += OnConnectTimeout;

while (true)
while (!_cts.Token.IsCancellationRequested)
{
_client = new Socket(SocketType.Stream, ProtocolType.Tcp)
{
ReceiveTimeout = 5500,
SendTimeout = 5500
};

_timer.Enabled = true;

try
{
var result = _client.BeginConnect(localEndPoint, null, null);
var success = result.AsyncWaitHandle.WaitOne(2000, true);
if (!success)
{
//UpdateStatus("Could not connect to Server! Retrying...", Color.DarkRed);
_client.Close();
}
else
using (_client = new Socket(SocketType.Stream, ProtocolType.Tcp))
{
_client.EndConnect(result);
_timer.Enabled = false;
_client.ReceiveTimeout = 5500;
_client.SendTimeout = 5500;

DataListen();
await ConnectWithTimeoutAsync(_client, localEndPoint, TimeSpan.FromSeconds(2));
await DataListenAsync();
}
}
catch (SocketException)
catch (OperationCanceledException)
{
// Cancellation was requested
break;
}
catch (Exception ex)
{
_client.Close();
if (_rpc != null && !_rpc.IsDisposed) _rpc.ClearPresence();
Console.WriteLine($"Error: {ex.Message}");
if (_rpc is { IsDisposed: false })
{
_rpc.ClearPresence();
}
await Task.Delay(5000, _cts.Token);
}
}

return 0;
}

private static async Task ConnectWithTimeoutAsync(Socket client, EndPoint endpoint, TimeSpan timeout)
{
using var timeoutCts = new CancellationTokenSource(timeout);
using var combinedCts = CancellationTokenSource.CreateLinkedTokenSource(timeoutCts.Token, _cts.Token);

try
{
await client.ConnectAsync(endpoint, combinedCts.Token);
Console.WriteLine("Connected to server.");
}
catch (OperationCanceledException) when (timeoutCts.IsCancellationRequested)
{
throw new TimeoutException("Connection attempt timed out.");
}
}

private static void DataListen()
private static async Task DataListenAsync()
{
while (true)
while (!_cts.Token.IsCancellationRequested)
{
try
{
var bytes = Utils.ReceiveExactly(_client);
var bytes = await Utils.ReceiveExactlyAsync(_client, cancellationToken: _cts.Token);

var title = new Title(bytes);
if (title.Magic == 0xffaadd23)
Expand All @@ -101,7 +112,11 @@ private static void DataListen()
_time = Timestamps.Now;
}

if (_rpc is not { CurrentPresence: null } && _lastProgramName == title.Name) continue;
if (_rpc is not { CurrentPresence: null } && _lastProgramName == title.Name)
{
continue;
}

if (_arguments.IgnoreHomeScreen && title.Name == "Home Menu")
{
_rpc.ClearPresence();
Expand All @@ -114,32 +129,33 @@ private static void DataListen()
}
else
{
if (_rpc != null && !_rpc.IsDisposed) _rpc.ClearPresence();
_client.Close();
return;
if (_rpc is { IsDisposed: false })
{
_rpc.ClearPresence();
}
break;
}
}
catch (OperationCanceledException)
{
// Cancellation was requested
break;
}
catch (SocketException)
{
if (_rpc != null && !_rpc.IsDisposed) _rpc.ClearPresence();
_client.Close();
return;
if (_rpc is { IsDisposed: false })
{
_rpc.ClearPresence();
}
break;
}
}
}

private static void OnConnectTimeout(object sender, ElapsedEventArgs e)
{
_lastProgramName = string.Empty;
_time = null;
}

private static void CurrentDomain_ProcessExit(object sender, EventArgs e)
{
if (_client != null && _client.Connected)
_client.Close();

if(_rpc != null && !_rpc.IsDisposed)
_rpc.Dispose();
_cts.Cancel();
_client?.Close();
_rpc?.Dispose();
}
}
23 changes: 23 additions & 0 deletions PresenceClient/PresenceClient-GUI/App.axaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="PresenceClient.App"
RequestedThemeVariant="Default">
<Application.Styles>
<Style Selector="Button.accent">
<Setter Property="Background" Value="#FF6200EE"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="CornerRadius" Value="4"/>
</Style>
</Application.Styles>

<Application.Styles>
<FluentTheme />
</Application.Styles>

<Application.Resources>
<SolidColorBrush x:Key="PrimaryBackgroundColor">#FFFFFF</SolidColorBrush>
<SolidColorBrush x:Key="PrimaryForegroundColor">#000000</SolidColorBrush>
<SolidColorBrush x:Key="AccentColor">#0078D7</SolidColorBrush>
</Application.Resources>
</Application>
29 changes: 29 additions & 0 deletions PresenceClient/PresenceClient-GUI/App.axaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using PresenceClient.Views;
using PresenceClient.ViewModels;

namespace PresenceClient;

public class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
}

public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
{
var mainWindow = new MainWindow
{
DataContext = new MainWindowViewModel(),
};
desktop.MainWindow = mainWindow;
}

base.OnFrameworkInitializationCompleted();
}
}
14 changes: 0 additions & 14 deletions PresenceClient/PresenceClient-GUI/App.config

This file was deleted.

7 changes: 0 additions & 7 deletions PresenceClient/PresenceClient-GUI/Config.cs

This file was deleted.

3 changes: 0 additions & 3 deletions PresenceClient/PresenceClient-GUI/FodyWeavers.xml

This file was deleted.

Loading

0 comments on commit fb1f815

Please sign in to comment.