diff --git a/Model/ResourceProject/Curseforge/CurseforgeAuthors.cs b/Model/Mod/Curseforge/CurseforgeAuthors.cs similarity index 67% rename from Model/ResourceProject/Curseforge/CurseforgeAuthors.cs rename to Model/Mod/Curseforge/CurseforgeAuthors.cs index 0bd956e6..8257a538 100644 --- a/Model/ResourceProject/Curseforge/CurseforgeAuthors.cs +++ b/Model/Mod/Curseforge/CurseforgeAuthors.cs @@ -1,6 +1,6 @@ using System; -namespace PCL.Core.Model.ResourceProject.Curseforge; +namespace PCL.Core.Model.Mod.Curseforge; [Serializable] public record CurseforgeAuthors( diff --git a/Model/ResourceProject/Curseforge/CurseforgeCategories.cs b/Model/Mod/Curseforge/CurseforgeCategories.cs similarity index 83% rename from Model/ResourceProject/Curseforge/CurseforgeCategories.cs rename to Model/Mod/Curseforge/CurseforgeCategories.cs index 3c6f2263..490a4ac0 100644 --- a/Model/ResourceProject/Curseforge/CurseforgeCategories.cs +++ b/Model/Mod/Curseforge/CurseforgeCategories.cs @@ -1,6 +1,6 @@ using System; -namespace PCL.Core.Model.ResourceProject.Curseforge; +namespace PCL.Core.Model.Mod.Curseforge; [Serializable] public record CurseforgeCategories( diff --git a/Model/ResourceProject/Curseforge/CurseforgeFile.cs b/Model/Mod/Curseforge/CurseforgeFile.cs similarity index 82% rename from Model/ResourceProject/Curseforge/CurseforgeFile.cs rename to Model/Mod/Curseforge/CurseforgeFile.cs index 9de6b567..f58b272b 100644 --- a/Model/ResourceProject/Curseforge/CurseforgeFile.cs +++ b/Model/Mod/Curseforge/CurseforgeFile.cs @@ -1,6 +1,6 @@ using System; -namespace PCL.Core.Model.ResourceProject.Curseforge; +namespace PCL.Core.Model.Mod.Curseforge; [Serializable] public record CurseforgeFile( diff --git a/Model/ResourceProject/Curseforge/CurseforgeHashes.cs b/Model/Mod/Curseforge/CurseforgeHashes.cs similarity index 64% rename from Model/ResourceProject/Curseforge/CurseforgeHashes.cs rename to Model/Mod/Curseforge/CurseforgeHashes.cs index 06342081..5c803c0d 100644 --- a/Model/ResourceProject/Curseforge/CurseforgeHashes.cs +++ b/Model/Mod/Curseforge/CurseforgeHashes.cs @@ -1,6 +1,6 @@ using System; -namespace PCL.Core.Model.ResourceProject.Curseforge; +namespace PCL.Core.Model.Mod.Curseforge; [Serializable] public record CurseforgeHashes( diff --git a/Model/ResourceProject/Curseforge/CurseforgeLinks.cs b/Model/Mod/Curseforge/CurseforgeLinks.cs similarity index 74% rename from Model/ResourceProject/Curseforge/CurseforgeLinks.cs rename to Model/Mod/Curseforge/CurseforgeLinks.cs index f5c4ee9e..b59075f6 100644 --- a/Model/ResourceProject/Curseforge/CurseforgeLinks.cs +++ b/Model/Mod/Curseforge/CurseforgeLinks.cs @@ -1,6 +1,6 @@ using System; -namespace PCL.Core.Model.ResourceProject.Curseforge; +namespace PCL.Core.Model.Mod.Curseforge; [Serializable] public record CurseforgeLinks( diff --git a/Model/ResourceProject/Curseforge/CurseforgePictures.cs b/Model/Mod/Curseforge/CurseforgePictures.cs similarity index 77% rename from Model/ResourceProject/Curseforge/CurseforgePictures.cs rename to Model/Mod/Curseforge/CurseforgePictures.cs index 3666e530..bf9c3b3d 100644 --- a/Model/ResourceProject/Curseforge/CurseforgePictures.cs +++ b/Model/Mod/Curseforge/CurseforgePictures.cs @@ -1,6 +1,6 @@ using System; -namespace PCL.Core.Model.ResourceProject.Curseforge; +namespace PCL.Core.Model.Mod.Curseforge; [Serializable] public record CurseforgePictures( diff --git a/Model/ResourceProject/Curseforge/CurseforgeProject.cs b/Model/Mod/Curseforge/CurseforgeProject.cs similarity index 90% rename from Model/ResourceProject/Curseforge/CurseforgeProject.cs rename to Model/Mod/Curseforge/CurseforgeProject.cs index 46de0f7c..618f35a4 100644 --- a/Model/ResourceProject/Curseforge/CurseforgeProject.cs +++ b/Model/Mod/Curseforge/CurseforgeProject.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace PCL.Core.Model.ResourceProject.Curseforge; +namespace PCL.Core.Model.Mod.Curseforge; [Serializable] public record class CurseforgeProject( diff --git a/Model/ResourceProject/Curseforge/CurseforgeResponseData.cs b/Model/Mod/Curseforge/CurseforgeResponseData.cs similarity index 81% rename from Model/ResourceProject/Curseforge/CurseforgeResponseData.cs rename to Model/Mod/Curseforge/CurseforgeResponseData.cs index 9f498af2..b08a6992 100644 --- a/Model/ResourceProject/Curseforge/CurseforgeResponseData.cs +++ b/Model/Mod/Curseforge/CurseforgeResponseData.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; -namespace PCL.Core.Model.ResourceProject.Curseforge; +namespace PCL.Core.Model.Mod.Curseforge; [Serializable] public record class CurseforgeProjectResponse(CurseforgeProject data); diff --git a/Model/ResourceProject/Curseforge/CurseforgeScreenshots.cs b/Model/Mod/Curseforge/CurseforgeScreenshots.cs similarity index 100% rename from Model/ResourceProject/Curseforge/CurseforgeScreenshots.cs rename to Model/Mod/Curseforge/CurseforgeScreenshots.cs diff --git a/Model/Mod/ModFiles.cs b/Model/Mod/ModFiles.cs new file mode 100644 index 00000000..0d39ce19 --- /dev/null +++ b/Model/Mod/ModFiles.cs @@ -0,0 +1,7 @@ +namespace PCL.Core.Model.Mod; + +public record ModFiles( + string Hash, + string DownloadUrl, + string FileName, + long FileSize); \ No newline at end of file diff --git a/Model/Mod/ModProjectDetail.cs b/Model/Mod/ModProjectDetail.cs new file mode 100644 index 00000000..da7359b7 --- /dev/null +++ b/Model/Mod/ModProjectDetail.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; + +namespace PCL.Core.Model.Mod; + +public record ModProjectDetail( + string Title, + string Slug, + string Id, + string Author, + string Description, + List Categories, + List GameVersions, + bool SupportClient, + bool SupportServer, + long Downloads, + string Icon); \ No newline at end of file diff --git a/Model/Mod/ModSearchResult.cs b/Model/Mod/ModSearchResult.cs new file mode 100644 index 00000000..b83cdcdf --- /dev/null +++ b/Model/Mod/ModSearchResult.cs @@ -0,0 +1,16 @@ +using System.Collections.Generic; +using PCL.Core.Utils.ModPlatform; + +namespace PCL.Core.Model.Mod; + +public record ModSearchResult( + string Title, + string Slug, + string Id, + string Author, + string Description, + ModProjectType ModProjectType, + long Downloads, + string Icon, + List GameVersions, + List Categories); \ No newline at end of file diff --git a/Model/Mod/ModUpdateCheckResult.cs b/Model/Mod/ModUpdateCheckResult.cs new file mode 100644 index 00000000..43a3a991 --- /dev/null +++ b/Model/Mod/ModUpdateCheckResult.cs @@ -0,0 +1,14 @@ +using System.Collections.Generic; +using PCL.Core.Utils.ModPlatform; + +namespace PCL.Core.Model.Mod; + +public record ModUpdateCheckResult( + string FileId, + string ProjectId, + List Dependencies, + string Changelog, + ModFileChannel FileChannel, + List SupportedLoaders, + List SupportedGameVersions, + List UpdateFiles); \ No newline at end of file diff --git a/Model/ResourceProject/Modrinth/ModrinthDonationUrl.cs b/Model/Mod/Modrinth/ModrinthDonationUrl.cs similarity index 70% rename from Model/ResourceProject/Modrinth/ModrinthDonationUrl.cs rename to Model/Mod/Modrinth/ModrinthDonationUrl.cs index ef9403b4..fd5895fd 100644 --- a/Model/ResourceProject/Modrinth/ModrinthDonationUrl.cs +++ b/Model/Mod/Modrinth/ModrinthDonationUrl.cs @@ -1,6 +1,6 @@ using System; -namespace PCL.Core.Model.ResourceProject.Modrinth; +namespace PCL.Core.Model.Mod.Modrinth; [Serializable] public record ModrinthDonationUrl( diff --git a/Model/ResourceProject/Modrinth/ModrinthGallery.cs b/Model/Mod/Modrinth/ModrinthGallery.cs similarity index 78% rename from Model/ResourceProject/Modrinth/ModrinthGallery.cs rename to Model/Mod/Modrinth/ModrinthGallery.cs index f4c97318..75ed6429 100644 --- a/Model/ResourceProject/Modrinth/ModrinthGallery.cs +++ b/Model/Mod/Modrinth/ModrinthGallery.cs @@ -1,6 +1,6 @@ using System; -namespace PCL.Core.Model.ResourceProject.Modrinth; +namespace PCL.Core.Model.Mod.Modrinth; [Serializable] public record ModrinthGallery( diff --git a/Model/ResourceProject/Modrinth/ModrinthLicense.cs b/Model/Mod/Modrinth/ModrinthLicense.cs similarity index 69% rename from Model/ResourceProject/Modrinth/ModrinthLicense.cs rename to Model/Mod/Modrinth/ModrinthLicense.cs index 3734cd62..881adb52 100644 --- a/Model/ResourceProject/Modrinth/ModrinthLicense.cs +++ b/Model/Mod/Modrinth/ModrinthLicense.cs @@ -1,6 +1,6 @@ using System; -namespace PCL.Core.Model.ResourceProject.Modrinth; +namespace PCL.Core.Model.Mod.Modrinth; [Serializable] public record ModrinthLicense( diff --git a/Model/ResourceProject/Modrinth/ModrinthModeratorMessage.cs b/Model/Mod/Modrinth/ModrinthModeratorMessage.cs similarity index 68% rename from Model/ResourceProject/Modrinth/ModrinthModeratorMessage.cs rename to Model/Mod/Modrinth/ModrinthModeratorMessage.cs index b6e87ac7..1c8fafcd 100644 --- a/Model/ResourceProject/Modrinth/ModrinthModeratorMessage.cs +++ b/Model/Mod/Modrinth/ModrinthModeratorMessage.cs @@ -1,6 +1,6 @@ using System; -namespace PCL.Core.Model.ResourceProject.Modrinth; +namespace PCL.Core.Model.Mod.Modrinth; [Serializable] public record ModrinthModeratorMessage( diff --git a/Model/ResourceProject/Modrinth/ModrinthProject.cs b/Model/Mod/Modrinth/ModrinthProjectModel.cs similarity index 91% rename from Model/ResourceProject/Modrinth/ModrinthProject.cs rename to Model/Mod/Modrinth/ModrinthProjectModel.cs index 49bbc48d..04cd80d8 100644 --- a/Model/ResourceProject/Modrinth/ModrinthProject.cs +++ b/Model/Mod/Modrinth/ModrinthProjectModel.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; -namespace PCL.Core.Model.ResourceProject.Modrinth; +namespace PCL.Core.Model.Mod.Modrinth; [Serializable] -public record class ModrinthProject( +public record class ModrinthProjectModel( string slug, string title, string description, diff --git a/PCL.Core.csproj b/PCL.Core.csproj index 4ce1c44b..62e99c2e 100644 --- a/PCL.Core.csproj +++ b/PCL.Core.csproj @@ -161,19 +161,23 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + @@ -199,6 +203,13 @@ + + + + + + + diff --git a/Service/HttpClientService.cs b/Service/HttpClientService.cs index 8816dbea..940312d2 100644 --- a/Service/HttpClientService.cs +++ b/Service/HttpClientService.cs @@ -1,106 +1,106 @@ -using System; -using System.Net.Http; -using System.Threading; -using PCL.Core.Helper; -using PCL.Core.LifecycleManagement; -using PCL.Core.Utils; - -namespace PCL.Core.Service; - -[LifecycleService(LifecycleState.Loading)] -public class HttpClientService : ILifecycleService -{ - public string Identifier => "network"; - public string Name => "网络服务"; - public bool SupportAsyncStart => true; - - private static LifecycleContext? _context; - private static LifecycleContext Context => _context!; - private HttpClientService() { _context = Lifecycle.GetContext(this); } - - public static HttpProxyManager Proxy { get; } = new(); - - private static HttpClientHandler _currentHandler = new() - { - UseProxy = true, - Proxy = Proxy - }; - - private static HttpClient _currentClient = new(_currentHandler); - - private static readonly object _OperationLock = new(); - - public static HttpClient GetClient() - { - lock (_OperationLock) - { - return _currentClient; - } - } - - private static HttpClientHandler? _previousHandler; - private static HttpClient? _previousClient; - - private static void _RefreshClient() - { - Context.Debug("正在刷新 HttpClient"); - _previousClient?.Dispose(); - _previousHandler?.Dispose(); - _previousClient = _currentClient; - _previousHandler = _currentHandler; - _currentHandler = new HttpClientHandler - { - UseProxy = true, - Proxy = Proxy - }; - _currentClient = new HttpClient(_currentHandler); - Context.Trace("已刷新 HttpClient"); - } - - private static readonly AutoResetEvent _RefreshEvent = new(false); - private static readonly AutoResetEvent _RefreshFinishedEvent = new(false); - - public static void RefreshClient() - { - lock (_OperationLock) - { - _manualRefresh = true; - _RefreshEvent.Set(); - _RefreshFinishedEvent.WaitOne(); - } - } - - private static bool _stopped = false; - private static bool _manualRefresh = false; - - public void Start() - { - Context.Trace("正在初始化 HttpClient 服务"); - NativeInterop.RunInNewThread(() => { - while (true) - { - _RefreshEvent.WaitOne(TimeSpan.FromHours(4)); - if (_stopped) break; - _RefreshClient(); - if (_manualRefresh) - { - _manualRefresh = false; - _RefreshFinishedEvent.Set(); - } - } - }, "HttpClient Refresh"); - } - - public void Stop() - { - lock (_OperationLock) - { - _stopped = true; - _RefreshEvent.Set(); - _currentClient.Dispose(); - _currentHandler.Dispose(); - _previousClient?.Dispose(); - _previousHandler?.Dispose(); - } - } -} +using System; +using System.Net.Http; +using System.Threading; +using PCL.Core.Helper; +using PCL.Core.LifecycleManagement; +using PCL.Core.Utils; + +namespace PCL.Core.Service; + +[LifecycleService(LifecycleState.Loading)] +public class HttpClientService : ILifecycleService +{ + public string Identifier => "network"; + public string Name => "网络服务"; + public bool SupportAsyncStart => true; + + private static LifecycleContext? _context; + private static LifecycleContext Context => _context!; + private HttpClientService() { _context = Lifecycle.GetContext(this); } + + public static HttpProxyManager Proxy { get; } = new(); + + private static HttpClientHandler _currentHandler = new() + { + UseProxy = true, + Proxy = Proxy + }; + + private static HttpClient _currentClient = new(_currentHandler); + + private static readonly object _OperationLock = new(); + + public static HttpClient GetClient() + { + lock (_OperationLock) + { + return _currentClient; + } + } + + private static HttpClientHandler? _previousHandler; + private static HttpClient? _previousClient; + + private static void _RefreshClient() + { + Context.Debug("正在刷新 HttpClient"); + _previousClient?.Dispose(); + _previousHandler?.Dispose(); + _previousClient = _currentClient; + _previousHandler = _currentHandler; + _currentHandler = new HttpClientHandler + { + UseProxy = true, + Proxy = Proxy + }; + _currentClient = new HttpClient(_currentHandler); + Context.Trace("已刷新 HttpClient"); + } + + private static readonly AutoResetEvent _RefreshEvent = new(false); + private static readonly AutoResetEvent _RefreshFinishedEvent = new(false); + + public static void RefreshClient() + { + lock (_OperationLock) + { + _manualRefresh = true; + _RefreshEvent.Set(); + _RefreshFinishedEvent.WaitOne(); + } + } + + private static bool _stopped = false; + private static bool _manualRefresh = false; + + public void Start() + { + Context.Trace("正在初始化 HttpClient 服务"); + NativeInterop.RunInNewThread(() => { + while (true) + { + _RefreshEvent.WaitOne(TimeSpan.FromHours(4)); + if (_stopped) break; + _RefreshClient(); + if (_manualRefresh) + { + _manualRefresh = false; + _RefreshFinishedEvent.Set(); + } + } + }, "HttpClient Refresh"); + } + + public void Stop() + { + lock (_OperationLock) + { + _stopped = true; + _RefreshEvent.Set(); + _currentClient.Dispose(); + _currentHandler.Dispose(); + _previousClient?.Dispose(); + _previousHandler?.Dispose(); + } + } +} diff --git a/Service/HttpService/HttpRequestBuilder.cs b/Service/HttpService/HttpRequestBuilder.cs new file mode 100644 index 00000000..bbbb7d66 --- /dev/null +++ b/Service/HttpService/HttpRequestBuilder.cs @@ -0,0 +1,6 @@ +namespace PCL.Core.Service.HttpService; + +public class HttpRequestBuilder +{ + +} \ No newline at end of file diff --git a/Utils/Minecraft/ModLoaders.cs b/Utils/Minecraft/ModLoaders.cs new file mode 100644 index 00000000..a11778d2 --- /dev/null +++ b/Utils/Minecraft/ModLoaders.cs @@ -0,0 +1,18 @@ +namespace PCL.Core.Utils.Minecraft; + +public enum ModLoaders +{ + Fabric, + Forge, + NeoForge, + Quilt, + Babric, + JavaAgent, + LegacyFabric, + LiteLoader, + RisugamisModLoader, + NilLoader, + Ornithe, + Rift, +} + diff --git a/Utils/Mod/IProject.cs b/Utils/Mod/IProject.cs new file mode 100644 index 00000000..8fa17b63 --- /dev/null +++ b/Utils/Mod/IProject.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using PCL.Core.Utils.Minecraft; + +namespace PCL.Core.Utils.Mod; + +public interface IProject +{ + string Name { get; } + string Slug { get; } + string Description { get; } + HashSet SupportedGameVersions { get; } + HashSet SupportedLoaders { get; } + Task> GetFiles(); +} \ No newline at end of file diff --git a/Utils/Mod/IProjectFile.cs b/Utils/Mod/IProjectFile.cs new file mode 100644 index 00000000..984f347d --- /dev/null +++ b/Utils/Mod/IProjectFile.cs @@ -0,0 +1,6 @@ +namespace PCL.Core.Utils.Mod; + +public interface IProjectFile +{ + +} \ No newline at end of file diff --git a/Utils/Mod/Modrinth/ModrinthProject.cs b/Utils/Mod/Modrinth/ModrinthProject.cs new file mode 100644 index 00000000..931ee190 --- /dev/null +++ b/Utils/Mod/Modrinth/ModrinthProject.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using PCL.Core.Model.Mod.Modrinth; +using PCL.Core.Utils.Minecraft; + +namespace PCL.Core.Utils.Mod.Modrinth; + +public class ModrinthProject : IProject +{ + private ModrinthProjectModel _model; + + public string Slug + { + get => _model.slug; + } + + public string Name + { + get => _model.title; + } + + public string Description + { + get => _model.description; + } + + public HashSet SupportedGameVersions + { + get => _model.versions.ToHashSet(); + } + + public HashSet SupportedLoaders + { + get => _model.loaders.ToHashSet(); + } + + public async Task> GetFiles() + { + throw new System.NotImplementedException(); + } +} \ No newline at end of file diff --git a/Utils/Mod/ProjectFileChannel.cs b/Utils/Mod/ProjectFileChannel.cs new file mode 100644 index 00000000..0b62788b --- /dev/null +++ b/Utils/Mod/ProjectFileChannel.cs @@ -0,0 +1,8 @@ +namespace PCL.Core.Utils.Mod; + +public enum ProjectFileChannel +{ + Stable, + Beta, + Alpha +} \ No newline at end of file diff --git a/Utils/Mod/ProjectFileStatus.cs b/Utils/Mod/ProjectFileStatus.cs new file mode 100644 index 00000000..64726b5b --- /dev/null +++ b/Utils/Mod/ProjectFileStatus.cs @@ -0,0 +1,7 @@ +namespace PCL.Core.Utils.Mod; + +public enum ProjectFileStatus +{ + Online, + Local +} \ No newline at end of file diff --git a/Utils/Mod/ProjectStatus.cs b/Utils/Mod/ProjectStatus.cs new file mode 100644 index 00000000..9e45a0e9 --- /dev/null +++ b/Utils/Mod/ProjectStatus.cs @@ -0,0 +1,8 @@ +namespace PCL.Core.Utils.Mod; + +public enum ProjectStatus +{ + FullyRecord, + BriefRecord, + NoRecord, +} \ No newline at end of file diff --git a/Utils/ModPlatform/IModPlatformService.cs b/Utils/ModPlatform/IModPlatformService.cs new file mode 100644 index 00000000..a3b3f4b2 --- /dev/null +++ b/Utils/ModPlatform/IModPlatformService.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using PCL.Core.Model.Mod; + +namespace PCL.Core.Utils.ModPlatform; + +public interface IModPlatformService +{ + Task> Search(ModSearch query); + Task GetProject(string id); + Task> CheckUpdatesFromHashes(IEnumerable fileHashes); +} \ No newline at end of file diff --git a/Utils/ModPlatform/ModFileChannel.cs b/Utils/ModPlatform/ModFileChannel.cs new file mode 100644 index 00000000..cf59b363 --- /dev/null +++ b/Utils/ModPlatform/ModFileChannel.cs @@ -0,0 +1,8 @@ +namespace PCL.Core.Utils.ModPlatform; + +public enum ModFileChannel +{ + Stable, + Beta, + Alpha +} \ No newline at end of file diff --git a/Utils/ModPlatform/ModProjectType.cs b/Utils/ModPlatform/ModProjectType.cs new file mode 100644 index 00000000..9610ddf9 --- /dev/null +++ b/Utils/ModPlatform/ModProjectType.cs @@ -0,0 +1,11 @@ +namespace PCL.Core.Utils.ModPlatform; + +public enum ModProjectType +{ + Mod, + Modpack, + ResourcePack, + Shader, + DataPack, + Plugins +} \ No newline at end of file diff --git a/Utils/ModPlatform/ModSearch.cs b/Utils/ModPlatform/ModSearch.cs new file mode 100644 index 00000000..5944fc5f --- /dev/null +++ b/Utils/ModPlatform/ModSearch.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using PCL.Core.Utils.Minecraft; + +namespace PCL.Core.Utils.ModPlatform; + +public record ModSearch( + string keyWord, + ModProjectType ModProjectType, + HashSet? modLoaders = null, + HashSet? categories = null, + HashSet? gameVersions = null, + int ResultLimit = 30); \ No newline at end of file diff --git a/Utils/ModPlatform/ModrinthFactsBuilder.cs b/Utils/ModPlatform/ModrinthFactsBuilder.cs new file mode 100644 index 00000000..2512bc01 --- /dev/null +++ b/Utils/ModPlatform/ModrinthFactsBuilder.cs @@ -0,0 +1,52 @@ +using System.Collections.Generic; + +namespace PCL.Core.Utils.ModPlatform; + +public class ModrinthFactsBuilder +{ + private List _content = []; + + public ModrinthFactsBuilder EqualProjectType(ModProjectType projectType) + { + _content.Add($"[\"project_type:{ModrinthPlatformService.ProjectType2String(projectType)}\"]"); + return this; + } + + public ModrinthFactsBuilder EqualGameVersion(string gameVersion) + { + _content.Add($"[\"versions:{gameVersion}\"]"); + return this; + } + + public ModrinthFactsBuilder EqualGameVersion(IEnumerable gameVersions) + { + foreach (var version in gameVersions) + EqualGameVersion(version); + return this; + } + + public ModrinthFactsBuilder EqualCategories(string categories) + { + _content.Add($"[\"categories:{categories}\"]"); + return this; + } + + public ModrinthFactsBuilder EqualCategories(IEnumerable categories) + { + foreach (var category in categories) + EqualCategories(category); + return this; + } + + public ModrinthFactsBuilder EqualLicense(string license) + { + _content.Add($"[\"license:{license}\"]"); + return this; + } + + public override string ToString() + { + var ret = $"[{string.Join(",", _content)}]"; + return ret; + } +} \ No newline at end of file diff --git a/Utils/ModPlatform/ModrinthPlatformService.cs b/Utils/ModPlatform/ModrinthPlatformService.cs new file mode 100644 index 00000000..d2d42562 --- /dev/null +++ b/Utils/ModPlatform/ModrinthPlatformService.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using PCL.Core.Model.Mod; +using PCL.Core.Service; +using PCL.Core.Utils.Minecraft; + +namespace PCL.Core.Utils.ModPlatform; + +public class ModrinthPlatformService : IModPlatformService +{ + private const string BaseUrl = "https://api.modrinth.com"; + + public async Task> Search(ModSearch query) + { + var queryUri = $"{BaseUrl}/search?"; + queryUri += $"query={query.keyWord}"; + var facts = new ModrinthFactsBuilder() + .EqualCategories(query.categories ?? Enumerable.Empty()) + .EqualCategories(query.modLoaders.Select(ProjectType2String) ?? Enumerable.Empty()) + .EqualGameVersion(query.gameVersions ?? Enumerable.Empty()) + .EqualProjectType(query.ModProjectType); + + using var request = new HttpRequestMessage(HttpMethod.Get,); + using var ret = await HttpClientService.GetClient().SendAsync(request, HttpCompletionOption.ResponseHeadersRead); + ret.EnsureSuccessStatusCode(); + var content = await ret.Content.ReadAsStringAsync(); + + } + + private static Dictionary _projectTypeStringMap = new() + { + [ModProjectType.Mod] = "mod", + [ModProjectType.Modpack] = "modpack", + [ModProjectType.ResourcePack] = "resourcepack", + [ModProjectType.Shader] = "shader" + }; + + public static string ProjectType2String(ModProjectType projectType) => _projectTypeStringMap.TryGetValue(projectType, out var value) ? value : string.Empty; + public static ModProjectType String2ProjectType(string projectType) => _projectTypeStringMap.FirstOrDefault(x => x.Value == projectType).Key; + + private static Dictionary _loaderStringMap = new() + { + [modl] + } +} \ No newline at end of file