diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs index 1e1b22cd..53ca0990 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs @@ -2,20 +2,24 @@ using nn.fs; #endif +using System.Collections.Generic; +using System.Linq; +using System.Text.RegularExpressions; + public class AxiNSIO { - string save_name => AxiNS.instance.mount.SaveMountName; - public string save_path => $"{save_name}:/"; + string save_name => AxiNS.instance.mount.SaveMountName; + public string save_path => $"{save_name}:/"; #if UNITY_SWITCH private FileHandle fileHandle = new nn.fs.FileHandle(); #endif - /// - /// 检查Path是否存在 - /// - /// - /// - public bool CheckPathExists(string filePath) - { + /// + /// 检查Path是否存在 + /// + /// + /// + public bool CheckPathExists(string filePath) + { #if !UNITY_SWITCH return false; #else @@ -25,14 +29,14 @@ public class AxiNSIO //这个异常捕获。真的别扭 return nn.fs.FileSystem.ResultPathAlreadyExists.Includes(result); #endif - } - /// - /// 检查Path是否不存在 - /// - /// - /// - public bool CheckPathNotFound(string filePath) - { + } + /// + /// 检查Path是否不存在 + /// + /// + /// + public bool CheckPathNotFound(string filePath) + { #if !UNITY_SWITCH return false; #else @@ -41,14 +45,14 @@ public class AxiNSIO //这个异常捕获。真的别扭 return nn.fs.FileSystem.ResultPathNotFound.Includes(result); #endif - } - /// - /// 创建目录,目录存在也会返回true - /// - /// - /// - public bool CreateDir(string filePath) - { + } + /// + /// 创建目录,目录存在也会返回true + /// + /// + /// + public bool CreateDir(string filePath) + { #if !UNITY_SWITCH return false; #else @@ -60,40 +64,38 @@ public class AxiNSIO } return true; #endif - } + } - - - /// - /// 保存并创建文件(如果目录不存在回先自动创建目录) - /// - /// - /// - /// - public bool FileToSaveWithCreate(string filePath, System.IO.MemoryStream ms) - { - return FileToSaveWithCreate(filePath, ms.ToArray()); - } - /// - /// 保存并创建文件(如果目录不存在回先自动创建目录) - /// - /// - /// - /// - public AxiNSWait_FileToSaveByMSWithCreate FileToSaveWithCreateAsync(string filePath, System.IO.MemoryStream ms) - { - var wait = new AxiNSWait_FileToSaveByMSWithCreate(filePath, ms); - AxiNS.instance.wait.AddWait(wait); - return wait; - } - /// - /// 保存并创建文件(如果目录不存在回先自动创建目录) - /// - /// - /// - /// - public bool FileToSaveWithCreate(string filePath, byte[] data) - { + /// + /// 保存并创建文件(如果目录不存在回先自动创建目录) + /// + /// + /// + /// + public bool FileToSaveWithCreate(string filePath, System.IO.MemoryStream ms) + { + return FileToSaveWithCreate(filePath, ms.ToArray()); + } + /// + /// 保存并创建文件(如果目录不存在回先自动创建目录) + /// + /// + /// + /// + public AxiNSWait_FileToSaveByMSWithCreate FileToSaveWithCreateAsync(string filePath, System.IO.MemoryStream ms) + { + var wait = new AxiNSWait_FileToSaveByMSWithCreate(filePath, ms); + AxiNS.instance.wait.AddWait(wait); + return wait; + } + /// + /// 保存并创建文件(如果目录不存在回先自动创建目录) + /// + /// + /// + /// + public bool FileToSaveWithCreate(string filePath, byte[] data) + { #if !UNITY_SWITCH return false; #else @@ -197,39 +199,39 @@ public class AxiNSIO return true; #endif - } - /// - /// 保存并创建文件(如果目录不存在回先自动创建目录) - /// - /// - /// - /// - public AxiNSWait_FileToSaveWithCreate FileToSaveWithCreateAsync(string filePath, byte[] data) - { - var wait = new AxiNSWait_FileToSaveWithCreate(filePath, data); - AxiNS.instance.wait.AddWait(wait); - return wait; - } - public byte[] LoadSwitchDataFile(string filename) - { - LoadSwitchDataFile(filename, out byte[] outputData); - return outputData; + } + /// + /// 保存并创建文件(如果目录不存在回先自动创建目录) + /// + /// + /// + /// + public AxiNSWait_FileToSaveWithCreate FileToSaveWithCreateAsync(string filePath, byte[] data) + { + var wait = new AxiNSWait_FileToSaveWithCreate(filePath, data); + AxiNS.instance.wait.AddWait(wait); + return wait; + } + public byte[] LoadSwitchDataFile(string filename) + { + LoadSwitchDataFile(filename, out byte[] outputData); + return outputData; } public bool LoadSwitchDataFile(string filename, ref System.IO.MemoryStream ms) - { - if (LoadSwitchDataFile(filename, out byte[] outputData)) - { - using (System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms)) - { - writer.Write(outputData); - } - return true; - } - return false; - } - public bool LoadSwitchDataFile(string filename, out byte[] outputData) - { + { + if (LoadSwitchDataFile(filename, out byte[] outputData)) + { + using (System.IO.BinaryWriter writer = new System.IO.BinaryWriter(ms)) + { + writer.Write(outputData); + } + return true; + } + return false; + } + public bool LoadSwitchDataFile(string filename, out byte[] outputData) + { #if !UNITY_SWITCH outputData = null; return false; @@ -280,15 +282,94 @@ public class AxiNSIO outputData = loadedData; return true; #endif - } - public AxiNSWait_LoadSwitchDataFile LoadSwitchDataFileAsync(string filename) - { - var wait = new AxiNSWait_LoadSwitchDataFile(filename); - AxiNS.instance.wait.AddWait(wait); - return wait; - } - public bool DeletePathFile(string filename) + } + public AxiNSWait_LoadSwitchDataFile LoadSwitchDataFileAsync(string filename) + { + var wait = new AxiNSWait_LoadSwitchDataFile(filename); + AxiNS.instance.wait.AddWait(wait); + return wait; + } + + public bool GetDirectoryFiles(string path, out string[] entrys) + { +#if !UNITY_SWITCH + entrys = null; + return false; +#else + return GetDirectoryEntrys(path,nn.fs.OpenDirectoryMode.File,out entrys); +#endif + } + + public bool GetDirectoryDirs(string path, out string[] entrys) + { +#if !UNITY_SWITCH + entrys = null; + return false; +#else + return GetDirectoryEntrys(path, nn.fs.OpenDirectoryMode.Directory, out entrys); +#endif + } + +#if UNITY_SWITCH + public bool GetDirectoryEntrys(string path, nn.fs.OpenDirectoryMode type, out string[] entrys) { + entrys = null; + return false; + nn.fs.DirectoryHandle dirHandle = new nn.fs.DirectoryHandle(); + nn.Result result = nn.fs.Directory.Open(ref dirHandle, path, type); + if (nn.fs.FileSystem.ResultPathNotFound.Includes(result)) + { + UnityEngine.Debug.Log($"目录 {path} 不存在"); + entrys = null; + return false; + } + long entryCount = 0; + nn.fs.Directory.GetEntryCount(ref entryCount, dirHandle); + nn.fs.DirectoryEntry[] dirEntries = new nn.fs.DirectoryEntry[entryCount]; + long actualEntries = 0; + nn.fs.Directory.Read(ref actualEntries, dirEntries, dirHandle, entryCount); + + entrys = new string[actualEntries]; + for (int i = 0; i < actualEntries; i++) + { + entrys[i] = dirEntries[i].name; + } + nn.fs.Directory.Close(dirHandle); + return true; + } +#endif + + public IEnumerable EnumerateFiles(string path, string searchPattern) + { +#if !UNITY_SWITCH + yield break; +#else + // 将通配符转换为正则表达式(支持*和?) + var regexPattern = "^" + + Regex.Escape(searchPattern) + .Replace("\\*", ".*") + .Replace("\\?", ".") + + "$"; + + var regex = new Regex(regexPattern, RegexOptions.IgnoreCase); + + if (!GetDirectoryEntrys(path, nn.fs.OpenDirectoryMode.File, out string[] entrys)) + { + yield break; + } + + for (int i = 0; i < entrys.Length; i++) + { + if (regex.IsMatch(System.IO.Path.GetFileName(entrys[i]))) + { + yield return entrys[i]; + } + } +#endif + } + + public bool DeletePathFile(string filename) + { #if !UNITY_SWITCH return false; #else @@ -323,15 +404,15 @@ public class AxiNSIO #endif #endif - } - public AxiNSWait_DeletePathFile DeletePathFileAsync(string filename) - { - var wait = new AxiNSWait_DeletePathFile(filename); - AxiNS.instance.wait.AddWait(wait); - return wait; - } - public bool DeletePathDir(string filename) - { + } + public AxiNSWait_DeletePathFile DeletePathFileAsync(string filename) + { + var wait = new AxiNSWait_DeletePathFile(filename); + AxiNS.instance.wait.AddWait(wait); + return wait; + } + public bool DeletePathDir(string filename) + { #if !UNITY_SWITCH return false; #else @@ -364,21 +445,21 @@ public class AxiNSIO UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif #endif - } - public AxiNSWait_DeletePathDir DeletePathDirAsync(string filename) - { - var wait = new AxiNSWait_DeletePathDir(filename); - AxiNS.instance.wait.AddWait(wait); - return wait; - } + } + public AxiNSWait_DeletePathDir DeletePathDirAsync(string filename) + { + var wait = new AxiNSWait_DeletePathDir(filename); + AxiNS.instance.wait.AddWait(wait); + return wait; + } - /// - /// 递归删除目录 - /// - /// - /// - public bool DeleteRecursivelyPathDir(string filename) - { + /// + /// 递归删除目录 + /// + /// + /// + public bool DeleteRecursivelyPathDir(string filename) + { #if !UNITY_SWITCH return false; #else @@ -411,15 +492,15 @@ public class AxiNSIO UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif #endif - } + } - /// - /// 递归删除情况 - /// - /// - /// - public bool CleanRecursivelyPathDir(string filename) - { + /// + /// 递归删除情况 + /// + /// + /// + public bool CleanRecursivelyPathDir(string filename) + { #if !UNITY_SWITCH return false; #else @@ -452,10 +533,10 @@ public class AxiNSIO UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif #endif - } + } - public bool RenameDir(string oldpath, string newpath) - { + public bool RenameDir(string oldpath, string newpath) + { #if !UNITY_SWITCH return false; #else @@ -489,9 +570,9 @@ public class AxiNSIO UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif #endif - } - bool EnsureParentDirectory(string filePath, bool bAutoCreateDir = true) - { + } + bool EnsureParentDirectory(string filePath, bool bAutoCreateDir = true) + { #if !UNITY_SWITCH return false; #else @@ -567,14 +648,14 @@ public class AxiNSIO return true; #endif - } - /// - /// 检查指定挂载点是否可访问 - /// - /// 路径前缀,例如 "save:/" 或 "sd:/" - /// 挂载点是否可访问 - bool IsMountPointAccessible(string pathPrefix) - { + } + /// + /// 检查指定挂载点是否可访问 + /// + /// 路径前缀,例如 "save:/" 或 "sd:/" + /// 挂载点是否可访问 + bool IsMountPointAccessible(string pathPrefix) + { #if !UNITY_SWITCH return false; #else @@ -612,5 +693,5 @@ public class AxiNSIO return true; // 其他挂载点需根据实际需求实现 } #endif - } + } } diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs index 8b32a30b..169c2b3f 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs @@ -118,7 +118,7 @@ public class AxiNSMount UnityEngine.Debug.LogError($"UnmountSDCardForDebug->已卸载{m_SdCardDebugMountName}:/ "); bInSdCardDebugMount = false; #endif - } + } public void UnmountSDCard() { #if UNITY_SWITCH diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/AxiIO.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/AxiIO.cs index 1d94006c..b27b32ff 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/AxiIO.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/AxiIO.cs @@ -1,6 +1,4 @@ -锘縰sing System; -using System.Collections.Generic; -using System.IO; +锘縰sing System.Collections.Generic; namespace AxiIO { @@ -15,7 +13,7 @@ namespace AxiIO if (m_io == null) { #if UNITY_SWITCH && !UNITY_EDITOR - m_io = new NintendoSwitchIO(); + m_io = new NSwitchIO(); #else m_io = new CSharpIO(); #endif @@ -50,7 +48,7 @@ namespace AxiIO AxiIO.io.file_WriteAllBytes(path, data); } - internal static void WriteAllBytesFromStream(string path, MemoryStream ms) + internal static void WriteAllBytesFromStream(string path, System.IO.MemoryStream ms) { AxiIO.io.file_WriteAllBytes(path, ms); } @@ -73,6 +71,16 @@ namespace AxiIO return AxiIO.io.dir_EnumerateFiles(path, searchPattern); } + public static string[] GetDirectories(string path) + { + return AxiIO.io.dir_GetDirectories(path); + } + + public static string[] GetFiles(string path) + { + return AxiIO.io.dir_GetFiles(path); + } + internal static void Delete(string cacheDirPath, bool v) { AxiIO.io.dir_Delete(cacheDirPath, v); diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/CSharpIO.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/CSharpIO.cs index 4092bb13..0f50530f 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/CSharpIO.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/CSharpIO.cs @@ -56,5 +56,15 @@ namespace AxiIO FileStream streaming = System.IO.File.OpenRead(filePath); return streaming.Read(readToArr, 0, 4); } + + public string[] dir_GetDirectories(string path) + { + return System.IO.Directory.GetDirectories(path); + } + + public string[] dir_GetFiles(string path) + { + return System.IO.Directory.GetFiles(path); + } } } \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/IAxiIO.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/IAxiIO.cs index 5248412f..8886f80a 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/IAxiIO.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/IAxiIO.cs @@ -15,5 +15,7 @@ namespace AxiIO void file_WriteAllBytes(string filePath, byte[] data); void file_WriteAllBytes(string filePath, System.IO.MemoryStream ms); int file_ReadBytesToArr(string filePath, byte[] readToArr, int start, int len); + string[] dir_GetDirectories(string path); + string[] dir_GetFiles(string path); }; } \ No newline at end of file diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NintendoSwitchIO.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NSwitchIO.cs similarity index 68% rename from AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NintendoSwitchIO.cs rename to AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NSwitchIO.cs index 1eeaf57c..d56d0aab 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NintendoSwitchIO.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NSwitchIO.cs @@ -1,12 +1,11 @@ 锘縰sing System; using System.Collections.Generic; -using System.IO; namespace AxiIO { - public class NintendoSwitchIO : IAxiIO + public class NSwitchIO : IAxiIO { - public NintendoSwitchIO() + public NSwitchIO() { AxiNS.instance.Init(); } @@ -22,7 +21,7 @@ namespace AxiIO public IEnumerable dir_EnumerateFiles(string path, string searchPattern) { - throw new NotImplementedException(); + return AxiNS.instance.io.EnumerateFiles(path, searchPattern); } public bool dir_Exists(string dirpath) @@ -30,6 +29,24 @@ namespace AxiIO return AxiNS.instance.io.CheckPathExists(dirpath); } + public string[] dir_GetDirectories(string path) + { + if (!AxiNS.instance.io.GetDirectoryDirs(path, out string[] result)) + { + return new string[0]; + } + return result; + } + + public string[] dir_GetFiles(string path) + { + if (!AxiNS.instance.io.GetDirectoryFiles(path, out string[] result)) + { + return new string[0]; + } + return result; + } + public void file_Delete(string filePath) { AxiNS.instance.io.DeletePathFile(filePath); @@ -58,7 +75,7 @@ namespace AxiIO AxiNS.instance.io.FileToSaveWithCreate(filePath, data); } - public void file_WriteAllBytes(string filePath, MemoryStream ms) + public void file_WriteAllBytes(string filePath, System.IO.MemoryStream ms) { AxiNS.instance.io.FileToSaveWithCreate(filePath, ms); } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NintendoSwitchIO.cs.meta b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NSwitchIO.cs.meta similarity index 100% rename from AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NintendoSwitchIO.cs.meta rename to AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NSwitchIO.cs.meta