diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs index 53ca0990..933682de 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSIO.cs @@ -2,6 +2,7 @@ using nn.fs; #endif +using nn.fs; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; @@ -13,6 +14,61 @@ public class AxiNSIO #if UNITY_SWITCH private FileHandle fileHandle = new nn.fs.FileHandle(); #endif + + static object commitLock = new object(); + + static bool bDirty = false; + + bool CommitSave() + { + lock (commitLock) + { +#if UNITY_SWITCH && !UNITY_EDITOR + + // 阻止用户在保存时,退出游戏 Switch 条例 0080 + UnityEngine.Switch.Notification.EnterExitRequestHandlingSection(); + nn.Result ret = FileSystem.Commit(save_name); + + if (!ret.IsSuccess()) + { + UnityEngine.Debug.LogError($"FileSystem.Commit({save_name}) 失败: " + ret.GetErrorInfo()); + return false; + } + + // 停止阻止用户退出游戏 + UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); + + bDirty = false; + return true; +#else + return false; +#endif + } + + } + + void SetCommitDirty() + { + lock (commitLock) + { + bDirty = true; + } + } + + public void ApplyAutoCommit() + { + bool temp; + lock (commitLock) + { + temp = bDirty; + } + + if (temp) + { + CommitSave(); + } + } + /// /// 检查Path是否存在 /// @@ -53,8 +109,11 @@ public class AxiNSIO /// public bool CreateDir(string filePath) { + lock (commitLock) + { + #if !UNITY_SWITCH - return false; + return false; #else // 使用封装函数检查和创建父目录 if (!EnsureParentDirectory(filePath, true)) @@ -64,6 +123,7 @@ public class AxiNSIO } return true; #endif + } } /// @@ -88,16 +148,20 @@ public class AxiNSIO AxiNS.instance.wait.AddWait(wait); return wait; } + /// /// 保存并创建文件(如果目录不存在回先自动创建目录) /// /// /// + /// 是否立即Commit到物理存储 /// - public bool FileToSaveWithCreate(string filePath, byte[] data) + public bool FileToSaveWithCreate(string filePath, byte[] data, bool immediatelyCommit = true) { + lock (commitLock) + { #if !UNITY_SWITCH - return false; + return false; #else if (!AxiNS.instance.mount.SaveIsMount) { @@ -181,24 +245,24 @@ public class AxiNSIO nn.fs.File.Close(fileHandle); - //必须得提交,否则没有真实写入 - result = FileSystem.Commit(save_name); - //result.abortUnlessSuccess(); - if (!result.IsSuccess()) - { - UnityEngine.Debug.LogError($"FileSystem.Commit({save_name}) 失败: " + result.GetErrorInfo()); - return false; - } - UnityEngine.Debug.Log($"FileSystem.Commit({save_name}) 成功: "); - - + #if UNITY_SWITCH && !UNITY_EDITOR // 停止阻止用户退出游戏 UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif - return true; + if(immediatelyCommit) + { + //必须得提交,否则没有真实写入 + return CommitSave(); + } + else + { + SetCommitDirty(); + return true; + } #endif + } } /// /// 保存并创建文件(如果目录不存在回先自动创建目录) @@ -232,7 +296,7 @@ public class AxiNSIO } public bool LoadSwitchDataFile(string filename, out byte[] outputData) { -#if !UNITY_SWITCH +#if !UNITY_SWITCH || UNITY_EDITOR outputData = null; return false; #else @@ -292,7 +356,8 @@ public class AxiNSIO public bool GetDirectoryFiles(string path, out string[] entrys) { -#if !UNITY_SWITCH +#if !UNITY_SWITCH || UNITY_EDITOR + entrys = null; return false; #else @@ -302,7 +367,7 @@ public class AxiNSIO public bool GetDirectoryDirs(string path, out string[] entrys) { -#if !UNITY_SWITCH +#if !UNITY_SWITCH || UNITY_EDITOR entrys = null; return false; #else @@ -311,38 +376,70 @@ public class AxiNSIO } #if UNITY_SWITCH - public bool GetDirectoryEntrys(string path, nn.fs.OpenDirectoryMode type, out string[] entrys) + 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); + nn.fs.DirectoryHandle eHandle = new nn.fs.DirectoryHandle(); + nn.Result result = nn.fs.Directory.Open(ref eHandle, 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, eHandle); + nn.fs.DirectoryEntry[] entries = new nn.fs.DirectoryEntry[entryCount]; + long actualEntries = 0; + nn.fs.Directory.Read(ref actualEntries, entries, eHandle, entryCount); entrys = new string[actualEntries]; - for (int i = 0; i < actualEntries; i++) - { - entrys[i] = dirEntries[i].name; - } - nn.fs.Directory.Close(dirHandle); + for (int i = 0; i < actualEntries; i++) + { + entrys[i] = System.IO.Path.Combine(path, entries[i].name); + } + nn.fs.Directory.Close(eHandle); return true; - } + } +#endif + + +#if UNITY_SWITCH + public bool GetDirectoryEntrysFullRecursion(string path, out string[] entrys) + { + nn.fs.DirectoryHandle eHandle = new nn.fs.DirectoryHandle(); + nn.Result result = nn.fs.Directory.Open(ref eHandle, path, OpenDirectoryMode.All); + if (nn.fs.FileSystem.ResultPathNotFound.Includes(result)) + { + UnityEngine.Debug.Log($"目录 {path} 不存在"); + entrys = null; + return false; + } + long entryCount = 0; + nn.fs.Directory.GetEntryCount(ref entryCount, eHandle); + nn.fs.DirectoryEntry[] entries = new nn.fs.DirectoryEntry[entryCount]; + long actualEntries = 0; + nn.fs.Directory.Read(ref actualEntries, entries, eHandle, entryCount); + + List temp = new List(); + for (int i = 0; i < actualEntries; i++) + { + string singlePath = System.IO.Path.Combine(path, entries[i].name); + temp.Add(singlePath); + if (entries[i].entryType == EntryType.Directory && GetDirectoryEntrysFullRecursion(singlePath, out string[] singleEntryList)) + { + temp.AddRange(singleEntryList); + } + } + nn.fs.Directory.Close(eHandle); + entrys = temp.ToArray(); + return true; + } #endif public IEnumerable EnumerateFiles(string path, string searchPattern) { -#if !UNITY_SWITCH - yield break; +#if !UNITY_SWITCH || UNITY_EDITOR + yield break; #else // 将通配符转换为正则表达式(支持*和?) var regexPattern = "^" + @@ -390,18 +487,12 @@ public class AxiNSIO UnityEngine.Debug.LogError($"nn.fs.File.Delete 失败 {filename} : result=>{result.GetErrorInfo()}"); return false; } - result = nn.fs.FileSystem.Commit(save_name); - if (!result.IsSuccess()) - { - UnityEngine.Debug.LogError($"FileSystem.Commit({save_name}) 失败: " + result.GetErrorInfo()); - return false; - } - return true; #if UNITY_SWITCH && !UNITY_EDITOR // End preventing the user from quitting the game while saving. UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif + return CommitSave(); #endif } @@ -432,18 +523,12 @@ public class AxiNSIO UnityEngine.Debug.LogError($"nn.fs.File.Delete 失败 {filename} : result=>{result.GetErrorInfo()}"); return false; } - result = nn.fs.FileSystem.Commit(save_name); - if (!result.IsSuccess()) - { - UnityEngine.Debug.LogError($"FileSystem.Commit({save_name}) 失败: " + result.GetErrorInfo()); - return false; - } - return true; #if UNITY_SWITCH && !UNITY_EDITOR // End preventing the user from quitting the game while saving. UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif + return CommitSave(); #endif } public AxiNSWait_DeletePathDir DeletePathDirAsync(string filename) @@ -479,18 +564,12 @@ public class AxiNSIO UnityEngine.Debug.LogError($"nn.fs.File.DeleteRecursively 失败 {filename} : result=>{result.GetErrorInfo()}"); return false; } - result = nn.fs.FileSystem.Commit(save_name); - if (!result.IsSuccess()) - { - UnityEngine.Debug.LogError($"FileSystem.Commit({save_name}) 失败: " + result.GetErrorInfo()); - return false; - } - return true; #if UNITY_SWITCH && !UNITY_EDITOR // End preventing the user from quitting the game while saving. UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif + return CommitSave(); #endif } @@ -520,18 +599,12 @@ public class AxiNSIO UnityEngine.Debug.LogError($"nn.fs.File.DeleteRecursively 失败 {filename} : result=>{result.GetErrorInfo()}"); return false; } - result = nn.fs.FileSystem.Commit(save_name); - if (!result.IsSuccess()) - { - UnityEngine.Debug.LogError($"FileSystem.Commit({save_name}) 失败: " + result.GetErrorInfo()); - return false; - } - return true; #if UNITY_SWITCH && !UNITY_EDITOR // End preventing the user from quitting the game while saving. UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif + return CommitSave(); #endif } @@ -557,18 +630,13 @@ public class AxiNSIO UnityEngine.Debug.LogError($"nn.fs.File.Rename 失败 {oldpath} to {newpath} : result=>{result.GetErrorInfo()}"); return false; } - result = nn.fs.FileSystem.Commit(save_name); - if (!result.IsSuccess()) - { - UnityEngine.Debug.LogError($"FileSystem.Commit({save_name}) 失败: " + result.GetErrorInfo()); - return false; - } - return true; #if UNITY_SWITCH && !UNITY_EDITOR // End preventing the user from quitting the game while saving. UnityEngine.Switch.Notification.LeaveExitRequestHandlingSection(); #endif + return CommitSave(); + #endif } bool EnsureParentDirectory(string filePath, bool bAutoCreateDir = true) diff --git a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs index 169c2b3f..bd17118d 100644 --- a/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs +++ b/AxibugEmuOnline.Client/Assets/Plugins/AxiNSApi/AxiNSMount.cs @@ -1,6 +1,5 @@ #if UNITY_SWITCH using nn.account; -using static AxiHttp; #endif public class AxiNSMount { diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/App.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/App.cs index 6b1406da..f0941b26 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/App.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/App.cs @@ -49,6 +49,10 @@ namespace AxibugEmuOnline.Client.ClientCore public static SonyVitaCommonDialog sonyVitaCommonDialog; #endif +#if UNITY_SWITCH + public static SwitchCommon switchCommon; +#endif + #endregion @@ -138,10 +142,15 @@ namespace AxibugEmuOnline.Client.ClientCore // Directory.CreateDirectory("ux0:data/AxibugEmu"); #if UNITY_PSP2 - //鍒涘缓PSV寮圭獥UI - sonyVitaCommonDialog = new GameObject().AddComponent(); //閲婃斁瑙g爜 FMV鐨26M鍐呭瓨锛屼竴鑸父鎴忕敤涓嶄笂锛圥SP鎵嶇敤閭g牬鐜╂剰鍎匡級 UnityEngine.PSVita.PSVitaVideoPlayer.TransferMemToMonoHeap(); + //鍒涘缓PSV寮圭獥UI + sonyVitaCommonDialog = new GameObject().AddComponent(); +#endif + +#if UNITY_SWITCH + //鍒涘缓鍒涘缓Switch + switchCommon = new GameObject().AddComponent(); #endif } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/AxiIO.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/AxiIO.cs index b27b32ff..a902398c 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/AxiIO.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/AxiIO.cs @@ -1,4 +1,5 @@ -锘縰sing System.Collections.Generic; +锘縰sing Sony.Vita.Dialog; +using System.Collections.Generic; namespace AxiIO { @@ -43,9 +44,15 @@ namespace AxiIO return AxiIO.io.file_ReadBytesToArr(filePath, readToArr, start, len); } - internal static void WriteAllBytes(string path, byte[] data) + /// + /// + /// + /// + /// + /// 鏄惁绔嬪嵆Commit鍒扮墿鐞嗗瓨鍌紙鐩墠鍙湁NS瀵规湰鍙傛暟鏈夋晥锛 + internal static void WriteAllBytes(string path, byte[] data, bool ImmediatelyCommit = true) { - AxiIO.io.file_WriteAllBytes(path, data); + AxiIO.io.file_WriteAllBytes(path, data, ImmediatelyCommit); } internal static void WriteAllBytesFromStream(string path, System.IO.MemoryStream ms) diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/CSharpIO.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/CSharpIO.cs index 0f50530f..3935bcbb 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/CSharpIO.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/CSharpIO.cs @@ -26,7 +26,13 @@ namespace AxiIO return System.IO.Directory.Exists(dirpath); } - public void file_WriteAllBytes(string filePath, byte[] data) + /// + /// + /// + /// + /// + /// 鏄惁绔嬪嵆Commit鍒扮墿鐞嗗瓨鍌紙C#鍘熺敓杩欓噷涓嶉渶瑕侊級 + public void file_WriteAllBytes(string filePath, byte[] data, bool immediatelyCommit = true) { System.IO.File.WriteAllBytes(filePath, data); } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/IAxiIO.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/IAxiIO.cs index 8886f80a..5a164dab 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/IAxiIO.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/IAxiIO.cs @@ -12,7 +12,13 @@ namespace AxiIO byte[] file_ReadAllBytes(string filePath); bool file_Exists(string filePath); void file_Delete(string filePath); - void file_WriteAllBytes(string filePath, byte[] data); + /// + /// + /// + /// + /// + /// 鏄惁绔嬪嵆Commit鍒扮墿鐞嗗瓨鍌紙鐩墠鍙湁NS瀵规湰鍙傛暟鏈夋晥锛 + void file_WriteAllBytes(string filePath, byte[] data, bool immediatelyCommit = true); 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); diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NSwitchIO.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NSwitchIO.cs index d56d0aab..c28e17c6 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NSwitchIO.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/AxiIO/NSwitchIO.cs @@ -70,7 +70,13 @@ namespace AxiIO return templen; } - public void file_WriteAllBytes(string filePath, byte[] data) + /// + /// + /// + /// + /// + /// 鏄惁绔嬪嵆Commit鍒扮墿鐞嗗瓨鍌 + public void file_WriteAllBytes(string filePath, byte[] data, bool immediatelyCommit = true) { AxiNS.instance.io.FileToSaveWithCreate(filePath, data); } diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/CacheManager.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/CacheManager.cs index 19d5f9df..f997b216 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/CacheManager.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Manager/CacheManager.cs @@ -38,7 +38,7 @@ namespace AxibugEmuOnline.Client if (!request.downloadHandler.bHadErr) { AxiIO.Directory.CreateDirectory(path); - AxiIO.File.WriteAllBytes($"{path}/{url.GetHashCode()}", request.downloadHandler.data); + AxiIO.File.WriteAllBytes($"{path}/{url.GetHashCode()}", request.downloadHandler.data, false); callback.Invoke(request.downloadHandler.data); } else diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/MonoCom/TickLoop.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/MonoCom/TickLoop.cs index 74fcd380..7b6b51da 100644 --- a/AxibugEmuOnline.Client/Assets/Script/AppMain/MonoCom/TickLoop.cs +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/MonoCom/TickLoop.cs @@ -15,6 +15,7 @@ namespace AxibugEmuOnline.Client public static Action LoopAction_tick; public static Action LoopAction_1s; public static Action LoopAction_3s; + public static Action LoopAction_15s; public Stopwatch sw = Stopwatch.StartNew(); public TimeSpan LastStartPingTime; public int LastPingSeed; @@ -42,6 +43,7 @@ namespace AxibugEmuOnline.Client } float LastLoopTime_1s; float LastLoopTime_3s; + float LastLoopTime_15s; private void Update() { NetMsg.Instance.DequeueNesMsg(); @@ -59,6 +61,12 @@ namespace AxibugEmuOnline.Client LastLoopTime_3s = Time.time; LoopAction_3s?.Invoke(); } + + if (Time.time - LastLoopTime_15s > 15) + { + LastLoopTime_15s = Time.time; + LoopAction_15s?.Invoke(); + } } void OnApplicationQuit() diff --git a/AxibugEmuOnline.Client/Assets/Script/AppMain/Switch/SwitchCommon.cs b/AxibugEmuOnline.Client/Assets/Script/AppMain/Switch/SwitchCommon.cs new file mode 100644 index 00000000..e28f5ee2 --- /dev/null +++ b/AxibugEmuOnline.Client/Assets/Script/AppMain/Switch/SwitchCommon.cs @@ -0,0 +1,21 @@ +锘縰sing AxibugEmuOnline.Client; +using UnityEngine; +public class SwitchCommon : MonoBehaviour +{ + void Start() + { + TickLoop.LoopAction_15s += ApplyCommit; + } + + void OnDisable() + { + TickLoop.LoopAction_15s -= ApplyCommit; + } + + private void ApplyCommit() + { +#if UNITY_SWITCH + AxiNS.instance.io.ApplyAutoCommit(); +#endif + } +}