TESTERS WANTED: RyuLDN implementation (#65)

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.
This commit is contained in:
Vudjun
2024-11-11 22:06:50 +00:00
committed by GitHub
parent abfcfcaf0f
commit 6d8738c048
93 changed files with 4100 additions and 189 deletions

View File

@ -9,6 +9,8 @@ using Ryujinx.HLE.HOS.Ipc;
using Ryujinx.HLE.HOS.Kernel.Threading;
using Ryujinx.HLE.HOS.Services.Ldn.Types;
using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnMitm;
using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.LdnRyu;
using Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator.Types;
using Ryujinx.Horizon.Common;
using Ryujinx.Memory;
using System;
@ -21,6 +23,9 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
{
class IUserLocalCommunicationService : IpcService, IDisposable
{
public static string DefaultLanPlayHost = "ryuldn.vudjun.com";
public static short LanPlayPort = 30456;
public INetworkClient NetworkClient { get; private set; }
private const int NifmRequestID = 90;
@ -175,19 +180,37 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
if (_state == NetworkState.AccessPointCreated || _state == NetworkState.StationConnected)
{
(_, UnicastIPAddressInformation unicastAddress) = NetworkHelpers.GetLocalInterface(context.Device.Configuration.MultiplayerLanInterfaceId);
if (unicastAddress == null)
ProxyConfig config = _state switch
{
context.ResponseData.Write(NetworkHelpers.ConvertIpv4Address(DefaultIPAddress));
context.ResponseData.Write(NetworkHelpers.ConvertIpv4Address(DefaultSubnetMask));
NetworkState.AccessPointCreated => _accessPoint.Config,
NetworkState.StationConnected => _station.Config,
_ => default
};
if (config.ProxyIp == 0)
{
(_, UnicastIPAddressInformation unicastAddress) = NetworkHelpers.GetLocalInterface(context.Device.Configuration.MultiplayerLanInterfaceId);
if (unicastAddress == null)
{
context.ResponseData.Write(NetworkHelpers.ConvertIpv4Address(DefaultIPAddress));
context.ResponseData.Write(NetworkHelpers.ConvertIpv4Address(DefaultSubnetMask));
}
else
{
Logger.Info?.Print(LogClass.ServiceLdn, $"Console's LDN IP is \"{unicastAddress.Address}\".");
context.ResponseData.Write(NetworkHelpers.ConvertIpv4Address(unicastAddress.Address));
context.ResponseData.Write(NetworkHelpers.ConvertIpv4Address(unicastAddress.IPv4Mask));
}
}
else
{
Logger.Info?.Print(LogClass.ServiceLdn, $"Console's LDN IP is \"{unicastAddress.Address}\".");
Logger.Info?.Print(LogClass.ServiceLdn, $"LDN obtained proxy IP.");
context.ResponseData.Write(NetworkHelpers.ConvertIpv4Address(unicastAddress.Address));
context.ResponseData.Write(NetworkHelpers.ConvertIpv4Address(unicastAddress.IPv4Mask));
context.ResponseData.Write(config.ProxyIp);
context.ResponseData.Write(config.ProxySubnetMask);
}
}
else
@ -1066,6 +1089,27 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
switch (mode)
{
case MultiplayerMode.LdnRyu:
try
{
string ldnServer = context.Device.Configuration.MultiplayerLdnServer;
if (string.IsNullOrEmpty(ldnServer))
{
ldnServer = DefaultLanPlayHost;
}
if (!IPAddress.TryParse(ldnServer, out IPAddress ipAddress))
{
ipAddress = Dns.GetHostEntry(ldnServer).AddressList[0];
}
NetworkClient = new LdnMasterProxyClient(ipAddress.ToString(), LanPlayPort, context.Device.Configuration);
}
catch (Exception ex)
{
Logger.Error?.Print(LogClass.ServiceLdn, "Could not locate LdnRyu server. Defaulting to stubbed wireless.");
Logger.Error?.Print(LogClass.ServiceLdn, ex.Message);
NetworkClient = new LdnDisabledClient();
}
break;
case MultiplayerMode.LdnMitm:
NetworkClient = new LdnMitmClient(context.Device.Configuration);
break;
@ -1103,7 +1147,7 @@ namespace Ryujinx.HLE.HOS.Services.Ldn.UserServiceCreator
_accessPoint?.Dispose();
_accessPoint = null;
NetworkClient?.Dispose();
NetworkClient?.DisconnectAndStop();
NetworkClient = null;
}
}