Skip to content

Commit

Permalink
Show version & add error popup
Browse files Browse the repository at this point in the history
  • Loading branch information
ButterscotchV committed Aug 6, 2024
1 parent 50ad2e3 commit 627ee5f
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 18 deletions.
51 changes: 48 additions & 3 deletions SlimeVrOta.Gui/MainWindow.axaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
Title="SlimeVR OTA Tool"
Icon="/Assets/icon.png"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterScreen"
Padding="8"
Background="{DynamicResource BackgroundBrush}">

Expand All @@ -15,20 +16,63 @@
<ResourceDictionary x:Key="Light">
<SolidColorBrush x:Key="BackgroundBrush">WhiteSmoke</SolidColorBrush>
<SolidColorBrush x:Key="MidgroundBrush">#e2d8eb</SolidColorBrush>
<SolidColorBrush x:Key="BorderBrush">#706080</SolidColorBrush>
<BoxShadows x:Key="BorderShadow">1 1 8 2 #c5c5c5</BoxShadows>
<SolidColorBrush x:Key="ProgressBrush">#d080ff</SolidColorBrush>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<SolidColorBrush x:Key="BackgroundBrush">#252525</SolidColorBrush>
<SolidColorBrush x:Key="MidgroundBrush">#383442</SolidColorBrush>
<SolidColorBrush x:Key="BorderBrush">#908892</SolidColorBrush>
<BoxShadows x:Key="BorderShadow">1 1 8 2 #161616</BoxShadows>
<SolidColorBrush x:Key="ProgressBrush">#a070d0</SolidColorBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>
</Window.Resources>

<StackPanel x:Name="Root" Spacing="4">
<StackPanel x:Name="Root">
<Popup WindowManagerAddShadowHint="False"
Placement="Bottom"
Name="ErrorPopup"
MinWidth="200"
MaxWidth="700"
MaxHeight="500">
<Border Padding="8"
CornerRadius="4"
BorderThickness="3"
BorderBrush="{DynamicResource BorderBrush}"
Background="{DynamicResource BackgroundBrush}"
HorizontalAlignment="Center"
VerticalAlignment="Center">
<Grid RowDefinitions="*,Auto">
<Border Grid.Row="0"
CornerRadius="4"
Background="{DynamicResource MidgroundBrush}"
VerticalAlignment="Stretch">
<ScrollViewer HorizontalScrollBarVisibility="Disabled"
AllowAutoHide="False">
<SelectableTextBlock Name="ErrorText"
TextWrapping="Wrap"
Padding="8"
SelectionBrush="{DynamicResource ProgressBrush}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
Unknown error.
</SelectableTextBlock>
</ScrollViewer>
</Border>
<Button Grid.Row="1"
Margin="0 8 0 0"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center"
Name="CloseErrorButton">
Close
</Button>
</Grid>
</Border>
</Popup>

<Border Padding="8"
CornerRadius="4"
BoxShadow="{DynamicResource BorderShadow}"
Expand All @@ -47,7 +91,7 @@
</Grid>
</Border>

<Border Margin="0 6 0 6"
<Border Margin="0 10 0 12"
Padding="8"
CornerRadius="4"
BoxShadow="{DynamicResource BorderShadow}"
Expand All @@ -69,7 +113,8 @@
</Grid>
</Border>

<TextBlock VerticalAlignment="Center"
<TextBlock Margin="0 0 0 4"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextTrimming="CharacterEllipsis"
Name="FlashStatusText">
Expand Down
89 changes: 74 additions & 15 deletions SlimeVrOta.Gui/MainWindow.axaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,28 +27,41 @@ public enum FlashState
Error
}

public FilePickerFileType ZipFileType =
public static readonly FilePickerFileType ZipFileType =
new("ZIP archive")
{
Patterns = ["*.zip"],
AppleUniformTypeIdentifiers = ["public.zip-archive"],
MimeTypes = ["application/zip", "x-zip-compressed"],
};

public FilePickerFileType BinFileType =
public static readonly FilePickerFileType BinFileType =
new("Firmware binary")
{
Patterns = ["*.bin"],
AppleUniformTypeIdentifiers = ["public.data"],
MimeTypes = ["application/octet-stream"],
};

public static readonly FilePickerFileType FirmwareFileType =
new("Firmware ZIP or binary")
{
Patterns = [.. ZipFileType.Patterns, .. BinFileType.Patterns],
AppleUniformTypeIdentifiers =
[
.. ZipFileType.AppleUniformTypeIdentifiers,
.. BinFileType.AppleUniformTypeIdentifiers
],
MimeTypes = [.. ZipFileType.MimeTypes, .. BinFileType.MimeTypes],
};

private IStorageFile? _firmwareFile;

