Skip to content

Commit ca9d9db

Browse files
committed
Read xb2 titles from an SD card
1 parent c34a89e commit ca9d9db

File tree

4 files changed

+82
-6
lines changed

4 files changed

+82
-6
lines changed

XbTool/XbTool/Options.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ public enum Task
3838
ExtractMinimap,
3939
GenerateSite,
4040
ExportQuests,
41-
ReplaceArchive
41+
ReplaceArchive,
42+
SdPrintTest
4243
}
4344
}

XbTool/XbTool/Tasks.cs

+14
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
using System;
22
using System.IO;
3+
using System.Linq;
4+
using LibHac.IO;
35
using XbTool.Bdat;
46
using XbTool.BdatString;
57
using XbTool.CodeGen;
@@ -88,6 +90,9 @@ internal static void RunTask(Options options)
8890
case Task.ReplaceArchive:
8991
ReplaceArchive(options);
9092
break;
93+
case Task.SdPrintTest:
94+
SdPrintTest(options);
95+
break;
9196
default:
9297
throw new ArgumentOutOfRangeException();
9398
}
@@ -435,5 +440,14 @@ private static void ExportQuests(Options options)
435440

436441
Xb2.Quest.Read.ExportQuests(tables, options.Output);
437442
}
443+
444+
private static void SdPrintTest(Options options)
445+
{
446+
if (options.Input == null) throw new NullReferenceException("No input path was specified.");
447+
if (options.Output == null) throw new NullReferenceException("No output path was specified.");
448+
449+
IFileSystem a = Xb2.FS.Create.CreateFileSystem(options.Input);
450+
File.WriteAllLines(options.Output, a.EnumerateEntries().Select(x => x.FullPath));
451+
}
438452
}
439453
}

XbTool/XbTool/Xb2/FS/Create.cs

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.IO;
4+
using System.Linq;
5+
using LibHac;
6+
using LibHac.IO;
7+
8+
namespace XbTool.Xb2.FS
9+
{
10+
public class Create
11+
{
12+
public static IFileSystem CreateFileSystem(string sdPath)
13+
{
14+
SwitchFs sdFs = OpenSdCard(sdPath);
15+
Application xb2App = sdFs.Applications[0x0100E95004038000];
16+
17+
var fsList = new List<IFileSystem>();
18+
fsList.Add(xb2App.Patch.MainNca.OpenSectionFileSystem(1, IntegrityCheckLevel.ErrorOnInvalid));
19+
fsList.AddRange(xb2App.AddOnContent.Select(x => x.MainNca.OpenSectionFileSystem(0, IntegrityCheckLevel.ErrorOnInvalid)));
20+
21+
return new LayeredFileSystem(fsList);
22+
}
23+
24+
public static SwitchFs OpenSdCard(string path, IProgressReport logger = null)
25+
{
26+
SwitchFs switchFs;
27+
Keyset keyset = OpenKeyset();
28+
29+
var baseFs = new LocalFileSystem(path);
30+
31+
if (Directory.Exists(Path.Combine(path, "Nintendo", "Contents", "registered")))
32+
{
33+
logger?.LogMessage("Treating path as SD card storage");
34+
switchFs = SwitchFs.OpenSdCard(keyset, baseFs);
35+
}
36+
else if (Directory.Exists(Path.Combine(path, "Contents", "registered")))
37+
{
38+
logger?.LogMessage("Treating path as NAND storage");
39+
switchFs = SwitchFs.OpenNandPartition(keyset, baseFs);
40+
}
41+
else
42+
{
43+
logger?.LogMessage("Treating path as a directory of loose NCAs");
44+
switchFs = SwitchFs.OpenNcaDirectory(keyset, baseFs);
45+
}
46+
47+
return switchFs;
48+
}
49+
50+
private static Keyset OpenKeyset()
51+
{
52+
string home = Environment.GetFolderPath(Environment.SpecialFolder.UserProfile);
53+
string homeKeyFile = Path.Combine(home, ".switch", "prod.keys");
54+
string homeTitleKeyFile = Path.Combine(home, ".switch", "title.keys");
55+
string homeConsoleKeyFile = Path.Combine(home, ".switch", "console.keys");
56+
57+
return ExternalKeys.ReadKeyFile(homeKeyFile, homeTitleKeyFile, homeConsoleKeyFile);
58+
}
59+
}
60+
}

XbTool/XbTool/XbTool.csproj

+6-5
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
<PropertyGroup>
44
<OutputType>Exe</OutputType>
5-
<TargetFrameworks>net45;netcoreapp2.0</TargetFrameworks>
5+
<TargetFrameworks>net46;netcoreapp2.1</TargetFrameworks>
66
</PropertyGroup>
77

88
<ItemGroup>
@@ -18,11 +18,12 @@
1818
<ItemGroup>
1919
<PackageReference Include="CsvHelper" Version="7.0.1" />
2020
<PackageReference Include="DotNet.Glob" Version="2.0.3" />
21+
<PackageReference Include="LibHac" Version="0.3.0" />
2122
<PackageReference Include="Npgsql" Version="4.0.3" />
22-
<PackageReference Condition=" '$(TargetFramework)' == 'net45' " Include="System.ValueTuple" Version="4.5.0" />
23-
<PackageReference Condition=" '$(TargetFramework)' == 'net45' " Include="DotNetZip" Version="1.11.0" />
24-
<PackageReference Condition=" '$(TargetFramework)' == 'netcoreapp2.0' " Include="Iconic.Zlib.Netstandard" Version="1.0.0" />
25-
<PackageReference Condition=" '$(TargetFramework)' == 'netcoreapp2.0' " Include="System.Drawing.Common" Version="4.5.0" />
23+
<PackageReference Condition=" '$(TargetFramework)' == 'net46' " Include="System.ValueTuple" Version="4.5.0" />
24+
<PackageReference Condition=" '$(TargetFramework)' == 'net46' " Include="DotNetZip" Version="1.11.0" />
25+
<PackageReference Condition=" '$(TargetFramework)' == 'netcoreapp2.1' " Include="Iconic.Zlib.Netstandard" Version="1.0.0" />
26+
<PackageReference Condition=" '$(TargetFramework)' == 'netcoreapp2.1' " Include="System.Drawing.Common" Version="4.5.0" />
2627
<PackageReference Include="Newtonsoft.Json" Version="11.0.2" />
2728
</ItemGroup>
2829

0 commit comments

Comments
 (0)