Skip to content

Commit

Permalink
Completed steps up to downloading forge universal jar for 1.8-1.12.
Browse files Browse the repository at this point in the history
Next step is processing the version.json and transforming it into a deliverable module.
  • Loading branch information
dscalzi committed Jan 12, 2020
1 parent baea8e6 commit 419a4d5
Show file tree
Hide file tree
Showing 14 changed files with 251 additions and 30 deletions.
7 changes: 6 additions & 1 deletion .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@
"type": "node",
"request": "launch",
"name": "Launch Program",
"program": "${workspaceFolder}\\dist\\index.js",
"program": "${workspaceFolder}\\src\\index.ts",
"args": [
"test",
"1.12.2",
"14.23.5.2847"
],
"preLaunchTask": "compile",
"outFiles": [
"${workspaceFolder}/dist/**/*.js"
Expand Down
29 changes: 29 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
},
"dependencies": {
"adm-zip": "^0.4.13",
"axios": "^0.19.1",
"fs-extra": "^8.1.0",
"yargs": "^15.1.0"
}
Expand Down
18 changes: 18 additions & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
/* tslint:disable:no-shadowed-variable */
import { writeFile } from 'fs-extra'
import { resolve as resolvePath } from 'path'
import { URL } from 'url'
import yargs from 'yargs'
import { DistributionStructure } from './model/struct/model/distribution.struct'
import { ResolverRegistry } from './resolver/ResolverRegistry'

