Update Platforms #390

Merged
Sirherobrine23 merged 10 commits from StashCode into main 2022-06-09 20:22:38 +00:00
38 changed files with 855 additions and 685 deletions
Showing only changes of commit 5500410506 - Show all commits

View File

@ -1,26 +1,21 @@
import path from "node:path";
import fs, { promises as fsPromise } from "node:fs";
import AdmZip from "adm-zip";
import { backupRoot as backupFolderPath } from "../pathControl";
import { genericAddFiles } from "./root";
import platforms from "../platform/index";
import AdmZip from "adm-zip";
export type zipOptions = true|false|{path: string};
export async function createZipBackup(WriteFile: zipOptions = false) {
export async function createZipBackup(options: zipOptions) {
if (!(fs.existsSync(backupFolderPath))) await fsPromise.mkdir(backupFolderPath, {recursive: true});
// Add Folders and files
const TempFolder = await genericAddFiles()
// Create empty zip Buffer
const zip = new AdmZip();
for (const file of await TempFolder.listFiles()) zip.addLocalFile(path.join(TempFolder.tempFolderPath, file), (path.sep+path.parse(file).dir));
await TempFolder.cleanFolder();
// Get Zip Buffer
const zipBuffer = zip.toBuffer();
let BackupFile = path.resolve(backupFolderPath, `${new Date().toString().replace(/[-\(\)\:\s+]/gi, "_")}.zip`);
if (WriteFile === true) await fsPromise.writeFile(BackupFile, zipBuffer);
else if (typeof WriteFile === "object") {
if (!!WriteFile.path) BackupFile = path.resolve(WriteFile.path);
await fsPromise.writeFile(BackupFile, zipBuffer);
zip.addFile("bedrock.zip", await platforms.bedrock.backup.CreateBackup());
zip.addFile("java.zip", await platforms.java.backup.CreateBackup());
zip.addFile("pocketmine.zip", await platforms.pocketmine.backup.CreateBackup());
zip.addFile("spigot.zip", await platforms.spigot.backup.CreateBackup());
if (typeof options === "boolean") return zip.toBuffer();
else {
const filePath = options?.path;
if (!filePath) throw new Error("No file path provided");
await fsPromise.writeFile(filePath, zip.toBuffer());
return filePath;
}
return zipBuffer;
}

View File

@ -67,16 +67,16 @@ export async function startServer(): Promise<BdsSession> {
if (/r\s+.*\:\s+.*\,\s+xuid\:\s+.*/gi.test(data)) {
const actionDate = new Date();
const [action, player, xuid] = (data.match(/r\s+(.*)\:\s+(.*)\,\s+xuid\:\s+(.*)/)||[]).slice(1, 4);
const __PlayerAction: playerAction2 = {player: player, xuid: xuid, action: "unknown", Date: actionDate};
if (action === "connected") __PlayerAction.action = "connect";
else if (action === "disconnected") __PlayerAction.action = "disconnect";
const playerAction: playerAction2 = {player: player, xuid: xuid, action: "unknown", Date: actionDate};
if (action === "connected") playerAction.action = "connect";
else if (action === "disconnected") playerAction.action = "disconnect";
// Server player event
serverEvents.emit("player", __PlayerAction);
delete __PlayerAction.action;
if (action === "connect") serverEvents.emit("player_connect", __PlayerAction);
else if (action === "disconnect") serverEvents.emit("player_disconnect", __PlayerAction);
else serverEvents.emit("player_unknown", __PlayerAction);
serverEvents.emit("player", playerAction);
delete playerAction.action;
if (action === "connect") serverEvents.emit("player_connect", playerAction);
else if (action === "disconnect") serverEvents.emit("player_disconnect", playerAction);
else serverEvents.emit("player_unknown", playerAction);
}
});
@ -173,23 +173,24 @@ export async function startServer(): Promise<BdsSession> {
serverEvents.on("port_listen", Seesion.ports.push);
serverEvents.on("started", date => {Seesion.server.started = true; Seesion.server.startDate = date;});
serverEvents.on("player", __PlayerAction => {
serverEvents.on("player", playerAction => {
// Add to object
if (!Seesion.Player[__PlayerAction.player]) Seesion.Player[__PlayerAction.player] = {
action: __PlayerAction.action,
date: __PlayerAction.Date,
history: [{
action: __PlayerAction.action,
date: __PlayerAction.Date
}]
}; else {
Seesion.Player[__PlayerAction.player].action = __PlayerAction.action;
Seesion.Player[__PlayerAction.player].date = __PlayerAction.Date;
Seesion.Player[__PlayerAction.player].history.push({
action: __PlayerAction.action,
date: __PlayerAction.Date
const playerExist = !!Seesion.Player[playerAction.player];
if (playerExist) {
Seesion.Player[playerAction.player].action = playerAction.action;
Seesion.Player[playerAction.player].date = playerAction.Date;
Seesion.Player[playerAction.player].history.push({
action: playerAction.action,
date: playerAction.Date
});
}
} else Seesion.Player[playerAction.player] = {
action: playerAction.action,
date: playerAction.Date,
history: [{
action: playerAction.action,
date: playerAction.Date
}]
};
});
// Return Session

View File

@ -7,7 +7,6 @@ export default async function javaTest() {
// Start Server
const server = await java.server.startServer();
server.server.on("log", console.log);
server.server.once("started", () => console.log("Server started"));
server.server.on("port_listen", port => console.log("Server listening on port: %o with protocol: %s", port.port, port.protocol));
await new Promise((resolve, reject) => {

View File

@ -4,7 +4,7 @@ import crypto from "crypto";
import node_cron from "cron";
import * as child_process from "../../childProcess";
import { backupRoot, serverRoot } from "../../pathControl";
import { BdsSession, bdsSessionCommands, serverListen } from '../../globalType';
import { BdsSession, bdsSessionCommands } from '../../globalType';
import { gitBackup, gitBackupOption } from "../../backup/git";
import { createZipBackup } from "../../backup/zip";
import events from "../../lib/customEvents";
@ -28,6 +28,17 @@ export async function startServer(): Promise<BdsSession> {
if (code === null) serverEvents.emit("err", new Error("Server exited with code null"));
});
// Detect server start
serverEvents.on("log", lineData => {
// [22:35:26] [Server thread/INFO]: Done (6.249s)! For help, type "help"
if (/\[.*\].*\s+Done\s+\(.*\)\!.*/.test(lineData)) serverEvents.emit("started", new Date());
});
// Parse ports
serverEvents.on("log", data => {
const portParse = data.match(/Starting\s+Minecraft\s+server\s+on\s+(.*)\:(\d+)/);
if (!!portParse) serverEvents.emit("port_listen", {port: parseInt(portParse[2]), protocol: "TCP", version: "IPv4/IPv6",});
});
// Run Command
const serverCommands: bdsSessionCommands = {
/**
@ -118,30 +129,9 @@ export async function startServer(): Promise<BdsSession> {
}
};
// Detect server start
serverEvents.on("log", lineData => {
// [22:35:26] [Server thread/INFO]: Done (6.249s)! For help, type "help"
if (/\[.*\].*\s+Done\s+\(.*\)\!.*/.test(lineData)) {
const StartDate = new Date();
Seesion.server.startDate = StartDate;
serverEvents.emit("started", StartDate);
Seesion.server.started = true;
}
});
// Parse ports
serverEvents.on("log", data => {
const portParse = data.match(/Starting\s+Minecraft\s+server\s+on\s+(.*)\:(\d+)/);
if (!!portParse) {
const portObject: serverListen = {
port: parseInt(portParse[2]),
version: "IPv4/IPv6"
};
serverEvents.emit("port_listen", portObject);
Seesion.ports.push(portObject);
}
});
// Server Events
serverEvents.on("port_listen", port => Seesion.ports.push(port));
serverEvents.on("started", StartDate => {Seesion.server.started = true; Seesion.server.startDate = StartDate;});
// Return Session
javaSesions[SessionID] = Seesion;

View File

@ -5,8 +5,7 @@ import admZip from "adm-zip";
import { serverRoot } from '../../pathControl';
const javaPath = path.join(serverRoot, "pocketmine");
const filesFoldertoIgnore = [];
const filesFoldertoIgnore = ["PocketMine.phar", "bin", "server.log"];
/**
* Create backup for Worlds and Settings
*/

View File

@ -52,7 +52,6 @@ async function InstallPrebuildPHP(serverPath: string) {
const ztsFind = await Readdirrec(path.resolve(serverPath, "bin"), [/.*debug-zts.*/]);
if (ztsFind.length === 0) return urlBin;
const phpIniPath = (await Readdirrec(path.resolve(serverPath, "bin"), [/php\.ini$/]))[0].path;
console.log("Updating php.ini");
let phpIni = await fs.promises.readFile(phpIniPath, "utf8");
if (phpIni.includes("extension_dir")) {
await fs.promises.writeFile(phpIniPath, phpIni.replace(/extension_dir=.*/g, ""));

View File

@ -0,0 +1,23 @@
import * as pocketmine from "./index";
export default async function pocketmineTest() {
// Download Server
const download = await pocketmine.DownloadServer(true);
console.log("Version: %s, Date: %o, url: %s", download.version, download.publishDate, download.url);
// Run Server
const server = await pocketmine.server.startServer();
server.server.once("started", () => console.log("Server started"));
server.commands.execCommand("eng").execCommand("n")
await new Promise((resolve, reject) => {
server.server.once("started", resolve);
server.server.once("closed", resolve);
server.server.once("err", reject);
});
await server.commands.stop();
// Backup
const zipFile = await pocketmine.backup.CreateBackup();
console.log("Backup created: %o", zipFile.length);
return;
}

View File

@ -15,22 +15,18 @@ export function getSessions() {return pocketmineSesions;}
const ServerPath = path.join(serverRoot, "pocketmine");
export async function startServer(): Promise<BdsSession> {
const SessionID = crypto.randomUUID();
const Process: {command: string; args: Array<string>; env: {[env: string]: string};} = {
command: "",
args: [],
env: {...process.env}
};
Process.args.push(path.join(ServerPath, "PocketMine.phar"));
const Process: {command: string; args: Array<string>} = {command: "", args: []};
if (process.platform === "win32") Process.command = path.resolve(ServerPath, "bin/php/php.exe");
else {
Process.command = path.resolve(ServerPath, "bin/bin/php");
await child_process.runAsync("chmod", ["a+x", Process.command]);
}
Process.args.push(path.join(ServerPath, "PocketMine.phar"));
// Start Server
const serverEvents = new events();
const StartDate = new Date();
const ServerProcess = await child_process.execServer({runOn: "host"}, Process.command, Process.args, {env: Process.env, cwd: ServerPath});
const ServerProcess = await child_process.execServer({runOn: "host"}, Process.command, Process.args, {cwd: ServerPath});
const { onExit, on: execOn } = ServerProcess;
// Log Server redirect to callbacks events and exit
execOn("out", data => serverEvents.emit("log_stdout", data));
@ -38,6 +34,50 @@ export async function startServer(): Promise<BdsSession> {
execOn("all", data => serverEvents.emit("log", data));
onExit().catch(err => {serverEvents.emit("err", err);return null}).then(code => serverEvents.emit("closed", code));
// On server started
serverEvents.on("log", lineData => {
// [22:52:05.580] [Server thread/INFO]: Done (0.583s)! For help, type "help" or "?"
if (/\[.*\].*\s+Done\s+\(.*\)\!.*/.test(lineData)) serverEvents.emit("started", new Date());
});
// Port listen
serverEvents.on("log", data => {
// [16:49:31.284] [Server thread/INFO]: Minecraft network interface running on [::]:19133
// [16:49:31.273] [Server thread/INFO]: Minecraft network interface running on 0.0.0.0:19132
if (/\[.*\]:\s+Minecraft\s+network\s+interface\s+running\s+on\s+.*/gi.test(data)) {
const matchString = data.match(/\[.*\]:\s+Minecraft\s+network\s+interface\s+running\s+on\s+(.*)/);
if (!!matchString) {
const portParse = matchString[1];
const portObject: serverListen = {port: 0, version: "IPv4", protocol: "UDP"};
const isIpv6 = /\[.*\]:/.test(portParse);
if (!isIpv6) portObject.port = parseInt(portParse.split(":")[1]);
else {
portObject.port = parseInt(portParse.replace(/\[.*\]:/, "").trim())
portObject.version = "IPv6";
}
serverEvents.emit("port_listen", portObject);
}
}
});
// Player Actions
serverEvents.on("log", data => {
const actionDate = new Date();
if (/\[.*\]:\s+(.*)\s+(.*)\s+the\s+game/gi.test(data)) {
const [action, player] = (data.match(/[.*]:\s+(.*)\s+(.*)\s+the\s+game/gi)||[]).slice(1, 3);
const playerAction: playerAction2 = {player: player, action: "unknown", Date: actionDate};
if (action === "joined") playerAction.action = "connect";
else if (action === "left") playerAction.action = "disconnect";
// Server player event
serverEvents.emit("player", playerAction);
delete playerAction.action;
if (action === "connect") serverEvents.emit("player_connect", playerAction);
else if (action === "disconnect") serverEvents.emit("player_disconnect", playerAction);
else serverEvents.emit("player_unknown", playerAction);
}
});
// Run Command
const serverCommands: bdsSessionCommands = {
/**
@ -128,69 +168,24 @@ export async function startServer(): Promise<BdsSession> {
}
};
// On server started
serverEvents.on("log", lineData => {
// [22:52:05.580] [Server thread/INFO]: Done (0.583s)! For help, type "help" or "?"
if (/\[.*\].*\s+Done\s+\(.*\)\!.*/.test(lineData)) {
const StartDate = new Date();
Seesion.server.startDate = StartDate;
serverEvents.emit("started", StartDate);
Seesion.server.started = true;
}
});
// Port listen
serverEvents.on("log", data => {
// [16:49:31.284] [Server thread/INFO]: Minecraft network interface running on [::]:19133
// [16:49:31.273] [Server thread/INFO]: Minecraft network interface running on 0.0.0.0:19132
if (/\[.*\]:\s+Minecraft\s+network\s+interface\s+running\s+on\s+.*/gi.test(data)) {
const matchString = data.match(/\[.*\]:\s+Minecraft\s+network\s+interface\s+running\s+on\s+(.*)/);
if (!!matchString) {
const portParse = matchString[1];
const isIpv6 = /\[.*\]:/.test(portParse);
const portObject: serverListen = {port: 0, version: "IPv4"};
if (!isIpv6) portObject.port = parseInt(portParse.split(":")[1]);
else {
portObject.port = parseInt(portParse.replace(/\[.*\]:/, "").trim())
portObject.version = "IPv6";
}
serverEvents.emit("port_listen", portObject);
Seesion.ports.push(portObject);
}
}
});
// Player Actions
serverEvents.on("log", data => {
if (/\[.*\]:\s+(.*)\s+(.*)\s+the\s+game/gi.test(data)) {
const actionDate = new Date();
const [action, player] = (data.match(/[.*]:\s+(.*)\s+(.*)\s+the\s+game/gi)||[]).slice(1, 3);
const __PlayerAction: playerAction2 = {player: player, action: "unknown", Date: actionDate};
if (action === "joined") __PlayerAction.action = "connect";
else if (action === "left") __PlayerAction.action = "disconnect";
if (!Seesion.Player[__PlayerAction.player]) Seesion.Player[__PlayerAction.player] = {
action: __PlayerAction.action,
date: actionDate,
serverEvents.on("started", StartDate => {Seesion.server.startDate = StartDate; Seesion.server.started = true;});
serverEvents.on("port_listen", portObject => Seesion.ports.push(portObject));
serverEvents.on("player", playerAction => {
if (!Seesion.Player[playerAction.player]) Seesion.Player[playerAction.player] = {
action: playerAction.action,
date: playerAction.Date,
history: [{
action: __PlayerAction.action,
date: actionDate
action: playerAction.action,
date: playerAction.Date
}]
}; else {
Seesion.Player[__PlayerAction.player].action = __PlayerAction.action;
Seesion.Player[__PlayerAction.player].date = actionDate;
Seesion.Player[__PlayerAction.player].history.push({
action: __PlayerAction.action,
date: actionDate
Seesion.Player[playerAction.player].action = playerAction.action;
Seesion.Player[playerAction.player].date = playerAction.Date;
Seesion.Player[playerAction.player].history.push({
action: playerAction.action,
date: playerAction.Date
});
}
// Server player event
serverEvents.emit("player", __PlayerAction);
delete __PlayerAction.action;
if (action === "connect") serverEvents.emit("player_connect", __PlayerAction);
else if (action === "disconnect") serverEvents.emit("player_disconnect", __PlayerAction);
else serverEvents.emit("player_unknown", __PlayerAction);
}
});
// Return Session

View File

@ -3,9 +3,9 @@ import * as fs from "node:fs/promises";
import * as path from "node:path";
import admZip from "adm-zip";
import { serverRoot } from '../../pathControl';
const javaPath = path.join(serverRoot, "java");
const javaPath = path.join(serverRoot, "spigot");
const filesFoldertoIgnore = [];
const filesFoldertoIgnore = ["Server.jar", "eula.txt", "libraries", "logs", "usercache.json", "versions"];
/**
* Create backup for Worlds and Settings

View File

@ -4,7 +4,7 @@ import crypto from "node:crypto";
import node_cron from "cron";
import * as child_process from "../../childProcess";
import { backupRoot, serverRoot } from "../../pathControl";
import { BdsSession, bdsSessionCommands, serverListen } from '../../globalType';
import { BdsSession, bdsSessionCommands } from '../../globalType';
import { gitBackup, gitBackupOption } from "../../backup/git";
import { createZipBackup } from "../../backup/zip";
import events from "../../lib/customEvents";
@ -26,6 +26,18 @@ export async function startServer(): Promise<BdsSession> {
execOn("all", data => serverEvents.emit("log", data));
onExit().catch(err => {serverEvents.emit("err", err);return null}).then(code => serverEvents.emit("closed", code));
// Server Start
serverEvents.on("log", lineData => {
// [22:35:26] [Server thread/INFO]: Done (6.249s)! For help, type "help"
if (/\[.*\].*\s+Done\s+\(.*\)\!.*/.test(lineData)) serverEvents.emit("started", new Date());
});
// Parse ports
serverEvents.on("log", data => {
const portParse = data.match(/Starting\s+Minecraft\s+server\s+on\s+(.*)\:(\d+)/);
if (!!portParse) serverEvents.emit("port_listen", {port: parseInt(portParse[2]), version: "IPv4/IPv6", protocol: "TCP"});
});
// Run Command
const serverCommands: bdsSessionCommands = {
/**
@ -116,25 +128,8 @@ export async function startServer(): Promise<BdsSession> {
}
};
serverEvents.on("log", lineData => {
// [22:35:26] [Server thread/INFO]: Done (6.249s)! For help, type "help"
if (/\[.*\].*\s+Done\s+\(.*\)\!.*/.test(lineData)) {
const StartDate = new Date();
Seesion.server.startDate = StartDate;
serverEvents.emit("started", StartDate);
Seesion.server.started = true;
}
});
// Parse ports
serverEvents.on("log", data => {
const portParse = data.match(/Starting\s+Minecraft\s+server\s+on\s+(.*)\:(\d+)/);
if (!!portParse) {
const portObject: serverListen = {port: parseInt(portParse[2]), version: "IPv4/IPv6"};
serverEvents.emit("port_listen", portObject);
Seesion.ports.push(portObject);
}
});
serverEvents.on("started", StartDate => {Seesion.server.startDate = StartDate; Seesion.server.started = true;});
serverEvents.on("port_listen", portObject => Seesion.ports.push(portObject));
// Return Session
javaSesions[SessionID] = Seesion;

View File

@ -0,0 +1,22 @@
import * as spigot from "./index";
export default async function spigotTest() {
// Download and install server
const download = await spigot.DownloadServer(true);
console.log("Version: %s, Date: %o, url: %s", download.version, download.publishDate, download.url);
// Start Server
const server = await spigot.server.startServer();
server.server.once("started", () => console.log("Server started"));
server.server.on("port_listen", port => console.log("Server listening on port: %o with protocol: %s", port.port, port.protocol));
await new Promise((resolve, reject) => {
server.server.once("started", resolve);
server.server.once("closed", code => code === null ? resolve(code) : reject(code));
});
await server.commands.stop();
// Backup
const zipFile = await spigot.backup.CreateBackup();
console.log("Backup created: %o", zipFile.length);
return;
}