Reewrite project #430
82
package-lock.json
generated
82
package-lock.json
generated
@@ -9,7 +9,7 @@
|
|||||||
"version": "4.0.0",
|
"version": "4.0.0",
|
||||||
"license": "GPL-3.0",
|
"license": "GPL-3.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@the-bds-maneger/server_versions": "^3.0.0",
|
"@the-bds-maneger/server_versions": "^3.0.1",
|
||||||
"adm-zip": "^0.5.9",
|
"adm-zip": "^0.5.9",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"cron": "^2.1.0",
|
"cron": "^2.1.0",
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
"@types/adm-zip": "^0.5.0",
|
"@types/adm-zip": "^0.5.0",
|
||||||
"@types/cron": "^2.0.0",
|
"@types/cron": "^2.0.0",
|
||||||
"@types/mocha": "^9.1.1",
|
"@types/mocha": "^9.1.1",
|
||||||
"@types/node": "^18.7.13",
|
"@types/node": "^18.7.14",
|
||||||
"@types/tar": "^6.1.2",
|
"@types/tar": "^6.1.2",
|
||||||
"mocha": "^10.0.0",
|
"mocha": "^10.0.0",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
@@ -68,9 +68,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@the-bds-maneger/server_versions": {
|
"node_modules/@the-bds-maneger/server_versions": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@the-bds-maneger/server_versions/-/server_versions-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@the-bds-maneger/server_versions/-/server_versions-3.0.1.tgz",
|
||||||
"integrity": "sha512-+t2r7+iJHNbcF1A3o953Dcxm3LLN138tiC7CMWAa7IoJFhpqjYZcijlJEUZ4y6ueTE59yqtwninOtmRnhrqE/g==",
|
"integrity": "sha512-PRpmjigZlfOtjVKE5371ZF0vjDV30L256hohAZYeoIWuHxzpSi6oJdT3gGp/qyUsXJ7r7Ac7A9OnFGJqgkwk5g==",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
@@ -145,9 +145,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "18.7.13",
|
"version": "18.7.14",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.14.tgz",
|
||||||
"integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw=="
|
"integrity": "sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/tar": {
|
"node_modules/@types/tar": {
|
||||||
"version": "6.1.2",
|
"version": "6.1.2",
|
||||||
@@ -160,9 +160,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/webidl-conversions": {
|
"node_modules/@types/webidl-conversions": {
|
||||||
"version": "6.1.1",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||||
"integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
|
"integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog=="
|
||||||
},
|
},
|
||||||
"node_modules/@types/whatwg-url": {
|
"node_modules/@types/whatwg-url": {
|
||||||
"version": "8.2.2",
|
"version": "8.2.2",
|
||||||
@@ -787,9 +787,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/diff": {
|
"node_modules/diff": {
|
||||||
"version": "4.0.2",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
|
||||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.3.1"
|
"node": ">=0.3.1"
|
||||||
@@ -1758,15 +1758,6 @@
|
|||||||
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
"integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
|
||||||
"dev": true
|
"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": {
|
"node_modules/mocha/node_modules/ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
||||||
@@ -2543,6 +2534,15 @@
|
|||||||
"node": ">=0.4.0"
|
"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": {
|
"node_modules/type-check": {
|
||||||
"version": "0.3.2",
|
"version": "0.3.2",
|
||||||
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
|
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
|
||||||
@@ -2896,9 +2896,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@the-bds-maneger/server_versions": {
|
"@the-bds-maneger/server_versions": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@the-bds-maneger/server_versions/-/server_versions-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/@the-bds-maneger/server_versions/-/server_versions-3.0.1.tgz",
|
||||||
"integrity": "sha512-+t2r7+iJHNbcF1A3o953Dcxm3LLN138tiC7CMWAa7IoJFhpqjYZcijlJEUZ4y6ueTE59yqtwninOtmRnhrqE/g==",
|
"integrity": "sha512-PRpmjigZlfOtjVKE5371ZF0vjDV30L256hohAZYeoIWuHxzpSi6oJdT3gGp/qyUsXJ7r7Ac7A9OnFGJqgkwk5g==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
@@ -2970,9 +2970,9 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "18.7.13",
|
"version": "18.7.14",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.13.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.7.14.tgz",
|
||||||
"integrity": "sha512-46yIhxSe5xEaJZXWdIBP7GU4HDTG8/eo0qd9atdiL+lFpA03y8KS+lkTN834TWJj5767GbWv4n/P6efyTFt1Dw=="
|
"integrity": "sha512-6bbDaETVi8oyIARulOE9qF1/Qdi/23z6emrUh0fNJRUmjznqrixD4MpGDdgOFk5Xb0m2H6Xu42JGdvAxaJR/wA=="
|
||||||
},
|
},
|
||||||
"@types/tar": {
|
"@types/tar": {
|
||||||
"version": "6.1.2",
|
"version": "6.1.2",
|
||||||
@@ -2985,9 +2985,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/webidl-conversions": {
|
"@types/webidl-conversions": {
|
||||||
"version": "6.1.1",
|
"version": "7.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-6.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||||
"integrity": "sha512-XAahCdThVuCFDQLT7R7Pk/vqeObFNL3YqRyFZg+AqAP/W1/w3xHaIxuW7WszQqTbIBOPRcItYJIou3i/mppu3Q=="
|
"integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog=="
|
||||||
},
|
},
|
||||||
"@types/whatwg-url": {
|
"@types/whatwg-url": {
|
||||||
"version": "8.2.2",
|
"version": "8.2.2",
|
||||||
@@ -3450,9 +3450,9 @@
|
|||||||
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
|
"integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg=="
|
||||||
},
|
},
|
||||||
"diff": {
|
"diff": {
|
||||||
"version": "4.0.2",
|
"version": "5.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz",
|
||||||
"integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==",
|
"integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"domexception": {
|
"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": {
|
"ms": {
|
||||||
"version": "2.1.3",
|
"version": "2.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
|
"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",
|
"resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz",
|
||||||
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
|
"integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==",
|
||||||
"dev": true
|
"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"
|
"node": ">=16.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@the-bds-maneger/server_versions": "^3.0.0",
|
"@the-bds-maneger/server_versions": "^3.0.1",
|
||||||
"adm-zip": "^0.5.9",
|
"adm-zip": "^0.5.9",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"cron": "^2.1.0",
|
"cron": "^2.1.0",
|
||||||
@@ -41,7 +41,7 @@
|
|||||||
"@types/adm-zip": "^0.5.0",
|
"@types/adm-zip": "^0.5.0",
|
||||||
"@types/cron": "^2.0.0",
|
"@types/cron": "^2.0.0",
|
||||||
"@types/mocha": "^9.1.1",
|
"@types/mocha": "^9.1.1",
|
||||||
"@types/node": "^18.7.13",
|
"@types/node": "^18.7.14",
|
||||||
"@types/tar": "^6.1.2",
|
"@types/tar": "^6.1.2",
|
||||||
"mocha": "^10.0.0",
|
"mocha": "^10.0.0",
|
||||||
"ts-node": "^10.9.1",
|
"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\"");
|
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}});
|
return new actions(exec(command, args, {cwd: serverPath, maxBuffer: Infinity, env: {LD_LIBRARY_PATH: process.platform === "win32"?undefined:serverPath}}), serverConfig);
|
||||||
const serverActions = new actions(serverProcess, serverConfig);
|
|
||||||
return {serverProcess, serverActions};
|
|
||||||
}
|
}
|
||||||
@@ -28,8 +28,7 @@ export function execFileAsync(command: string, args?: execOptions|string[], opti
|
|||||||
|
|
||||||
export class customChild {
|
export class customChild {
|
||||||
private eventMiter = new EventEmitter({captureRejections: false});
|
private eventMiter = new EventEmitter({captureRejections: false});
|
||||||
private tempLog = {};
|
public child?: ChildProcess;
|
||||||
private child?: ChildProcess;
|
|
||||||
|
|
||||||
public kill(signal?: number|NodeJS.Signals) {if(this.child?.killed) return this.child?.killed;return this.child?.kill(signal);}
|
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[]) {
|
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: "breakStderr", fn: (data: string) => void): this;
|
||||||
public once(act: string, fn: (...args: any[]) => void): this {this.eventMiter.once(act, fn);return this;}
|
public once(act: string, fn: (...args: any[]) => void): this {this.eventMiter.once(act, fn);return this;}
|
||||||
|
|
||||||
|
private tempLog = {};
|
||||||
constructor(child: ChildProcess) {
|
constructor(child: ChildProcess) {
|
||||||
this.child = child;
|
this.child = child;
|
||||||
child.on("close", (code, signal) => this.emit("close", {code, signal}));
|
child.on("close", (code, signal) => this.emit("close", {code, signal}));
|
||||||
child.on("exit", (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.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
|
// Storage tmp lines
|
||||||
const parseLog = (to: "breakStdout"|"breakStderr", data: string): any => {
|
const parseLog = (to: "breakStdout"|"breakStderr", data: string): any => {
|
||||||
if (this.tempLog[to] === undefined) this.tempLog[to] = "";
|
|
||||||
const lines = data.split(/\r?\n/);
|
const lines = data.split(/\r?\n/);
|
||||||
if (lines.length === 1) return this.tempLog[to] += lines[0];
|
if (lines.length === 1) {
|
||||||
for (const line of lines.slice(0, -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);
|
if (!this.tempLog[to]) return this.eventMiter.emit(to, line);
|
||||||
this.eventMiter.emit(to, this.tempLog[to]+line);
|
this.eventMiter.emit(to, this.tempLog[to]+line);
|
||||||
delete this.tempLog[to];
|
delete this.tempLog[to];
|
||||||
@@ -79,8 +85,6 @@ export class customChild {
|
|||||||
}
|
}
|
||||||
child.stdout.on("data", data => parseLog("breakStdout", data));
|
child.stdout.on("data", data => parseLog("breakStdout", data));
|
||||||
child.stderr.on("data", data => parseLog("breakStderr", 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 childOptions: ObjectEncodingOptions & ExecFileOptions = {};
|
||||||
let childArgs: string[] = [];
|
let childArgs: string[] = [];
|
||||||
if (args instanceof Array) childArgs = args; else if (args instanceof Object) childOptions = args as execOptions;
|
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};
|
if (childOptions?.env) childOptions.env = {...process.env, ...childOptions.env};
|
||||||
return new customChild(execFile(command, childArgs, childOptions));
|
return new customChild(execFile(command, childArgs, childOptions));
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import type { customChild } from "./childPromisses";
|
import type { customChild } from "./childPromisses";
|
||||||
import { EventEmitter } from "node:events";
|
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 playerBase = {playerName: string, connectTime: Date, xuid?: string};
|
||||||
export type actionsPlayer = {
|
export type actionsPlayer = {
|
||||||
name: "playerConnect"|"playerDisconnect"|"playerUnknown",
|
name: "playerConnect"|"playerDisconnect"|"playerUnknown",
|
||||||
@@ -19,22 +20,104 @@ export type actionsServerStarted = {
|
|||||||
callback: (data: string, done: (started: serverStarted) => void) => void
|
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 {
|
export class actions {
|
||||||
private events = new EventEmitter({captureRejections: false});
|
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;
|
public on(act: "playerConnect"|"playerDisconnect"|"playerUnknown", fn: (data: playerBase) => void): this;
|
||||||
on(act: "portListening", fn: (data: portListen) => void): this;
|
public on(act: "portListening", fn: (data: portListen) => void): this;
|
||||||
on(act: "serverStarted", fn: (data: serverStarted) => void): this;
|
public 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: "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;
|
public once(act: "playerConnect"|"playerDisconnect"|"playerUnknown", fn: (data: playerBase) => void): this;
|
||||||
once(act: "portListening", fn: (data: portListen) => void): this;
|
public once(act: "portListening", fn: (data: portListen) => void): this;
|
||||||
once(act: "serverStarted", fn: (data: serverStarted) => void): this;
|
public 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: "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[]) {
|
constructor(child: customChild, config: actionConfig[]) {
|
||||||
child.on("breakStdout", data => config.forEach(fn => fn.callback(data, (...args) => this.events.emit(fn.name, ...args))));
|
this.childProcess = child;
|
||||||
child.on("breakStderr", data => config.forEach(fn => fn.callback(data, (...args) => this.events.emit(fn.name, ...args))));
|
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?.minMemory) args.push(`-Xms${Config?.minMemory}m`);
|
||||||
if (Config?.maxMemory) args.push(`-Xmx${Config?.maxMemory}m`);
|
if (Config?.maxMemory) args.push(`-Xmx${Config?.maxMemory}m`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
args.push(jarPath);
|
args.push(jarPath);
|
||||||
const serverProcess = exec(command, args, {cwd: serverPath, maxBuffer: Infinity});
|
return new actions(exec(command, args, {cwd: serverPath, maxBuffer: Infinity}), serverConfig);
|
||||||
const serverActions = new actions(serverProcess, serverConfig);
|
|
||||||
return {serverProcess, serverActions};
|
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ import * as fs from "node:fs/promises";
|
|||||||
import * as os from "node:os";
|
import * as os from "node:os";
|
||||||
import * as tar from "tar";
|
import * as tar from "tar";
|
||||||
import { existsSync as fsExistsSync } from "node:fs";
|
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 { execFileAsync, exec } from './childPromisses';
|
||||||
import { serverRoot } from "./pathControl";
|
import { serverRoot } from "./pathControl";
|
||||||
import { getBuffer } from "./httpRequest";
|
import { getBuffer } from "./httpRequest";
|
||||||
@@ -12,6 +12,7 @@ import AdmZip from "adm-zip";
|
|||||||
import { promisify } from 'node:util';
|
import { promisify } from 'node:util';
|
||||||
export const serverPath = path.join(serverRoot, "pocketmine");
|
export const serverPath = path.join(serverRoot, "pocketmine");
|
||||||
export const serverPhar = path.join(serverPath, "pocketmine.phar");
|
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>) {
|
async function Readdir(pathRead: string, filter?: Array<RegExp>) {
|
||||||
if (!filter) filter = [/.*/];
|
if (!filter) filter = [/.*/];
|
||||||
@@ -54,7 +55,7 @@ async function buildPhp() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function installPhp(): Promise<void> {
|
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 (!file) return buildPhp();
|
||||||
if (fsExistsSync(path.resolve(serverPath, "bin"))) await fs.rm(path.resolve(serverPath, "bin"), {recursive: true});
|
if (fsExistsSync(path.resolve(serverPath, "bin"))) await fs.rm(path.resolve(serverPath, "bin"), {recursive: true});
|
||||||
await fs.mkdir(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") {
|
if (process.platform === "linux"||process.platform === "android"||process.platform === "darwin") {
|
||||||
const ztsFind = await Readdir(path.resolve(serverPath, "bin"), [/.*debug-zts.*/]);
|
const ztsFind = await Readdir(path.resolve(serverPath, "bin"), [/.*debug-zts.*/]);
|
||||||
if (ztsFind.length === 0) return;
|
if (ztsFind.length > 0) {
|
||||||
const phpIniPath = (await Readdir(path.resolve(serverPath, "bin"), [/php\.ini$/]))[0].path;
|
const phpIniPath = (await Readdir(path.resolve(serverPath, "bin"), [/php\.ini$/]))[0].path;
|
||||||
let phpIni = await fs.readFile(phpIniPath, "utf8");
|
let phpIni = await fs.readFile(phpIniPath, "utf8");
|
||||||
if (phpIni.includes("extension_dir")) await fs.writeFile(phpIniPath, phpIni.replace(/extension_dir=.*/g, ""));
|
if (phpIni.includes("extension_dir")) await fs.writeFile(phpIniPath, phpIni.replace(/extension_dir=.*/g, ""));
|
||||||
phpIni = phpIni+`\nextension_dir=${ztsFind[0].path}`
|
phpIni = phpIni+`\nextension_dir=${path.resolve(ztsFind[0].path, "..")}`
|
||||||
await fs.writeFile(phpIniPath, phpIni);
|
await fs.writeFile(phpIniPath, phpIni);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// test it's works php
|
// test it's works php
|
||||||
await fs.writeFile(path.join(os.tmpdir(), "test.php"), `<?php echo "Hello World";`);
|
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) {
|
export async function installServer(version: string|boolean) {
|
||||||
@@ -109,9 +111,5 @@ const serverConfig: actionConfig[] = [
|
|||||||
|
|
||||||
export async function startServer() {
|
export async function startServer() {
|
||||||
if (!fsExistsSync(serverPath)) throw new Error("Install server fist!");
|
if (!fsExistsSync(serverPath)) throw new Error("Install server fist!");
|
||||||
const phpFile = path.join(serverPath, "bin", process.platform === "win32"?"php":"bin", "php");
|
return new actions(exec(phpBinPath, [serverPhar], {cwd: serverPath, maxBuffer: Infinity}), serverConfig);
|
||||||
|
|
||||||
const serverProcess = exec(phpFile, [serverPhar], {cwd: serverPath, maxBuffer: Infinity});
|
|
||||||
const serverActions = new actions(serverProcess, serverConfig);
|
|
||||||
return {serverProcess, serverActions};
|
|
||||||
}
|
}
|
||||||
@@ -41,9 +41,6 @@ export async function startServer(Config?: {maxMemory?: number, minMemory?: numb
|
|||||||
if (Config?.maxMemory) args.push(`-Xmx${Config?.maxMemory}m`);
|
if (Config?.maxMemory) args.push(`-Xmx${Config?.maxMemory}m`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
args.push(jarPath);
|
args.push(jarPath);
|
||||||
const serverProcess = exec(command, args, {cwd: serverPath, maxBuffer: Infinity});
|
return new actions(exec(command, args, {cwd: serverPath, maxBuffer: Infinity}), serverConfig);
|
||||||
const serverActions = new actions(serverProcess, serverConfig);
|
|
||||||
return {serverProcess, serverActions};
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,10 @@ import { installServer, startServer } from "../src/bedrock";
|
|||||||
describe("Bedrock", () => {
|
describe("Bedrock", () => {
|
||||||
it("Install and Start", async function(){
|
it("Install and Start", async function(){
|
||||||
this.timeout(1000*60*60*15);
|
this.timeout(1000*60*60*15);
|
||||||
await installServer(true);
|
await installServer("latest");
|
||||||
const serverManeger = await startServer();
|
const serverManeger = await startServer();
|
||||||
serverManeger.serverProcess.on("stdoutRaw", data => process.stdout.write(data));
|
serverManeger.on("log_stdout", data => process.stdout.write(data));
|
||||||
serverManeger.serverActions.once("serverStarted", () => serverManeger.serverProcess.writeStdin("stop"));
|
serverManeger.once("serverStarted", () => serverManeger.stopServer());
|
||||||
return new Promise((done, reject) => serverManeger.serverProcess.on("close", ({code}) => code === 0?done():reject(new Error("Exit another code "+code))));
|
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