Parse version manifest and download forge libraries.

TODO:
Integrate base url propagation.
Integrate PackXZExtract to calculate hashes  of jar.pack.xz files.
OR ammend the distribution spec to accept different hash algos (requires helioslauncher update).
This commit is contained in:
Daniel Scalzi
2020-01-12 03:42:34 -05:00
parent 419a4d5e91
commit 0674bd5808
7 changed files with 149 additions and 24 deletions

View File

@@ -1,5 +1,12 @@
import AdmZip from 'adm-zip'
import { createHash } from 'crypto'
import { lstat, readFile, Stats } from 'fs-extra'
import { VersionManifest } from '../../../model/forge/versionmanifest'
import { Artifact } from '../../../model/spec/artifact'
import { Module } from '../../../model/spec/module'
import { Type } from '../../../model/spec/type'
import { ForgeRepoStructure } from '../../../model/struct/repo/forgerepo.struct'
import { MavenUtil } from '../../../util/maven'
import { ForgeResolver } from '../forge.resolver'
export class Forge18Adapter extends ForgeResolver {
@@ -18,8 +25,7 @@ export class Forge18Adapter extends ForgeResolver {
}
public async getModule(): Promise<Module> {
await this.getForgeByVersion()
return null as unknown as Module
return this.getForgeByVersion()
}
public isForVersion(version: string) {
@@ -33,7 +39,7 @@ export class Forge18Adapter extends ForgeResolver {
console.debug(`Checking for forge version at ${targetLocalPath}..`)
if (!await forgeRepo.artifactExists(targetLocalPath)) {
console.debug(`Forge not found locally, initializing download..`)
await forgeRepo.downloadArtifact(
await forgeRepo.downloadArtifactByComponents(
this.REMOTE_REPOSITORY,
ForgeRepoStructure.FORGE_GROUP,
ForgeRepoStructure.FORGE_ARTIFACT,
@@ -42,11 +48,81 @@ export class Forge18Adapter extends ForgeResolver {
console.debug('Using locally discovered forge.')
}
console.debug(`Beginning processing of Forge v${this.forgeVersion} (Minecraft ${this.minecraftVersion})`)
const forgeUniversalBuffer = await readFile(targetLocalPath)
const zip = new AdmZip(forgeUniversalBuffer)
const zipEntries = zip.getEntries()
let versionManifest
for (const entry of zipEntries) {
if (entry.entryName === 'version.json') {
versionManifest = zip.readAsText(entry)
break
}
}
if (!versionManifest) {
throw new Error('Failed to find version.json in forge universal jar.')
}
versionManifest = JSON.parse(versionManifest) as VersionManifest
const forgeModule: Module = {
id: MavenUtil.mavenComponentsToIdentifier(
ForgeRepoStructure.FORGE_GROUP,
ForgeRepoStructure.FORGE_ARTIFACT,
artifactVersion, 'universal'
),
name: 'Minecraft Forge',
type: Type.ForgeHosted,
artifact: this.generateArtifact(forgeUniversalBuffer, await lstat(targetLocalPath)),
subModules: []
}
for (const lib of versionManifest.libraries) {
if (lib.name.startsWith('net.minecraftforge:forge:')) {
// We've already processed forge.
continue
}
console.debug(`Processing ${lib.name}..`)
const libRepo = this.repoStructure.getLibRepoStruct()
const extension = this.determineExtension(lib.checksums)
const localPath = libRepo.getArtifactById(lib.name, extension) as string
if (!await libRepo.artifactExists(localPath)) {
console.debug(`Not found locally, downloading..`)
await libRepo.downloadArtifactById(lib.url || 'https://libraries.minecraft.net/', lib.name, extension)
} else {
console.debug('Using local copy.')
}
const libBuf = await readFile(localPath)
const stats = await lstat(localPath)
forgeModule.subModules?.push({
id: lib.name,
name: `Minecraft Forge (${MavenUtil.getMavenComponents(lib.name)?.artifact})`,
type: Type.Library,
artifact: this.generateArtifact(libBuf, stats)
})
}
return forgeModule
}
// TODO
// extract manifest
// parse manifest
// return module
private generateArtifact(buf: Buffer, stats: Stats): Artifact {
return {
size: stats.size,
MD5: createHash('md5').update(buf).digest('hex'),
url: 'TODO'
}
}
private determineExtension(checksums: string[] | undefined) {
return checksums != null && checksums.length > 1 ? 'jar.pack.xz' : 'jar'
}
}