Created new SteamWorkshopDownloader and IncludeSteamWorkshopItems compilation step

This commit is contained in:
erri120 2019-12-02 17:44:24 +01:00
parent 4a3b5d8161
commit 7a38d3fb24
No known key found for this signature in database
GPG Key ID: A8C0A18D8D4D3135
4 changed files with 216 additions and 0 deletions

View File

@ -0,0 +1,70 @@
using System;
using System.Linq;
using System.Text.RegularExpressions;
using Alphaleonis.Win32.Filesystem;
using Wabbajack.Common;
namespace Wabbajack.Lib.CompilationSteps
{
public class IncludeSteamWorkshopItems : ACompilationStep
{
private readonly SteamGame _game;
private readonly Regex _regex = new Regex("steamWorkshopItem_\\d*\\.meta$");
public IncludeSteamWorkshopItems(ACompiler compiler, SteamGame steamGame) : base(compiler)
{
_game = steamGame;
}
public override Directive Run(RawSourceFile source)
{
if (!_regex.IsMatch(source.Path))
return null;
try
{
var lines = File.ReadAllLines(source.AbsolutePath);
var id = 0;
lines.Where(l => l.StartsWith("itemID=")).Do(l => int.TryParse(l.Replace("itemID=", ""), out id));
if (id == 0)
return null;
SteamWorkshopItem item = null;
_game.WorkshopItems.Where(i => i.ItemID == id).Do(i => item = i);
if (item == null)
return null;
var fromSteam = source.EvolveTo<SteamMeta>();
fromSteam.SourceDataID = _compiler.IncludeFile(source.AbsolutePath);
fromSteam.ItemID = item.ItemID;
fromSteam.Size = item.Size;
return fromSteam;
}
catch (Exception e)
{
Utils.LogToFile($"Exception while trying to evolve source to FromSteam\n{e}");
return null;
}
}
public override IState GetState()
{
return new State(_game);
}
public class State : IState
{
private readonly SteamGame _game;
public State(SteamGame game)
{
_game = game;
}
public ICompilationStep CreateStep(ACompiler compiler)
{
return new IncludeSteamWorkshopItems(compiler, _game);
}
}
}
}

View File

@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Wabbajack.Common;
using Wabbajack.Lib.Validation;
namespace Wabbajack.Lib.Downloaders
{
public class SteamWorkshopDownloader : IUrlDownloader
{
private SteamWorkshopItem _item;
public AbstractDownloadState GetDownloaderState(dynamic archiveINI)
{
var id = archiveINI?.General?.itemID;
var steamID = archiveINI?.General?.steamID;
var size = archiveINI?.General?.itemSize;
_item = new SteamWorkshopItem
{
ItemID = id != null ? int.Parse(id) : 0,
Size = size != null ? int.Parse(size) : 0,
Game = steamID != null ? GameRegistry.GetBySteamID(int.Parse(steamID)) : null
};
return new State {Item = _item};
}
public void Prepare()
{
}
public AbstractDownloadState GetDownloaderState(string url)
{
throw new NotImplementedException();
}
public class State : AbstractDownloadState
{
public SteamWorkshopItem Item { get; set; }
public override bool IsWhitelisted(ServerWhitelist whitelist)
{
return true;
}
public override void Download(Archive a, string destination)
{
var currentLib = "";
SteamHandler.Instance.InstallFolders.Where(f => f.Contains(Item.Game.InstallDir)).Do(s => currentLib = s);
var downloadFolder = Path.Combine(currentLib, "workshop", "downloads", Item.Game.AppId.ToString());
var contentFolder = Path.Combine(currentLib, "workshop", "content", Item.Game.AppId.ToString());
var p = new Process
{
StartInfo = new ProcessStartInfo
{
FileName = Path.Combine(SteamHandler.Instance.SteamPath, "steam.exe"),
CreateNoWindow = true,
Arguments = $"console +workshop_download_item {Item.Game.AppId} {Item.ItemID}"
}
};
p.Start();
//TODO: async
var finished = false;
while (!finished)
{
if(!Directory.Exists(Path.Combine(downloadFolder, Item.ItemID.ToString())))
if (Directory.Exists(Path.Combine(contentFolder, Item.ItemID.ToString())))
finished = true;
Thread.Sleep(1000);
}
}
public override bool Verify()
{
//TODO: find a way to verify steam workshop items
throw new NotImplementedException();
}
public override IDownloader GetDownloader()
{
return DownloadDispatcher.GetInstance<SteamWorkshopDownloader>();
}
public override string GetReportEntry(Archive a)
{
return $"* Steam - [{Item.ItemID}]";
}
}
}
}

