mirror of
https://github.com/wabbajack-tools/wabbajack.git
synced 2024-08-30 18:42:17 +00:00
No more MessagePack, Json is love, Json is life
This commit is contained in:
parent
3d16b1e838
commit
45254b0055
@ -127,7 +127,7 @@ namespace Compression.BSA.Test
|
||||
TestContext.WriteLine($"Verifying {bsa}");
|
||||
using var b = BSADispatch.OpenRead(tempFile);
|
||||
TestContext.WriteLine($"Performing A/B tests on {bsa}");
|
||||
Assert.Equal(a.State.ToJSON(), b.State.ToJSON());
|
||||
Assert.Equal(a.State.ToJson(), b.State.ToJson());
|
||||
|
||||
// Check same number of files
|
||||
Assert.Equal(a.Files.Count(), b.Files.Count());
|
||||
@ -135,7 +135,7 @@ namespace Compression.BSA.Test
|
||||
await a.Files.Zip(b.Files, (ai, bi) => (ai, bi))
|
||||
.PMap(Queue, pair =>
|
||||
{
|
||||
Assert.Equal(pair.ai.State.ToJSON(), pair.bi.State.ToJSON());
|
||||
Assert.Equal(pair.ai.State.ToJson(), pair.bi.State.ToJson());
|
||||
//Console.WriteLine($" - {pair.ai.Path}");
|
||||
Assert.Equal(pair.ai.Path, pair.bi.Path);
|
||||
//Equal(pair.ai.Compressed, pair.bi.Compressed);
|
||||
@ -154,7 +154,7 @@ namespace Compression.BSA.Test
|
||||
|
||||
private static T ViaJson<T>(T i)
|
||||
{
|
||||
return i.ToJSON().FromJSONString<T>();
|
||||
return i.ToJson().FromJsonString<T>();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.console" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
|
||||
|
@ -15,7 +15,7 @@ namespace Wabbajack.BuildServer.Test
|
||||
[Fact]
|
||||
public async Task CanGetHeartbeat()
|
||||
{
|
||||
var heartbeat = (await _client.GetStringAsync(MakeURL("heartbeat"))).FromJSONString<string>();
|
||||
var heartbeat = (await _client.GetStringAsync(MakeURL("heartbeat"))).FromJsonString<string>();
|
||||
Assert.True(TimeSpan.Parse(heartbeat) > TimeSpan.Zero);
|
||||
}
|
||||
|
||||
|
@ -32,7 +32,7 @@ namespace Wabbajack.BuildServer.Test
|
||||
[Fact, Priority(1)]
|
||||
public async Task CanListMyUploadedFiles()
|
||||
{
|
||||
var result = (await _authedClient.GetStringAsync(MakeURL("uploaded_files/list"))).FromJSONString<string[]>();
|
||||
var result = (await _authedClient.GetStringAsync(MakeURL("uploaded_files/list"))).FromJsonString<string[]>();
|
||||
Utils.Log("Loaded: " + result);
|
||||
|
||||
|
||||
|
@ -7,13 +7,13 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="Xunit.Priority" Version="1.1.6" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.0.1" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.2.1" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.1" />
|
||||
<PackageReference Include="XunitContext" Version="1.9.0" />
|
||||
<PackageReference Include="XunitContext" Version="1.9.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -113,7 +113,7 @@ namespace Wabbajack.BuildServer.Controllers
|
||||
{
|
||||
ContentType = "application/json",
|
||||
StatusCode = (int) HttpStatusCode.OK,
|
||||
Content = lst.ToJSON()
|
||||
Content = lst.ToJson()
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -80,7 +80,7 @@ namespace Wabbajack.BuildServer.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(new {Save = toSave.ToArray(), Delete = toDelete.ToArray()}.ToJSON(prettyPrint:true));
|
||||
return Ok(new {Save = toSave.ToArray(), Delete = toDelete.ToArray()}.ToJson());
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
@ -154,7 +154,7 @@ namespace Wabbajack.BuildServer.Controllers
|
||||
}
|
||||
});
|
||||
}
|
||||
return Ok(newArchive.ToJSON());
|
||||
return Ok(newArchive.ToJson());
|
||||
}
|
||||
|
||||
private async Task<Archive> FindAlternatives(NexusDownloader.State state, Hash srcHash)
|
||||
|
@ -112,7 +112,7 @@ namespace Wabbajack.BuildServer.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
return Ok(new {Remain = seen.ToArray(), Deleted = duplicate.ToArray()}.ToJSON(prettyPrint:true));
|
||||
return Ok(new {Remain = seen.ToArray(), Deleted = duplicate.ToArray()}.ToJson());
|
||||
}
|
||||
|
||||
|
||||
@ -204,7 +204,7 @@ namespace Wabbajack.BuildServer.Controllers
|
||||
var user = User.FindFirstValue(ClaimTypes.Name);
|
||||
Utils.Log($"List Uploaded Files {user}");
|
||||
var files = await SQL.AllUploadedFilesForUser(user);
|
||||
return Ok(files.OrderBy(f => f.UploadDate).Select(f => f.MungedName ).ToArray().ToJSON(prettyPrint:true));
|
||||
return Ok(files.OrderBy(f => f.UploadDate).Select(f => f.MungedName ).ToArray().ToJson());
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
|
@ -184,8 +184,8 @@ namespace Wabbajack.BuildServer.Model.Models
|
||||
@"INSERT INTO dbo.Jobs (Created, Priority, Payload, OnSuccess) VALUES (GETDATE(), @Priority, @Payload, @OnSuccess)",
|
||||
new {
|
||||
job.Priority,
|
||||
Payload = job.Payload.ToJSON(),
|
||||
OnSuccess = job.OnSuccess?.ToJSON() ?? null});
|
||||
Payload = job.Payload.ToJson(),
|
||||
OnSuccess = job.OnSuccess?.ToJson() ?? null});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@ -201,7 +201,7 @@ namespace Wabbajack.BuildServer.Model.Models
|
||||
new {
|
||||
job.Id,
|
||||
Success = job.Result.ResultType == JobResultType.Success,
|
||||
ResultPayload = job.Result.ToJSON()
|
||||
ResultPayload = job.Result.ToJson()
|
||||
|
||||
});
|
||||
|
||||
@ -258,12 +258,12 @@ namespace Wabbajack.BuildServer.Model.Models
|
||||
{
|
||||
public override void SetValue(IDbDataParameter parameter, AJobPayload value)
|
||||
{
|
||||
parameter.Value = value.ToJSON();
|
||||
parameter.Value = value.ToJson();
|
||||
}
|
||||
|
||||
public override AJobPayload Parse(object value)
|
||||
{
|
||||
return ((string)value).FromJSONString<AJobPayload>();
|
||||
return ((string)value).FromJsonString<AJobPayload>();
|
||||
}
|
||||
}
|
||||
|
||||
@ -346,7 +346,7 @@ namespace Wabbajack.BuildServer.Model.Models
|
||||
Hash = hash,
|
||||
PrimaryKey = state.PrimaryKeyString,
|
||||
IniState = string.Join("\n", state.GetMetaIni()),
|
||||
JsonState = state.ToJSON()
|
||||
JsonState = state.ToJson()
|
||||
});
|
||||
}
|
||||
|
||||
@ -451,7 +451,7 @@ namespace Wabbajack.BuildServer.Model.Models
|
||||
{
|
||||
await using var conn = await Open();
|
||||
var results = await conn.QueryAsync<string>("SELECT Summary from dbo.ModLists");
|
||||
return results.Select(s => s.FromJSONString<ModlistSummary>()).ToList();
|
||||
return results.Select(s => s.FromJsonString<ModlistSummary>()).ToList();
|
||||
}
|
||||
|
||||
public async Task<DetailedStatus> GetDetailedModlistStatus(string machineUrl)
|
||||
@ -462,13 +462,13 @@ namespace Wabbajack.BuildServer.Model.Models
|
||||
{
|
||||
machineUrl
|
||||
});
|
||||
return result.FromJSONString<DetailedStatus>();
|
||||
return result.FromJsonString<DetailedStatus>();
|
||||
}
|
||||
public async Task<List<DetailedStatus>> GetDetailedModlistStatuses()
|
||||
{
|
||||
await using var conn = await Open();
|
||||
var results = await conn.QueryAsync<string>("SELECT DetailedStatus from dbo.ModLists");
|
||||
return results.Select(s => s.FromJSONString<DetailedStatus>()).ToList();
|
||||
return results.Select(s => s.FromJsonString<DetailedStatus>()).ToList();
|
||||
}
|
||||
|
||||
|
||||
@ -523,7 +523,7 @@ namespace Wabbajack.BuildServer.Model.Models
|
||||
new {Hash = startingHash});
|
||||
return result == null ? null : new Archive
|
||||
{
|
||||
State = result.FromJSONString<AbstractDownloadState>(),
|
||||
State = result.FromJsonString<AbstractDownloadState>(),
|
||||
Hash = startingHash
|
||||
};
|
||||
}
|
||||
@ -535,7 +535,7 @@ namespace Wabbajack.BuildServer.Model.Models
|
||||
new {PrimaryKey = primaryKey});
|
||||
return result == default ? null : new Archive
|
||||
{
|
||||
State = result.State.FromJSONString<AbstractDownloadState>(),
|
||||
State = result.State.FromJsonString<AbstractDownloadState>(),
|
||||
Hash = Hash.FromLong(result.Hash)
|
||||
};
|
||||
}
|
||||
@ -604,9 +604,9 @@ namespace Wabbajack.BuildServer.Model.Models
|
||||
new
|
||||
{
|
||||
MachineUrl = dto.Metadata.Links.MachineURL,
|
||||
Metadata = dto.Metadata.ToJSON(),
|
||||
Summary = dto.Summary.ToJSON(),
|
||||
DetailedStatus = dto.DetailedStatus.ToJSON()
|
||||
Metadata = dto.Metadata.ToJson(),
|
||||
Summary = dto.Summary.ToJson(),
|
||||
DetailedStatus = dto.DetailedStatus.ToJson()
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -16,10 +16,10 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CsvHelper" Version="15.0.3" />
|
||||
<PackageReference Include="Dapper" Version="2.0.30" />
|
||||
<PackageReference Include="FluentFTP" Version="32.2.2" />
|
||||
<PackageReference Include="graphiql" Version="1.2.0" />
|
||||
<PackageReference Include="CsvHelper" Version="15.0.4" />
|
||||
<PackageReference Include="Dapper" Version="2.0.35" />
|
||||
<PackageReference Include="FluentFTP" Version="32.3.1" />
|
||||
<PackageReference Include="graphiql" Version="2.0.0" />
|
||||
<PackageReference Include="GraphQL" Version="3.0.0-preview-1352" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Authentication.Core" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.1" />
|
||||
@ -28,7 +28,7 @@
|
||||
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.2.0" />
|
||||
<PackageReference Include="Microsoft.OpenApi" Version="1.1.4" />
|
||||
<PackageReference Include="Nettle" Version="1.3.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.1.0" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore" Version="5.3.1" />
|
||||
<PackageReference Include="System.Data.SqlClient" Version="4.8.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
<RuntimeIdentifier>win10-x64</RuntimeIdentifier>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Reactive" Version="4.3.2" />
|
||||
<PackageReference Include="System.Reactive" Version="4.4.1" />
|
||||
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.6.0-preview.18571.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -1,5 +1,8 @@
|
||||
using System.IO;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json.Converters;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using Xunit;
|
||||
|
||||
namespace Wabbajack.Common.Test
|
||||
@ -51,23 +54,52 @@ namespace Wabbajack.Common.Test
|
||||
await RoundTrips(new FullPath((AbsolutePath)@"c:\"));
|
||||
}
|
||||
|
||||
|
||||
class Base
|
||||
{
|
||||
public int BaseNumber { get; set; }
|
||||
}
|
||||
|
||||
[JsonName("ChildA")]
|
||||
class ChildA : Base
|
||||
{
|
||||
public int ChildANumber { get; set; }
|
||||
}
|
||||
|
||||
[JsonName("ChildB")]
|
||||
class ChildB : ChildA
|
||||
{
|
||||
public int ChildBNumber { get; set; }
|
||||
}
|
||||
|
||||
|
||||
[Fact]
|
||||
public async Task JsonSerializationUser()
|
||||
{
|
||||
var start = new ChildB {BaseNumber = 1, ChildANumber = 2, ChildBNumber = 3};
|
||||
|
||||
var result = (ChildB)start.ToJson().FromJsonString<Base>();
|
||||
|
||||
Utils.Log(start.ToJson());
|
||||
|
||||
Assert.Equal(start.BaseNumber, result.BaseNumber);
|
||||
Assert.Equal(start.ChildANumber, result.ChildANumber);
|
||||
Assert.Equal(start.ChildBNumber, result.ChildBNumber);
|
||||
|
||||
Assert.DoesNotContain("Wabbajack.Common.Test.Serialization", start.ToJson());
|
||||
|
||||
|
||||
}
|
||||
|
||||
private static async Task RoundTrips<T>(T input)
|
||||
{
|
||||
Assert.Equal(input, RoundTripJson(input));
|
||||
Assert.Equal(input, await RoundTripMessagePack(input));
|
||||
}
|
||||
|
||||
private static T RoundTripJson<T>(T input)
|
||||
{
|
||||
return input.ToJSON().FromJSONString<T>();
|
||||
return input.ToJson().FromJsonString<T>();
|
||||
}
|
||||
|
||||
private static async Task<T> RoundTripMessagePack<T>(T input)
|
||||
{
|
||||
await using var ms = new MemoryStream();
|
||||
await ms.WriteAsMessagePackAsync(input);
|
||||
ms.Position = 0;
|
||||
return await ms.ReadAsMessagePackAsync<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +102,7 @@ namespace Wabbajack.Common.Http
|
||||
public async Task<T> GetJsonAsync<T>(string s)
|
||||
{
|
||||
var result = await GetStringAsync(s);
|
||||
return result.FromJSONString<T>();
|
||||
return result.FromJsonString<T>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using File = Alphaleonis.Win32.Filesystem.File;
|
||||
|
||||
namespace Wabbajack.Common
|
||||
@ -19,70 +25,56 @@ namespace Wabbajack.Common
|
||||
new GameConverter(),
|
||||
new PercentConverter(),
|
||||
};
|
||||
|
||||
public static JsonSerializerSettings JsonSettings =>
|
||||
new JsonSerializerSettings {
|
||||
TypeNameHandling = TypeNameHandling.Objects,
|
||||
SerializationBinder = new JsonNameSerializationBinder(),
|
||||
Converters = Converters};
|
||||
|
||||
|
||||
public static void ToJSON<T>(this T obj, string filename)
|
||||
public static void ToJson<T>(this T obj, string filename)
|
||||
{
|
||||
if (File.Exists(filename))
|
||||
File.Delete(filename);
|
||||
File.WriteAllText(filename,
|
||||
JsonConvert.SerializeObject(obj, Formatting.Indented,
|
||||
new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.Auto, Converters = Converters}));
|
||||
File.WriteAllText(filename, JsonConvert.SerializeObject(obj, Formatting.Indented, JsonSettings));
|
||||
}
|
||||
|
||||
public static string ToJSON<T>(this T obj,
|
||||
TypeNameHandling handling = TypeNameHandling.All,
|
||||
TypeNameAssemblyFormatHandling format = TypeNameAssemblyFormatHandling.Full,
|
||||
bool prettyPrint = false)
|
||||
|
||||
public static void ToJson<T>(this T obj, Stream stream)
|
||||
{
|
||||
return JsonConvert.SerializeObject(obj, Formatting.Indented,
|
||||
new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = handling,
|
||||
TypeNameAssemblyFormatHandling = format,
|
||||
Formatting = prettyPrint ? Formatting.Indented : Formatting.None,
|
||||
Converters = Converters
|
||||
});
|
||||
using var tw = new StreamWriter(stream, Encoding.UTF8, leaveOpen: true);
|
||||
using var writer = new JsonTextWriter(tw);
|
||||
var ser = JsonSerializer.Create(JsonSettings);
|
||||
ser.Serialize(writer, obj);
|
||||
}
|
||||
|
||||
public static T FromJSON<T>(this AbsolutePath filename,
|
||||
public static string ToJson<T>(this T obj)
|
||||
{
|
||||
return JsonConvert.SerializeObject(obj, JsonSettings);
|
||||
}
|
||||
|
||||
public static T FromJson<T>(this AbsolutePath filename,
|
||||
TypeNameHandling handling = TypeNameHandling.All,
|
||||
TypeNameAssemblyFormatHandling format = TypeNameAssemblyFormatHandling.Full)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(filename.ReadAllText(),
|
||||
new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = handling, TypeNameAssemblyFormatHandling = format, Converters = Converters
|
||||
})!;
|
||||
return JsonConvert.DeserializeObject<T>(filename.ReadAllText(), JsonSettings)!;
|
||||
}
|
||||
|
||||
public static T FromJSONString<T>(this string data,
|
||||
TypeNameHandling handling = TypeNameHandling.All,
|
||||
public static T FromJsonString<T>(this string data,
|
||||
TypeNameHandling handling = TypeNameHandling.Objects,
|
||||
TypeNameAssemblyFormatHandling format = TypeNameAssemblyFormatHandling.Full)
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(data,
|
||||
new JsonSerializerSettings
|
||||
{
|
||||
TypeNameHandling = handling, TypeNameAssemblyFormatHandling = format, Converters = Converters
|
||||
})!;
|
||||
return JsonConvert.DeserializeObject<T>(data, JsonSettings)!;
|
||||
}
|
||||
|
||||
public static T FromJSON<T>(this Stream data)
|
||||
public static T FromJson<T>(this Stream stream)
|
||||
{
|
||||
var s = Encoding.UTF8.GetString(data.ReadAll());
|
||||
try
|
||||
{
|
||||
return JsonConvert.DeserializeObject<T>(s,
|
||||
new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.Auto, Converters = Converters})!;
|
||||
}
|
||||
catch (JsonSerializationException)
|
||||
{
|
||||
var error = JsonConvert.DeserializeObject<NexusErrorResponse>(s,
|
||||
new JsonSerializerSettings {TypeNameHandling = TypeNameHandling.Auto});
|
||||
if (error != null)
|
||||
Log($"Exception while deserializing\nError code: {error.code}\nError message: {error.message}");
|
||||
throw;
|
||||
}
|
||||
using var tr = new StreamReader(stream, Encoding.UTF8, leaveOpen: true);
|
||||
using var reader = new JsonTextReader(tr);
|
||||
var ser = JsonSerializer.Create(JsonSettings);
|
||||
return ser.Deserialize<T>(reader);
|
||||
}
|
||||
|
||||
|
||||
|
||||
private class HashJsonConverter : JsonConverter<Hash>
|
||||
@ -237,5 +229,87 @@ namespace Wabbajack.Common
|
||||
return game.Game;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public class JsonNameSerializationBinder : ISerializationBinder
|
||||
{
|
||||
private Dictionary<string, Type> _nameToType;
|
||||
private Dictionary<Type, string> _typeToName;
|
||||
|
||||
public JsonNameSerializationBinder()
|
||||
{
|
||||
var customDisplayNameTypes =
|
||||
AppDomain.CurrentDomain
|
||||
.GetAssemblies()
|
||||
.Where(a => a.FullName != null && a.FullName.StartsWith("Wabbajack"))
|
||||
.SelectMany(a =>
|
||||
{
|
||||
try
|
||||
{
|
||||
return a.GetTypes();
|
||||
}
|
||||
catch (ReflectionTypeLoadException)
|
||||
{
|
||||
return new Type[0];
|
||||
}
|
||||
})
|
||||
//concat with references if desired
|
||||
.Where(x => x
|
||||
.GetCustomAttributes(false)
|
||||
.Any(y => y is JsonNameAttribute));
|
||||
|
||||
_nameToType = customDisplayNameTypes.ToDictionary(
|
||||
t => t.GetCustomAttributes(false).OfType<JsonNameAttribute>().First().Name,
|
||||
t => t);
|
||||
|
||||
_typeToName = _nameToType.ToDictionary(
|
||||
t => t.Value,
|
||||
t => t.Key);
|
||||
|
||||
}
|
||||
|
||||
public Type BindToType(string? assemblyName, string typeName)
|
||||
{
|
||||
if (typeName.EndsWith("[]"))
|
||||
{
|
||||
var result = BindToType(assemblyName, typeName.Substring(0, typeName.Length - 2));
|
||||
return result.MakeArrayType();
|
||||
}
|
||||
|
||||
if (_nameToType.ContainsKey(typeName))
|
||||
return _nameToType[typeName];
|
||||
|
||||
var val = Type.GetType(typeName);
|
||||
if (val != null)
|
||||
return val;
|
||||
|
||||
if (assemblyName != null)
|
||||
{
|
||||
var assembly = AppDomain.CurrentDomain.Load(assemblyName);
|
||||
if (assembly != null)
|
||||
{
|
||||
var result = assembly.GetType(typeName);
|
||||
if (result != null) return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
throw new InvalidDataException($"No Binding name for {typeName}");
|
||||
}
|
||||
|
||||
public void BindToName(Type serializedType, out string? assemblyName, out string? typeName)
|
||||
{
|
||||
if (!_typeToName.ContainsKey(serializedType))
|
||||
{
|
||||
throw new InvalidDataException($"No Binding name for {serializedType}");
|
||||
}
|
||||
|
||||
var name = _typeToName[serializedType];
|
||||
|
||||
assemblyName = null;
|
||||
typeName = name;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,186 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using MessagePack;
|
||||
using MessagePack.Formatters;
|
||||
using MessagePack.Resolvers;
|
||||
|
||||
namespace Wabbajack.Common
|
||||
{
|
||||
public partial class Utils
|
||||
{
|
||||
private static MessagePackSerializerOptions? _messagePackOptions;
|
||||
private static IFormatterResolver? _resolver;
|
||||
|
||||
private static void MessagePackInit()
|
||||
{
|
||||
_resolver = CompositeResolver.Create(
|
||||
new List<IMessagePackFormatter>
|
||||
{
|
||||
new HashFormatter(),
|
||||
new RelativePathFormatter(),
|
||||
new AbsolutePathFormatter(),
|
||||
new HashRelativePathFormatter(),
|
||||
new FullPathFormatter()
|
||||
},
|
||||
new List<IFormatterResolver> {StandardResolver.Instance}
|
||||
);
|
||||
_messagePackOptions = MessagePackSerializerOptions.Standard
|
||||
.WithResolver(_resolver)
|
||||
.WithCompression(MessagePackCompression.Lz4BlockArray);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a object to this stream using MessagePack
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="obj"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static async Task WriteAsMessagePackAsync<T>(this Stream stream, T obj)
|
||||
{
|
||||
await MessagePackSerializer.SerializeAsync(stream, obj, _messagePackOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a object to this stream using MessagePack
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <param name="obj"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public static void WriteAsMessagePack<T>(this Stream stream, T obj)
|
||||
{
|
||||
MessagePackSerializer.Serialize(stream, obj, _messagePackOptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a object from this stream using MessagePack
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static async Task<T> ReadAsMessagePackAsync<T>(this Stream stream)
|
||||
{
|
||||
return await MessagePackSerializer.DeserializeAsync<T>(stream, _messagePackOptions);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Reads a object from this stream using MessagePack
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static T ReadAsMessagePack<T>(this Stream stream)
|
||||
{
|
||||
return MessagePackSerializer.Deserialize<T>(stream, _messagePackOptions);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
#region Formatters
|
||||
|
||||
public class HashFormatter : IMessagePackFormatter<Hash>
|
||||
{
|
||||
public void Serialize(ref MessagePackWriter writer, Hash value, MessagePackSerializerOptions options)
|
||||
{
|
||||
writer.WriteUInt64((ulong)value);
|
||||
}
|
||||
|
||||
public Hash Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
|
||||
{
|
||||
return new Hash(reader.ReadUInt64());
|
||||
}
|
||||
}
|
||||
|
||||
public class RelativePathFormatter : IMessagePackFormatter<RelativePath>
|
||||
{
|
||||
public void Serialize(ref MessagePackWriter writer, RelativePath value, MessagePackSerializerOptions options)
|
||||
{
|
||||
if (value == default)
|
||||
{
|
||||
writer.WriteString(new byte[0]);
|
||||
return;
|
||||
}
|
||||
|
||||
var encoded = Encoding.UTF8.GetBytes((string)value);
|
||||
writer.WriteString(encoded);
|
||||
}
|
||||
|
||||
public RelativePath Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
|
||||
{
|
||||
return (RelativePath)reader.ReadString();
|
||||
}
|
||||
}
|
||||
|
||||
public class AbsolutePathFormatter : IMessagePackFormatter<AbsolutePath>
|
||||
{
|
||||
public void Serialize(ref MessagePackWriter writer, AbsolutePath value, MessagePackSerializerOptions options)
|
||||
{
|
||||
var encoded = Encoding.UTF8.GetBytes((string)value);
|
||||
writer.WriteString(encoded);
|
||||
}
|
||||
|
||||
public AbsolutePath Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
|
||||
{
|
||||
return (AbsolutePath)reader.ReadString();
|
||||
}
|
||||
}
|
||||
|
||||
public class HashRelativePathFormatter : IMessagePackFormatter<HashRelativePath>
|
||||
{
|
||||
public void Serialize(ref MessagePackWriter writer, HashRelativePath value, MessagePackSerializerOptions options)
|
||||
{
|
||||
writer.WriteArrayHeader(value.Paths.Length + 1);
|
||||
writer.WriteUInt64((ulong)value.BaseHash);
|
||||
foreach (var path in value.Paths)
|
||||
{
|
||||
var encoded = Encoding.UTF8.GetBytes((string)path);
|
||||
writer.WriteString(encoded);
|
||||
}
|
||||
}
|
||||
|
||||
public HashRelativePath Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
|
||||
{
|
||||
var header = reader.ReadArrayHeader();
|
||||
var hash = Hash.FromULong(reader.ReadUInt64());
|
||||
var paths = new RelativePath[header - 1];
|
||||
for (int idx = 0; idx < header - 1; idx += 1)
|
||||
{
|
||||
paths[idx] = (RelativePath)reader.ReadString();
|
||||
}
|
||||
return new HashRelativePath(hash, paths);
|
||||
}
|
||||
}
|
||||
|
||||
public class FullPathFormatter : IMessagePackFormatter<FullPath>
|
||||
{
|
||||
public void Serialize(ref MessagePackWriter writer, FullPath value, MessagePackSerializerOptions options)
|
||||
{
|
||||
writer.WriteArrayHeader(value.Paths.Length + 1);
|
||||
writer.WriteString(Encoding.UTF8.GetBytes((string)value.Base));
|
||||
foreach (var path in value.Paths)
|
||||
{
|
||||
var encoded = Encoding.UTF8.GetBytes((string)path);
|
||||
writer.WriteString(encoded);
|
||||
}
|
||||
}
|
||||
|
||||
public FullPath Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
|
||||
{
|
||||
var header = reader.ReadArrayHeader();
|
||||
var basePath = (AbsolutePath)reader.ReadString();
|
||||
var paths = new RelativePath[header - 1];
|
||||
for (int idx = 0; idx < header - 1; idx += 1)
|
||||
{
|
||||
paths[idx] = (RelativePath)reader.ReadString();
|
||||
}
|
||||
return new FullPath(basePath, paths);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
19
Wabbajack.Common/Serialization/Json/JsonNameAttribute.cs
Normal file
19
Wabbajack.Common/Serialization/Json/JsonNameAttribute.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
|
||||
namespace Wabbajack.Common.Serialization.Json
|
||||
{
|
||||
/// <summary>
|
||||
/// Defines the polymorphic name of this type when serialized via Json. This value will
|
||||
/// be stored in the "_wjType" field.
|
||||
/// </summary>
|
||||
public class JsonNameAttribute : Attribute
|
||||
{
|
||||
public string Name { get; }
|
||||
|
||||
public JsonNameAttribute(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -59,7 +59,6 @@ namespace Wabbajack.Common
|
||||
Consts.LocalAppDataPath.CreateDirectory();
|
||||
Consts.LogsFolder.CreateDirectory();
|
||||
|
||||
MessagePackInit();
|
||||
_startTime = DateTime.Now;
|
||||
|
||||
if (LogFile.Exists)
|
||||
@ -832,7 +831,8 @@ namespace Wabbajack.Common
|
||||
/// <returns></returns>
|
||||
public static T ViaJSON<T>(this T tv)
|
||||
{
|
||||
return tv.ToJSON().FromJSONString<T>();
|
||||
var json = tv.ToJson();
|
||||
return json.FromJsonString<T>();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -999,14 +999,14 @@ namespace Wabbajack.Common
|
||||
/// <param name="data"></param>
|
||||
public static void ToEcryptedJson<T>(this T data, string key)
|
||||
{
|
||||
var bytes = Encoding.UTF8.GetBytes(data.ToJSON());
|
||||
var bytes = Encoding.UTF8.GetBytes(data.ToJson());
|
||||
bytes.ToEcryptedData(key);
|
||||
}
|
||||
|
||||
public static T FromEncryptedJson<T>(string key)
|
||||
{
|
||||
var decoded = FromEncryptedData(key);
|
||||
return Encoding.UTF8.GetString(decoded).FromJSONString<T>();
|
||||
return Encoding.UTF8.GetString(decoded).FromJsonString<T>();
|
||||
}
|
||||
|
||||
|
||||
|
@ -28,11 +28,10 @@
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Genbox.AlphaFS" Version="2.2.2.1" />
|
||||
<PackageReference Include="ini-parser-netstandard" Version="2.5.2" />
|
||||
<PackageReference Include="MessagePack" Version="2.1.90" />
|
||||
<PackageReference Include="Microsoft.Win32.Registry" Version="4.7.0" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="Octodiff" Version="1.2.1" />
|
||||
<PackageReference Include="ReactiveUI" Version="11.2.3" />
|
||||
<PackageReference Include="ReactiveUI" Version="11.3.1" />
|
||||
<PackageReference Include="SharpZipLib" Version="1.2.0" />
|
||||
<PackageReference Include="System.Data.HashFunction.xxHash" Version="2.0.0" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
|
@ -26,7 +26,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
@ -139,7 +139,7 @@ namespace Wabbajack.Lib
|
||||
ModList.ReadmeIsWebsite = ReadmeIsWebsite;
|
||||
|
||||
using (var of = ModListOutputFolder.Combine("modlist").Create())
|
||||
of.WriteAsMessagePack(ModList);
|
||||
ModList.ToJson(of);
|
||||
|
||||
ModListOutputFile.Delete();
|
||||
|
||||
@ -191,7 +191,7 @@ namespace Wabbajack.Lib
|
||||
NumberOfInstalledFiles = ModList.Directives.Count,
|
||||
SizeOfInstalledFiles = ModList.Directives.Sum(a => a.Size)
|
||||
};
|
||||
metadata.ToJSON(ModListOutputFile + ".meta.json");
|
||||
metadata.ToJson(ModListOutputFile + ".meta.json");
|
||||
|
||||
|
||||
Utils.Log("Removing ModList staging folder");
|
||||
@ -201,7 +201,7 @@ namespace Wabbajack.Lib
|
||||
public void GenerateManifest()
|
||||
{
|
||||
var manifest = new Manifest(ModList);
|
||||
manifest.ToJSON(ModListOutputFile + ".manifest.json");
|
||||
manifest.ToJson(ModListOutputFile + ".manifest.json");
|
||||
}
|
||||
|
||||
public async Task GatherArchives()
|
||||
|
@ -79,10 +79,10 @@ namespace Wabbajack.Lib
|
||||
{
|
||||
entry = ar.GetEntry("modlist.json");
|
||||
using (var e = entry.Open())
|
||||
return e.FromJSON<ModList>();
|
||||
return e.FromJson<ModList>();
|
||||
}
|
||||
using (var e = entry.Open())
|
||||
return e.ReadAsMessagePack<ModList>();
|
||||
return e.FromJson<ModList>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -18,7 +18,7 @@ namespace Wabbajack.Lib
|
||||
{
|
||||
using var response = await GetClient()
|
||||
.GetAsync($"https://{Consts.WabbajackCacheHostname}/alternative/{hash.ToHex()}");
|
||||
return !response.IsSuccessStatusCode ? null : (await response.Content.ReadAsStringAsync()).FromJSONString<Archive>();
|
||||
return !response.IsSuccessStatusCode ? null : (await response.Content.ReadAsStringAsync()).FromJsonString<Archive>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -1,22 +0,0 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json;
|
||||
using Wabbajack.Common;
|
||||
|
||||
namespace Wabbajack.Lib.CompilationSteps
|
||||
{
|
||||
public static class Serialization
|
||||
{
|
||||
public static string Serialize(IEnumerable<ICompilationStep> stack)
|
||||
{
|
||||
return stack.Select(s => s.GetState()).ToList()
|
||||
.ToJSON(TypeNameHandling.Auto, TypeNameAssemblyFormatHandling.Simple);
|
||||
}
|
||||
|
||||
public static List<ICompilationStep> Deserialize(string stack, ACompiler compiler)
|
||||
{
|
||||
return stack.FromJSONString<List<IState>>(TypeNameHandling.Auto, TypeNameAssemblyFormatHandling.Simple)
|
||||
.Select(s => s.CreateStep(compiler)).ToList();
|
||||
}
|
||||
}
|
||||
}
|
@ -3,8 +3,9 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Compression.BSA;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using Wabbajack.Lib.Downloaders;
|
||||
using Wabbajack.VirtualFileSystem;
|
||||
|
||||
@ -36,122 +37,98 @@ namespace Wabbajack.Lib
|
||||
}
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("ModList")]
|
||||
public class ModList
|
||||
{
|
||||
/// <summary>
|
||||
/// Archives required by this modlist
|
||||
/// </summary>
|
||||
[Key(0)]
|
||||
public List<Archive> Archives;
|
||||
|
||||
/// <summary>
|
||||
/// Author of the ModList
|
||||
/// </summary>
|
||||
[Key(1)]
|
||||
public string Author;
|
||||
|
||||
/// <summary>
|
||||
/// Description of the ModList
|
||||
/// </summary>
|
||||
[Key(2)]
|
||||
public string Description;
|
||||
|
||||
/// <summary>
|
||||
/// Install directives
|
||||
/// </summary>
|
||||
[Key(3)]
|
||||
public List<Directive> Directives;
|
||||
|
||||
/// <summary>
|
||||
/// The game variant to which this game applies
|
||||
/// </summary>
|
||||
[Key(4)]
|
||||
public Game GameType;
|
||||
|
||||
/// <summary>
|
||||
/// Hash of the banner-image
|
||||
/// </summary>
|
||||
[Key(5)]
|
||||
public RelativePath Image;
|
||||
|
||||
/// <summary>
|
||||
/// The Mod Manager used to create the modlist
|
||||
/// </summary>
|
||||
[Key(6)]
|
||||
public ModManager ModManager;
|
||||
|
||||
/// <summary>
|
||||
/// Name of the ModList
|
||||
/// </summary>
|
||||
[Key(7)]
|
||||
public string Name;
|
||||
|
||||
/// <summary>
|
||||
/// readme path or website
|
||||
/// </summary>
|
||||
[Key(8)]
|
||||
public string Readme;
|
||||
|
||||
/// <summary>
|
||||
/// Whether readme is a website
|
||||
/// </summary>
|
||||
[Key(9)]
|
||||
public bool ReadmeIsWebsite;
|
||||
|
||||
/// <summary>
|
||||
/// The build version of Wabbajack used when compiling the Modlist
|
||||
/// </summary>
|
||||
[Key(10)]
|
||||
public Version WabbajackVersion;
|
||||
|
||||
/// <summary>
|
||||
/// Website of the ModList
|
||||
/// </summary>
|
||||
[Key(11)]
|
||||
public Uri Website;
|
||||
|
||||
/// <summary>
|
||||
/// The size of all the archives once they're downloaded
|
||||
/// </summary>
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public long DownloadSize => Archives.Sum(a => a.Size);
|
||||
|
||||
/// <summary>
|
||||
/// The size of all the files once they are installed (excluding downloaded archives)
|
||||
/// </summary>
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public long InstallSize => Directives.Sum(s => s.Size);
|
||||
|
||||
public ModList Clone()
|
||||
{
|
||||
using var ms = new MemoryStream();
|
||||
ms.WriteAsMessagePack(this);
|
||||
this.ToJson(ms);
|
||||
ms.Position = 0;
|
||||
return ms.ReadAsMessagePack<ModList>();
|
||||
return ms.FromJson<ModList>();
|
||||
}
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[Union(0, typeof(ArchiveMeta))]
|
||||
[Union(1, typeof(CreateBSA))]
|
||||
[Union(2, typeof(FromArchive))]
|
||||
[Union(3, typeof(MergedPatch))]
|
||||
[Union(4, typeof(InlineFile))]
|
||||
[Union(5, typeof(PatchedFromArchive))]
|
||||
[Union(6, typeof(RemappedInlineFile))]
|
||||
[Union(7, typeof(CleanedESM))]
|
||||
public abstract class Directive
|
||||
{
|
||||
[Key(0)]
|
||||
public Hash Hash { get; set; }
|
||||
[Key(1)]
|
||||
public long Size { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// location the file will be copied to, relative to the install path.
|
||||
/// </summary>
|
||||
[Key(2)]
|
||||
public RelativePath To { get; set; }
|
||||
}
|
||||
|
||||
@ -164,20 +141,18 @@ namespace Wabbajack.Lib
|
||||
{
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("InlineFile")]
|
||||
public class InlineFile : Directive
|
||||
{
|
||||
/// <summary>
|
||||
/// Data that will be written as-is to the destination location;
|
||||
/// </summary>
|
||||
[Key(3)]
|
||||
public RelativePath SourceDataID { get; set; }
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("ArchiveMeta")]
|
||||
public class ArchiveMeta : Directive
|
||||
{
|
||||
[Key(3)]
|
||||
public RelativePath SourceDataID { get; set; }
|
||||
}
|
||||
|
||||
@ -186,117 +161,99 @@ namespace Wabbajack.Lib
|
||||
/// <summary>
|
||||
/// File meant to be extracted before the installation
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
[JsonName("PropertyFile")]
|
||||
public class PropertyFile : InlineFile
|
||||
{
|
||||
[Key(4)]
|
||||
public PropertyType Type;
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("CleanedESM")]
|
||||
public class CleanedESM : InlineFile
|
||||
{
|
||||
[Key(4)]
|
||||
public Hash SourceESMHash;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A file that has the game and MO2 folders remapped on installation
|
||||
/// </summary>
|
||||
[MessagePackObject]
|
||||
[JsonName("RemappedInlineFile")]
|
||||
public class RemappedInlineFile : InlineFile
|
||||
{
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("SteamMeta")]
|
||||
public class SteamMeta : ArchiveMeta
|
||||
{
|
||||
[Key(4)]
|
||||
public int ItemID { get; set; }
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("FromArchive")]
|
||||
public class FromArchive : Directive
|
||||
{
|
||||
private string _fullPath;
|
||||
|
||||
[Key(3)]
|
||||
public HashRelativePath ArchiveHashPath { get; set; }
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public VirtualFile FromFile { get; set; }
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public string FullPath => _fullPath ??= string.Join("|", ArchiveHashPath);
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("CreateBSA")]
|
||||
public class CreateBSA : Directive
|
||||
{
|
||||
[Key(3)]
|
||||
public RelativePath TempID { get; set; }
|
||||
[Key(4)]
|
||||
public ArchiveStateObject State { get; set; }
|
||||
[Key(5)]
|
||||
public List<FileStateObject> FileStates { get; set; }
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("PatchedFromArchive")]
|
||||
public class PatchedFromArchive : FromArchive
|
||||
{
|
||||
[Key(4)]
|
||||
public Hash FromHash { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The file to apply to the source file to patch it
|
||||
/// </summary>
|
||||
[Key(5)]
|
||||
public RelativePath PatchID { get; set; }
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("SourcePatch")]
|
||||
public class SourcePatch
|
||||
{
|
||||
[Key(0)]
|
||||
public Hash Hash { get; set; }
|
||||
[Key(1)]
|
||||
public RelativePath RelativePath { get; set; }
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("MergedPatch")]
|
||||
public class MergedPatch : Directive
|
||||
{
|
||||
[Key(3)]
|
||||
public RelativePath PatchID { get; set; }
|
||||
[Key(4)]
|
||||
public List<SourcePatch> Sources { get; set; }
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("Archive")]
|
||||
public class Archive
|
||||
{
|
||||
/// <summary>
|
||||
/// xxHash64 of the archive
|
||||
/// </summary>
|
||||
[Key(0)]
|
||||
public Hash Hash { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Meta INI for the downloaded archive
|
||||
/// </summary>
|
||||
[Key(1)]
|
||||
public string Meta { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Human friendly name of this archive
|
||||
/// </summary>
|
||||
[Key(2)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Key(3)]
|
||||
public long Size { get; set; }
|
||||
|
||||
[Key(4)]
|
||||
public AbstractDownloadState State { get; set; }
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,7 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Alphaleonis.Win32.Filesystem;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Lib.Validation;
|
||||
|
||||
@ -22,22 +21,6 @@ namespace Wabbajack.Lib.Downloaders
|
||||
Task<bool> LoadMetaData();
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[Union(0, typeof(HTTPDownloader.State))]
|
||||
[Union(1, typeof(GameFileSourceDownloader.State))]
|
||||
[Union(2, typeof(GoogleDriveDownloader.State))]
|
||||
[Union(3, typeof(LoversLabDownloader.State))]
|
||||
[Union(4, typeof(ManualDownloader.State))]
|
||||
[Union(5, typeof(MediaFireDownloader.State))]
|
||||
[Union(6, typeof(MegaDownloader.State))]
|
||||
[Union(7, typeof(ModDBDownloader.State))]
|
||||
[Union(8, typeof(NexusDownloader.State))]
|
||||
[Union(9, typeof(SteamWorkshopDownloader.State))]
|
||||
[Union(10, typeof(VectorPlexusDownloader.State))]
|
||||
[Union(11, typeof(AFKModsDownloader.State))]
|
||||
[Union(12, typeof(TESAllianceDownloader.State))]
|
||||
[Union(13, typeof(BethesdaNetDownloader.State))]
|
||||
[Union(14, typeof(YouTubeDownloader.State))]
|
||||
public abstract class AbstractDownloadState
|
||||
{
|
||||
|
||||
@ -69,10 +52,10 @@ namespace Wabbajack.Lib.Downloaders
|
||||
TypeToName = NameToType.ToDictionary(k => k.Value, k => k.Key);
|
||||
}
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public abstract object[] PrimaryKey { get; }
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public string PrimaryKeyString
|
||||
{
|
||||
get
|
||||
|
@ -5,12 +5,9 @@ using System.Net;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using HtmlAgilityPack;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Lib.Validation;
|
||||
using File = System.IO.File;
|
||||
|
||||
namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
@ -74,47 +71,34 @@ namespace Wabbajack.Lib.Downloaders
|
||||
}
|
||||
|
||||
|
||||
[MessagePackObject]
|
||||
public class State<TStateDownloader> : AbstractDownloadState, IMetaState where TStateDownloader : IDownloader
|
||||
{
|
||||
[Key(0)]
|
||||
public string FullURL { get; set; }
|
||||
[Key(1)]
|
||||
public bool IsAttachment { get; set; }
|
||||
[Key(2)]
|
||||
public string FileID { get; set; }
|
||||
|
||||
[Key(3)]
|
||||
public string FileName { get; set; }
|
||||
|
||||
// from IMetaState
|
||||
[Key(4)]
|
||||
|
||||
public Uri URL => new Uri($"{Site}/files/file/{FileName}");
|
||||
[Key(5)]
|
||||
public string Name { get; set; }
|
||||
[Key(6)]
|
||||
public string Author { get; set; }
|
||||
[Key(7)]
|
||||
public string Version { get; set; }
|
||||
[Key(8)]
|
||||
public string ImageURL { get; set; }
|
||||
[Key(9)]
|
||||
public virtual bool IsNSFW { get; set; }
|
||||
[Key(10)]
|
||||
public string Description { get; set; }
|
||||
|
||||
private static bool IsHTTPS => Downloader.SiteURL.AbsolutePath.StartsWith("https://");
|
||||
private static string URLPrefix => IsHTTPS ? "https://" : "http://";
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public static string Site => string.IsNullOrWhiteSpace(Downloader.SiteURL.Query)
|
||||
? $"{URLPrefix}{Downloader.SiteURL.Host}"
|
||||
: Downloader.SiteURL.ToString();
|
||||
|
||||
public static AbstractNeedsLoginDownloader Downloader => (AbstractNeedsLoginDownloader)(object)DownloadDispatcher.GetInstance<TDownloader>();
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public override object[] PrimaryKey
|
||||
{
|
||||
get
|
||||
@ -183,7 +167,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
return await streamResult.Content.ReadAsStreamAsync();
|
||||
|
||||
// Sometimes LL hands back a json object telling us to wait until a certain time
|
||||
var times = (await streamResult.Content.ReadAsStringAsync()).FromJSONString<WaitResponse>();
|
||||
var times = (await streamResult.Content.ReadAsStringAsync()).FromJsonString<WaitResponse>();
|
||||
var secs = times.Download - times.CurrentTime;
|
||||
for (int x = 0; x < secs; x++)
|
||||
{
|
||||
|
@ -10,6 +10,7 @@ using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Text.Json.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
using Newtonsoft.Json.Linq;
|
||||
@ -18,6 +19,7 @@ using Org.BouncyCastle.Crypto.Parameters;
|
||||
using Org.BouncyCastle.Security;
|
||||
using ReactiveUI;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using Wabbajack.Lib.Validation;
|
||||
using File = Alphaleonis.Win32.Filesystem.File;
|
||||
using Game = Wabbajack.Common.Game;
|
||||
@ -90,7 +92,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
|
||||
try
|
||||
{
|
||||
var result = last_line.FromJSONString<BethesdaNetData>();
|
||||
var result = last_line.FromJsonString<BethesdaNetData>();
|
||||
result.ToEcryptedJson(DataName);
|
||||
return result;
|
||||
}
|
||||
@ -113,10 +115,14 @@ namespace Wabbajack.Lib.Downloaders
|
||||
public Uri SiteURL => new Uri("https://bethesda.net");
|
||||
public Uri IconUri { get; }
|
||||
|
||||
|
||||
[JsonName("BethesdaNetDownloader")]
|
||||
public class State : AbstractDownloadState
|
||||
{
|
||||
public string GameName { get; set; }
|
||||
public string ContentId { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public override object[] PrimaryKey => new object[] {GameName, ContentId};
|
||||
|
||||
public override bool IsWhitelisted(ServerWhitelist whitelist)
|
||||
@ -210,7 +216,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
var posted = await client.PostAsync("https://api.bethesda.net/beam/accounts/external_login",
|
||||
new StringContent(login_info.body, Encoding.UTF8, "application/json"));
|
||||
|
||||
info.AccessToken = (await posted.Content.ReadAsStringAsync()).FromJSONString<BeamLoginResponse>().access_token;
|
||||
info.AccessToken = (await posted.Content.ReadAsStringAsync()).FromJsonString<BeamLoginResponse>().access_token;
|
||||
|
||||
client.Headers.Add(("x-cdp-app", "UGC SDK"));
|
||||
client.Headers.Add(("x-cdp-app-ver", "0.9.11314/debug"));
|
||||
@ -220,7 +226,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
posted = await client.PostAsync("https://api.bethesda.net/cdp-user/auth",
|
||||
new StringContent("{\"access_token\": \"" + info.AccessToken + "\"}", Encoding.UTF8,
|
||||
"application/json"));
|
||||
info.CDPToken = (await posted.Content.ReadAsStringAsync()).FromJSONString<CDPLoginResponse>().token;
|
||||
info.CDPToken = (await posted.Content.ReadAsStringAsync()).FromJsonString<CDPLoginResponse>().token;
|
||||
|
||||
client.Headers.Add(("X-Access-Token", info.AccessToken));
|
||||
var got = await client.GetAsync($"https://api.bethesda.net/mods/ugc-workshop/content/get?content_id={ContentId}");
|
||||
@ -238,7 +244,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
got = await client.GetAsync(
|
||||
$"https://api.bethesda.net/cdp-user/projects/{info.CDPProductId}/branches/{info.CDPBranchId}/tree/.json");
|
||||
|
||||
var tree = (await got.Content.ReadAsStringAsync()).FromJSONString<CDPTree>();
|
||||
var tree = (await got.Content.ReadAsStringAsync()).FromJsonString<CDPTree>();
|
||||
|
||||
got.Dispose();
|
||||
got = await client.PostAsync($"https://api.bethesda.net/mods/ugc-content/add-subscription", new StringContent($"{{\"content_id\": \"{ContentId}\"}}", Encoding.UTF8, "application/json"));
|
||||
|
@ -1,13 +1,8 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Alphaleonis.Win32.Filesystem;
|
||||
using MessagePack;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using Wabbajack.Lib.Validation;
|
||||
using File = Alphaleonis.Win32.Filesystem.File;
|
||||
using Game = Wabbajack.Common.Game;
|
||||
|
||||
namespace Wabbajack.Lib.Downloaders
|
||||
@ -48,22 +43,18 @@ namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("GameFileSourceDownloader")]
|
||||
public class State : AbstractDownloadState
|
||||
{
|
||||
[Key(0)]
|
||||
public Game Game { get; set; }
|
||||
[Key(1)]
|
||||
public RelativePath GameFile { get; set; }
|
||||
[Key(2)]
|
||||
public Hash Hash { get; set; }
|
||||
[Key(3)]
|
||||
public string GameVersion { get; set; }
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
internal AbsolutePath SourcePath => Game.MetaData().GameLocation().Value.Combine(GameFile);
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public override object[] PrimaryKey { get => new object[] {Game, GameVersion, GameFile}; }
|
||||
|
||||
public override bool IsWhitelisted(ServerWhitelist whitelist)
|
||||
|
@ -1,8 +1,8 @@
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using Wabbajack.Lib.Exceptions;
|
||||
using Wabbajack.Lib.Validation;
|
||||
|
||||
@ -35,13 +35,12 @@ namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("GoogleDriveDownloader")]
|
||||
public class State : AbstractDownloadState
|
||||
{
|
||||
[Key(0)]
|
||||
public string Id { get; set; }
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public override object[] PrimaryKey { get => new object[] {Id}; }
|
||||
|
||||
public override bool IsWhitelisted(ServerWhitelist whitelist)
|
||||
|
@ -5,11 +5,11 @@ using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using Wabbajack.Lib.Exceptions;
|
||||
using Wabbajack.Lib.Validation;
|
||||
using File = Alphaleonis.Win32.Filesystem.File;
|
||||
|
||||
namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
@ -50,19 +50,17 @@ namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("HttpDownloader")]
|
||||
public class State : AbstractDownloadState
|
||||
{
|
||||
[Key(0)]
|
||||
public string Url { get; set; }
|
||||
|
||||
[Key(1)]
|
||||
public List<string> Headers { get; set; }
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public Common.Http.Client Client { get; set; }
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public override object[] PrimaryKey { get => new object[] {Url};}
|
||||
|
||||
public override bool IsWhitelisted(ServerWhitelist whitelist)
|
||||
|
@ -2,8 +2,9 @@
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using HtmlAgilityPack;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using Wabbajack.Lib.WebAutomation;
|
||||
|
||||
namespace Wabbajack.Lib.Downloaders
|
||||
@ -32,9 +33,11 @@ namespace Wabbajack.Lib.Downloaders
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[JsonName("LoversLabDownloader")]
|
||||
public class State : State<LoversLabDownloader>
|
||||
{
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public override bool IsNSFW => true;
|
||||
|
||||
public override async Task<bool> LoadMetaData()
|
||||
|
@ -4,9 +4,10 @@ using System.Reactive.Linq;
|
||||
using System.Security;
|
||||
using System.Threading.Tasks;
|
||||
using CG.Web.MegaApiClient;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using ReactiveUI;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
|
||||
namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
@ -90,6 +91,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
}
|
||||
|
||||
[JsonName("MegaDownloader")]
|
||||
public class State : HTTPDownloader.State
|
||||
{
|
||||
private static MegaApiClient MegaApiClient => DownloadDispatcher.GetInstance<MegaDownloader>().MegaApiClient;
|
||||
|
@ -1,15 +1,11 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reactive.Linq;
|
||||
using System.IO;
|
||||
using System.Reactive.Subjects;
|
||||
using System.Threading.Tasks;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.IO;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using Wabbajack.Lib.Validation;
|
||||
using File = System.IO.File;
|
||||
|
||||
namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
@ -71,13 +67,12 @@ namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("ManualDownloader")]
|
||||
public class State : AbstractDownloadState
|
||||
{
|
||||
[Key(0)]
|
||||
public string Url { get; set; }
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public override object[] PrimaryKey { get => new object[] {Url}; }
|
||||
|
||||
public override bool IsWhitelisted(ServerWhitelist whitelist)
|
||||
|
@ -1,12 +1,10 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using HtmlAgilityPack;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using Wabbajack.Lib.Validation;
|
||||
|
||||
namespace Wabbajack.Lib.Downloaders
|
||||
@ -36,14 +34,12 @@ namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("ModDBDownloader")]
|
||||
public class State : AbstractDownloadState
|
||||
{
|
||||
|
||||
[Key(0)]
|
||||
public string Url { get; set; }
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public override object[] PrimaryKey { get => new object[]{Url}; }
|
||||
|
||||
public override bool IsWhitelisted(ServerWhitelist whitelist)
|
||||
|
@ -1,12 +1,13 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using System.Linq;
|
||||
using System.Reactive;
|
||||
using System.Reactive.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using ReactiveUI;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using Wabbajack.Common.StatusFeed.Errors;
|
||||
using Wabbajack.Lib.NexusApi;
|
||||
using Wabbajack.Lib.Validation;
|
||||
@ -128,38 +129,29 @@ namespace Wabbajack.Lib.Downloaders
|
||||
}
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("NexusDownloader")]
|
||||
public class State : AbstractDownloadState, IMetaState
|
||||
{
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public Uri URL => new Uri($"http://nexusmods.com/{Game.MetaData().NexusName}/mods/{ModID}");
|
||||
|
||||
[Key(0)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Key(1)]
|
||||
public string Author { get; set; }
|
||||
|
||||
[Key(2)]
|
||||
public string Version { get; set; }
|
||||
|
||||
[Key(3)]
|
||||
public string ImageURL { get; set; }
|
||||
|
||||
[Key(4)]
|
||||
public bool IsNSFW { get; set; }
|
||||
|
||||
[Key(5)]
|
||||
public string Description { get; set; }
|
||||
|
||||
[Key(6)]
|
||||
[JsonProperty("GameName")]
|
||||
[JsonConverter(typeof(Utils.GameConverter))]
|
||||
public Game Game { get; set; }
|
||||
|
||||
[Key(7)]
|
||||
public long ModID { get; set; }
|
||||
[Key(8)]
|
||||
public long FileID { get; set; }
|
||||
|
||||
public async Task<bool> LoadMetaData()
|
||||
@ -167,7 +159,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
return true;
|
||||
}
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public override object[] PrimaryKey { get => new object[]{Game, ModID, FileID};}
|
||||
|
||||
public override bool IsWhitelisted(ServerWhitelist whitelist)
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using MessagePack;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
|
||||
namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
@ -16,7 +17,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("TESAllianceDownloader")]
|
||||
public class State : State<TESAllianceDownloader>{}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using MessagePack;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
|
||||
namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
@ -17,7 +16,7 @@ namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("VectorPlexisDownloader")]
|
||||
public class State : State<VectorPlexusDownloader>
|
||||
{
|
||||
}
|
||||
|
@ -1,14 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Web;
|
||||
using MessagePack;
|
||||
using Newtonsoft.Json;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using Wabbajack.Lib.Validation;
|
||||
using YoutubeExplode;
|
||||
using YoutubeExplode.Exceptions;
|
||||
@ -59,19 +59,17 @@ namespace Wabbajack.Lib.Downloaders
|
||||
{
|
||||
}
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("YouTubeDownloader")]
|
||||
public class State : AbstractDownloadState
|
||||
{
|
||||
[Key(0)]
|
||||
public string Key { get; set; }
|
||||
|
||||
[Key(1)]
|
||||
public List<Track> Tracks { get; set; } = new List<Track>();
|
||||
|
||||
[IgnoreMember]
|
||||
[JsonIgnore]
|
||||
public override object[] PrimaryKey => new object[] {Key};
|
||||
|
||||
[MessagePackObject]
|
||||
[JsonName("YouTubeTrack")]
|
||||
public class Track
|
||||
{
|
||||
public enum FormatEnum
|
||||
@ -79,16 +77,12 @@ namespace Wabbajack.Lib.Downloaders
|
||||
XWM,
|
||||
WAV
|
||||
}
|
||||
[Key(0)]
|
||||
public FormatEnum Format { get; set; }
|
||||
|
||||
[Key(1)]
|
||||
public string Name { get; set; }
|
||||
|
||||
[Key(2)]
|
||||
public TimeSpan Start { get; set; }
|
||||
|
||||
[Key(3)]
|
||||
public TimeSpan End { get; set; }
|
||||
}
|
||||
|
||||
|
@ -186,7 +186,7 @@ namespace Wabbajack.Lib.FileUploader
|
||||
|
||||
public static async Task<IEnumerable<string>> GetMyFiles()
|
||||
{
|
||||
return (await (await GetAuthorizedClient()).GetStringAsync($"https://{Consts.WabbajackCacheHostname}/uploaded_files/list")).FromJSONString<string[]>();
|
||||
return (await (await GetAuthorizedClient()).GetStringAsync($"https://{Consts.WabbajackCacheHostname}/uploaded_files/list")).FromJsonString<string[]>();
|
||||
}
|
||||
|
||||
public static async Task<string> DeleteFile(string name)
|
||||
|
@ -1,16 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Wabbajack.Lib.GraphQL.DTOs
|
||||
{
|
||||
public class UploadedFile
|
||||
{
|
||||
public string Id { get; set; }
|
||||
public string Name { get; set; }
|
||||
public string MungedName { get; set; }
|
||||
public DateTime UploadDate { get; set; }
|
||||
public string Uploader { get; set; }
|
||||
public Uri Uri { get; set; }
|
||||
public string Hash { get; set; }
|
||||
public long Size { get; set; }
|
||||
}
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Net.Http.Headers;
|
||||
using System.Threading.Tasks;
|
||||
using GraphQL.Client;
|
||||
using GraphQL.Client.Http;
|
||||
using GraphQL.Common.Request;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Lib.FileUploader;
|
||||
using Wabbajack.Lib.GraphQL.DTOs;
|
||||
using Path = Alphaleonis.Win32.Filesystem.Path;
|
||||
|
||||
namespace Wabbajack.Lib.GraphQL
|
||||
{
|
||||
public class GraphQLService
|
||||
{
|
||||
public static readonly Uri BaseURL = new Uri("https://build.wabbajack.org/graphql");
|
||||
|
||||
public static async Task<List<UploadedFile>> GetUploadedFiles()
|
||||
{
|
||||
var client = new GraphQLHttpClient(BaseURL);
|
||||
var query = new GraphQLRequest
|
||||
{
|
||||
Query = @"
|
||||
query uploadedFilesQuery {
|
||||
uploadedFiles {
|
||||
id
|
||||
name
|
||||
hash
|
||||
uri
|
||||
uploader
|
||||
uploadDate
|
||||
}
|
||||
}"
|
||||
};
|
||||
var result = await client.SendQueryAsync(query);
|
||||
return result.GetDataFieldAs<List<UploadedFile>>("uploadedFiles");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ using Alphaleonis.Win32.Filesystem;
|
||||
using CefSharp;
|
||||
using CefSharp.OffScreen;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
|
||||
namespace Wabbajack.Lib.LibCefHelpers
|
||||
{
|
||||
@ -74,6 +75,7 @@ namespace Wabbajack.Lib.LibCefHelpers
|
||||
}
|
||||
}
|
||||
|
||||
[JsonName("HttpCookie")]
|
||||
public class Cookie
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
@ -1,9 +1,11 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
|
||||
namespace Wabbajack.Lib
|
||||
{
|
||||
[JsonName("Manifest")]
|
||||
public class Manifest
|
||||
{
|
||||
public string Name;
|
||||
|
@ -4,6 +4,7 @@ using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using Newtonsoft.Json;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Common.Serialization.Json;
|
||||
using Game = Wabbajack.Common.Game;
|
||||
|
||||
namespace Wabbajack.Lib.ModListRegistry
|
||||
@ -62,10 +63,10 @@ namespace Wabbajack.Lib.ModListRegistry
|
||||
var metadataResult = client.GetStringAsync(Consts.ModlistMetadataURL);
|
||||
var summaryResult = client.GetStringAsync(Consts.ModlistSummaryURL);
|
||||
|
||||
var metadata = (await metadataResult).FromJSONString<List<ModlistMetadata>>();
|
||||
var metadata = (await metadataResult).FromJsonString<List<ModlistMetadata>>();
|
||||
try
|
||||
{
|
||||
var summaries = (await summaryResult).FromJSONString<List<ModlistSummary>>().ToDictionary(d => d.Name);
|
||||
var summaries = (await summaryResult).FromJsonString<List<ModlistSummary>>().ToDictionary(d => d.Name);
|
||||
|
||||
foreach (var data in metadata)
|
||||
if (summaries.TryGetValue(data.Title, out var summary))
|
||||
@ -90,6 +91,7 @@ namespace Wabbajack.Lib.ModListRegistry
|
||||
}
|
||||
}
|
||||
|
||||
[JsonName("DownloadMetadata")]
|
||||
public class DownloadMetadata
|
||||
{
|
||||
public Hash Hash { get; set; }
|
||||
|
@ -233,7 +233,7 @@ namespace Wabbajack.Lib.NexusApi
|
||||
|
||||
|
||||
await using var stream = await response.Content.ReadAsStreamAsync();
|
||||
return stream.FromJSON<T>();
|
||||
return stream.FromJson<T>();
|
||||
}
|
||||
catch (TimeoutException)
|
||||
{
|
||||
|
@ -7,10 +7,10 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CefSharp.Common">
|
||||
<Version>79.1.350</Version>
|
||||
<Version>79.1.360</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="CefSharp.OffScreen">
|
||||
<Version>79.1.350</Version>
|
||||
<Version>79.1.360</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Fody">
|
||||
<Version>6.1.1</Version>
|
||||
@ -19,17 +19,14 @@
|
||||
<Version>2.2.2.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="GraphQL.Client">
|
||||
<Version>2.0.0-alpha.3</Version>
|
||||
<Version>3.0.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="HtmlAgilityPack">
|
||||
<Version>1.11.22</Version>
|
||||
<Version>1.11.23</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MegaApiClient">
|
||||
<Version>1.7.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MessagePackAnalyzer">
|
||||
<Version>2.1.90</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.CSharp">
|
||||
<Version>4.7.0</Version>
|
||||
</PackageReference>
|
||||
@ -37,13 +34,13 @@
|
||||
<Version>2.1.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="ReactiveUI">
|
||||
<Version>11.2.3</Version>
|
||||
<Version>11.3.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="ReactiveUI.Fody">
|
||||
<Version>11.2.3</Version>
|
||||
<Version>11.3.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="SharpCompress">
|
||||
<Version>0.24.0</Version>
|
||||
<Version>0.25.0</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.Collections.Immutable">
|
||||
<Version>1.7.0</Version>
|
||||
|
@ -59,7 +59,7 @@ namespace Wabbajack.Lib
|
||||
.Where(f => f.FileName == Consts.SettingsJson)
|
||||
.Where(f =>
|
||||
{
|
||||
var settings = f.FromJSON<zEditSettings>();
|
||||
var settings = f.FromJson<zEditSettings>();
|
||||
|
||||
if (settings.modManager != "Mod Organizer 2")
|
||||
{
|
||||
@ -109,7 +109,7 @@ namespace Wabbajack.Lib
|
||||
|
||||
Utils.Log($"Using merge file {mergeFile}");
|
||||
|
||||
var merges = mergeFile.FromJSON<List<zEditMerge>>().GroupBy(f => (f.name, f.filename)).ToArray();
|
||||
var merges = mergeFile.FromJson<List<zEditMerge>>().GroupBy(f => (f.name, f.filename)).ToArray();
|
||||
|
||||
merges.Where(m => m.Count() > 1)
|
||||
.Do(m =>
|
||||
|
@ -529,11 +529,7 @@ namespace Wabbajack.Test
|
||||
|
||||
private T RoundTripState<T>(T state)
|
||||
{
|
||||
using var ms = new MemoryStream();
|
||||
ms.WriteAsMessagePack(state);
|
||||
ms.Position = 0;
|
||||
|
||||
return ms.ReadAsMessagePack<T>();
|
||||
return state.ToJson().FromJsonString<T>();
|
||||
}
|
||||
|
||||
|
||||
|
@ -27,13 +27,13 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CefSharp.Common" Version="79.1.350" />
|
||||
<PackageReference Include="CefSharp.OffScreen" Version="79.1.350" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.2.0" />
|
||||
<PackageReference Include="CefSharp.Common" Version="79.1.360" />
|
||||
<PackageReference Include="CefSharp.OffScreen" Version="79.1.360" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.5.0" />
|
||||
<PackageReference Include="xunit" Version="2.4.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.0.1" />
|
||||
<PackageReference Include="XunitContext" Version="1.9.0" />
|
||||
<PackageReference Include="coverlet.collector" Version="1.2.1" />
|
||||
<PackageReference Include="XunitContext" Version="1.9.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
@ -36,7 +36,7 @@ namespace Wabbajack.Test
|
||||
mergePath = Path.Combine(utils.MO2Folder, Consts.MO2ModFolderName)
|
||||
};
|
||||
|
||||
settings.ToJSON(Path.Combine(utils.MO2Folder, "tools", "mator", "bleh", "profiles", "myprofile",
|
||||
settings.ToJson(Path.Combine(utils.MO2Folder, "tools", "mator", "bleh", "profiles", "myprofile",
|
||||
"settings.json"));
|
||||
|
||||
new List<zEditIntegration.zEditMerge>()
|
||||
@ -64,7 +64,7 @@ namespace Wabbajack.Test
|
||||
}
|
||||
}
|
||||
}
|
||||
}.ToJSON(Path.Combine(utils.MO2Folder, "tools", "mator", "bleh", "profiles", "myprofile", "merges.json"));
|
||||
}.ToJson(Path.Combine(utils.MO2Folder, "tools", "mator", "bleh", "profiles", "myprofile", "merges.json"));
|
||||
|
||||
utils.Configure();
|
||||
|
||||
|
@ -4,12 +4,9 @@ using System.Collections.Immutable;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
using K4os.Hash.Crc;
|
||||
using MessagePack;
|
||||
using Wabbajack.Common;
|
||||
using Path = Alphaleonis.Win32.Filesystem.Path;
|
||||
|
||||
namespace Wabbajack.VirtualFileSystem
|
||||
{
|
||||
@ -230,7 +227,7 @@ namespace Wabbajack.VirtualFileSystem
|
||||
|
||||
using (var stream = await response.Content.ReadAsStreamAsync())
|
||||
{
|
||||
return stream.FromJSON<IndexedVirtualFile>();
|
||||
return stream.FromJson<IndexedVirtualFile>();
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
|
@ -37,7 +37,7 @@ namespace Wabbajack
|
||||
// Version check
|
||||
try
|
||||
{
|
||||
settings = Consts.SettingsFile.FromJSON<MainSettings>();
|
||||
settings = Consts.SettingsFile.FromJson<MainSettings>();
|
||||
if (settings.Version == Consts.SettingsVersion)
|
||||
return true;
|
||||
}
|
||||
|
@ -1,22 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reactive.Disposables;
|
||||
using System.Reactive.Linq;
|
||||
using System.Reactive.Subjects;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
using System.Windows;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using Alphaleonis.Win32.Filesystem;
|
||||
using Microsoft.WindowsAPICodePack.Shell.PropertySystem;
|
||||
using ReactiveUI;
|
||||
using ReactiveUI.Fody.Helpers;
|
||||
using Wabbajack.Common;
|
||||
using Wabbajack.Lib.FileUploader;
|
||||
using Wabbajack.Lib.GraphQL;
|
||||
using Wabbajack.Lib.GraphQL.DTOs;
|
||||
using File = System.IO.File;
|
||||
|
||||
namespace Wabbajack
|
||||
{
|
||||
|
@ -57,8 +57,8 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="CefSharp.Wpf" Version="79.1.350" />
|
||||
<PackageReference Include="DynamicData" Version="6.14.8" />
|
||||
<PackageReference Include="CefSharp.Wpf" Version="79.1.360" />
|
||||
<PackageReference Include="DynamicData" Version="6.14.10" />
|
||||
<PackageReference Include="Extended.Wpf.Toolkit" Version="3.8.1" />
|
||||
<PackageReference Include="Fody" Version="6.1.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
@ -70,12 +70,12 @@
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="MahApps.Metro" Version="2.0.0-alpha0748" />
|
||||
<PackageReference Include="MahApps.Metro.IconPacks" Version="3.4.0" />
|
||||
<PackageReference Include="MahApps.Metro.IconPacks" Version="3.7.0" />
|
||||
<PackageReference Include="PInvoke.Gdi32" Version="0.6.6" />
|
||||
<PackageReference Include="PInvoke.User32" Version="0.6.6" />
|
||||
<PackageReference Include="ReactiveUI" Version="11.2.3" />
|
||||
<PackageReference Include="ReactiveUI.Fody" Version="11.2.3" />
|
||||
<PackageReference Include="ReactiveUI.WPF" Version="11.2.3" />
|
||||
<PackageReference Include="ReactiveUI" Version="11.3.1" />
|
||||
<PackageReference Include="ReactiveUI.Fody" Version="11.3.1" />
|
||||
<PackageReference Include="ReactiveUI.WPF" Version="11.3.1" />
|
||||
<PackageReference Include="SharpDX.DXGI" Version="4.2.0" />
|
||||
<PackageReference Include="WindowsAPICodePack-Shell" Version="1.1.1" />
|
||||
<PackageReference Include="WPFThemes.DarkBlend" Version="1.0.8" />
|
||||
|
Loading…
Reference in New Issue
Block a user