Rewrite in typescrypt #327
@ -1,5 +1,3 @@
|
||||
node_modules/
|
||||
.git/
|
||||
*.log
|
||||
Test
|
||||
test
|
||||
dist/
|
@ -1,29 +0,0 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"commonjs": true,
|
||||
"es2021": true,
|
||||
"node": true
|
||||
},
|
||||
"globals": {
|
||||
"bds_log_string": "writable",
|
||||
"bds_server_string": "writable",
|
||||
"external_ip": "writable"
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 12,
|
||||
"sourceType": "module",
|
||||
"ecmaFeatures": {
|
||||
"jsx": true
|
||||
}
|
||||
},
|
||||
"rules": {
|
||||
"quotes": [
|
||||
"error",
|
||||
"double"
|
||||
],
|
||||
"eqeqeq": 0,
|
||||
"no-async-promise-executor": "off"
|
||||
}
|
||||
}
|
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1,2 +0,0 @@
|
||||
* text=lf eol=lf
|
||||
*.sh text=lf eol=lf
|
15
.gitignore
vendored
15
.gitignore
vendored
@ -1,14 +1,5 @@
|
||||
# Log
|
||||
*.log
|
||||
|
||||
# Node
|
||||
node_modules/
|
||||
.dccache
|
||||
docs/
|
||||
the-bds-maneger-core-*.tgz
|
||||
|
||||
# **
|
||||
.husky
|
||||
Servers
|
||||
.Build/Releases.json
|
||||
esm/
|
||||
dist/
|
||||
src/**/*.d.ts
|
||||
src/**/*.d.js
|
32
.npmignore
32
.npmignore
@ -1,31 +1 @@
|
||||
# Log
|
||||
*.log
|
||||
|
||||
# Develop files
|
||||
.devcontainer/
|
||||
.vscode/
|
||||
.Build/
|
||||
|
||||
# Linters
|
||||
.eslint*
|
||||
|
||||
# test files
|
||||
*.test
|
||||
*test*.*js
|
||||
*Test*.*js
|
||||
test/
|
||||
Test/
|
||||
|
||||
# Git
|
||||
git*
|
||||
.git*
|
||||
|
||||
# Docker
|
||||
.docker*
|
||||
Docker*
|
||||
|
||||
# Npm
|
||||
the-bds-maneger-core*.tgz
|
||||
|
||||
# External Packages
|
||||
packages/**/*
|
||||
!dist/
|
2815
package-lock.json
generated
2815
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@ -7,12 +7,15 @@
|
||||
"version": "2.0.0",
|
||||
"description": "A very simple way to manage Minecraft servers",
|
||||
"main": "dist/index.js",
|
||||
"types": "src/index.ts",
|
||||
"exports": {
|
||||
"require": "./dist/src/index.js",
|
||||
"import": "./dist/esm/index.js"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "tsc"
|
||||
"build": "run-s build:*",
|
||||
"build:cjs": "tsc --module commonjs --outDir dist/cjs",
|
||||
"build:esm": "tsc --module es2020 --outDir dist/esm"
|
||||
},
|
||||
"nodemonConfig": {
|
||||
"ignore": [
|
||||
@ -60,10 +63,15 @@
|
||||
"android"
|
||||
],
|
||||
"dependencies": {
|
||||
"@the-bds-maneger/server_versions": "^1.1.0",
|
||||
"adm-zip": "^0.5.9",
|
||||
"axios": "^0.26.1",
|
||||
"cors": "^2.8.5",
|
||||
"express": "^4.17.3",
|
||||
"typescript": "^4.6.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/adm-zip": "^0.4.34",
|
||||
"@types/node": "^17.0.22",
|
||||
"npm-run-all": "^4.1.5"
|
||||
}
|
||||
}
|
||||
|
87
src/HttpRequests.ts
Normal file
87
src/HttpRequests.ts
Normal file
@ -0,0 +1,87 @@
|
||||
import axios from "axios";
|
||||
|
||||
type githubRelease = {
|
||||
url: string;
|
||||
assets_url: string;
|
||||
upload_url: string;
|
||||
html_url: string;
|
||||
id: number;
|
||||
tarball_url: string;
|
||||
zipball_url: string;
|
||||
body: string;
|
||||
author: {
|
||||
login: string;
|
||||
id: number;
|
||||
node_id: string;
|
||||
avatar_url: string;
|
||||
gravatar_id: string;
|
||||
url: string;
|
||||
html_url: string;
|
||||
followers_url: string;
|
||||
following_url: string;
|
||||
gists_url: string;
|
||||
starred_url: string;
|
||||
subscriptions_url: string;
|
||||
organizations_url: string;
|
||||
repos_url: string;
|
||||
events_url: string;
|
||||
received_events_url: string;
|
||||
type: string;
|
||||
site_admin: boolean;
|
||||
};
|
||||
node_id: string;
|
||||
tag_name: string;
|
||||
target_commitish: string;
|
||||
name: string;
|
||||
draft: boolean;
|
||||
prerelease: boolean;
|
||||
created_at: string;
|
||||
published_at: string;
|
||||
assets: Array<{
|
||||
url: string;
|
||||
id: number;
|
||||
node_id: string;
|
||||
name: string;
|
||||
label: string;
|
||||
content_type: string;
|
||||
state: string;
|
||||
size: number;
|
||||
download_count: number;
|
||||
created_at: string;
|
||||
updated_at: string;
|
||||
browser_download_url: string;
|
||||
uploader: {
|
||||
login: string;
|
||||
id: number;
|
||||
node_id: string;
|
||||
avatar_url: string;
|
||||
gravatar_id: string;
|
||||
url: string;
|
||||
html_url: string;
|
||||
followers_url: string;
|
||||
following_url: string;
|
||||
gists_url: string;
|
||||
starred_url: string;
|
||||
subscriptions_url: string;
|
||||
organizations_url: string;
|
||||
repos_url: string;
|
||||
events_url: string;
|
||||
received_events_url: string;
|
||||
type: string;
|
||||
site_admin: boolean;
|
||||
};
|
||||
}>;
|
||||
};
|
||||
|
||||
export async function getBuffer(url: string, headers: {[d: string]: any} = {}): Promise<Buffer> {
|
||||
const dataReponse = await axios.get(url, {
|
||||
headers: (headers||{}),
|
||||
responseType: "arraybuffer",
|
||||
});
|
||||
return Buffer.from(dataReponse.data);
|
||||
}
|
||||
|
||||
export async function getGithubRelease(Username: string, Repo: string): Promise<Array<githubRelease>> {
|
||||
const data = await getBuffer(`https://api.github.com/repos/${Username}/${Repo}/releases`);
|
||||
return JSON.parse(data.toString("utf8"));
|
||||
}
|
@ -1,6 +1,64 @@
|
||||
import BdsManegerVersions from "@the-bds-maneger/server_versions/src/cjs/index";
|
||||
import axios from "axios";
|
||||
import path from "path";
|
||||
import fs from "fs";
|
||||
import os from "os";
|
||||
import adm_zip from "adm-zip";
|
||||
import { getBuffer, getGithubRelease } from "./HttpRequests";
|
||||
|
||||
async function DownloadServer(Version: string|boolean, Platform: "bedrock"|"java"|"pocketmine"|"spigot"|"dragonfly") {
|
||||
if (Platform === "bedrock") {}
|
||||
type getVersionsType = {
|
||||
latest: {
|
||||
[d: string]: string|undefined
|
||||
};
|
||||
platform: Array<{
|
||||
name: "pocketmine"|"java"|"bedrock"|"dragonfly"|"spigot";
|
||||
version: string;
|
||||
Date: string;
|
||||
data: string | {[platform: string]: {[arch: string]: string;};};
|
||||
}>;
|
||||
};
|
||||
|
||||
export async function getVersions(): Promise<getVersionsType> {
|
||||
return JSON.parse((await getBuffer("https://raw.githubusercontent.com/The-Bds-Maneger/ServerVersions/main/src/Versions.json")).toString("utf8"));
|
||||
}
|
||||
|
||||
async function InstallPHP(PathToInstall: string) {
|
||||
const Release = (await getGithubRelease("The-Bds-Maneger", "PocketMinePHPAutoBinBuilds"))[0].assets.find(asset => RegExp(process.platform).test(asset.name) && RegExp(os.arch()).test(asset.name));
|
||||
if (!Release) throw new Error("No file found for this Platform and Arch");
|
||||
const PHPZip = new adm_zip(await getBuffer(Release.browser_download_url));
|
||||
if (fs.existsSync(path.resolve(PathToInstall, "bin"))) await fs.promises.rmdir(path.resolve(PathToInstall, "bin"), {recursive: true});
|
||||
PHPZip.extractAllTo(PathToInstall, true);
|
||||
return Release;
|
||||
}
|
||||
|
||||
export async function DownloadServer(Platform: "bedrock"|"java"|"pocketmine"|"spigot"|"dragonfly", Version: string|boolean) {
|
||||
const ServerPath = path.resolve(process.env.SERVERPATH||path.join(os.homedir(), "bds_core"));
|
||||
const versions = await getVersions()
|
||||
const info = versions.platform.filter(v => v.name === Platform).find(v => v.version === (typeof Version === "boolean"?versions.latest[Platform]:Version));
|
||||
if (Platform === "bedrock") {
|
||||
const BedrockPath = path.resolve(ServerPath, "bedrock");
|
||||
if (!(await fs.existsSync(BedrockPath))) fs.mkdirSync(BedrockPath, {recursive: true});
|
||||
const BedrockZip = new adm_zip(await getBuffer(info.data[process.platform][process.arch]));
|
||||
BedrockZip.extractAllTo(BedrockPath, true);
|
||||
} else if (Platform === "java") {
|
||||
const JavaPath = path.resolve(ServerPath, "java");
|
||||
if (!(await fs.existsSync(JavaPath))) fs.mkdirSync(JavaPath, {recursive: true});
|
||||
await fs.promises.writeFile(path.resolve(JavaPath, "Server.jar"), await getBuffer(String(info.data)));
|
||||
} else if (Platform === "spigot") {
|
||||
const SpigotPath = path.resolve(ServerPath, "spigot");
|
||||
if (!(await fs.existsSync(SpigotPath))) fs.mkdirSync(SpigotPath, {recursive: true});
|
||||
await fs.promises.writeFile(path.resolve(SpigotPath, "Spigot.jar"), await getBuffer(String(info.data)));
|
||||
} else if (Platform === "pocketmine") {
|
||||
const PocketminePath = path.resolve(ServerPath, "pocketmine");
|
||||
if (!(await fs.existsSync(PocketminePath))) fs.mkdirSync(PocketminePath, {recursive: true});
|
||||
await InstallPHP(PocketminePath);
|
||||
await fs.promises.writeFile(path.resolve(PocketminePath, "PocketMine.phar"), await getBuffer(String(info.data)));
|
||||
} else if (Platform === "dragonfly") {
|
||||
const DragonflyPath = path.resolve(ServerPath, "dragonfly");
|
||||
if (!(await fs.existsSync(DragonflyPath))) fs.mkdirSync(DragonflyPath, {recursive: true});
|
||||
await fs.promises.writeFile(path.resolve(DragonflyPath, "Dragonfly"+(process.platform === "win32"?".exe":"")), await getBuffer(String(info.data)));
|
||||
}
|
||||
return {
|
||||
Version: info.version,
|
||||
Date: new Date(info.Date),
|
||||
url: (typeof info.data === "string"? info.data : info.data[process.platform][process.arch])
|
||||
};
|
||||
}
|
90
src/server.ts
Normal file
90
src/server.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import path from "path";
|
||||
import os from "os";
|
||||
import crypto from "crypto";
|
||||
import child_process from "child_process";
|
||||
|
||||
type Session = {
|
||||
startDate: Date;
|
||||
on: (from: "stdout"|"stderr", callback: (data: string) => void) => void;
|
||||
exit: (callback: (code: number, signal: string) => void) => void;
|
||||
commands: {
|
||||
tpPlayer: (username: string, x: number, y: number, z: number) => void;
|
||||
execCommand: (command: string) => void;
|
||||
}
|
||||
};
|
||||
|
||||
const Sessions: {[Session: string]: Session} = {};
|
||||
export async function getSessions() {return Sessions;}
|
||||
|
||||
export function Start(Platform: "bedrock"|"java"|"pocketmine"|"spigot"|"dragonfly"): Session {
|
||||
const ServerPath = path.resolve(process.env.SERVERPATH||path.join(os.homedir(), "bds_core"));
|
||||
const Process: {command: string; args: Array<string>; env: {[env: string]: string}; cwd: string;} = {
|
||||
command: "",
|
||||
args: [],
|
||||
env: {...process.env},
|
||||
cwd: process.cwd()
|
||||
};
|
||||
if (Platform === "bedrock") {
|
||||
if (process.platform === "darwin") throw new Error("Run Docker image");
|
||||
Process.command = path.resolve(ServerPath, "bedrock/bedrock"+(process.platform === "win32"?".exe":""));
|
||||
if (process.platform !== "win32") {
|
||||
child_process.execFileSync("chmod", ["a+x", Process.command]);
|
||||
Process.env.LD_LIBRARY_PATH = path.resolve(ServerPath, "bedrock");
|
||||
if (process.arch !== "x64") {
|
||||
console.warn("Minecraft bedrock start with emulated x64 architecture");
|
||||
Process.args.push(Process.command);
|
||||
Process.command = "qemu-x86_64-static";
|
||||
}
|
||||
}
|
||||
} else if (Platform === "java"||Platform === "spigot") {
|
||||
Process.command = "java";
|
||||
Process.args.push("-jar");
|
||||
if (Platform === "java") Process.args.push(path.resolve(ServerPath, "java/Server.jar"));
|
||||
else Process.args.push(path.resolve(ServerPath, "spigot/Spigot.jar"));
|
||||
} else if (Platform === "pocketmine") {
|
||||
if (process.platform === "win32") Process.command = path.resolve(ServerPath, "pocketmine/bins/php/php");
|
||||
else Process.command = path.resolve(ServerPath, "pocketmine/bins/php7/bin/php");
|
||||
Process.args.push(path.resolve(ServerPath, "pocketmine/PocketMine-MP.phar"));
|
||||
}
|
||||
|
||||
// Start Server
|
||||
const ServerProcess = child_process.execFile(Process.command, Process.args, {env: Process.env, cwd: Process.cwd, maxBuffer: Infinity});
|
||||
const StartDate = new Date();
|
||||
|
||||
// Log callback
|
||||
const onLog = (from: "stdout"|"stderr", callback: (data: string) => void) => {
|
||||
ServerProcess[from].on("data", callback);
|
||||
return;
|
||||
}
|
||||
|
||||
// Exit callback
|
||||
const onExit = (callback: (code: number, signal: string) => void): void => {
|
||||
ServerProcess.on("exit", callback);
|
||||
}
|
||||
|
||||
// Run Command
|
||||
const execCommand = (...command) => {
|
||||
ServerProcess.stdin.write(command.join(" ")+"\n");
|
||||
return;
|
||||
};
|
||||
|
||||
// Teleport player
|
||||
const tpPlayer = (username: string, x: number, y: number, z: number) => {
|
||||
execCommand("tp", username, x, y, z);
|
||||
return;
|
||||
}
|
||||
|
||||
// Return Session
|
||||
const Seesion = {
|
||||
id: crypto.randomUUID(),
|
||||
startDate: StartDate,
|
||||
on: onLog,
|
||||
exit: onExit,
|
||||
commands: {
|
||||
execCommand: execCommand,
|
||||
tpPlayer: tpPlayer,
|
||||
}
|
||||
};
|
||||
Sessions[Seesion.id] = Seesion;
|
||||
return Seesion;
|
||||
}
|
Reference in New Issue
Block a user