No more MessagePack, Json is love, Json is life

This commit is contained in:
Timothy Baldridge 2020-04-06 14:48:54 -06:00
parent 3d16b1e838
commit 45254b0055
54 changed files with 346 additions and 604 deletions

View File

@ -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>();
}
}

View File

@ -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" />

View File

@ -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);
}

View File

@ -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);

View File

@ -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>

View File

@ -113,7 +113,7 @@ namespace Wabbajack.BuildServer.Controllers
{
ContentType = "application/json",
StatusCode = (int) HttpStatusCode.OK,
Content = lst.ToJSON()
Content = lst.ToJson()
};
}

View File

@ -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)

View File

@ -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]

View File

@ -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()
});
}

View File

@ -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>

View File

@ -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>

View File

@ -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>();
}
}
}

View File

@ -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>();
}
}
}

View File

@ -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;
}
}
}
}

View File

@ -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
}

View 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;
}
}
}

View File

@ -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>();
}

View File

@ -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" />

View File

@ -26,7 +26,7 @@
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="9.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
</ItemGroup>
</Project>

View File

@ -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()

View File

@ -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>

View File

@ -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>

View File

@ -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();
}
}
}

View File

@ -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; }
}

View File

@ -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

View File

@ -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++)
{

View File

@ -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"));

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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()

View File

@ -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;

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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>{}
}
}

View File

@ -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>
{
}

View File

@ -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; }
}

View File

@ -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)

View File

@ -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; }
}
}

View File

@ -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");
}
}
}

View File

@ -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; }

View File

@ -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;

View File

@ -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; }

View File

@ -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)
{

View File

@ -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>

View File

@ -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 =>

View File

@ -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>();
}

View File

@ -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>

View File

@ -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();

View File

@ -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)

View File

@ -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;
}

View File

@ -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
{

View File

@ -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" />