Rewrite in typescrypt #327

Merged
Sirherobrine23 merged 13 commits from re_Typescript into main 2022-03-28 21:43:14 +00:00
10 changed files with 1709 additions and 1457 deletions
Showing only changes of commit be7a0d23fe - Show all commits

View File

@ -1,5 +1,3 @@
node_modules/ node_modules/
.git/ .git/
*.log dist/
Test
test

View File

@ -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
View File

@ -1,2 +0,0 @@
* text=lf eol=lf
*.sh text=lf eol=lf

15
.gitignore vendored
View File

@ -1,14 +1,5 @@
# Log
*.log *.log
# Node
node_modules/ node_modules/
.dccache dist/
docs/ src/**/*.d.ts
the-bds-maneger-core-*.tgz src/**/*.d.js
# **
.husky
Servers
.Build/Releases.json
esm/

View File

@ -1,31 +1 @@
# Log !dist/
*.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/**/*

2829
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -7,12 +7,15 @@
"version": "2.0.0", "version": "2.0.0",
"description": "A very simple way to manage Minecraft servers", "description": "A very simple way to manage Minecraft servers",
"main": "dist/index.js", "main": "dist/index.js",
"types": "src/index.ts",
"exports": { "exports": {
"require": "./dist/src/index.js", "require": "./dist/src/index.js",
"import": "./dist/esm/index.js" "import": "./dist/esm/index.js"
}, },
"scripts": { "scripts": {
"build": "tsc" "build": "run-s build:*",
"build:cjs": "tsc --module commonjs --outDir dist/cjs",
"build:esm": "tsc --module es2020 --outDir dist/esm"
}, },
"nodemonConfig": { "nodemonConfig": {
"ignore": [ "ignore": [
@ -60,10 +63,15 @@
"android" "android"
], ],
"dependencies": { "dependencies": {
"@the-bds-maneger/server_versions": "^1.1.0", "adm-zip": "^0.5.9",
"axios": "^0.26.1", "axios": "^0.26.1",
"cors": "^2.8.5", "cors": "^2.8.5",
"express": "^4.17.3", "express": "^4.17.3",
"typescript": "^4.6.2" "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
View 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"));
}

View File

@ -1,6 +1,64 @@
import BdsManegerVersions from "@the-bds-maneger/server_versions/src/cjs/index"; import path from "path";
import axios from "axios"; 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") { type getVersionsType = {
if (Platform === "bedrock") {} 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
View 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;
}