Monorepo project #508
| @@ -1,11 +0,0 @@ | ||||
| FROM ghcr.io/sirherobrine23/initjs:latest | ||||
| # Install dependecies to Bedrock server | ||||
| RUN (apt update && apt install -y libssl1.1 || (echo "deb http://security.ubuntu.com/ubuntu focal-security main" | tee /etc/apt/sources.list.d/focal-security.list && apt update && apt install -y libssl1.1)) || echo exit $? | ||||
|  | ||||
| # Add non root user and Install oh my zsh | ||||
| ARG USERNAME="devcontainer" | ||||
| ARG USER_UID="1000" | ||||
| ARG USER_GID=$USER_UID | ||||
| RUN initjs create-user --username "${USERNAME}" --uid "${USER_UID}" --gid "${USER_GID}" --groups sudo --groups docker | ||||
| USER $USERNAME | ||||
| WORKDIR /home/$USERNAME | ||||
| @@ -1,49 +0,0 @@ | ||||
| { | ||||
|   "name": "Bds Maneger Core", | ||||
|   "updateRemoteUserUID": false, | ||||
|   "containerUser": "develop", | ||||
|   "remoteUser": "develop", | ||||
|   "overrideCommand": false, | ||||
|   "postCreateCommand": "npm install", | ||||
|   "build": { | ||||
|     "dockerfile": "Dockerfile", | ||||
|     "args": { | ||||
|       "USERNAME": "develop", | ||||
|       "USER_UID": "1000" | ||||
|     } | ||||
|   }, | ||||
|   "runArgs": [ | ||||
|     "--init", | ||||
|     "--privileged" | ||||
|   ], | ||||
|   "mounts": [ | ||||
|     "target=/var/lib/docker,type=volume,source=bdsmanegercore" | ||||
|   ], | ||||
|   "extensions": [ | ||||
| 		"benshabatnoam.google-translate-ext", | ||||
| 		"eamodio.gitlens", | ||||
| 		"github.vscode-pull-request-github", | ||||
| 		"visualstudioexptteam.vscodeintellicode", | ||||
| 		"redhat.vscode-yaml", | ||||
| 		"ms-vscode-remote.remote-containers", | ||||
| 		"wix.vscode-import-cost", | ||||
| 		"eg2.vscode-npm-script", | ||||
| 		"christian-kohler.npm-intellisense", | ||||
| 		"christian-kohler.path-intellisense", | ||||
| 		"aaron-bond.better-comments", | ||||
| 		"vscode-icons-team.vscode-icons", | ||||
| 		"me-dutour-mathieu.vscode-github-actions", | ||||
| 		"cschleiden.vscode-github-actions", | ||||
| 		"oderwat.indent-rainbow", | ||||
| 		"ms-azuretools.vscode-docker", | ||||
| 		"formulahendry.code-runner", | ||||
| 		"chrmarti.regex" | ||||
| 	], | ||||
| 	"settings": { | ||||
|     "editor.tabSize": 2, | ||||
|     "editor.minimap.enabled": false, | ||||
|     "files.eol": "\n", | ||||
|     "files.trimFinalNewlines": true, | ||||
|     "files.trimTrailingWhitespace": true | ||||
|   } | ||||
| } | ||||
| @@ -10,4 +10,4 @@ updates: | ||||
|     schedule: | ||||
|       interval: monthly | ||||
|     assignees: | ||||
|       - Sirherobrine23 | ||||
|       - Sirherobrine23 | ||||
							
								
								
									
										29
									
								
								.github/spigotBuilld/index.mjs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										29
									
								
								.github/spigotBuilld/index.mjs
									
									
									
									
										vendored
									
									
								
							| @@ -1,29 +0,0 @@ | ||||
| #!/usr/bin/env node | ||||
| import { createReadStream, promises as fs } from "node:fs"; | ||||
| import { Cloud, Extends } from "@sirherobrine23/coreutils"; | ||||
| import path from "path"; | ||||
| const { tenancy, fingerprint, privateKey, user, passphase } = process.env; | ||||
| const oracleBucket = await Cloud.oracleBucket({ | ||||
|   region: "sa-saopaulo-1", | ||||
|   name: "bdsFiles", | ||||
|   namespace: "grwodtg32n4d", | ||||
|   auth: { | ||||
|     type: "user", | ||||
|     tenancy, | ||||
|     fingerprint, | ||||
|     privateKey, | ||||
|     user, | ||||
|     passphase | ||||
|   } | ||||
| }) | ||||
| const __dirname = path.resolve(process.cwd(), process.argv.slice(2)[0]||""); | ||||
|  | ||||
| await Extends.extendsFS.readdir({folderPath: __dirname}).then(files => files.filter(file => file.endsWith(".jar"))).then(async files => { | ||||
|   for (const file of files) { | ||||
|     const version = path.basename(file, ".jar").split("-")[1]; | ||||
|     if (!version) continue; | ||||
|     console.log("Uploading %s, file: %O", version, "SpigotBuild/"+version+".jar"); | ||||
|     await oracleBucket.uploadFile("SpigotBuild/"+version+".jar", createReadStream(file)).then(() => console.log("Uploaded %s", version)); | ||||
|     await fs.unlink(file); | ||||
|   } | ||||
| }); | ||||
							
								
								
									
										24
									
								
								.github/uploadphp/index.mjs
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										24
									
								
								.github/uploadphp/index.mjs
									
									
									
									
										vendored
									
									
								
							| @@ -1,24 +0,0 @@ | ||||
| #!/usr/bin/env node | ||||
| import { createReadStream } from "node:fs"; | ||||
| import coreutils, { extendFs } from "@sirherobrine23/coreutils"; | ||||
| import path from "node:path"; | ||||
| import fs from "node:fs/promises"; | ||||
| if (!process.env.OCI_AUTHKEY) throw new Error("No key auth"); | ||||
| const ociKeyAuth = (process.env.OCI_AUTHKEY||"").trim(); | ||||
| console.log("using key to upload '%s'", ociKeyAuth); | ||||
|  | ||||
| const files = (await extendFs.readdir({folderPath: path.join(process.cwd(), "phpOutput")})).filter(file => file.endsWith(".tar.gz")||file.endsWith(".zip")||file.endsWith(".tgz")); | ||||
| await Promise.all(files.map(async file => { | ||||
|   const fileName = path.basename(file); | ||||
|   console.log("Uploading %s", fileName); | ||||
|   await coreutils.httpRequest.bufferFetch({ | ||||
|     url: `https://objectstorage.sa-saopaulo-1.oraclecloud.com/p/${ociKeyAuth}/n/grwodtg32n4d/b/bdsFiles/o/php_bin/${encodeURIComponent(fileName.toLowerCase())}`, | ||||
|     method: "PUT", | ||||
|     body: createReadStream(file), | ||||
|     headers: { | ||||
|       "Content-Length": (await fs.lstat(file)).size.toString(), | ||||
|       "Content-Type": "application/octet-stream" | ||||
|     } | ||||
|   }); | ||||
|   console.log("Upload success to %s", fileName); | ||||
| })); | ||||
							
								
								
									
										43
									
								
								.github/workflows/code_analyzer.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								.github/workflows/code_analyzer.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,43 +0,0 @@ | ||||
| name: Code Analyze | ||||
| on: | ||||
|   push: | ||||
|     branches: | ||||
|       - main | ||||
|   pull_request: | ||||
|     branches: | ||||
|       - main | ||||
|   schedule: | ||||
|     - cron: "26 8 * * 1" | ||||
|  | ||||
| jobs: | ||||
|   snyk: | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - uses: actions/checkout@master | ||||
|       - name: Run Snyk to check for vulnerabilities | ||||
|         uses: snyk/actions/node@master | ||||
|         continue-on-error: true | ||||
|         env: | ||||
|           SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} | ||||
|         with: | ||||
|           args: --sarif-file-output=snyk.sarif | ||||
|       - name: Upload result to GitHub Code Scanning | ||||
|         continue-on-error: true | ||||
|         uses: github/codeql-action/upload-sarif@v2 | ||||
|         with: | ||||
|           sarif_file: snyk.sarif | ||||
|  | ||||
|   codeql: | ||||
|     name: CodeQL Analyze | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout repository | ||||
|         uses: actions/checkout@v2 | ||||
|       - name: Initialize CodeQL | ||||
|         uses: github/codeql-action/init@v2 | ||||
|         with: | ||||
|           languages: javascript | ||||
|       - name: Autobuild | ||||
|         uses: github/codeql-action/autobuild@v2 | ||||
|       - name: Perform CodeQL Analysis | ||||
|         uses: github/codeql-action/analyze@v2 | ||||
							
								
								
									
										43
									
								
								.github/workflows/gendocs.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										43
									
								
								.github/workflows/gendocs.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -1,43 +0,0 @@ | ||||
| name: Deploy bds core wiki | ||||
| on: | ||||
|   push: | ||||
|     branches: | ||||
|     - main | ||||
|     paths: | ||||
|     - "src/**/*" | ||||
|     - "tests/**/*" | ||||
|     - "package*.json" | ||||
|  | ||||
| permissions: | ||||
|   contents: read | ||||
|   pages: write | ||||
|   id-token: write | ||||
|  | ||||
| jobs: | ||||
|   deploy_doc: | ||||
|     environment: | ||||
|       name: github-pages | ||||
|       url: ${{ steps.deployment.outputs.page_url }} | ||||
|     runs-on: ubuntu-latest | ||||
|     steps: | ||||
|       - name: Checkout | ||||
|         uses: actions/checkout@v3 | ||||
|  | ||||
|       - uses: actions/setup-node@v3.6.0 | ||||
|         name: Setup node.js | ||||
|         with: | ||||
|           node-version: latest | ||||
|  | ||||
|       - run: npm ci | ||||
|  | ||||
|       - name: Gen docs | ||||
|         run: npm run docs | ||||
|  | ||||
|       - name: Upload artifact | ||||
|         uses: actions/upload-pages-artifact@v1 | ||||
|         with: | ||||
|           path: "docs" | ||||
|  | ||||
|       - name: Deploy to GitHub Pages | ||||
|         id: deployment | ||||
|         uses: actions/deploy-pages@v1 | ||||
							
								
								
									
										221
									
								
								.github/workflows/php_buid.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										221
									
								
								.github/workflows/php_buid.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,221 +0,0 @@ | ||||
