diff --git a/src/core/launch.ts b/src/core/launch.ts index 9469984..4c14239 100644 --- a/src/core/launch.ts +++ b/src/core/launch.ts @@ -1,3 +1,4 @@ +import { version as packageVersion } from "../../package.json"; import { spawn } from "child_process"; import { LaunchArguments } from "../utils/types"; @@ -6,9 +7,9 @@ export function launch( gameRoot: string, detached = false, ) { - console.log(`Working directory : ${gameRoot}`); + console.log(`[nlk ${packageVersion}] Working directory : ${gameRoot}`); console.log( - `Launching command : ${launchArguments.command} ${launchArguments.args.join(" ")}`, + `[nlk ${packageVersion}] Launching command : ${launchArguments.command} ${launchArguments.args.join(" ")}`, ); const process = spawn(launchArguments.command, launchArguments.args, { detached, diff --git a/src/instance/instance.ts b/src/instance/instance.ts index 9bfc977..6459944 100644 --- a/src/instance/instance.ts +++ b/src/instance/instance.ts @@ -3,6 +3,7 @@ import * as core from "../core"; import path from "path"; import { os, arch } from "../utils/systemInfo"; import { EventEmitter } from "node:events"; +import { InstallError, LaunchError } from "../utils/errors"; function getJavaOs() { switch (os()) { @@ -38,7 +39,13 @@ function getJavaOs() { } interface InstanceEvents { - progress: [type: string, done: number, total: number, doneSize: number, totalSize: number]; + progress: [ + type: string, + done: number, + total: number, + doneSize: number, + totalSize: number, + ]; } export class Instance extends EventEmitter { @@ -48,11 +55,13 @@ export class Instance extends EventEmitter { paths: Paths; args: { java: string; game: string }; versionManifest: Version; - javaLocation?: string + javaLocation?: string; + ready: boolean; constructor() { super(); this.args = { java: "", game: "" }; + this.ready = false; } setVersion(version: string) { @@ -97,93 +106,152 @@ export class Instance extends EventEmitter { this.args.game = game || ""; } - async install() { + async initialize() { this.versionManifest = await core.version.getVersionManifest( this.version, this.paths.version, ); - await core.version.downloadJar(this.versionManifest, this.paths.version); - const librariesDownloader = await core.LibrariesDownloader( - this.paths.libraries, - this.versionManifest, - ); - librariesDownloader.on("completed", () => { - this.emit( - "progress", - "libraries", - librariesDownloader.done, - librariesDownloader.total, - librariesDownloader.doneSize, - librariesDownloader.totalSize, - ); - }); - await librariesDownloader.run(); - - const assetsDownloader = await core.AssetsDownloader( - this.paths.assets, - this.versionManifest, - ); - assetsDownloader.on("completed", () => { - this.emit( - "progress", - "assets", - assetsDownloader.done, - assetsDownloader.total, - assetsDownloader.doneSize, - assetsDownloader.totalSize, - ); - }); - await assetsDownloader.run(); - - const nativesDownloader = await core.NativesDownloader( - this.paths.natives, - this.versionManifest, - ); - nativesDownloader.on("completed", () => { - this.emit( - "progress", - "natives", - nativesDownloader.done, - nativesDownloader.total, - nativesDownloader.doneSize, - nativesDownloader.totalSize, - ); - }); - await nativesDownloader.run(); - - this.javaLocation = path.join(this.paths.javaRoot, this.versionManifest.javaVersion.component) - - const javaDownloader = await core.java.JavaDownloader( - getJavaOs(), - this.versionManifest.javaVersion.component, + this.javaLocation = path.join( this.paths.javaRoot, + this.versionManifest.javaVersion.component, ); - javaDownloader.on("completed", () => { - this.emit( - "progress", - "java", - javaDownloader.done, - javaDownloader.total, - javaDownloader.doneSize, - javaDownloader.totalSize, + } + + async install() { + try { + await this.initialize(); + this.ready = true; + await core.version.downloadJar(this.versionManifest, this.paths.version); + } catch (original) { + const error = new InstallError("version", original); + error.throw(); + } + + try { + const librariesDownloader = await core.LibrariesDownloader( + this.paths.libraries, + this.versionManifest, ); - }); - await javaDownloader.run(); + + librariesDownloader.on("completed", () => { + this.emit( + "progress", + "libraries", + librariesDownloader.done, + librariesDownloader.total, + librariesDownloader.doneSize, + librariesDownloader.totalSize, + ); + }); + await librariesDownloader.run(); + } catch (original) { + const error = new InstallError("libraries", original); + error.throw(); + } + + try { + const assetsDownloader = await core.AssetsDownloader( + this.paths.assets, + this.versionManifest, + ); + assetsDownloader.on("completed", () => { + this.emit( + "progress", + "assets", + assetsDownloader.done, + assetsDownloader.total, + assetsDownloader.doneSize, + assetsDownloader.totalSize, + ); + }); + await assetsDownloader.run(); + } catch (original) { + const error = new InstallError("assets", original); + error.throw(); + } + + try { + const nativesDownloader = await core.NativesDownloader( + this.paths.natives, + this.versionManifest, + ); + nativesDownloader.on("completed", () => { + this.emit( + "progress", + "natives", + nativesDownloader.done, + nativesDownloader.total, + nativesDownloader.doneSize, + nativesDownloader.totalSize, + ); + }); + await nativesDownloader.run(); + } catch (original) { + const error = new InstallError("natives", original); + error.throw(); + } + + try { + const javaDownloader = await core.java.JavaDownloader( + getJavaOs(), + this.versionManifest.javaVersion.component, + this.paths.javaRoot, + ); + javaDownloader.on("completed", () => { + this.emit( + "progress", + "java", + javaDownloader.done, + javaDownloader.total, + javaDownloader.doneSize, + javaDownloader.totalSize, + ); + }); + await javaDownloader.run(); + } catch (original) { + const error = new InstallError("java", original); + error.throw(); + } } async launch() { - const args = await core.arguments.generateLaunchArguments( - await core.version.getVersionManifest(this.version, this.paths.version), - this.javaLocation, - this.paths.root, - this.paths.version, - this.auth, - { customGameArgs: this.args.game, customJvmArgs: this.args.java }, - ); + try { + if (!this.ready) { + try { + await this.initialize(); + } catch (original) { + const error = new InstallError("version", original); + error.throw(); + } + } - const process = core.launch(args, this.paths.root); + const args = await core.arguments.generateLaunchArguments( + await core.version.getVersionManifest(this.version, this.paths.version), + this.javaLocation, + this.paths.root, + this.paths.version, + this.auth, + { customGameArgs: this.args.game, customJvmArgs: this.args.java }, + ); - return process; + const process = core.launch(args, this.paths.root); + + return process; + } catch (original) { + const error = new LaunchError( + { + version: this.version, + versionPath: this.paths.version, + javaLocation: this.javaLocation, + rootPath: this.paths.root, + auth: this.auth, + customGameArgs: this.args.game, + customJvmArgs: this.args.java, + }, + original, + ); + error.throw(); + } } } diff --git a/src/utils/errors.ts b/src/utils/errors.ts new file mode 100644 index 0000000..a6197a3 --- /dev/null +++ b/src/utils/errors.ts @@ -0,0 +1,44 @@ +import { version as packageVersion } from "../../package.json"; +import { LaunchErrorInfos } from "./types"; + +export class InstallError extends Error { + step: string; + original: Error; + constructor(step: string, original: Error) { + super(); + this.step = step; + this.original = original; + } + + throw() { + console.error( + `[nlk ${packageVersion}] Error occured when installing ${this.step}: ${this.original.message}`, + ); + console.error(`[nlk ${packageVersion}] Original error is:`, this.original); + + throw this; + } +} + +export class LaunchError extends Error { + infos: LaunchErrorInfos; + original: Error; + constructor( + infos: LaunchErrorInfos, + original: Error, + ) { + super(); + this.infos = infos; + this.original = original; + } + + throw() { + console.error( + `[nlk ${packageVersion}] Error occured when launching the game: ${this.original.message}`, + ); + console.error(`[nlk ${packageVersion}] Original error is:`, this.original); + console.dir(this.infos); + + throw this; + } +} diff --git a/src/utils/types.ts b/src/utils/types.ts index d301f83..3cebca3 100644 --- a/src/utils/types.ts +++ b/src/utils/types.ts @@ -185,4 +185,14 @@ export type Paths = { libraries?: string natives?: string javaRoot?: string -} \ No newline at end of file +} + +export type LaunchErrorInfos = { + version: string; + versionPath: string; + javaLocation: string; + rootPath: string; + auth: Auth; + customGameArgs: string; + customJvmArgs: string; + } \ No newline at end of file