diff --git a/CFPABot/Azusa/Pages/Diff.razor b/CFPABot/Azusa/Pages/Diff.razor index 308efc0..f7b7282 100644 --- a/CFPABot/Azusa/Pages/Diff.razor +++ b/CFPABot/Azusa/Pages/Diff.razor @@ -740,10 +740,38 @@ try { + if (slug.StartsWith("modrinth-datapack-")) + { + var realSlug = slug["modrinth-datapack-".Length..]; + var addon = await ModrinthManager.GetMod(realSlug); + foreach (var modVersion in versions) + { + var loaders = new[] { "datapack" }; + var modEnFile = await ModrinthManager.GetModEnFile(addon, modVersion.ToVersionDirectory().ToMCVersion(), loaders, LangType.EN); + var modCnFile = await ModrinthManager.GetModEnFile(addon, modVersion.ToVersionDirectory().ToMCVersion(), loaders, LangType.CN); + + if (modEnFile.files != null && modEnFile.files.FirstOrDefault() is { } f2) + { + var s = $"{modCnFile.downloadFileName} 的英文语言文件"; + + textsV.Add(s); + langV.Add(LangFileWrapper.FromContent(f2)); + } + + if (modCnFile.files != null && modCnFile.files.FirstOrDefault() is { } f) + { + var s = $"{modCnFile.downloadFileName} 的中文语言文件"; + + textsV.Add(s); + langV.Add(LangFileWrapper.FromContent(f)); + } + } + return; + } if (slug.StartsWith("modrinth-")) { - slug = slug["modrinth-".Length..]; - var addon = await ModrinthManager.GetMod(slug); + var realSlug = slug["modrinth-".Length..]; + var addon = await ModrinthManager.GetMod(realSlug); foreach (var modVersion in versions) { var modEnFile = await ModrinthManager.GetModEnFile(addon, modVersion.ToVersionDirectory().ToMCVersion(), LangType.EN); @@ -767,6 +795,32 @@ } return; } + else if (slug.StartsWith("texture-packs-")) + { + var realSlug = slug["texture-packs-".Length..]; + var addon = await CurseManager.GetAddon(realSlug); + foreach (var modVersion in versions) + { + var modEnFile = await CurseManager.GetModEnFile(addon, modVersion.ToVersionDirectory().ToMCVersion(), LangType.EN); + var modCnFile = await CurseManager.GetModEnFile(addon, modVersion.ToVersionDirectory().ToMCVersion(), LangType.CN); + + if (modEnFile.files != null && modEnFile.files.FirstOrDefault() is { } f2) + { + var s = $"{modCnFile.downloadFileName} 的英文语言文件"; + + textsV.Add(s); + langV.Add(LangFileWrapper.FromContent(f2)); + } + + if (modCnFile.files != null && modCnFile.files.FirstOrDefault() is { } f) + { + var s = $"{modCnFile.downloadFileName} 的中文语言文件"; + + textsV.Add(s); + langV.Add(LangFileWrapper.FromContent(f)); + } + } + } else { var addon = await CurseManager.GetAddon(slug); diff --git a/CFPABot/Command/CommandProcessor.cs b/CFPABot/Command/CommandProcessor.cs index d12698e..3d7bf3d 100644 --- a/CFPABot/Command/CommandProcessor.cs +++ b/CFPABot/Command/CommandProcessor.cs @@ -154,7 +154,42 @@ public static async Task RunInternal(int prid, string content, int commentID, Gi MCVersion.v1122 => "en_us.lang", _ => "en_us.json" }; - if (curseForgeID.StartsWith("modrinth-")) + if (curseForgeID.StartsWith("modrinth-datapack-")) + { + var originalID = curseForgeID; + curseForgeID = curseForgeID["modrinth-datapack-".Length..]; + var addon = await ModrinthManager.GetMod(curseForgeID); + + var modID = await ModrinthManager.GetModID(addon, version, new[] { "datapack" }, true, false); + var (files, downloadFileName) = await ModrinthManager.GetModEnFile(addon, version, new[] { "datapack" }, LangType.EN); + if (files.Length != 1) + { + sb.AppendLine(Locale.Command_update_en_MultipleLangFiles); + continue; + } + + sb.AppendLine(string.Format(Locale.Command_update_en_Success, downloadFileName)); + var f = files[0]; + using var sr = new MemoryStream(f.ToUTF8Bytes()).CreateStreamReader(Encoding.UTF8); + using var sw = File.Open( + Path.Combine(r.WorkingDirectory, + $"projects/assets/{originalID}/{versionString}/{modID}/lang/{versionFile}"), + FileMode.Create).CreateStreamWriter(new UTF8Encoding(false)); + + switch (version) + { + case MCVersion.v1122: + new LangFormatter(sr, sw).Format(); + break; + default: + new JsonFormatter(sr, sw).Format(); + break; + } + + r.AddAllFiles(); + r.Commit($"Update en_us file for {(originalID.Replace("\"", "\\\""))}", user); + } + else if (curseForgeID.StartsWith("modrinth-")) { curseForgeID = curseForgeID["modrinth-".Length..]; var addon = await ModrinthManager.GetMod(curseForgeID); @@ -190,7 +225,10 @@ public static async Task RunInternal(int prid, string content, int commentID, Gi } else { - var addon = await CurseManager.GetAddon(curseForgeID); + var cfIDForApi = curseForgeID; + if (curseForgeID.StartsWith("texture-packs-")) + cfIDForApi = curseForgeID["texture-packs-".Length..]; + var addon = await CurseManager.GetAddon(cfIDForApi); var modID = await CurseManager.GetModID(addon, version, true, false); var (files, downloadFileName) = await CurseManager.GetModEnFile(addon, version, LangType.EN); @@ -221,7 +259,7 @@ public static async Task RunInternal(int prid, string content, int commentID, Gi r.AddAllFiles(); r.Commit($"Update en_us file for {(curseForgeID.Replace("\"", "\\\""))}", user); } - + } if (line.StartsWith("/add-co-author ")) @@ -452,6 +490,8 @@ void Format(LangFileType? type = null) // continue; // } var slug = args[0]; + if (slug.StartsWith("texture-packs-")) + slug = slug["texture-packs-".Length..]; var curseForgeProjectID = args[1]; var curseForgeProjectIDInt = curseForgeProjectID.ToInt(); ModIDMappingMetadata.Instance.Mapping[slug] = curseForgeProjectIDInt; diff --git a/CFPABot/Controllers/CompareController.cs b/CFPABot/Controllers/CompareController.cs index 57e6a3f..9e690d4 100644 --- a/CFPABot/Controllers/CompareController.cs +++ b/CFPABot/Controllers/CompareController.cs @@ -167,7 +167,8 @@ async Task R(string l) CurseForge.APIClient.Models.Mods.Mod addon = null; try { - addon = await CurseManager.GetAddon(modid); + var cfSlug = modid.StartsWith("texture-packs-") ? modid["texture-packs-".Length..] : modid; + addon = await CurseManager.GetAddon(cfSlug); } catch (Exception e) { diff --git a/CFPABot/Controllers/UtilsController.cs b/CFPABot/Controllers/UtilsController.cs index bea9321..9d8b626 100644 --- a/CFPABot/Controllers/UtilsController.cs +++ b/CFPABot/Controllers/UtilsController.cs @@ -44,13 +44,15 @@ public IActionResult GitHubToken() [HttpGet("ModID")] public async Task ModID([FromQuery]string slug, [FromQuery] string versionString) { + if (slug.StartsWith("texture-packs-")) + slug = slug["texture-packs-".Length..]; return await CurseManager.GetModID(await CurseManager.GetAddon(slug), versionString.ToMCVersion(), true, false); } [HttpGet("GetAllModFilesInRepo")] public async Task GetAllModFilesInRepo() { - var mods = ModList.ModListConfig.Instance.ModLists.Select(x => new {slug=x.modSlug, cfid= ModIDMappingMetadata.Instance.Mapping.GetValueOrDefault(x.modSlug), versions = x.versions.Select(y => y.version.ToVersionDirectory()) }) + var mods = ModList.ModListConfig.Instance.ModLists.Select(x => new {slug=x.modSlug, cfid= ModIDMappingMetadata.Instance.Mapping.GetValueOrDefault(x.modSlug.StartsWith("texture-packs-") ? x.modSlug["texture-packs-".Length..] : x.modSlug), versions = x.versions.Select(y => y.version.ToVersionDirectory()) }) .Where(x => x.cfid != 0); return new JsonResult(mods); @@ -93,12 +95,24 @@ public async Task GetModName(string slug) { try { - if (slug.StartsWith("modrinth-")) + if (slug.StartsWith("modrinth-datapack-")) + { + slug = slug["modrinth-datapack-".Length..]; + var mod = await ModrinthManager.GetMod(slug); + return Content(mod.Title); + } + else if (slug.StartsWith("modrinth-")) { slug = slug["modrinth-".Length..]; var mod = await ModrinthManager.GetMod(slug); return Content(mod.Title); } + else if (slug.StartsWith("texture-packs-")) + { + slug = slug["texture-packs-".Length..]; + var mod = await CurseManager.GetAddon(slug); + return Content(mod.Name); + } else { var mod = await CurseManager.GetAddon(slug); diff --git a/CFPABot/Utils/CommentBuilder.cs b/CFPABot/Utils/CommentBuilder.cs index f715dc8..57f064c 100644 --- a/CFPABot/Utils/CommentBuilder.cs +++ b/CFPABot/Utils/CommentBuilder.cs @@ -257,7 +257,7 @@ public async Task UpdateModLinkSegment(FileDiff[] diffs) var addons = new List(); var tasks = new List(); - foreach (var modid in modids.Where(x => x != "1UNKNOWN" && x != "0-modrinth-mod" && !x.StartsWith("modrinth-"))) + foreach (var modid in modids.Where(x => x != "1UNKNOWN" && x != "0-modrinth-mod" && !x.StartsWith("modrinth-") && !x.StartsWith("texture-packs-") && !x.StartsWith("modrinth-datapack-"))) { tasks.Add(Task.Run(async () => { @@ -280,7 +280,7 @@ public async Task UpdateModLinkSegment(FileDiff[] diffs) var client = new ModrinthClient(); - var modrinthMods = modInfos.Where(x => x.CurseForgeID.StartsWith("modrinth-")).Select(m => m.CurseForgeID.Substring("modrinth-".Length)).Distinct().ToArray(); + var modrinthMods = modInfos.Where(x => x.CurseForgeID.StartsWith("modrinth-") && !x.CurseForgeID.StartsWith("modrinth-datapack-")).Select(m => m.CurseForgeID.Substring("modrinth-".Length)).Distinct().ToArray(); var sbModrinthError = new StringBuilder(); var modrinthList = new List<(string slug, string url, string iconUrl, string name)>(); @@ -346,7 +346,41 @@ public async Task UpdateModLinkSegment(FileDiff[] diffs) sb.AppendLine(); } - if (addons.Count == 0 && modrinthList.Count == 0) + // texture-packs (CurseForge 材质包) + var texturePackSlugs = modInfos.Where(x => x.CurseForgeID.StartsWith("texture-packs-")) + .Select(m => m.CurseForgeID.Substring("texture-packs-".Length)).Distinct().ToArray(); + var texturePackList = new List<(string prefixedSlug, Mod addon)>(); + foreach (var realSlug in texturePackSlugs) + { + try + { + var addon = await CurseManager.GetAddon(realSlug); + texturePackList.Add(($"texture-packs-{realSlug}", addon)); + } + catch (CheckException e) + { + lock (sb) { sb.AppendLine(e.Message); } + } + } + + // modrinth-datapack (Modrinth 数据包) + var datapackMods = modInfos.Where(x => x.CurseForgeID.StartsWith("modrinth-datapack-")) + .Select(m => m.CurseForgeID.Substring("modrinth-datapack-".Length)).Distinct().ToArray(); + var datapackList = new List<(string prefixedSlug, string url, string iconUrl, string name)>(); + foreach (var realSlug in datapackMods) + { + try + { + var project = await client.Project.GetAsync(realSlug); + datapackList.Add(($"modrinth-datapack-{realSlug}", project.Url, project.IconUrl, project.Title)); + } + catch (ModrinthApiException e) + { + sb.AppendLine($"Modrinth Datapack 检索遇到问题:{e.Message}"); + } + } + + if (addons.Count == 0 && modrinthList.Count == 0 && texturePackList.Count == 0 && datapackList.Count == 0) { sb.AppendLine("ℹ 此 PR 没有检测到 CurseForge/Modrinth 模组修改。"); return; @@ -372,6 +406,35 @@ public async Task UpdateModLinkSegment(FileDiff[] diffs) modCount++; } + foreach (var (prefixedSlug, url, iconUrl, name) in datapackList) + { + sb1.AppendLine($"| " + + /* Thumbnail*/ $" |" + + /* Mod Name */ $" [**{name.Trim().Replace("[", "\\[").Replace("]", "\\]").Replace("|", "\\|")}**]({url}) |" + + /* Source */ $" " + + /* Mcmod */ $" [🟩 MCMOD](https://cn.bing.com/search?q=site:mcmod.cn%20{HttpUtility.UrlEncode(name)}) \\|" + + /* Compare */ $" [:file_folder: 对比(Azusa)](https://cfpa.cyan.cafe/Azusa/Diff/{PullRequestID}/{prefixedSlug}) |" + + /* Mod DL */ $" Modrinth Datapack |" + + "" + ); + modCount++; + } + + foreach (var (prefixedSlug, addon) in texturePackList) + { + Interlocked.Increment(ref modCount); + var infos = modInfos.Where(i => i.CurseForgeID == prefixedSlug).ToArray(); + var versions = infos.Select(i => i.Version).ToArray(); + sb1.AppendLine($"| " + + /* Thumbnail*/ $"{await CurseManager.GetThumbnailText(addon).ConfigureAwait(false)} |" + + /* Mod Name */ $" [**{addon.Name.Trim().Replace("[", "\\[").Replace("]", "\\]").Replace("|", "\\|")}**]({addon.Links.WebsiteUrl}) |" + + /* Source */ $" {CurseManager.GetRepoText(addon)} \\|" + + /* Mcmod */ $" [🟩 MCMOD](https://cn.bing.com/search?q=site:mcmod.cn%20{HttpUtility.UrlEncode(addon.Name)}) \\|" + + /* Compare */ $" [:file_folder: 对比(Azusa)](https://cfpa.cyan.cafe/Azusa/Diff/{PullRequestID}/{prefixedSlug}) |" + + /* Mod DL */ $" {await CurseManager.GetModRepoLinkText(addon, infos).ConfigureAwait(false)} |" + + ""); + } + foreach (var addon in addons.AsParallel().AsSequential().Select(async d1 => { Interlocked.Increment(ref modCount); @@ -934,7 +997,17 @@ public async Task UpdateCheckSegment(FileDiff[] diffs) try { var slug = names[2]; - if (slug.StartsWith("modrinth-")) + if (slug.StartsWith("modrinth-datapack-")) + { + var realSlug = slug["modrinth-datapack-".Length..]; + var addon = await ModrinthManager.GetMod(realSlug); + var modDomain = + await ModrinthManager.GetModID(addon, names[3].ToMCStandardVersion(), new[] { "datapack" }, true, false); + var rdir = $"projects/assets/{slug}/{names[3]}/{modDomain}/lang/"; + sb.AppendLine($" 自动找到该模组 Domain 为 `{modDomain}`,可能正确文件夹为 `{rdir}`。使用命令 `/mv \"{names.Take(4).Connect("/")}/\" \"{rdir}\"` 来移动路径。"); + sb.AppendLine(); + } + else if (slug.StartsWith("modrinth-")) { slug = slug["modrinth-".Length..]; var addon = await ModrinthManager.GetMod(slug); @@ -944,13 +1017,23 @@ public async Task UpdateCheckSegment(FileDiff[] diffs) sb.AppendLine($" 自动找到该模组 Domain 为 `{modDomain}`,可能正确文件夹为 `{rdir}`。使用命令 `/mv \"{names.Take(4).Connect("/")}/\" \"{rdir}\"` 来移动路径。"); sb.AppendLine(); } + else if (slug.StartsWith("texture-packs-")) + { + var realSlug = slug["texture-packs-".Length..]; + var addon = await CurseManager.GetAddon(realSlug); + var modDomain = + await CurseManager.GetModID(addon, names[3].ToMCStandardVersion(), true, false); + var rdir = $"projects/assets/{slug}/{names[3]}/{modDomain}/lang/"; + sb.AppendLine($" 自动找到该模组 Domain 为 `{modDomain}`,可能正确文件夹为 `{rdir}`。使用命令 `/mv \"{names.Take(4).Connect("/")}/\" \"{rdir}\"` 来移动路径。"); + sb.AppendLine(); + } else { var addon = await CurseManager.GetAddon(names[2]); var modDomain = await CurseManager.GetModID(addon, names[3].ToMCStandardVersion(), true, false); var rdir = $"projects/assets/{names[2]}/{names[3]}/{modDomain}/lang/"; - sb.AppendLine($" 自动找到该模组 Domain 为 `{modDomain}`,可能正确文件夹为 `{rdir}`。使用命令 `/mv \"{names.Take(4).Connect("/")}/\" \"{rdir}\"` 来移动路径。"); + sb.AppendLine($" 自动找到该模组 Mod Domain 为 `{modDomain}`,可能正确文件夹为 `{rdir}`。使用命令 `/mv \"{names.Take(4).Connect("/")}/\" \"{rdir}\"` 来移动路径。"); sb.AppendLine(); } @@ -974,12 +1057,42 @@ public async Task UpdateCheckSegment(FileDiff[] diffs) sb.AppendLine($"⚠ 检测到一个语言文件,但提交路径不正常。缺少了 {{ModDomain}} 或 {{CurseForge 项目名}} 文件夹。请检查提交路径:`{diff.To}`;"); try { - var addon = await CurseManager.GetAddon(names[2]); - var modDomain = - await CurseManager.GetModID(addon, names[3].ToMCStandardVersion(), true, false); - var rdir = $"projects/assets/{names[2]}/{names[3]}/{modDomain}/lang/"; - sb.AppendLine($" 自动找到了该模组的 Mod Domain 为 `{modDomain}`,可能的正确文件夹为 `{rdir}`。 你可以使用命令 `/mv \"{names.Take(5).Connect("/")}/\" \"{rdir}\"` 来移动路径。"); - sb.AppendLine(); + var slug = names[2]; + if (slug.StartsWith("modrinth-datapack-")) + { + var realSlug = slug["modrinth-datapack-".Length..]; + var addon = await ModrinthManager.GetMod(realSlug); + var modDomain = await ModrinthManager.GetModID(addon, names[3].ToMCStandardVersion(), new[] { "datapack" }, true, false); + var rdir = $"projects/assets/{slug}/{names[3]}/{modDomain}/lang/"; + sb.AppendLine($" 自动找到了该模组的 Mod Domain 为 `{modDomain}`,可能的正确文件夹为 `{rdir}`。 你可以使用命令 `/mv \"{names.Take(5).Connect("/")}/\" \"{rdir}\"` 来移动路径。"); + sb.AppendLine(); + } + else if (slug.StartsWith("modrinth-")) + { + var realSlug = slug["modrinth-".Length..]; + var addon = await ModrinthManager.GetMod(realSlug); + var modDomain = await ModrinthManager.GetModID(addon, names[3].ToMCStandardVersion(), true, false); + var rdir = $"projects/assets/{names[2]}/{names[3]}/{modDomain}/lang/"; + sb.AppendLine($" 自动找到了该模组的 Mod Domain 为 `{modDomain}`,可能的正确文件夹为 `{rdir}`。 你可以使用命令 `/mv \"{names.Take(5).Connect("/")}/\" \"{rdir}\"` 来移动路径。"); + sb.AppendLine(); + } + else if (slug.StartsWith("texture-packs-")) + { + var realSlug = slug["texture-packs-".Length..]; + var addon = await CurseManager.GetAddon(realSlug); + var modDomain = await CurseManager.GetModID(addon, names[3].ToMCStandardVersion(), true, false); + var rdir = $"projects/assets/{slug}/{names[3]}/{modDomain}/lang/"; + sb.AppendLine($" 自动找到了该模组的 Mod Domain 为 `{modDomain}`,可能的正确文件夹为 `{rdir}`。 你可以使用命令 `/mv \"{names.Take(5).Connect("/")}/\" \"{rdir}\"` 来移动路径。"); + sb.AppendLine(); + } + else + { + var addon = await CurseManager.GetAddon(names[2]); + var modDomain = await CurseManager.GetModID(addon, names[3].ToMCStandardVersion(), true, false); + var rdir = $"projects/assets/{names[2]}/{names[3]}/{modDomain}/lang/"; + sb.AppendLine($" 自动找到了该模组的 Mod Domain 为 `{modDomain}`,可能的正确文件夹为 `{rdir}`。 你可以使用命令 `/mv \"{names.Take(5).Connect("/")}/\" \"{rdir}\"` 来移动路径。"); + sb.AppendLine(); + } } catch (Exception) { @@ -1062,7 +1175,11 @@ public async Task UpdateCheckSegment(FileDiff[] diffs) try { - if (curseID != "1UNKNOWN" && curseID != "0-modrinth-mod" && !curseID.StartsWith("modrinth-")) + if (curseID.StartsWith("texture-packs-")) + { + addon = await CurseManager.GetAddon(curseID["texture-packs-".Length..]); + } + else if (curseID != "1UNKNOWN" && curseID != "0-modrinth-mod" && !curseID.StartsWith("modrinth-")) addon = await CurseManager.GetAddon(curseID); } catch (Exception) @@ -1101,7 +1218,12 @@ public async Task UpdateCheckSegment(FileDiff[] diffs) try { - if (curseID != "1UNKNOWN" && curseID != "0-modrinth-mod" && !curseID.StartsWith("modrinth-")) + if (curseID.StartsWith("texture-packs-")) + { + var realSlug = curseID["texture-packs-".Length..]; + addon = await CurseManager.GetAddon(realSlug); + } + else if (curseID != "1UNKNOWN" && curseID != "0-modrinth-mod" && !curseID.StartsWith("modrinth-")) addon = await CurseManager.GetAddon(curseID); } catch (Exception) @@ -1109,11 +1231,13 @@ public async Task UpdateCheckSegment(FileDiff[] diffs) sb.AppendLine(string.Format(Locale.Check_ModID_ModNotFound, curseID, versionString)); } - if (addon != null && addon.Slug != curseID) + var curseIDForApi = curseID.StartsWith("texture-packs-") ? curseID["texture-packs-".Length..] : curseID; + if (addon != null && addon.Slug != curseIDForApi) { + var slugPrefix = curseID.StartsWith("texture-packs-") ? "texture-packs-" : ""; sb.AppendLine("❌ 检测到此模组作者更改了 Slug 名,请使用以下命令进行路径移动:"); sb.AppendLine("```"); - sb.AppendLine($"/mv projects/assets/{curseID}/{versionString}/ projects/assets/{addon.Slug}/{versionString}/"); + sb.AppendLine($"/mv projects/assets/{curseID}/{versionString}/ projects/assets/{slugPrefix}{addon.Slug}/{versionString}/"); sb.AppendLine($"/add-mapping {addon.Slug} {addon.Id}"); sb.AppendLine("```"); sb.AppendLine(); @@ -1158,7 +1282,9 @@ public async Task UpdateCheckSegment(FileDiff[] diffs) Project z = null; try { - if (curseID.StartsWith("modrinth-")) + if (curseID.StartsWith("modrinth-datapack-")) + z = await ModrinthManager.GetMod(curseID["modrinth-datapack-".Length..]); + else if (curseID.StartsWith("modrinth-")) z = await ModrinthManager.GetMod(curseID["modrinth-".Length..]); } catch (Exception) @@ -1168,7 +1294,9 @@ public async Task UpdateCheckSegment(FileDiff[] diffs) if (z != null) try { - var filemodid = await ModrinthManager.GetModIDForCheck(z, mcVersion); + var filemodid = curseID.StartsWith("modrinth-datapack-") + ? await ModrinthManager.GetModIDForCheck(z, mcVersion, new[] { "datapack" }) + : await ModrinthManager.GetModIDForCheck(z, mcVersion); if (filemodid == null || filemodid.Length == 0) { sb.AppendLine(string.Format(Locale.Check_ModID_ModIDNotFound, "modrinth~" + modid)); diff --git a/CFPABot/Utils/CurseManager.cs b/CFPABot/Utils/CurseManager.cs index 06f1e56..f98f076 100644 --- a/CFPABot/Utils/CurseManager.cs +++ b/CFPABot/Utils/CurseManager.cs @@ -527,7 +527,7 @@ public class ModIDMappingMetadata : Configuration { public Dictionary Mapping { get; set; } = new(); public DateTime LastUpdate { get; set; } - [JsonIgnore] public int LastID => Mapping.Values.Max(); + [JsonIgnore] public int LastID => Mapping.Values.DefaultIfEmpty(0).Max(); } static class CurseForgeClientExtensions @@ -550,26 +550,32 @@ public static async Task Update() static void AddMapping(List addons) { - foreach (var addon in addons.Where(s => s.GameId == 432 && s.Links.WebsiteUrl.StartsWith("https://www.curseforge.com/minecraft/mc-mods/"))) + foreach (var addon in addons.Where(s => s.GameId == 432 && (s.Links.WebsiteUrl.StartsWith("https://www.curseforge.com/minecraft/mc-mods/") || s.Links.WebsiteUrl.StartsWith("https://www.curseforge.com/minecraft/texture-packs/")))) lock (ModIDMappingMetadata.Instance) { ModIDMappingMetadata.Instance.Mapping[addon.Slug] = (int)addon.Id; } } - // public static async Task Build() - // { - // var client = new ForgeClient(); - // var config = ModIDMappingMetadata.Instance; - // for (int i = 0; i < 40; i++) - // { - // var addons = await client.Addons.RetriveAddons(Enumerable.Range(i * 20000 + 1, 20000).ToArray()); - // AddMapping(addons); - // Console.WriteLine($"初始化 Mapping: {i + 1}/40"); - // } - // config.LastUpdate = DateTime.Now; - // ModIDMappingMetadata.Save(); - // } - // + public static async Task Build() + { + var config = ModIDMappingMetadata.Instance; + for (int i = 0; i < 40; i++) + { + try + { + var ids = Enumerable.Range(i * 20000 + 1, 20000).Select(x => x).ToList(); + var addons = await CurseManager.GetCfClient().GetModsByIdListAsync(new GetModsByIdsListRequestBody() { ModIds = ids }); + AddMapping(addons.Data); + } + catch (Exception e) + { + Log.Error(e, $"Build mapping batch {i + 1}/40 failed"); + } + } + config.LastUpdate = DateTime.Now; + ModIDMappingMetadata.Save(); + } + // static SemaphoreSlim semaphore = new SemaphoreSlim(1); // public static async Task UpdateIfRequired() // { diff --git a/CFPABot/Utils/ModrinthManager.cs b/CFPABot/Utils/ModrinthManager.cs index 1eeda85..38f8a55 100644 --- a/CFPABot/Utils/ModrinthManager.cs +++ b/CFPABot/Utils/ModrinthManager.cs @@ -21,13 +21,20 @@ public static Task GetMod(string slug) return Instance.Project.GetAsync(slug); } - public static async Task GetModID(Project addon, MCVersion? version, bool enforcedLang = false, + static string[] DefaultLoaders(MCVersion? version) => + version?.ToString().Contains("fabric") == true ? new[] { "fabric" } : new[] { "forge" }; + + public static Task GetModID(Project addon, MCVersion? version, bool enforcedLang = false, + bool connect = true) + => GetModID(addon, version, DefaultLoaders(version), enforcedLang, connect); + + public static async Task GetModID(Project addon, MCVersion? version, string[] loaders, bool enforcedLang = false, bool connect = true) { if (version == null) return "未知"; try { - var versions = await Instance.Version.GetProjectVersionListAsync(addon.Slug, new []{ version.ToString().Contains("fabric") ? "fabric": "forge"}); + var versions = await Instance.Version.GetProjectVersionListAsync(addon.Slug, loaders); if (versions.FirstOrDefault(f => f.GameVersions.Any(x=> x.StartsWith(version.Value.ToStandardVersionString()))) is { } file) { var fileName = await Download.DownloadFile(file.Files.First().Url); // 我好累 @@ -51,12 +58,15 @@ public static async Task GetModID(Project addon, MCVersion? version, boo return "未知"; } - public static async Task GetModIDForCheck(Project addon, MCVersion? version) + public static Task GetModIDForCheck(Project addon, MCVersion? version) + => GetModIDForCheck(addon, version, DefaultLoaders(version)); + + public static async Task GetModIDForCheck(Project addon, MCVersion? version, string[] loaders) { if (version == null) return null; try { - var versions = await Instance.Version.GetProjectVersionListAsync(addon.Slug, new []{ version.ToString().Contains("fabric") ? "fabric": "forge"}); + var versions = await Instance.Version.GetProjectVersionListAsync(addon.Slug, loaders); if (versions.Where(x => x.GameVersions.Any(y => y.StartsWith(version.Value.ToStandardVersionString()))).FirstOrDefault() is {} file) { var fileName = await Download.DownloadFile(file.Files.Any(x => x.FileName.ToLower().Contains("fabric") && version.ToString().Contains("fabric"))?file.Files.First(x => x.FileName.ToLower().Contains("fabric")).Url: file.Files.First().Url); @@ -79,12 +89,15 @@ public static async Task GetModIDForCheck(Project addon, MCVersion? ve return null; } - public static async Task<(string[] files, string downloadFileName)> GetModEnFile(Project addon, MCVersion? version, LangType type) + public static Task<(string[] files, string downloadFileName)> GetModEnFile(Project addon, MCVersion? version, LangType type) + => GetModEnFile(addon, version, DefaultLoaders(version), type); + + public static async Task<(string[] files, string downloadFileName)> GetModEnFile(Project addon, MCVersion? version, string[] loaders, LangType type) { if (version == null) return (null, null); try { - var versions = await Instance.Version.GetProjectVersionListAsync(addon.Slug, new[] { version.ToString().Contains("fabric") ? "fabric" : "forge" }); + var versions = await Instance.Version.GetProjectVersionListAsync(addon.Slug, loaders); if (versions.Where(x => x.GameVersions.Any(y => y.StartsWith(version.Value.ToStandardVersionString()))).FirstOrDefault() is { } file) { var d = file.Files.Any(x => x.FileName.ToLower().Contains("fabric") && version.ToString().Contains("fabric")) ? file.Files.First(x => x.FileName.ToLower().Contains("fabric")) : file.Files.First();