private static readonly int _port = 6969;
private readonly byte[] _udpBuffer = new byte[65535];
private static readonly IPEndPoint _localEndPoint = new(IPAddress.Any, _port);

private bool _runDiscoveryOnClose = false;
private Socket? _socket;
private IPEndPoint _endPoint = new(IPAddress.Any, _port);

Expand All @@ -75,12 +88,11 @@ public MainWindow()
{
InitializeComponent();

CloseErrorButton.Click += CloseError;
FirmwareDropBox.AddHandler(DragDrop.DropEvent, SelectFirmwareDrop);
SelectFileButton.Click += SelectFirmwareBrowse;
RemoveTrackerButton.Click += RemoveTracker;
FlashButton.Click += FlashFirmware;

_ = ReceiveHandshake();
}

protected override void OnLoaded(RoutedEventArgs e)
Expand All @@ -90,8 +102,10 @@ protected override void OnLoaded(RoutedEventArgs e)
MinWidth = Width + 100;
MinHeight = Height;
MaxHeight = Height;

SizeToContent = SizeToContent.Manual;
Title = $"SlimeVR OTA Tool v{Constants.Version}";

_ = ReceiveHandshake();
}

protected override void OnClosed(EventArgs e)
Expand All @@ -102,6 +116,24 @@ protected override void OnClosed(EventArgs e)
_socket = null;
}

private void ShowError(string text)
{
ErrorText.Text = text;
ErrorPopup.IsOpen = true;
}

public void CloseError(object? sender, RoutedEventArgs e)
{
ErrorText.Text = "Unknown error.";
ErrorPopup.IsOpen = false;

if (_runDiscoveryOnClose && CurrentState == FlashState.Connecting)
{
_ = ReceiveHandshake(5000);
}
_runDiscoveryOnClose = false;
}

private void UpdateFileStatus()
{
if (CanAcceptFile)
Expand Down Expand Up @@ -163,7 +195,7 @@ public async void SelectFirmwareBrowse(object? sender, RoutedEventArgs e)
new FilePickerOpenOptions()
{
Title = "Select firmware file...",
FileTypeFilter = [ZipFileType, BinFileType],
FileTypeFilter = [FirmwareFileType],
AllowMultiple = false,
}
);
Expand All @@ -190,16 +222,42 @@ private void UpdateTrackerStatus()
}
}

public async Task ReceiveHandshake(CancellationToken cancelToken = default)
public async Task ReceiveHandshake(int delay = 0, CancellationToken cancelToken = default)
{
if (_socket == null)
if (delay > 0)
{
_socket = new Socket(
AddressFamily.InterNetwork,
SocketType.Dgram,
ProtocolType.Udp
);
_socket.Bind(_localEndPoint);
try
{
await Task.Delay(delay, cancelToken);
}
catch
{
if (cancelToken.IsCancellationRequested)
return;
}
}

if (_socket == null || _socket?.IsBound != true)
{
try
{
_socket?.Dispose();
_socket = new Socket(
AddressFamily.InterNetwork,
SocketType.Dgram,
ProtocolType.Udp
);
_socket.Bind(_localEndPoint);
}
catch (Exception ex)
{
Debug.WriteLine(ex);
_runDiscoveryOnClose = true;
ShowError(
$"Error while binding socket, make sure SlimeVR isn't running and port {_port} is not in use!\n\n{ex}"
);
return;
}
}

while (!cancelToken.IsCancellationRequested && _socket.IsBound)
Expand Down Expand Up @@ -366,7 +424,7 @@ public async void FlashFirmware(object? sender, RoutedEventArgs e)
CurrentState = FlashState.Waiting;

using var cancelSrc = new CancellationTokenSource();
var handshake = ReceiveHandshake(cancelSrc.Token);
var handshake = ReceiveHandshake(cancelToken: cancelSrc.Token);
// 45 second timeout, it should not take that long
cancelSrc.CancelAfter(45000);

Expand Down Expand Up @@ -398,6 +456,7 @@ public async void FlashFirmware(object? sender, RoutedEventArgs e)
catch (Exception ex)
{
Debug.WriteLine(ex);
ShowError(ex.ToString());
CurrentState = FlashState.Error;
}
}
Expand Down
7 changes: 7 additions & 0 deletions SlimeVrOta/Constants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace SlimeVrOta
{
public static class Constants
{
public static readonly string Version = "0.3.0";
}
}
2 changes: 2 additions & 0 deletions SlimeVrOta/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

try
{
Console.WriteLine($"SlimeVR OTA Tool v{Constants.Version}");

var file = new FileInfo("firmware-part-0.bin");
if (!file.Exists)
{
Expand Down

0 comments on commit 627ee5f

Please sign in to comment.