From 3c09abf9e612c3776a2a931a9553fcb3f15731d3 Mon Sep 17 00:00:00 2001
From: Ac_K <Acoustik666@gmail.com>
Date: Sun, 10 Jan 2021 21:26:59 +0100
Subject: [PATCH] pctl: Stub IsFreeCommunicationAvailable (#1893)

* pctl: Stub IsFreeCommunicationAvailable

This PR stub call IsFreeCommunicationAvailable since it's the same as call CheckFreeCommunicationPermission without a sets of an internal field.
I've fixed a wrong logic found while I'm checked the call by RE.

This fix #1883.

* Fix comments
---
 .../IParentalControlService.cs                | 48 +++++++++++++------
 1 file changed, 34 insertions(+), 14 deletions(-)

diff --git a/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs b/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs
index 032c157d75..6c159801cf 100644
--- a/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs
+++ b/Ryujinx.HLE/HOS/Services/Pctl/ParentalControlServiceFactory/IParentalControlService.cs
@@ -1,3 +1,4 @@
+using LibHac.Ns;
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE.HOS.Services.Arp;
 using System;
@@ -6,17 +7,16 @@ namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory
 {
     class IParentalControlService : IpcService
     {
-        private int   _permissionFlag;
-        private ulong _titleId;
-        private bool  _freeCommunicationEnabled;
-        private int[] _ratingAge;
+        private int                      _permissionFlag;
+        private ulong                    _titleId;
+        private ParentalControlFlagValue _parentalControlFlag;
+        private int[]                    _ratingAge;
 
         // TODO: Find where they are set.
-        private bool  _restrictionEnabled                  = false;
-        private bool  _featuresRestriction                 = false;
-        private bool  _stereoVisionRestrictionConfigurable = true;
-
-        private bool  _stereoVisionRestriction             = false;
+        private bool _restrictionEnabled                  = false;
+        private bool _featuresRestriction                 = false;
+        private bool _stereoVisionRestrictionConfigurable = true;
+        private bool _stereoVisionRestriction             = false;
 
         public IParentalControlService(ServiceCtx context, bool withInitialize, int permissionFlag)
         {
@@ -50,8 +50,8 @@ namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory
                         _titleId = titleId;
 
                         // TODO: Call nn::arp::GetApplicationControlProperty here when implemented, if it return ResultCode.Success we assign fields.
-                        _ratingAge                = Array.ConvertAll(context.Device.Application.ControlData.Value.RatingAge.ToArray(), Convert.ToInt32);
-                        _freeCommunicationEnabled = context.Device.Application.ControlData.Value.ParentalControl == LibHac.Ns.ParentalControlFlagValue.FreeCommunication;
+                        _ratingAge           = Array.ConvertAll(context.Device.Application.ControlData.Value.RatingAge.ToArray(), Convert.ToInt32);
+                        _parentalControlFlag = context.Device.Application.ControlData.Value.ParentalControl;
                     }
                 }
 
@@ -77,13 +77,16 @@ namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory
         // CheckFreeCommunicationPermission()
         public ResultCode CheckFreeCommunicationPermission(ServiceCtx context)
         {
-            // TODO: This checks some extra internal fields which are to be determined.
-
-            if (!_freeCommunicationEnabled && _restrictionEnabled)
+            if (_parentalControlFlag == ParentalControlFlagValue.FreeCommunication && _restrictionEnabled)
             {
+                // TODO: It seems to checks if an entry exists in the FreeCommunicationApplicationList using the TitleId.
+                //       Then it returns FreeCommunicationDisabled if the entry doesn't exist.
+
                 return ResultCode.FreeCommunicationDisabled;
             }
 
+            // NOTE: This sets an internal field to true. Usage have to be determined.
+
             Logger.Stub?.PrintStub(LogClass.ServicePctl);
 
             return ResultCode.Success;
@@ -96,6 +99,23 @@ namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory
             return IsStereoVisionPermittedImpl();
         }
 
+        [Command(1018)]
+        // IsFreeCommunicationAvailable()
+        public ResultCode IsFreeCommunicationAvailable(ServiceCtx context)
+        {
+            if (_parentalControlFlag == ParentalControlFlagValue.FreeCommunication && _restrictionEnabled)
+            {
+                // TODO: It seems to checks if an entry exists in the FreeCommunicationApplicationList using the TitleId.
+                //       Then it returns FreeCommunicationDisabled if the entry doesn't exist.
+
+                return ResultCode.FreeCommunicationDisabled;
+            }
+
+            Logger.Stub?.PrintStub(LogClass.ServicePctl);
+
+            return ResultCode.Success;
+        }
+
         [Command(1031)]
         // IsRestrictionEnabled() -> b8
         public ResultCode IsRestrictionEnabled(ServiceCtx context)