Skip to content

Commit

Permalink
Merge branch 'Corona-Studio:master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
fr1g authored Jul 29, 2023
2 parents b5a504e + a2df298 commit dfd643e
Show file tree
Hide file tree
Showing 124 changed files with 2,394 additions and 754 deletions.
10 changes: 8 additions & 2 deletions ProjBobcat/ProjBobcat/Class/Helper/AuthPropertyHelper.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
using System.Collections.Generic;
using System.Linq;
using System.Text.Json;
using System.Text.Json.Serialization;
using ProjBobcat.Class.Model;
using ProjBobcat.Class.Model.LauncherProfile;
using ProjBobcat.Class.Model.YggdrasilAuth;

namespace ProjBobcat.Class.Helper;

[JsonSerializable(typeof(Dictionary<string, string[]>))]
partial class UserPropertiesContext : JsonSerializerContext
{
}

/// <summary>
/// AuthProperty工具类
/// </summary>
Expand All @@ -17,7 +23,7 @@ public static class AuthPropertyHelper
/// </summary>
/// <param name="properties">Property 集合</param>
/// <returns>解析好的User Property</returns>
public static string ResolveUserProperties(this IEnumerable<PropertyModel> properties)
public static string ResolveUserProperties(this IEnumerable<PropertyModel>? properties)
{
if (properties == null) return "{}";

Expand All @@ -26,7 +32,7 @@ public static string ResolveUserProperties(this IEnumerable<PropertyModel> prope
item => item.Name,
item => new[] { item.Value });

return JsonSerializer.Serialize(keyValues);
return JsonSerializer.Serialize(keyValues, UserPropertiesContext.Default.DictionaryStringStringArray);
}


Expand Down
6 changes: 4 additions & 2 deletions ProjBobcat/ProjBobcat/Class/Helper/CryptoHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ namespace ProjBobcat.Class.Helper;
/// </summary>
public static class CryptoHelper
{

public static string BytesToString(this byte[] bytes) => BitConverter.ToString(bytes).Replace("-", string.Empty);
public static string BytesToString(this byte[] bytes)
{
return BitConverter.ToString(bytes).Replace("-", string.Empty);
}
}
79 changes: 65 additions & 14 deletions ProjBobcat/ProjBobcat/Class/Helper/CurseForgeAPIHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,65 @@
using System.Net.Http.Json;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Threading.Tasks;
using ProjBobcat.Class.Model.CurseForge;
using ProjBobcat.Class.Model.CurseForge.API;

namespace ProjBobcat.Class.Helper;

#region Temp Models

record AddonInfoReqModel(IEnumerable<int> modIds);

Check warning on line 15 in ProjBobcat/ProjBobcat/Class/Helper/CurseForgeAPIHelper.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

The type 'AddonInfoReqModel' defines init-only properties, deserialization of which is currently not supported in source generation mode.

Check warning on line 15 in ProjBobcat/ProjBobcat/Class/Helper/CurseForgeAPIHelper.cs

View workflow job for this annotation

GitHub Actions / Analyze (csharp)

The type 'AddonInfoReqModel' defines init-only properties, deserialization of which is currently not supported in source generation mode.

[JsonSerializable(typeof(AddonInfoReqModel))]
partial class AddonInfoReqModelContext : JsonSerializerContext
{
}

[JsonSerializable(typeof(DataModelWithPagination<CurseForgeAddonInfo[]>))]
partial class SearchAddonsResultModelContext : JsonSerializerContext
{
}

[JsonSerializable(typeof(DataModel<CurseForgeAddonInfo>))]
partial class GetAddonResultModelContext : JsonSerializerContext
{
}

[JsonSerializable(typeof(DataModel<CurseForgeAddonInfo[]>))]
partial class GetAddonsResultModelContext : JsonSerializerContext
{
}

[JsonSerializable(typeof(DataModel<CurseForgeLatestFileModel[]>))]
partial class GetAddonFilesResultModelContext : JsonSerializerContext
{
}

[JsonSerializable(typeof(DataModel<CurseForgeSearchCategoryModel[]>))]
partial class GetCategoriesResultContext : JsonSerializerContext
{
}

[JsonSerializable(typeof(DataModel<CurseForgeFeaturedAddonModel>))]
partial class GetFeaturedAddonsResultContext : JsonSerializerContext
{
}

[JsonSerializable(typeof(DataModel<string>))]
partial class DataModelStringResultContext : JsonSerializerContext
{
}

#endregion