| name: PHP build | ||||
| on: | ||||
|   workflow_dispatch: | ||||
|   schedule: | ||||
|     - cron: "0 0 */2 * 0" | ||||
|  | ||||
| jobs: | ||||
|   # Android Build arm64 | ||||
|   android: | ||||
|     runs-on: ubuntu-latest | ||||
|     name: Android | ||||
|     steps: | ||||
|       - name: Clone Repository | ||||
|         uses: actions/checkout@v3 | ||||
|         with: | ||||
|           repository: pmmp/php-build-scripts | ||||
|           submodules: true | ||||
|  | ||||
|       - name: Cache musl | ||||
|         uses: actions/cache@v3 | ||||
|         with: | ||||
|           key: ${{ runner.os }}-android_musl | ||||
|           path: muslCrossMake | ||||
|  | ||||
|       - name: Build musl to android | ||||
|         env: | ||||
|           DEBIAN_FRONTEND: "noninteractive" | ||||
|         run: | | ||||
|           set -ex | ||||
|           sudo apt update | ||||
|           sudo apt -y install build-essential curl make autoconf automake libtool m4 wget gzip bzip2 bison g++ git cmake pkg-config re2c libtool* unzip zip tar | ||||
|  | ||||
|           # Build musl | ||||
|           if ! [[ -d muslCrossMake ]];then | ||||
|             mkdir muslCrossMake | ||||
|             INITIAL_PATH="$(pwd)" | ||||
|             cd muslCrossMake | ||||
|             git clone https://github.com/pmmp/musl-cross-make.git ./ | ||||
|             (echo "TARGET = aarch64-linux-musl"; echo "OUTPUT = /usr/local") > config.mak | ||||
|             make | ||||
|             sudo make install -j$(nproc) | ||||
|           else | ||||
|             cd muslCrossMake | ||||
|             sudo make install -j$(nproc) | ||||
|           fi | ||||
|  | ||||
|       - name: "Building php bin" | ||||
|         continue-on-error: true | ||||
|         timeout-minutes: 40 | ||||
|         run: | | ||||
|           ./compile.sh -t android-aarch64 -x -f -g -j$(nproc) | ||||
|           # Compress files | ||||
|           cd bin/php*/ | ||||
|           pwd | ||||
|           # ZIP | ||||
|           zip -r "${{ github.workspace }}/android_arm64.zip" * | ||||
|           # tar | ||||
|           tar -czf "${{ github.workspace }}/android_arm64.tar.gz" * | ||||
|  | ||||
|       - name: Upload artifacts | ||||
|         uses: actions/upload-artifact@v3 | ||||
|         with: | ||||
|           name: android_arm64 | ||||
|           path: "*.tar.gz" | ||||
|  | ||||
|   # Linux Build | ||||
|   linux: | ||||
|     strategy: | ||||
|       fail-fast: false | ||||
|       matrix: | ||||
|         target: | ||||
|         - ubuntu-latest | ||||
|         - arm64 | ||||
|     name: "Linux - ${{ matrix.target }}" | ||||
|     runs-on: ${{ matrix.target }} | ||||
|     steps: | ||||
|       - name: Clone Repository | ||||
|         uses: actions/checkout@v3 | ||||
|         with: | ||||
|           repository: pmmp/php-build-scripts | ||||
|           submodules: true | ||||
|  | ||||
|       - name: Install tools and dependencies | ||||
|         run: | | ||||
|           sudo apt-get update | ||||
|           sudo apt-get install -y cmake pkg-config make autoconf automake libtool libtool-bin m4 wget libc-bin gzip bzip2 bison g++ git re2c zip tar | ||||
|  | ||||
|       - name: Compile PHP | ||||
|         continue-on-error: true | ||||
|         timeout-minutes: 40 | ||||
|         run: | | ||||
|           set -ex | ||||
|           ./compile.sh -j 4 -f -g -s | ||||
|  | ||||
|           # Compress files | ||||
|           cd bin/php*/ | ||||
|           pwd | ||||
|           # ZIP | ||||
|           zip -r "${{ github.workspace }}/linux_${{ runner.arch }}.zip" * | ||||
|           # tar | ||||
|           tar -czf "${{ github.workspace }}/linux_${{ runner.arch }}.tar.gz" * | ||||
|  | ||||
|       - name: Upload artifacts | ||||
|         uses: actions/upload-artifact@v3 | ||||
|         with: | ||||
|           name: linux_${{ runner.arch }} | ||||
|           path: | | ||||
|             *.tar.gz | ||||
|             *.zip | ||||
|  | ||||
|   # MacOS Build | ||||
|   macos: | ||||
|     runs-on: macos-11 | ||||
|     name: MacOS | ||||
|     steps: | ||||
|       - name: Clone Repository | ||||
|         uses: actions/checkout@v3 | ||||
|         with: | ||||
|           repository: pmmp/php-build-scripts | ||||
|           submodules: true | ||||
|  | ||||
|       - name: Install dependecies | ||||
|         run: brew install libtool autoconf automake pkg-config bison re2c | ||||
|  | ||||
|       - name: "Building php" | ||||
|         continue-on-error: true | ||||
|         timeout-minutes: 40 | ||||
|         run: | | ||||
|           export PATH="/usr/local/opt/bison/bin:$PATH" | ||||
|           set -ex | ||||
|           trap "exit 1" ERR | ||||
|           ./compile.sh -j4 -f -g || (cat *.log && exit 1) | ||||
|  | ||||
|       - name: Create tarballs | ||||
|         run: | | ||||
|           cd bin/*/ | ||||
|           pwd | ||||
|           # ZIP | ||||
|           zip -r "${{ github.workspace }}/darwin_${{ runner.arch }}.zip" * | ||||
|           # tar | ||||
|           tar -czf "${{ github.workspace }}/darwin_${{ runner.arch }}.tar.gz" * | ||||
|  | ||||
|       - name: Upload artifacts | ||||
|         uses: actions/upload-artifact@v3 | ||||
|         with: | ||||
|           name: darwin_${{ runner.arch }} | ||||
|           path: | | ||||
|             *.tar.gz | ||||
|             *.zip | ||||
|  | ||||
|   # Windows build | ||||
|   win32: | ||||
|     runs-on: windows-2019 | ||||
|     name: Windows | ||||
|     steps: | ||||
|       - name: Clone Repository | ||||
|         uses: actions/checkout@v3 | ||||
|         with: | ||||
|           repository: pmmp/php-build-scripts | ||||
|           submodules: true | ||||
|  | ||||
|       - name: Windows Depencies Install | ||||
|         run: choco install --no-progress wget | ||||
|  | ||||
|       - name: "Building php bin" | ||||
|         run: .\windows-compile-vs.bat | ||||
|         env: | ||||
|           VS_EDITION: Enterprise | ||||
|           SOURCES_PATH: ${{ github.workspace }}\pocketmine-php-sdk | ||||
|  | ||||
|       - name: show log | ||||
|         run: type compile.log | ||||
|  | ||||
|       - name: Rename files | ||||
|         shell: node {0} | ||||
|         run: | | ||||
|           const fs = require("fs"); | ||||
|           const path = require("path"); | ||||
|           const files = fs.readdirSync(process.cwd()).filter(file => file.endsWith(".zip")); | ||||
|           for (const zip of files) { | ||||
|             console.log("File:", path.join(process.cwd(), zip)); | ||||
|             if (/debug/i.test(zip)) fs.rmSync(path.join(process.cwd(), zip)); | ||||
|             else fs.renameSync(path.join(process.cwd(), zip), path.join(process.cwd(), "win32_x64.zip")); | ||||
|           } | ||||
|  | ||||
|       - name: Upload artifacts | ||||
|         uses: actions/upload-artifact@v3 | ||||
|         with: | ||||
|           name: Windows | ||||
|           path: "*.zip" | ||||
|  | ||||
|   # Upload to bucket | ||||
|   upload: | ||||
|     runs-on: ubuntu-latest | ||||
|     needs: | ||||
|     - win32 | ||||
|     - macos | ||||
|     - linux | ||||
|     - android | ||||
|     steps: | ||||
|     - uses: actions/checkout@v3 | ||||
|       name: Code checkout | ||||
|  | ||||
|     - uses: actions/setup-node@v3.6.0 | ||||
|       name: Setup node.js | ||||
|       with: | ||||
|         node-version: latest | ||||
|  | ||||
|     - name: Install node depencies | ||||
|       run: npm install --no-save | ||||
|  | ||||
|     - name: Download tarbals | ||||
|       uses: actions/download-artifact@v3 | ||||
|       with: | ||||
|         path: ./phpOutput | ||||
|  | ||||
|     - name: Upload to bucket | ||||
|       run: node .github/uploadphp/index.mjs | ||||
|       timeout-minutes: 25 | ||||
|       env: | ||||
|         OCI_AUTHKEY: ${{ secrets.OCI_AUTHKEY }} | ||||
							
								
								
									
										69
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										69
									
								
								.github/workflows/publish.yml
									
									
									
									
										vendored
									
									
								
							| @@ -1,69 +0,0 @@ | ||||
| name: Publish package | ||||
| on: | ||||
|   release: | ||||
|     types: | ||||
|       - prereleased | ||||
|       - released | ||||
|  | ||||
| permissions: | ||||
|   pull-requests: write | ||||
|   id-token: write | ||||
|  | ||||
| jobs: | ||||
|   publishpackage: | ||||
|     runs-on: ubuntu-latest | ||||
|     name: Publish | ||||
|     steps: | ||||
|     - uses: actions/checkout@v3 | ||||
|       name: Code checkout | ||||
|       with: | ||||
|         persist-credentials: true | ||||
|         ref: main | ||||
|         fetch-depth: 2 | ||||
|         submodules: true | ||||
|  | ||||
|     # Install basic tools | ||||
|     - uses: actions/setup-node@v3.6.0 | ||||
|       name: Setup node.js | ||||
|       with: | ||||
|         registry-url: https://registry.npmjs.org/ | ||||
|         node-version: latest | ||||
|  | ||||
|     - name: Edit version | ||||
|       shell: node {0} | ||||
|       run: | | ||||
|         const fs = require("fs"); | ||||
|         const path = require("path"); | ||||
|         const packagePath = path.join(process.cwd(), "package.json"); | ||||
|         const package = JSON.parse(fs.readFileSync(packagePath, "utf8")); | ||||
|         package.version = "${{ github.ref }}"; | ||||
|         package.version = package.version.replace(/[A-Za-z_\/]+/, ""); | ||||
|         fs.writeFileSync(packagePath, JSON.stringify(package, null, 2)); | ||||
|  | ||||
|     # Install depencides and build | ||||
|     - run: npm ci && npm run build | ||||
|  | ||||
|     # Publish | ||||
|     - run: npm publish --tag ${{ github.event.release.prerelease && 'next' || 'latest' }} | ||||
|       name: Publish to npm | ||||
|       env: | ||||
|         NODE_AUTH_TOKEN: ${{ secrets.NPM_ORG_TOKEN }} | ||||
|  | ||||
|     # Add version to environment variables | ||||
|     - name: Add version to environment variables | ||||
|       run: | | ||||
|         cat package.json | jq -r '.version' > /tmp/version.txt | ||||
|         echo "PACKAGE_VERSION=$(cat /tmp/version.txt)" >> $GITHUB_ENV | ||||
|  | ||||
|     # Create pull request to update version in main branch | ||||
|     - uses: peter-evans/create-pull-request@v4 | ||||
|       name: Create Pull Request | ||||
|       continue-on-error: true | ||||
|       with: | ||||
|         commit-message: Update version v${{ env.PACKAGE_VERSION }} | ||||
|         delete-branch: true | ||||
|         assignees: SirHerobrine23 | ||||
|         reviewers: SirHerobrine23 | ||||
|         branch: update-version | ||||
|         title: Update package version v${{ env.PACKAGE_VERSION }} | ||||
|         body: Auto update package version, created with GitHub Actions | ||||
							
								
								
									
										116
									
								
								.github/workflows/spigotBuild.yaml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										116
									
								
								.github/workflows/spigotBuild.yaml
									
									
									
									
										vendored
									
									
								
							| @@ -1,116 +0,0 @@ | ||||
| name: Spigot Build | ||||
| on: | ||||
|   workflow_dispatch: | ||||
|   schedule: | ||||
|     - cron: "0 0 */2 * 0" | ||||
|   push: | ||||
|     branches: | ||||
|       - main | ||||
|     paths: | ||||
|       - ".github/workflows/spigotBuild.yaml" | ||||
|       - ".github/spigotBuilld/**/*" | ||||
|  | ||||
| jobs: | ||||
|   build: | ||||
|     runs-on: ubuntu-latest | ||||
|     strategy: | ||||
|       matrix: | ||||
|         version: | ||||
|         - latest | ||||
|         - "1.19.2" | ||||
|         - "1.19.1" | ||||
|         - "1.19" | ||||
|         - "1.18.2" | ||||
|         - "1.18.1" | ||||
|         - "1.18-rc3" | ||||
|         - "1.18-pre8" | ||||
|         - "1.18-pre5" | ||||
|         - "1.18" | ||||
|         - "1.17.1" | ||||
|         - "1.17" | ||||
|         - "1.16.5" | ||||
|         - "1.16.4" | ||||
|         - "1.16.3" | ||||
|         - "1.16.2" | ||||
|         - "1.16.1" | ||||
|         - "1.15.2" | ||||
|         - "1.15.1" | ||||
|         - "1.15" | ||||
|         - "1.14.4" | ||||
|         - "1.14.3-pre4" | ||||
|         - "1.14.3" | ||||
|         - "1.14.2" | ||||
|         - "1.14.1" | ||||
|         - "1.14-pre5" | ||||
|         - "1.14" | ||||
|         - "1.13.2" | ||||
|         - "1.13.1" | ||||
|         - "1.13-pre7" | ||||
|         - "1.13" | ||||
|         - "1.12.2" | ||||
|         - "1.12.1" | ||||
|         - "1.12" | ||||
|         - "1.11.2" | ||||
|         - "1.11.1" | ||||
|         - "1.11" | ||||
|         - "1.10.2" | ||||
|         - "1.10" | ||||
|         - "1.9.4" | ||||
|         - "1.9.2" | ||||
|         - "1.9" | ||||
|         - "1.8.8" | ||||
|         - "1.8.7" | ||||
|         - "1.8.6" | ||||
|         - "1.8.5" | ||||
|         - "1.8.4" | ||||
|         - "1.8.3" | ||||
|         - "1.8" | ||||
|     steps: | ||||
|     - name: Install ${{ startsWith(matrix.version, 'latest') && '19' || (startsWith(matrix.version, '1.19')||startsWith(matrix.version, '1.18')) && '17' || startsWith(matrix.version, '1.17') && '16' || '8' }} java | ||||
|       uses: actions/setup-java@v3 | ||||
|       continue-on-error: true | ||||
|       with: | ||||
|         distribution: liberica | ||||
|         java-version: ${{ (startsWith(matrix.version, 'latest')||startsWith(matrix.version, '1.19')||startsWith(matrix.version, '1.18')) && '17' || startsWith(matrix.version, '1.17') && '16' || '8' }} | ||||
|  | ||||
|     - name: Build | ||||
|       continue-on-error: true | ||||
|       run: | | ||||
|         wget -qO build.jar https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar | ||||
|         java -jar build.jar --rev "${{ matrix.version || 'latest' }}" | ||||
|  | ||||
|     - name: Upload to actifial | ||||
|       uses: actions/upload-artifact@v3 | ||||
|       with: | ||||
|         name: ${{ matrix.version || 'latest' }} | ||||
|         path: "*.jar" | ||||
|  | ||||
|   # Upload | ||||
|   upload: | ||||
|     runs-on: ubuntu-latest | ||||
|     needs: build | ||||
|     steps: | ||||
|     - uses: actions/checkout@v3 | ||||
|       name: Code checkout | ||||
|  | ||||
|     - name: Setup node | ||||
|       uses: actions/setup-node@v3 | ||||
|       with: | ||||
|         node-version: latest | ||||
|  | ||||
|     - name: Install node depencies | ||||
|       run: npm install --no-save | ||||
|  | ||||
|     - name: Download artifacts | ||||
|       uses: actions/download-artifact@v3 | ||||
|       with: | ||||
|         path: artifacts | ||||
|  | ||||
|     - name: Upload to actifial | ||||
|       run: node .github/spigotBuilld/index.mjs artifacts | ||||
|       env: | ||||
|         tenancy: ${{ secrets.OCI_TENANCY }} | ||||
|         fingerprint: ${{ secrets.OCI_FING }} | ||||
|         privateKey: ${{ secrets.OCI_PRIV }} | ||||
|         user: ${{ secrets.OCI_USER }} | ||||
|         passphase: ${{ secrets.OCI_PASSPHASE || '' }} | ||||
| @@ -1,23 +1,13 @@ | ||||
| 
 | ||||
| name: Test | ||||
| on: | ||||
|   push: | ||||
|     branches: | ||||
|     - main | ||||
|     paths: | ||||
|       - "src/**/*" | ||||
|       - "tests/**/*" | ||||
|       - "package*.json" | ||||
|   pull_request: | ||||
|     branches: | ||||
|     - main | ||||
| 
 | ||||
| jobs: | ||||
|   test: | ||||
|     runs-on: ubuntu-latest | ||||
|     name: "Test" | ||||
|     env: | ||||
|       BDS_HOME: "~/.bdsCore" | ||||
|       bdscoreroot: "~/.bdsCore" | ||||
|     steps: | ||||
|     - uses: actions/checkout@v3 | ||||
|       name: Code checkout | ||||
| @@ -36,8 +26,8 @@ jobs: | ||||
| 
 | ||||
|     # Install dependecies | ||||
|     - name: Install nodejs dependencies | ||||
|       run: npm ci | ||||
|       run: npm install --no-save | ||||
| 
 | ||||
|     # Run test | ||||
|     - name: Test | ||||
|       run: npm run test | ||||
|     # Build Core | ||||
|     - name: Core Build | ||||
|       run: cd package/core && npm run build | ||||
							
								
								
									
										19
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										19
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -1,17 +1,6 @@ | ||||
| /*.log | ||||
| # Node | ||||
| node_modules/ | ||||
| dist/ | ||||
| src/**/*.d.ts | ||||
| src/**/*.d.js | ||||
| src/**/*.js | ||||
| docs/ | ||||
|  | ||||
| # PHP Bins | ||||
| muslCrossMake/ | ||||
| phpOutput/ | ||||
| *.tar.gz | ||||
| *.tgz | ||||
| *.zip | ||||
|  | ||||
| # Spigot | ||||
| *.jar | ||||
| # Typescript | ||||
| packages/**/*.js | ||||
| packages/**/*.d.ts | ||||
							
								
								
									
										19
									
								
								.gitpod.yml
									
									
									
									
									
								
							
							
						
						
									
										19
									
								
								.gitpod.yml
									
									
									
									
									
								
							| @@ -1,19 +0,0 @@ | ||||
| image: | ||||
|   file: .devcontainer/Dockerfile | ||||
| tasks: | ||||
|   - init: npm install | ||||
| vscode: | ||||
|   extensions: | ||||
|     - formulahendry.code-runner | ||||
|     - github.vscode-pull-request-github | ||||
|     - redhat.vscode-yaml | ||||
|     - eamodio.gitlens | ||||
|     - wix.vscode-import-cost | ||||
|     - eg2.vscode-npm-script | ||||
|     - christian-kohler.npm-intellisense | ||||
|     - christian-kohler.path-intellisense | ||||
|     - aaron-bond.better-comments | ||||
|     - vscode-icons-team.vscode-icons | ||||
|     - cschleiden.vscode-github-actions | ||||
|     - oderwat.indent-rainbow | ||||
|     - ms-azuretools.vscode-docker | ||||
							
								
								
									
										8
									
								
								.hintrc
									
									
									
									
									
								
							
							
						
						
									
										8
									
								
								.hintrc
									
									
									
									
									
								
							| @@ -1,8 +0,0 @@ | ||||