function rootOption(yargs: yargs.Argv) {
return yargs.option('root', {
Expand Down Expand Up @@ -166,6 +168,21 @@ const validateCommand: yargs.CommandModule = {
}
}

const testCommand: yargs.CommandModule = {
command: 'test <mcVer> <forgeVer>',
describe: 'Validate a distribution.json against the spec.',
builder: (yargs) => {
return namePositional(yargs)
},
handler: async (argv) => {
console.debug(`Invoked test with mcVer ${argv.mcVer} forgeVer ${argv.forgeVer}`)
const resolver = ResolverRegistry.getForgeResolver('1.12.2', '14.23.5.2847', 'D:/TestRoot2', 'D:/TestRoot2')
if (resolver != null) {
await resolver.getModule()
}
}
}

// Registering yargs configuration.
// tslint:disable-next-line:no-unused-expression
yargs
Expand All @@ -174,6 +191,7 @@ yargs
.command(initCommand)
.command(generateCommand)
.command(validateCommand)
.command(testCommand)
.demandCommand()
.help()
.argv
35 changes: 33 additions & 2 deletions src/model/struct/repo/BaseMavenRepo.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { resolve } from 'path'
import axios from 'axios'
import { createWriteStream, mkdirs, pathExists } from 'fs-extra'
import { dirname, resolve } from 'path'
import { resolve as resolveURL } from 'url'
import { MavenUtil } from '../../../util/maven'
import { BaseFileStructure } from '../BaseFileStructure'

Expand All @@ -19,8 +22,36 @@ export abstract class BaseMavenRepo extends BaseFileStructure {

public getArtifactByComponents(group: string, artifact: string, version: string,
classifier?: string, extension = 'jar'): string {
throw resolve(this.containerDirectory,
return resolve(this.containerDirectory,
MavenUtil.mavenComponentsToString(group, artifact, version, classifier, extension))
}

public async artifactExists(path: string) {
return pathExists(path)
}

public async downloadArtifact(url: string, group: string, artifact: string, version: string,
classifier?: string, extension?: string) {
const relative = MavenUtil.mavenComponentsToString(group, artifact, version, classifier, extension)
const resolvedURL = resolveURL(url, relative).toString()
console.debug(`Downloading ${resolvedURL}..`)
const response = await axios({
method: 'get',
url: resolvedURL,
responseType: 'stream'
})
const localPath = resolve(this.containerDirectory, relative)
await mkdirs(dirname(localPath))
const writer = createWriteStream(localPath)
response.data.pipe(writer)
// tslint:disable-next-line: no-shadowed-variable
return new Promise((resolve, reject) => {
writer.on('finish', () => {
console.debug(`Completed download of ${resolvedURL}.`)
resolve()
})
writer.on('error', reject)
})
}

}
8 changes: 7 additions & 1 deletion src/model/struct/repo/forgerepo.struct.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ import { BaseMavenRepo } from './BaseMavenRepo'

export class ForgeRepoStructure extends BaseMavenRepo {

public static readonly FORGE_GROUP = 'net.minecraftforge'
public static readonly FORGE_ARTIFACT = 'forge'

constructor(
absoluteRoot: string,
relativeRoot: string
Expand All @@ -10,7 +13,10 @@ export class ForgeRepoStructure extends BaseMavenRepo {
}

public getLocalForge(version: string, classifier?: string) {
this.getArtifactByComponents('net.minecraftforge', 'forge', version, classifier, 'jar')
return this.getArtifactByComponents(
ForgeRepoStructure.FORGE_GROUP,
ForgeRepoStructure.FORGE_ARTIFACT,
version, classifier, 'jar')
}

}
23 changes: 23 additions & 0 deletions src/resolver/ResolverRegistry.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Forge113Adapter } from './forge/adapter/forge113.resolver'
import { Forge18Adapter } from './forge/adapter/forge18.resolver'
import { ForgeResolver } from './forge/forge.resolver'

export class ResolverRegistry {

public static readonly FORGE_ADAPTER_IMPL = [
Forge18Adapter,
Forge113Adapter
]

public static getForgeResolver(
minecraftVersion: string,
forgeVersion: string,
absoluteRoot: string, relativeRoot: string): ForgeResolver | undefined {
for (const impl of ResolverRegistry.FORGE_ADAPTER_IMPL) {
if (impl.isForVersion(minecraftVersion)) {
return new impl(absoluteRoot, relativeRoot, minecraftVersion, forgeVersion)
}
}
}

}
11 changes: 11 additions & 0 deletions src/resolver/baseresolver.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
import { Module } from '../model/spec/module'
import { VersionUtil } from '../util/versionutil'
import { Resolver } from './resolver'

export abstract class BaseResolver implements Resolver {

protected static isVersionAcceptable(version: string, acceptable: number[]): boolean {
const versionComponents = VersionUtil.getMinecraftVersionComponents(version)
if (versionComponents != null && versionComponents.major === 1) {
return acceptable.find((element) => versionComponents.minor === element) != null
}
return false
}

constructor(
protected absoluteRoot: string,
protected relativeRoot: string
) {}

public abstract getModule(): Promise<Module>

public abstract isForVersion(version: string): boolean

}
27 changes: 27 additions & 0 deletions src/resolver/forge/adapter/forge113.resolver.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { Module } from '../../../model/spec/module'
import { ForgeResolver } from '../forge.resolver'

export class Forge113Adapter extends ForgeResolver {

public static isForVersion(version: string) {
return Forge113Adapter.isVersionAcceptable(version, [13, 14, 15])
}

constructor(
absoluteRoot: string,
relativeRoot: string,
minecraftVersion: string,
forgeVersion: string
) {
super(absoluteRoot, relativeRoot, minecraftVersion, forgeVersion)
}

public async getModule(): Promise<Module> {
return null as unknown as Module
}

public isForVersion(version: string): boolean {
return Forge113Adapter.isForVersion(version)
}

}
42 changes: 42 additions & 0 deletions src/resolver/forge/adapter/forge18.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,52 @@
import { Module } from '../../../model/spec/module'
import { ForgeRepoStructure } from '../../../model/struct/repo/forgerepo.struct'
import { ForgeResolver } from '../forge.resolver'

export class Forge18Adapter extends ForgeResolver {

public static isForVersion(version: string) {
return Forge18Adapter.isVersionAcceptable(version, [8, 9, 10, 11, 12])
}

constructor(
absoluteRoot: string,
relativeRoot: string,
minecraftVersion: string,
forgeVersion: string
) {
super(absoluteRoot, relativeRoot, minecraftVersion, forgeVersion)
}

public async getModule(): Promise<Module> {
await this.getForgeByVersion()
return null as unknown as Module
}

public isForVersion(version: string) {
return Forge18Adapter.isForVersion(version)
}

public async getForgeByVersion() {
const forgeRepo = this.repoStructure.getForgeRepoStruct()
const artifactVersion = `${this.minecraftVersion}-${this.forgeVersion}`
const targetLocalPath = forgeRepo.getLocalForge(artifactVersion, 'universal')
console.debug(`Checking for forge version at ${targetLocalPath}..`)
if (!await forgeRepo.artifactExists(targetLocalPath)) {
console.debug(`Forge not found locally, initializing download..`)
await forgeRepo.downloadArtifact(
this.REMOTE_REPOSITORY,
ForgeRepoStructure.FORGE_GROUP,
ForgeRepoStructure.FORGE_ARTIFACT,
artifactVersion, 'universal', 'jar')
} else {
console.debug('Using locally discovered forge.')
}
console.debug(`Beginning processing of Forge v${this.forgeVersion} (Minecraft ${this.minecraftVersion})`)
}

// TODO
// extract manifest
// parse manifest
// return module

}
21 changes: 4 additions & 17 deletions src/resolver/forge/forge.resolver.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,20 @@
import { Module } from '../../model/spec/module'
import { RepoStructure } from '../../model/struct/repo/repo.struct'
import { BaseResolver } from '../baseresolver'
import { Forge18Adapter } from './adapter/forge18.resolver'

export abstract class ForgeResolver extends BaseResolver {

public static getResolver(version: string) {
return ForgeResolver.ADAPTER_LIST[version]
}

// tslint:disable: object-literal-key-quotes
private static readonly ADAPTER_LIST: {[version: string]: any} = {
'1.8': Forge18Adapter,
'1.9': Forge18Adapter,
'1.10': Forge18Adapter,
'1.11': Forge18Adapter,
'1.12': Forge18Adapter
}
protected readonly REMOTE_REPOSITORY = 'https://files.minecraftforge.net/maven/'

protected repoStructure: RepoStructure

constructor(
absoluteRoot: string,
relativeRoot: string
relativeRoot: string,
protected minecraftVersion: string,
protected forgeVersion: string
) {
super(absoluteRoot, relativeRoot)
this.repoStructure = new RepoStructure(absoluteRoot, relativeRoot)
}

public abstract getModule(): Promise<Module>

}
Loading

0 comments on commit 419a4d5

Please sign in to comment.