View File

@ -40,6 +40,10 @@ namespace Wabbajack.Lib
public const string StagingMarkerName = "__vortex_staging_folder";
public const string DownloadMarkerName = "__vortex_downloads_folder";
private bool _isSteamGame;
private SteamGame _steamGame;
private bool _hasSteamWorkshopItems;
public VortexCompiler(Game game, string gamePath, string vortexFolder, string downloadsFolder, string stagingFolder, string outputFile)
{
Game = game;
@ -52,6 +56,15 @@ namespace Wabbajack.Lib
ModListOutputFolder = "output_folder";
ModListOutputFile = outputFile;
// there can be max one game after filtering
SteamHandler.Instance.Games.Where(g => g.Game != null && g.Game == game).Do(g =>
{
_isSteamGame = true;
_steamGame = g;
SteamHandler.Instance.LoadWorkshopItems(_steamGame);
_hasSteamWorkshopItems = _steamGame.WorkshopItems.Count > 0;
});
ActiveArchives = new List<string>();
}
@ -310,6 +323,38 @@ namespace Wabbajack.Lib
ActiveArchives.Add(Path.GetFileNameWithoutExtension(f));
}
});
Utils.Log($"Checking for Steam Workshop Items...");
if (!_isSteamGame || _steamGame == null || _steamGame.WorkshopItems.Count <= 0)
return;
_steamGame.WorkshopItems.Do(item =>
{
Utils.Log($"Creating meta file for {item.ItemID}");
var metaString = "[General]\n" +
"repository=Steam\n" +
"installed=true\n" +
$"gameName={GameName}\n" +
$"steamID={_steamGame.AppId}\n" +
$"itemID={item.ItemID}\n" +
$"itemSize={item.Size}\n";
var filePath = Path.Combine(DownloadsFolder, $"steamWorkshopItem_{item.ItemID}.meta");
if (File.Exists(filePath))
{
Utils.Log($"File {filePath} already exists, skipping...");
return;
}
try
{
File.WriteAllText(filePath, metaString);
}
catch (Exception e)
{
Utils.LogToFile($"Exception while writing to disk at {filePath}\n{e}");
}
});
}
public override IEnumerable<ICompilationStep> GetStack()
@ -333,6 +378,8 @@ namespace Wabbajack.Lib
return new List<ICompilationStep>
{
new IncludePropertyFiles(this),
new IncludeSteamWorkshopItems(this, _steamGame),
_hasSteamWorkshopItems ? new IncludeRegex(this, "^steamWorkshopItem_\\d*\\.meta$") : null,
new IgnoreDisabledVortexMods(this),
new IncludeVortexDeployment(this),
new IgnoreVortex(this),

View File

@ -103,6 +103,7 @@
<Compile Include="CompilationSteps\IncludePatches.cs" />
<Compile Include="CompilationSteps\IncludePropertyFiles.cs" />
<Compile Include="CompilationSteps\IncludeRegex.cs" />
<Compile Include="CompilationSteps\IncludeSteamWorkshopItems.cs" />
<Compile Include="CompilationSteps\IncludeStubbedConfigFiles.cs" />
<Compile Include="CompilationSteps\IncludeTaggedMods.cs" />
<Compile Include="CompilationSteps\IncludeThisProfile.cs" />
@ -110,6 +111,7 @@
<Compile Include="CompilationSteps\IStackStep.cs" />
<Compile Include="CompilationSteps\PatchStockESMs.cs" />
<Compile Include="CompilationSteps\Serialization.cs" />
<Compile Include="Downloaders\SteamWorkshopDownloader.cs" />
<Compile Include="MO2Compiler.cs" />
<Compile Include="Data.cs" />
<Compile Include="Downloaders\AbstractDownloadState.cs" />