Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support Fabric and FabricMod type #5

Merged
merged 4 commits into from
Dec 3, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions lib/common/distribution/DistributionFactory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,15 @@ export class HeliosModule {
case Type.Library:
case Type.Forge:
case Type.ForgeHosted:
case Type.Fabric:
case Type.LiteLoader:
return join(commonDir, 'libraries', relativePath)
case Type.ForgeMod:
case Type.LiteMod:
// TODO Move to /mods/forge eventually..
return join(commonDir, 'modstore', relativePath)
case Type.FabricMod:
return join(commonDir, 'mods', 'fabric', relativePath)
case Type.File:
default:
return join(instanceDir, this.serverId, relativePath)
Expand Down
43 changes: 22 additions & 21 deletions lib/dl/distribution/DistributionIndexProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { mcVersionAtLeast } from '../../common/util/MojangUtils'
import { ensureDir, readJson, writeJson } from 'fs-extra'
import StreamZip from 'node-stream-zip'
import { dirname } from 'path'
import { VersionJsonBase } from '../mojang/MojangTypes'

export class DistributionIndexProcessor extends IndexProcessor {

Expand Down Expand Up @@ -43,7 +44,7 @@ export class DistributionIndexProcessor extends IndexProcessor {
}

public async postDownload(): Promise<void> {
await this.loadForgeVersionJson()
await this.loadModLoaderVersionJson()
}

private async validateModules(modules: HeliosModule[], accumulator: Asset[]): Promise<void> {
Expand All @@ -67,44 +68,35 @@ export class DistributionIndexProcessor extends IndexProcessor {
}
}

// TODO Type the return type.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public async loadForgeVersionJson(): Promise<any> {
public async loadModLoaderVersionJson(): Promise<VersionJsonBase> {

const server: HeliosServer = this.distribution.getServerById(this.serverId)!
if(server == null) {
throw new AssetGuardError(`Invalid server id ${this.serverId}`)
}

const forgeModule = server.modules.find(({ rawModule: { type } }) => type === Type.ForgeHosted || type === Type.Forge)
const modLoaderModule = server.modules.find(({ rawModule: { type } }) => type === Type.ForgeHosted || type === Type.Forge || type === Type.Fabric)

if(forgeModule == null) {
throw new AssetGuardError('No Forge module found!')
if(modLoaderModule == null) {
throw new AssetGuardError('No mod loader found!')
}

if(DistributionIndexProcessor.isForgeGradle3(server.rawServer.minecraftVersion, forgeModule.getMavenComponents().version)) {

const versionManifstModule = forgeModule.subModules.find(({ rawModule: { type }}) => type === Type.VersionManifest)
if(versionManifstModule == null) {
throw new AssetGuardError('No Forge version manifest module found!')
}

// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return await readJson(versionManifstModule.getPath(), 'utf-8')

if(modLoaderModule.rawModule.type === Type.Fabric
|| DistributionIndexProcessor.isForgeGradle3(server.rawServer.minecraftVersion, modLoaderModule.getMavenComponents().version)) {
return await this.loadVersionManifest<VersionJsonBase>(modLoaderModule)
} else {

const zip = new StreamZip.async({ file: forgeModule.getPath() })
const zip = new StreamZip.async({ file: modLoaderModule.getPath() })

try {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const data = JSON.parse((await zip.entryData('version.json')).toString('utf8'))
const writePath = getVersionJsonPath(this.commonDir, data.id as string)

const data = JSON.parse((await zip.entryData('version.json')).toString('utf8')) as VersionJsonBase
const writePath = getVersionJsonPath(this.commonDir, data.id)

await ensureDir(dirname(writePath))
await writeJson(writePath, data)

// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return data
}
finally {
Expand All @@ -114,6 +106,15 @@ export class DistributionIndexProcessor extends IndexProcessor {
}
}

public async loadVersionManifest<T>(modLoaderModule: HeliosModule): Promise<T> {
const versionManifstModule = modLoaderModule.subModules.find(({ rawModule: { type }}) => type === Type.VersionManifest)
if(versionManifstModule == null) {
throw new AssetGuardError('No mod loader version manifest module found!')
}

return await readJson(versionManifstModule.getPath(), 'utf-8') as T
}

// TODO Move this to a util maybe
public static isForgeGradle3(mcVersion: string, forgeVersion: string): boolean {

Expand Down
20 changes: 10 additions & 10 deletions lib/dl/mojang/MojangIndexProcessor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ensureDir, pathExists, readFile, readJson, writeFile } from 'fs-extra'
import { Asset, HashAlgo } from '../Asset'
import { AssetGuardError } from '../AssetGuardError'
import { IndexProcessor } from '../IndexProcessor'
import { AssetIndex, LibraryArtifact, MojangVersionManifest, VersionJson } from './MojangTypes'
import { AssetIndex, LibraryArtifact, MojangVersionManifest, VersionJsonBase } from './MojangTypes'
import { calculateHashByBuffer, getLibraryDir, getVersionJarPath, getVersionJsonPath, validateLocalFile } from '../../common/util/FileUtils'
import { getMojangOS, isLibraryCompatible } from '../../common/util/MojangUtils'
import { LoggerUtil } from '../../util/LoggerUtil'
Expand All @@ -19,7 +19,7 @@ export class MojangIndexProcessor extends IndexProcessor {

private static readonly logger = LoggerUtil.getLogger('MojangIndexProcessor')

private versionJson!: VersionJson
private versionJson!: VersionJsonBase
private assetIndex!: AssetIndex
private client = got.extend({
responseType: 'json'
Expand Down Expand Up @@ -67,12 +67,12 @@ export class MojangIndexProcessor extends IndexProcessor {
}

// Can be called without init - needed for launch process.
public async getVersionJson(): Promise<VersionJson> {
public async getVersionJson(): Promise<VersionJsonBase> {
const versionManifest = await this.loadVersionManifest()
return await this.loadVersionJson(this.version, versionManifest)
}

private async loadAssetIndex(versionJson: VersionJson): Promise<AssetIndex> {
private async loadAssetIndex(versionJson: VersionJsonBase): Promise<AssetIndex> {
const assetIndexPath = this.getAssetIndexPath(versionJson.assetIndex.id)
const assetIndex = await this.loadContentWithRemoteFallback<AssetIndex>(versionJson.assetIndex.url, assetIndexPath, { algo: HashAlgo.SHA1, value: versionJson.assetIndex.sha1 })
if(assetIndex == null) {
Expand All @@ -81,14 +81,14 @@ export class MojangIndexProcessor extends IndexProcessor {
return assetIndex
}

private async loadVersionJson(version: string, versionManifest: MojangVersionManifest | null): Promise<VersionJson> {
private async loadVersionJson(version: string, versionManifest: MojangVersionManifest | null): Promise<VersionJsonBase> {
const versionJsonPath = getVersionJsonPath(this.commonDir, version)
if(versionManifest != null) {
const versionInfo = versionManifest.versions.find(({ id }) => id === version)
if(versionInfo == null) {
throw new AssetGuardError(`Invalid version: ${version}.`)
}
const versionJson = await this.loadContentWithRemoteFallback<VersionJson>(versionInfo.url, versionJsonPath, { algo: HashAlgo.SHA1, value: versionInfo.sha1 })
const versionJson = await this.loadContentWithRemoteFallback<VersionJsonBase>(versionInfo.url, versionJsonPath, { algo: HashAlgo.SHA1, value: versionInfo.sha1 })
if(versionJson == null) {
throw new AssetGuardError(`Failed to download ${version} json index.`)
}
Expand All @@ -98,7 +98,7 @@ export class MojangIndexProcessor extends IndexProcessor {
} else {
// Attempt to find local index.
if(await pathExists(versionJsonPath)) {
return await readJson(versionJsonPath) as VersionJson
return await readJson(versionJsonPath) as VersionJsonBase
} else {
throw new AssetGuardError(`Unable to load version manifest and ${version} json index does not exist locally.`)
}
Expand Down Expand Up @@ -204,7 +204,7 @@ export class MojangIndexProcessor extends IndexProcessor {

}

private async validateLibraries(versionJson: VersionJson): Promise<Asset[]> {
private async validateLibraries(versionJson: VersionJsonBase): Promise<Asset[]> {

const libDir = getLibraryDir(this.commonDir)
const notValid: Asset[] = []
Expand Down Expand Up @@ -241,7 +241,7 @@ export class MojangIndexProcessor extends IndexProcessor {
return notValid
}

private async validateClient(versionJson: VersionJson): Promise<Asset[]> {
private async validateClient(versionJson: VersionJsonBase): Promise<Asset[]> {

const version = versionJson.id
const versionJarPath = getVersionJarPath(this.commonDir, version)
Expand All @@ -262,7 +262,7 @@ export class MojangIndexProcessor extends IndexProcessor {

}

private async validateLogConfig(versionJson: VersionJson): Promise<Asset[]> {
private async validateLogConfig(versionJson: VersionJsonBase): Promise<Asset[]> {

const logFile = versionJson.logging.client.file
const path = join(this.assetPath, 'log_configs', logFile.id)
Expand Down
29 changes: 20 additions & 9 deletions lib/dl/mojang/MojangTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,8 @@ export interface Library {
rules?: Rule[]
}

export interface VersionJson {
export interface VersionJsonBase {

arguments: {
game: string[]
jvm: {
rules: Rule[]
value: string[]
}[]
}
assetIndex: {
id: string
sha1: string
Expand All @@ -70,6 +63,10 @@ export interface VersionJson {
server: BaseArtifact
}
id: string
/**
* Only on modloader version properties (extend and override base version)
*/
inheritsFrom?: string
libraries: Library[]
logging: {
client: {
Expand All @@ -84,11 +81,25 @@ export interface VersionJson {
}
}
mainClass: string
minimumLauncherVersion: number
releaseTime: string
time: string
type: string
}

export interface VersionJsonLegacy extends VersionJsonBase {
minecraftArguments: string
}

export interface VersionJsonNew extends VersionJsonBase {
arguments: {
game: (string | RuleBasedArgument)[]
jvm: (string | RuleBasedArgument)[]
}
}

export interface RuleBasedArgument {
rules: Rule[]
value: string | string[]
}

export interface AssetIndex {
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"chai-as-promised": "^7.1.1",
"cross-env": "^7.0.3",
"eslint": "^8.50.0",
"helios-distribution-types": "^1.2.0",
"helios-distribution-types": "^1.3.0",
"mocha": "^10.2.0",
"nock": "^13.3.3",
"rimraf": "^5.0.5",
Expand Down