Skip to content

Commit

Permalink
fix: Cover some cases resource packs are added to mods
Browse files Browse the repository at this point in the history
  • Loading branch information
ci010 committed Jan 1, 2024
1 parent 16c94ff commit 1564c92
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 7 deletions.
24 changes: 23 additions & 1 deletion xmcl-runtime/modpack/getCurseforgeFiles.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
import { File, CurseforgeApiError, CurseforgeV1Client } from '@xmcl/curseforge'
import { File, CurseforgeApiError, CurseforgeV1Client, Mod } from '@xmcl/curseforge'

export async function getCurseforgeProjects(client: CurseforgeV1Client, ids: number[]): Promise<Mod[]> {
try {
const mods = await client.getMods(ids)
return mods
} catch (e) {
if (e instanceof CurseforgeApiError && e.status === 400) {
if (ids.length === 1) {
// TODO: handle this
return []
}
// divide into two parts
const mid = Math.floor(ids.length / 2)
const [left, right] = await Promise.all([
getCurseforgeProjects(client, ids.slice(0, mid)),
getCurseforgeProjects(client, ids.slice(mid)),
])
return [...left, ...right]
}
throw e
}
}

export async function getCurseforgeFiles(client: CurseforgeV1Client, ids: number[]): Promise<File[]> {
try {
Expand Down
25 changes: 22 additions & 3 deletions xmcl-runtime/modpack/pluginCurseforgeModpackHandler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { File, HashAlgo } from '@xmcl/curseforge'
import { File, HashAlgo, Mod } from '@xmcl/curseforge'
import { CurseforgeModpackManifest, InstanceFile, ResourceDomain, getInstanceConfigFromCurseforgeModpack } from '@xmcl/runtime-api'
import { readEntry } from '@xmcl/unzip'
import { join } from 'path'
Expand All @@ -7,7 +7,7 @@ import { LauncherAppPlugin } from '~/app'
import { CurseForgeService } from '~/curseforge'
import { ModpackService } from './ModpackService'
import { guessCurseforgeFileUrl } from '../util/curseforge'
import { getCurseforgeFiles } from './getCurseforgeFiles'
import { getCurseforgeFiles, getCurseforgeProjects } from './getCurseforgeFiles'

export const pluginCurseforgeModpackHandler: LauncherAppPlugin = async (app) => {
const modpackService = await app.registry.get(ModpackService)
Expand Down Expand Up @@ -36,6 +36,7 @@ export const pluginCurseforgeModpackHandler: LauncherAppPlugin = async (app) =>

const curseforgeService = await app.registry.getOrCreate(CurseForgeService)
const files = await getCurseforgeFiles(curseforgeService.client, ids)
const mods = await getCurseforgeProjects(curseforgeService.client, files.map(f => f.modId))
const infos: InstanceFile[] = []

const dict: Record<string, File> = {}
Expand All @@ -45,15 +46,33 @@ export const pluginCurseforgeModpackHandler: LauncherAppPlugin = async (app) =>
}
dict[file.id] = file
}
const modDict: Record<string, Mod> = {}
for (const mod of mods) {
if (modDict[mod.id]) {
modpackService.warn(`Duplicated curseforge mod return from curseforge API: ${mod.id}`)
}
modDict[mod.id] = mod
}

for (let i = 0; i < manifest.files.length; i++) {
const manifestFile = manifest.files[i]
const file = dict[manifestFile.fileID]
const mod = modDict[file.modId]
if (!file) {
modpackService.warn(`Skip file ${manifestFile.fileID} because it is not found in curseforge API`)
continue
}
const domain = file.fileName.endsWith('.jar') ? ResourceDomain.Mods : file.modules.some(f => f.name === 'META-INF') ? ResourceDomain.Mods : ResourceDomain.ResourcePacks
let domain: ResourceDomain | undefined
if (mod) {
domain = mod.primaryCategoryId === 12
? ResourceDomain.ResourcePacks
: mod.primaryCategoryId === 6
? ResourceDomain.Mods
: undefined
}
if (!domain) {
domain = file.fileName.endsWith('.jar') ? ResourceDomain.Mods : file.modules.some(f => f.name === 'META-INF') ? ResourceDomain.Mods : ResourceDomain.ResourcePacks
}
const sha1 = file.hashes.find(v => v.algo === HashAlgo.Sha1)?.value
infos.push({
downloads: file.downloadUrl ? [file.downloadUrl] : guessCurseforgeFileUrl(file.id, file.fileName),
Expand Down
25 changes: 22 additions & 3 deletions xmcl-runtime/modpack/pluginMcbbsModpackHandler.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { File, HashAlgo } from '@xmcl/curseforge'
import { File, HashAlgo, Mod } from '@xmcl/curseforge'
import { InstanceFile, McbbsModpackManifest, ModpackFileInfoCurseforge, ResourceDomain, getInstanceConfigFromMcbbsModpack } from '@xmcl/runtime-api'
import { readEntry } from '@xmcl/unzip'
import { join } from 'path'
Expand All @@ -7,7 +7,7 @@ import { LauncherAppPlugin } from '~/app'
import { CurseForgeService } from '~/curseforge'
import { ModpackService } from './ModpackService'
import { guessCurseforgeFileUrl } from '../util/curseforge'
import { getCurseforgeFiles } from './getCurseforgeFiles'
import { getCurseforgeFiles, getCurseforgeProjects } from './getCurseforgeFiles'

export const pluginMcbbsModpackHandler: LauncherAppPlugin = async (app) => {
const modpackService = await app.registry.get(ModpackService)
Expand All @@ -27,6 +27,7 @@ export const pluginMcbbsModpackHandler: LauncherAppPlugin = async (app) => {
const ids = curseforgeFiles.map(f => f.fileID).filter(id => typeof id === 'number')
const curseforgeService = await app.registry.getOrCreate(CurseForgeService)
const files = await getCurseforgeFiles(curseforgeService.client, ids)
const mods = await getCurseforgeProjects(curseforgeService.client, files.map(f => f.modId))

const dict: Record<string, File> = {}
for (const file of files) {
Expand All @@ -35,6 +36,13 @@ export const pluginMcbbsModpackHandler: LauncherAppPlugin = async (app) => {
}
dict[file.id] = file
}
const modDict: Record<string, Mod> = {}
for (const mod of mods) {
if (modDict[mod.id]) {
modpackService.warn(`Duplicated curseforge mod return from curseforge API: ${mod.id}`)
}
modDict[mod.id] = mod
}

for (let i = 0; i < files.length; i++) {
const manifestFile = manifest.files[i]
Expand All @@ -46,7 +54,18 @@ export const pluginMcbbsModpackHandler: LauncherAppPlugin = async (app) => {
modpackService.warn(`Skip file ${manifestFile.fileID} because it is not found in curseforge API`)
continue
}
const domain = file.fileName.endsWith('.jar') ? ResourceDomain.Mods : file.modules.some(f => f.name === 'META-INF') ? ResourceDomain.Mods : ResourceDomain.ResourcePacks
let domain: ResourceDomain | undefined
const mod = modDict[file.modId]
if (mod) {
domain = mod.primaryCategoryId === 12
? ResourceDomain.ResourcePacks
: mod.primaryCategoryId === 6
? ResourceDomain.Mods
: undefined
}
if (!domain) {
domain = file.fileName.endsWith('.jar') ? ResourceDomain.Mods : file.modules.some(f => f.name === 'META-INF') ? ResourceDomain.Mods : ResourceDomain.ResourcePacks
}
const sha1 = file.hashes.find(v => v.algo === HashAlgo.Sha1)?.value
infos.push({
downloads: file.downloadUrl ? [file.downloadUrl] : guessCurseforgeFileUrl(file.id, file.fileName),
Expand Down

0 comments on commit 1564c92

Please sign in to comment.