From 53e66645260e1dfe382138fa8ed09376da99cb60 Mon Sep 17 00:00:00 2001
From: Alex Barney <thealexbarney@gmail.com>
Date: Tue, 30 Oct 2018 20:34:27 -0600
Subject: [PATCH] Update libhac. Load tickets from XCI files (#476)

---
 Ryujinx.HLE/HOS/Horizon.cs     | 38 +++++++++++++++++++++++-----------
 Ryujinx.HLE/Ryujinx.HLE.csproj |  2 +-
 Ryujinx/Config.cs              |  5 ++++-
 3 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/Ryujinx.HLE/HOS/Horizon.cs b/Ryujinx.HLE/HOS/Horizon.cs
index 1cb419b9..af175bd4 100644
--- a/Ryujinx.HLE/HOS/Horizon.cs
+++ b/Ryujinx.HLE/HOS/Horizon.cs
@@ -10,6 +10,7 @@ using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.IO;
 using System.Linq;
+using Nso = Ryujinx.HLE.Loaders.Executables.Nso;
 
 namespace Ryujinx.HLE.HOS
 {
@@ -51,7 +52,7 @@ namespace Ryujinx.HLE.HOS
 
         public string CurrentTitle { get; private set; }
 
-        public bool EnableFsIntegrityChecks { get; set; }
+        public IntegrityCheckLevel FsIntegrityCheckLevel { get; set; }
 
         public Horizon(Switch Device)
         {
@@ -187,6 +188,16 @@ namespace Ryujinx.HLE.HOS
             Nca PatchNca   = null;
             Nca ControlNca = null;
 
+            foreach (PfsFileEntry TicketEntry in Xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".tik")))
+            {
+                Ticket ticket = new Ticket(Xci.SecurePartition.OpenFile(TicketEntry));
+
+                if (!KeySet.TitleKeys.ContainsKey(ticket.RightsId))
+                {
+                    KeySet.TitleKeys.Add(ticket.RightsId, ticket.GetTitleKey(KeySet));
+                }
+            }
+
             foreach (PfsFileEntry FileEntry in Xci.SecurePartition.Files.Where(x => x.Name.EndsWith(".nca")))
             {
                 Stream NcaStream = Xci.SecurePartition.OpenFile(FileEntry);
@@ -234,7 +245,7 @@ namespace Ryujinx.HLE.HOS
 
         public void ReadControlData(Nca ControlNca)
         {
-            Romfs ControlRomfs = new Romfs(ControlNca.OpenSection(0, false, EnableFsIntegrityChecks));
+            Romfs ControlRomfs = new Romfs(ControlNca.OpenSection(0, false, FsIntegrityCheckLevel));
 
             byte[] ControlFile = ControlRomfs.GetFile("/control.nacp");
 
@@ -297,29 +308,32 @@ namespace Ryujinx.HLE.HOS
 
         public void LoadNca(Nca MainNca, Nca ControlNca)
         {
-            NcaSection RomfsSection = MainNca.Sections.FirstOrDefault(x => x?.Type == SectionType.Romfs || x?.Type == SectionType.Bktr);
-            NcaSection ExefsSection = MainNca.Sections.FirstOrDefault(x => x?.IsExefs == true);
+            if (MainNca.Header.ContentType != ContentType.Program)
+            {
+                Logger.PrintError(LogClass.Loader, "Selected NCA is not a \"Program\" NCA");
 
-            if (ExefsSection == null)
+                return;
+            }
+
+            Stream RomfsStream = MainNca.OpenSection(ProgramPartitionType.Data, false, FsIntegrityCheckLevel);
+            Stream ExefsStream = MainNca.OpenSection(ProgramPartitionType.Code, false, FsIntegrityCheckLevel);
+
+            if (ExefsStream == null)
             {
                 Logger.PrintError(LogClass.Loader, "No ExeFS found in NCA");
 
                 return;
             }
 
-            if (RomfsSection == null)
+            if (RomfsStream == null)
             {
                 Logger.PrintWarning(LogClass.Loader, "No RomFS found in NCA");
             }
             else
             {
-                Stream RomfsStream = MainNca.OpenSection(RomfsSection.SectionNum, false, EnableFsIntegrityChecks);
-
                 Device.FileSystem.SetRomFs(RomfsStream);
             }
-
-            Stream ExefsStream = MainNca.OpenSection(ExefsSection.SectionNum, false, EnableFsIntegrityChecks);
-
+            
             Pfs Exefs = new Pfs(ExefsStream);
 
             Npdm MetaData = null;
@@ -358,7 +372,7 @@ namespace Ryujinx.HLE.HOS
 
             Nacp ReadControlData()
             {
-                Romfs ControlRomfs = new Romfs(ControlNca.OpenSection(0, false, EnableFsIntegrityChecks));
+                Romfs ControlRomfs = new Romfs(ControlNca.OpenSection(0, false, FsIntegrityCheckLevel));
 
                 byte[] ControlFile = ControlRomfs.GetFile("/control.nacp");
 
diff --git a/Ryujinx.HLE/Ryujinx.HLE.csproj b/Ryujinx.HLE/Ryujinx.HLE.csproj
index 6625136a..165a3d9d 100644
--- a/Ryujinx.HLE/Ryujinx.HLE.csproj
+++ b/Ryujinx.HLE/Ryujinx.HLE.csproj
@@ -26,7 +26,7 @@
     <ProjectReference Include="..\Ryujinx.Audio\Ryujinx.Audio.csproj" />
     <ProjectReference Include="..\Ryujinx.Common\Ryujinx.Common.csproj" />
     <ProjectReference Include="..\Ryujinx.Graphics\Ryujinx.Graphics.csproj" />
-    <PackageReference Include="LibHac" Version="0.1.2" />
+    <PackageReference Include="LibHac" Version="0.1.3" />
   </ItemGroup>
 
 </Project>
diff --git a/Ryujinx/Config.cs b/Ryujinx/Config.cs
index 2e739852..dcead648 100644
--- a/Ryujinx/Config.cs
+++ b/Ryujinx/Config.cs
@@ -1,3 +1,4 @@
+using LibHac;
 using Ryujinx.Common.Logging;
 using Ryujinx.HLE;
 using Ryujinx.UI.Input;
@@ -68,7 +69,9 @@ namespace Ryujinx
                 device.System.EnableMultiCoreScheduling();
             }
 
-            device.System.EnableFsIntegrityChecks = Convert.ToBoolean(parser.Value("Enable_FS_Integrity_Checks"));
+            device.System.FsIntegrityCheckLevel = Convert.ToBoolean(parser.Value("Enable_FS_Integrity_Checks"))
+                ? IntegrityCheckLevel.ErrorOnInvalid
+                : IntegrityCheckLevel.None;
 
             JoyConKeyboard = new JoyConKeyboard(