diff --git a/ShinRyuModManager-CE/GameModel.cs b/ShinRyuModManager-CE/GameModel.cs index 11eccdd..61c94e3 100644 --- a/ShinRyuModManager-CE/GameModel.cs +++ b/ShinRyuModManager-CE/GameModel.cs @@ -31,9 +31,9 @@ public static void DoY5HActProcedure(MLO mlo) { var filePath = Path.Combine("mods", mod, file.Name.Trim('/')); var fileInfo = new FileInfo(filePath); // Get the folder from a path like so -> data/hact/h5000_some_hact/cmn/cmn.bin - var hactDir = fileInfo.Directory.Parent.Name; + var hactDir = fileInfo.Directory!.Parent!.Name; - if (fileInfo.Directory.Parent.Parent.Name == "hact") { + if (fileInfo.Directory.Parent.Parent!.Name == "hact") { var hactPath = fileInfo.Directory.Parent.FullName; var parPath = Path.Combine(fileInfo.Directory.Parent.Parent.FullName, hactDir + ".par"); @@ -65,7 +65,7 @@ public static void DoY5HActProcedure(MLO mlo) { foreach (var hactDirPath in hactDirs) { var hactDir = new DirectoryInfo(hactDirPath); - var parlessDir = new DirectoryInfo(Path.Combine(GamePath.ModsPath, "Parless", "hact", hactDir.Name)); + var parlessDir = new DirectoryInfo(Path.Combine(GamePath.ParlessDir, "hact", hactDir.Name)); if (!parlessDir.Exists) parlessDir.Create(); @@ -94,7 +94,28 @@ public static void DoY5HActProcedure(MLO mlo) { } } - Gibbed.Yakuza0.Pack.Program.Main([parlessDir.FullName], Path.Combine(parlessDir.Parent.FullName, $"{hactDir.Name}.par")); + Gibbed.Yakuza0.Pack.Program.Main([parlessDir.FullName], Path.Combine(parlessDir.Parent!.FullName, $"{hactDir.Name}.par")); + } + } + + public static void DoY0DCLegacyModelSupport(MLO mlo) { + var parlessDir = new DirectoryInfo(GamePath.ParlessDir); + + parlessDir.Create(); + + foreach (var modName in mlo.Mods) { + var modDir = Path.Combine(GamePath.ModsPath, modName); + + if (!Directory.Exists(modDir)) + continue; + + var legacyCharaDir = Path.Combine(modDir, "chara", "w64"); + var newCharaDir = Path.Combine(parlessDir.FullName, "chara", "ngen"); + + if (!Directory.Exists(legacyCharaDir)) + continue; + + Utils.CopyDirectory(legacyCharaDir, newCharaDir); } } @@ -111,9 +132,9 @@ public static void DoOEHActProcedure(MLO mlo) { var fileInfo = new FileInfo(filePath); //get the folder from a path like this -> data/hact/h5000_some_hact/cmn/cmn.bin - var hactDir = fileInfo.Directory.Parent.Name; + var hactDir = fileInfo.Directory!.Parent!.Name; - if (fileInfo.Directory.Parent.Parent.Name == "hact") { + if (fileInfo.Directory.Parent.Parent!.Name == "hact") { var hactPath = fileInfo.Directory.Parent.FullName; var parPath = Path.Combine(fileInfo.Directory.Parent.Parent.FullName, hactDir + ".par"); @@ -126,10 +147,8 @@ public static void DoOEHActProcedure(MLO mlo) { if (!Directory.Exists(Path.Combine(hactPath, "000")) || !Directory.Exists(Path.Combine(hactPath, "cmn"))) continue; - if (hactDirs.Contains(hactPath)) + if (!hactDirs.Add(hactPath)) continue; - - hactDirs.Add(hactPath); } hasHacts = true; @@ -142,22 +161,22 @@ public static void DoOEHActProcedure(MLO mlo) { foreach (var hactDirPath in hactDirs) { var hactDir = new DirectoryInfo(hactDirPath); - var parlessDir = new DirectoryInfo(Path.Combine(GamePath.ModsPath, "Parless", "hact", hactDir.Name)); + var parlessDir = new DirectoryInfo(Path.Combine(GamePath.ParlessDir, "hact", hactDir.Name)); if (!parlessDir.Exists) parlessDir.Create(); - foreach (var dir in hactDir.GetDirectories()) { + foreach (var dirName in hactDir.EnumerateDirectories().Select(x => x.Name)) { //We already repack ptc - if (dir.Name == "ptc" /*&& File.Exists(Path.Combine(hactDir.FullName, "ptc.par"))*/) + if (dirName == "ptc" /*&& File.Exists(Path.Combine(hactDir.FullName, "ptc.par"))*/) continue; - var outputFakeDir = Path.Combine(parlessDir.FullName, dir.Name); + var outputFakeDir = Path.Combine(parlessDir.FullName, dirName); if(!Directory.Exists(outputFakeDir)) Directory.CreateDirectory(outputFakeDir); - var outputPath = Path.Combine(parlessDir.FullName, dir.Name + ".par"); + var outputPath = Path.Combine(parlessDir.FullName, dirName + ".par"); Gibbed.Yakuza0.Pack.Program.Main([outputFakeDir], outputPath); @@ -168,7 +187,7 @@ public static void DoOEHActProcedure(MLO mlo) { } } - Gibbed.Yakuza0.Pack.Program.Main([parlessDir.FullName], Path.Combine(parlessDir.Parent.FullName, hactDir.Name + ".par")); + Gibbed.Yakuza0.Pack.Program.Main([parlessDir.FullName], Path.Combine(parlessDir.Parent!.FullName, hactDir.Name + ".par")); } } @@ -185,9 +204,9 @@ public static void DoDEHActProcedure(MLO mlo, string codename) { var fileInfo = new FileInfo(filePath); //get the folder from a path like this -> data/hact_yazawa/h5000_some_hact/cmn/cmn.bin - var hactDir = fileInfo.Directory.Parent.Name; + var hactDir = fileInfo.Directory!.Parent!.Name; - if (fileInfo.Directory.Parent.Parent.Name == $"hact_{codename}") { + if (fileInfo.Directory.Parent.Parent!.Name == $"hact_{codename}") { var hactPath = fileInfo.Directory.Parent.FullName; var parPath = Path.Combine(fileInfo.Directory.Parent.Parent.FullName, hactDir + ".par"); @@ -219,7 +238,7 @@ public static void DoDEHActProcedure(MLO mlo, string codename) { foreach (var hactDirPath in hactDirs) { var hactDir = new DirectoryInfo(hactDirPath); - var parlessDir = new DirectoryInfo(Path.Combine(GamePath.ModsPath, "Parless", "hact_" + codename, hactDir.Name)); + var parlessDir = new DirectoryInfo(Path.Combine(GamePath.ParlessDir, "hact_" + codename, hactDir.Name)); if (!parlessDir.Exists) parlessDir.Create(); @@ -233,7 +252,7 @@ public static void DoDEHActProcedure(MLO mlo, string codename) { Gibbed.Yakuza0.Pack.Program.Main([dir.FullName], outputPath); } - Gibbed.Yakuza0.Pack.Program.Main([parlessDir.FullName], Path.Combine(parlessDir.Parent.FullName, hactDir.Name + ".par")); + Gibbed.Yakuza0.Pack.Program.Main([parlessDir.FullName], Path.Combine(parlessDir.Parent!.FullName, hactDir.Name + ".par")); new DirectoryInfo(parlessDir.FullName).Delete(true); } @@ -267,12 +286,12 @@ public static void DoUBIKProcedure(MLO mlo) { foreach (var node in ubik!.Children) { var ubikFile = node.GetFormatAs(); - if (ubikFile.IsCompressed) + if (ubikFile!.IsCompressed) node.TransformWith(); var filePath = Path.Combine(ubikDir, node.Name); - if (node.Stream.Length > 0) + if (node.Stream!.Length > 0) node.Stream.WriteTo(filePath); } diff --git a/ShinRyuModManager-CE/ModLoadOrder/CpkPatcher.cs b/ShinRyuModManager-CE/ModLoadOrder/CpkPatcher.cs index 0d17f0a..e516d7b 100644 --- a/ShinRyuModManager-CE/ModLoadOrder/CpkPatcher.cs +++ b/ShinRyuModManager-CE/ModLoadOrder/CpkPatcher.cs @@ -14,15 +14,12 @@ public static async Task RepackDictionary(Dictionary> cpkDi Log.Information("Repacking CPKs..."); - var cpkPath = Path.Combine(GamePath.ModsPath, "Parless"); - - if (!Directory.Exists(cpkPath)) - Directory.CreateDirectory(cpkPath); + Directory.CreateDirectory(GamePath.ParlessDir); foreach (var kvp in cpkDict) { var key = kvp.Key.Trim(Path.DirectorySeparatorChar); - var cpkDir = Path.Combine(cpkPath, key); + var cpkDir = Path.Combine(GamePath.ParlessDir, key); string origCpk; diff --git a/ShinRyuModManager-CE/ModLoadOrder/Mods/Mod.cs b/ShinRyuModManager-CE/ModLoadOrder/Mods/Mod.cs index 5f8c38d..f227b8d 100644 --- a/ShinRyuModManager-CE/ModLoadOrder/Mods/Mod.cs +++ b/ShinRyuModManager-CE/ModLoadOrder/Mods/Mod.cs @@ -202,7 +202,7 @@ public void AddFiles(string path, string check) { if (!Directory.Exists(gmtFolderPath)) break; - var baseParlessPath = Path.Combine(GamePath.ModsPath, "Parless", "motion", "gmt"); + var baseParlessPath = Path.Combine(GamePath.ParlessDir, "motion", "gmt"); foreach (var p in Directory.GetFiles(gmtFolderPath).Where(f => !f.EndsWith(Constants.VORTEX_MANAGED_FILE)).Select(GamePath.GetDataPathFrom)) { // Copy any gmts to the appropriate hash folder in Parless diff --git a/ShinRyuModManager-CE/ParRepacker.cs b/ShinRyuModManager-CE/ParRepacker.cs index 1b67ab7..7dd2231 100644 --- a/ShinRyuModManager-CE/ParRepacker.cs +++ b/ShinRyuModManager-CE/ParRepacker.cs @@ -26,17 +26,15 @@ private static void DeleteDirectory(string targetDirectory) { } public static void RemoveOldRepackedPars() { - var pathToParlessMods = Path.Combine(GamePath.ModsPath, "Parless"); - - if (!Directory.Exists(pathToParlessMods)) + if (!Directory.Exists(GamePath.ParlessDir)) return; Log.Information("Removing old pars..."); try { - DeleteDirectory(pathToParlessMods); + DeleteDirectory(GamePath.ParlessDir); } catch { - Log.Warning("Failed to remove old pars! {PathToParlessMods}", pathToParlessMods); + Log.Warning("Failed to remove old pars! {PathToParlessMods}", GamePath.ParlessDir); } Log.Information("Removed old pars."); @@ -58,10 +56,6 @@ public static async Task RepackDictionary(Dictionary> parDi } await Task.WhenAll(parTasks); - - /*foreach (var parModPair in parDictionary) { - RepackPar(parModPair.Key, parModPair.Value); - }*/ Log.Information("Repacked {ParDictionaryCount} par(s)!", parDictionary.Count); } @@ -71,7 +65,13 @@ private static void RepackPar(string parPath, List mods) { var parPathReal = GamePath.GetRootParPath(parPath + ".par"); var pathToPar = Path.Combine(GamePath.DataPath, parPathReal); - var pathToModPar = Path.Combine(GamePath.ModsPath, "Parless", parPath + ".par"); + var pathToModPar = Path.Combine(GamePath.ParlessDir, parPath + ".par"); + + if (string.IsNullOrEmpty(parPathReal)) { + Log.Information("ParRepacker: ParPathReal is empty for {ParPath} - skipping", parPath); + + return; + } // Check if actual repackable par is nested if (parPath + ".par" != parPathReal) { diff --git a/ShinRyuModManager-CE/Program.cs b/ShinRyuModManager-CE/Program.cs index 4222aaf..51180b9 100644 --- a/ShinRyuModManager-CE/Program.cs +++ b/ShinRyuModManager-CE/Program.cs @@ -28,23 +28,19 @@ public static class Program { private static bool _isSilent; private static bool _migrated; private static IniData _iniData; - - private static readonly FileIniDataParser IniParser; + + private static readonly FileIniDataParser IniParser = new() { + Parser = { + Configuration = { + AssigmentSpacer = string.Empty + } + } + }; public static bool RebuildMlo { get; private set; } = true; public static bool IsRebuildMloSupported { get; private set; } = true; public static LogEventLevel LogLevel { get; private set; } = LogEventLevel.Information; public static List LibraryMetaCache { get; set; } = []; - - static Program() { - IniParser = new FileIniDataParser { - Parser = { - Configuration = { - AssigmentSpacer = string.Empty - } - } - }; - } [STAThread] private static void Main(string[] args) { @@ -149,10 +145,8 @@ private static void LoadConfig() { _looseFilesEnabled = int.Parse(looseFiles) == 1; } - if (_iniData.TryGetKey("RyuModManager.Verbose", out var verbose)) { - if (int.Parse(verbose) == 1) { - LogLevel = LogEventLevel.Verbose; - } + if (_iniData.TryGetKey("RyuModManager.Verbose", out var verbose) && int.Parse(verbose) == 1) { + LogLevel = LogEventLevel.Verbose; } if (_iniData.TryGetKey("RyuModManager.CheckForUpdates", out var check)) { @@ -193,18 +187,9 @@ private static void LoadConfig() { } internal static List PreRun() { - if (GamePath.CurrentGame != Game.Unsupported && !Directory.Exists(GamePath.MODS)) { - if (!Directory.Exists(GamePath.MODS)) { - // Create mods folder if it does not exist - Log.Information($"\"{GamePath.MODS}\" folder was not found. Creating empty folder... "); - Directory.CreateDirectory(GamePath.MODS); - } - - if (!Directory.Exists(GamePath.LIBRARIES)) { - // Create libraries folder if it does not exist - Log.Information($"\"{GamePath.LIBRARIES}\" folder was not found. Creating empty folder... "); - Directory.CreateDirectory(GamePath.LIBRARIES); - } + if (GamePath.CurrentGame != Game.Unsupported) { + Directory.CreateDirectory(GamePath.MODS); + Directory.CreateDirectory(GamePath.LIBRARIES); } // TODO: Maybe move this to a separate "Game patches" file @@ -245,15 +230,14 @@ internal static List PreRun() { // Read ini (again) to check if we should try importing the old load order file _iniData = IniParser.ReadFile(Constants.INI); - if (GamePath.CurrentGame is Game.Judgment or Game.LostJudgment or Game.LikeADragonPirates) { + if (GamePath.CurrentGame is Game.Judgment or Game.LostJudgment or Game.LikeADragonPirates + && _iniData.TryGetKey("Overrides.RebuildMLO", out _)) { // Disable RebuildMLO when using an external mod manager - if (_iniData.TryGetKey("Overrides.RebuildMLO", out _)) { - Log.Warning("Game specific patch: Disabling RebuildMLO for some games when using an external mod manager..."); - - _iniData.Sections["Overrides"]["RebuildMLO"] = "0"; - IniParser.WriteFile(Constants.INI, _iniData); - RebuildMlo = false; - } + Log.Warning("Game specific patch: Disabling RebuildMLO for some games when using an external mod manager..."); + + _iniData.Sections["Overrides"]["RebuildMLO"] = "0"; + IniParser.WriteFile(Constants.INI, _iniData); + RebuildMlo = false; } var mods = new List(); @@ -293,12 +277,9 @@ internal static List PreRun() { } } - if (!GamePath.IsXbox(Path.Combine(GamePath.FullGamePath))) - return mods; - - if (!_iniData.TryGetKey("Overrides.RebuildMLO", out _)) + if (!GamePath.IsXbox(Path.Combine(GamePath.FullGamePath)) || !_iniData.TryGetKey("Overrides.RebuildMLO", out _)) return mods; - + Log.Warning("Game specific patch: Disabling RebuildMLO for Xbox games..."); _iniData.Sections["Overrides"]["RebuildMLO"] = "0"; @@ -318,78 +299,81 @@ internal static async Task RunGeneration(List mods) { // Remove previously repacked pars, to avoid unwanted side effects ParRepacker.RemoveOldRepackedPars(); + + if (GamePath.CurrentGame == Game.Unsupported) { + Log.Warning("Aborting: No supported game was found in this directory"); + + return; + } - if (GamePath.CurrentGame != Game.Unsupported) { - if (mods is { Count: > 0 } || _looseFilesEnabled) { - // Create Parless mod as highest priority - mods.Remove("Parless"); - mods.Insert(0, "Parless"); + if (mods is { Count: > 0 } || _looseFilesEnabled) { + // Create Parless mod as highest priority + mods.Remove("Parless"); + mods.Insert(0, "Parless"); - Directory.CreateDirectory(Constants.PARLESS_MODS_PATH); + Directory.CreateDirectory(Constants.PARLESS_MODS_PATH); - Log.Information("Generating MLO..."); + Log.Information("Generating MLO..."); + + var sw = Stopwatch.StartNew(); + + var result = await Generator.GenerateModeLoadOrder(mods, _looseFilesEnabled, _cpkRepackingEnabled); + + if (GameModel.SupportsUBIK(GamePath.CurrentGame)) { + GameModel.DoUBIKProcedure(result); + } - var sw = Stopwatch.StartNew(); + switch (GamePath.CurrentGame) { + case Game.Yakuza5: + GameModel.DoY5HActProcedure(result); + break; - var result = await Generator.GenerateModeLoadOrder(mods, _looseFilesEnabled, _cpkRepackingEnabled); + case Game.Yakuza0_DC: + GameModel.DoOEHActProcedure(result); + GameModel.DoY0DCLegacyModelSupport(result); + break; - if (GameModel.SupportsUBIK(GamePath.CurrentGame)) { - GameModel.DoUBIKProcedure(result); - } - - switch (GamePath.CurrentGame) { - case Game.Yakuza5: - GameModel.DoY5HActProcedure(result); - break; - - case Game.Yakuza0: - case Game.YakuzaKiwami: - GameModel.DoOEHActProcedure(result); - break; - - case Game.YakuzaKiwami2: - GameModel.DoDEHActProcedure(result, "lexus2"); - break; - - case Game.Judgment: - GameModel.DoDEHActProcedure(result, "judge"); - break; - - case Game.YakuzaLikeADragon: - GameModel.DoDEHActProcedure(result, "yazawa"); - break; - - case Game.LikeADragonGaiden: - GameModel.DoDEHActProcedure(result, "aston"); - break; - - case Game.LostJudgment: - GameModel.DoDEHActProcedure(result, "coyote"); - break; - - case Game.LikeADragon8: - GameModel.DoDEHActProcedure(result, "elvis"); - break; - - case Game.LikeADragonPirates: - GameModel.DoDEHActProcedure(result, "spr"); - break; - - case Game.YakuzaKiwami3: - GameModel.DoDEHActProcedure(result, "lexus3"); - break; - } + case Game.Yakuza0: + case Game.YakuzaKiwami: + GameModel.DoOEHActProcedure(result); + break; - sw.Stop(); - Log.Information("MLO Generation took: {ElapsedTotalSeconds} seconds", sw.Elapsed.TotalSeconds); - - return; + case Game.YakuzaKiwami2: + GameModel.DoDEHActProcedure(result, "lexus2"); + break; + + case Game.Judgment: + GameModel.DoDEHActProcedure(result, "judge"); + break; + + case Game.YakuzaLikeADragon: + GameModel.DoDEHActProcedure(result, "yazawa"); + break; + + case Game.LikeADragonGaiden: + GameModel.DoDEHActProcedure(result, "aston"); + break; + + case Game.LostJudgment: + GameModel.DoDEHActProcedure(result, "coyote"); + break; + + case Game.LikeADragon8: + GameModel.DoDEHActProcedure(result, "elvis"); + break; + + case Game.LikeADragonPirates: + GameModel.DoDEHActProcedure(result, "spr"); + break; + + case Game.YakuzaKiwami3: + GameModel.DoDEHActProcedure(result, "lexus3"); + break; } - Log.Warning("Aborting: No mods were found, and .parless paths are disabled"); + sw.Stop(); + Log.Information("MLO Generation took: {ElapsedTotalSeconds} seconds", sw.Elapsed.TotalSeconds); } - - Log.Warning("Aborting: No supported game was found in this directory"); } private static void PostRun() { @@ -403,12 +387,6 @@ private static void PostRun() { Log.Warning($"Warning: \"{Constants.ASI}\" is missing from this directory. Shin Ryu Mod Manager will NOT function properly without this file"); } - // Calculate the checksum for the game's exe to inform the user if their version might be unsupported - if (LogLevel <= LogEventLevel.Warning && InvalidGameExe()) { - Log.Error("Warning: Game version is unrecognized. Please use the latest Steam version of the game.\n" + - "Shin Ryu Mod Manager will still generate the load order, but the game might CRASH or not function properly"); - } - if (!_isSilent) { Log.Information("Program finished. Press any key to exit..."); Console.ReadKey(); @@ -469,15 +447,6 @@ internal static bool MissingAsi() { return !File.Exists(Constants.ASI); } - internal static bool InvalidGameExe() { - return false; - - /* - string path = Path.Combine(GetGamePath(), GetGameExe()); - return GetGame() == Game.Unsupported || !GameHash.ValidateFile(path, GetGame()); - */ - } - public static List ReadModListTxt(string text) { var mods = new List(); @@ -704,10 +673,8 @@ public static async Task InstallModDependenciesAsync(string mod) { if (string.IsNullOrEmpty(meta.Dependencies)) return; - foreach (var dep in meta.Dependencies.Split(';')) { - if (!DoesLibraryExist(dep)) { - await InstallLibraryAsync(dep); - } + foreach (var dep in meta.Dependencies.Split(';').Where(x => !DoesLibraryExist(x))) { + await InstallLibraryAsync(dep); } } } diff --git a/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj b/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj index a019bfc..32976ed 100644 --- a/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj +++ b/ShinRyuModManager-CE/ShinRyuModManager-CE.csproj @@ -14,7 +14,7 @@ true - 1.3.1 + 1.3.2 $(AssemblyVersion) ShinRyuModManager-CE SRMM Studio diff --git a/ShinRyuModManager-CE/UserInterface/Assets/changelog.md b/ShinRyuModManager-CE/UserInterface/Assets/changelog.md index c05db5d..7ba7c94 100644 --- a/ShinRyuModManager-CE/UserInterface/Assets/changelog.md +++ b/ShinRyuModManager-CE/UserInterface/Assets/changelog.md @@ -1,3 +1,6 @@ +> ### **%{color:orange} Version 1.3.2 %** ### +* Implemented changes from SRMM 4.6.8 + > ### **%{color:orange} Version 1.3.1 %** ### * Repacked for updated Parless from SRMM 4.6.7 @@ -24,7 +27,7 @@ --- > ### **%{color:orange} Version 1.2.3 %** ### -* Implemented changed from SRMM 4.6.6 +* Implemented changes from SRMM 4.6.6 --- @@ -34,7 +37,7 @@ --- > ### **%{color:orange} Version 1.2.1 %** ### -* Fixed linux bug with auto updater failing to check version +* Fixed Linux bug with auto updater failing to check version --- diff --git a/ShinRyuModManager-CE/UserInterface/Views/MainWindow.axaml.cs b/ShinRyuModManager-CE/UserInterface/Views/MainWindow.axaml.cs index e8d3a92..14381ef 100644 --- a/ShinRyuModManager-CE/UserInterface/Views/MainWindow.axaml.cs +++ b/ShinRyuModManager-CE/UserInterface/Views/MainWindow.axaml.cs @@ -83,10 +83,6 @@ private async Task RunPreInitAsync() { if (Program.MissingAsi()) { _ = await MessageBoxWindow.Show(this, "Warning", $"{Constants.ASI} is missing from this directory. Mods will NOT be applied without this file."); } - - if (Program.InvalidGameExe()) { - _ = await MessageBoxWindow.Show(this, "Error", "Game version is unrecognized. Please use the latest Steam version of the game. The mod list will still be saved.\nMods may still work depending on the version."); - } } } diff --git a/ShinRyuModManager-CE/Utils.cs b/ShinRyuModManager-CE/Utils.cs index 127c08f..3442abc 100644 --- a/ShinRyuModManager-CE/Utils.cs +++ b/ShinRyuModManager-CE/Utils.cs @@ -123,4 +123,23 @@ internal static bool CompareVersionIsHigher(string versionTarget, string version return false; } } + + public static void CopyDirectory(string srcDirectory, string destDirectory) { + if (!Directory.Exists(srcDirectory)) + throw new DirectoryNotFoundException($"Directory \"{srcDirectory}\" doesn't exist."); + + Directory.CreateDirectory(destDirectory); + + foreach (var file in Directory.EnumerateFiles(srcDirectory)) { + var destFile = Path.Combine(destDirectory, Path.GetFileName(file)); + + File.Copy(file, destFile, true); + } + + foreach (var dir in Directory.EnumerateDirectories(srcDirectory)) { + var destSubDir = Path.Combine(destDirectory, Path.GetFileName(dir)); + + CopyDirectory(dir, destSubDir); + } + } } diff --git a/Utils/Game.cs b/Utils/Game.cs index 045c3e9..a66c310 100644 --- a/Utils/Game.cs +++ b/Utils/Game.cs @@ -9,6 +9,7 @@ public enum Game { // Old Engine Yakuza0, + Yakuza0_DC, YakuzaKiwami, // Dragon Engine diff --git a/Utils/GameHash.cs b/Utils/GameHash.cs deleted file mode 100644 index fce478a..0000000 --- a/Utils/GameHash.cs +++ /dev/null @@ -1,62 +0,0 @@ -using System.Security.Cryptography; - -namespace Utils; - -public static class GameHash { - public static bool ValidateFile(string path, Game game) { - try { - //Xbox doesnt like being read! - if (GamePath.IsXbox(new FileInfo(path).Directory.FullName)) { - return true; - } - - using var md5Hash = MD5.Create(); - using var file = File.OpenRead(path); - var gameHash = GetGameHash(game); - - var computedHash = md5Hash.ComputeHash(file); - - return gameHash.Count <= 0 || gameHash.Any(arr => arr.SequenceEqual(computedHash)); - } catch { - return true; - } - } - - private static List GetGameHash(Game game) { - return game switch { - Game.Yakuza0 => [ - new byte[] { 168, 70, 120, 237, 170, 16, 229, 118, 232, 54, 167, 130, 194, 37, 220, 14 }, // Steam ver. - new byte[] { 32, 44, 24, 38, 67, 27, 82, 26, 205, 131, 3, 24, 44, 150, 150, 84 } // GOG ver. - ], - Game.YakuzaKiwami => [ - new byte[] { 142, 39, 38, 133, 251, 26, 47, 181, 222, 56, 98, 207, 178, 123, 175, 8 }, // Steam ver. - new byte[] { 114, 65, 77, 21, 216, 176, 138, 129, 56, 13, 182, 66, 10, 202, 126, 150 } // GOG ver. - ], - Game.YakuzaKiwami2 => [ - new byte[] { 143, 2, 192, 39, 60, 179, 172, 44, 242, 201, 155, 226, 50, 192, 204, 0 }, // Steam ver. - new byte[] { 193, 175, 140, 27, 230, 27, 94, 96, 67, 221, 175, 168, 32, 228, 240, 101 } // GOG ver. - ], - Game.Yakuza3 => [ - new byte[] { 172, 112, 65, 90, 116, 185, 119, 107, 139, 148, 48, 80, 40, 13, 107, 113 }, // Steam ver. - new byte[] { 89, 69, 173, 134, 170, 154, 242, 60, 218, 44, 38, 126, 35, 19, 173, 104 } // GOG ver. - ], - Game.Yakuza4 => [ - new byte[] { 41, 89, 36, 15, 180, 25, 237, 66, 222, 176, 78, 130, 33, 146, 77, 132 }, // Steam ver. - new byte[] { 104, 219, 147, 29, 124, 200, 240, 165, 188, 22, 150, 130, 1, 28, 224, 84 } // GOG ver. - ], - Game.Yakuza5 => [ - new byte[] { 51, 96, 128, 207, 98, 131, 90, 216, 213, 88, 198, 186, 60, 99, 176, 201 }, // Steam ver. - new byte[] { 241, 225, 30, 149, 210, 236, 3, 215, 58, 238, 223, 99, 16, 195, 221, 19 } // GOG ver. - ], - Game.Yakuza6 => [ - new byte[] { 176, 204, 180, 91, 160, 163, 81, 217, 243, 92, 5, 157, 214, 129, 217, 7 }, //Steam ver. - new byte[] { 3, 74, 1, 122, 239, 147, 32, 206, 253, 233, 202, 68, 39, 125, 126, 187 } // GOG ver. - ], - Game.YakuzaLikeADragon => [ - new byte[] { 188, 204, 133, 1, 251, 100, 190, 56, 10, 122, 164, 173, 244, 134, 246, 5 }, //Steam ver. - new byte[] { 95, 8, 201, 91, 31, 191, 26, 183, 208, 76, 54, 13, 206, 163, 188, 44, } // GOG ver. - ], - _ => [] - }; - } -} diff --git a/Utils/GamePath.cs b/Utils/GamePath.cs index cfbc391..9b6339e 100644 --- a/Utils/GamePath.cs +++ b/Utils/GamePath.cs @@ -12,6 +12,7 @@ public static class GamePath { public static string FullGamePath { get; } public static string DataPath { get; } public static string ModsPath { get; } + public static string ParlessDir { get; } public static string ExternalModsPath { get; } public static string LibrariesPath { get; } public static string GameExe { get; } @@ -20,6 +21,7 @@ static GamePath() { FullGamePath = Environment.CurrentDirectory; DataPath = Path.Combine(FullGamePath, DATA); ModsPath = Path.Combine(FullGamePath, MODS); + ParlessDir = Path.Combine(ModsPath, "Parless"); ExternalModsPath = Path.Combine(ModsPath, Constants.EXTERNAL_MODS); LibrariesPath = Path.Combine(FullGamePath, LIBRARIES); @@ -205,6 +207,7 @@ private static bool IsSteamInstalledLinux() { public static string GetGameFriendlyName(Game g) { return g switch { Game.Yakuza0 => "Yakuza 0", + Game.Yakuza0_DC => "Yakuza 0: Director's Cut", Game.YakuzaKiwami => "Yakuza Kiwami", Game.YakuzaKiwami2 => "Yakuza Kiwami 2", Game.Yakuza3 => "Yakuza 3 Remastered", @@ -228,6 +231,7 @@ public static string GetGameFriendlyName(Game g) { public static int? GetGameSteamId(Game game) { return game switch { Game.Yakuza0 => 638970, + Game.Yakuza0_DC => 2988580, Game.YakuzaKiwami => 834530, Game.YakuzaKiwami2 => 927380, Game.Yakuza3 => 1088710,