| { | ||||
|   "extends": [ | ||||
|     "development" | ||||
|   ], | ||||
|   "hints": { | ||||
|     "typescript-config/strict": "off" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										11
									
								
								.mocharc.yml
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								.mocharc.yml
									
									
									
									
									
								
							| @@ -1,11 +0,0 @@ | ||||
| exit: true | ||||
| colors: true | ||||
| full-trace: true | ||||
| recursive: true | ||||
| parallel: true | ||||
| timeout: 0 | ||||
| node-option: | ||||
|   - "experimental-specifier-resolution=node" | ||||
|   - "loader=ts-node/esm" | ||||
| extension: | ||||
|   - "test.ts" | ||||
| @@ -1,2 +0,0 @@ | ||||
| !dist/ | ||||
| backup_*.zip | ||||
							
								
								
									
										22
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										22
									
								
								.vscode/extensions.json
									
									
									
									
										vendored
									
									
								
							| @@ -1,22 +0,0 @@ | ||||
| { | ||||
|   "recommendations": [ | ||||
|     "formulahendry.code-runner", | ||||
|     "chrmarti.regex", | ||||
|     "benshabatnoam.google-translate-ext", | ||||
| 		"eamodio.gitlens", | ||||
| 		"github.vscode-pull-request-github", | ||||
| 		"visualstudioexptteam.vscodeintellicode", | ||||
| 		"redhat.vscode-yaml", | ||||
| 		"ms-vscode-remote.remote-containers", | ||||
| 		"wix.vscode-import-cost", | ||||
| 		"eg2.vscode-npm-script", | ||||
| 		"christian-kohler.npm-intellisense", | ||||
| 		"christian-kohler.path-intellisense", | ||||
| 		"aaron-bond.better-comments", | ||||
| 		"vscode-icons-team.vscode-icons", | ||||
| 		"me-dutour-mathieu.vscode-github-actions", | ||||
| 		"cschleiden.vscode-github-actions", | ||||
| 		"oderwat.indent-rainbow", | ||||
| 		"ms-azuretools.vscode-docker" | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										34
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										34
									
								
								.vscode/launch.json
									
									
									
									
										vendored
									
									
								
							| @@ -1,34 +0,0 @@ | ||||
| { | ||||
| 	"version": "0.2.0", | ||||
| 	"configurations": [ | ||||
|     { | ||||
|       "type": "node", | ||||
|       "name": "Current file", | ||||
|       "internalConsoleOptions": "openOnSessionStart", | ||||
|       "request": "launch", | ||||
|       "env": { | ||||
|         "BDSD_IGNORE_KEY": "1", | ||||
|         "PORT": "3000" | ||||
|       }, | ||||
|       "args": [ | ||||
|         "-r", "ts-node/register", | ||||
|         "${file}" | ||||
|       ], | ||||
|     }, | ||||
|     { | ||||
|       "type": "node", | ||||
|       "name": "Mocha Tests", | ||||
|       "program": "${workspaceFolder}/node_modules/mocha/bin/mocha.js", | ||||
|       "internalConsoleOptions": "openOnSessionStart", | ||||
|       "request": "launch", | ||||
|       "skipFiles": [ | ||||
|         "<node_internals>/**" | ||||
|       ], | ||||
|       "args": [ | ||||
|         "-r", "ts-node/register", | ||||
|         "--colors", | ||||
|         "${workspaceFolder}/tests/**/*.ts" | ||||
|       ], | ||||
|     }, | ||||
| 	] | ||||
| } | ||||
							
								
								
									
										6
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
								
							| @@ -8,9 +8,7 @@ | ||||
|   "files.trimTrailingWhitespace": true, | ||||
|   "files.exclude": { | ||||
|     "**/node_modules/": true, | ||||
|     // Ignore generate tsc files | ||||
|     "**/dist/": true, | ||||
|     "**/src/**/*.js": false, | ||||
|     "**/src/**/*.d.ts": false, | ||||
|     "**/src/**/*.js": true, | ||||
|     "**/src/**/*.d.ts": true, | ||||
|   } | ||||
| } | ||||
| @@ -1,128 +0,0 @@ | ||||
| # Contributor Covenant Code of Conduct | ||||
|  | ||||
| ## Our Pledge | ||||
|  | ||||
| We as members, contributors, and leaders pledge to make participation in our | ||||
| community a harassment-free experience for everyone, regardless of age, body | ||||
| size, visible or invisible disability, ethnicity, sex characteristics, gender | ||||
| identity and expression, level of experience, education, socio-economic status, | ||||
| nationality, personal appearance, race, religion, or sexual identity | ||||
| and orientation. | ||||
|  | ||||
| We pledge to act and interact in ways that contribute to an open, welcoming, | ||||
| diverse, inclusive, and healthy community. | ||||
|  | ||||
| ## Our Standards | ||||
|  | ||||
| Examples of behavior that contributes to a positive environment for our | ||||
| community include: | ||||
|  | ||||
| * Demonstrating empathy and kindness toward other people | ||||
| * Being respectful of differing opinions, viewpoints, and experiences | ||||
| * Giving and gracefully accepting constructive feedback | ||||
| * Accepting responsibility and apologizing to those affected by our mistakes, | ||||
|   and learning from the experience | ||||
| * Focusing on what is best not just for us as individuals, but for the | ||||
|   overall community | ||||
|  | ||||
| Examples of unacceptable behavior include: | ||||
|  | ||||
| * The use of sexualized language or imagery, and sexual attention or | ||||
|   advances of any kind | ||||
| * Trolling, insulting or derogatory comments, and personal or political attacks | ||||
| * Public or private harassment | ||||
| * Publishing others' private information, such as a physical or email | ||||
|   address, without their explicit permission | ||||
| * Other conduct which could reasonably be considered inappropriate in a | ||||
|   professional setting | ||||
|  | ||||
| ## Enforcement Responsibilities | ||||
|  | ||||
| Community leaders are responsible for clarifying and enforcing our standards of | ||||
| acceptable behavior and will take appropriate and fair corrective action in | ||||
| response to any behavior that they deem inappropriate, threatening, offensive, | ||||
| or harmful. | ||||
|  | ||||
| Community leaders have the right and responsibility to remove, edit, or reject | ||||
| comments, commits, code, wiki edits, issues, and other contributions that are | ||||
| not aligned to this Code of Conduct, and will communicate reasons for moderation | ||||
| decisions when appropriate. | ||||
|  | ||||
| ## Scope | ||||
|  | ||||
| This Code of Conduct applies within all community spaces, and also applies when | ||||
| an individual is officially representing the community in public spaces. | ||||
| Examples of representing our community include using an official e-mail address, | ||||
| posting via an official social media account, or acting as an appointed | ||||
| representative at an online or offline event. | ||||
|  | ||||
| ## Enforcement | ||||
|  | ||||
| Instances of abusive, harassing, or otherwise unacceptable behavior may be | ||||
| reported to the community leaders responsible for enforcement at | ||||
| Email or Github issues. | ||||
| All complaints will be reviewed and investigated promptly and fairly. | ||||
|  | ||||
| All community leaders are obligated to respect the privacy and security of the | ||||
| reporter of any incident. | ||||
|  | ||||
| ## Enforcement Guidelines | ||||
|  | ||||
| Community leaders will follow these Community Impact Guidelines in determining | ||||
| the consequences for any action they deem in violation of this Code of Conduct: | ||||
|  | ||||
| ### 1. Correction | ||||
|  | ||||
| **Community Impact**: Use of inappropriate language or other behavior deemed | ||||
| unprofessional or unwelcome in the community. | ||||
|  | ||||
| **Consequence**: A private, written warning from community leaders, providing | ||||
| clarity around the nature of the violation and an explanation of why the | ||||
| behavior was inappropriate. A public apology may be requested. | ||||
|  | ||||
| ### 2. Warning | ||||
|  | ||||
| **Community Impact**: A violation through a single incident or series | ||||
| of actions. | ||||
|  | ||||
| **Consequence**: A warning with consequences for continued behavior. No | ||||
| interaction with the people involved, including unsolicited interaction with | ||||
| those enforcing the Code of Conduct, for a specified period of time. This | ||||
| includes avoiding interactions in community spaces as well as external channels | ||||
| like social media. Violating these terms may lead to a temporary or | ||||
| permanent ban. | ||||
|  | ||||
| ### 3. Temporary Ban | ||||
|  | ||||
| **Community Impact**: A serious violation of community standards, including | ||||
| sustained inappropriate behavior. | ||||
|  | ||||
| **Consequence**: A temporary ban from any sort of interaction or public | ||||
| communication with the community for a specified period of time. No public or | ||||
| private interaction with the people involved, including unsolicited interaction | ||||
| with those enforcing the Code of Conduct, is allowed during this period. | ||||
| Violating these terms may lead to a permanent ban. | ||||
|  | ||||
| ### 4. Permanent Ban | ||||
|  | ||||
| **Community Impact**: Demonstrating a pattern of violation of community | ||||
| standards, including sustained inappropriate behavior,  harassment of an | ||||
| individual, or aggression toward or disparagement of classes of individuals. | ||||
|  | ||||
| **Consequence**: A permanent ban from any sort of public interaction within | ||||
| the community. | ||||
|  | ||||
| ## Attribution | ||||
|  | ||||
| This Code of Conduct is adapted from the [Contributor Covenant][homepage], | ||||
| version 2.0, available at | ||||
| https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. | ||||
|  | ||||
| Community Impact Guidelines were inspired by [Mozilla's code of conduct | ||||
| enforcement ladder](https://github.com/mozilla/diversity). | ||||
|  | ||||
| [homepage]: https://www.contributor-covenant.org | ||||
|  | ||||
| For answers to common questions about this code of conduct, see the FAQ at | ||||
| https://www.contributor-covenant.org/faq. Translations are available at | ||||
| https://www.contributor-covenant.org/translations. | ||||
| @@ -1,8 +0,0 @@ | ||||
| # Contributing to the core | ||||
|  | ||||
| We hope to have multiple platforms supported by the project, as I want to bring together multiple servers to be managed in one place. | ||||
|  | ||||
| Any new platform will have to fork the repository or open an issue to request the new platform. | ||||
|  | ||||
| 1. not all servers can be added because of project licensing but we can talk to the maintainers if needed. | ||||
| 2. This project is designed to run on various operating systems such as Android, Linux, Windows and MacOS (other systems can be added to be supported). | ||||
							
								
								
									
										5
									
								
								LICENSE
									
									
									
									
									
								
							
							
						
						
									
										5
									
								
								LICENSE
									
									
									
									
									
								
							| @@ -632,7 +632,7 @@ state the exclusion of warranty; and each file should have at least | ||||
| the "copyright" line and a pointer to where the full notice is found. | ||||
|  | ||||
|     <one line to give the program's name and a brief idea of what it does.> | ||||
|     Copyright (C) <year>  <name of author> | ||||
|     Copyright (C) 2023  Matheus Sampaio Queiroga | ||||
|  | ||||
|     This program is free software: you can redistribute it and/or modify | ||||
|     it under the terms of the GNU General Public License as published by | ||||
| @@ -652,7 +652,7 @@ Also add information on how to contact you by electronic and paper mail. | ||||
|   If the program does terminal interaction, make it output a short | ||||
| notice like this when it starts in an interactive mode: | ||||
|  | ||||
|     <program>  Copyright (C) <year>  <name of author> | ||||
|     <program>  Copyright (C) 2023  Matheus Sampaio Queiroga | ||||
|     This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||||
|     This is free software, and you are welcome to redistribute it | ||||
|     under certain conditions; type `show c' for details. | ||||
| @@ -672,4 +672,3 @@ may consider it more useful to permit linking proprietary applications with | ||||
| the library.  If this is what you want to do, use the GNU Lesser General | ||||
| Public License instead of this License.  But first, please read | ||||
| <https://www.gnu.org/licenses/why-not-lgpl.html>. | ||||
|  | ||||
|   | ||||
							
								
								
									
										12
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								README.md
									
									
									
									
									
								
							| @@ -1,12 +0,0 @@ | ||||
| # Bds Maneger Core | ||||
|  | ||||
| A quick way to install, update and start your Minecraft Java and Bedrock server. | ||||
|  | ||||
| ## Current Bds core support servers | ||||
|  | ||||
| 1. `Bedrock` (Mojang) | ||||
| 2. `Java` (Mojang) | ||||
| 3. `Pocketmine` (PMMP - Minecraft bedrock server writed in PHP) | ||||
| 4. `Spigot` (Spigot-MC is Minecraft java server to add plugins and more to server) | ||||
| 5. `Powernukkit` (Minecraft Bedrock Server in java) | ||||
| 6. `Paper` (PaperMC is Minecraft java server with plugins and mods) | ||||
| @@ -1,135 +0,0 @@ | ||||
| server-name=Dedicated Server | ||||
| # Used as the server name | ||||
| # Allowed values: Any string without semicolon symbol. | ||||
|  | ||||
| gamemode=survival | ||||
| # Sets the game mode for new players. | ||||
| # Allowed values: "survival", "creative", or "adventure" | ||||
|  | ||||
| force-gamemode=false | ||||
| # force-gamemode=false (or force-gamemode  is not defined in the server.properties) | ||||
| # prevents the server from sending to the client gamemode values other | ||||
| # than the gamemode value saved by the server during world creation | ||||
| # even if those values are set in server.properties after world creation. | ||||
| #  | ||||
| # force-gamemode=true forces the server to send to the client gamemode values | ||||
| # other than the gamemode value saved by the server during world creation | ||||
| # if those values are set in server.properties after world creation. | ||||
|  | ||||
| difficulty=easy | ||||
| # Sets the difficulty of the world. | ||||
| # Allowed values: "peaceful", "easy", "normal", or "hard" | ||||
|  | ||||
| allow-cheats=false | ||||
| # If true then cheats like commands can be used. | ||||
| # Allowed values: "true" or "false" | ||||
|  | ||||
| max-players=10 | ||||
| # The maximum number of players that can play on the server. | ||||
| # Allowed values: Any positive integer | ||||
|  | ||||
| online-mode=true | ||||
| # If true then all connected players must be authenticated to Xbox Live. | ||||
| # Clients connecting to remote (non-LAN) servers will always require Xbox Live authentication regardless of this setting. | ||||
| # If the server accepts connections from the Internet, then it's highly recommended to enable online-mode. | ||||
| # Allowed values: "true" or "false" | ||||
|  | ||||
| allow-list=false | ||||
| # If true then all connected players must be listed in the separate allowlist.json file. | ||||
| # Allowed values: "true" or "false" | ||||
|  | ||||
| server-port=34215 | ||||
| # Which IPv4 port the server should listen to. | ||||
| # Allowed values: Integers in the range [1, 65535] | ||||
|  | ||||
| server-portv6=33657 | ||||
| # Which IPv6 port the server should listen to. | ||||
| # Allowed values: Integers in the range [1, 65535] | ||||
|  | ||||
| view-distance=32 | ||||
| # The maximum allowed view distance in number of chunks. | ||||
| # Allowed values: Positive integer equal to 5 or greater. | ||||
|  | ||||
| tick-distance=4 | ||||
| # The world will be ticked this many chunks away from any player. | ||||
| # Allowed values: Integers in the range [4, 12] | ||||
|  | ||||
| player-idle-timeout=30 | ||||
| # After a player has idled for this many minutes they will be kicked. If set to 0 then players can idle indefinitely. | ||||
| # Allowed values: Any non-negative integer. | ||||
|  | ||||
| max-threads=8 | ||||
| # Maximum number of threads the server will try to use. If set to 0 or removed then it will use as many as possible. | ||||
| # Allowed values: Any positive integer. | ||||
|  | ||||
| level-name=Bedrock level | ||||
| # Allowed values: Any string without semicolon symbol or symbols illegal for file name: /\n\r\t\f`?*\\<>|\": | ||||
|  | ||||
| level-seed= | ||||
| # Use to randomize the world | ||||
| # Allowed values: Any string | ||||
|  | ||||
| default-player-permission-level=member | ||||
| # Permission level for new players joining for the first time. | ||||
| # Allowed values: "visitor", "member", "operator" | ||||
|  | ||||
| texturepack-required=false | ||||
| # Force clients to use texture packs in the current world | ||||
| # Allowed values: "true" or "false" | ||||
|  | ||||
| content-log-file-enabled=false | ||||
| # Enables logging content errors to a file | ||||
| # Allowed values: "true" or "false" | ||||
|  | ||||
| compression-threshold=1 | ||||
| # Determines the smallest size of raw network payload to compress | ||||
| # Allowed values: 0-65535 | ||||
|  | ||||
| compression-algorithm=zlib | ||||
| # Determines the compression algorithm to use for networking | ||||
| # Allowed values: "zlib", "snappy" | ||||
|  | ||||
| server-authoritative-movement=server-auth | ||||
| # Allowed values: "client-auth", "server-auth", "server-auth-with-rewind" | ||||
| # Enables server authoritative movement. If "server-auth", the server will replay local user input on | ||||
| # the server and send down corrections when the client's position doesn't match the server's. | ||||
| # If "server-auth-with-rewind" is enabled and the server sends a correction, the clients will be instructed | ||||
| # to rewind time back to the correction time, apply the correction, then replay all the player's inputs since then. This results in smoother and more frequent corrections. | ||||
| # Corrections will only happen if correct-player-movement is set to true. | ||||
|  | ||||
| player-movement-score-threshold=20 | ||||
| # The number of incongruent time intervals needed before abnormal behavior is reported. | ||||
| # Disabled by server-authoritative-movement. | ||||
|  | ||||
| player-movement-action-direction-threshold=0.85 | ||||
| # The amount that the player's attack direction and look direction can differ. | ||||
| # Allowed values: Any value in the range of [0, 1] where 1 means that the | ||||
| # direction of the players view and the direction the player is attacking | ||||
| # must match exactly and a value of 0 means that the two directions can | ||||
| # differ by up to and including 90 degrees. | ||||
|  | ||||
| player-movement-distance-threshold=0.3 | ||||
| # The difference between server and client positions that needs to be exceeded before abnormal behavior is detected. | ||||
| # Disabled by server-authoritative-movement. | ||||
|  | ||||
| player-movement-duration-threshold-in-ms=500 | ||||
| # The duration of time the server and client positions can be out of sync (as defined by player-movement-distance-threshold) | ||||
| # before the abnormal movement score is incremented. This value is defined in milliseconds. | ||||
| # Disabled by server-authoritative-movement. | ||||
|  | ||||
| correct-player-movement=false | ||||
| # If true, the client position will get corrected to the server position if the movement score exceeds the threshold. | ||||
|  | ||||
|  | ||||
| server-authoritative-block-breaking=false | ||||
| # If true, the server will compute block mining operations in sync with the client so it can verify that the client should be able to break blocks when it thinks it can. | ||||
|  | ||||
| chat-restriction=None | ||||
| # Allowed values: "None", "Dropped", "Disabled" | ||||
| # This represents the level of restriction applied to the chat for each player that joins the server. | ||||
| # "None" is the default and represents regular free chat. | ||||
| # "Dropped" means the chat messages are dropped and never sent to any client. Players receive a message to let them know the feature is disabled. | ||||
| # "Disabled" means that unless the player is an operator, the chat UI does not even appear. No information is displayed to the player. | ||||
|  | ||||
| disable-player-interaction=false | ||||
| # If true, the server will inform clients that they should ignore other players when interacting with the world. This is not server authoritative. | ||||
| @@ -1,57 +0,0 @@ | ||||
| #Minecraft server properties | ||||
| #Mon Oct 17 00:27:26 UTC 2022 | ||||
| enable-jmx-monitoring=false | ||||
| rcon.port=25575 | ||||
| level-seed= | ||||
| gamemode=survival | ||||
| enable-command-block=false | ||||
| enable-query=false | ||||
| generator-settings={} | ||||
| enforce-secure-profile=true | ||||
| level-name=world | ||||
| motd=A Minecraft Server | ||||
| query.port=25565 | ||||
| pvp=true | ||||
| generate-structures=true | ||||
| max-chained-neighbor-updates=1000000 | ||||
| difficulty=easy | ||||
| network-compression-threshold=256 | ||||
| max-tick-time=60000 | ||||
| require-resource-pack=false | ||||
| use-native-transport=true | ||||
| max-players=20 | ||||
| online-mode=true | ||||
| enable-status=true | ||||
| allow-flight=false | ||||
| broadcast-rcon-to-ops=true | ||||
| view-distance=10 | ||||
| server-ip= | ||||
| resource-pack-prompt= | ||||
| allow-nether=true | ||||
| server-port=25565 | ||||
| enable-rcon=false | ||||
| sync-chunk-writes=true | ||||
| op-permission-level=4 | ||||
| prevent-proxy-connections=false | ||||
| hide-online-players=false | ||||
| resource-pack= | ||||
| entity-broadcast-range-percentage=100 | ||||
| simulation-distance=10 | ||||
| rcon.password= | ||||
| player-idle-timeout=0 | ||||
| force-gamemode=false | ||||
| rate-limit=0 | ||||
| hardcore=false | ||||
| white-list=false | ||||
| broadcast-console-to-ops=true | ||||
| spawn-npcs=true | ||||
| previews-chat=false | ||||
| spawn-animals=true | ||||
| function-permission-level=2 | ||||
| level-type=minecraft\:normal | ||||
| text-filtering-config= | ||||
| spawn-monsters=true | ||||
| enforce-whitelist=false | ||||
| spawn-protection=16 | ||||
| resource-pack-sha1= | ||||
| max-world-size=29999984 | ||||
							
								
								
									
										1338
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										1338
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										58
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										58
									
								
								package.json
									
									
									
									
									
								
							| @@ -1,52 +1,16 @@ | ||||
| { | ||||
|   "name": "@the-bds-maneger/core", | ||||
|   "version": "5.4.0", | ||||
|   "description": "A very simple way to manage Minecraft servers", | ||||
|   "author": "Sirherobrine23", | ||||
|   "name": "@the-bds-maneger/monorepo", | ||||
|   "private": true, | ||||
|   "scripts": {}, | ||||
|   "author": "Matheus Sampaio Queiroga <srherobrine20@gmail.com>", | ||||
|   "license": "GPL-3.0", | ||||
|   "homepage": "https://sirherobrine23.org/BdsProject", | ||||
|   "type": "module", | ||||
|   "types": "./src/index.d.ts", | ||||
|   "main": "./src/index.js", | ||||
|   "private": false, | ||||
|   "publishConfig": { | ||||
|     "access": "public" | ||||
|   }, | ||||
|   "scripts": { | ||||
|     "docs": "typedoc --readme none --out docs src/index.ts", | ||||
|     "build": "tsc", | ||||
|     "test": "mocha src" | ||||
|   }, | ||||
|   "repository": { | ||||
|     "type": "git", | ||||
|     "url": "git+https://github.com/Sirherobrine23/Bds-Maneger-Core.git" | ||||
|   }, | ||||
|   "keywords": [], | ||||
|   "bugs": { | ||||
|     "url": "https://github.com/Sirherobrine23/Bds-Maneger-Core/issues/new", | ||||
|     "email": "support_bds@sirherobrine23.org" | ||||
|   }, | ||||
|   "engines": { | ||||
|     "node": ">=16.0.0" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@sirherobrine23/coreutils": "^3.1.2", | ||||
|     "adm-zip": "^0.5.10", | ||||
|     "compare-versions": "^5.0.3", | ||||
|     "debug": "^4.3.4", | ||||
|     "prismarine-nbt": "^2.2.1", | ||||
|     "tar": "^6.1.13" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/adm-zip": "^0.5.0", | ||||
|     "@types/debug": "^4.1.7", | ||||
|     "@types/mocha": "^10.0.1", | ||||
|     "@types/node": "^18.13.0", | ||||
|     "@types/tar": "^6.1.3", | ||||
|     "mocha": "^10.2.0", | ||||
|     "ts-node": "^10.9.1", | ||||
|     "tsconfig-paths": "^4.1.2", | ||||
|     "typedoc": "^0.23.24", | ||||
|     "@types/node": "^18.14.0", | ||||
|     "typescript": "^4.9.5" | ||||
|   } | ||||
|   }, | ||||
|   "workspaces": [ | ||||
|     "package/core", | ||||
|     "package/cli", | ||||
|     "package/docker" | ||||
|   ] | ||||
| } | ||||
|   | ||||
							
								
								
									
										18
									
								
								package/cli/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								package/cli/package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,18 @@ | ||||
| { | ||||
|   "name": "@the-bds-maneger/cli", | ||||
|   "version": "1.0.0", | ||||
|   "description": "", | ||||
|   "main": "src/index.js", | ||||
|   "type": "module", | ||||
|   "scripts": {}, | ||||
|   "keywords": [], | ||||
|   "author": "Matheus Sampaio Queiroga <srherobrine20@gmail.com>", | ||||
|   "license": "ISC", | ||||
|   "dependencies": { | ||||
|     "@the-bds-maneger/core": "*", | ||||
|     "yargs": "^17.7.0" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/yargs": "^17.0.22" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										39
									
								
								package/cli/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								package/cli/src/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| #!/usr/bin/env node | ||||
| import bdsCore from "@the-bds-maneger/core"; | ||||
| import yargs from "yargs"; | ||||
|  | ||||
| // Init yargs | ||||
| yargs(process.argv.slice(2)).version(false).help(true).strictCommands().demandCommand() | ||||
|  | ||||
| // bedrock | ||||
| .command("bedrock", "Bedrock", yargs => yargs.command("install", "Install Server", async yargs => { | ||||
|   const options = yargs.option("altServer", { | ||||
|     string: true, | ||||
|     description: "Select a server other than Mojang", | ||||
|     demandOption: false, | ||||
|     choices: [ | ||||
|       "pocketmine", | ||||
|       "powernukkit", | ||||
|       "cloudbust" | ||||
|     ], | ||||
|   }).option("list", { | ||||
|     alias: "l", | ||||
|     boolean: true, | ||||
|     default: false, | ||||
|     description: "List versions instead of installing" | ||||
|   }).option("version", { | ||||
|     alias: "V", | ||||
|     string: true, | ||||
|     default: "latest", | ||||
|     description: "Server version to install", | ||||
|   }).parseSync(); | ||||
|   if (options.list) return console.log(JSON.stringify(await bdsCore.Bedrock.listVersions({altServer: options.altServer as any}), null, 2)); | ||||
|   const data = await bdsCore.Bedrock.installServer({ | ||||
|     altServer: options.altServer as any, | ||||
|     version: options.version, | ||||
|   }); | ||||
|   console.log("Server ID: %O", data.id); | ||||
| })) | ||||
|  | ||||
| // run | ||||
| .parseAsync(); | ||||
							
								
								
									
										31
									
								
								package/cli/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								package/cli/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|     "esModuleInterop": true, | ||||
|     "module": "NodeNext", | ||||
|     "moduleResolution": "NodeNext", | ||||
|     "target": "ESNext", | ||||
|     "forceConsistentCasingInFileNames": true, | ||||
|     "declaration": true, | ||||
|     "strict": false, | ||||
|     "noUnusedLocals": true, | ||||
|     "isolatedModules": true, | ||||
|     "noImplicitReturns": true, | ||||
|     "noFallthroughCasesInSwitch": true, | ||||
|     "skipLibCheck": true, | ||||
|     "allowJs": true, | ||||
|     "lib": [ | ||||
|       "ESNext" | ||||
|     ] | ||||
|   }, | ||||
|   "exclude": [ | ||||
|     "**/*.test.*" | ||||
|   ], | ||||
|   "ts-node": { | ||||
|     "esm": true | ||||
|   }, | ||||
|   "references": [ | ||||
|     { | ||||
|       "path": "../core" | ||||
|     } | ||||
|   ] | ||||
| } | ||||
							
								
								
									
										5
									
								
								package/core/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								package/core/README.md
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,5 @@ | ||||
| # Bds Maneger Core | ||||
|  | ||||
| Este é um nucleo de utilização basica como: Fazer download do servidor, Gerenciar e outras coisas. | ||||
|  | ||||
| **Atualmente suportamos varias servidores, tanto para o Bedrock tanto o Java** | ||||
							
								
								
									
										26
									
								
								package/core/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								package/core/package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,26 @@ | ||||
| { | ||||
|   "name": "@the-bds-maneger/core", | ||||
|   "version": "1.0.0", | ||||
|   "description": "", | ||||
|   "main": "src/index.js", | ||||
|   "types": "src/index.d.ts", | ||||
|   "type": "module", | ||||
|   "author": "Matheus Sampaio Queiroga <srherobrine20@gmail.com>", | ||||
|   "license": "GPL-3.0", | ||||
|   "scripts": { | ||||
|     "build": "tsc --build --clean && tsc" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@sirherobrine23/cloud": "^3.2.1", | ||||
|     "@sirherobrine23/extends": "^3.2.1", | ||||
|     "@sirherobrine23/http": "^3.2.1", | ||||
|     "semver": "^7.3.8", | ||||
|     "tar": "^6.1.13", | ||||
|     "unzip-stream": "^0.3.1" | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@types/semver": "^7.3.13", | ||||
|     "@types/tar": "^6.1.4", | ||||
|     "@types/unzip-stream": "^0.3.1" | ||||
|   } | ||||
| } | ||||
							
								
								
									
										12
									
								
								package/core/src/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								package/core/src/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,12 @@ | ||||
| export * from "./serverManeger.js"; | ||||
| export * as Bedrock from "./servers/bedrock.js"; | ||||
| export * as Java from "./servers/java.js"; | ||||
|  | ||||
| import * as serverManeger from "./serverManeger.js"; | ||||
| import * as Bedrock from "./servers/bedrock.js"; | ||||
| import * as Java from "./servers/java.js"; | ||||
| export default { | ||||
|   ...serverManeger, | ||||
|   Bedrock, | ||||
|   Java | ||||
| }; | ||||
| @@ -1,11 +1,12 @@ | ||||
| import { Cloud } from "@sirherobrine23/coreutils"; | ||||
| import { oracleBucket } from "@sirherobrine23/cloud"; | ||||
| 
 | ||||
| export const oracleBucket = await Cloud.oracleBucket({ | ||||
| export const oracleStorage = await oracleBucket.oracleBucket({ | ||||
|   region: "sa-saopaulo-1", | ||||
|   namespace: "grwodtg32n4d", | ||||
|   name: "bdsFiles", | ||||
|   auth: { | ||||
|     type: "preAuthentication", | ||||
|     // Public auth (No write enabled).
 | ||||
|     PreAuthenticatedKey: "0IKM-5KFpAF8PuWoVe86QFsF4sipU2rXfojpaOMEdf4QgFQLcLlDWgMSPHWmjf5W" | ||||
|   } | ||||
| }); | ||||
							
								
								
									
										121
									
								
								package/core/src/serverManeger.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										121
									
								
								package/core/src/serverManeger.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,121 @@ | ||||
| import { extendsFS } from "@sirherobrine23/extends"; | ||||
| import child_process from "node:child_process"; | ||||
| import crypto from "node:crypto"; | ||||
| import path from "node:path"; | ||||
| import fs from "node:fs/promises"; | ||||
| import os from "node:os"; | ||||
|  | ||||
| // Default bds maneger core | ||||
| export const bdsManegerRoot = process.env.bdscoreroot ? path.resolve(process.cwd(), process.env.bdscoreroot) : path.join(os.homedir(), ".bdsmaneger"); | ||||
| if (!(await extendsFS.exists(bdsManegerRoot))) await fs.mkdir(bdsManegerRoot, {recursive: true}); | ||||
|  | ||||
| export type runOptions = { | ||||
|   cwd: string, | ||||
|   env?: {[k: string]: string|number|boolean}, | ||||
|   command: string, | ||||
|   args?: (string|number|boolean)[], | ||||
|   serverActions?: { | ||||
|     stop?(child: serverRun): void|Promise<void>, | ||||
|   } | ||||
| }; | ||||
|  | ||||
| export declare class serverRun extends child_process.ChildProcess { | ||||
|   on(event: string, listener: (...args: any[]) => void): this; | ||||
|   on(event: "error", listener: (err: Error) => void): this; | ||||
|   on(event: "close", listener: (code: number | null, signal: NodeJS.Signals | null) => void): this; | ||||
|   on(event: "disconnect", listener: () => void): this; | ||||
|   on(event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void): this; | ||||
|   on(event: "message", listener: (message: child_process.Serializable, sendHandle: child_process.SendHandle) => void): this; | ||||
|   on(event: "spawn", listener: () => void): this; | ||||
|  | ||||
|   once(event: string, listener: (...args: any[]) => void): this; | ||||
|   once(event: "error", listener: (err: Error) => void): this; | ||||
|   once(event: "close", listener: (code: number | null, signal: NodeJS.Signals | null) => void): this; | ||||
|   once(event: "disconnect", listener: () => void): this; | ||||
|   once(event: "exit", listener: (code: number | null, signal: NodeJS.Signals | null) => void): this; | ||||
|   once(event: "message", listener: (message: child_process.Serializable, sendHandle: child_process.SendHandle) => void): this; | ||||
|   once(event: "spawn", listener: () => void): this; | ||||
|  | ||||
|   stopServer(): Promise<{code?: number, signal?: NodeJS.Signals}>; | ||||
|   sendCommand(...args: (string|number|boolean)[]): this; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  */ | ||||
| export async function runServer(options: runOptions): Promise<serverRun> { | ||||
|   const child = child_process.execFile(options.command, [...((options.args ?? []).map(String))], { | ||||
|     maxBuffer: Infinity, | ||||
|     cwd: options.cwd || process.cwd(), | ||||
|     env: { | ||||
|       ...process.env, | ||||
|       ...Object.keys(options.env ?? {}).reduce((acc, a) => { | ||||
|         acc[a] = String(options.env[a]); | ||||
|         return acc; | ||||
|       }, {}) | ||||
|     } | ||||
|   }) as serverRun; | ||||
|   child.sendCommand = function (...args) { | ||||
|     if (!child.stdin.writable) { | ||||
|       child.emit("error", new Error("cannot send command to server")); | ||||
|       return child; | ||||
|     }; | ||||
|     child.stdin.write(args.map(String).join(" ")+"\n"); | ||||
|     return child; | ||||
|   } | ||||
|  | ||||
|   child.stopServer = async function () { | ||||
|     const stop = options.serverActions?.stop ?? function (child) { | ||||
|  | ||||
|     }; | ||||
|     Promise.resolve().then(() => stop(child)).catch(err => child.emit("error", err)); | ||||
|     return new Promise((done, reject) => child.once("error", reject).once("exit", (code, signal) => done({code, signal}))); | ||||
|   } | ||||
|   return child; | ||||
| } | ||||
|  | ||||
| export type manegerOptions = { | ||||
|   ID?: string, | ||||
|   newID?: boolean, | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * | ||||
|  */ | ||||
| export async function serverManeger(options: manegerOptions) { | ||||
|   if (!options) throw new TypeError("Por favor adicione as opções do serverManeger!"); | ||||
|   if (!options.ID) options.newID = true; | ||||
|   if (options.newID) { | ||||
|     while(true) { | ||||
|       options.ID = crypto.randomBytes(16).toString("hex"); | ||||
|       if (!(await fs.readdir(bdsManegerRoot)).includes(options.ID)) break; | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   /** | ||||
|    * Platform ID root path | ||||
|    */ | ||||
|   const rootPath = path.join(bdsManegerRoot, options.ID); | ||||
|   if (!(await extendsFS.exists(rootPath))) await fs.mkdir(rootPath, {recursive: true}); | ||||
|  | ||||
|   // sub-folders | ||||
|   const serverFolder = path.join(rootPath, "server"); | ||||
|   const backup = path.join(rootPath, "backups"); | ||||
|  | ||||
|   for await (const p of [ | ||||
|     serverFolder, | ||||
|     backup, | ||||
|   ]) if (!(await extendsFS.exists(p))) await fs.mkdir(p, {recursive: true}); | ||||
|  | ||||
|   return { | ||||
|     id: options.ID, | ||||
|     rootPath, | ||||
|     serverFolder, | ||||
|     backup, | ||||
|     async runCommand(options: Omit<runOptions, "cwd">) { | ||||
|       return runServer({...options, cwd: serverFolder}); | ||||
|     } | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export type serverManegerV1 = Awaited<ReturnType<typeof serverManeger>>; | ||||
							
								
								
									
										206
									
								
								package/core/src/servers/bedrock.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										206
									
								
								package/core/src/servers/bedrock.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,206 @@ | ||||
| import coreHttp, { Github, large } from "@sirherobrine23/http"; | ||||
| import { manegerOptions, runOptions, serverManeger } from "../serverManeger.js"; | ||||
| import { commandExists } from "../childPromisses.js"; | ||||
| import { oracleStorage } from "../internal.js"; | ||||
| import { pipeline } from "node:stream/promises"; | ||||
| import semver from "semver"; | ||||
| import unzip from "unzip-stream"; | ||||
| import utils from "node:util"; | ||||
| import path from "node:path"; | ||||
| import tar from "tar"; | ||||
| import extendsFS from "@sirherobrine23/extends"; | ||||
|  | ||||
| export type bedrockOptions = manegerOptions & { | ||||
|   /** | ||||
|    * Servidor alternativo ao invés do servidor ofical da Mojang | ||||
|    */ | ||||
|   altServer?: "pocketmine"|"powernukkit"|"cloudbust", | ||||
|   allowBeta?: boolean | ||||
| }; | ||||
|  | ||||
| const pocketmineGithub = await Github.GithubManeger("pmmp", "PocketMine-MP"); | ||||
|  | ||||
| export async function listVersions(options: {altServer: "powernukkit"} & Omit<bedrockOptions, "altServer"|keyof manegerOptions>): Promise<{version: string, mcpeVersion: string, date: Date, variantType: "stable"|"snapshot", url: string}[]>; | ||||
| export async function listVersions(options: {altServer: "pocketmine"} & Omit<bedrockOptions, "altServer"|keyof manegerOptions>): Promise<Github.githubRelease[]>; | ||||
| export async function listVersions(): Promise<{version: string, date: Date, release?: "stable"|"preview", url: {[platform in NodeJS.Platform]?: {[arch in NodeJS.Architecture]?: string}}}[]>; | ||||
| export async function listVersions(options?: Omit<bedrockOptions, keyof manegerOptions>) { | ||||
|   if (!options) options = {}; | ||||
|   if (options.altServer === "pocketmine") return pocketmineGithub.getRelease(); | ||||
|   else if (options.altServer === "powernukkit") { | ||||
|     const releases_version = (await coreHttp.jsonRequest<{[k: string]: {version: string, releaseTime: number, minecraftVersion: string, artefacts: string[], commitId:  string, snapshotBuild?: number}[]}>("https://raw.githubusercontent.com/PowerNukkit/powernukkit-version-aggregator/master/powernukkit-versions.json")).body; | ||||
|     return Object.keys(releases_version).reduce((acc, key) => { | ||||
|       for (const data of releases_version[key]) { | ||||
|         const dt = new Date(data.releaseTime); | ||||
|         const getArtefactExtension = (artefactId: string) => (artefactId.includes("REDUCED_JAR")) ? ".jar" : (artefactId.includes("REDUCED_SOURCES_JAR")) ? "-sources.jar" : (artefactId.includes("SHADED_JAR")) ? "-shaded.jar" : (artefactId.includes("SHADED_SOURCES_JAR")) ? "-shaded-sources.jar" : (artefactId.includes("JAVADOC_JAR")) ? "-javadoc.jar" : ".unknown"; | ||||
|         function buildArtefactUrl(data: any, artefactId?: string) { | ||||
|           const buildReleaseArtefactUrl = (data: any, artefactId?: string) => !data.artefacts.includes(artefactId) ? null : utils.format("https://search.maven.org/remotecontent?filepath=org/powernukkit/powernukkit/%s/powernukkit-%s%s", data.version, data.version, getArtefactExtension(artefactId)); | ||||
|           const buildSnapshotArtefactUrl = (data: any, artefactId?: string) => !data.artefacts.includes(artefactId) ? null : utils.format("https://oss.sonatype.org/content/repositories/snapshots/org/powernukkit/powernukkit/%s-SNAPSHOT/powernukkit-%s-%s%s", data.version.substring(0, data.version.indexOf("-SNAPSHOT")), data.version.substring(0, data.version.indexOf("-SNAPSHOT")), dt.getUTCFullYear().toString().padStart(4, "0") + (dt.getUTCMonth() + 1).toString().padStart(2, "0") + dt.getUTCDate().toString().padStart(2, "0") + "." + dt.getUTCHours().toString().padStart(2, "0") + dt.getUTCMinutes().toString().padStart(2, "0") + dt.getUTCSeconds().toString().padStart(2, "0") + "-" + data.snapshotBuild, getArtefactExtension(artefactId)); | ||||
|           if (artefactId == "GIT_SOURCE") { | ||||
|             if (data.commitId) return utils.format("https://github.com/PowerNukkit/PowerNukkit/tree/%s", data.commitId); | ||||
|             else if (data.snapshotBuild && data.artefacts.includes("SHADED_SOURCES_JAR")) return buildSnapshotArtefactUrl(data, "SHADED_SOURCES_JAR"); | ||||
|             else if (data.snapshotBuild && data.artefacts.includes("REDUCED_SOURCES_JAR")) return buildSnapshotArtefactUrl(data, "REDUCED_SOURCES_JAR"); | ||||
|             else if (data.artefacts.includes("SHADED_SOURCES_JAR")) return buildReleaseArtefactUrl(data, "SHADED_SOURCES_JAR"); | ||||
|             else if (data.artefacts.includes("REDUCED_SOURCES_JAR")) return buildReleaseArtefactUrl(data, "REDUCED_SOURCES_JAR"); | ||||
|           } else if (data.snapshotBuild) return buildSnapshotArtefactUrl(data, artefactId); | ||||
|           else return buildReleaseArtefactUrl(data, artefactId); | ||||
|           return null; | ||||
|         } | ||||
|         const artefacts = data.artefacts.reduce((acc, artefactId) => {acc[artefactId] = buildArtefactUrl(data, artefactId); return acc;}, {} as {[key: string]: string}); | ||||
|         const verRel = { | ||||
|           version: data.version, | ||||
|           mcpeVersion: data.minecraftVersion, | ||||
|           date: dt, | ||||
|           variantType: (!data.snapshotBuild?"snapshot":"stable") as "stable"|"snapshot", | ||||
|           url: artefacts.SHADED_JAR || artefacts.REDUCED_JAR | ||||
|         }; | ||||
|         if (!!verRel.url) acc.push(verRel); | ||||
|       } | ||||
|       return acc; | ||||
|     }, [] as {version: string, mcpeVersion: string, date: Date, variantType: "stable"|"snapshot", url: string}[]).filter(a => !!a.url).sort((b, a) => (b.date.getTime() - a.date.getTime()) - semver.compare(semver.valid(semver.coerce(a.version)), semver.valid(semver.coerce(b.version)))); | ||||
|   } else if (options.altServer === "cloudbust") throw new TypeError("O Cloudbust não tem listagem de versöes"); | ||||
|   return (await coreHttp.jsonRequest<{version: string, date: Date, release?: "stable"|"preview", url: {[platform in NodeJS.Platform]?: {[arch in NodeJS.Architecture]?: string}}}[]>("https://sirherobrine23.github.io/BedrockFetch/all.json")).body; | ||||
| } | ||||
|  | ||||
| export async function installServer(options: bedrockOptions & {version?: string}): Promise<{id: string, version: string, mcpeVersion?: string, releaseDate: Date}> { | ||||
|   const serverPath = await serverManeger(options); | ||||
|   if (options.altServer === "pocketmine") { | ||||
|     const version = (options.version ?? "latest").trim(); | ||||
|     const rel = (await pocketmineGithub.getRelease(version)); | ||||
|     if (!rel) throw new Error("Não foi possivel encontrar a versão informada do Pocketmine!"); | ||||
|  | ||||
|     const phpFile = (await oracleStorage.listFiles("php_bin")).find(file => file.name.includes(process.platform) && file.name.includes(process.arch)); | ||||
|     if (!phpFile) throw new Error(`Não foi possivel encontra os arquivos do php para o ${process.platform} com a arquitetura ${process.arch}`); | ||||
|     if (phpFile.name.endsWith(".tar.gz")) await pipeline(await oracleStorage.getFileStream(phpFile.name), tar.extract({cwd: serverPath.serverFolder})); | ||||
|     else if (phpFile.name.endsWith(".zip")) await pipeline(await oracleStorage.getFileStream(phpFile.name), unzip.Extract({path: serverPath.serverFolder})); | ||||
|     else throw new Error("Arquivo encontrado não é suportado!"); | ||||
|  | ||||
|     // save phar | ||||
|     await large.saveFile({ | ||||
|       url: rel.assets.find(a => a.name.endsWith(".phar"))?.browser_download_url, | ||||
|       path: path.join(serverPath.serverFolder, "server.phar") | ||||
|     }); | ||||
|  | ||||
|     return { | ||||
|       id: serverPath.id, | ||||
|       version: rel.tag_name, | ||||
|       releaseDate: new Date(rel.published_at) | ||||
|     }; | ||||
|   } else if (options.altServer === "powernukkit") { | ||||
|     const version = (options.version ?? "latest").trim(); | ||||
|     const releases = await listVersions({altServer: "powernukkit"}); | ||||
|     const relVersion = releases.find(rel => { | ||||
|       if (rel.variantType === "snapshot") if (!options.allowBeta) return false; | ||||
|       if (version.toLowerCase() === "latest") return true; | ||||
|       return (rel.version === version || rel.mcpeVersion === version); | ||||
|     }); | ||||
|     if (!relVersion) throw new Error("A versão não foi encontrada, por favor verique a versão informada!"); | ||||
|     await large.saveFile({ | ||||
|       path: path.join(serverPath.serverFolder, "server.jar"), | ||||
|       url: relVersion.url | ||||
|     }); | ||||
|     return { | ||||
|       id: serverPath.id, | ||||
|       version: relVersion.version, | ||||
|       mcpeVersion: relVersion.mcpeVersion, | ||||
|       releaseDate: relVersion.date, | ||||
|     }; | ||||
|   } else if (options.altServer === "cloudbust") { | ||||
|     await large.saveFile({ | ||||
|       url: "https://ci.opencollab.dev/job/NukkitX/job/Server/job/bleeding/lastSuccessfulBuild/artifact/target/Cloudburst.jar", | ||||
|       path: path.join(serverPath.serverFolder, "server.jar") | ||||
|     }); | ||||
|  | ||||
|     return { | ||||
|       id: serverPath.id, | ||||
|       version: "bleeding", | ||||
|       releaseDate: new Date() | ||||
|     }; | ||||
|   } | ||||
|   const bedrockVersion = (await listVersions()).find(rel => { | ||||
|     if (rel.release === "preview" && !!options.allowBeta) return false; | ||||
|     const version = (options.version ?? "latest").trim(); | ||||
|     if (version.toLowerCase() === "latest") return true; | ||||
|     return rel.version === version; | ||||
|   }); | ||||
|   if (!bedrockVersion) throw new Error("Não existe essa versão"); | ||||
|   let downloadUrl = bedrockVersion.url[process.platform]?.[process.arch]; | ||||
|   if ((["android", "linux"] as NodeJS.Process["platform"][]).includes(process.platform) && process.arch !== "x64") { | ||||
|     if (!downloadUrl) { | ||||
|       for (const emu of ["qemu-x86_64-static", "qemu-x86_64", "box64"]) { | ||||
|         if (downloadUrl) break; | ||||
|         if (await commandExists(emu)) downloadUrl = bedrockVersion.url.linux?.x64; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   if (!downloadUrl) throw new Error(`Não existe o URL de download para ${process.platform} na arquitetura ${process.arch}`); | ||||
|   await pipeline(await coreHttp.streamRequest(downloadUrl), unzip.Extract({path: serverPath.serverFolder})); | ||||
|   return { | ||||
|     id: serverPath.id, | ||||
|     version: bedrockVersion.version, | ||||
|     releaseDate: bedrockVersion.date, | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export async function startServer(options: bedrockOptions) { | ||||
|   const serverPath = await serverManeger(options); | ||||
|   if (options.altServer === "powernukkit"||options.altServer === "cloudbust") { | ||||
|     return serverPath.runCommand({ | ||||
|       command: "java", | ||||
|       args: [ | ||||
|         "-XX:+UseG1GC", | ||||
|         "-XX:+ParallelRefProcEnabled", | ||||
|         "-XX:MaxGCPauseMillis=200", | ||||
|         "-XX:+UnlockExperimentalVMOptions", | ||||
|         "-XX:+DisableExplicitGC", | ||||
|         "-XX:+AlwaysPreTouch", | ||||
|         "-XX:G1NewSizePercent=30", | ||||
|         "-XX:G1MaxNewSizePercent=40", | ||||
|         "-XX:G1HeapRegionSize=8M", | ||||
|         "-XX:G1ReservePercent=20", | ||||
|         "-XX:G1HeapWastePercent=5", | ||||
|         "-XX:G1MixedGCCountTarget=4", | ||||
|         "-XX:InitiatingHeapOccupancyPercent=15", | ||||
|         "-XX:G1MixedGCLiveThresholdPercent=90", | ||||
|         "-XX:G1RSetUpdatingPauseTimePercent=5", | ||||
|         "-XX:SurvivorRatio=32", | ||||
|         "-XX:+PerfDisableSharedMem", | ||||
|         "-XX:MaxTenuringThreshold=1", | ||||
|         "-Dusing.aikars.flags=https://mcflags.emc.gs", | ||||
|         "-Daikars.new.flags=true", | ||||
|         "-jar", "server.jar", | ||||
|       ], | ||||
|       serverActions: { | ||||
|         stop(child) { | ||||
|           child.sendCommand("stop"); | ||||
|         }, | ||||
|       } | ||||
|     }) | ||||
|   } else if (options.altServer === "pocketmine") { | ||||
|     return serverPath.runCommand({ | ||||
|       command: (await extendsFS.readdir(serverPath.serverFolder)).find(file => file.endsWith("php")||file.endsWith("php.exe")), | ||||
|       args: [ | ||||
|         "server.jar", | ||||
|         "--no-wizard" | ||||
|       ] | ||||
|     }); | ||||
|   } | ||||
|   if (process.platform === "darwin") throw new Error("Run in docker or podman!"); | ||||
|   const run: Omit<runOptions, "cwd"> = { | ||||
|     command: path.join(serverPath.serverFolder, "bedrock_server"), | ||||
|     serverActions: { | ||||
|       stop(child) { | ||||
|         child.sendCommand("stop"); | ||||
|       }, | ||||
|     } | ||||
|   }; | ||||
|   if ((["android", "linux"] as NodeJS.Process["platform"][]).includes(process.platform) && process.arch !== "x64") { | ||||
|     for (const emu of ["qemu-x86_64-static", "qemu-x86_64", "box64"]) { | ||||
|       if (await commandExists(emu)) { | ||||
|         run.args = [emu, run.command]; | ||||
|         run.command = emu; | ||||
|         break; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   return serverPath.runCommand(run); | ||||
| } | ||||
							
								
								
									
										9
									
								
								package/core/src/servers/java.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								package/core/src/servers/java.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| import { manegerOptions } from "../serverManeger.js"; | ||||
|  | ||||
| export type javaOptions = manegerOptions & { | ||||
|   /** | ||||
|    * Servidor alternativo ao invés do servidor ofical da Mojang | ||||
|    */ | ||||
|   altServer?: "spigot"|"paper"|"purpur", | ||||
|   allowBeta?: boolean | ||||
| }; | ||||
							
								
								
									
										27
									
								
								package/core/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								package/core/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|     "esModuleInterop": true, | ||||
|     "module": "NodeNext", | ||||
|     "moduleResolution": "NodeNext", | ||||
|     "target": "ESNext", | ||||
|     "forceConsistentCasingInFileNames": true, | ||||
|     "declaration": true, | ||||
|     "strict": false, | ||||
|     "noUnusedLocals": true, | ||||
|     "isolatedModules": true, | ||||
|     "noImplicitReturns": true, | ||||
|     "noFallthroughCasesInSwitch": true, | ||||
|     "skipLibCheck": true, | ||||
|     "allowJs": true, | ||||
|     "lib": [ | ||||
|       "ESNext" | ||||
|     ], | ||||
|     "composite": true | ||||
|   }, | ||||
|   "exclude": [ | ||||
|     "**/*.test.*" | ||||
|   ], | ||||
|   "ts-node": { | ||||
|     "esm": true | ||||
|   } | ||||
| } | ||||
							
								
								
									
										17
									
								
								package/docker/package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								package/docker/package.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | ||||
| { | ||||
|   "name": "@the-bds-maneger/docker", | ||||
|   "private": true, | ||||
|   "version": "1.0.0", | ||||
|   "description": "", | ||||
|   "type": "module", | ||||
|   "bin": { | ||||
|     "bdsdocker": "./src/index.js" | ||||
|   }, | ||||
|   "devDependencies": {}, | ||||
|   "scripts": { | ||||
|     "test": "echo \"Error: no test specified\" && exit 1" | ||||
|   }, | ||||
|   "keywords": [], | ||||
|   "author": "Matheus Sampaio Queiroga <srherobrine20@gmail.com>", | ||||
|   "license": "ISC" | ||||
| } | ||||
							
								
								
									
										31
									
								
								package/docker/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								package/docker/tsconfig.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,31 @@ | ||||
| { | ||||
|   "compilerOptions": { | ||||
|     "esModuleInterop": true, | ||||
|     "module": "NodeNext", | ||||
|     "moduleResolution": "NodeNext", | ||||
|     "target": "ESNext", | ||||
|     "forceConsistentCasingInFileNames": true, | ||||
|     "declaration": true, | ||||
|     "strict": false, | ||||
|     "noUnusedLocals": true, | ||||
|     "isolatedModules": true, | ||||
|     "noImplicitReturns": true, | ||||
|     "noFallthroughCasesInSwitch": true, | ||||
|     "skipLibCheck": true, | ||||
|     "allowJs": true, | ||||
|     "lib": [ | ||||
|       "ESNext" | ||||
|     ] | ||||
|   }, | ||||
|   "exclude": [ | ||||
|     "**/*.test.*" | ||||
|   ], | ||||
|   "ts-node": { | ||||
|     "esm": true | ||||
|   }, | ||||
|   "references": [ | ||||
|     { | ||||
|       "path": "../core" | ||||
|     } | ||||
|   ] | ||||
| } | ||||
| @@ -1,3 +0,0 @@ | ||||
| export * as serverManeger from "./serverManeger.js"; | ||||
| export * as Bedrock from "./platform/Bedrock.js"; | ||||
| export * as Java from "./platform/Java.js"; | ||||
| @@ -1,43 +0,0 @@ | ||||
| export default {parse, stringify}; | ||||
| export type properitiesBase = {[key: string]: string|number|true|false}; | ||||
|  | ||||
| /** | ||||
|  * Parse Proprieties files and return a map of properties. | ||||
|  * | ||||
|  * @param Proper - String with the properties or similar files | ||||
|  * @returns | ||||
|  */ | ||||
| export function parse<PropertiesObject extends properitiesBase>(Proper: string): PropertiesObject { | ||||
|   const ProPri = {}; | ||||
|   const ProperSplit = Proper.replace(/\\\s+?\n/gi, "").split(/\r?\n/).map(Line => Line.trim()).filter(line => /.*(\s+)?\=(\s+)?.*/.test(line) && !/^#/.test(line)); | ||||
|   for (const Line of ProperSplit) { | ||||
|     const LineMatch = Line.match(/^([^\s\=]+)\s*\=(.*)$/); | ||||
|     const key = LineMatch[1].trim(), value = LineMatch[2].trim(); | ||||
|     ProPri[key] = value; | ||||
|     if (ProPri[key] === "true") ProPri[key] = true; | ||||
|     else if (ProPri[key] === "false") ProPri[key] = false; | ||||
|     else if (/^[0-9]+\.[0-9]+/.test(ProPri[key]) && !/^[0-9]+\.[0-9]+\.[0-9]+/.test(ProPri[key])) ProPri[key] = parseFloat(ProPri[key]); | ||||
|     else if (/^[0-9]+/.test(ProPri[key])) ProPri[key] = parseInt(ProPri[key]); | ||||
|   } | ||||
|   return ProPri as PropertiesObject; | ||||
| } | ||||
|  | ||||
| /** | ||||
|  * Convert json to properities files. | ||||
|  * | ||||
|  * @param ProPri - String with properties file | ||||
|  * @returns | ||||
|  */ | ||||
| export function stringify(ProPri: properitiesBase): string { | ||||
|   const Proper = []; | ||||
|   for (const key of Object.keys(ProPri)) { | ||||
|     if (ProPri[key] === null||ProPri[key] === undefined) Proper.push(`${key}=`); | ||||
|     else if (ProPri[key] === true) Proper.push(`${key}=true`); | ||||
|     else if (ProPri[key] === false) Proper.push(`${key}=false`); | ||||
|     else if (typeof ProPri[key] === "number") Proper.push(`${key}=${ProPri[key]}`); | ||||
|     else if (typeof ProPri[key] === "string") Proper.push(`${key}=${ProPri[key]}`); | ||||
|     else if (typeof ProPri[key] === "object") Proper.push(`${key}=${JSON.stringify(ProPri[key])}`); | ||||
|     else console.error(`[Proprieties.stringify] ${key} is not a valid type.`); | ||||
|   } | ||||
|   return Proper.join("\n"); | ||||
| } | ||||
| @@ -1,86 +0,0 @@ | ||||
| import dgram from "node:dgram"; | ||||
| import net from "node:net"; | ||||
|  | ||||
| export type proxyUdpToTcpOptions = { | ||||
|   udpType?: dgram.SocketType, | ||||
|   listen?: number, | ||||
|   portListen?: (port: number) => void | ||||
| }; | ||||
|  | ||||
| export type proxyTcpToUdpClient = { | ||||
|   udpType?: dgram.SocketType, | ||||
|   listen?: number, | ||||
|   remote: { | ||||
|     host: string, | ||||
|     port: number | ||||
|   }, | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * Transfer packets from UDP to TCP to send through some tunnel that only accepts TCP | ||||
|  * | ||||
|  * This also means that it will also have error transporting the data, so it is not guaranteed to work properly even more when dealing with UDP packets. | ||||
|  */ | ||||
| export function proxyUdpToTcp(udpPort: number, options?: proxyUdpToTcpOptions) { | ||||
|   const tcpServer = net.createServer(); | ||||
|   tcpServer.on("error", err => console.error(err)); | ||||
|   tcpServer.on("connection", socket => { | ||||
|     const udpClient = dgram.createSocket(options?.udpType||"udp4"); | ||||
|  | ||||
|     // Close Sockets | ||||
|     udpClient.once("close", () => socket.end()); | ||||
|     socket.once("close", () => udpClient.close()); | ||||
|  | ||||
|     // Print error | ||||
|     udpClient.on("error", console.error); | ||||
|     socket.on("error", console.error); | ||||
|  | ||||
|     // Pipe Datas | ||||
|     udpClient.on("message", data => socket.write(data)); | ||||
|     socket.on("data", data => udpClient.send(data)); | ||||
|  | ||||
|     // Connect | ||||
|     udpClient.connect(udpPort); | ||||
|   }); | ||||
|  | ||||
|   // Listen | ||||
|   tcpServer.listen(options?.listen||0, function() { | ||||
|     const addr = this.address(); | ||||
|     if (options?.portListen) options.portListen(addr.port); | ||||
|     console.debug("bds proxy port listen, %s, (udp -> tcp)", addr.port); | ||||
|     tcpServer.once("close", () => console.debug("bds proxy close, %s", addr.port)); | ||||
|   }); | ||||
|  | ||||
|   return tcpServer; | ||||
| } | ||||
|  | ||||
| export function proxyTcpToUdp(options: proxyTcpToUdpClient) { | ||||
|   const sessions: {[keyIP: string]: net.Socket} = {}; | ||||
|   const udp = dgram.createSocket(options?.udpType||"udp4"); | ||||
|  | ||||
|   udp.on("error", console.error); | ||||
|   udp.on("message", (msg, ipInfo) => { | ||||
|     const keyInfo = `${ipInfo.address}:${ipInfo.port}`; | ||||
|  | ||||
|     // Client TCP | ||||
|     if (!sessions[keyInfo]) { | ||||
|       sessions[keyInfo] = net.createConnection(options.remote); | ||||
|       sessions[keyInfo].on("data", data => udp.send(data, ipInfo.port, ipInfo.address)); | ||||
|       sessions[keyInfo].on("error", console.error); | ||||
|       sessions[keyInfo].once("close", () => { | ||||
|         delete sessions[keyInfo]; | ||||
|         console.log("Client %s:%f close", ipInfo.address, ipInfo.port); | ||||
|       }); | ||||
|       console.log("Client %s:%f connected", ipInfo.address, ipInfo.port); | ||||
|     } | ||||
|  | ||||
|     // Send message | ||||
|     sessions[keyInfo].write(msg); | ||||
|   }); | ||||
|  | ||||
|   // Listen port | ||||
|   udp.bind(options.listen||0, function(){ | ||||
|     const addr = this.address(); | ||||
|     console.log("Port listen, %s (tcp -> udp)", addr.port); | ||||
|   }); | ||||
| } | ||||
| @@ -1,11 +0,0 @@ | ||||
| import net from "net" | ||||
| export async function randomPort(): Promise<number> { | ||||
|   return new Promise((res, rej) => { | ||||
|     const srv = net.createServer(); | ||||
|     srv.listen(0, () => { | ||||
|       const address = srv.address(); | ||||
|       if (typeof address === "string") return rej(new Error("Invalid listen port")); | ||||
|       srv.close((_err) => res(address.port)); | ||||
|     }); | ||||
|   }); | ||||
| } | ||||
| @@ -1,252 +0,0 @@ | ||||
| import { createServerManeger, platformPathID, pathOptions, serverConfig } from "../serverManeger.js"; | ||||
| import { promises as fs, createWriteStream } from "node:fs"; | ||||
| import { oracleBucket } from "../lib/remote.js"; | ||||
| import { promisify } from "node:util"; | ||||
| import { pipeline } from "node:stream/promises"; | ||||
| import * as childPromisses from "../lib/childPromisses.js"; | ||||
| import coreUtils from "@sirherobrine23/coreutils"; | ||||
| import AdmZip from "adm-zip"; | ||||
| import path from "node:path"; | ||||
| import tar from "tar"; | ||||
|  | ||||
| export type bedrockRootOption = pathOptions & { | ||||
|   variant?: "oficial"|"Pocketmine-PMMP"|"Powernukkit"|"Cloudbust" | ||||
| }; | ||||
|  | ||||
| export const hostArchEmulate = Object.freeze([ | ||||
|   "qemu-x86_64-static", | ||||
|   "qemu-x86_64", | ||||
|   "box64" | ||||
| ]); | ||||
|  | ||||
| type bedrockVersionJSON = { | ||||
|   version: string, | ||||
|   date: Date, | ||||
|   release?: "stable"|"preview", | ||||
|   url: { | ||||
|     [platform in NodeJS.Platform]?: { | ||||
|       [arch in NodeJS.Architecture]?: string | ||||
|     } | ||||
|   } | ||||
| }; | ||||
|  | ||||
| async function getPHPBin(options?: bedrockRootOption) { | ||||
|   options = {variant: "oficial", ...options}; | ||||
|   const serverPath = await platformPathID("bedrock", options); | ||||
|   const binFolder = path.join(serverPath.serverPath, "bin"); | ||||
|   const files = await coreUtils.Extends.readdir({folderPath: binFolder}); | ||||
|   const file = files.find((v) => v.endsWith("php.exe")||v.endsWith("php")); | ||||
|   if (!file) throw new Error("PHP Bin not found"); | ||||
|   return file; | ||||
| } | ||||
|  | ||||
| export async function installServer(version?: string, options?: bedrockRootOption) { | ||||
|   options = {variant: "oficial", ...options}; | ||||
|   const serverPath = await platformPathID("bedrock", options); | ||||
|   if (options?.variant === "Pocketmine-PMMP") { | ||||
|     if (!version) version = "latest"; | ||||
|     const phpBin = ((await oracleBucket.listFiles()) as any[]).filter(({name}) => name.includes("php_bin/")).filter(({name}) => name.includes(process.platform) && name.includes(process.arch)).at(0); | ||||
|     if (!phpBin) throw new Error("PHP Bin not found"); | ||||
|     const binFolder = path.join(serverPath.serverPath, "bin"); | ||||
|     if (await coreUtils.Extends.exists(binFolder)) await fs.rm(binFolder, {recursive: true}); | ||||
|     await fs.mkdir(binFolder); | ||||
|     await pipeline(await oracleBucket.getFileStream(phpBin.name), createWriteStream(path.join(binFolder, "phpTmp"))); | ||||
|  | ||||
|     if (phpBin.name.endsWith(".tar.gz")) { | ||||
|       await tar.extract({ | ||||
|         file: path.join(binFolder, "phpTmp"), | ||||
|         cwd: binFolder | ||||
|       }); | ||||
|     } else if (phpBin.name.endsWith(".zip")) { | ||||
|       await promisify((new AdmZip(path.join(binFolder, "phpTmp"))).extractAllToAsync)(binFolder, true, true); | ||||
|     } | ||||
|     await fs.rm(path.join(binFolder, "phpTmp")); | ||||
|  | ||||
|     const rel = await (await coreUtils.http.Github.GithubManeger("pmmp", "PocketMine-MP")).getRelease(); | ||||
|     const relData = version.trim().toLowerCase() === "latest" ? rel.at(0) : rel.find((v) => v.tag_name === version.trim()); | ||||
|     if (!relData) throw new Error("Version not found"); | ||||
|     const phpAsset = relData.assets.find((a) => a.name.endsWith(".phar"))?.browser_download_url; | ||||
|     if (!phpAsset) throw new Error("PHP asset not found"); | ||||
|     await coreUtils.http.large.saveFile({url: phpAsset, path: path.join(serverPath.serverPath, "PocketMine-MP.phar")}); | ||||
|  | ||||
|     return { | ||||
|       version: relData.tag_name, | ||||
|       releaseDate: new Date(relData.published_at), | ||||
|       release: (relData.prerelease ? "preview" : "stable") as "preview"|"stable", | ||||
|       url: phpAsset, | ||||
|       phpBin: phpBin.name, | ||||
|     }; | ||||
|   } else if (options?.variant === "Powernukkit") { | ||||
|     if (!version) version = "latest"; | ||||
|     const versions = await coreUtils.http.jsonRequest<{version: string, mcpeVersion: string, date: string, url: string, variantType: "snapshot"|"stable"}[]>("https://mcpeversion-static.sirherobrine23.org/powernukkit/all.json").then(data => data.body); | ||||
|     const versionData = version.trim().toLowerCase() === "latest" ? versions.at(-1) : versions.find((v) => v.version === version.trim() || v.mcpeVersion === version.trim()); | ||||
|     if (!versionData) throw new Error("Version not found"); | ||||
|     const url = versionData.url; | ||||
|     if (!url) throw new Error("Platform not supported"); | ||||
|     await coreUtils.http.large.saveFile({url, path: path.join(serverPath.serverPath, "server.jar")}); | ||||
|     return { | ||||
|       version: versionData.version, | ||||
|       mcpeVersion: versionData.mcpeVersion, | ||||
|       variantType: versionData.variantType, | ||||
|       releaseDate: new Date(versionData.date), | ||||
|       url, | ||||
|     }; | ||||
|   } else if (options?.variant === "Cloudbust") { | ||||
|     await coreUtils.http.large.saveFile({ | ||||
|       url: "https://ci.opencollab.dev/job/NukkitX/job/Server/job/bleeding/lastSuccessfulBuild/artifact/target/Cloudburst.jar", | ||||
|       path: path.join(serverPath.serverPath, "server.jar") | ||||
|     }); | ||||
|  | ||||
|     return { | ||||
|       version: "bleeding", | ||||
|       releaseDate: new Date(), | ||||
|       release: "preview", | ||||
|       url: "https://ci.opencollab.dev/job/NukkitX/job/Server/job/bleeding/lastSuccessfulBuild/artifact/target/Cloudburst.jar", | ||||
|     }; | ||||
|   } else { | ||||
|     if (!version) version = "latest"; | ||||
|     const versions = await coreUtils.http.jsonRequest<bedrockVersionJSON[]>("https://sirherobrine23.github.io/BedrockFetch/all.json").then(data => data.body); | ||||
|     const versionData = version.trim().toLowerCase() === "latest" ? versions.at(-1) : versions.find((v) => v.version === version.trim()); | ||||
|     if (!versionData) throw new Error("Version not found"); | ||||
|     let currentPlatform = process.platform; | ||||
|     if (currentPlatform === "android") currentPlatform = "linux"; | ||||
|     const url = versionData.url[currentPlatform]?.[process.arch]; | ||||
|     if (!url) throw new Error("Platform not supported"); | ||||
|     (await coreUtils.http.large.admZip(url)).zip.extractAllTo(serverPath.serverPath, true, true); | ||||
|     return { | ||||
|       version: versionData.version, | ||||
|       releaseDate: new Date(versionData.date), | ||||
|       release: versionData.release ?? "stable", | ||||
|       url: url | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| export async function startServer(options?: bedrockRootOption) { | ||||
|   // Bad fix options | ||||
|   options = {variant: "oficial", ...options}; | ||||
|   const serverPath = await platformPathID("bedrock", options); | ||||
|   // Server Object | ||||
|   const serverExec: serverConfig = { | ||||
|     exec: { | ||||
|       cwd: serverPath.serverPath, | ||||
|     }, | ||||
|     actions: {} | ||||
|   }; | ||||
|  | ||||
|   if (options?.variant === "Pocketmine-PMMP") { | ||||
|     serverExec.exec.exec = await getPHPBin(); | ||||
|     serverExec.exec.args = ["PocketMine-MP.phar", "--no-wizard"]; | ||||
|     serverExec.actions = { | ||||
|       stopServer(child_process) { | ||||
|         child_process.stdin.write("stop\n"); | ||||
|       }, | ||||
|       onStart(lineData, fnRegister) { | ||||
|         if (!(lineData.includes("INFO") && lineData.includes("Done") && lineData.includes("help"))) return; | ||||
|         const doneStart = new Date(); | ||||
|         fnRegister({ | ||||
|           serverAvaible: doneStart, | ||||
|           bootUp: runStart.getTime() - doneStart.getTime() | ||||
|         }); | ||||
|       }, | ||||
|     }; | ||||
|   } else if (options?.variant === "Powernukkit" || options?.variant === "Cloudbust") { | ||||
|     serverExec.exec.exec = "java"; | ||||
|     serverExec.exec.args = [ | ||||
|       "-XX:+UseG1GC", | ||||
|       "-XX:+ParallelRefProcEnabled", | ||||
|       "-XX:MaxGCPauseMillis=200", | ||||
|       "-XX:+UnlockExperimentalVMOptions", | ||||
|       "-XX:+DisableExplicitGC", | ||||
|       "-XX:+AlwaysPreTouch", | ||||
|       "-XX:G1NewSizePercent=30", | ||||
|       "-XX:G1MaxNewSizePercent=40", | ||||
|       "-XX:G1HeapRegionSize=8M", | ||||
|       "-XX:G1ReservePercent=20", | ||||
|       "-XX:G1HeapWastePercent=5", | ||||
|       "-XX:G1MixedGCCountTarget=4", | ||||
|       "-XX:InitiatingHeapOccupancyPercent=15", | ||||
|       "-XX:G1MixedGCLiveThresholdPercent=90", | ||||
|       "-XX:G1RSetUpdatingPauseTimePercent=5", | ||||
|       "-XX:SurvivorRatio=32", | ||||
|       "-XX:+PerfDisableSharedMem", | ||||
|       "-XX:MaxTenuringThreshold=1", | ||||
|       "-Dusing.aikars.flags=https://mcflags.emc.gs", | ||||
|       "-Daikars.new.flags=true", | ||||
|       "-jar", "server.jar" | ||||
|     ]; | ||||
|     serverExec.actions = { | ||||
|       stopServer(child_process) { | ||||
|         child_process.stdin.write("stop\n"); | ||||
|       }, | ||||
|       onStart(lineData, fnRegister) { | ||||
|         if (!(lineData.includes("INFO") && lineData.includes("Done") && lineData.includes("help"))) return; | ||||
|         const doneStart = new Date(); | ||||
|         fnRegister({ | ||||
|           serverAvaible: doneStart, | ||||
|           bootUp: runStart.getTime() - doneStart.getTime() | ||||
|         }); | ||||
|       }, | ||||
|     }; | ||||
|   } else { | ||||
|     if (process.platform === "win32") serverExec.exec.exec = "bedrock_server.exe"; | ||||
|     else if (process.platform === "darwin") throw new Error("MacOS is not supported, run in Docker or Virtual Machine"); | ||||
|     else { | ||||
|       serverExec.exec.exec = path.join(serverPath.serverPath, "bedrock_server"); | ||||
|       serverExec.exec.env = { | ||||
|         LD_LIBRARY_PATH: serverPath.serverPath | ||||
|       }; | ||||
|     } | ||||
|     if ((["android", "linux"]).includes(process.platform) && process.arch !== "x64") { | ||||
|       const exec = serverExec.exec.exec; | ||||
|       serverExec.exec.exec = undefined; | ||||
|       for (const command of hostArchEmulate) { | ||||
|         if (await childPromisses.commandExists(command, true)) { | ||||
|           serverExec.exec.args = [exec]; | ||||
|           serverExec.exec.exec = command; | ||||
|           break; | ||||
|         } | ||||
|         if (!serverExec.exec.exec) throw new Error("No emulator found for this platform"); | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     const startTest = /\[.*\]\s+Server\s+started\./; | ||||
|     // Server actions | ||||
|     serverExec.actions = { | ||||
|       stopServer(child_process) { | ||||
|         child_process.stdin.write("stop\n"); | ||||
|       }, | ||||
|       onStart(lineData, fnRegister) {if (startTest.test(lineData)) fnRegister({serverAvaible: new Date()});}, | ||||
|       playerActions(lineData, fnRegister) { | ||||
|         const playerActionsV1 = /\[.*\]\s+Player\s+((dis|)connected):\s+(.*),\s+xuid:\s+([0-9]+)/; | ||||
|         const newPlayerActions = /\[.*INFO\]\s+Player\s+(Spawned|connected|disconnected):\s+([\s\S\w]+)\s+(xuid:\s+([0-9]+))?/; | ||||
|         const connectTime = new Date(); | ||||
|         if (!(newPlayerActions.test(lineData)||playerActionsV1.test(lineData))) return; | ||||
|         let playerName: string, action: string, xuid: string; | ||||
|         if (newPlayerActions.test(lineData)) { | ||||
|           const [, actionV2,, playerNameV2,, xuidV2] = lineData.match(newPlayerActions); | ||||
|           playerName = playerNameV2; | ||||
|           action = actionV2; | ||||
|           xuid = xuidV2; | ||||
|         } else { | ||||
|           const [, actionV1,, playerNameV1, xuidV1] = lineData.match(newPlayerActions); | ||||
|           playerName = playerNameV1; | ||||
|           action = actionV1; | ||||
|           xuid = xuidV1; | ||||
|         } | ||||
|         fnRegister({ | ||||
|           player: playerName, | ||||
|           action: action === "Spawned" ? "spawned" : action === "connected" ? "join" : "leave", | ||||
|           actionDate: connectTime, | ||||
|           sessionID: serverPath.id, | ||||
|           more: { | ||||
|             xuid | ||||
|           } | ||||
|         }); | ||||
|       }, | ||||
|     }; | ||||
|   } | ||||
|  | ||||
|   const runStart = new Date(); | ||||
|   return createServerManeger(serverExec); | ||||
| } | ||||
| @@ -1,16 +0,0 @@ | ||||
| import { pathOptions } from "../serverManeger.js"; | ||||
|  | ||||
| export type javaRootOption = pathOptions & { | ||||
|   variant?: "oficial"|"Spigot"|"Paper"|"Purpur", | ||||
| }; | ||||
|  | ||||
| export async function installServer(options?: javaRootOption) { | ||||
|   options = {variant: "oficial", ...options}; | ||||
|   if (options?.variant === "Spigot") { | ||||
|   } else if (options?.variant === "Paper") { | ||||
|   } else if (options?.variant === "Purpur") { | ||||
|   } else {} | ||||
| } | ||||
|  | ||||
| export default startServer; | ||||
| export async function startServer(options?: javaRootOption) {} | ||||
| @@ -1,216 +0,0 @@ | ||||
| import { createInterface as readline } from "node:readline"; | ||||
| import { promises as fs } from "node:fs"; | ||||
| import child_process from "node:child_process"; | ||||
| import { Cloud, Extends as extendFs } from "@sirherobrine23/coreutils"; | ||||
| import crypto from "node:crypto"; | ||||
| import path from "node:path"; | ||||
| import os from "node:os"; | ||||
| import EventEmitter from "node:events"; | ||||
|  | ||||
| export type pathOptions = { | ||||
|   id?: "default"|string, | ||||
|   newId?: boolean, | ||||
|   withBuildFolder?: boolean, | ||||
| }; | ||||
|  | ||||
| export let bdsRoot = process.env.BDS_HOME?(process.env.BDS_HOME.startsWith("~")?process.env.BDS_HOME.replace("~", os.homedir()):process.env.BDS_HOME):path.join(os.homedir(), ".bdsManeger"); | ||||
| export async function platformPathID(platform: "bedrock"|"java", options?: pathOptions) { | ||||
|   if (!(["bedrock", "java"].includes(platform))) throw new Error("Invalid platform target"); | ||||
|   options = {id: "default", ...options}; | ||||
|   const platformRoot = path.join(bdsRoot, platform); | ||||
|   if (!await extendFs.exists(platformRoot)) await fs.mkdir(platformRoot, {recursive: true}); | ||||
|   if (!options) options = {}; | ||||
|  | ||||
|   // Create if not exists | ||||
|   const foldersAndLink = await fs.readdir(platformRoot); | ||||
|   if (foldersAndLink.length === 0) options.newId = true; | ||||
|   if (options.newId) { | ||||
|     options.id = crypto.randomBytes(16).toString("hex"); | ||||
|     fs.mkdir(path.join(platformRoot, options.id), {recursive: true}); | ||||
|     if (await extendFs.exists(path.join(platformRoot, "default"))) await fs.unlink(path.join(platformRoot, "default")); | ||||
|     await fs.symlink(path.join(platformRoot, options.id), path.join(platformRoot, "default")); | ||||
|   } else if (!await extendFs.exists(path.join(platformRoot, options.id))) throw new Error("Folder ID not created!"); | ||||
|  | ||||
|   // Get real id | ||||
|   if (!(/^[A-Za-z0-9]*$/).test(options.id)) throw new Error("Invalid Platform ID"); | ||||
|   if (options?.id === "default") options.id = path.basename(await fs.realpath(path.join(platformRoot, options.id)).catch(async () => (await fs.readdir(platformRoot)).sort().at(0))); | ||||
|  | ||||
|   // Mount Paths | ||||
|   const serverRoot = path.join(platformRoot, options.id); | ||||
|   const serverPath = path.join(serverRoot, "server"); | ||||
|   const hooksPath = path.join(serverRoot, "hooks"); | ||||
|   const backupPath = path.join(serverRoot, "backup"); | ||||
|   const logsPath = path.join(serverRoot, "logs"); | ||||
|   let buildFolder: string; | ||||
|   if (options?.withBuildFolder) buildFolder = path.join(serverRoot, "build"); | ||||
|  | ||||
|   // Create folder if not exists | ||||
|   if (!(await extendFs.exists(serverRoot))) await fs.mkdir(serverRoot, {recursive: true}); | ||||
|   if (!(await extendFs.exists(serverPath))) await fs.mkdir(serverPath, {recursive: true}); | ||||
|   if (!(await extendFs.exists(hooksPath))) await fs.mkdir(hooksPath, {recursive: true}); | ||||
|   if (!(await extendFs.exists(backupPath))) await fs.mkdir(backupPath, {recursive: true}); | ||||
|   if (!(await extendFs.exists(logsPath))) await fs.mkdir(logsPath, {recursive: true}); | ||||
|   if (buildFolder && !(await extendFs.exists(buildFolder))) await fs.mkdir(buildFolder, {recursive: true}); | ||||
|  | ||||
|   return { | ||||
|     id: options?.id, | ||||
|     serverRoot, | ||||
|     serverPath, | ||||
|     hooksPath, | ||||
|     backupPath, | ||||
|     logsPath, | ||||
|     buildFolder, | ||||
|     platformIDs: foldersAndLink | ||||
|   }; | ||||
| } | ||||
|  | ||||
| export type playerAction = ({action: "join"|"spawned"|"leave"}|{ | ||||
|   action: "kick"|"ban", | ||||
|   reason?: string, | ||||
|   by?: string | ||||
| }) & { | ||||
|   player: string, | ||||
|   actionDate: Date, | ||||
|   sessionID: string | ||||
|   more?: any, | ||||
|   latestAction?: playerAction | ||||
| } | ||||
|  | ||||
| export type serverConfig = { | ||||
|   exec: { | ||||
|     exec?: string, | ||||
|     args?: string[], | ||||
|     cwd?: string, | ||||
|     env?: NodeJS.ProcessEnv & {[key: string]: string}, | ||||
|   }, | ||||
|   actions?: { | ||||
|     stopServer?: (child_process: child_process.ChildProcess) => void, | ||||
|     onStart?: (lineData: string, fnRegister: (data?: {serverAvaible?: Date, bootUp?: number}) => void) => void, | ||||
|     playerActions?: (lineData: string, fnRegister: (data: playerAction) => void) => void, | ||||
|   }, | ||||
|   maneger?: { | ||||
|     backup?: { | ||||
|       folderWatch: {local: string, remoteParent?: string}[], | ||||
|     } & ({ | ||||
|       cloud: "google", | ||||
|       config: Cloud.googleOptions | ||||
|     }|{ | ||||
|       cloud: "oracle_bucket", | ||||
|       config: Cloud.oracleOptions | ||||
|     }) | ||||
|   } | ||||
| }; | ||||
|  | ||||
| declare class serverManeger extends EventEmitter { | ||||
|   on(event: "error", fn: (lineLog: any) => void): this; | ||||
|   once(event: "error", fn: (lineLog: any) => void): this; | ||||
|   emit(event: "error", data: any): boolean; | ||||
|  | ||||
|   on(event: "log", fn: (lineLog: string) => void): this; | ||||
|   once(event: "log", fn: (lineLog: string) => void): this; | ||||
|   emit(event: "log", data: string): boolean; | ||||
|  | ||||
|   on(event: "rawLog", fn: (raw: any) => void): this; | ||||
|   once(event: "rawLog", fn: (raw: any) => void): this; | ||||
|   emit(event: "rawLog", data: any): boolean; | ||||
|  | ||||
|   // Player actions | ||||
|   on(event: "playerAction", fn: (playerAction: playerAction) => void): this; | ||||
|   once(event: "playerAction", fn: (playerAction: playerAction) => void): this; | ||||
|   emit(event: "playerAction", data: playerAction): boolean; | ||||
|  | ||||
|   // Server started | ||||
|   on(event: "serverStarted", fn: (data: {serverAvaible: Date, bootUp: number}) => void): this; | ||||
|   once(event: "serverStarted", fn: (data: {serverAvaible: Date, bootUp: number}) => void): this; | ||||
|   emit(event: "serverStarted", data: {serverAvaible: Date, bootUp: number}): boolean; | ||||
| } | ||||
|  | ||||
| export async function createServerManeger(serverOptions: serverConfig): Promise<serverManeger> { | ||||
|   const internalStops: (() => any|void)[] = []; | ||||
|   if (serverOptions?.maneger?.backup) { | ||||
|     const { folderWatch, cloud } = serverOptions?.maneger?.backup; | ||||
|     if (cloud === "oracle_bucket") { | ||||
|       const { config } = serverOptions?.maneger?.backup; | ||||
|       const ociClient = await Cloud.oracleBucket(config); | ||||
|       for await (const folder of folderWatch) { | ||||
|         ociClient; | ||||
|         folder; | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   const serverExec = child_process.execFile(serverOptions.exec.exec, serverOptions.exec.args ?? [], { | ||||
|     cwd: serverOptions.exec.cwd, | ||||
|     windowsHide: true, | ||||
|     maxBuffer: Infinity, | ||||
|     env: { | ||||
|       ...process.env, | ||||
|       ...serverOptions.exec.env | ||||
|     }, | ||||
|   }); | ||||
|   const playerActions: playerAction[] = []; | ||||
|   const internalEvent = new class serverManeger extends EventEmitter { | ||||
|     async stopServer() { | ||||
|       const stopServer = serverOptions.actions?.stopServer ?? ((child_process) => child_process.kill("SIGKILL")); | ||||
|       await Promise.resolve(stopServer(serverExec)).catch(err => internalEvent.emit("error", err)); | ||||
|       internalStops.forEach((fn) => Promise.resolve().then(() => fn()).catch(err => internalEvent.emit("error", err))); | ||||
|     } | ||||
|  | ||||
|     getPlayers() { | ||||
|       return playerActions ?? []; | ||||
|     } | ||||
|   }; | ||||
|   serverExec.on("error", internalEvent.emit.bind(internalEvent, "error")); | ||||
|   const stdoutReadline = readline({input: serverExec.stdout}); | ||||
|   stdoutReadline.on("line", (line) => internalEvent.emit("log", line)); | ||||
|   stdoutReadline.on("error", internalEvent.emit.bind(internalEvent, "error")); | ||||
|   serverExec.stdout.on("data", (data) => internalEvent.emit("rawLog", data)); | ||||
|  | ||||
|   const stderrReadline = readline({input: serverExec.stderr}); | ||||
|   stderrReadline.on("line", (line) => internalEvent.emit("log", line)); | ||||
|   stderrReadline.on("error", internalEvent.emit.bind(internalEvent, "error")); | ||||
|   serverExec.stderr.on("data", (data) => internalEvent.emit("rawLog", data)); | ||||
|  | ||||
|   // Server start | ||||
|   if (serverOptions.actions?.onStart) { | ||||
|     const serverStartFN = serverOptions.actions.onStart; | ||||
|     let lock = false; | ||||
|     const started = new Date(); | ||||
|     async function register(data?: {serverAvaible?: Date, bootUp?: number}) { | ||||
|       if (lock) return; | ||||
|       const eventData = { | ||||
|         serverAvaible: data?.serverAvaible ?? new Date(), | ||||
|         bootUp: data?.bootUp ?? new Date().getTime() - started.getTime() | ||||
|       }; | ||||
|       internalEvent.emit("serverStarted", eventData); | ||||
|       lock = true; | ||||
|       stderrReadline.removeListener("line", register); | ||||
|       stdoutReadline.removeListener("line", register); | ||||
|       // emit and remove new listener for serverStarted | ||||
|       internalEvent.removeAllListeners("serverStarted"); | ||||
|       internalEvent.prependListener("serverStarted", () => { | ||||
|         internalEvent.emit("serverStarted", eventData); | ||||
|         internalEvent.removeAllListeners("serverStarted"); | ||||
|       }); | ||||
|     } | ||||
|     stdoutReadline.on("line", (line) => serverStartFN(line, register)); | ||||
|     stderrReadline.on("line", (line) => serverStartFN(line, register)); | ||||
|   } | ||||
|  | ||||
|   // Player actions | ||||
|   if (serverOptions.actions?.playerActions) { | ||||
|     const playerFn = serverOptions.actions.playerActions; | ||||
|     const registerData = (data: playerAction) => { | ||||
|       const player = playerActions.find((player) => player.player === data.player); | ||||
|       if (!player) playerActions.push(data); | ||||
|       else { | ||||
|         data.latestAction = player; | ||||
|         playerActions[playerActions.indexOf(player)] = data; | ||||
|       } | ||||
|       internalEvent.emit("playerAction", data); | ||||
|     } | ||||
|     stdoutReadline.on("line", (line) => playerFn(line, registerData)); | ||||
|     stderrReadline.on("line", (line) => playerFn(line, registerData)); | ||||
|   } | ||||
|  | ||||
|   return internalEvent; | ||||
| } | ||||
| @@ -4,22 +4,21 @@ | ||||
|     "module": "NodeNext", | ||||
|     "moduleResolution": "NodeNext", | ||||
|     "target": "ESNext", | ||||
|     "forceConsistentCasingInFileNames": true, | ||||
|     "declaration": true, | ||||
|     "strict": false, | ||||
|     "forceConsistentCasingInFileNames": true, | ||||
|     "noUnusedLocals": true, | ||||
|     "isolatedModules": true, | ||||
|     "noImplicitReturns": true, | ||||
|     "noFallthroughCasesInSwitch": true, | ||||
|     "skipLibCheck": true, | ||||
|     "allowJs": true, | ||||
|     "lib": ["ES6"] | ||||
|     "lib": [ | ||||
|       "ESNext" | ||||
|     ] | ||||
|   }, | ||||
|   "include": [ | ||||
|     "src/**/*" | ||||
|   ], | ||||
|   "exclude": [ | ||||
|     "src/**/*.test.ts", | ||||
|     "node_modules/**/*" | ||||
|     "**/*.test.ts" | ||||
|   ], | ||||
|   "ts-node": { | ||||
|     "esm": true | ||||
|   | ||||
		Reference in New Issue
	
	Block a user