diff --git a/.gitignore b/.gitignore index e9b160c2..e5bbec84 100644 --- a/.gitignore +++ b/.gitignore @@ -14,6 +14,9 @@ /AxibugEmuOnline.Client/ProjectSettings/AutoStreamingSettings.asset /AxibugEmuOnline.Client/Logs +/AxibugEmuOnline.Client/Assets/AxiProjectTools/AxiNSPack/switch_keys/*.keys +/AxibugEmuOnline.Client/Assets/AxiProjectTools/AxiNSPack/switch_keys/*.keys.meta + /virtuanessrc097-master /AxibugEmuOnline.Server/config.cfg /AxibugEmuOnline.Server/bin/ diff --git a/AxibugEmuOnline.Client/Assets/AxiProjectTools/AxiNSPack/Editors/AxibugNSPTools.cs b/AxibugEmuOnline.Client/Assets/AxiProjectTools/AxiNSPack/Editors/AxibugNSPTools.cs index 5234487e..4da1036a 100644 --- a/AxibugEmuOnline.Client/Assets/AxiProjectTools/AxiNSPack/Editors/AxibugNSPTools.cs +++ b/AxibugEmuOnline.Client/Assets/AxiProjectTools/AxiNSPack/Editors/AxibugNSPTools.cs @@ -1,23 +1,24 @@ -using System.Collections.Generic; -using System.Linq; -using System.Text.RegularExpressions; using System; -using UnityEditor; +using System.Collections.Generic; using System.IO; -using UnityEngine; +using System.Linq; using System.Text; +using System.Text.RegularExpressions; +using UnityEditor; +using UnityEditor.Build.Reporting; +using UnityEngine; namespace AxibugEmuOnline.Editors { public class AxibugNSPTools : Editor { - static string WorkRoot = Path.GetFullPath(Path.Combine(Application.dataPath,"AxiProjectTools/AxiNSPack")); + static string WorkRoot = Path.GetFullPath(Path.Combine(Application.dataPath, "AxiProjectTools/AxiNSPack")); static string switch_keys = Path.GetFullPath(Path.Combine(Application.dataPath, "AxiProjectTools/AxiNSPack/switch_keys")); static string hacpack_root = Path.GetFullPath(Path.Combine(Application.dataPath, "AxiProjectTools/AxiNSPack/hacpack")); static Dictionary<string, string> tools = new Dictionary<string, string>(); static string prodKeysPath; - - [MenuItem("Axibug��ֲ����/Switch/AxibugNSPTools/RepackNSP")] + + [MenuItem("Axibug��ֲ����/Switch/AxibugNSPTools/RepackNSP(�����¹���NPS��")] static void RepackNSP() { if (!CheckEnvironmentVariable()) @@ -25,7 +26,7 @@ namespace AxibugEmuOnline.Editors string path = EditorUtility.OpenFilePanel( title: "ѡ�� .nsp �ļ�", - directory: Path.Combine(Application.dataPath,".."), // Ĭ��·��Ϊ��Ŀ Assets Ŀ¼ + directory: Path.Combine(Application.dataPath, ".."), // Ĭ��·��Ϊ��Ŀ Assets Ŀ¼ extension: "nsp" // �����ļ�����Ϊ .nsp ); @@ -34,6 +35,62 @@ namespace AxibugEmuOnline.Editors RepackNSP(path); } + + [MenuItem("Axibug��ֲ����/Switch/AxibugNSPTools/Build With RepackNSP(���NSP�����¹���NPS��")] + static void BuildWithRepackNSP() + { + if (!CheckEnvironmentVariable()) + return; + + if (!EditorUtility.DisplayDialog("ȷ�ϰ���Ϣ", $"�������?", "����", "ȡ��")) + return; + + var levels = new List<string>(); + foreach (var scene in EditorBuildSettings.scenes) + { + if (scene.enabled) + levels.Add(scene.path); + } + + var buildOpt = EditorUserBuildSettings.development ? BuildOptions.Development : BuildOptions.None; + if (EditorUserBuildSettings.buildWithDeepProfilingSupport) + buildOpt |= BuildOptions.EnableDeepProfilingSupport; + if (EditorUserBuildSettings.allowDebugging) + buildOpt |= BuildOptions.AllowDebugging; + + //��ѡ����NSP�� + EditorUserBuildSettings.switchCreateRomFile = true; + +#if UNITY_2018_1_OR_NEWER && !UNITY_6000_0_OR_NEWER + string titleid = PlayerSettings.Switch.applicationID; +#else + string titleid = "null"; +#endif + string targetName = $"{Application.productName}_{titleid}.nsp"; + + string _locationPathName = $"Output/NSPBuild/{targetName}"; + var options = new BuildPlayerOptions + { + scenes = levels.ToArray(), + locationPathName = _locationPathName, + target = BuildTarget.Switch, + options = buildOpt + }; + + try + { + BuildReport report = BuildPipeline.BuildPlayer(options); + } + catch(Exception ex) + { + Debug.LogError($"[AxibugNSPTools] Unity Build NSP ����:{ex.ToString()}"); + return; + } + + string NSPFullPath = Path.GetFullPath(Path.Combine(Application.dataPath, "..", _locationPathName)); + RepackNSP(NSPFullPath); + } + static bool CheckEnvironmentVariable() { // ��ȡ������������Ҫ���ӻ���������飩 @@ -66,7 +123,7 @@ namespace AxibugEmuOnline.Editors // ��ȡ������������Ҫ���ӻ���������飩 string sdkRoot = Environment.GetEnvironmentVariable("NINTENDO_SDK_ROOT"); tools["authoringTool"] = Path.Combine(sdkRoot, "Tools/CommandLineTools/AuthoringTool/AuthoringTool.exe"); - tools["hacPack"] = hacpack_root; + tools["hacPack"] = Path.Combine(hacpack_root, "hacpack"); #endregion #region ����NSP�ļ�·�� @@ -76,21 +133,30 @@ namespace AxibugEmuOnline.Editors #endregion #region ��ȡTitle ID - string titleID = ExtractTitleID(nspFilePath) ?? ManualTitleIDInput(); + string titleID = ExtractTitleID(nspFilePath); + if (string.IsNullOrEmpty(titleID)) + { + Debug.LogError($"[AxibugNSPTools]NSP�ļ���һ���֣��������TitleID"); + return; + } Debug.Log($"[AxibugNSPTools]Using Title ID: {titleID}"); #endregion + EditorUtility.DisplayProgressBar("AxibugNSPTools", $"������ʱĿ¼", 0); #region ������ʱĿ¼ CleanDirectory(Path.Combine(nspParentDir, "repacker_extract")); CleanDirectory(Path.Combine(Path.GetTempPath(), "NCA")); CleanDirectory(Path.Combine(WorkRoot, "hacpack_backup")); #endregion + EditorUtility.DisplayProgressBar("AxibugNSPTools", $"���NSP�ļ�", 0.2f); #region ���NSP�ļ� string extractPath = Path.Combine(nspParentDir, "repacker_extract"); ExecuteCommand($"{tools["authoringTool"]} extract -o \"{extractPath}\" \"{nspFilePath}\""); - var (controlPath, programPath) = FindNACPAndNPDPaths(extractPath); + string controlPath = null; + string programPath = null; + FindNACPAndNPDPaths(extractPath, ref controlPath, ref programPath); if (controlPath == null || programPath == null) { Debug.LogError("[AxibugNSPTools] Critical directory structure not found!"); @@ -100,12 +166,17 @@ namespace AxibugEmuOnline.Editors #region �ؽ�NCA/NSP string tmpPath = Path.Combine(Path.GetTempPath(), "NCA"); + EditorUtility.DisplayProgressBar("AxibugNSPTools", $"�ؽ�NCA", 0.6f); string programNCA = BuildProgramNCA(tmpPath, titleID, programPath); + EditorUtility.DisplayProgressBar("AxibugNSPTools", $"�ؽ�NCA", 0.7f); string controlNCA = BuildControlNCA(tmpPath, titleID, controlPath); + EditorUtility.DisplayProgressBar("AxibugNSPTools", $"�ؽ�NCA", 0.8f); BuildMetaNCA(tmpPath, titleID, programNCA, controlNCA); - + EditorUtility.DisplayProgressBar("AxibugNSPTools", $"�ؽ�NSP", 0.9f); string outputNSP = BuildFinalNSP(nspFilePath, nspParentDir, tmpPath, titleID); + EditorUtility.DisplayProgressBar("AxibugNSPTools", $"�ؽ�NSP", 1f); Debug.Log($"[AxibugNSPTools]Repacking completed: {outputNSP}"); + EditorUtility.ClearProgressBar(); #endregion } @@ -122,11 +193,6 @@ namespace AxibugEmuOnline.Editors return match.Success ? match.Value : null; } - static string ManualTitleIDInput() - { - Console.Write("Enter Title ID manually: "); - return Console.ReadLine().Trim(); - } static void CleanDirectory(string path) { @@ -137,16 +203,15 @@ namespace AxibugEmuOnline.Editors } } - static (string, string) FindNACPAndNPDPaths(string basePath) + static void FindNACPAndNPDPaths(string basePath, ref string controlPath, ref string programPath) { foreach (var dir in Directory.GetDirectories(basePath)) { if (File.Exists(Path.Combine(dir, "fs0/control.nacp"))) - return (dir, null); + controlPath = dir; if (File.Exists(Path.Combine(dir, "fs0/main.npdm"))) - return (null, dir); + programPath = dir; } - return (null, null); } static string ExecuteCommand(string command) @@ -225,6 +290,7 @@ namespace AxibugEmuOnline.Editors $"--type nca --ncatype control --romfsdir \"{controlDir}/fs0\""; string output = ExecuteCommand($"{tools["hacPack"]} {args}"); + return ParseNCAOutput(output, "Control"); } @@ -254,7 +320,6 @@ namespace AxibugEmuOnline.Editors { var line = output.Split('\n') .FirstOrDefault(l => l.Contains($"Created {type} NCA:")); - return line?.Split(':').Last().Trim(); } #endregion diff --git a/AxibugEmuOnline.Client/Assets/AxiProjectTools/AxiNSPack/hacpack/repack.exe b/AxibugEmuOnline.Client/Assets/AxiProjectTools/AxiNSPack/hacpack/repack.exe new file mode 100644 index 00000000..3cecbf90 Binary files /dev/null and b/AxibugEmuOnline.Client/Assets/AxiProjectTools/AxiNSPack/hacpack/repack.exe differ diff --git a/AxibugEmuOnline.Client/Assets/AxiProjectTools/AxiNSPack/hacpack/repack.exe.meta b/AxibugEmuOnline.Client/Assets/AxiProjectTools/AxiNSPack/hacpack/repack.exe.meta new file mode 100644 index 00000000..1f42b7df --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/AxiProjectTools/AxiNSPack/hacpack/repack.exe.meta @@ -0,0 +1,7 @@ +fileFormatVersion: 2 +guid: 17912de8f13787e4f8a2dccfb2f91c74 +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: