Reewrite project #430
82
package-lock.json
generated
82
package-lock.json
generated
@ -9,7 +9,7 @@
|
||||
"version": "4.0.0",
|
||||
"license": "GPL-3.0",
|
||||
"dependencies": {
|
||||
"@the-bds-maneger/server_versions": "^3.0.0",
|
||||
"@the-bds-maneger/server_versions": "^3.0.1",
|
||||
"adm-zip": "^0.5.9",
|
||||
"axios": "^0.27.2",
|
||||
"cron": "^2.1.0",
|
||||
@ -20,7 +20,7 @@
|
||||
"@types/adm-zip": "^0.5.0",
|
||||
"@types/cron": "^2.0.0",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@types/node": "^18.7.13",
|
||||
"@types/node": "^18.7.14",
|
||||
"@types/tar": "^6.1.2",
|
||||
"mocha": "^10.0.0",
|
||||
"ts-node": "^10.9.1",
|
||||
@ -68,9 +68,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@the-bds-maneger/server_versions": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@the-bds-maneger/server_versions/-/server_versions-3.0.0.tgz",
|
||||
"integrity": "sha512-+t2r7+iJHNbcF1A3o953Dcxm3LLN138tiC7CMWAa7IoJFhpqjYZcijlJEUZ4y6ueTE59yqtwninOtmRnhrqE/g==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@the-bds-maneger/server_versions/-/server_versions-3.0.1.tgz",
|
||||
"integrity": "sha512-PRpmjigZlfOtjVKE5371ZF0vjDV30L256hohAZYeoIWuHxzpSi6oJdT3gGp/qyUsXJ7r7Ac7A9OnFGJqgkwk5g==",
|
||||
"dependencies": {
|
||||
"axios": "^0.27.2",
|
||||
"cors": "^2.8.5",
|
||||
@ -145,9 +145,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "18.7.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz",
|
||||
"integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw=="
|
||||
"version": "18.7.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.14.tgz",
|
||||
"integrity": "sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA=="
|
||||
},
|
||||
"node_modules/@types/tar": {
|
||||
"version": "6.1.2",
|
||||
@ -160,9 +160,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/@types/webidl-conversions": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
|
||||
"integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||
"integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog=="
|
||||
},
|
||||
"node_modules/@types/whatwg-url": {
|
||||
"version": "8.2.2",
|
||||
@ -787,9 +787,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
|
||||
"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
@ -1758,15 +1758,6 @@
|
||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/mocha/node_modules/diff": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
|
||||
"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/mocha/node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
@ -2543,6 +2534,15 @@
|
||||
"node": ">=0.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ts-node/node_modules/diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.3.1"
|
||||
}
|
||||
},
|
||||
"node_modules/type-check": {
|
||||
"version": "0.3.2",
|
||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
|
||||
@ -2896,9 +2896,9 @@
|
||||
}
|
||||
},
|
||||
"@the-bds-maneger/server_versions": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@the-bds-maneger/server_versions/-/server_versions-3.0.0.tgz",
|
||||
"integrity": "sha512-+t2r7+iJHNbcF1A3o953Dcxm3LLN138tiC7CMWAa7IoJFhpqjYZcijlJEUZ4y6ueTE59yqtwninOtmRnhrqE/g==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/@the-bds-maneger/server_versions/-/server_versions-3.0.1.tgz",
|
||||
"integrity": "sha512-PRpmjigZlfOtjVKE5371ZF0vjDV30L256hohAZYeoIWuHxzpSi6oJdT3gGp/qyUsXJ7r7Ac7A9OnFGJqgkwk5g==",
|
||||
"requires": {
|
||||
"axios": "^0.27.2",
|
||||
"cors": "^2.8.5",
|
||||
@ -2970,9 +2970,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "18.7.13",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz",
|
||||
"integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw=="
|
||||
"version": "18.7.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.14.tgz",
|
||||
"integrity": "sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA=="
|
||||
},
|
||||
"@types/tar": {
|
||||
"version": "6.1.2",
|
||||
@ -2985,9 +2985,9 @@
|
||||
}
|
||||
},
|
||||
"@types/webidl-conversions": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
|
||||
"integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||
"integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog=="
|
||||
},
|
||||
"@types/whatwg-url": {
|
||||
"version": "8.2.2",
|
||||
@ -3450,9 +3450,9 @@
|
||||
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
|
||||
},
|
||||
"diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
|
||||
"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
|
||||
"dev": true
|
||||
},
|
||||
"domexception": {
|
||||
@ -4140,12 +4140,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"diff": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
|
||||
"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
|
||||
"dev": true
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||
@ -4712,6 +4706,12 @@
|
||||
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
|
||||
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
|
||||
"dev": true
|
||||
},
|
||||
"diff": {
|
||||
"version": "4.0.2",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -30,7 +30,7 @@
|
||||
"node": ">=16.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"@the-bds-maneger/server_versions": "^3.0.0",
|
||||
"@the-bds-maneger/server_versions": "^3.0.1",
|
||||
"adm-zip": "^0.5.9",
|
||||
"axios": "^0.27.2",
|
||||
"cron": "^2.1.0",
|
||||
@ -41,7 +41,7 @@
|
||||
"@types/adm-zip": "^0.5.0",
|
||||
"@types/cron": "^2.0.0",
|
||||
"@types/mocha": "^9.1.1",
|
||||
"@types/node": "^18.7.13",
|
||||
"@types/node": "^18.7.14",
|
||||
"@types/tar": "^6.1.2",
|
||||
"mocha": "^10.0.0",
|
||||
"ts-node": "^10.9.1",
|
||||
|
@ -86,7 +86,5 @@ export async function startServer() {
|
||||
else throw new Error("Cannot emulate x64 architecture. Check the documentents in \"https://github.com/The-Bds-Maneger/Bds-Maneger-Core/wiki/Server-Platforms#minecraft-bedrock-server-alpha\"");
|
||||
}
|
||||
|
||||
const serverProcess = exec(command, args, {cwd: serverPath, maxBuffer: Infinity, env: {LD_LIBRARY_PATH: process.platform === "win32"?undefined:serverPath}});
|
||||
const serverActions = new actions(serverProcess, serverConfig);
|
||||
return {serverProcess, serverActions};
|
||||
return new actions(exec(command, args, {cwd: serverPath, maxBuffer: Infinity, env: {LD_LIBRARY_PATH: process.platform === "win32"?undefined:serverPath}}), serverConfig);
|
||||
}
|
@ -28,8 +28,7 @@ export function execFileAsync(command: string, args?: execOptions|string[], opti
|
||||
|
||||
export class customChild {
|
||||
private eventMiter = new EventEmitter({captureRejections: false});
|
||||
private tempLog = {};
|
||||
private child?: ChildProcess;
|
||||
public child?: ChildProcess;
|
||||
|
||||
public kill(signal?: number|NodeJS.Signals) {if(this.child?.killed) return this.child?.killed;return this.child?.kill(signal);}
|
||||
public writeStdin(command: string, args?: string[]) {
|
||||
@ -61,17 +60,24 @@ export class customChild {
|
||||
public once(act: "breakStderr", fn: (data: string) => void): this;
|
||||
public once(act: string, fn: (...args: any[]) => void): this {this.eventMiter.once(act, fn);return this;}
|
||||
|
||||
private tempLog = {};
|
||||
constructor(child: ChildProcess) {
|
||||
this.child = child;
|
||||
child.on("close", (code, signal) => this.emit("close", {code, signal}));
|
||||
child.on("exit", (code, signal) => this.emit("close", {code, signal}));
|
||||
child.on("error", err => this.emit("error", err));
|
||||
child.stdout.on("data", data => this.eventMiter.emit("stdoutRaw", data instanceof Buffer ? data.toString("utf8"):data));
|
||||
child.stderr.on("data", data => this.eventMiter.emit("stderrRaw", data instanceof Buffer ? data.toString("utf8"):data));
|
||||
// Storage tmp lines
|
||||
const parseLog = (to: "breakStdout"|"breakStderr", data: string): any => {
|
||||
if (this.tempLog[to] === undefined) this.tempLog[to] = "";
|
||||
const lines = data.split(/\r?\n/);
|
||||
if (lines.length === 1) return this.tempLog[to] += lines[0];
|
||||
for (const line of lines.slice(0, -1)) {
|
||||
if (lines.length === 1) {
|
||||
if (this.tempLog[to] === undefined) this.tempLog[to] = "";
|
||||
return this.tempLog[to] += lines[0];
|
||||
}
|
||||
const a = lines.pop();
|
||||
if (a !== "") lines.push(a);
|
||||
for (const line of lines) {
|
||||
if (!this.tempLog[to]) return this.eventMiter.emit(to, line);
|
||||
this.eventMiter.emit(to, this.tempLog[to]+line);
|
||||
delete this.tempLog[to];
|
||||
@ -79,8 +85,6 @@ export class customChild {
|
||||
}
|
||||
child.stdout.on("data", data => parseLog("breakStdout", data));
|
||||
child.stderr.on("data", data => parseLog("breakStderr", data));
|
||||
child.stdout.on("data", data => this.eventMiter.emit("stdoutRaw", data instanceof Buffer ? data.toString("utf8"):data));
|
||||
child.stderr.on("data", data => this.eventMiter.emit("stderrRaw", data instanceof Buffer ? data.toString("utf8"):data));
|
||||
}
|
||||
};
|
||||
|
||||
@ -92,7 +96,7 @@ export function exec(command: string, args?: ObjectEncodingOptions & ExecFileOpt
|
||||
let childOptions: ObjectEncodingOptions & ExecFileOptions = {};
|
||||
let childArgs: string[] = [];
|
||||
if (args instanceof Array) childArgs = args; else if (args instanceof Object) childOptions = args as execOptions;
|
||||
if (!options) childOptions = options;
|
||||
if (options) childOptions = options;
|
||||
if (childOptions?.env) childOptions.env = {...process.env, ...childOptions.env};
|
||||
return new customChild(execFile(command, childArgs, childOptions));
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import type { customChild } from "./childPromisses";
|
||||
import { EventEmitter } from "node:events";
|
||||
|
||||
export type playerClass = {[player: string]: {action: "connect"|"disconnect"|"unknown"; date: Date; history: Array<{action: "connect"|"disconnect"|"unknown"; date: Date}>}};
|
||||
export type playerBase = {playerName: string, connectTime: Date, xuid?: string};
|
||||
export type actionsPlayer = {
|
||||
name: "playerConnect"|"playerDisconnect"|"playerUnknown",
|
||||
@ -19,22 +20,104 @@ export type actionsServerStarted = {
|
||||
callback: (data: string, done: (started: serverStarted) => void) => void
|
||||
}
|
||||
|
||||
export type actionConfig = actionsPlayer|actionsPort|actionsServerStarted|actionsServerStarted;
|
||||
export type actionsServerStop = {
|
||||
name: "serverStop",
|
||||
run: (childProcess: customChild) => void
|
||||
}
|
||||
|
||||
export type actionTp = {
|
||||
name: "tp",
|
||||
run: (childProcess: customChild, x: number|string, y: number|string, z: number|string) => void
|
||||
}
|
||||
|
||||
export type actionRun = actionsServerStop|actionTp;
|
||||
export type actionCallback = actionsPlayer|actionsPort|actionsServerStarted|actionsServerStarted;
|
||||
export type actionConfig = actionCallback|actionRun;
|
||||
export class actions {
|
||||
private events = new EventEmitter({captureRejections: false});
|
||||
private childProcess: customChild;
|
||||
private stopServerFunction?: (childProcess: customChild) => void;
|
||||
private tpfunction?: (childProcess: customChild, x: number|string, y: number|string, z: number|string) => void;
|
||||
|
||||
on(act: "playerConnect"|"playerDisconnect"|"playerUnknown", fn: (data: playerBase) => void): this;
|
||||
on(act: "portListening", fn: (data: portListen) => void): this;
|
||||
on(act: "serverStarted", fn: (data: serverStarted) => void): this;
|
||||
on(act: string, fn: (...args: any[]) => void) {this.events.on(act, fn); return this;}
|
||||
public on(act: "playerConnect"|"playerDisconnect"|"playerUnknown", fn: (data: playerBase) => void): this;
|
||||
public on(act: "portListening", fn: (data: portListen) => void): this;
|
||||
public on(act: "serverStarted", fn: (data: serverStarted) => void): this;
|
||||
public on(act: "log_stderr", fn: (data: string) => void): this;
|
||||
public on(act: "log_stdout", fn: (data: string) => void): this;
|
||||
public on(act: "exit", fn: (data: {code: number, signal: NodeJS.Signals}) => void): this;
|
||||
public on(act: string, fn: (...args: any[]) => void) {this.events.on(act, fn); return this;}
|
||||
|
||||
once(act: "playerConnect"|"playerDisconnect"|"playerUnknown", fn: (data: playerBase) => void): this;
|
||||
once(act: "portListening", fn: (data: portListen) => void): this;
|
||||
once(act: "serverStarted", fn: (data: serverStarted) => void): this;
|
||||
once(act: string, fn: (...args: any[]) => void) {this.events.once(act, fn); return this;}
|
||||
public once(act: "playerConnect"|"playerDisconnect"|"playerUnknown", fn: (data: playerBase) => void): this;
|
||||
public once(act: "portListening", fn: (data: portListen) => void): this;
|
||||
public once(act: "serverStarted", fn: (data: serverStarted) => void): this;
|
||||
public once(act: "log_stderr", fn: (data: string) => void): this;
|
||||
public once(act: "log_stdout", fn: (data: string) => void): this;
|
||||
public once(act: "exit", fn: (data: {code: number, signal: NodeJS.Signals}) => void): this;
|
||||
public once(act: string, fn: (...args: any[]) => void) {this.events.once(act, fn); return this;}
|
||||
|
||||
public stopServer() {
|
||||
if (typeof this.stopServer === "undefined") this.childProcess.kill("SIGKILL");
|
||||
this.stopServerFunction(this.childProcess);
|
||||
return this;
|
||||
}
|
||||
|
||||
public tp(x: number|string = 0, y: number|string = 0, z: number|string = 0) {
|
||||
if (typeof this.stopServer === "undefined") throw new Error("TP command not configured!");
|
||||
this.tpfunction(this.childProcess, x, y, z);
|
||||
return this;
|
||||
}
|
||||
|
||||
public runCommand(...command: Array<string|number>) {
|
||||
const psCommand = command.map(a => String(a));
|
||||
this.childProcess.writeStdin(psCommand.join(" "));
|
||||
}
|
||||
|
||||
public portListening: portListen[] = [];
|
||||
public playerActions: playerClass = {};
|
||||
|
||||
constructor(child: customChild, config: actionConfig[]) {
|
||||
child.on("breakStdout", data => config.forEach(fn => fn.callback(data, (...args) => this.events.emit(fn.name, ...args))));
|
||||
child.on("breakStderr", data => config.forEach(fn => fn.callback(data, (...args) => this.events.emit(fn.name, ...args))));
|
||||
this.childProcess = child;
|
||||
child.on("close", data => this.events.emit("exit", data));
|
||||
child.on("breakStdout", data => this.events.emit("log_stdout", data));
|
||||
child.on("breakStderr", data => this.events.emit("log_stderr", data));
|
||||
|
||||
this.on("portListening", data => this.portListening.push(data));
|
||||
this.on("playerConnect", (data): any => {
|
||||
if (!this.playerActions[data.playerName]) return this.playerActions[data.playerName] = {
|
||||
action: "connect",
|
||||
date: data.connectTime,
|
||||
history: [{action: "connect", date: data.connectTime}]
|
||||
}
|
||||
this.playerActions[data.playerName].action = "connect";
|
||||
this.playerActions[data.playerName].date = data.connectTime;
|
||||
this.playerActions[data.playerName].history.push({action: "connect", date: data.connectTime});
|
||||
});
|
||||
this.on("playerDisconnect", (data): any => {
|
||||
if (!this.playerActions[data.playerName]) return this.playerActions[data.playerName] = {
|
||||
action: "disconnect",
|
||||
date: data.connectTime,
|
||||
history: [{action: "disconnect", date: data.connectTime}]
|
||||
}
|
||||
this.playerActions[data.playerName].action = "disconnect";
|
||||
this.playerActions[data.playerName].date = data.connectTime;
|
||||
this.playerActions[data.playerName].history.push({action: "disconnect", date: data.connectTime});
|
||||
});
|
||||
this.on("playerUnknown", (data): any => {
|
||||
if (!this.playerActions[data.playerName]) return this.playerActions[data.playerName] = {
|
||||
action: "unknown",
|
||||
date: data.connectTime,
|
||||
history: [{action: "unknown", date: data.connectTime}]
|
||||
}
|
||||
this.playerActions[data.playerName].action = "unknown";
|
||||
this.playerActions[data.playerName].date = data.connectTime;
|
||||
this.playerActions[data.playerName].history.push({action: "unknown", date: data.connectTime});
|
||||
});
|
||||
|
||||
const actions = config.filter((a: actionCallback) => typeof a?.callback === "function") as actionCallback[];
|
||||
child.on("breakStdout", data => actions.forEach(fn => fn.callback(data, (...args: any[]) => this.events.emit(fn.name, ...args))));
|
||||
child.on("breakStderr", data => actions.forEach(fn => fn.callback(data, (...args: any[]) => this.events.emit(fn.name, ...args))));
|
||||
for (const action of (config.filter((a: actionRun) => typeof a?.run === "function") as actionRun[])) {
|
||||
if (action.name === "serverStop") this.stopServerFunction = action.run;
|
||||
}
|
||||
}
|
||||
}
|
@ -40,10 +40,6 @@ export async function startServer(Config?: {maxMemory?: number, minMemory?: numb
|
||||
if (Config?.minMemory) args.push(`-Xms${Config?.minMemory}m`);
|
||||
if (Config?.maxMemory) args.push(`-Xmx${Config?.maxMemory}m`);
|
||||
}
|
||||
|
||||
|
||||
args.push(jarPath);
|
||||
const serverProcess = exec(command, args, {cwd: serverPath, maxBuffer: Infinity});
|
||||
const serverActions = new actions(serverProcess, serverConfig);
|
||||
return {serverProcess, serverActions};
|
||||
return new actions(exec(command, args, {cwd: serverPath, maxBuffer: Infinity}), serverConfig);
|
||||
}
|
@ -3,7 +3,7 @@ import * as fs from "node:fs/promises";
|
||||
import * as os from "node:os";
|
||||
import * as tar from "tar";
|
||||
import { existsSync as fsExistsSync } from "node:fs";
|
||||
import { getPocketminePhar, versionUrl } from "@the-bds-maneger/server_versions";
|
||||
import { getPocketminePhar, versionAPIs } from "@the-bds-maneger/server_versions";
|
||||
import { execFileAsync, exec } from './childPromisses';
|
||||
import { serverRoot } from "./pathControl";
|
||||
import { getBuffer } from "./httpRequest";
|
||||
@ -12,6 +12,7 @@ import AdmZip from "adm-zip";
|
||||
import { promisify } from 'node:util';
|
||||
export const serverPath = path.join(serverRoot, "pocketmine");
|
||||
export const serverPhar = path.join(serverPath, "pocketmine.phar");
|
||||
export const phpBinPath = path.join(serverPath, "bin", (process.platform === "win32"?"php":"bin"), "php");
|
||||
|
||||
async function Readdir(pathRead: string, filter?: Array<RegExp>) {
|
||||
if (!filter) filter = [/.*/];
|
||||
@ -54,7 +55,7 @@ async function buildPhp() {
|
||||
}
|
||||
|
||||
async function installPhp(): Promise<void> {
|
||||
const file = (await getBuffer(`${versionUrl}/pocketmine/bin?os=${process.platform}&arch=${process.arch}`).then(res => JSON.parse(res.toString("utf8")) as {url: string, name: string}[]))[0];
|
||||
const file = (await getBuffer(`${versionAPIs[0]}/pocketmine/bin?os=${process.platform}&arch=${process.arch}`).then(res => JSON.parse(res.toString("utf8")) as {url: string, name: string}[]))[0];
|
||||
if (!file) return buildPhp();
|
||||
if (fsExistsSync(path.resolve(serverPath, "bin"))) await fs.rm(path.resolve(serverPath, "bin"), {recursive: true});
|
||||
await fs.mkdir(path.resolve(serverPath, "bin"), {recursive: true});
|
||||
@ -68,16 +69,17 @@ async function installPhp(): Promise<void> {
|
||||
}
|
||||
if (process.platform === "linux"||process.platform === "android"||process.platform === "darwin") {
|
||||
const ztsFind = await Readdir(path.resolve(serverPath, "bin"), [/.*debug-zts.*/]);
|
||||
if (ztsFind.length === 0) return;
|
||||
const phpIniPath = (await Readdir(path.resolve(serverPath, "bin"), [/php\.ini$/]))[0].path;
|
||||
let phpIni = await fs.readFile(phpIniPath, "utf8");
|
||||
if (phpIni.includes("extension_dir")) await fs.writeFile(phpIniPath, phpIni.replace(/extension_dir=.*/g, ""));
|
||||
phpIni = phpIni+`\nextension_dir=${ztsFind[0].path}`
|
||||
await fs.writeFile(phpIniPath, phpIni);
|
||||
if (ztsFind.length > 0) {
|
||||
const phpIniPath = (await Readdir(path.resolve(serverPath, "bin"), [/php\.ini$/]))[0].path;
|
||||
let phpIni = await fs.readFile(phpIniPath, "utf8");
|
||||
if (phpIni.includes("extension_dir")) await fs.writeFile(phpIniPath, phpIni.replace(/extension_dir=.*/g, ""));
|
||||
phpIni = phpIni+`\nextension_dir=${path.resolve(ztsFind[0].path, "..")}`
|
||||
await fs.writeFile(phpIniPath, phpIni);
|
||||
}
|
||||
}
|
||||
// test it's works php
|
||||
await fs.writeFile(path.join(os.tmpdir(), "test.php"), `<?php echo "Hello World";`);
|
||||
await execFileAsync(path.join(serverPath, "bin", process.platform === "win32" ? "php/php.exe" : "php"), ["-f", path.join(os.tmpdir(), "test.php")]).catch(buildPhp);
|
||||
await execFileAsync(phpBinPath, ["-f", path.join(os.tmpdir(), "test.php")]).catch(buildPhp);
|
||||
}
|
||||
|
||||
export async function installServer(version: string|boolean) {
|
||||
@ -109,9 +111,5 @@ const serverConfig: actionConfig[] = [
|
||||
|
||||
export async function startServer() {
|
||||
if (!fsExistsSync(serverPath)) throw new Error("Install server fist!");
|
||||
const phpFile = path.join(serverPath, "bin", process.platform === "win32"?"php":"bin", "php");
|
||||
|
||||
const serverProcess = exec(phpFile, [serverPhar], {cwd: serverPath, maxBuffer: Infinity});
|
||||
const serverActions = new actions(serverProcess, serverConfig);
|
||||
return {serverProcess, serverActions};
|
||||
return new actions(exec(phpBinPath, [serverPhar], {cwd: serverPath, maxBuffer: Infinity}), serverConfig);
|
||||
}
|
@ -41,9 +41,6 @@ export async function startServer(Config?: {maxMemory?: number, minMemory?: numb
|
||||
if (Config?.maxMemory) args.push(`-Xmx${Config?.maxMemory}m`);
|
||||
}
|
||||
|
||||
|
||||
args.push(jarPath);
|
||||
const serverProcess = exec(command, args, {cwd: serverPath, maxBuffer: Infinity});
|
||||
const serverActions = new actions(serverProcess, serverConfig);
|
||||
return {serverProcess, serverActions};
|
||||
return new actions(exec(command, args, {cwd: serverPath, maxBuffer: Infinity}), serverConfig);
|
||||
}
|
||||
|
@ -3,10 +3,10 @@ import { installServer, startServer } from "../src/bedrock";
|
||||
describe("Bedrock", () => {
|
||||
it("Install and Start", async function(){
|
||||
this.timeout(1000*60*60*15);
|
||||
await installServer(true);
|
||||
await installServer("latest");
|
||||
const serverManeger = await startServer();
|
||||
serverManeger.serverProcess.on("stdoutRaw", data => process.stdout.write(data));
|
||||
serverManeger.serverActions.once("serverStarted", () => serverManeger.serverProcess.writeStdin("stop"));
|
||||
return new Promise((done, reject) => serverManeger.serverProcess.on("close", ({code}) => code === 0?done():reject(new Error("Exit another code "+code))));
|
||||
serverManeger.on("log_stdout", data => process.stdout.write(data));
|
||||
serverManeger.once("serverStarted", () => serverManeger.stopServer());
|
||||
return new Promise((done, reject) => serverManeger.on("exit", ({code}) => code === 0?done():reject(new Error("Exit another code "+code))));
|
||||
});
|
||||
});
|
||||
|
20
tests/pocketmine.ts
Normal file
20
tests/pocketmine.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { installServer, startServer } from "../src/pocketmine";
|
||||
|
||||
describe("Pocketmine", () => {
|
||||
it("Install and Start", async function() {
|
||||
this.timeout(1000*60*60*15);
|
||||
await installServer("latest");
|
||||
const serverManeger = await startServer();
|
||||
serverManeger.on("log_stdout", console.log);
|
||||
serverManeger.on("log_stdout", data => {
|
||||
if(/set-up.*wizard/.test(data)) {
|
||||
serverManeger.runCommand("eng");
|
||||
serverManeger.runCommand("y");
|
||||
serverManeger.runCommand("y");
|
||||
serverManeger.runCommand("");
|
||||
}
|
||||
});
|
||||
serverManeger.on("serverStarted", () => serverManeger.stopServer());
|
||||
return new Promise((done, reject) => serverManeger.on("exit", ({code}) => code === 0?done():reject(new Error("Exit another code "+code))));
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user