From 32e057133bb5478cacf708616141a06af38fe7ba Mon Sep 17 00:00:00 2001 From: Norbyte Date: Tue, 23 Apr 2019 21:15:46 +0200 Subject: [PATCH] Use a package blacklist instead of a whitelist Allows handling future updates properly --- LSLib/LS/Common.cs | 2 +- StoryCompiler/ModResources.cs | 141 ++++++++++++++++++----------- StoryCompiler/StoryCompiler.csproj | 2 +- 3 files changed, 89 insertions(+), 56 deletions(-) diff --git a/LSLib/LS/Common.cs b/LSLib/LS/Common.cs index a5e81017..070a5f0a 100644 --- a/LSLib/LS/Common.cs +++ b/LSLib/LS/Common.cs @@ -6,7 +6,7 @@ public static class Common { public const int MajorVersion = 1; public const int MinorVersion = 12; - public const int PatchVersion = 3; + public const int PatchVersion = 4; /// /// Returns the version number of the LSLib library diff --git a/StoryCompiler/ModResources.cs b/StoryCompiler/ModResources.cs index 75c24eb6..31d2b62f 100644 --- a/StoryCompiler/ModResources.cs +++ b/StoryCompiler/ModResources.cs @@ -23,11 +23,13 @@ public ModInfo(String name) public class ModResources : IDisposable { - private static Regex scriptRe = new Regex("^Mods/(.*)/Story/RawFiles/Goals/(.*\\.txt)$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); - private static Regex orphanQueryIgnoresRe = new Regex("^Mods/(.*)/Story/story_orphanqueries_ignore_local\\.txt$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); - private static Regex globalsRe = new Regex("^Mods/(.*)/Globals/.*/.*/.*\\.lsf$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); - private static Regex levelObjectsRe = new Regex("^Mods/(.*)/Levels/.*/(Characters|Items|Triggers)/.*\\.lsf$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); - + private static readonly Regex scriptRe = new Regex("^Mods/(.*)/Story/RawFiles/Goals/(.*\\.txt)$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); + private static readonly Regex orphanQueryIgnoresRe = new Regex("^Mods/(.*)/Story/story_orphanqueries_ignore_local\\.txt$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); + private static readonly Regex globalsRe = new Regex("^Mods/(.*)/Globals/.*/.*/.*\\.lsf$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); + private static readonly Regex levelObjectsRe = new Regex("^Mods/(.*)/Levels/.*/(Characters|Items|Triggers)/.*\\.lsf$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); + // Pattern for excluding subsequent parts of a multi-part archive + private static readonly Regex archivePartRe = new Regex("^(.*)_[1-9]\\.pak$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); + public Dictionary Mods = new Dictionary(); public AbstractFileInfo StoryHeaderFile; public TargetGame Game = TargetGame.DOS2; @@ -96,89 +98,120 @@ private void AddLevelObjectsToMod(string modName, string path, AbstractFileInfo GetMod(modName).LevelObjects[path] = file; } - private void DiscoverPackage(string packagePath) + private void DiscoverPackagedFile(AbstractFileInfo file) { - var reader = new PackageReader(packagePath); - var package = reader.Read(); - foreach (var file in package.Files) + if (file.Name.EndsWith(".txt", StringComparison.Ordinal) && file.Name.Contains("/Story/RawFiles/Goals")) { - if (file.Name.EndsWith(".txt", StringComparison.Ordinal) && file.Name.Contains("/Story/RawFiles/Goals")) + var match = scriptRe.Match(file.Name); + if (match != null && match.Success) { - var match = scriptRe.Match(file.Name); - if (match != null && match.Success) - { - AddScriptToMod(match.Groups[1].Value, match.Groups[2].Value, file); - } + AddScriptToMod(match.Groups[1].Value, match.Groups[2].Value, file); } + } - if (file.Name.EndsWith("/Story/story_orphanqueries_ignore_local.txt", StringComparison.Ordinal)) + if (file.Name.EndsWith("/Story/story_orphanqueries_ignore_local.txt", StringComparison.Ordinal)) + { + var match = orphanQueryIgnoresRe.Match(file.Name); + if (match != null && match.Success) { - var match = orphanQueryIgnoresRe.Match(file.Name); - if (match != null && match.Success) - { - GetMod(match.Groups[1].Value).OrphanQueryIgnoreList = file; - } + GetMod(match.Groups[1].Value).OrphanQueryIgnoreList = file; } + } - if (CollectNames) + if (CollectNames) + { + if (file.Name.EndsWith(".lsf", StringComparison.Ordinal) && file.Name.Contains("/Globals/")) { - if (file.Name.EndsWith(".lsf", StringComparison.Ordinal) && file.Name.Contains("/Globals/")) + var match = globalsRe.Match(file.Name); + if (match != null && match.Success) { - var match = globalsRe.Match(file.Name); - if (match != null && match.Success) - { - AddGlobalsToMod(match.Groups[1].Value, match.Groups[0].Value, file); - } + AddGlobalsToMod(match.Groups[1].Value, match.Groups[0].Value, file); } + } - if (file.Name.EndsWith(".lsf", StringComparison.Ordinal) && file.Name.Contains("/Levels/")) + if (file.Name.EndsWith(".lsf", StringComparison.Ordinal) && file.Name.Contains("/Levels/")) + { + var match = levelObjectsRe.Match(file.Name); + if (match != null && match.Success) { - var match = levelObjectsRe.Match(file.Name); - if (match != null && match.Success) - { - AddLevelObjectsToMod(match.Groups[1].Value, match.Groups[0].Value, file); - } + AddLevelObjectsToMod(match.Groups[1].Value, match.Groups[0].Value, file); } } + } - if (file.Name.EndsWith("/Story/RawFiles/story_header.div", StringComparison.Ordinal)) + if (file.Name.EndsWith("/Story/RawFiles/story_header.div", StringComparison.Ordinal)) + { + StoryHeaderFile = new FilesystemFileInfo { - StoryHeaderFile = file; - } + FilesystemPath = @"C:\Program Files (x86)\Steam\steamapps\common\Divinity Original Sin 2\DefEd\Data\Mods\DebugDummy_fbe41258-13a8-4f1c-b5ae-c47aa18607be\Story\RawFiles\story_header.div", + Name = @"C:\Program Files (x86)\Steam\steamapps\common\Divinity Original Sin 2\DefEd\Data\Mods\DebugDummy_fbe41258-13a8-4f1c-b5ae-c47aa18607be\Story\RawFiles\story_header.div" + }; + } + } + + private void DiscoverPackage(string packagePath) + { + var reader = new PackageReader(packagePath); + LoadedPackages.Add(reader); + var package = reader.Read(); + + foreach (var file in package.Files) + { + DiscoverPackagedFile(file); } } private void DiscoverPackages(string gameDataPath) { - // We load main packages first - List packagePaths = new List + // List of packages we won't ever load + // These packages don't contain any mod resources, but have a large + // file table that makes loading unneccessarily slow. + HashSet packageBlacklist = new HashSet { - "Arena.pak", - "GameMaster.pak", - "Origins.pak", - "Shared.pak" + "Effects.pak", + "Engine.pak", + "EngineShaders.pak", + "Game.pak", + "GamePlatform.pak", + "Icons.pak", + "LowTex.pak", + "Materials.pak", + "Minimaps.pak", + "SharedSoundBanks.pak", + "SharedSounds.pak", + "Textures.pak" }; - - if (Game == TargetGame.DOS2DE) + + // Load non-patch packages first + foreach (var path in Directory.GetFiles(gameDataPath, "*.pak")) { - packagePaths.Add("SharedDOS.pak"); + var baseName = Path.GetFileName(path); + if (!baseName.StartsWith("Patch") + && !packageBlacklist.Contains(baseName) + // Don't load 2nd, 3rd, ... parts of a multi-part archive + && !archivePartRe.IsMatch(baseName)) + { + DiscoverPackage(path); + } } // ... and add patch files later foreach (var path in Directory.GetFiles(gameDataPath, "Patch*.pak")) { - packagePaths.Add(Path.GetFileName(path)); + DiscoverPackage(path); } + } - foreach (var relativePath in packagePaths) + public void DiscoverUserPackages(string gameDataPath) + { + foreach (var packagePath in Directory.GetFiles(gameDataPath, "*.pak")) { - var baseName = Path.GetFileNameWithoutExtension(relativePath); - // Skip parts 2, 3, etc. of multi-part packages - if (baseName[baseName.Length - 2] == '_') continue; - - var packagePath = gameDataPath + "\\" + relativePath; - DiscoverPackage(packagePath); + // Don't load 2nd, 3rd, ... parts of a multi-part archive + if (!archivePartRe.IsMatch(packagePath)) + { + DiscoverPackage(packagePath); + } } } diff --git a/StoryCompiler/StoryCompiler.csproj b/StoryCompiler/StoryCompiler.csproj index 4be9fba1..f2116e23 100644 --- a/StoryCompiler/StoryCompiler.csproj +++ b/StoryCompiler/StoryCompiler.csproj @@ -12,6 +12,7 @@ 512 true + false publish\ true Disk @@ -24,7 +25,6 @@ true 0 1.0.0.%2a - false false true