mirror of
https://git.ryujinx.app/ryubing/ryujinx.git
synced 2025-08-11 12:47:51 +02:00

These changes allow players to matchmake for local wireless using a LDN server. The network implementation originates from Berry's public TCP RyuLDN fork. Logo and unrelated changes have been removed. Additionally displays LDN game status in the game selection window when RyuLDN is enabled. Functionality is only enabled while network mode is set to "RyuLDN" in the settings.
208 lines
6.6 KiB
C#
208 lines
6.6 KiB
C#
using Avalonia.Controls;
|
|
using Avalonia.Threading;
|
|
using FluentAvalonia.UI.Controls;
|
|
using Ryujinx.Ava.Common.Locale;
|
|
using Ryujinx.Ava.UI.Controls;
|
|
using Ryujinx.Ava.UI.Helpers;
|
|
using Ryujinx.Ava.UI.Windows;
|
|
using Ryujinx.HLE;
|
|
using Ryujinx.HLE.HOS.Applets;
|
|
using Ryujinx.HLE.HOS.Services.Am.AppletOE.ApplicationProxyService.ApplicationProxy.Types;
|
|
using Ryujinx.HLE.UI;
|
|
using Ryujinx.UI.Common.Configuration;
|
|
using System;
|
|
using System.Threading;
|
|
|
|
namespace Ryujinx.Ava.UI.Applet
|
|
{
|
|
internal class AvaHostUIHandler : IHostUIHandler
|
|
{
|
|
private readonly MainWindow _parent;
|
|
|
|
public IHostUITheme HostUITheme { get; }
|
|
|
|
public AvaHostUIHandler(MainWindow parent)
|
|
{
|
|
_parent = parent;
|
|
|
|
HostUITheme = new AvaloniaHostUITheme(parent);
|
|
}
|
|
|
|
public bool DisplayMessageDialog(ControllerAppletUIArgs args)
|
|
{
|
|
ManualResetEvent dialogCloseEvent = new(false);
|
|
|
|
bool okPressed = false;
|
|
|
|
if (ConfigurationState.Instance.IgnoreApplet)
|
|
return false;
|
|
|
|
Dispatcher.UIThread.InvokeAsync(async () =>
|
|
{
|
|
var response = await ControllerAppletDialog.ShowControllerAppletDialog(_parent, args);
|
|
if (response == UserResult.Ok)
|
|
{
|
|
okPressed = true;
|
|
}
|
|
|
|
dialogCloseEvent.Set();
|
|
});
|
|
|
|
dialogCloseEvent.WaitOne();
|
|
|
|
return okPressed;
|
|
}
|
|
|
|
public bool DisplayMessageDialog(string title, string message)
|
|
{
|
|
ManualResetEvent dialogCloseEvent = new(false);
|
|
|
|
bool okPressed = false;
|
|
|
|
Dispatcher.UIThread.InvokeAsync(async () =>
|
|
{
|
|
try
|
|
{
|
|
ManualResetEvent deferEvent = new(false);
|
|
|
|
bool opened = false;
|
|
|
|
UserResult response = await ContentDialogHelper.ShowDeferredContentDialog(_parent,
|
|
title,
|
|
message,
|
|
string.Empty,
|
|
LocaleManager.Instance[LocaleKeys.DialogOpenSettingsWindowLabel],
|
|
string.Empty,
|
|
LocaleManager.Instance[LocaleKeys.SettingsButtonClose],
|
|
(int)Symbol.Important,
|
|
deferEvent,
|
|
async window =>
|
|
{
|
|
if (opened)
|
|
{
|
|
return;
|
|
}
|
|
|
|
opened = true;
|
|
|
|
_parent.SettingsWindow = new SettingsWindow(_parent.VirtualFileSystem, _parent.ContentManager);
|
|
|
|
await _parent.SettingsWindow.ShowDialog(window);
|
|
|
|
_parent.SettingsWindow = null;
|
|
|
|
opened = false;
|
|
});
|
|
|
|
if (response == UserResult.Ok)
|
|
{
|
|
okPressed = true;
|
|
}
|
|
|
|
dialogCloseEvent.Set();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogMessageDialogErrorExceptionMessage, ex));
|
|
|
|
dialogCloseEvent.Set();
|
|
}
|
|
});
|
|
|
|
dialogCloseEvent.WaitOne();
|
|
|
|
return okPressed;
|
|
}
|
|
|
|
public bool DisplayInputDialog(SoftwareKeyboardUIArgs args, out string userText)
|
|
{
|
|
ManualResetEvent dialogCloseEvent = new(false);
|
|
|
|
bool okPressed = false;
|
|
bool error = false;
|
|
string inputText = args.InitialText ?? string.Empty;
|
|
|
|
Dispatcher.UIThread.InvokeAsync(async () =>
|
|
{
|
|
try
|
|
{
|
|
_parent.ViewModel.AppHost.NpadManager.BlockInputUpdates();
|
|
(UserResult result, string userInput) = await SwkbdAppletDialog.ShowInputDialog(LocaleManager.Instance[LocaleKeys.SoftwareKeyboard], args);
|
|
|
|
if (result == UserResult.Ok)
|
|
{
|
|
inputText = userInput;
|
|
okPressed = true;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
error = true;
|
|
|
|
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogSoftwareKeyboardErrorExceptionMessage, ex));
|
|
}
|
|
finally
|
|
{
|
|
dialogCloseEvent.Set();
|
|
}
|
|
});
|
|
|
|
dialogCloseEvent.WaitOne();
|
|
_parent.ViewModel.AppHost.NpadManager.UnblockInputUpdates();
|
|
|
|
userText = error ? null : inputText;
|
|
|
|
return error || okPressed;
|
|
}
|
|
|
|
public void ExecuteProgram(Switch device, ProgramSpecifyKind kind, ulong value)
|
|
{
|
|
device.Configuration.UserChannelPersistence.ExecuteProgram(kind, value);
|
|
_parent.ViewModel.AppHost?.Stop();
|
|
}
|
|
|
|
public bool DisplayErrorAppletDialog(string title, string message, string[] buttons)
|
|
{
|
|
ManualResetEvent dialogCloseEvent = new(false);
|
|
|
|
bool showDetails = false;
|
|
|
|
Dispatcher.UIThread.InvokeAsync(async () =>
|
|
{
|
|
try
|
|
{
|
|
ErrorAppletWindow msgDialog = new(_parent, buttons, message)
|
|
{
|
|
Title = title,
|
|
WindowStartupLocation = WindowStartupLocation.CenterScreen,
|
|
Width = 400
|
|
};
|
|
|
|
object response = await msgDialog.Run();
|
|
|
|
if (response != null && buttons is { Length: > 1 } && (int)response != buttons.Length - 1)
|
|
{
|
|
showDetails = true;
|
|
}
|
|
|
|
dialogCloseEvent.Set();
|
|
|
|
msgDialog.Close();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
dialogCloseEvent.Set();
|
|
|
|
await ContentDialogHelper.CreateErrorDialog(LocaleManager.Instance.UpdateAndGetDynamicValue(LocaleKeys.DialogErrorAppletErrorExceptionMessage, ex));
|
|
}
|
|
});
|
|
|
|
dialogCloseEvent.WaitOne();
|
|
|
|
return showDetails;
|
|
}
|
|
|
|
public IDynamicTextInputHandler CreateDynamicTextInputHandler() => new AvaloniaDynamicTextInputHandler(_parent);
|
|
}
|
|
}
|