diff --git a/Ryujinx.HLE/HLEConfiguration.cs b/Ryujinx.HLE/HLEConfiguration.cs
index bba21435b..70706f0f6 100644
--- a/Ryujinx.HLE/HLEConfiguration.cs
+++ b/Ryujinx.HLE/HLEConfiguration.cs
@@ -98,6 +98,11 @@ namespace Ryujinx.HLE
///
internal readonly bool EnablePtc;
+ ///
+ /// Control if the guest application should be told that there is a Internet connection available.
+ ///
+ internal readonly bool EnableInternetAccess;
+
///
/// Control LibHac's integrity check level.
///
@@ -122,8 +127,8 @@ namespace Ryujinx.HLE
/// This cannot be changed after instantiation.
internal readonly string TimeZone;
-
///
+ /// Type of the memory manager used on CPU emulation.
///
public MemoryManagerMode MemoryManagerMode { internal get; set; }
@@ -163,6 +168,7 @@ namespace Ryujinx.HLE
bool enableVsync,
bool enableDockedMode,
bool enablePtc,
+ bool enableInternetAccess,
IntegrityCheckLevel fsIntegrityCheckLevel,
int fsGlobalAccessLogMode,
long systemTimeOffset,
@@ -186,6 +192,7 @@ namespace Ryujinx.HLE
EnableVsync = enableVsync;
EnableDockedMode = enableDockedMode;
EnablePtc = enablePtc;
+ EnableInternetAccess = enableInternetAccess;
FsIntegrityCheckLevel = fsIntegrityCheckLevel;
FsGlobalAccessLogMode = fsGlobalAccessLogMode;
SystemTimeOffset = systemTimeOffset;
diff --git a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs
index a1c40aebc..7a3fdabd0 100644
--- a/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs
+++ b/Ryujinx.HLE/HOS/Services/Nifm/StaticService/IRequest.cs
@@ -8,6 +8,13 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
{
class IRequest : IpcService
{
+ private enum RequestState
+ {
+ Error = 1,
+ OnHold = 2,
+ Available = 3
+ }
+
private KEvent _event0;
private KEvent _event1;
@@ -28,7 +35,11 @@ namespace Ryujinx.HLE.HOS.Services.Nifm.StaticService
// GetRequestState() -> u32
public ResultCode GetRequestState(ServiceCtx context)
{
- context.ResponseData.Write(1);
+ RequestState requestState = context.Device.Configuration.EnableInternetAccess
+ ? RequestState.Available
+ : RequestState.Error;
+
+ context.ResponseData.Write((int)requestState);
Logger.Stub?.PrintStub(LogClass.ServiceNifm);
diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs
index 355ef8647..43c7ee7d9 100644
--- a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs
+++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/IClient.cs
@@ -106,7 +106,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
_isPrivileged = isPrivileged;
}
- private LinuxError ConvertError(WsaError errorCode)
+ private static LinuxError ConvertError(WsaError errorCode)
{
if (!_errorMap.TryGetValue(errorCode, out LinuxError errno))
{
@@ -116,6 +116,56 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
return errno;
}
+ private static SocketFlags ConvertBsdSocketFlags(BsdSocketFlags bsdSocketFlags)
+ {
+ BsdSocketFlags SupportedFlags =
+ BsdSocketFlags.Oob |
+ BsdSocketFlags.Peek |
+ BsdSocketFlags.DontRoute |
+ BsdSocketFlags.Trunc |
+ BsdSocketFlags.CTrunc;
+
+ SocketFlags socketFlags = SocketFlags.None;
+
+ if (bsdSocketFlags.HasFlag(BsdSocketFlags.Oob))
+ {
+ socketFlags |= SocketFlags.OutOfBand;
+ }
+
+ if (bsdSocketFlags.HasFlag(BsdSocketFlags.Peek))
+ {
+ socketFlags |= SocketFlags.Peek;
+ }
+
+ if (bsdSocketFlags.HasFlag(BsdSocketFlags.DontRoute))
+ {
+ socketFlags |= SocketFlags.DontRoute;
+ }
+
+ if (bsdSocketFlags.HasFlag(BsdSocketFlags.Trunc))
+ {
+ socketFlags |= SocketFlags.Truncated;
+ }
+
+ if (bsdSocketFlags.HasFlag(BsdSocketFlags.CTrunc))
+ {
+ socketFlags |= SocketFlags.ControlDataTruncated;
+ }
+
+ bsdSocketFlags &= ~(BsdSocketFlags.Oob |
+ BsdSocketFlags.Peek |
+ BsdSocketFlags.DontRoute |
+ BsdSocketFlags.Trunc |
+ BsdSocketFlags.CTrunc);
+
+ if (bsdSocketFlags != BsdSocketFlags.None)
+ {
+ Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported socket flags: {bsdSocketFlags}");
+ }
+
+ return socketFlags;
+ }
+
private ResultCode WriteWinSock2Error(ServiceCtx context, WsaError errorCode)
{
return WriteBsdResult(context, -1, ConvertError(errorCode));
@@ -463,8 +513,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
// Recv(u32 socket, u32 flags) -> (i32 ret, u32 bsd_errno, array message)
public ResultCode Recv(ServiceCtx context)
{
- int socketFd = context.RequestData.ReadInt32();
- SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32();
+ int socketFd = context.RequestData.ReadInt32();
+ BsdSocketFlags socketFlags = (BsdSocketFlags)context.RequestData.ReadInt32();
(ulong receivePosition, ulong receiveLength) = context.Request.GetBufferType0x22();
@@ -474,18 +524,11 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
if (socket != null)
{
- if (socketFlags != SocketFlags.None && (socketFlags & SocketFlags.OutOfBand) == 0
- && (socketFlags & SocketFlags.Peek) == 0)
- {
- Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported Recv flags: {socketFlags}");
- return WriteBsdResult(context, -1, LinuxError.EOPNOTSUPP);
- }
-
byte[] receivedBuffer = new byte[receiveLength];
try
{
- result = socket.Handle.Receive(receivedBuffer, socketFlags);
+ result = socket.Handle.Receive(receivedBuffer, ConvertBsdSocketFlags(socketFlags));
errno = SetResultErrno(socket.Handle, result);
context.Memory.Write(receivePosition, receivedBuffer);
@@ -503,8 +546,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
// RecvFrom(u32 sock, u32 flags) -> (i32 ret, u32 bsd_errno, u32 addrlen, buffer message, buffer)
public ResultCode RecvFrom(ServiceCtx context)
{
- int socketFd = context.RequestData.ReadInt32();
- SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32();
+ int socketFd = context.RequestData.ReadInt32();
+ BsdSocketFlags socketFlags = (BsdSocketFlags)context.RequestData.ReadInt32();
(ulong receivePosition, ulong receiveLength) = context.Request.GetBufferType0x22();
(ulong sockAddrOutPosition, ulong sockAddrOutSize) = context.Request.GetBufferType0x22(1);
@@ -515,20 +558,12 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
if (socket != null)
{
- if (socketFlags != SocketFlags.None && (socketFlags & SocketFlags.OutOfBand) == 0
- && (socketFlags & SocketFlags.Peek) == 0)
- {
- Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported Recv flags: {socketFlags}");
-
- return WriteBsdResult(context, -1, LinuxError.EOPNOTSUPP);
- }
-
byte[] receivedBuffer = new byte[receiveLength];
EndPoint endPoint = new IPEndPoint(IPAddress.Any, 0);
try
{
- result = socket.Handle.ReceiveFrom(receivedBuffer, receivedBuffer.Length, socketFlags, ref endPoint);
+ result = socket.Handle.ReceiveFrom(receivedBuffer, receivedBuffer.Length, ConvertBsdSocketFlags(socketFlags), ref endPoint);
errno = SetResultErrno(socket.Handle, result);
context.Memory.Write(receivePosition, receivedBuffer);
@@ -547,8 +582,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
// Send(u32 socket, u32 flags, buffer) -> (i32 ret, u32 bsd_errno)
public ResultCode Send(ServiceCtx context)
{
- int socketFd = context.RequestData.ReadInt32();
- SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32();
+ int socketFd = context.RequestData.ReadInt32();
+ BsdSocketFlags socketFlags = (BsdSocketFlags)context.RequestData.ReadInt32();
(ulong sendPosition, ulong sendSize) = context.Request.GetBufferType0x21();
@@ -558,21 +593,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
if (socket != null)
{
- if (socketFlags != SocketFlags.None && socketFlags != SocketFlags.OutOfBand
- && socketFlags != SocketFlags.Peek && socketFlags != SocketFlags.DontRoute)
- {
- Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported Send flags: {socketFlags}");
-
- return WriteBsdResult(context, -1, LinuxError.EOPNOTSUPP);
- }
-
byte[] sendBuffer = new byte[sendSize];
context.Memory.Read(sendPosition, sendBuffer);
try
{
- result = socket.Handle.Send(sendBuffer, socketFlags);
+ result = socket.Handle.Send(sendBuffer, ConvertBsdSocketFlags(socketFlags));
errno = SetResultErrno(socket.Handle, result);
}
catch (SocketException exception)
@@ -589,8 +616,8 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
// SendTo(u32 socket, u32 flags, buffer, buffer) -> (i32 ret, u32 bsd_errno)
public ResultCode SendTo(ServiceCtx context)
{
- int socketFd = context.RequestData.ReadInt32();
- SocketFlags socketFlags = (SocketFlags)context.RequestData.ReadInt32();
+ int socketFd = context.RequestData.ReadInt32();
+ BsdSocketFlags socketFlags = (BsdSocketFlags)context.RequestData.ReadInt32();
(ulong sendPosition, ulong sendSize) = context.Request.GetBufferType0x21();
(ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x21(1);
@@ -601,14 +628,6 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
if (socket != null)
{
- if (socketFlags != SocketFlags.None && socketFlags != SocketFlags.OutOfBand
- && socketFlags != SocketFlags.Peek && socketFlags != SocketFlags.DontRoute)
- {
- Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported Send flags: {socketFlags}");
-
- return WriteBsdResult(context, -1, LinuxError.EOPNOTSUPP);
- }
-
byte[] sendBuffer = new byte[sendSize];
context.Memory.Read(sendPosition, sendBuffer);
@@ -617,7 +636,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
try
{
- result = socket.Handle.SendTo(sendBuffer, sendBuffer.Length, socketFlags, endPoint);
+ result = socket.Handle.SendTo(sendBuffer, sendBuffer.Length, ConvertBsdSocketFlags(socketFlags), endPoint);
errno = SetResultErrno(socket.Handle, result);
}
catch (SocketException exception)
@@ -737,7 +756,14 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
}
catch (SocketException exception)
{
- errno = ConvertError((WsaError)exception.ErrorCode);
+ if (!socket.Handle.Blocking && exception.ErrorCode == (int)WsaError.WSAEWOULDBLOCK)
+ {
+ errno = LinuxError.EINPROGRESS;
+ }
+ else
+ {
+ errno = ConvertError((WsaError)exception.ErrorCode);
+ }
}
}
@@ -794,9 +820,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
// GetSockOpt(u32 socket, u32 level, u32 option_name) -> (i32 ret, u32 bsd_errno, u32, buffer)
public ResultCode GetSockOpt(ServiceCtx context)
{
- int socketFd = context.RequestData.ReadInt32();
- int level = context.RequestData.ReadInt32();
- int optionName = context.RequestData.ReadInt32();
+ int socketFd = context.RequestData.ReadInt32();
+ SocketOptionLevel level = (SocketOptionLevel)context.RequestData.ReadInt32();
+ SocketOptionName optionName = (SocketOptionName)context.RequestData.ReadInt32();
(ulong bufferPosition, ulong bufferSize) = context.Request.GetBufferType0x22();
@@ -805,16 +831,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
if (socket != null)
{
- errno = LinuxError.ENOPROTOOPT;
-
- if (level == 0xFFFF)
- {
- errno = HandleGetSocketOption(context, socket, (SocketOptionName)optionName, bufferPosition, bufferSize);
- }
- else
- {
- Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported GetSockOpt Level: {(SocketOptionLevel)level}");
- }
+ errno = HandleGetSocketOption(context, socket, optionName, level, bufferPosition, bufferSize);
}
return WriteBsdResult(context, 0, errno);
@@ -916,7 +933,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
return WriteBsdResult(context, result, errno);
}
- private LinuxError HandleGetSocketOption(ServiceCtx context, BsdSocket socket, SocketOptionName optionName, ulong optionValuePosition, ulong optionValueSize)
+ private static LinuxError HandleGetSocketOption(
+ ServiceCtx context,
+ BsdSocket socket,
+ SocketOptionName optionName,
+ SocketOptionLevel level,
+ ulong optionValuePosition,
+ ulong optionValueSize)
{
try
{
@@ -936,19 +959,19 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
case SocketOptionName.SendTimeout:
case SocketOptionName.Type:
case SocketOptionName.Linger:
- socket.Handle.GetSocketOption(SocketOptionLevel.Socket, optionName, optionValue);
+ socket.Handle.GetSocketOption(level, optionName, optionValue);
context.Memory.Write(optionValuePosition, optionValue);
return LinuxError.SUCCESS;
case (SocketOptionName)0x200:
- socket.Handle.GetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, optionValue);
+ socket.Handle.GetSocketOption(level, SocketOptionName.ReuseAddress, optionValue);
context.Memory.Write(optionValuePosition, optionValue);
return LinuxError.SUCCESS;
default:
- Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported SetSockOpt OptionName: {optionName}");
+ Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported GetSockOpt OptionName: {optionName}");
return LinuxError.EOPNOTSUPP;
}
@@ -959,7 +982,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
}
}
- private LinuxError HandleSetSocketOption(ServiceCtx context, BsdSocket socket, SocketOptionName optionName, ulong optionValuePosition, ulong optionValueSize)
+ private static LinuxError HandleSetSocketOption(
+ ServiceCtx context,
+ BsdSocket socket,
+ SocketOptionName optionName,
+ SocketOptionLevel level,
+ ulong optionValuePosition,
+ ulong optionValueSize)
{
try
{
@@ -977,17 +1006,17 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
case SocketOptionName.SendTimeout:
case SocketOptionName.Type:
case SocketOptionName.ReuseAddress:
- socket.Handle.SetSocketOption(SocketOptionLevel.Socket, optionName, context.Memory.Read((ulong)optionValuePosition));
+ socket.Handle.SetSocketOption(level, optionName, context.Memory.Read((ulong)optionValuePosition));
return LinuxError.SUCCESS;
case (SocketOptionName)0x200:
- socket.Handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, context.Memory.Read((ulong)optionValuePosition));
+ socket.Handle.SetSocketOption(level, SocketOptionName.ReuseAddress, context.Memory.Read((ulong)optionValuePosition));
return LinuxError.SUCCESS;
case SocketOptionName.Linger:
- socket.Handle.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger,
+ socket.Handle.SetSocketOption(level, SocketOptionName.Linger,
new LingerOption(context.Memory.Read((ulong)optionValuePosition) != 0, context.Memory.Read((ulong)optionValuePosition + 4)));
return LinuxError.SUCCESS;
@@ -1008,9 +1037,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
// SetSockOpt(u32 socket, u32 level, u32 option_name, buffer option_value) -> (i32 ret, u32 bsd_errno)
public ResultCode SetSockOpt(ServiceCtx context)
{
- int socketFd = context.RequestData.ReadInt32();
- int level = context.RequestData.ReadInt32();
- int optionName = context.RequestData.ReadInt32();
+ int socketFd = context.RequestData.ReadInt32();
+ SocketOptionLevel level = (SocketOptionLevel)context.RequestData.ReadInt32();
+ SocketOptionName optionName = (SocketOptionName)context.RequestData.ReadInt32();
(ulong bufferPos, ulong bufferSize) = context.Request.GetBufferType0x21();
@@ -1019,16 +1048,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
if (socket != null)
{
- errno = LinuxError.ENOPROTOOPT;
-
- if (level == 0xFFFF)
- {
- errno = HandleSetSocketOption(context, socket, (SocketOptionName)optionName, bufferPos, bufferSize);
- }
- else
- {
- Logger.Warning?.Print(LogClass.ServiceBsd, $"Unsupported SetSockOpt Level: {(SocketOptionLevel)level}");
- }
+ errno = HandleSetSocketOption(context, socket, optionName, level, bufferPos, bufferSize);
}
return WriteBsdResult(context, 0, errno);
diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketFlags.cs b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketFlags.cs
new file mode 100644
index 000000000..4dc56356d
--- /dev/null
+++ b/Ryujinx.HLE/HOS/Services/Sockets/Bsd/Types/BsdSocketFlags.cs
@@ -0,0 +1,24 @@
+using System.Net.Sockets;
+
+namespace Ryujinx.HLE.HOS.Services.Sockets.Bsd
+{
+ enum BsdSocketFlags
+ {
+ None = 0,
+ Oob = 0x1,
+ Peek = 0x2,
+ DontRoute = 0x4,
+ Eor = 0x8,
+ Trunc = 0x10,
+ CTrunc = 0x20,
+ WaitAll = 0x40,
+ DontWait = 0x80,
+ Eof = 0x100,
+ Notification = 0x2000,
+ Nbio = 0x4000,
+ Compat = 0x8000,
+ SoCallbck = 0x10000,
+ NoSignal = 0x20000,
+ CMsgCloExec = 0x40000
+ }
+}
\ No newline at end of file
diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs
index 06df4d134..f5ae3818a 100644
--- a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs
+++ b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/IResolver.cs
@@ -155,7 +155,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
ulong responseBufferPosition = context.Request.ReceiveBuff[0].Position;
ulong responseBufferSize = context.Request.ReceiveBuff[0].Size;
- return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, 0, 0);
+ return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, false, 0, 0);
}
[CommandHipc(8)]
@@ -213,7 +213,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
(ulong responseBufferPosition, ulong responseBufferSize) = context.Request.GetBufferType0x22();
(ulong optionsBufferPosition, ulong optionsBufferSize) = context.Request.GetBufferType0x21();
- return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, optionsBufferPosition, optionsBufferSize);
+ return GetAddrInfoRequestImpl(context, responseBufferPosition, responseBufferSize, true, optionsBufferPosition, optionsBufferSize);
}
private ResultCode GetHostByNameRequestImpl(ServiceCtx context, ulong inputBufferPosition, ulong inputBufferSize, ulong outputBufferPosition, ulong outputBufferSize, ulong optionsBufferPosition, ulong optionsBufferSize)
@@ -391,7 +391,13 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
return bufferPosition - originalBufferPosition;
}
- private ResultCode GetAddrInfoRequestImpl(ServiceCtx context, ulong responseBufferPosition, ulong responseBufferSize, ulong optionsBufferPosition, ulong optionsBufferSize)
+ private ResultCode GetAddrInfoRequestImpl(
+ ServiceCtx context,
+ ulong responseBufferPosition,
+ ulong responseBufferSize,
+ bool withOptions,
+ ulong optionsBufferPosition,
+ ulong optionsBufferSize)
{
bool enableNsdResolve = (context.RequestData.ReadInt32() & 1) != 0;
uint cancelHandle = context.RequestData.ReadUInt32();
@@ -402,7 +408,7 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
// NOTE: We ignore hints for now.
DeserializeAddrInfos(context.Memory, (ulong)context.Request.SendBuff[2].Position, (ulong)context.Request.SendBuff[2].Size);
- if (optionsBufferSize > 0)
+ if (withOptions)
{
// TODO: Find unknown, Parse and use options.
uint unknown = context.RequestData.ReadUInt32();
@@ -457,9 +463,19 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres
serializedSize = SerializeAddrInfos(context, responseBufferPosition, responseBufferSize, hostEntry, port);
}
- context.ResponseData.Write((int)netDbErrorCode);
- context.ResponseData.Write((int)errno);
- context.ResponseData.Write(serializedSize);
+ if (withOptions)
+ {
+ context.ResponseData.Write(serializedSize);
+ context.ResponseData.Write((int)errno);
+ context.ResponseData.Write((int)netDbErrorCode);
+ context.ResponseData.Write(0);
+ }
+ else
+ {
+ context.ResponseData.Write((int)netDbErrorCode);
+ context.ResponseData.Write((int)errno);
+ context.ResponseData.Write(serializedSize);
+ }
return ResultCode.Success;
}
diff --git a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfo4.cs b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfo4.cs
index 515d8649d..0e1d3aaeb 100644
--- a/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfo4.cs
+++ b/Ryujinx.HLE/HOS/Services/Sockets/Sfdnsres/Types/AddrInfo4.cs
@@ -21,9 +21,9 @@ namespace Ryujinx.HLE.HOS.Services.Sockets.Sfdnsres.Types
Port = port;
Address = default;
- address.GetAddressBytes().AsSpan().CopyTo(Address.ToSpan());
-
- Address.ToSpan().Reverse();
+ Span outAddress = Address.ToSpan();
+ address.TryWriteBytes(outAddress, out _);
+ outAddress.Reverse();
}
}
}
\ No newline at end of file
diff --git a/Ryujinx.HLE/Switch.cs b/Ryujinx.HLE/Switch.cs
index 29d2ddd44..ac7d46112 100644
--- a/Ryujinx.HLE/Switch.cs
+++ b/Ryujinx.HLE/Switch.cs
@@ -49,7 +49,7 @@ namespace Ryujinx.HLE
throw new ArgumentNullException(nameof(configuration.AudioDeviceDriver));
}
- if (configuration.UserChannelPersistence== null)
+ if (configuration.UserChannelPersistence == null)
{
throw new ArgumentNullException(nameof(configuration.UserChannelPersistence));
}
diff --git a/Ryujinx.Headless.SDL2/Options.cs b/Ryujinx.Headless.SDL2/Options.cs
index 2c635a596..c8829d064 100644
--- a/Ryujinx.Headless.SDL2/Options.cs
+++ b/Ryujinx.Headless.SDL2/Options.cs
@@ -79,6 +79,9 @@ namespace Ryujinx.Headless.SDL2
[Option("enable-ptc", Required = false, Default = true, HelpText = "Enables profiled translation cache persistency.")]
public bool? EnablePtc { get; set; }
+ [Option("enable-internet-connection", Required = false, Default = false, HelpText = "Enables guest Internet connection.")]
+ public bool? EnableInternetAccess { get; set; }
+
[Option("enable-fs-integrity-checks", Required = false, Default = true, HelpText = "Enables integrity checks on Game content files.")]
public bool? EnableFsIntegrityChecks { get; set; }
diff --git a/Ryujinx.Headless.SDL2/Program.cs b/Ryujinx.Headless.SDL2/Program.cs
index eddf93518..2b169478e 100644
--- a/Ryujinx.Headless.SDL2/Program.cs
+++ b/Ryujinx.Headless.SDL2/Program.cs
@@ -459,6 +459,7 @@ namespace Ryujinx.Headless.SDL2
(bool)options.EnableVsync,
(bool)options.EnableDockedMode,
(bool)options.EnablePtc,
+ (bool)options.EnableInternetAccess,
(bool)options.EnableFsIntegrityChecks ? LibHac.FsSystem.IntegrityCheckLevel.ErrorOnInvalid : LibHac.FsSystem.IntegrityCheckLevel.None,
options.FsGlobalAccessLogMode,
options.SystemTimeOffset,
diff --git a/Ryujinx/Configuration/ConfigurationFileFormat.cs b/Ryujinx/Configuration/ConfigurationFileFormat.cs
index 648004d5f..b06e04e0d 100644
--- a/Ryujinx/Configuration/ConfigurationFileFormat.cs
+++ b/Ryujinx/Configuration/ConfigurationFileFormat.cs
@@ -14,8 +14,11 @@ namespace Ryujinx.Configuration
///
/// The current version of the file format
///
- public const int CurrentVersion = 33;
+ public const int CurrentVersion = 34;
+ ///
+ /// Version of the configuration file format
+ ///
public int Version { get; set; }
///
@@ -98,7 +101,6 @@ namespace Ryujinx.Configuration
///
public GraphicsDebugLevel LoggingGraphicsDebugLevel { get; set; }
-
///
/// Change System Language
///
@@ -154,16 +156,16 @@ namespace Ryujinx.Configuration
///
public bool EnableShaderCache { get; set; }
- ///
- /// Enables or disables multi-core scheduling of threads
- ///
- public bool EnableMulticoreScheduling { get; set; }
-
///
/// Enables or disables profiled translation cache persistency
///
public bool EnablePtc { get; set; }
+ ///
+ /// Enables or disables guest Internet access
+ ///
+ public bool EnableInternetAccess { get; set; }
+
///
/// Enables integrity checks on Game content files
///
diff --git a/Ryujinx/Configuration/ConfigurationState.cs b/Ryujinx/Configuration/ConfigurationState.cs
index 02136591d..b0b01771a 100644
--- a/Ryujinx/Configuration/ConfigurationState.cs
+++ b/Ryujinx/Configuration/ConfigurationState.cs
@@ -205,6 +205,11 @@ namespace Ryujinx.Configuration
///
public ReactiveObject EnablePtc { get; private set; }
+ ///
+ /// Enables or disables guest Internet access
+ ///
+ public ReactiveObject EnableInternetAccess { get; private set; }
+
///
/// Enables integrity checks on Game content files
///
@@ -250,6 +255,8 @@ namespace Ryujinx.Configuration
EnableDockedMode.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableDockedMode));
EnablePtc = new ReactiveObject();
EnablePtc.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnablePtc));
+ EnableInternetAccess = new ReactiveObject();
+ EnableInternetAccess.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableInternetAccess));
EnableFsIntegrityChecks = new ReactiveObject();
EnableFsIntegrityChecks.Event += static (sender, e) => LogValueChange(sender, e, nameof(EnableFsIntegrityChecks));
FsGlobalAccessLogMode = new ReactiveObject();
@@ -276,7 +283,7 @@ namespace Ryujinx.Configuration
/// Enable or disable keyboard support (Independent from controllers binding)
///
public ReactiveObject EnableKeyboard { get; private set; }
-
+
///
/// Enable or disable mouse support (Independent from controllers binding)
///
@@ -464,6 +471,7 @@ namespace Ryujinx.Configuration
EnableVsync = Graphics.EnableVsync,
EnableShaderCache = Graphics.EnableShaderCache,
EnablePtc = System.EnablePtc,
+ EnableInternetAccess = System.EnableInternetAccess,
EnableFsIntegrityChecks = System.EnableFsIntegrityChecks,
FsGlobalAccessLogMode = System.FsGlobalAccessLogMode,
AudioBackend = System.AudioBackend,
@@ -534,6 +542,7 @@ namespace Ryujinx.Configuration
Graphics.EnableVsync.Value = true;
Graphics.EnableShaderCache.Value = true;
System.EnablePtc.Value = true;
+ System.EnableInternetAccess.Value = false;
System.EnableFsIntegrityChecks.Value = true;
System.FsGlobalAccessLogMode.Value = 0;
System.AudioBackend.Value = AudioBackend.SDL2;
@@ -956,6 +965,15 @@ namespace Ryujinx.Configuration
configurationFileUpdated = true;
}
+ if (configurationFileFormat.Version < 34)
+ {
+ Common.Logging.Logger.Warning?.Print(LogClass.Application, $"Outdated configuration version {configurationFileFormat.Version}, migrating to version 34.");
+
+ configurationFileFormat.EnableInternetAccess = false;
+
+ configurationFileUpdated = true;
+ }
+
Logger.EnableFileLog.Value = configurationFileFormat.EnableFileLog;
Graphics.BackendThreading.Value = configurationFileFormat.BackendThreading;
Graphics.ResScale.Value = configurationFileFormat.ResScale;
@@ -984,6 +1002,7 @@ namespace Ryujinx.Configuration
Graphics.EnableVsync.Value = configurationFileFormat.EnableVsync;
Graphics.EnableShaderCache.Value = configurationFileFormat.EnableShaderCache;
System.EnablePtc.Value = configurationFileFormat.EnablePtc;
+ System.EnableInternetAccess.Value = configurationFileFormat.EnableInternetAccess;
System.EnableFsIntegrityChecks.Value = configurationFileFormat.EnableFsIntegrityChecks;
System.FsGlobalAccessLogMode.Value = configurationFileFormat.FsGlobalAccessLogMode;
System.AudioBackend.Value = configurationFileFormat.AudioBackend;
diff --git a/Ryujinx/Ui/MainWindow.cs b/Ryujinx/Ui/MainWindow.cs
index 51a09a319..e78d1a46d 100644
--- a/Ryujinx/Ui/MainWindow.cs
+++ b/Ryujinx/Ui/MainWindow.cs
@@ -206,7 +206,7 @@ namespace Ryujinx.Ui
ConfigurationState.Instance.System.IgnoreMissingServices.Event += UpdateIgnoreMissingServicesState;
ConfigurationState.Instance.Graphics.AspectRatio.Event += UpdateAspectRatioState;
ConfigurationState.Instance.System.EnableDockedMode.Event += UpdateDockedModeState;
- ConfigurationState.Instance.System.AudioVolume.Event += UpdateAudioVolumeState;
+ ConfigurationState.Instance.System.AudioVolume.Event += UpdateAudioVolumeState;
if (ConfigurationState.Instance.Ui.StartFullscreen)
{
@@ -434,7 +434,7 @@ namespace Ryujinx.Ui
else
{
Logger.Warning?.Print(LogClass.Audio, "SDL2 is not supported, trying to fall back to OpenAL.");
-
+
if (OpenALHardwareDeviceDriver.IsSupported)
{
Logger.Warning?.Print(LogClass.Audio, "Found OpenAL, changing configuration.");
@@ -447,7 +447,7 @@ namespace Ryujinx.Ui
else
{
Logger.Warning?.Print(LogClass.Audio, "OpenAL is not supported, trying to fall back to SoundIO.");
-
+
if (SoundIoHardwareDeviceDriver.IsSupported)
{
Logger.Warning?.Print(LogClass.Audio, "Found SoundIO, changing configuration.");
@@ -460,8 +460,8 @@ namespace Ryujinx.Ui
else
{
Logger.Warning?.Print(LogClass.Audio, "SoundIO is not supported, falling back to dummy audio out.");
- }
- }
+ }
+ }
}
}
else if (ConfigurationState.Instance.System.AudioBackend.Value == AudioBackend.SoundIo)
@@ -499,7 +499,7 @@ namespace Ryujinx.Ui
else
{
Logger.Warning?.Print(LogClass.Audio, "OpenAL is not supported, falling back to dummy audio out.");
- }
+ }
}
}
}
@@ -525,7 +525,7 @@ namespace Ryujinx.Ui
else
{
Logger.Warning?.Print(LogClass.Audio, "SDL2 is not supported, trying to fall back to SoundIO.");
-
+
if (SoundIoHardwareDeviceDriver.IsSupported)
{
Logger.Warning?.Print(LogClass.Audio, "Found SoundIO, changing configuration.");
@@ -563,6 +563,7 @@ namespace Ryujinx.Ui
ConfigurationState.Instance.Graphics.EnableVsync,
ConfigurationState.Instance.System.EnableDockedMode,
ConfigurationState.Instance.System.EnablePtc,
+ ConfigurationState.Instance.System.EnableInternetAccess,
fsIntegrityCheckLevel,
ConfigurationState.Instance.System.FsGlobalAccessLogMode,
ConfigurationState.Instance.System.SystemTimeOffset,
diff --git a/Ryujinx/Ui/Windows/SettingsWindow.cs b/Ryujinx/Ui/Windows/SettingsWindow.cs
index c5aeebdaa..1b9796386 100644
--- a/Ryujinx/Ui/Windows/SettingsWindow.cs
+++ b/Ryujinx/Ui/Windows/SettingsWindow.cs
@@ -52,6 +52,7 @@ namespace Ryujinx.Ui.Windows
[GUI] CheckButton _vSyncToggle;
[GUI] CheckButton _shaderCacheToggle;
[GUI] CheckButton _ptcToggle;
+ [GUI] CheckButton _internetToggle;
[GUI] CheckButton _fsicToggle;
[GUI] RadioButton _mmSoftware;
[GUI] RadioButton _mmHost;
@@ -226,6 +227,11 @@ namespace Ryujinx.Ui.Windows
_ptcToggle.Click();
}
+ if (ConfigurationState.Instance.System.EnableInternetAccess)
+ {
+ _internetToggle.Click();
+ }
+
if (ConfigurationState.Instance.System.EnableFsIntegrityChecks)
{
_fsicToggle.Click();
@@ -496,6 +502,7 @@ namespace Ryujinx.Ui.Windows
ConfigurationState.Instance.Graphics.EnableVsync.Value = _vSyncToggle.Active;
ConfigurationState.Instance.Graphics.EnableShaderCache.Value = _shaderCacheToggle.Active;
ConfigurationState.Instance.System.EnablePtc.Value = _ptcToggle.Active;
+ ConfigurationState.Instance.System.EnableInternetAccess.Value = _internetToggle.Active;
ConfigurationState.Instance.System.EnableFsIntegrityChecks.Value = _fsicToggle.Active;
ConfigurationState.Instance.System.MemoryManagerMode.Value = memoryMode;
ConfigurationState.Instance.System.ExpandRam.Value = _expandRamToggle.Active;
diff --git a/Ryujinx/Ui/Windows/SettingsWindow.glade b/Ryujinx/Ui/Windows/SettingsWindow.glade
index fa544edb2..d9b36daf6 100644
--- a/Ryujinx/Ui/Windows/SettingsWindow.glade
+++ b/Ryujinx/Ui/Windows/SettingsWindow.glade
@@ -1507,6 +1507,24 @@
6
+
+
+
+ False
+ True
+ 7
+
+