Add support for reading mods.toml file from 1.13+ forge mods.
This commit is contained in:
5
package-lock.json
generated
5
package-lock.json
generated
@@ -514,6 +514,11 @@
|
|||||||
"has-flag": "^3.0.0"
|
"has-flag": "^3.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"toml": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/toml/-/toml-3.0.0.tgz",
|
||||||
|
"integrity": "sha512-y/mWCZinnvxjTKYhJ+pYxwD0mRLVvOtdS2Awbgxln6iEnt4rk0yBxeSBHkGJcPucRiG0e55mwWp+g/05rsrd6w=="
|
||||||
|
},
|
||||||
"tslib": {
|
"tslib": {
|
||||||
"version": "1.10.0",
|
"version": "1.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
|
||||||
|
|||||||
@@ -39,6 +39,7 @@
|
|||||||
"axios": "^0.19.1",
|
"axios": "^0.19.1",
|
||||||
"dotenv": "^8.2.0",
|
"dotenv": "^8.2.0",
|
||||||
"fs-extra": "^8.1.0",
|
"fs-extra": "^8.1.0",
|
||||||
|
"toml": "^3.0.0",
|
||||||
"yargs": "^15.1.0"
|
"yargs": "^15.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { inspect } from 'util'
|
|||||||
import yargs from 'yargs'
|
import yargs from 'yargs'
|
||||||
import { DistributionStructure } from './model/struct/model/distribution.struct'
|
import { DistributionStructure } from './model/struct/model/distribution.struct'
|
||||||
import { ServerStructure } from './model/struct/model/server.struct'
|
import { ServerStructure } from './model/struct/model/server.struct'
|
||||||
import { ResolverRegistry } from './resolver/ResolverRegistry'
|
import { VersionSegmentedRegistry } from './util/VersionSegmentedRegistry'
|
||||||
|
|
||||||
dotenv.config()
|
dotenv.config()
|
||||||
|
|
||||||
@@ -217,7 +217,7 @@ 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(argv.mcVer as string,
|
const resolver = VersionSegmentedRegistry.getForgeResolver(argv.mcVer as string,
|
||||||
argv.forgeVer as string, getRoot(), '', getBaseURL())
|
argv.forgeVer as string, getRoot(), '', getBaseURL())
|
||||||
if (resolver != null) {
|
if (resolver != null) {
|
||||||
const mdl = await resolver.getModule()
|
const mdl = await resolver.getModule()
|
||||||
|
|||||||
29
src/model/forge/modstoml.ts
Normal file
29
src/model/forge/modstoml.ts
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
// https://github.com/MinecraftForge/MinecraftForge/blob/1.15.x/mdk/src/main/resources/META-INF/mods.toml
|
||||||
|
|
||||||
|
export interface ModsToml {
|
||||||
|
|
||||||
|
modLoader: string,
|
||||||
|
loaderVersion: string
|
||||||
|
issueTrackerURL?: string
|
||||||
|
|
||||||
|
mods: Array<{
|
||||||
|
modId: string
|
||||||
|
version: string
|
||||||
|
displayName: string
|
||||||
|
updateJSONURL?: string
|
||||||
|
displayURL?: string
|
||||||
|
logoFile?: string
|
||||||
|
credits?: string
|
||||||
|
authors?: string
|
||||||
|
description: string
|
||||||
|
}>
|
||||||
|
|
||||||
|
dependencies?: {[modId: string]: {
|
||||||
|
modId: string,
|
||||||
|
mandatory: boolean,
|
||||||
|
versionRange: string,
|
||||||
|
ordering?: 'NONE' | 'BEFORE' | 'AFTER'
|
||||||
|
side: 'BOTH' | 'CLIENT' | 'SERVER'
|
||||||
|
}}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,16 +1,11 @@
|
|||||||
import AdmZip from 'adm-zip'
|
|
||||||
import { Stats } from 'fs-extra'
|
import { Stats } from 'fs-extra'
|
||||||
import { join } from 'path'
|
import { join } from 'path'
|
||||||
import { resolve } from 'url'
|
import { resolve } from 'url'
|
||||||
import { capitalize } from '../../../../util/stringutils'
|
import { VersionSegmented } from '../../../../util/VersionSegmented'
|
||||||
import { McModInfo } from '../../../forge/mcmodinfo'
|
|
||||||
import { McModInfoList } from '../../../forge/mcmodinfolist'
|
|
||||||
import { Type } from '../../../spec/type'
|
import { Type } from '../../../spec/type'
|
||||||
import { ModuleStructure } from './module.struct'
|
import { ModuleStructure } from './module.struct'
|
||||||
|
|
||||||
export class ForgeModStructure extends ModuleStructure {
|
export abstract class BaseForgeModStructure extends ModuleStructure implements VersionSegmented {
|
||||||
|
|
||||||
private forgeModMetadata: {[property: string]: McModInfo | undefined} = {}
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
absoluteRoot: string,
|
absoluteRoot: string,
|
||||||
@@ -20,13 +15,8 @@ export class ForgeModStructure extends ModuleStructure {
|
|||||||
super(absoluteRoot, relativeRoot, 'forgemods', baseUrl, Type.ForgeMod)
|
super(absoluteRoot, relativeRoot, 'forgemods', baseUrl, Type.ForgeMod)
|
||||||
}
|
}
|
||||||
|
|
||||||
protected async getModuleId(name: string, path: string, stats: Stats, buf: Buffer): Promise<string> {
|
public abstract isForVersion(version: string): boolean
|
||||||
const fmData = this.getForgeModMetadata(buf, name)
|
|
||||||
return this.generateMavenIdentifier(fmData.modid, fmData.version)
|
|
||||||
}
|
|
||||||
protected async getModuleName(name: string, path: string, stats: Stats, buf: Buffer): Promise<string> {
|
|
||||||
return capitalize((this.getForgeModMetadata(buf, name)).name)
|
|
||||||
}
|
|
||||||
protected async getModuleUrl(name: string, path: string, stats: Stats): Promise<string> {
|
protected async getModuleUrl(name: string, path: string, stats: Stats): Promise<string> {
|
||||||
return resolve(this.baseUrl, join(this.relativeRoot, name))
|
return resolve(this.baseUrl, join(this.relativeRoot, name))
|
||||||
}
|
}
|
||||||
@@ -34,75 +24,4 @@ export class ForgeModStructure extends ModuleStructure {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
private getForgeModMetadata(buf: Buffer, name: string): McModInfo {
|
|
||||||
if (!this.forgeModMetadata.hasOwnProperty(name)) {
|
|
||||||
const zip = new AdmZip(buf)
|
|
||||||
const zipEntries = zip.getEntries()
|
|
||||||
|
|
||||||
// Optifine is a tweak that can be loaded as a forge mod. It does not
|
|
||||||
// appear to contain a mcmod.info class. This a special case we will
|
|
||||||
// account for.
|
|
||||||
if (name.toLowerCase().indexOf('optifine') > -1) {
|
|
||||||
// Read zip for changelog.txt
|
|
||||||
let rawChangelog
|
|
||||||
for (const entry of zipEntries) {
|
|
||||||
if (entry.entryName === 'changelog.txt') {
|
|
||||||
rawChangelog = zip.readAsText(entry)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!rawChangelog) {
|
|
||||||
throw new Error('Failed to read OptiFine changelog.')
|
|
||||||
}
|
|
||||||
const info = rawChangelog.split('\n')[0].trim()
|
|
||||||
const version = info.split(' ')[1]
|
|
||||||
this.forgeModMetadata[name] = ({
|
|
||||||
modid: 'optifine',
|
|
||||||
name: info,
|
|
||||||
version,
|
|
||||||
mcversion: version.substring(0, version.indexOf('_'))
|
|
||||||
}) as unknown as McModInfo
|
|
||||||
return this.forgeModMetadata[name] as McModInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
let raw
|
|
||||||
for (const entry of zipEntries) {
|
|
||||||
if (entry.entryName === 'mcmod.info') {
|
|
||||||
raw = zip.readAsText(entry)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let createDefault = false
|
|
||||||
|
|
||||||
if (raw) {
|
|
||||||
// Assuming the main mod will be the first entry in this file.
|
|
||||||
try {
|
|
||||||
const resolved = JSON.parse(raw) as object
|
|
||||||
if (resolved.hasOwnProperty('modListVersion')) {
|
|
||||||
this.forgeModMetadata[name] = (resolved as McModInfoList).modList[0]
|
|
||||||
} else {
|
|
||||||
this.forgeModMetadata[name] = (resolved as McModInfo[])[0]
|
|
||||||
}
|
|
||||||
} catch (err) {
|
|
||||||
console.error(`ForgeMod ${name} contains an invalid mcmod.info file.`)
|
|
||||||
createDefault = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
console.error(`ForgeMod ${name} does not contain mcmod.info file.`)
|
|
||||||
createDefault = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if (createDefault) {
|
|
||||||
this.forgeModMetadata[name] = ({
|
|
||||||
modid: name.substring(0, name.lastIndexOf('.')).toLowerCase(),
|
|
||||||
name,
|
|
||||||
version: '0.0.0'
|
|
||||||
}) as unknown as McModInfo
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.forgeModMetadata[name] as McModInfo
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
104
src/model/struct/model/module/forgemod/forgemod113.struct.ts
Normal file
104
src/model/struct/model/module/forgemod/forgemod113.struct.ts
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
import AdmZip from 'adm-zip'
|
||||||
|
import { Stats } from 'fs-extra'
|
||||||
|
import toml from 'toml'
|
||||||
|
import { capitalize } from '../../../../../util/stringutils'
|
||||||
|
import { VersionUtil } from '../../../../../util/versionutil'
|
||||||
|
import { ModsToml } from '../../../../forge/modstoml'
|
||||||
|
import { BaseForgeModStructure } from '../forgemod.struct'
|
||||||
|
|
||||||
|
export class ForgeModStructure113 extends BaseForgeModStructure {
|
||||||
|
|
||||||
|
public static isForVersion(version: string) {
|
||||||
|
return VersionUtil.isVersionAcceptable(version, [13, 14, 15])
|
||||||
|
}
|
||||||
|
|
||||||
|
private forgeModMetadata: {[property: string]: ModsToml | undefined} = {}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
absoluteRoot: string,
|
||||||
|
relativeRoot: string,
|
||||||
|
baseUrl: string
|
||||||
|
) {
|
||||||
|
super(absoluteRoot, relativeRoot, baseUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
public isForVersion(version: string): boolean {
|
||||||
|
return ForgeModStructure113.isForVersion(version)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async getModuleId(name: string, path: string, stats: Stats, buf: Buffer): Promise<string> {
|
||||||
|
const fmData = this.getForgeModMetadata(buf, name)
|
||||||
|
return this.generateMavenIdentifier(fmData.mods[0].modId, fmData.mods[0].version)
|
||||||
|
}
|
||||||
|
protected async getModuleName(name: string, path: string, stats: Stats, buf: Buffer): Promise<string> {
|
||||||
|
return capitalize((this.getForgeModMetadata(buf, name)).mods[0].displayName)
|
||||||
|
}
|
||||||
|
|
||||||
|
private getForgeModMetadata(buf: Buffer, name: string): ModsToml {
|
||||||
|
|
||||||
|
if (!this.forgeModMetadata.hasOwnProperty(name)) {
|
||||||
|
const zip = new AdmZip(buf)
|
||||||
|
const zipEntries = zip.getEntries()
|
||||||
|
|
||||||
|
// Optifine is a tweak that can be loaded as a forge mod. It does not
|
||||||
|
// appear to contain a mcmod.info class. This a special case we will
|
||||||
|
// account for.
|
||||||
|
if (name.toLowerCase().indexOf('optifine') > -1) {
|
||||||
|
// Read zip for changelog.txt
|
||||||
|
let rawChangelog
|
||||||
|
for (const entry of zipEntries) {
|
||||||
|
if (entry.entryName === 'changelog.txt') {
|
||||||
|
rawChangelog = zip.readAsText(entry)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rawChangelog) {
|
||||||
|
throw new Error('Failed to read OptiFine changelog.')
|
||||||
|
}
|
||||||
|
const info = rawChangelog.split('\n')[0].trim()
|
||||||
|
const version = info.split(' ')[1]
|
||||||
|
this.forgeModMetadata[name] = ({
|
||||||
|
modid: 'optifine',
|
||||||
|
name: info,
|
||||||
|
version,
|
||||||
|
mcversion: version.substring(0, version.indexOf('_'))
|
||||||
|
}) as unknown as ModsToml
|
||||||
|
return this.forgeModMetadata[name] as ModsToml
|
||||||
|
}
|
||||||
|
|
||||||
|
const raw = zip.readAsText('META-INF/mods.toml')
|
||||||
|
|
||||||
|
let createDefault = false
|
||||||
|
|
||||||
|
if (raw) {
|
||||||
|
// Assuming the main mod will be the first entry in this file.
|
||||||
|
try {
|
||||||
|
this.forgeModMetadata[name] = toml.parse(raw) as ModsToml
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`ForgeMod ${name} contains an invalid mods.toml file.`)
|
||||||
|
createDefault = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error(`ForgeMod ${name} does not contain mods.toml file.`)
|
||||||
|
createDefault = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (createDefault) {
|
||||||
|
this.forgeModMetadata[name] = ({
|
||||||
|
modLoader: 'javafml',
|
||||||
|
loaderVersion: '',
|
||||||
|
mods: [{
|
||||||
|
modId: name.substring(0, name.lastIndexOf('.')).toLowerCase(),
|
||||||
|
version: '0.0.0',
|
||||||
|
displayName: name,
|
||||||
|
description: ''
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.forgeModMetadata[name] as ModsToml
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
108
src/model/struct/model/module/forgemod/forgemod17.struct.ts
Normal file
108
src/model/struct/model/module/forgemod/forgemod17.struct.ts
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
import AdmZip from 'adm-zip'
|
||||||
|
import { Stats } from 'fs-extra'
|
||||||
|
import { capitalize } from '../../../../../util/stringutils'
|
||||||
|
import { VersionUtil } from '../../../../../util/versionutil'
|
||||||
|
import { McModInfo } from '../../../../forge/mcmodinfo'
|
||||||
|
import { McModInfoList } from '../../../../forge/mcmodinfolist'
|
||||||
|
import { BaseForgeModStructure } from '../forgemod.struct'
|
||||||
|
|
||||||
|
export class ForgeModStructure17 extends BaseForgeModStructure {
|
||||||
|
|
||||||
|
public static isForVersion(version: string) {
|
||||||
|
return VersionUtil.isVersionAcceptable(version, [7, 8, 9, 10, 11, 12])
|
||||||
|
}
|
||||||
|
|
||||||
|
private forgeModMetadata: {[property: string]: McModInfo | undefined} = {}
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
absoluteRoot: string,
|
||||||
|
relativeRoot: string,
|
||||||
|
baseUrl: string
|
||||||
|
) {
|
||||||
|
super(absoluteRoot, relativeRoot, baseUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
public isForVersion(version: string): boolean {
|
||||||
|
return ForgeModStructure17.isForVersion(version)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected async getModuleId(name: string, path: string, stats: Stats, buf: Buffer): Promise<string> {
|
||||||
|
const fmData = this.getForgeModMetadata(buf, name)
|
||||||
|
return this.generateMavenIdentifier(fmData.modid, fmData.version)
|
||||||
|
}
|
||||||
|
protected async getModuleName(name: string, path: string, stats: Stats, buf: Buffer): Promise<string> {
|
||||||
|
return capitalize((this.getForgeModMetadata(buf, name)).name)
|
||||||
|
}
|
||||||
|
|
||||||
|
private getForgeModMetadata(buf: Buffer, name: string): McModInfo {
|
||||||
|
if (!this.forgeModMetadata.hasOwnProperty(name)) {
|
||||||
|
const zip = new AdmZip(buf)
|
||||||
|
const zipEntries = zip.getEntries()
|
||||||
|
|
||||||
|
// Optifine is a tweak that can be loaded as a forge mod. It does not
|
||||||
|
// appear to contain a mcmod.info class. This a special case we will
|
||||||
|
// account for.
|
||||||
|
if (name.toLowerCase().indexOf('optifine') > -1) {
|
||||||
|
// Read zip for changelog.txt
|
||||||
|
let rawChangelog
|
||||||
|
for (const entry of zipEntries) {
|
||||||
|
if (entry.entryName === 'changelog.txt') {
|
||||||
|
rawChangelog = zip.readAsText(entry)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!rawChangelog) {
|
||||||
|
throw new Error('Failed to read OptiFine changelog.')
|
||||||
|
}
|
||||||
|
const info = rawChangelog.split('\n')[0].trim()
|
||||||
|
const version = info.split(' ')[1]
|
||||||
|
this.forgeModMetadata[name] = ({
|
||||||
|
modid: 'optifine',
|
||||||
|
name: info,
|
||||||
|
version,
|
||||||
|
mcversion: version.substring(0, version.indexOf('_'))
|
||||||
|
}) as unknown as McModInfo
|
||||||
|
return this.forgeModMetadata[name] as McModInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
let raw
|
||||||
|
for (const entry of zipEntries) {
|
||||||
|
if (entry.entryName === 'mcmod.info') {
|
||||||
|
raw = zip.readAsText(entry)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let createDefault = false
|
||||||
|
|
||||||
|
if (raw) {
|
||||||
|
// Assuming the main mod will be the first entry in this file.
|
||||||
|
try {
|
||||||
|
const resolved = JSON.parse(raw) as object
|
||||||
|
if (resolved.hasOwnProperty('modListVersion')) {
|
||||||
|
this.forgeModMetadata[name] = (resolved as McModInfoList).modList[0]
|
||||||
|
} else {
|
||||||
|
this.forgeModMetadata[name] = (resolved as McModInfo[])[0]
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`ForgeMod ${name} contains an invalid mcmod.info file.`)
|
||||||
|
createDefault = true
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.error(`ForgeMod ${name} does not contain mcmod.info file.`)
|
||||||
|
createDefault = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (createDefault) {
|
||||||
|
this.forgeModMetadata[name] = ({
|
||||||
|
modid: name.substring(0, name.lastIndexOf('.')).toLowerCase(),
|
||||||
|
name,
|
||||||
|
version: '0.0.0'
|
||||||
|
}) as unknown as McModInfo
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.forgeModMetadata[name] as McModInfo
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
import { lstat, mkdirs, pathExists, readdir, readFile, writeFile } from 'fs-extra'
|
import { lstat, mkdirs, pathExists, readdir, readFile, writeFile } from 'fs-extra'
|
||||||
import { dirname, join, resolve as resolvePath } from 'path'
|
import { dirname, join, resolve as resolvePath } from 'path'
|
||||||
import { resolve as resolveUrl } from 'url'
|
import { resolve as resolveUrl } from 'url'
|
||||||
import { ResolverRegistry } from '../../../resolver/ResolverRegistry'
|
import { VersionSegmentedRegistry } from '../../../util/VersionSegmentedRegistry'
|
||||||
import { ServerMeta } from '../../nebula/servermeta'
|
import { ServerMeta } from '../../nebula/servermeta'
|
||||||
import { Server } from '../../spec/server'
|
import { Server } from '../../spec/server'
|
||||||
import { BaseModelStructure } from './basemodel.struct'
|
import { BaseModelStructure } from './basemodel.struct'
|
||||||
import { MiscFileStructure } from './module/file.struct'
|
import { MiscFileStructure } from './module/file.struct'
|
||||||
import { ForgeModStructure } from './module/forgemod.struct'
|
|
||||||
import { LiteModStructure } from './module/litemod.struct'
|
import { LiteModStructure } from './module/litemod.struct'
|
||||||
|
|
||||||
export class ServerStructure extends BaseModelStructure<Server> {
|
export class ServerStructure extends BaseModelStructure<Server> {
|
||||||
@@ -47,7 +46,12 @@ export class ServerStructure extends BaseModelStructure<Server> {
|
|||||||
await mkdirs(absoluteServerRoot)
|
await mkdirs(absoluteServerRoot)
|
||||||
|
|
||||||
if (options.forgeVersion != null) {
|
if (options.forgeVersion != null) {
|
||||||
const fms = new ForgeModStructure(absoluteServerRoot, relativeServerRoot, this.baseUrl)
|
const fms = VersionSegmentedRegistry.getForgeModStruct(
|
||||||
|
minecraftVersion,
|
||||||
|
absoluteServerRoot,
|
||||||
|
relativeServerRoot,
|
||||||
|
this.baseUrl
|
||||||
|
)
|
||||||
await fms.init()
|
await fms.init()
|
||||||
const serverMeta: ServerMeta = {
|
const serverMeta: ServerMeta = {
|
||||||
forgeVersion: options.forgeVersion
|
forgeVersion: options.forgeVersion
|
||||||
@@ -99,24 +103,25 @@ export class ServerStructure extends BaseModelStructure<Server> {
|
|||||||
|
|
||||||
// Read server meta
|
// Read server meta
|
||||||
const serverMeta: ServerMeta = JSON.parse(await readFile(resolvePath(absoluteServerRoot, 'servermeta.json'), 'utf-8'))
|
const serverMeta: ServerMeta = JSON.parse(await readFile(resolvePath(absoluteServerRoot, 'servermeta.json'), 'utf-8'))
|
||||||
|
const minecraftVersion = match[2]
|
||||||
|
|
||||||
const forgeResolver = ResolverRegistry.getForgeResolver(
|
const forgeResolver = VersionSegmentedRegistry.getForgeResolver(
|
||||||
match[2],
|
minecraftVersion,
|
||||||
serverMeta.forgeVersion,
|
serverMeta.forgeVersion,
|
||||||
dirname(this.containerDirectory),
|
dirname(this.containerDirectory),
|
||||||
'',
|
'',
|
||||||
this.baseUrl
|
this.baseUrl
|
||||||
)
|
)
|
||||||
|
|
||||||
if (forgeResolver == null) {
|
|
||||||
console.error(`No forge resolver found for Minecraft ${match[2]}, aborting.`)
|
|
||||||
throw new Error(`No forge resolver found for Minecraft ${match[2]}!`)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Resolve forge
|
// Resolve forge
|
||||||
const forgeItselfModule = await forgeResolver.getModule()
|
const forgeItselfModule = await forgeResolver.getModule()
|
||||||
|
|
||||||
const forgeModStruct = new ForgeModStructure(absoluteServerRoot, relativeServerRoot, this.baseUrl)
|
const forgeModStruct = VersionSegmentedRegistry.getForgeModStruct(
|
||||||
|
minecraftVersion,
|
||||||
|
absoluteServerRoot,
|
||||||
|
relativeServerRoot,
|
||||||
|
this.baseUrl
|
||||||
|
)
|
||||||
const forgeModModules = await forgeModStruct.getSpecModel()
|
const forgeModModules = await forgeModStruct.getSpecModel()
|
||||||
|
|
||||||
const liteModStruct = new LiteModStructure(absoluteServerRoot, relativeServerRoot, this.baseUrl)
|
const liteModStruct = new LiteModStructure(absoluteServerRoot, relativeServerRoot, this.baseUrl)
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
import { Forge113Adapter } from './forge/adapter/forge113.resolver'
|
|
||||||
import { Forge17Adapter } from './forge/adapter/forge17.resolver'
|
|
||||||
import { ForgeResolver } from './forge/forge.resolver'
|
|
||||||
|
|
||||||
export class ResolverRegistry {
|
|
||||||
|
|
||||||
public static readonly FORGE_ADAPTER_IMPL = [
|
|
||||||
Forge17Adapter,
|
|
||||||
Forge113Adapter
|
|
||||||
]
|
|
||||||
|
|
||||||
public static getForgeResolver(
|
|
||||||
minecraftVersion: string,
|
|
||||||
forgeVersion: string,
|
|
||||||
absoluteRoot: string,
|
|
||||||
relativeRoot: string,
|
|
||||||
baseURL: string): ForgeResolver | undefined {
|
|
||||||
for (const impl of ResolverRegistry.FORGE_ADAPTER_IMPL) {
|
|
||||||
if (impl.isForVersion(minecraftVersion)) {
|
|
||||||
return new impl(absoluteRoot, relativeRoot, baseURL, minecraftVersion, forgeVersion)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,16 +1,8 @@
|
|||||||
import { Module } from '../model/spec/module'
|
import { Module } from '../model/spec/module'
|
||||||
import { VersionUtil } from '../util/versionutil'
|
import { VersionSegmented } from '../util/VersionSegmented'
|
||||||
import { Resolver } from './resolver'
|
import { Resolver } from './resolver'
|
||||||
|
|
||||||
export abstract class BaseResolver implements Resolver {
|
export abstract class BaseResolver implements Resolver, VersionSegmented {
|
||||||
|
|
||||||
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(
|
constructor(
|
||||||
protected absoluteRoot: string,
|
protected absoluteRoot: string,
|
||||||
|
|||||||
@@ -8,12 +8,13 @@ import { ForgeRepoStructure } from '../../../model/struct/repo/forgerepo.struct'
|
|||||||
import { LibRepoStructure } from '../../../model/struct/repo/librepo.struct'
|
import { LibRepoStructure } from '../../../model/struct/repo/librepo.struct'
|
||||||
import { JavaUtil } from '../../../util/javautil'
|
import { JavaUtil } from '../../../util/javautil'
|
||||||
import { MavenUtil } from '../../../util/maven'
|
import { MavenUtil } from '../../../util/maven'
|
||||||
|
import { VersionUtil } from '../../../util/versionutil'
|
||||||
import { ForgeResolver } from '../forge.resolver'
|
import { ForgeResolver } from '../forge.resolver'
|
||||||
|
|
||||||
export class Forge113Adapter extends ForgeResolver {
|
export class Forge113Adapter extends ForgeResolver {
|
||||||
|
|
||||||
public static isForVersion(version: string) {
|
public static isForVersion(version: string) {
|
||||||
return Forge113Adapter.isVersionAcceptable(version, [13, 14, 15])
|
return VersionUtil.isVersionAcceptable(version, [13, 14, 15])
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
@@ -8,12 +8,13 @@ import { Type } from '../../../model/spec/type'
|
|||||||
import { ForgeRepoStructure } from '../../../model/struct/repo/forgerepo.struct'
|
import { ForgeRepoStructure } from '../../../model/struct/repo/forgerepo.struct'
|
||||||
import { MavenUtil } from '../../../util/maven'
|
import { MavenUtil } from '../../../util/maven'
|
||||||
import { PackXZExtractWrapper } from '../../../util/PackXZExtractWrapper'
|
import { PackXZExtractWrapper } from '../../../util/PackXZExtractWrapper'
|
||||||
|
import { VersionUtil } from '../../../util/versionutil'
|
||||||
import { ForgeResolver } from '../forge.resolver'
|
import { ForgeResolver } from '../forge.resolver'
|
||||||
|
|
||||||
export class Forge17Adapter extends ForgeResolver {
|
export class Forge17Adapter extends ForgeResolver {
|
||||||
|
|
||||||
public static isForVersion(version: string) {
|
public static isForVersion(version: string) {
|
||||||
return Forge17Adapter.isVersionAcceptable(version, [7, 8, 9, 10, 11, 12])
|
return VersionUtil.isVersionAcceptable(version, [7, 8, 9, 10, 11, 12])
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
|
|||||||
5
src/util/VersionSegmented.ts
Normal file
5
src/util/VersionSegmented.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
export interface VersionSegmented {
|
||||||
|
|
||||||
|
isForVersion(version: string): boolean
|
||||||
|
|
||||||
|
}
|
||||||
46
src/util/VersionSegmentedRegistry.ts
Normal file
46
src/util/VersionSegmentedRegistry.ts
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import { ForgeModStructure113 } from '../model/struct/model/module/forgemod/forgemod113.struct'
|
||||||
|
import { ForgeModStructure17 } from '../model/struct/model/module/forgemod/forgemod17.struct'
|
||||||
|
import { Forge113Adapter } from '../resolver/forge/adapter/forge113.resolver'
|
||||||
|
import { Forge17Adapter } from '../resolver/forge/adapter/forge17.resolver'
|
||||||
|
|
||||||
|
export class VersionSegmentedRegistry {
|
||||||
|
|
||||||
|
public static readonly FORGE_ADAPTER_IMPL = [
|
||||||
|
Forge17Adapter,
|
||||||
|
Forge113Adapter
|
||||||
|
]
|
||||||
|
|
||||||
|
public static readonly FORGEMOD_STRUCT_IML = [
|
||||||
|
ForgeModStructure17,
|
||||||
|
ForgeModStructure113
|
||||||
|
]
|
||||||
|
|
||||||
|
public static getForgeResolver(
|
||||||
|
minecraftVersion: string,
|
||||||
|
forgeVersion: string,
|
||||||
|
absoluteRoot: string,
|
||||||
|
relativeRoot: string,
|
||||||
|
baseURL: string) {
|
||||||
|
for (const impl of VersionSegmentedRegistry.FORGE_ADAPTER_IMPL) {
|
||||||
|
if (impl.isForVersion(minecraftVersion)) {
|
||||||
|
return new impl(absoluteRoot, relativeRoot, baseURL, minecraftVersion, forgeVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error(`No forge resolver found for Minecraft ${minecraftVersion}!`)
|
||||||
|
}
|
||||||
|
|
||||||
|
public static getForgeModStruct(
|
||||||
|
minecraftVersion: string,
|
||||||
|
absoluteRoot: string,
|
||||||
|
relativeRoot: string,
|
||||||
|
baseUrl: string
|
||||||
|
) {
|
||||||
|
for (const impl of VersionSegmentedRegistry.FORGEMOD_STRUCT_IML) {
|
||||||
|
if (impl.isForVersion(minecraftVersion)) {
|
||||||
|
return new impl(absoluteRoot, relativeRoot, baseUrl)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new Error(`No forge mod structure found for Minecraft ${minecraftVersion}!`)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -20,4 +20,12 @@ export class VersionUtil {
|
|||||||
throw new Error(`${version} is not a valid minecraft version!`)
|
throw new Error(`${version} is not a valid minecraft version!`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public 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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user