mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
integrated the new download framework into the app
This commit is contained in:
parent
1e64544783
commit
bf11273c15
@ -551,5 +551,11 @@ namespace Wabbajack.Common
|
||||
{
|
||||
return tv.ToJSON().FromJSONString<T>();
|
||||
}
|
||||
|
||||
public static void Error(string msg)
|
||||
{
|
||||
Log(msg);
|
||||
throw new Exception(msg);
|
||||
}
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Security.Policy;
|
||||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Downloaders;
|
||||
using Wabbajack.Validation;
|
||||
using Game = Wabbajack.Common.Game;
|
||||
|
||||
@ -56,7 +57,7 @@ namespace Wabbajack.Test
|
||||
[TestMethod]
|
||||
public void TestRightsFallthrough()
|
||||
{
|
||||
var permissions = validate.FilePermissions(new NexusMod()
|
||||
var permissions = validate.FilePermissions(new NexusDownloader.State
|
||||
{
|
||||
Author = "bill",
|
||||
GameName = "Skyrim",
|
||||
@ -69,7 +70,7 @@ namespace Wabbajack.Test
|
||||
permissions.CanModifyAssets.AssertIsFalse();
|
||||
permissions.CanUseInOtherGames.AssertIsFalse();
|
||||
|
||||
permissions = validate.FilePermissions(new NexusMod()
|
||||
permissions = validate.FilePermissions(new NexusDownloader.State
|
||||
{
|
||||
Author = "bob",
|
||||
GameName = "Skyrim",
|
||||
@ -82,7 +83,7 @@ namespace Wabbajack.Test
|
||||
permissions.CanModifyAssets.AssertIsTrue();
|
||||
permissions.CanUseInOtherGames.AssertIsTrue();
|
||||
|
||||
permissions = validate.FilePermissions(new NexusMod()
|
||||
permissions = validate.FilePermissions(new NexusDownloader.State
|
||||
{
|
||||
Author = "bill",
|
||||
GameName = "Fallout4",
|
||||
@ -95,7 +96,7 @@ namespace Wabbajack.Test
|
||||
permissions.CanModifyAssets.AssertIsTrue();
|
||||
permissions.CanUseInOtherGames.AssertIsTrue();
|
||||
|
||||
permissions = validate.FilePermissions(new NexusMod()
|
||||
permissions = validate.FilePermissions(new NexusDownloader.State
|
||||
{
|
||||
Author = "bill",
|
||||
GameName = "Skyrim",
|
||||
@ -108,7 +109,7 @@ namespace Wabbajack.Test
|
||||
permissions.CanModifyAssets.AssertIsTrue();
|
||||
permissions.CanUseInOtherGames.AssertIsTrue();
|
||||
|
||||
permissions = validate.FilePermissions(new NexusMod()
|
||||
permissions = validate.FilePermissions(new NexusDownloader.State
|
||||
{
|
||||
Author = "bill",
|
||||
GameName = "Skyrim",
|
||||
@ -131,14 +132,18 @@ namespace Wabbajack.Test
|
||||
GameType = Game.Skyrim,
|
||||
Archives = new List<Archive>
|
||||
{
|
||||
new NexusMod
|
||||
new Archive
|
||||
{
|
||||
GameName = "Skyrim",
|
||||
Author = "bill",
|
||||
ModID = "42",
|
||||
FileID = "33",
|
||||
State = new NexusDownloader.State
|
||||
{
|
||||
GameName = "Skyrim",
|
||||
Author = "bill",
|
||||
ModID = "42",
|
||||
FileID = "33",
|
||||
},
|
||||
Hash = "DEADBEEF"
|
||||
}
|
||||
|
||||
},
|
||||
Directives = new List<Directive>
|
||||
{
|
||||
@ -196,44 +201,44 @@ namespace Wabbajack.Test
|
||||
|
||||
// Error due to file downloaded from 3rd party
|
||||
modlist.GameType = Game.Skyrim;
|
||||
modlist.Archives[0] = new DirectURLArchive()
|
||||
modlist.Archives[0] = new Archive()
|
||||
{
|
||||
URL = "https://somebadplace.com",
|
||||
State = new HTTPDownloader.State() { Url = "https://somebadplace.com" },
|
||||
Hash = "DEADBEEF"
|
||||
};
|
||||
errors = validate.Validate(modlist);
|
||||
Assert.AreEqual(errors.Count(), 1);
|
||||
Assert.AreEqual(1, errors.Count());
|
||||
|
||||
// Ok due to file downloaded from whitelisted 3rd party
|
||||
modlist.GameType = Game.Skyrim;
|
||||
modlist.Archives[0] = new DirectURLArchive()
|
||||
modlist.Archives[0] = new Archive
|
||||
{
|
||||
URL = "https://somegoodplace.com/myfile",
|
||||
State = new HTTPDownloader.State { Url = "https://somegoodplace.com/baz.7z" },
|
||||
Hash = "DEADBEEF"
|
||||
};
|
||||
errors = validate.Validate(modlist);
|
||||
Assert.AreEqual(errors.Count(), 0);
|
||||
Assert.AreEqual(0, errors.Count());
|
||||
|
||||
|
||||
// Error due to file downloaded from bad 3rd party
|
||||
modlist.GameType = Game.Skyrim;
|
||||
modlist.Archives[0] = new GoogleDriveMod()
|
||||
modlist.Archives[0] = new Archive
|
||||
{
|
||||
Id = "bleg",
|
||||
State = new GoogleDriveDownloader.State { Id = "bleg"},
|
||||
Hash = "DEADBEEF"
|
||||
};
|
||||
errors = validate.Validate(modlist);
|
||||
Assert.AreEqual(errors.Count(), 1);
|
||||
|
||||
// Error due to file downloaded from good 3rd party
|
||||
// Ok due to file downloaded from good google site
|
||||
modlist.GameType = Game.Skyrim;
|
||||
modlist.Archives[0] = new GoogleDriveMod()
|
||||
modlist.Archives[0] = new Archive
|
||||
{
|
||||
Id = "googleDEADBEEF",
|
||||
State = new GoogleDriveDownloader.State { Id = "googleDEADBEEF" },
|
||||
Hash = "DEADBEEF"
|
||||
};
|
||||
errors = validate.Validate(modlist);
|
||||
Assert.AreEqual(errors.Count(), 0);
|
||||
Assert.AreEqual(0, errors.Count());
|
||||
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ using System.Windows.Input;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Threading;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Downloaders;
|
||||
using Wabbajack.NexusApi;
|
||||
using Wabbajack.UI;
|
||||
|
||||
@ -484,7 +485,10 @@ namespace Wabbajack
|
||||
|
||||
ApplyModlistProperties();
|
||||
|
||||
_slideShow.SlideShowElements = modlist.Archives.OfType<NexusMod>().Select(m =>
|
||||
_slideShow.SlideShowElements = modlist.Archives
|
||||
.Select(m => m.State)
|
||||
.OfType<NexusDownloader.State>()
|
||||
.Select(m =>
|
||||
new Slide(NexusApiUtils.FixupSummary(m.ModName),m.ModID,
|
||||
NexusApiUtils.FixupSummary(m.Summary), NexusApiUtils.FixupSummary(m.Author),
|
||||
m.Adult,m.NexusURL,m.SlideShowPic)).ToList();
|
||||
|
@ -13,6 +13,7 @@ using System.Text.RegularExpressions;
|
||||
using System.Web;
|
||||
using VFS;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Downloaders;
|
||||
using Wabbajack.NexusApi;
|
||||
using Wabbajack.Validation;
|
||||
using Directory = Alphaleonis.Win32.Filesystem.Directory;
|
||||
@ -469,123 +470,21 @@ namespace Wabbajack
|
||||
{
|
||||
if (found.IniData == null)
|
||||
Error($"No download metadata found for {found.Name}, please use MO2 to query info or add a .meta file and try again.");
|
||||
var general = found.IniData.General;
|
||||
if (general == null)
|
||||
Error($"No General section in mod metadata found for {found.Name}, please use MO2 to query info or add the info and try again.");
|
||||
|
||||
Archive result;
|
||||
var result = new Archive();
|
||||
result.State = (AbstractDownloadState)DownloadDispatcher.ResolveArchive(found.IniData);
|
||||
|
||||
if (general.directURL != null && general.directURL.StartsWith("https://drive.google.com"))
|
||||
{
|
||||
var regex = new Regex("((?<=id=)[a-zA-Z0-9_-]*)|(?<=\\/file\\/d\\/)[a-zA-Z0-9_-]*");
|
||||
var match = regex.Match(general.directURL);
|
||||
result = new GoogleDriveMod
|
||||
{
|
||||
Id = match.ToString()
|
||||
};
|
||||
}
|
||||
else if (general.directURL != null && general.directURL.StartsWith(Consts.MegaPrefix))
|
||||
{
|
||||
result = new MEGAArchive
|
||||
{
|
||||
URL = general.directURL
|
||||
};
|
||||
}
|
||||
else if (general.directURL != null && general.directURL.StartsWith("https://www.dropbox.com/"))
|
||||
{
|
||||
var uri = new UriBuilder((string)general.directURL);
|
||||
var query = HttpUtility.ParseQueryString(uri.Query);
|
||||
|
||||
if (query.GetValues("dl").Count() > 0)
|
||||
query.Remove("dl");
|
||||
|
||||
query.Set("dl", "1");
|
||||
|
||||
uri.Query = query.ToString();
|
||||
|
||||
result = new DirectURLArchive
|
||||
{
|
||||
URL = uri.ToString()
|
||||
};
|
||||
}
|
||||
else if (general.directURL != null &&
|
||||
general.directURL.StartsWith("https://www.moddb.com/downloads/start"))
|
||||
{
|
||||
result = new MODDBArchive
|
||||
{
|
||||
URL = general.directURL
|
||||
};
|
||||
}
|
||||
else if (general.directURL != null && general.directURL.StartsWith("http://www.mediafire.com/file/"))
|
||||
{
|
||||
Error("MediaFire links are not currently supported");
|
||||
return null;
|
||||
/*result = new MediaFireArchive()
|
||||
{
|
||||
URL = general.directURL
|
||||
};*/
|
||||
}
|
||||
else if (general.directURL != null)
|
||||
{
|
||||
var tmp = new DirectURLArchive
|
||||
{
|
||||
URL = general.directURL
|
||||
};
|
||||
if (general.directURLHeaders != null)
|
||||
{
|
||||
tmp.Headers = new List<string>();
|
||||
tmp.Headers.AddRange(general.directURLHeaders.Split('|'));
|
||||
}
|
||||
|
||||
result = tmp;
|
||||
}
|
||||
else if (general.modID != null && general.fileID != null && general.gameName != null)
|
||||
{
|
||||
var nm = new NexusMod
|
||||
{
|
||||
GameName = general.gameName,
|
||||
FileID = general.fileID,
|
||||
ModID = general.modID,
|
||||
Version = general.version ?? "0.0.0.0"
|
||||
};
|
||||
/*var info = new NexusApiClient().GetModInfo(nm);
|
||||
nm.Author = info.author;
|
||||
nm.UploadedBy = info.uploaded_by;
|
||||
nm.UploaderProfile = info.uploaded_users_profile_url;
|
||||
nm.ModName = info.name;
|
||||
nm.SlideShowPic = info.picture_url;
|
||||
nm.NexusURL = NexusApiUtils.GetModURL(info.game_name, info.mod_id);
|
||||
nm.Summary = info.summary;
|
||||
nm.Adult = info.contains_adult_content;*/
|
||||
|
||||
result = nm;
|
||||
}
|
||||
else if (general.manualURL != null)
|
||||
{
|
||||
result = new ManualArchive
|
||||
{
|
||||
URL = general.manualURL,
|
||||
Notes = general.manualNotes,
|
||||
};
|
||||
}
|
||||
else
|
||||
{
|
||||
Error($"No way to handle archive {found.Name} but it's required by the modlist");
|
||||
return null;
|
||||
}
|
||||
if (result.State == null)
|
||||
Error($"{found.Name} could not be handled by any of the downloaders");
|
||||
|
||||
result.Name = found.Name;
|
||||
result.Hash = found.File.Hash;
|
||||
result.Meta = found.Meta;
|
||||
result.Size = found.File.Size;
|
||||
|
||||
if (result is ManualArchive) return result;
|
||||
|
||||
Info($"Checking link for {found.Name}");
|
||||
|
||||
var installer = new Installer("", null, "");
|
||||
|
||||
if (!installer.DownloadArchive(result, false))
|
||||
if (!result.State.Verify())
|
||||
Error(
|
||||
$"Unable to resolve link for {found.Name}. If this is hosted on the Nexus the file may have been removed.");
|
||||
|
||||
|
@ -4,6 +4,7 @@ using System.Collections.Generic;
|
||||
using Compression.BSA;
|
||||
using VFS;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Downloaders;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
@ -218,81 +219,7 @@ namespace Wabbajack
|
||||
public string Name;
|
||||
|
||||
public long Size;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class NexusMod : Archive
|
||||
{
|
||||
public string Author;
|
||||
public string FileID;
|
||||
public string GameName;
|
||||
public string ModID;
|
||||
public string UploadedBy;
|
||||
public string UploaderProfile;
|
||||
public string Version;
|
||||
public string SlideShowPic;
|
||||
public string ModName;
|
||||
public string NexusURL;
|
||||
public string Summary;
|
||||
public bool Adult;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class ManualArchive : Archive
|
||||
{
|
||||
public string URL;
|
||||
public string Notes;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class GoogleDriveMod : Archive
|
||||
{
|
||||
public string Id;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// URL that can be downloaded directly without any additional options
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class DirectURLArchive : Archive
|
||||
{
|
||||
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
|
||||
public List<string> Headers;
|
||||
|
||||
public string URL;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An archive that requires additional HTTP headers.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class DirectURLArchiveEx : DirectURLArchive
|
||||
{
|
||||
public Dictionary<string, string> Headers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Archive that comes from MEGA
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class MEGAArchive : DirectURLArchive
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Archive that comes from MODDB
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class MODDBArchive : DirectURLArchive
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Archive that comes from MediaFire
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class MediaFireArchive : DirectURLArchive
|
||||
{
|
||||
public AbstractDownloadState State { get; set; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
|
@ -30,5 +30,7 @@ namespace Wabbajack.Downloaders
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public abstract bool Verify();
|
||||
|
||||
public abstract IDownloader GetDownloader();
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,8 @@ namespace Wabbajack.Downloaders
|
||||
new DropboxDownloader(),
|
||||
new GoogleDriveDownloader(),
|
||||
new HTTPDownloader(),
|
||||
new NexusDownloader()
|
||||
new NexusDownloader(),
|
||||
new ManualDownloader()
|
||||
};
|
||||
|
||||
private static Dictionary<Type, IDownloader> _indexedDownloaders;
|
||||
|
@ -9,11 +9,6 @@ namespace Wabbajack.Downloaders
|
||||
{
|
||||
public class DropboxDownloader : IDownloader
|
||||
{
|
||||
public void Init()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public AbstractDownloadState GetDownloaderState(dynamic archive_ini)
|
||||
{
|
||||
var urlstring = archive_ini?.General?.directURL;
|
||||
@ -34,5 +29,9 @@ namespace Wabbajack.Downloaders
|
||||
Url = uri.ToString().Replace("dropbox.com:443/", "dropbox.com/")
|
||||
};
|
||||
}
|
||||
|
||||
public void Prepare()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -29,6 +29,10 @@ namespace Wabbajack.Downloaders
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Prepare()
|
||||
{
|
||||
}
|
||||
|
||||
public class State : AbstractDownloadState
|
||||
{
|
||||
public string Id { get; set; }
|
||||
@ -58,6 +62,11 @@ namespace Wabbajack.Downloaders
|
||||
{
|
||||
return ToHttpState().Verify();
|
||||
}
|
||||
|
||||
public override IDownloader GetDownloader()
|
||||
{
|
||||
return DownloadDispatcher.GetInstance<GoogleDriveDownloader>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,6 +36,10 @@ namespace Wabbajack.Downloaders
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Prepare()
|
||||
{
|
||||
}
|
||||
|
||||
public class State : AbstractDownloadState
|
||||
{
|
||||
public string Url { get; set; }
|
||||
@ -119,6 +123,11 @@ namespace Wabbajack.Downloaders
|
||||
{
|
||||
return DoDownload(new Archive {Name = ""}, "", false);
|
||||
}
|
||||
|
||||
public override IDownloader GetDownloader()
|
||||
{
|
||||
return DownloadDispatcher.GetInstance<HTTPDownloader>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,8 +7,13 @@ using Wabbajack.Validation;
|
||||
|
||||
namespace Wabbajack.Downloaders
|
||||
{
|
||||
interface IDownloader
|
||||
public interface IDownloader
|
||||
{
|
||||
AbstractDownloadState GetDownloaderState(dynamic archive_ini);
|
||||
|
||||
/// <summary>
|
||||
/// Called before any downloads are inacted by the installer;
|
||||
/// </summary>
|
||||
void Prepare();
|
||||
}
|
||||
}
|
||||
|
@ -24,6 +24,10 @@ namespace Wabbajack.Downloaders
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Prepare()
|
||||
{
|
||||
}
|
||||
|
||||
public class State : HTTPDownloader.State
|
||||
{
|
||||
public override void Download(Archive a, string destination)
|
||||
|
@ -39,6 +39,23 @@ namespace Wabbajack.Downloaders
|
||||
return null;
|
||||
}
|
||||
|
||||
public void Prepare()
|
||||
{
|
||||
var client = new NexusApiClient();
|
||||
var status = client.GetUserStatus();
|
||||
if (!client.IsAuthenticated)
|
||||
{
|
||||
Utils.Error($"Authenticating for the Nexus failed. A nexus account is required to automatically download mods.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!status.is_premium)
|
||||
{
|
||||
Utils.Error($"Automated installs with Wabbajack requires a premium nexus account. {client.Username} is not a premium account.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
public class State : AbstractDownloadState
|
||||
{
|
||||
public string Author;
|
||||
@ -96,6 +113,11 @@ namespace Wabbajack.Downloaders
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override IDownloader GetDownloader()
|
||||
{
|
||||
return DownloadDispatcher.GetInstance<NexusDownloader>();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@ using System.Text.RegularExpressions;
|
||||
using System.Windows;
|
||||
using VFS;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Downloaders;
|
||||
using Wabbajack.NexusApi;
|
||||
using Wabbajack.Validation;
|
||||
using Directory = Alphaleonis.Win32.Filesystem.Directory;
|
||||
@ -162,7 +163,8 @@ namespace Wabbajack
|
||||
private void AskToEndorse()
|
||||
{
|
||||
var mods = ModList.Archives
|
||||
.OfType<NexusMod>()
|
||||
.Select(m => m.State)
|
||||
.OfType<NexusDownloader.State>()
|
||||
.GroupBy(f => (f.GameName, f.ModID))
|
||||
.Select(mod => mod.First())
|
||||
.ToArray();
|
||||
@ -419,24 +421,11 @@ namespace Wabbajack
|
||||
Info($"Missing {missing.Count} archives");
|
||||
|
||||
Info("Getting Nexus API Key, if a browser appears, please accept");
|
||||
if (ModList.Archives.OfType<NexusMod>().Any())
|
||||
{
|
||||
var client = new NexusApiClient();
|
||||
var status = client.GetUserStatus();
|
||||
if (!client.IsAuthenticated)
|
||||
{
|
||||
Error(
|
||||
$"Authenticating for the Nexus failed. A nexus account is required to automatically download mods.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!status.is_premium)
|
||||
{
|
||||
Error(
|
||||
$"Automated installs with Wabbajack requires a premium nexus account. {client.Username} is not a premium account.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
var dispatchers = ModList.Archives.Select(m => m.State.GetDownloader()).Distinct();
|
||||
|
||||
foreach (var dispatcher in dispatchers)
|
||||
dispatcher.Prepare();
|
||||
|
||||
DownloadMissingArchives(missing);
|
||||
}
|
||||
@ -460,39 +449,7 @@ namespace Wabbajack
|
||||
{
|
||||
try
|
||||
{
|
||||
switch (archive)
|
||||
{
|
||||
case NexusMod a:
|
||||
string url;
|
||||
/*
|
||||
try
|
||||
{
|
||||
|
||||
url = new NexusApiClient().GetNexusDownloadLink(a, !download);
|
||||
if (!download) return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Info($"{a.Name} - Error Getting Nexus Download URL - {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
|
||||
Info($"Downloading Nexus Archive - {archive.Name} - {a.GameName} - {a.ModID} - {a.FileID}");
|
||||
DownloadURLDirect(archive, url);
|
||||
*/
|
||||
return true;
|
||||
case MEGAArchive a:
|
||||
return DownloadMegaArchive(a, download);
|
||||
case GoogleDriveMod a:
|
||||
return DownloadGoogleDriveArchive(a, download);
|
||||
case MODDBArchive a:
|
||||
return DownloadModDBArchive(archive, (archive as MODDBArchive).URL, download);
|
||||
case MediaFireArchive a:
|
||||
return false;
|
||||
//return DownloadMediaFireArchive(archive, a.URL, download);
|
||||
case DirectURLArchive a:
|
||||
return DownloadURLDirect(archive, a.URL, headers: a.Headers, download: download);
|
||||
}
|
||||
archive.State.Download(archive, Path.Combine(DownloadFolder, archive.Name));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@ -504,128 +461,6 @@ namespace Wabbajack
|
||||
return false;
|
||||
}
|
||||
|
||||
private void DownloadMediaFireArchive(Archive a, string url)
|
||||
{
|
||||
var client = new HttpClient();
|
||||
var result = client.GetStringSync(url);
|
||||
var regex = new Regex("(?<= href =\\\").*\\.mediafire\\.com.*(?=\\\")");
|
||||
var confirm = regex.Match(result);
|
||||
DownloadURLDirect(a, confirm.ToString(), client);
|
||||
}
|
||||
|
||||
private bool DownloadMegaArchive(MEGAArchive m, bool download)
|
||||
{
|
||||
var client = new MegaApiClient();
|
||||
Status("Logging into MEGA (as anonymous)");
|
||||
client.LoginAnonymous();
|
||||
var file_link = new Uri(m.URL);
|
||||
var node = client.GetNodeFromLink(file_link);
|
||||
if (!download) return true;
|
||||
Status($"Downloading MEGA file: {m.Name}");
|
||||
|
||||
var output_path = Path.Combine(DownloadFolder, m.Name);
|
||||
client.DownloadFile(file_link, output_path);
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool DownloadGoogleDriveArchive(GoogleDriveMod a, bool download)
|
||||
{
|
||||
var initial_url = $"https://drive.google.com/uc?id={a.Id}&export=download";
|
||||
var client = new HttpClient();
|
||||
var result = client.GetStringSync(initial_url);
|
||||
var regex = new Regex("(?<=/uc\\?export=download&confirm=).*(?=;id=)");
|
||||
var confirm = regex.Match(result);
|
||||
return DownloadURLDirect(a, $"https://drive.google.com/uc?export=download&confirm={confirm}&id={a.Id}",
|
||||
client, download);
|
||||
}
|
||||
|
||||
private bool DownloadModDBArchive(Archive archive, string url, bool download)
|
||||
{
|
||||
var client = new HttpClient();
|
||||
var result = client.GetStringSync(url);
|
||||
var regex = new Regex("https:\\/\\/www\\.moddb\\.com\\/downloads\\/mirror\\/.*(?=\\\")");
|
||||
var match = regex.Match(result);
|
||||
return DownloadURLDirect(archive, match.Value, download: download);
|
||||
}
|
||||
|
||||
private bool DownloadURLDirect(Archive archive, string url, HttpClient client = null, bool download = true,
|
||||
List<string> headers = null)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (client == null)
|
||||
{
|
||||
client = new HttpClient();
|
||||
client.DefaultRequestHeaders.Add("User-Agent", Consts.UserAgent);
|
||||
}
|
||||
|
||||
if (headers != null)
|
||||
foreach (var header in headers)
|
||||
{
|
||||
var idx = header.IndexOf(':');
|
||||
var k = header.Substring(0, idx);
|
||||
var v = header.Substring(idx + 1);
|
||||
client.DefaultRequestHeaders.Add(k, v);
|
||||
}
|
||||
|
||||
long total_read = 0;
|
||||
var buffer_size = 1024 * 32;
|
||||
|
||||
var response = client.GetSync(url);
|
||||
var stream = response.Content.ReadAsStreamAsync();
|
||||
try
|
||||
{
|
||||
stream.Wait();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
}
|
||||
|
||||
;
|
||||
if (stream.IsFaulted)
|
||||
{
|
||||
Info($"While downloading {url} - {stream.Exception.ExceptionToString()}");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!download)
|
||||
return true;
|
||||
|
||||
var header_var = "1";
|
||||
if (response.Content.Headers.Contains("Content-Length"))
|
||||
header_var = response.Content.Headers.GetValues("Content-Length").FirstOrDefault();
|
||||
|
||||
var content_size = header_var != null ? long.Parse(header_var) : 1;
|
||||
|
||||
var output_path = Path.Combine(DownloadFolder, archive.Name);
|
||||
;
|
||||
|
||||
using (var webs = stream.Result)
|
||||
using (var fs = File.OpenWrite(output_path))
|
||||
{
|
||||
var buffer = new byte[buffer_size];
|
||||
while (true)
|
||||
{
|
||||
var read = webs.Read(buffer, 0, buffer_size);
|
||||
if (read == 0) break;
|
||||
Status($"Downloading {archive.Name}", (int)(total_read * 100 / content_size));
|
||||
|
||||
fs.Write(buffer, 0, read);
|
||||
total_read += read;
|
||||
}
|
||||
}
|
||||
|
||||
Status($"Hashing {archive.Name}");
|
||||
HashArchive(output_path);
|
||||
return true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Info($"{archive.Name} - Error downloading from: {url}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void HashArchives()
|
||||
{
|
||||
HashedArchives = Directory.EnumerateFiles(DownloadFolder)
|
||||
|
@ -208,7 +208,7 @@ namespace Wabbajack.NexusApi
|
||||
return true;
|
||||
}
|
||||
|
||||
public NexusFileInfo GetFileInfo(NexusMod mod)
|
||||
public NexusFileInfo GetFileInfo(NexusDownloader.State mod)
|
||||
{
|
||||
var url = $"https://api.nexusmods.com/v1/games/{ConvertGameName(mod.GameName)}/mods/{mod.ModID}/files/{mod.FileID}.json";
|
||||
return Get<NexusFileInfo>(url);
|
||||
@ -251,7 +251,7 @@ namespace Wabbajack.NexusApi
|
||||
return result;
|
||||
}
|
||||
|
||||
public EndorsementResponse EndorseMod(NexusMod mod)
|
||||
public EndorsementResponse EndorseMod(NexusDownloader.State mod)
|
||||
{
|
||||
Utils.Status($"Endorsing ${mod.GameName} - ${mod.ModID}");
|
||||
var url = $"https://api.nexusmods.com/v1/games/{ConvertGameName(mod.GameName)}/mods/{mod.ModID}/endorse.json";
|
||||
|
@ -63,6 +63,7 @@ namespace Wabbajack
|
||||
var hash = archive.Hash.FromBase64().ToHEX();
|
||||
switch (archive)
|
||||
{
|
||||
/*
|
||||
case NexusMod m:
|
||||
var profile = m.UploaderProfile.Replace("/games/",
|
||||
"/" + NexusApiUtils.ConvertGameName(m.GameName).ToLower() + "/");
|
||||
@ -84,6 +85,7 @@ namespace Wabbajack
|
||||
case DirectURLArchive m:
|
||||
NoWrapText($"* URL - [{m.Name} - {m.URL}]({m.URL})");
|
||||
break;
|
||||
*/
|
||||
}
|
||||
|
||||
NoWrapText($" * Size : {archive.Size.ToFileSizeString()}");
|
||||
@ -147,8 +149,11 @@ namespace Wabbajack
|
||||
|
||||
private IEnumerable<Archive> SortArchives(List<Archive> lstArchives)
|
||||
{
|
||||
/*
|
||||
var lst = lstArchives.OfType<NexusMod>().OrderBy(m => m.Author).ThenBy(m => m.Name);
|
||||
return lst.Concat(lstArchives.Where(m => !(m is NexusMod)).OrderBy(m => m.Name));
|
||||
*/
|
||||
return lstArchives;
|
||||
}
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Downloaders;
|
||||
using YamlDotNet.Serialization;
|
||||
using YamlDotNet.Serialization.NamingConventions;
|
||||
using Path = Alphaleonis.Win32.Filesystem.Path;
|
||||
@ -84,7 +85,7 @@ namespace Wabbajack.Validation
|
||||
/// </summary>
|
||||
/// <param name="mod"></param>
|
||||
/// <returns></returns>
|
||||
public Permissions FilePermissions(NexusMod mod)
|
||||
public Permissions FilePermissions(NexusDownloader.State mod)
|
||||
{
|
||||
var author_permissions = AuthorPermissions.GetOrDefault(mod.Author)?.Permissions;
|
||||
var game_permissions = AuthorPermissions.GetOrDefault(mod.Author)?.Games.GetOrDefault(mod.GameName)?.Permissions;
|
||||
@ -109,10 +110,10 @@ namespace Wabbajack.Validation
|
||||
public IEnumerable<string> Validate(ModList modlist)
|
||||
{
|
||||
ConcurrentStack<string> ValidationErrors = new ConcurrentStack<string>();
|
||||
|
||||
|
||||
var nexus_mod_permissions = modlist.Archives
|
||||
.OfType<NexusMod>()
|
||||
.PMap(a => (a.Hash, FilePermissions(a), a))
|
||||
.Where(a => a.State is NexusDownloader.State)
|
||||
.PMap(a => (a.Hash, FilePermissions((NexusDownloader.State)a.State), a))
|
||||
.ToDictionary(a => a.Hash, a => new { permissions = a.Item2, archive = a.a });
|
||||
|
||||
modlist.Directives
|
||||
@ -122,13 +123,14 @@ namespace Wabbajack.Validation
|
||||
if (nexus_mod_permissions.TryGetValue(p.ArchiveHashPath[0], out var archive))
|
||||
{
|
||||
var ext = Path.GetExtension(p.ArchiveHashPath.Last());
|
||||
var url = (archive.archive.State as NexusDownloader.State).NexusURL;
|
||||
if (Consts.AssetFileExtensions.Contains(ext) && !(archive.permissions.CanModifyAssets ?? true))
|
||||
{
|
||||
ValidationErrors.Push($"{p.To} from {archive.archive.NexusURL} is set to disallow asset modification");
|
||||
ValidationErrors.Push($"{p.To} from {url} is set to disallow asset modification");
|
||||
}
|
||||
else if (Consts.ESPFileExtensions.Contains(ext) && !(archive.permissions.CanModifyESPs ?? true))
|
||||
{
|
||||
ValidationErrors.Push($"{p.To} from {archive.archive.NexusURL} is set to disallow asset ESP modification");
|
||||
ValidationErrors.Push($"{p.To} from {url} is set to disallow asset ESP modification");
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -139,10 +141,11 @@ namespace Wabbajack.Validation
|
||||
{
|
||||
if (nexus_mod_permissions.TryGetValue(p.ArchiveHashPath[0], out var archive))
|
||||
{
|
||||
var url = (archive.archive.State as NexusDownloader.State).NexusURL;
|
||||
if (!(archive.permissions.CanExtractBSAs ?? true) &&
|
||||
p.ArchiveHashPath.Skip(1).ButLast().Any(a => Consts.SupportedBSAs.Contains(Path.GetExtension(a).ToLower())))
|
||||
{
|
||||
ValidationErrors.Push($"{p.To} from {archive.archive.NexusURL} is set to disallow BSA Extraction");
|
||||
ValidationErrors.Push($"{p.To} from {url} is set to disallow BSA Extraction");
|
||||
}
|
||||
}
|
||||
});
|
||||
@ -150,34 +153,25 @@ namespace Wabbajack.Validation
|
||||
var nexus = NexusApi.NexusApiUtils.ConvertGameName(GameRegistry.Games[modlist.GameType].NexusName);
|
||||
|
||||
modlist.Archives
|
||||
.OfType<NexusMod>()
|
||||
.Where(m => NexusApi.NexusApiUtils.ConvertGameName(m.GameName) != nexus)
|
||||
.Where(a => a.State is NexusDownloader.State)
|
||||
.Where(m => NexusApi.NexusApiUtils.ConvertGameName(((NexusDownloader.State)m.State).GameName) != nexus)
|
||||
.Do(m =>
|
||||
{
|
||||
var permissions = FilePermissions(m);
|
||||
var permissions = FilePermissions((NexusDownloader.State)m.State);
|
||||
if (!(permissions.CanUseInOtherGames ?? true))
|
||||
{
|
||||
ValidationErrors.Push(
|
||||
$"The modlist is for {nexus} but {m.Name} is for game type {m.GameName} and is not allowed to be converted to other game types");
|
||||
$"The modlist is for {nexus} but {m.Name} is for game type {((NexusDownloader.State)m.State).GameName} and is not allowed to be converted to other game types");
|
||||
}
|
||||
});
|
||||
|
||||
modlist.Archives
|
||||
.OfType<GoogleDriveMod>()
|
||||
.PMap(m =>
|
||||
{
|
||||
if (!ServerWhitelist.GoogleIDs.Contains(m.Id))
|
||||
ValidationErrors.Push($"{m.Name} uses Google Drive id {m.Id} but that id is not in the file whitelist.");
|
||||
});
|
||||
|
||||
modlist.Archives
|
||||
.OfType<DirectURLArchive>()
|
||||
.PMap(m =>
|
||||
.Where(m => !m.State.IsWhitelisted(ServerWhitelist))
|
||||
.Do(m =>
|
||||
{
|
||||
if (!ServerWhitelist.AllowedPrefixes.Any(prefix => m.URL.StartsWith(prefix)))
|
||||
ValidationErrors.Push($"{m.Name} will be downloaded from {m.URL} but that URL is not in the server whitelist");
|
||||
ValidationErrors.Push($"{m.Name} is not a whitelisted download");
|
||||
});
|
||||
|
||||
|
||||
return ValidationErrors.ToList();
|
||||
}
|
||||
}
|
||||
|
@ -194,6 +194,7 @@
|
||||
<Compile Include="Downloaders\DownloadDispatcher.cs" />
|
||||
<Compile Include="Downloaders\DropboxDownloader.cs" />
|
||||
<Compile Include="Downloaders\IDownloader.cs" />
|
||||
<Compile Include="Downloaders\ManualDownloader.cs" />
|
||||
<Compile Include="Downloaders\MegaDownloader.cs" />
|
||||
<Compile Include="Downloaders\NexusDownloader.cs" />
|
||||
<Compile Include="LambdaCommand.cs" />
|
||||
|
Loading…
Reference in New Issue
Block a user