Initial work on 1.13 forge resolver, fixes.
Moved java executable to its own util class. Fixed artifact resolution links for older versions of forge. 1.13 support is going to be difficult because forge does not make anything developer friendly.
This commit is contained in:
5
.vscode/launch.json
vendored
5
.vscode/launch.json
vendored
@@ -10,9 +10,8 @@
|
|||||||
"name": "Launch Program",
|
"name": "Launch Program",
|
||||||
"program": "${workspaceFolder}\\src\\index.ts",
|
"program": "${workspaceFolder}\\src\\index.ts",
|
||||||
"args": [
|
"args": [
|
||||||
"test",
|
"g",
|
||||||
"1.12.2",
|
"distro"
|
||||||
"14.23.5.2847"
|
|
||||||
],
|
],
|
||||||
"preLaunchTask": "compile",
|
"preLaunchTask": "compile",
|
||||||
"outFiles": [
|
"outFiles": [
|
||||||
|
|||||||
@@ -217,7 +217,8 @@ const testCommand: yargs.CommandModule = {
|
|||||||
handler: async (argv) => {
|
handler: async (argv) => {
|
||||||
console.debug(`Invoked test with mcVer ${argv.mcVer} forgeVer ${argv.forgeVer}`)
|
console.debug(`Invoked test with mcVer ${argv.mcVer} forgeVer ${argv.forgeVer}`)
|
||||||
console.log(process.cwd())
|
console.log(process.cwd())
|
||||||
const resolver = ResolverRegistry.getForgeResolver('1.12.2', '14.23.5.2847', getRoot(), '', getBaseURL())
|
const resolver = ResolverRegistry.getForgeResolver(argv.mcVer as string,
|
||||||
|
argv.forgeVer as string, getRoot(), '', getBaseURL())
|
||||||
if (resolver != null) {
|
if (resolver != null) {
|
||||||
const mdl = await resolver.getModule()
|
const mdl = await resolver.getModule()
|
||||||
console.log(inspect(mdl, false, null, true))
|
console.log(inspect(mdl, false, null, true))
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ export interface VersionManifest {
|
|||||||
url?: string,
|
url?: string,
|
||||||
checksums?: string[],
|
checksums?: string[],
|
||||||
serverreq?: boolean,
|
serverreq?: boolean,
|
||||||
clientreq?: boolean
|
clientreq?: boolean,
|
||||||
|
comment?: string
|
||||||
}>
|
}>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ export class ServerStructure extends BaseModelStructure<Server> {
|
|||||||
const forgeResolver = ResolverRegistry.getForgeResolver(
|
const forgeResolver = ResolverRegistry.getForgeResolver(
|
||||||
match[2],
|
match[2],
|
||||||
serverMeta.forgeVersion,
|
serverMeta.forgeVersion,
|
||||||
dirname(this.absoluteRoot),
|
dirname(this.containerDirectory),
|
||||||
'',
|
'',
|
||||||
this.baseUrl
|
this.baseUrl
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -43,4 +43,8 @@ export class RepoStructure extends BaseFileStructure {
|
|||||||
return join(this.absoluteRoot, 'temp')
|
return join(this.absoluteRoot, 'temp')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public getWorkDirectory() {
|
||||||
|
return join(this.absoluteRoot, 'work')
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,9 @@
|
|||||||
|
import { spawn } from 'child_process'
|
||||||
|
import { copy, mkdirs, pathExists, remove, writeFile } from 'fs-extra'
|
||||||
|
import { basename, join } from 'path'
|
||||||
import { Module } from '../../../model/spec/module'
|
import { Module } from '../../../model/spec/module'
|
||||||
|
import { ForgeRepoStructure } from '../../../model/struct/repo/forgerepo.struct'
|
||||||
|
import { JavaUtil } from '../../../util/javautil'
|
||||||
import { ForgeResolver } from '../forge.resolver'
|
import { ForgeResolver } from '../forge.resolver'
|
||||||
|
|
||||||
export class Forge113Adapter extends ForgeResolver {
|
export class Forge113Adapter extends ForgeResolver {
|
||||||
@@ -18,11 +23,62 @@ export class Forge113Adapter extends ForgeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async getModule(): Promise<Module> {
|
public async getModule(): Promise<Module> {
|
||||||
return null as unknown as Module
|
await this.process()
|
||||||
|
return {} as unknown as Module
|
||||||
}
|
}
|
||||||
|
|
||||||
public isForVersion(version: string): boolean {
|
public isForVersion(version: string): boolean {
|
||||||
return Forge113Adapter.isForVersion(version)
|
return Forge113Adapter.isForVersion(version)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async process() {
|
||||||
|
const forgeRepo = this.repoStructure.getForgeRepoStruct()
|
||||||
|
const installerPath = forgeRepo.getLocalForge(this.artifactVersion, 'installer')
|
||||||
|
console.debug(`Checking for forge installer at ${installerPath}..`)
|
||||||
|
if (!await forgeRepo.artifactExists(installerPath)) {
|
||||||
|
console.debug(`Forge installer not found locally, initializing download..`)
|
||||||
|
await forgeRepo.downloadArtifactByComponents(
|
||||||
|
this.REMOTE_REPOSITORY,
|
||||||
|
ForgeRepoStructure.FORGE_GROUP,
|
||||||
|
ForgeRepoStructure.FORGE_ARTIFACT,
|
||||||
|
this.artifactVersion, 'installer', 'jar'
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
console.debug('Using locally discovered forge installer.')
|
||||||
|
}
|
||||||
|
console.debug(`Beginning processing of Forge v${this.forgeVersion} (Minecraft ${this.minecraftVersion})`)
|
||||||
|
|
||||||
|
const workDir = this.repoStructure.getWorkDirectory()
|
||||||
|
if (await pathExists(workDir)) {
|
||||||
|
await remove(workDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
await mkdirs(workDir)
|
||||||
|
|
||||||
|
const workingInstaller = join(workDir, basename(installerPath))
|
||||||
|
|
||||||
|
await copy(installerPath, workingInstaller)
|
||||||
|
|
||||||
|
// Required for the installer to function.
|
||||||
|
await writeFile(join(workDir, 'launcher_profiles.json'), JSON.stringify({}))
|
||||||
|
|
||||||
|
console.debug(`Spawning forge installer`)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private executeInstaller(installerExec: string) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const child = spawn(JavaUtil.getJavaExecutable(), [
|
||||||
|
'-jar',
|
||||||
|
installerExec
|
||||||
|
])
|
||||||
|
child.stdout.on('data', (data) => console.log('[Forge Installer]', data.toString('utf8')))
|
||||||
|
child.stderr.on('data', (data) => console.error('[Forge Installer]', data.toString('utf8')))
|
||||||
|
child.on('close', (code, signal) => {
|
||||||
|
console.log('[Forge Installer]', 'Exited with code', code)
|
||||||
|
resolve()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { ForgeResolver } from '../forge.resolver'
|
|||||||
export class Forge18Adapter extends ForgeResolver {
|
export class Forge18Adapter extends ForgeResolver {
|
||||||
|
|
||||||
public static isForVersion(version: string) {
|
public static isForVersion(version: string) {
|
||||||
return Forge18Adapter.isVersionAcceptable(version, [8, 9, 10, 11, 12])
|
return Forge18Adapter.isVersionAcceptable(version, [7, 8, 9, 10, 11, 12])
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@@ -37,8 +37,7 @@ export class Forge18Adapter extends ForgeResolver {
|
|||||||
|
|
||||||
public async getForgeByVersion() {
|
public async getForgeByVersion() {
|
||||||
const forgeRepo = this.repoStructure.getForgeRepoStruct()
|
const forgeRepo = this.repoStructure.getForgeRepoStruct()
|
||||||
const artifactVersion = `${this.minecraftVersion}-${this.forgeVersion}`
|
const targetLocalPath = forgeRepo.getLocalForge(this.artifactVersion, 'universal')
|
||||||
const targetLocalPath = forgeRepo.getLocalForge(artifactVersion, 'universal')
|
|
||||||
console.debug(`Checking for forge version at ${targetLocalPath}..`)
|
console.debug(`Checking for forge version at ${targetLocalPath}..`)
|
||||||
if (!await forgeRepo.artifactExists(targetLocalPath)) {
|
if (!await forgeRepo.artifactExists(targetLocalPath)) {
|
||||||
console.debug(`Forge not found locally, initializing download..`)
|
console.debug(`Forge not found locally, initializing download..`)
|
||||||
@@ -46,7 +45,7 @@ export class Forge18Adapter extends ForgeResolver {
|
|||||||
this.REMOTE_REPOSITORY,
|
this.REMOTE_REPOSITORY,
|
||||||
ForgeRepoStructure.FORGE_GROUP,
|
ForgeRepoStructure.FORGE_GROUP,
|
||||||
ForgeRepoStructure.FORGE_ARTIFACT,
|
ForgeRepoStructure.FORGE_ARTIFACT,
|
||||||
artifactVersion, 'universal', 'jar')
|
this.artifactVersion, 'universal', 'jar')
|
||||||
} else {
|
} else {
|
||||||
console.debug('Using locally discovered forge.')
|
console.debug('Using locally discovered forge.')
|
||||||
}
|
}
|
||||||
@@ -75,7 +74,7 @@ export class Forge18Adapter extends ForgeResolver {
|
|||||||
id: MavenUtil.mavenComponentsToIdentifier(
|
id: MavenUtil.mavenComponentsToIdentifier(
|
||||||
ForgeRepoStructure.FORGE_GROUP,
|
ForgeRepoStructure.FORGE_GROUP,
|
||||||
ForgeRepoStructure.FORGE_ARTIFACT,
|
ForgeRepoStructure.FORGE_ARTIFACT,
|
||||||
artifactVersion, 'universal'
|
this.artifactVersion, 'universal'
|
||||||
),
|
),
|
||||||
name: 'Minecraft Forge',
|
name: 'Minecraft Forge',
|
||||||
type: Type.ForgeHosted,
|
type: Type.ForgeHosted,
|
||||||
@@ -86,7 +85,7 @@ export class Forge18Adapter extends ForgeResolver {
|
|||||||
this.baseUrl,
|
this.baseUrl,
|
||||||
ForgeRepoStructure.FORGE_GROUP,
|
ForgeRepoStructure.FORGE_GROUP,
|
||||||
ForgeRepoStructure.FORGE_ARTIFACT,
|
ForgeRepoStructure.FORGE_ARTIFACT,
|
||||||
artifactVersion, 'universal'
|
this.artifactVersion, 'universal'
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
subModules: []
|
subModules: []
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ export abstract class ForgeResolver extends BaseResolver {
|
|||||||
protected readonly REMOTE_REPOSITORY = 'https://files.minecraftforge.net/maven/'
|
protected readonly REMOTE_REPOSITORY = 'https://files.minecraftforge.net/maven/'
|
||||||
|
|
||||||
protected repoStructure: RepoStructure
|
protected repoStructure: RepoStructure
|
||||||
|
protected artifactVersion: string
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
absoluteRoot: string,
|
absoluteRoot: string,
|
||||||
@@ -16,6 +17,55 @@ export abstract class ForgeResolver extends BaseResolver {
|
|||||||
) {
|
) {
|
||||||
super(absoluteRoot, relativeRoot, baseUrl)
|
super(absoluteRoot, relativeRoot, baseUrl)
|
||||||
this.repoStructure = new RepoStructure(absoluteRoot, relativeRoot)
|
this.repoStructure = new RepoStructure(absoluteRoot, relativeRoot)
|
||||||
|
this.artifactVersion = this.inferArtifactVersion()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Coverage is not 100% but that doesnt matter.
|
||||||
|
// It's enough and you should always use the latest version anyway.
|
||||||
|
public inferArtifactVersion() {
|
||||||
|
const version = `${this.minecraftVersion}-${this.forgeVersion}`
|
||||||
|
|
||||||
|
const ver = this.forgeVersion.split('.')
|
||||||
|
const major = Number(ver[0])
|
||||||
|
if ([12, 11, 10].indexOf(major) > -1) {
|
||||||
|
const minor = Number(ver[1])
|
||||||
|
const revision = Number(ver[2])
|
||||||
|
const extra = Number(ver[3])
|
||||||
|
|
||||||
|
if (major === 10) {
|
||||||
|
if (minor === 13 && revision >= 2 && extra >= 1300) {
|
||||||
|
return `${version}-1.7.10`
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (major === 11) {
|
||||||
|
if (minor === 15) {
|
||||||
|
if (revision === 1 && extra >= 1890) {
|
||||||
|
return `${version}-1.8.9`
|
||||||
|
} else
|
||||||
|
if (revision === 0 && extra <= 1654) {
|
||||||
|
return `${version}-1.8.8`
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (minor === 14 && revision === 0 && extra <= 1295) {
|
||||||
|
return `${version}-1.8`
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
if (major === 12) {
|
||||||
|
if (minor === 17 && revision === 0 && extra <= 1936) {
|
||||||
|
return `${version}-1.9.4`
|
||||||
|
} else
|
||||||
|
if (minor === 16) {
|
||||||
|
if (revision === 0 && extra <= 1885) {
|
||||||
|
return `${version}-1.9`
|
||||||
|
} else
|
||||||
|
if (revision === 1 && extra === 1938) {
|
||||||
|
return `${version}-1.9.0`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return version
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import { spawn } from 'child_process'
|
import { spawn } from 'child_process'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
|
import { JavaUtil } from './javautil'
|
||||||
|
|
||||||
export class PackXZExtractWrapper {
|
export class PackXZExtractWrapper {
|
||||||
|
|
||||||
public static getJavaExecutable() {
|
|
||||||
return process.env.JAVA_EXECUTABLE as string
|
|
||||||
}
|
|
||||||
|
|
||||||
public static getPackXZExtract() {
|
public static getPackXZExtract() {
|
||||||
return join(process.cwd(), 'libraries', 'java', 'PackXZExtract.jar')
|
return join(process.cwd(), 'libraries', 'java', 'PackXZExtract.jar')
|
||||||
}
|
}
|
||||||
@@ -25,7 +22,7 @@ export class PackXZExtractWrapper {
|
|||||||
|
|
||||||
private static execute(command: string, paths: string[]) {
|
private static execute(command: string, paths: string[]) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const child = spawn(PackXZExtractWrapper.getJavaExecutable(), [
|
const child = spawn(JavaUtil.getJavaExecutable(), [
|
||||||
'-jar',
|
'-jar',
|
||||||
PackXZExtractWrapper.getPackXZExtract(),
|
PackXZExtractWrapper.getPackXZExtract(),
|
||||||
command,
|
command,
|
||||||
|
|||||||
7
src/util/javautil.ts
Normal file
7
src/util/javautil.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
export class JavaUtil {
|
||||||
|
|
||||||
|
public static getJavaExecutable() {
|
||||||
|
return process.env.JAVA_EXECUTABLE as string
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ export class VersionUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null
|
throw new Error(`${version} is not a valid minecraft version!`)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user