feat: replace console.log with events

This commit is contained in:
HerozDotExe 2026-03-21 23:56:50 +01:00
parent 96bf0456a1
commit eb380f9403
10 changed files with 69 additions and 36 deletions

View file

@ -1,14 +1,15 @@
import { version as packageVersion } from "../../package.json";
import { spawn } from "child_process";
import { LaunchArguments } from "../utils/types";
import { LaunchArguments, logger } from "../utils/types";
export function launch(
launchArguments: LaunchArguments,
gameRoot: string,
logger: logger,
detached = false,
) {
console.log(`[nlk ${packageVersion}] Working directory : ${gameRoot}`);
console.log(
logger("launch", `[nlk ${packageVersion}] Working directory : ${gameRoot}`);
logger("launch",
`[nlk ${packageVersion}] Launching command : ${launchArguments.command} ${launchArguments.args.join(" ")}`,
);

View file

@ -6,7 +6,6 @@ export function mergeManifests(base: Version, layer: Version) {
const result = { ...base }
result.libraries = [];
result.mainClass = layer.mainClass;
console.log(base)
// const librariesNames = base.libraries.map(
// (lib) => {

View file

@ -1,7 +1,7 @@
import path from "path";
import { downloadFile } from "../utils/fetch";
import { getTempFolder } from "../utils/temp";
import { LauncherProfiles, Modloader, Version } from "../utils/types";
import { LauncherProfiles, logger, Modloader, Version } from "../utils/types";
import fs from "fs/promises";
import { spawn } from "child_process";
import { version as packageVersion } from "../../package.json";
@ -68,9 +68,11 @@ export function runForgeInstaller(
javaExecutable: string,
forgeInstallerPath: string,
fakeLauncher: string,
installType: "Client" | "Server"
installType: "Client" | "Server",
logger: logger
) {
console.log(
logger(
"forge",
`[nlk ${packageVersion}] Running forge installer : "${javaExecutable} -jar ${forgeInstallerPath} --install${installType} ${path.join(fakeLauncher)}"`,
);
const forgeInstaller = spawn(javaExecutable, [
@ -81,11 +83,11 @@ export function runForgeInstaller(
], { cwd: fakeLauncher });
forgeInstaller.stdout.on("data", (data: Buffer) =>
console.log(data.toString()),
logger("forge", data.toString()),
);
forgeInstaller.stderr.on("data", (data: Buffer) =>
console.log(data.toString()),
logger("forge", data.toString()),
);
return new Promise<void>((res, rej) => {
@ -118,7 +120,8 @@ export interface ModloaderConfig extends Config {
export async function installForge(
config: ModloaderConfig,
versionManifest: Version
versionManifest: Version,
logger: logger
) {
const forgeLibDir = path.join(config.paths.root, "libraries", "net", "minecraftforge", "forge", `${versionManifest.id}-${config.modloader.version}`)
const neoForgeLibDir = path.join(config.paths.root, "libraries", "net", "neoforged", "neoforge", `${config.modloader.version}`)
@ -147,7 +150,7 @@ export async function installForge(
const modernInstaller = isModernForge(versionManifest.id)
await runForgeInstaller(config.javaExecutable, forgeInstallerPath, fakeLauncher, modernInstaller ? "Client" : "Server");
await runForgeInstaller(config.javaExecutable, forgeInstallerPath, fakeLauncher, modernInstaller ? "Client" : "Server", logger);
// Copy libraries and versions files
for (const file of await fs.readdir(path.join(fakeLauncher, "libraries"))) {

View file

@ -1,5 +1,5 @@
import { EventEmitter } from "node:stream";
import { Auth, InstanceEvents, Modloader, Paths, ProcessArgs, ProcessRam, Version } from "../utils/types";
import { Auth, InstanceEvents, logger, Modloader, Paths, ProcessArgs, ProcessRam, Version } from "../utils/types";
import path from "node:path";
import { argumentsGenerator, AssetsDownloader, launch, LibrariesDownloader, NativesDownloader, version } from "../core";
import { ConfigError, InstallError, LaunchError } from "../utils/errors";
@ -25,13 +25,13 @@ export interface Config extends BaseConfig {
ram: Required<ProcessRam>
}
export function defineConfig(...layers: Partial<BaseConfig>[]) {
export function defineConfig(logger: logger, ...layers: Partial<BaseConfig>[]) {
let config: Partial<BaseConfig> = {} as Partial<BaseConfig>;
for (const layer of layers) {
config = { ...config, ...layer }
}
if (!config.auth || !config.paths?.root || !config.paths?.instance || !config.version || !config.javaExecutable) {
throw new ConfigError("Invalid config provided", config)
throw new ConfigError("Invalid config provided", config, logger)
}
config.paths = {
@ -54,16 +54,26 @@ export class Instance extends EventEmitter<InstanceEvents> {
config: Config
versionLocation: string
versionManifest: Version
logger: logger
constructor(...layers: Partial<BaseConfig>[]) {
super()
this.config = defineConfig(...layers)
this.logger = (step: string, message: unknown) => {
this.emit("log", step, message)
}
this.config = defineConfig(this.logger, ...layers)
this.ready = false
this.versionManifest = {} as Version
this.versionLocation = ""
}
private async log(step: string, message: unknown) {
this.emit("log", step, message)
}
private async init() {
this.log("init", "Initializing instance")
this.versionLocation = path.join(this.config.paths.versions, this.config.version);
if (this.config.modloader) {
@ -87,7 +97,7 @@ export class Instance extends EventEmitter<InstanceEvents> {
this.versionLocation,
);
} catch (error) {
throw new InstallError("An error occured while initializing instance", "install-init", this.config, { cause: error })
throw new InstallError("An error occured while initializing instance", "install-init", this.config, this.logger, { cause: error })
}
try {
@ -109,7 +119,7 @@ export class Instance extends EventEmitter<InstanceEvents> {
await librariesDownloader.run();
} catch (error) {
throw new InstallError("An error occured while downloading libraries", "libraries", this.config, { cause: error })
throw new InstallError("An error occured while downloading libraries", "libraries", this.config, this.logger, { cause: error })
}
try {
@ -131,7 +141,7 @@ export class Instance extends EventEmitter<InstanceEvents> {
await assetsDownloader.run();
} catch (error) {
throw new InstallError("An error occured while downloading assets", "assets", this.config, { cause: error })
throw new InstallError("An error occured while downloading assets", "assets", this.config, this.logger, { cause: error })
}
try {
@ -151,12 +161,12 @@ export class Instance extends EventEmitter<InstanceEvents> {
});
await nativesDownloader.run();
} catch (error) {
throw new InstallError("An error occured while downloadng natives", "natives", this.config, { cause: error })
throw new InstallError("An error occured while downloadng natives", "natives", this.config, this.logger, { cause: error })
}
const javaError = await checkJava(this.config.javaExecutable)
if (javaError) {
throw new InstallError("Invalid java provieded", "java", this.config, { cause: javaError })
throw new InstallError("Invalid java provided", "java", this.config, this.logger, { cause: javaError })
}
if (this.config.modloader) {
@ -166,14 +176,15 @@ export class Instance extends EventEmitter<InstanceEvents> {
case "neoforge":
await installForge(
this.config as ModloaderConfig,
this.versionManifest
this.versionManifest,
this.logger
);
break;
default:
throw new Error("Unknown modloader");
}
} catch (error) {
throw new InstallError("An error occured while installing the modloader", "modloader", this.config, { cause: error })
throw new InstallError("An error occured while installing the modloader", "modloader", this.config, this.logger, { cause: error })
}
}
}
@ -182,7 +193,7 @@ export class Instance extends EventEmitter<InstanceEvents> {
try {
if (!this.ready) await this.init()
} catch (error) {
throw new LaunchError("An error occured while initializing instance", "launch-init", this.config, { cause: error })
throw new LaunchError("An error occured while initializing instance", "launch-init", this.config, this.logger, { cause: error })
}
if (this.config.modloader) {
@ -223,7 +234,7 @@ export class Instance extends EventEmitter<InstanceEvents> {
throw new Error("Unknown modloader");
}
} catch (error) {
throw new LaunchError("An error occured while preparing the modloader", "modloader", this.config, { cause: error })
throw new LaunchError("An error occured while preparing the modloader", "modloader", this.config, this.logger, { cause: error })
}
}
@ -235,15 +246,15 @@ export class Instance extends EventEmitter<InstanceEvents> {
);
} catch (error) {
throw new LaunchError("An error occured while generating launch arguments", "arguments", this.config, { cause: error })
throw new LaunchError("An error occured while generating launch arguments", "arguments", this.config, this.logger, { cause: error })
}
try {
const process = launch(args!, this.config.paths.instance);
const process = launch(args!, this.config.paths.instance, this.logger);
return process;
} catch (error) {
throw new LaunchError("An error occured while launching minecraft", "launch-process", this.config, { cause: error })
throw new LaunchError("An error occured while launching minecraft", "launch-process", this.config, this.logger, { cause: error })
}
}
}

View file

@ -1,19 +1,20 @@
import { BaseConfig, Config } from "../launcher/instance"
import { logger } from "./types"
export class ConfigError extends Error {
constructor(message: string, config: Partial<BaseConfig>, options?: ErrorOptions) {
constructor(message: string, config: Partial<BaseConfig>, logger: logger, options?: ErrorOptions) {
super(message, options)
console.log("Provided config was:")
console.log(config)
logger("error", "Provided config was:")
logger("error", config)
}
}
export class InstallError extends Error {
constructor(message: string, step: string, config: Config, options?: ErrorOptions) {
constructor(message: string, step: string, config: Config, logger: logger, options?: ErrorOptions) {
super(`[${step}] ${message}`, options)
console.log("Provided config was:")
console.log(config)
logger("error", "Provided config was:")
logger("error", config)
}
}
export class LaunchError extends InstallError {}
export class LaunchError extends InstallError { }

View file

@ -229,7 +229,11 @@ export interface InstanceEvents {
total: number,
doneSize: number,
totalSize: number,
];
],
log: [
step: string,
message: unknown
]
}
export type ProcessArgs = {
@ -240,4 +244,6 @@ export type ProcessArgs = {
export type ProcessRam = {
max?: string,
min?: string
}
}
export type logger = (step: string, message: unknown) => void

View file

@ -24,6 +24,9 @@ test("launch game", { timeout: 0, tags: ["full", "forge"] }, async () => {
});
instance.on("progress", console.log);
instance.on("log", (step, msg) => {
console.log(`[${step}] ${msg}`)
})
await instance.install();
const p = await instance.launch();

View file

@ -24,6 +24,9 @@ test("launch game", { timeout: 0, tags: ["full", "vanilla"] }, async () => {
});
instance.on("progress", console.log);
instance.on("log", (step, msg) => {
console.log(`[${step}] ${msg}`)
})
await instance.install();
const p = await instance.launch();

View file

@ -20,6 +20,9 @@ test("launch game", { timeout: 0, tags: ["full", "forge"] }, async () => {
});
instance.on("progress", console.log);
instance.on("log", (step, msg) => {
console.log(`[${step}] ${msg}`)
})
await instance.install();
const p = await instance.launch();

View file

@ -20,6 +20,9 @@ test("launch game", { timeout: 0, tags: ["full", "forge"] }, async () => {
});
instance.on("progress", console.log);
instance.on("log", (step, msg) => {
console.log(`[${step}] ${msg}`)
})
await instance.install();
const p = await instance.launch();