Merge pull request #947 from erri120/dd-mo2-fix

Fixes for DD MO2 implementation
This commit is contained in:
Timothy Baldridge 2020-07-06 04:38:31 -07:00 committed by GitHub
commit 92b915c7ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 83 additions and 75 deletions

View File

@ -190,7 +190,7 @@ namespace Wabbajack.Common
/// </summary>
public static GameMetaData GetByFuzzyName(string someName)
{
return TryGetByFuzzyName(someName) ?? throw new ArgumentNullException($"{someName} could not be translated to a game");
return TryGetByFuzzyName(someName) ?? throw new ArgumentNullException(nameof(someName), $"\"{someName}\" could not be translated to a game!");
}
/// <summary>

View File

@ -23,7 +23,7 @@ namespace Wabbajack.Common.StoreHandlers
{
public readonly SteamGame Game;
public int ItemID;
public int Size;
public long Size;
public SteamWorkshopItem(SteamGame game)
{
@ -210,7 +210,7 @@ namespace Wabbajack.Common.StoreHandlers
.Where(f => f.IsFile)
.Do(f =>
{
if (f.FileName.ToString() != $"appworkshop{game.ID}.acf")
if (f.FileName.ToString() != $"appworkshop_{game.ID}.acf")
return;
Utils.Log($"Found Steam Workshop item file {f} for \"{game.Name}\"");
@ -284,7 +284,7 @@ namespace Wabbajack.Common.StoreHandlers
return;
if (currentLine == bracketStart + 1)
if (!int.TryParse(GetVdfValue(l), out currentItem.Size))
if (!long.TryParse(GetVdfValue(l), out currentItem.Size))
return;
if (bracketStart == 0 || bracketEnd == 0 || currentItem.ItemID == 0 || currentItem.Size == 0)
@ -305,14 +305,15 @@ namespace Wabbajack.Common.StoreHandlers
private static string GetVdfValue(string line)
{
var trim = line.Trim('\t').Replace("\t", "");
string[] s = trim.Split('\"');
return s[3].Replace("\\\\", "\\");
var split = trim.Split('\"');
return split.Length >= 4 ? split[3].Replace("\\\\", "\\") : string.Empty;
}
private static string GetSingleVdfValue(string line)
{
var trim = line.Trim('\t').Replace("\t", "");
return trim.Split('\"')[1];
var split = trim.Split('\"');
return split.Length >= 2 ? split[1] : string.Empty;
}
}
}

View File

@ -1,46 +0,0 @@
using System;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Newtonsoft.Json;
using Wabbajack.Common;
namespace Wabbajack.Lib.CompilationSteps
{
public class IncludeGenericGamePlugin : ACompilationStep
{
private readonly bool _validGame;
private readonly string _pluginsFolder = string.Empty;
private readonly string _gameName = string.Empty;
public IncludeGenericGamePlugin(ACompiler compiler) : base(compiler)
{
if (!(compiler is MO2Compiler mo2Compiler))
return;
if (mo2Compiler.CompilingGame.NexusName == null)
return;
_validGame = mo2Compiler.CompilingGame.IsGenericMO2Plugin;
_pluginsFolder = mo2Compiler.MO2Folder.Combine("plugins").ToString();
_gameName = $"game_{mo2Compiler.CompilingGame.NexusName}.py";
}
private static Regex regex = new Regex(@"^game_$");
public override async ValueTask<Directive?> Run(RawSourceFile source)
{
if (!_validGame)
return null;
if (!source.AbsolutePath.ToString().StartsWith(_pluginsFolder))
return null;
if(!source.AbsolutePath.FileName.ToString().Equals(_gameName, StringComparison.InvariantCultureIgnoreCase))
return null;
var res = source.EvolveTo<InlineFile>();
res.SourceDataID = await _compiler.IncludeFile(await source.AbsolutePath.ReadAllBytesAsync());
return res;
}
}
}

View File

@ -16,6 +16,7 @@ namespace Wabbajack.Lib.CompilationSteps
private VirtualFile? _bsa;
private Dictionary<RelativePath, IEnumerable<VirtualFile>> _indexedByName;
private MO2Compiler _mo2Compiler;
private bool _isGenericGame;
public IncludePatches(ACompiler compiler, VirtualFile? constructingFromBSA = null) : base(compiler)
{
@ -30,10 +31,18 @@ namespace Wabbajack.Lib.CompilationSteps
.Where(f => f.IsNative)
.GroupBy(f => f.FullPath.FileName)
.ToDictionary(f => f.Key, f => (IEnumerable<VirtualFile>)f);
_isGenericGame = _mo2Compiler.CompilingGame.IsGenericMO2Plugin;
}
public override async ValueTask<Directive?> Run(RawSourceFile source)
{
if (_isGenericGame)
{
if (source.Path.StartsWith(Consts.GameFolderFilesDir))
return null;
}
var name = source.File.Name.FileName;
RelativePath nameWithoutExt = name;
if (name.Extension == Consts.MOHIDDEN)

View File

@ -1,5 +1,6 @@
using System;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Alphaleonis.Win32.Filesystem;
@ -10,31 +11,55 @@ namespace Wabbajack.Lib.CompilationSteps
{
public class IncludeSteamWorkshopItems : ACompilationStep
{
private readonly SteamGame _game;
private readonly Regex _regex = new Regex("steamWorkshopItem_\\d*\\.meta$");
private readonly bool _isGenericGame;
private readonly SteamGame? _game;
public IncludeSteamWorkshopItems(ACompiler compiler, SteamGame steamGame) : base(compiler)
public IncludeSteamWorkshopItems(ACompiler compiler) : base(compiler)
{
_game = steamGame;
var mo2Compiler = (MO2Compiler)compiler;
_isGenericGame = mo2Compiler.CompilingGame.IsGenericMO2Plugin;
_game = (SteamGame)StoreHandler.Instance.SteamHandler.Games.FirstOrDefault(x =>
mo2Compiler.CompilingGame.SteamIDs!.Contains(x.ID));
}
public override async ValueTask<Directive?> Run(RawSourceFile source)
{
if (!_isGenericGame)
return null;
if (_game == null)
return null;
if (!_regex.IsMatch((string)source.Path))
return null;
try
{
var lines = await source.AbsolutePath.ReadAllLinesAsync();
var id = 0;
lines.Where(l => l.StartsWith("itemID=")).Do(l => int.TryParse(l.Replace("itemID=", ""), out id));
var sID = lines.FirstOrDefault(l => l.StartsWith("itemID="))?.Replace("itemID=", "");
if (string.IsNullOrEmpty(sID))
{
Utils.Error($"Found no itemID= in file {source.AbsolutePath}!");
return null;
}
if(!int.TryParse(sID, out var id))
{
Utils.Error($"Unable to parse int {sID} in {source.AbsolutePath}");
return null;
}
//Get-ChildItem -Name -Directory | ForEach-Object -Process {Out-File -FilePath .\steamWorkshopItem_$_.meta -InputObject "itemID=$($_)" -Encoding utf8}
if (id == 0)
return null;
SteamWorkshopItem? item = null;
_game.WorkshopItems.Where(i => i.ItemID == id).Do(i => item = i);
SteamWorkshopItem? item = _game.WorkshopItems.FirstOrDefault(x => x.ItemID == id);
if (item == null)
{
Utils.Error($"Unable to find workshop item with ID {id} in loaded workshop item list!");
return null;
}
var fromSteam = source.EvolveTo<SteamMeta>();
fromSteam.SourceDataID = await _compiler.IncludeFile(source.AbsolutePath);

View File

@ -68,7 +68,8 @@ namespace Wabbajack.Lib.Downloaders
public static async Task<AbstractDownloadState> ResolveArchive(dynamic ini, bool quickMode = false)
{
var states = await Task.WhenAll(Downloaders.Select(d => (Task<AbstractDownloadState>)d.GetDownloaderState(ini, quickMode)));
var states = await Task.WhenAll(Downloaders.Select(d =>
(Task<AbstractDownloadState>)d.GetDownloaderState(ini, quickMode)));
return states.FirstOrDefault(result => result != null);
}

View File

@ -58,6 +58,7 @@ namespace Wabbajack.Lib.Downloaders
if (general.modID != null && general.fileID != null && general.gameName != null)
{
var game = GameRegistry.GetByFuzzyName((string)general.gameName).Game;
if (quickMode)
{
return new State

View File

@ -204,20 +204,27 @@ namespace Wabbajack.Lib
{
foreach (var ag in AvailableGames)
{
var files = await ClientAPI.GetExistingGameFiles(Queue, ag);
Utils.Log($"Including {files.Length} stock game files from {ag} as download sources");
IndexedArchives.AddRange(files.Select(f =>
try
{
var meta = f.State.GetMetaIniString();
var ini = meta.LoadIniString();
var state = (GameFileSourceDownloader.State)f.State;
return new IndexedArchive(
VFS.Index.ByRootPath[ag.MetaData().GameLocation().Combine(state.GameFile)])
var files = await ClientAPI.GetExistingGameFiles(Queue, ag);
Utils.Log($"Including {files.Length} stock game files from {ag} as download sources");
IndexedArchives.AddRange(files.Select(f =>
{
IniData = ini, Meta = meta,
};
}));
var meta = f.State.GetMetaIniString();
var ini = meta.LoadIniString();
var state = (GameFileSourceDownloader.State)f.State;
return new IndexedArchive(
VFS.Index.ByRootPath[ag.MetaData().GameLocation().Combine(state.GameFile)])
{
IniData = ini, Meta = meta,
};
}));
}
catch (Exception e)
{
Utils.Error(e, "Unable to find existing game files, skipping.");
}
}
}
@ -397,7 +404,15 @@ namespace Wabbajack.Lib
{
var metaname = filename.WithExtension(Consts.MetaFileExtension);
if (!metaname.Exists) return true;
return await DownloadDispatcher.ResolveArchive(metaname.LoadIniFile()) == null;
try
{
return await DownloadDispatcher.ResolveArchive(metaname.LoadIniFile()) == null;
}
catch (Exception e)
{
Utils.ErrorThrow(e, $"Exception while checking meta {filename}");
return false;
}
}
var to_find = (await MO2DownloadsFolder.EnumerateFiles()
@ -576,7 +591,7 @@ namespace Wabbajack.Lib
{
new IgnoreGameFilesIfGameFolderFilesExist(this),
new IncludePropertyFiles(this),
new IncludeGenericGamePlugin(this),
//new IncludeSteamWorkshopItems(this),
new IgnoreSaveFiles(this),
new IgnoreStartsWith(this,"logs\\"),
new IgnoreStartsWith(this, "downloads\\"),
@ -623,6 +638,8 @@ namespace Wabbajack.Lib
new IgnoreEndsWith(this, "portable.txt"),
new IgnoreEndsWith(this, ".bin"),
new IgnoreEndsWith(this, ".refcache"),
//Include custom categories
new IncludeRegex(this, "categories.dat$"),
new IgnoreWabbajackInstallCruft(this),