public static class CurseForgeAPIHelper
{
const string BaseUrl = "https://api.curseforge.com/v1";

static string ApiKey { get; set; }
static HttpClient Client => HttpClientHelper.GetNewClient(HttpClientHelper.DefaultClientName);
static HttpClient Client => HttpClientHelper.DefaultClient;

static HttpRequestMessage Req(HttpMethod method, string url)
{
Expand All @@ -37,7 +84,8 @@ public static void SetApiKey(string apiKey)
using var req = Req(HttpMethod.Get, reqUrl);
using var res = await Client.SendAsync(req);

return await res.Content.ReadFromJsonAsync<DataModelWithPagination<CurseForgeAddonInfo[]>>();
return await res.Content.ReadFromJsonAsync(SearchAddonsResultModelContext.Default
.DataModelWithPaginationCurseForgeAddonInfoArray);
}

public static async Task<CurseForgeAddonInfo?> GetAddon(int addonId)
Expand All @@ -47,16 +95,15 @@ public static void SetApiKey(string apiKey)
using var req = Req(HttpMethod.Get, reqUrl);
using var res = await Client.SendAsync(req);

return (await res.Content.ReadFromJsonAsync<DataModel<CurseForgeAddonInfo>>())?.Data;
return (await res.Content.ReadFromJsonAsync(GetAddonResultModelContext.Default.DataModelCurseForgeAddonInfo))
?.Data;
}

public static async Task<CurseForgeAddonInfo[]?> GetAddons(IEnumerable<int> addonIds)
{
const string reqUrl = $"{BaseUrl}/mods";
var data = JsonSerializer.Serialize(new
{
modIds = addonIds
});
var data = JsonSerializer.Serialize(new AddonInfoReqModel(addonIds),
AddonInfoReqModelContext.Default.AddonInfoReqModel);

using var req = Req(HttpMethod.Post, reqUrl);
req.Content = new StringContent(data, Encoding.UTF8, "application/json");
Expand All @@ -65,7 +112,8 @@ public static void SetApiKey(string apiKey)

res.EnsureSuccessStatusCode();

return (await res.Content.ReadFromJsonAsync<DataModel<CurseForgeAddonInfo[]>>())?.Data;
return (await res.Content.ReadFromJsonAsync(GetAddonsResultModelContext.Default
.DataModelCurseForgeAddonInfoArray))?.Data;
}

public static async Task<CurseForgeLatestFileModel[]?> GetAddonFiles(int addonId)
Expand All @@ -75,7 +123,8 @@ public static void SetApiKey(string apiKey)
using var req = Req(HttpMethod.Get, reqUrl);
using var res = await Client.SendAsync(req);

return (await res.Content.ReadFromJsonAsync<DataModel<CurseForgeLatestFileModel[]>>())?.Data;
return (await res.Content.ReadFromJsonAsync(GetAddonFilesResultModelContext.Default
.DataModelCurseForgeLatestFileModelArray))?.Data;
}

public static async Task<CurseForgeSearchCategoryModel[]?> GetCategories(int gameId = 432)
Expand All @@ -85,21 +134,23 @@ public static void SetApiKey(string apiKey)
using var req = Req(HttpMethod.Get, reqUrl);
using var res = await Client.SendAsync(req);

return (await res.Content.ReadFromJsonAsync<DataModel<CurseForgeSearchCategoryModel[]>>())?.Data;
return (await res.Content.ReadFromJsonAsync(GetCategoriesResultContext.Default
.DataModelCurseForgeSearchCategoryModelArray))?.Data;
}

public static async Task<CurseForgeFeaturedAddonModel?> GetFeaturedAddons(FeaturedQueryOptions options)
{
const string reqUrl = $"{BaseUrl}/mods/featured";
var reqJson = JsonSerializer.Serialize(options);
var reqJson = JsonSerializer.Serialize(options, FeaturedQueryOptionsContext.Default.FeaturedQueryOptions);

using var req = Req(HttpMethod.Post, reqUrl);
req.Content = new StringContent(reqJson, Encoding.UTF8, "application/json");

using var res = await Client.SendAsync(req);
res.EnsureSuccessStatusCode();

return (await res.Content.ReadFromJsonAsync<DataModel<CurseForgeFeaturedAddonModel>>())?.Data;
return (await res.Content.ReadFromJsonAsync(GetFeaturedAddonsResultContext.Default
.DataModelCurseForgeFeaturedAddonModel))?.Data;
}

public static async Task<string?> GetAddonDownloadUrl(long addonId, long fileId)
Expand All @@ -110,7 +161,7 @@ public static void SetApiKey(string apiKey)
using var res = await Client.SendAsync(req);
res.EnsureSuccessStatusCode();

return (await res.Content.ReadFromJsonAsync<DataModel<string>>())?.Data;
return (await res.Content.ReadFromJsonAsync(DataModelStringResultContext.Default.DataModelString))?.Data;
}

