mirror of
https://github.com/HolographicHat/Yae.git
synced 2025-12-08 23:48:12 +08:00
aot
This commit is contained in:
@@ -21,11 +21,11 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Google.Protobuf" Version="3.26.1" />
|
||||
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.49-beta">
|
||||
<PackageReference Include="Google.Protobuf" Version="3.29.0" />
|
||||
<PackageReference Include="Microsoft.Windows.CsWin32" Version="0.3.106">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Grpc.Tools" Version="2.62.0">
|
||||
<PackageReference Include="Grpc.Tools" Version="2.67.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
|
||||
103
src/Export.cs
103
src/Export.cs
@@ -5,6 +5,7 @@ using System.Text;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Microsoft.Win32;
|
||||
using YaeAchievement.Outputs;
|
||||
using YaeAchievement.Parsers;
|
||||
using YaeAchievement.res;
|
||||
|
||||
@@ -14,10 +15,6 @@ public static class Export {
|
||||
|
||||
public static uint ExportTo { get; set; } = uint.MaxValue;
|
||||
|
||||
private static readonly JsonSerializerOptions JsonOpts = new () {
|
||||
WriteIndented = true
|
||||
};
|
||||
|
||||
public static void Choose(AchievementAllDataNotify data) {
|
||||
if (ExportTo == uint.MaxValue) {
|
||||
Console.Write(App.ExportChoose);
|
||||
@@ -41,12 +38,8 @@ public static class Export {
|
||||
})).Invoke(data);
|
||||
}
|
||||
|
||||
private class CocogoatResponse {
|
||||
[JsonPropertyName("key")] public string Code { get; init; } = null!;
|
||||
}
|
||||
|
||||
private static void ToCocogoat(AchievementAllDataNotify data) {
|
||||
var result = JsonSerializer.Serialize(ExportToUIAFApp(data));
|
||||
var result = UIAFSerializer.Serialize(data);
|
||||
using var request = new HttpRequestMessage();
|
||||
request.Method = HttpMethod.Post;
|
||||
request.RequestUri = new Uri($"https://77.cocogoat.cn/v1/memo?source={App.AllAchievement}");
|
||||
@@ -57,18 +50,15 @@ public static class Export {
|
||||
return;
|
||||
}
|
||||
var responseText = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
|
||||
var responseJson = JsonSerializer.Deserialize<CocogoatResponse>(responseText)!;
|
||||
Console.WriteLine(Utils.ShellOpen($"https://cocogoat.work/achievement?memo={responseJson.Code}")
|
||||
var responseJson = JsonSerializer.Deserialize(responseText, CocogoatResponseContext.Default.CocogoatResponse)!;
|
||||
Console.WriteLine(Utils.ShellOpen($"https://cocogoat.work/achievement?memo={responseJson.Key}")
|
||||
? App.ExportToCocogoatSuccess
|
||||
: $"https://cocogoat.work/achievement?memo={responseJson.Code}");
|
||||
: $"https://cocogoat.work/achievement?memo={responseJson.Key}");
|
||||
}
|
||||
|
||||
private static void ToWxApp1(AchievementAllDataNotify data) {
|
||||
var id = Guid.NewGuid().ToString("N").Substring(20, 8);
|
||||
var result = JsonSerializer.Serialize(new Dictionary<string, object> {
|
||||
{ "key", id },
|
||||
{ "data", ExportToUIAFApp(data) }
|
||||
});
|
||||
var result = WxApp1Serializer.Serialize(data, id);
|
||||
using var request = new HttpRequestMessage();
|
||||
request.Method = HttpMethod.Post;
|
||||
request.RequestUri = new Uri("https://api.qyinter.com/achievementRedis");
|
||||
@@ -79,7 +69,7 @@ public static class Export {
|
||||
|
||||
private static void ToHuTao(AchievementAllDataNotify data) {
|
||||
if (CheckWinUIAppScheme("hutao")) {
|
||||
Utils.CopyToClipboard(JsonSerializer.Serialize(ExportToUIAFApp(data)));
|
||||
Utils.CopyToClipboard(UIAFSerializer.Serialize(data));
|
||||
Utils.ShellOpen("hutao://achievement/import");
|
||||
Console.WriteLine(App.ExportToSnapGenshinSuccess);
|
||||
} else {
|
||||
@@ -90,7 +80,7 @@ public static class Export {
|
||||
|
||||
private static void ToXunkong(AchievementAllDataNotify data) {
|
||||
if (CheckWinUIAppScheme("xunkong")) {
|
||||
Utils.CopyToClipboard(JsonSerializer.Serialize(ExportToUIAFApp(data)));
|
||||
Utils.CopyToClipboard(UIAFSerializer.Serialize(data));
|
||||
Utils.ShellOpen("xunkong://import-achievement?caller=YaeAchievement&from=clipboard");
|
||||
Console.WriteLine(App.ExportToXunkongSuccess);
|
||||
} else {
|
||||
@@ -101,7 +91,7 @@ public static class Export {
|
||||
|
||||
private static void ToTeyvatGuide(AchievementAllDataNotify data) {
|
||||
if (Process.GetProcessesByName("TeyvatGuide").Length != 0) {
|
||||
Utils.CopyToClipboard(JsonSerializer.Serialize(ExportToUIAFApp(data)));
|
||||
Utils.CopyToClipboard(UIAFSerializer.Serialize(data));
|
||||
Utils.ShellOpen("teyvatguide://import_uigf?app=YaeAchievement");
|
||||
Console.WriteLine(App.ExportToTauriSuccess);
|
||||
} else {
|
||||
@@ -113,39 +103,21 @@ public static class Export {
|
||||
// ReSharper disable once InconsistentNaming
|
||||
private static void ToUIAFJson(AchievementAllDataNotify data) {
|
||||
var path = Path.GetFullPath($"uiaf-{DateTime.Now:yyyyMMddHHmmss}.json");
|
||||
if (TryWriteToFile(path, JsonSerializer.Serialize(ExportToUIAFApp(data)))) {
|
||||
if (TryWriteToFile(path, UIAFSerializer.Serialize(data))) {
|
||||
Console.WriteLine(App.ExportToFileSuccess, path);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ToPaimon(AchievementAllDataNotify data) {
|
||||
var info = GlobalVars.AchievementInfo.Items.ToDictionary(pair => pair.Key, pair => pair.Value.Group);
|
||||
var final = new Dictionary<string, Dictionary<uint, Dictionary<uint, bool>>> {
|
||||
["achievement"] = data.AchievementList
|
||||
.Where(achievement => achievement.Status is AchievementStatus.Finished or AchievementStatus.RewardTaken)
|
||||
.Where(achievement => info.ContainsKey(achievement.Id))
|
||||
.GroupBy(achievement => info[achievement.Id], achievement => achievement.Id)
|
||||
.OrderBy(group => group.Key)
|
||||
.ToDictionary(group => group.Key, group => group.ToDictionary(id => id, _ => true))
|
||||
};
|
||||
var path = Path.GetFullPath($"export-{DateTime.Now:yyyyMMddHHmmss}-paimon.json");
|
||||
if (TryWriteToFile(path, JsonSerializer.Serialize(final))) {
|
||||
if (TryWriteToFile(path, PaimonSerializer.Serialize(data))) {
|
||||
Console.WriteLine(App.ExportToFileSuccess, path);
|
||||
}
|
||||
}
|
||||
|
||||
private static void ToSeelie(AchievementAllDataNotify data) {
|
||||
var output = new Dictionary<uint, Dictionary<string, bool>>();
|
||||
foreach (var ach in data.AchievementList.Where(a => a.Status is AchievementStatus.Finished or AchievementStatus.RewardTaken)) {
|
||||
output[ach.Id] = new Dictionary<string, bool> {
|
||||
["done"] = true
|
||||
};
|
||||
}
|
||||
var final = new Dictionary<string, Dictionary<uint, Dictionary<string, bool>>> {
|
||||
["achievements"] = output.OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value)
|
||||
};
|
||||
var path = Path.GetFullPath($"export-{DateTime.Now:yyyyMMddHHmmss}-seelie.json");
|
||||
if (TryWriteToFile(path, JsonSerializer.Serialize(final))) {
|
||||
if (TryWriteToFile(path, SeelieSerializer.Serialize(data))) {
|
||||
Console.WriteLine(App.ExportToFileSuccess, path);
|
||||
}
|
||||
}
|
||||
@@ -187,34 +159,12 @@ public static class Export {
|
||||
|
||||
private static void ToRawJson(AchievementAllDataNotify data) {
|
||||
var path = Path.GetFullPath($"export-{DateTime.Now:yyyyMMddHHmmss}-raw.json");
|
||||
var text = JsonSerializer.Serialize(data, JsonOpts);
|
||||
var text = AchievementRawDataSerializer.Serialize(data);
|
||||
if (TryWriteToFile(path, text)) {
|
||||
Console.WriteLine(App.ExportToFileSuccess, path);
|
||||
}
|
||||
}
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
private static Dictionary<string, object> ExportToUIAFApp(AchievementAllDataNotify data) {
|
||||
var output = data.AchievementList
|
||||
.Where(a => (uint)a.Status > 1 || a.CurrentProgress > 0)
|
||||
.Select(ach => new Dictionary<string, uint> {
|
||||
["id"] = ach.Id,
|
||||
["status"] = (uint) ach.Status,
|
||||
["current"] = ach.CurrentProgress,
|
||||
["timestamp"] = ach.FinishTimestamp
|
||||
})
|
||||
.ToList();
|
||||
return new Dictionary<string, object> {
|
||||
["info"] = new Dictionary<string, object> {
|
||||
["export_app"] = "YaeAchievement",
|
||||
["export_timestamp"] = DateTimeOffset.Now.ToUnixTimeSeconds(),
|
||||
["export_app_version"] = GlobalVars.AppVersionName,
|
||||
["uiaf_version"] = "v1.1"
|
||||
},
|
||||
["list"] = output
|
||||
};
|
||||
}
|
||||
|
||||
// ReSharper disable once InconsistentNaming
|
||||
private static bool CheckWinUIAppScheme(string protocol) {
|
||||
return (string?)Registry.ClassesRoot.OpenSubKey(protocol)?.GetValue("") == $"URL:{protocol}";
|
||||
@@ -252,3 +202,30 @@ public static class Export {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class WxApp1Root {
|
||||
|
||||
public string Key { get; init; } = null!;
|
||||
|
||||
public UIAFRoot Data { get; init; } = null!;
|
||||
|
||||
}
|
||||
|
||||
[JsonSerializable(typeof(WxApp1Root))]
|
||||
[JsonSourceGenerationOptions(
|
||||
GenerationMode = JsonSourceGenerationMode.Serialization,
|
||||
PropertyNamingPolicy = JsonKnownNamingPolicy.SnakeCaseLower
|
||||
)]
|
||||
public partial class WxApp1Serializer : JsonSerializerContext {
|
||||
|
||||
public static string Serialize(AchievementAllDataNotify ntf, string key) => JsonSerializer.Serialize(new WxApp1Root {
|
||||
Key = key,
|
||||
Data = Outputs.UIAFRoot.FromNotify(ntf)
|
||||
}, Default.WxApp1Root);
|
||||
}
|
||||
|
||||
public record CocogoatResponse(string Key);
|
||||
|
||||
[JsonSerializable(typeof(CocogoatResponse))]
|
||||
[JsonSourceGenerationOptions(PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
|
||||
public partial class CocogoatResponseContext : JsonSerializerContext;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.Reflection;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Reflection;
|
||||
using Proto;
|
||||
|
||||
namespace YaeAchievement;
|
||||
@@ -10,7 +11,6 @@ namespace YaeAchievement;
|
||||
|
||||
public static class GlobalVars {
|
||||
|
||||
public static bool DebugProxy => false;
|
||||
public static bool UnexpectedExit { get; set; } = true;
|
||||
public static bool PauseOnExit { get; set; } = true;
|
||||
public static Version AppVersion { get; } = Assembly.GetEntryAssembly()!.GetName().Version!;
|
||||
@@ -28,11 +28,12 @@ public static class GlobalVars {
|
||||
public const string RinBucketHost = "https://rin.holohat.work";
|
||||
public const string SakuraBucketHost = "https://cn-cd-1259389942.file.myqcloud.com";
|
||||
|
||||
public static AchievementInfo AchievementInfo { get; }
|
||||
[field:MaybeNull]
|
||||
public static AchievementInfo AchievementInfo =>
|
||||
field ??= AchievementInfo.Parser.ParseFrom(Utils.GetBucketFile("schicksal/metadata").GetAwaiter().GetResult());
|
||||
|
||||
static GlobalVars() {
|
||||
Directory.CreateDirectory(DataPath);
|
||||
Directory.CreateDirectory(CachePath);
|
||||
AchievementInfo = AchievementInfo.Parser.ParseFrom(Utils.GetBucketFile("schicksal/metadata").GetAwaiter().GetResult());
|
||||
}
|
||||
}
|
||||
|
||||
37
src/Outputs/Paimon.cs
Normal file
37
src/Outputs/Paimon.cs
Normal file
@@ -0,0 +1,37 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using YaeAchievement.Parsers;
|
||||
|
||||
namespace YaeAchievement.Outputs;
|
||||
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable PropertyCanBeMadeInitOnly.Global
|
||||
#pragma warning disable CA1822 // ReSharper disable MemberCanBeMadeStatic.Global
|
||||
|
||||
public class PaimonRoot {
|
||||
|
||||
public Dictionary<uint, Dictionary<uint, bool>> Achievement { get; set; } = null!;
|
||||
|
||||
public static PaimonRoot FromNotify(AchievementAllDataNotify ntf) {
|
||||
var info = GlobalVars.AchievementInfo.Items.ToDictionary(pair => pair.Key, pair => pair.Value.Group);
|
||||
return new PaimonRoot {
|
||||
Achievement = ntf.AchievementList
|
||||
.Where(a => a.Status >= AchievementStatus.Finished && info.ContainsKey(a.Id))
|
||||
.GroupBy(a => info[a.Id], a => a.Id)
|
||||
.OrderBy(g => g.Key)
|
||||
.ToDictionary(g => g.Key, g => g.ToDictionary(id => id, _ => true))
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[JsonSerializable(typeof(PaimonRoot))]
|
||||
[JsonSourceGenerationOptions(
|
||||
GenerationMode = JsonSourceGenerationMode.Serialization,
|
||||
PropertyNamingPolicy = JsonKnownNamingPolicy.SnakeCaseLower
|
||||
)]
|
||||
public partial class PaimonSerializer : JsonSerializerContext {
|
||||
|
||||
public static string Serialize(AchievementAllDataNotify ntf) {
|
||||
return JsonSerializer.Serialize(Outputs.PaimonRoot.FromNotify(ntf), Default.PaimonRoot);
|
||||
}
|
||||
}
|
||||
39
src/Outputs/Seelie.cs
Normal file
39
src/Outputs/Seelie.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using YaeAchievement.Parsers;
|
||||
|
||||
namespace YaeAchievement.Outputs;
|
||||
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable PropertyCanBeMadeInitOnly.Global
|
||||
#pragma warning disable CA1822 // ReSharper disable MemberCanBeMadeStatic.Global
|
||||
|
||||
public class SeelieRoot {
|
||||
|
||||
public class AchievementFinishStatus {
|
||||
|
||||
public bool Done => true;
|
||||
|
||||
}
|
||||
|
||||
public Dictionary<uint, AchievementFinishStatus> Achievements { get; set; } = null!;
|
||||
|
||||
public static SeelieRoot FromNotify(AchievementAllDataNotify ntf) => new () {
|
||||
Achievements = ntf.AchievementList
|
||||
.Where(a => a.Status >= AchievementStatus.Finished)
|
||||
.OrderBy(a => a.Id)
|
||||
.ToDictionary(a => a.Id, _ => new AchievementFinishStatus())
|
||||
};
|
||||
}
|
||||
|
||||
[JsonSerializable(typeof(SeelieRoot))]
|
||||
[JsonSourceGenerationOptions(
|
||||
GenerationMode = JsonSourceGenerationMode.Serialization,
|
||||
PropertyNamingPolicy = JsonKnownNamingPolicy.SnakeCaseLower
|
||||
)]
|
||||
public partial class SeelieSerializer : JsonSerializerContext {
|
||||
|
||||
public static string Serialize(AchievementAllDataNotify ntf) {
|
||||
return JsonSerializer.Serialize(Outputs.SeelieRoot.FromNotify(ntf), Default.SeelieRoot);
|
||||
}
|
||||
}
|
||||
65
src/Outputs/UIAF.cs
Normal file
65
src/Outputs/UIAF.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using YaeAchievement.Parsers;
|
||||
|
||||
namespace YaeAchievement.Outputs;
|
||||
|
||||
// ReSharper disable InconsistentNaming
|
||||
// ReSharper disable MemberCanBePrivate.Global
|
||||
// ReSharper disable PropertyCanBeMadeInitOnly.Global
|
||||
#pragma warning disable CA1822 // ReSharper disable MemberCanBeMadeStatic.Global
|
||||
|
||||
public class UApplicationInfo {
|
||||
|
||||
public string ExportApp => "YaeAchievement";
|
||||
|
||||
public string ExportAppVersion => GlobalVars.AppVersionName;
|
||||
|
||||
public long ExportTimestamp => DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||
|
||||
public string UIAFVersion => "v1.1";
|
||||
|
||||
}
|
||||
|
||||
public class UAchievementInfo {
|
||||
|
||||
public uint Id { get; set; }
|
||||
|
||||
public uint Status { get; set; }
|
||||
|
||||
public uint Current { get; set; }
|
||||
|
||||
public uint Timestamp { get; set; }
|
||||
|
||||
}
|
||||
|
||||
public class UIAFRoot {
|
||||
|
||||
public UApplicationInfo Info => new ();
|
||||
|
||||
public IEnumerable<UAchievementInfo> List { get; set; } = null!;
|
||||
|
||||
public static UIAFRoot FromNotify(AchievementAllDataNotify ntf) => new () {
|
||||
List = ntf.AchievementList
|
||||
.Where(a => a.Status >= AchievementStatus.Finished || a.CurrentProgress > 0)
|
||||
.Select(a => new UAchievementInfo {
|
||||
Id = a.Id,
|
||||
Status = (uint) a.Status,
|
||||
Current = a.CurrentProgress,
|
||||
Timestamp = a.FinishTimestamp
|
||||
})
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
[JsonSerializable(typeof(UIAFRoot))]
|
||||
[JsonSourceGenerationOptions(
|
||||
GenerationMode = JsonSourceGenerationMode.Serialization,
|
||||
PropertyNamingPolicy = JsonKnownNamingPolicy.SnakeCaseLower
|
||||
)]
|
||||
public partial class UIAFSerializer : JsonSerializerContext {
|
||||
|
||||
public static string Serialize(AchievementAllDataNotify ntf) {
|
||||
return JsonSerializer.Serialize(Outputs.UIAFRoot.FromNotify(ntf), Default.UIAFRoot);
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using Google.Protobuf;
|
||||
using YaeAchievement.res;
|
||||
|
||||
@@ -109,3 +111,16 @@ public class AchievementAllDataNotify {
|
||||
private static extern byte[] ReadRawBytes(CodedInputStream stream, int size);
|
||||
|
||||
}
|
||||
|
||||
[JsonSerializable(typeof(AchievementAllDataNotify))]
|
||||
[JsonSourceGenerationOptions(
|
||||
WriteIndented = true,
|
||||
GenerationMode = JsonSourceGenerationMode.Serialization,
|
||||
PropertyNamingPolicy = JsonKnownNamingPolicy.SnakeCaseLower
|
||||
)]
|
||||
public partial class AchievementRawDataSerializer : JsonSerializerContext {
|
||||
|
||||
public static string Serialize(AchievementAllDataNotify ntf) {
|
||||
return JsonSerializer.Serialize(ntf, Default.AchievementAllDataNotify);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ namespace YaeAchievement;
|
||||
public static class Utils {
|
||||
|
||||
public static readonly HttpClient CHttpClient = new (new HttpClientHandler {
|
||||
Proxy = GlobalVars.DebugProxy ? new WebProxy("http://127.0.0.1:8888") : null,
|
||||
AutomaticDecompression = DecompressionMethods.Brotli | DecompressionMethods.GZip
|
||||
}) {
|
||||
DefaultRequestHeaders = {
|
||||
|
||||
Reference in New Issue
Block a user