Reewrite project #430

Merged
Sirherobrine23 merged 13 commits from reewriteProject into main 2022-08-31 10:03:14 +00:00
10 changed files with 188 additions and 92 deletions
Showing only changes of commit ce1a124fbc - Show all commits

82
package-lock.json generated
View File

@ -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
}
}
},

View File

@ -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",

View File

@ -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);
}

View File

@ -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));
}

View File

@ -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;
}
}
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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
View 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))));
});
});