diff --git a/ShinRyuModManager-CE/GameModel.cs b/ShinRyuModManager-CE/GameModel.cs index 1186e3b..95a919e 100644 --- a/ShinRyuModManager-CE/GameModel.cs +++ b/ShinRyuModManager-CE/GameModel.cs @@ -403,14 +403,16 @@ public static void DoUBIKProcedure(MLO mlo) { } public static void DoYK3HActProcedure(MLO mlo, string codename) { - var hactDir = new DirectoryInfo(GamePath.DataPath).EnumerateDirectories().FirstOrDefault(x => x.Name.StartsWith("hact_"))?.FullName; - - if (string.IsNullOrEmpty(hactDir)) + var haveHAct = mlo.Files.Any(x => x.Name.Contains("/hact_")); + + if (!haveHAct) return; - - var haveTalk = mlo.Files.Any(x => x.Name.Contains("/hact_")); - if (!haveTalk) + var hactDir = new DirectoryInfo(GamePath.DataPath) + .EnumerateDirectories() + .FirstOrDefault(x => x.Name.StartsWith("hact_"))?.FullName; + + if (string.IsNullOrEmpty(hactDir)) return; var rootHActDir = Path.Combine(GamePath.ParlessDir, "hact_" + codename); @@ -433,6 +435,7 @@ public static void DoYK3HActProcedure(MLO mlo, string codename) { if (string.IsNullOrEmpty(hActDirPath)) continue; + var hActDir = new DirectoryInfo(hActDirPath); foreach (var dir in hActDir.EnumerateDirectories()) { @@ -448,15 +451,17 @@ public static void DoYK3HActProcedure(MLO mlo, string codename) { } public static void DoTalkProcedureYK3(MLO mlo, string codename) { - var hactDir = new DirectoryInfo(GamePath.DataPath).GetDirectories().FirstOrDefault(x => x.Name.StartsWith("hact_"))?.FullName; - - if (string.IsNullOrEmpty(hactDir)) - return; - var haveTalk = mlo.Files.Any(x => x.Name.Contains("/talk_")); if (!haveTalk) return; + + var hactDir = new DirectoryInfo(GamePath.DataPath) + .EnumerateDirectories() + .FirstOrDefault(x => x.Name.StartsWith("hact_"))?.FullName; + + if (string.IsNullOrEmpty(hactDir)) + return; var rootTalkDir = Path.Combine(GamePath.ParlessDir, "talk_" + codename); diff --git a/ShinRyuModManager-CE/ModLoadOrder/Generator.cs b/ShinRyuModManager-CE/ModLoadOrder/Generator.cs index 1039ea9..002799f 100644 --- a/ShinRyuModManager-CE/ModLoadOrder/Generator.cs +++ b/ShinRyuModManager-CE/ModLoadOrder/Generator.cs @@ -78,7 +78,7 @@ public static async Task GenerateModeLoadOrder(List mods, bool loo // Check for folders which do not exist in the data path in the mod's root List foldersNotFound = []; - foreach (var subPath in Directory.GetDirectories(modPath)) { + foreach (var subPath in Directory.EnumerateDirectories(modPath)) { var subPathName = new DirectoryInfo(subPath).Name; if (GamePath.DirectoryExistsInData(subPathName) || GamePath.FileExistsInData($"{subPathName}.par")) diff --git a/ShinRyuModManager-CE/ModLoadOrder/Mods/Mod.cs b/ShinRyuModManager-CE/ModLoadOrder/Mods/Mod.cs index 684a26a..6ed7401 100644 --- a/ShinRyuModManager-CE/ModLoadOrder/Mods/Mod.cs +++ b/ShinRyuModManager-CE/ModLoadOrder/Mods/Mod.cs @@ -211,11 +211,14 @@ public void AddFiles(string path, string check) { continue; var fileName = Path.GetFileName(p); - var fileNameNoExt = Path.GetFileNameWithoutExtension(p); - var gmtHashName = fileNameNoExt.Length <= 30 ? fileNameNoExt : fileNameNoExt[..30]; - var gmtPath = Path.Combine(gmtFolderPath, fileName); + var fileNameNoExt = Path.GetFileNameWithoutExtension(p).ToLowerInvariant(); + + var hash = new PXDHash(); + hash.Set(fileNameNoExt); - var checksum = ComputePirateYakuzaChecksum(gmtHashName); + var gmtPath = Path.Combine(gmtFolderPath, fileName); + + var checksum = string.Concat("00", hash.Checksum.ToString("x4").AsSpan(2, 2)); var destinationDirectory = Path.Combine(baseParlessPath, checksum); if (!Directory.Exists(destinationDirectory)) @@ -268,10 +271,4 @@ protected static string CheckFolder(string name) { return folder ?? string.Empty; } - - private static string ComputePirateYakuzaChecksum(string input) { - var sum = Encoding.UTF8.GetBytes(input).Sum(b => b) % 256; - - return sum.ToString("x4"); - } } diff --git a/ShinRyuModManager-CE/Program.cs b/ShinRyuModManager-CE/Program.cs index f73adf0..fe8a3ea 100644 --- a/ShinRyuModManager-CE/Program.cs +++ b/ShinRyuModManager-CE/Program.cs @@ -257,11 +257,11 @@ internal static List PreRun(Profile? profile = null) { if (File.Exists(Constants.TXT_OLD)) { mods.AddRange(ModListSerializer.Read(Constants.TXT_OLD, profile)); - File.Move(Constants.TXT_OLD, $"{Constants.TXT_OLD}.bak"); + File.Move(Constants.TXT_OLD, $"{Constants.TXT_OLD}.bak", true); } else if (File.Exists(Constants.TXT)) { mods.AddRange(ModListSerializer.Read(Constants.TXT, profile)); - File.Move(Constants.TXT, $"{Constants.TXT}.bak"); + File.Move(Constants.TXT, $"{Constants.TXT}.bak", true); } else if (File.Exists(Constants.MOD_LIST)) { mods.AddRange(ModListSerializer.Read(Constants.MOD_LIST, profile)); } else { diff --git a/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj b/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj index 29fc650..4e9da6a 100644 --- a/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj +++ b/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj @@ -14,7 +14,7 @@ true - 1.4.2 + 1.4.3 $(AssemblyVersion) ShinRyuModManager-CE SRMM Studio diff --git a/ShinRyuModManager-CE/UserInterface/Assets/changelog.md b/ShinRyuModManager-CE/UserInterface/Assets/changelog.md index 6d28ec6..9be4233 100644 --- a/ShinRyuModManager-CE/UserInterface/Assets/changelog.md +++ b/ShinRyuModManager-CE/UserInterface/Assets/changelog.md @@ -1,4 +1,9 @@ -> ### **%{color:gold} Version 1.4.2 %** ### +> ### **%{color:gold} Version 1.4.3 %** ### +* Implemented improved PYIH and newer hashing from SRMM 4.7.7 + +--- + +> ### **%{color:orange} Version 1.4.2 %** ### * Implemented **experimental** Talk and HAct repack methods from SRMM 4.7.6 --- diff --git a/Utils/PXDHash.cs b/Utils/PXDHash.cs new file mode 100644 index 0000000..84ded20 --- /dev/null +++ b/Utils/PXDHash.cs @@ -0,0 +1,30 @@ +using System.Runtime.InteropServices; + +namespace Utils; + +[StructLayout(LayoutKind.Sequential, Size = 32)] +public struct PXDHash { + public ushort Checksum { get; set; } + + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 30)] + private char[] str; // 0x0002 + + public void Set(string val) { + Checksum = 0; + + if (str == null || str.Length <= 0) + str = new char[30]; + + var valChar = val.ToCharArray(); + var len = valChar.Length <= 30 ? valChar.Length : 30; + + for (var i = 0; i < len; i++) { + Checksum += (byte)valChar[i]; + str[i] = valChar[i]; + } + } + + public override string ToString() { + return new string(str); + } +}