public static async Task<string?> GetAddonDescriptionHtml(long addonId)
Expand All @@ -121,6 +172,6 @@ public static void SetApiKey(string apiKey)
using var res = await Client.SendAsync(req);
res.EnsureSuccessStatusCode();

return (await res.Content.ReadFromJsonAsync<DataModel<string>>())?.Data;
return (await res.Content.ReadFromJsonAsync(DataModelStringResultContext.Default.DataModelString))?.Data;
}
}
7 changes: 3 additions & 4 deletions ProjBobcat/ProjBobcat/Class/Helper/DownloadHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ public static class DownloadHelper
/// </summary>
public static int DownloadThread { get; set; } = 8;

static HttpClient DataClient => HttpClientHelper.GetNewClient(HttpClientHelper.DataClientName);
static HttpClient DataClient => HttpClientHelper.DataClient;

#region 下载数据

Expand Down Expand Up @@ -218,10 +218,9 @@ public static async Task AdvancedDownloadListFile(IEnumerable<DownloadFile> file

#region 分片下载

static HttpClient HeadClient => HttpClientHelper.GetNewClient(HttpClientHelper.HeadClientName);
static HttpClient HeadClient => HttpClientHelper.HeadClient;

static HttpClient MultiPartClient =>
HttpClientHelper.GetNewClient(HttpClientHelper.MultiPartClientName);
static HttpClient MultiPartClient => HttpClientHelper.MultiPartClient;

static readonly MemoryPool<byte> Pool = MemoryPool<byte>.Shared;

Expand Down
37 changes: 37 additions & 0 deletions ProjBobcat/ProjBobcat/Class/Helper/FileTypeHelper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
using System;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using ProjBobcat.Class.Model;
using SharpCompress.Archives;

namespace ProjBobcat.Class.Helper;

public static class FileTypeHelper
{
public static async Task<AssetFileType> TryDetectFileTypeAsync(string filePath)
{
if (!File.Exists(filePath)) throw new IOException("File not found.");

var extension = Path.GetExtension(filePath);

switch (extension)
{
case ".mrpack":
return AssetFileType.ModrinthModPack;
case ".zip":
{
await using var fs = File.OpenRead(filePath);
using var archive = ArchiveFactory.Open(fs);

if (archive.Entries.Any(e => e.Key.Equals("manifest.json", StringComparison.OrdinalIgnoreCase)))
return AssetFileType.CurseForgeModPack;
if (archive.Entries.Any(e => e.Key.Equals("modrinth.index.json", StringComparison.OrdinalIgnoreCase)))
return AssetFileType.ModrinthModPack;
break;
}
}

return AssetFileType.Unknown;
}
}
2 changes: 1 addition & 1 deletion ProjBobcat/ProjBobcat/Class/Helper/GamePathHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ public static string OfficialLauncherGamePath()
var basePath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
#elif OSX
var path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var basePath = Path.Combine(path, "Application Support");
var basePath = Path.Combine(path, "Library", "Application Support");
#elif LINUX
var basePath = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
#endif
Expand Down
16 changes: 13 additions & 3 deletions ProjBobcat/ProjBobcat/Class/Helper/GameRegexHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,26 @@

namespace ProjBobcat.Class.Helper;

public static class GameRegexHelper
public static partial class GameRegexHelper
{
const string GameVersionRegexStr = "[0-9]{1,}.[0-9]{1,}[.]?[0-9]{0,}";

const string ForgeLegacyJarRegexStr =
"forge-[0-9]{1,}.[0-9]{1,}[.]?[0-9]{0,}-[0-9]{1,}.[0-9]{1,}.[0-9]{1,}.[0-9]{4}-[0-9]{1,}.[0-9]{1,}[.]?[0-9]{0,}-universal.jar";

#pragma warning disable SYSLIB1045 // 转换为“GeneratedRegexAttribute”。

#if NET7_0_OR_GREATER
[GeneratedRegex("[0-9]{1,}.[0-9]{1,}[.]?[0-9]{0,}")]
public static partial Regex GameVersionRegex();

[GeneratedRegex("forge-[0-9]{1,}.[0-9]{1,}[.]?[0-9]{0,}-[0-9]{1,}.[0-9]{1,}.[0-9]{1,}.[0-9]{4}-[0-9]{1,}.[0-9]{1,}[.]?[0-9]{0,}-universal.jar")]
public static partial Regex ForgeLegacyJarRegex();

#else

public static readonly Regex GameVersionRegex = new(GameVersionRegexStr, RegexOptions.Compiled);

public static readonly Regex ForgeLegacyJarRegex = new(ForgeLegacyJarRegexStr, RegexOptions.Compiled);
#pragma warning restore SYSLIB1045 // 转换为“GeneratedRegexAttribute”。

#endif
}
Loading

0 comments on commit dfd643e

Please sign in to comment.