From d219a313bc8136babfe0c05fbd6ef120c4336917 Mon Sep 17 00:00:00 2001 From: Alexander Medvedev Date: Mon, 11 Aug 2025 22:42:58 +0200 Subject: [PATCH] Better formatting --- README.md | 3 +- bun.lock | 68 +++---------------- docs/en/about/benchmarks.md | 19 +++--- docs/en/config/authentication.md | 41 ++++++++++- docs/en/config/basic.md | 35 +++++++++- docs/en/config/commands.md | 16 ++++- docs/en/config/compression.md | 10 +++ docs/en/config/introduction.md | 2 +- docs/en/config/lan-broadcast.md | 13 ++++ docs/en/config/logging.md | 25 ++++++- docs/en/config/proxy.md | 17 ++++- docs/en/config/pvp.md | 19 ++++++ docs/en/config/query.md | 10 +++ docs/en/config/rcon.md | 28 ++++++++ docs/en/config/resource-pack.md | 25 ++++++- docs/en/developer/contributing.md | 27 +++++--- docs/en/developer/introduction.md | 5 +- docs/en/developer/mobile.md | 28 +++++--- .../en/developer/networking/authentication.md | 22 +++--- docs/en/developer/networking/networking.md | 36 +++++----- docs/en/developer/networking/rcon.md | 12 ++-- docs/en/developer/world.md | 36 +++++----- docs/en/index.md | 11 ++- docs/en/plugin-dev/introduction.md | 2 +- .../plugin-dev/plugin-template/basic-logic.md | 34 ++++++++-- .../plugin-template/creating-project.md | 16 ++++- .../plugin-template/introduction.md | 2 + .../plugin-dev/plugin-template/inventories.md | 5 +- .../plugin-dev/plugin-template/join-event.md | 16 ++++- .../plugin-template/rock-paper-scissors.md | 9 ++- docs/en/troubleshooting/common_issues.md | 4 +- docs/nl/about/benchmarks.md | 2 +- docs/nl/developer/networking/networking.md | 16 +++-- docs/pt/about/benchmarks.md | 2 +- docs/pt/developer/networking/networking.md | 10 ++- docs/zh_cn/about/benchmarks.md | 2 +- docs/zh_cn/developer/contributing.md | 14 +++- docs/zh_cn/developer/introduction.md | 3 +- docs/zh_cn/developer/mobile.md | 14 +++- .../developer/networking/authentication.md | 6 +- docs/zh_cn/developer/networking/networking.md | 32 ++++----- docs/zh_cn/developer/networking/rcon.md | 2 +- docs/zh_cn/developer/world.md | 26 +++---- docs/zh_cn/index.md | 9 ++- docs/zh_cn/plugin-dev/introduction.md | 3 +- .../plugin-dev/plugin-template/basic-logic.md | 30 +++++++- .../plugin-template/creating-project.md | 18 ++++- .../plugin-template/introduction.md | 4 +- .../plugin-dev/plugin-template/join-event.md | 16 ++++- docs/zh_cn/troubleshooting/common_issues.md | 4 +- package.json | 4 +- 51 files changed, 579 insertions(+), 234 deletions(-) diff --git a/README.md b/README.md index 172a506..6e409c0 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,5 @@ -### Development +# Development + 1. Install [Bun](https://bun.sh) 2. Download dependencies by running `bun install` 3. Edit the documentation diff --git a/bun.lock b/bun.lock index 3249e8b..71085d8 100644 --- a/bun.lock +++ b/bun.lock @@ -164,7 +164,7 @@ "@shikijs/vscode-textmate": ["@shikijs/vscode-textmate@10.0.1", "", {}, "sha512-fTIQwLF+Qhuws31iw7Ncl1R3HUDtGwIipiJ9iU+UsDUwMhegFcQKQHd51nZjb7CArq0MvON8rbgCGQYWHUKAdg=="], - "@types/bun": ["@types/bun@1.2.19", "", { "dependencies": { "bun-types": "1.2.19" } }, "sha512-d9ZCmrH3CJ2uYKXQIUuZ/pUnTqIvLDS0SK7pFmbx8ma+ziH/FRMoAq5bYpRG7y+w1gl+HgyNZbtqgMq4W4e2Lg=="], + "@types/bun": ["@types/bun@1.2.20", "", { "dependencies": { "bun-types": "1.2.20" } }, "sha512-dX3RGzQ8+KgmMw7CsW4xT5ITBSCrSbfHc36SNT31EOUg/LA9JWq0VDdEXDRSe1InVWpd2yLUM1FUF/kEOyTzYA=="], "@types/estree": ["@types/estree@1.0.6", "", {}, "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw=="], @@ -212,7 +212,7 @@ "@vue/server-renderer": ["@vue/server-renderer@3.5.18", "", { "dependencies": { "@vue/compiler-ssr": "3.5.18", "@vue/shared": "3.5.18" }, "peerDependencies": { "vue": "3.5.18" } }, "sha512-PvIHLUoWgSbDG7zLHqSqaCoZvHi6NNmfVFOqO+OnwvqMz/tqQr3FuGWS8ufluNddk7ZLBJYMrjcw1c6XzR12mA=="], - "@vue/shared": ["@vue/shared@3.5.13", "", {}, "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ=="], + "@vue/shared": ["@vue/shared@3.5.18", "", {}, "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA=="], "@vueuse/core": ["@vueuse/core@12.5.0", "", { "dependencies": { "@types/web-bluetooth": "^0.0.20", "@vueuse/metadata": "12.5.0", "@vueuse/shared": "12.5.0", "vue": "^3.5.13" } }, "sha512-GVyH1iYqNANwcahAx8JBm6awaNgvR/SwZ1fjr10b8l1HIgDp82ngNbfzJUgOgWEoxjL+URAggnlilAEXwCOZtg=="], @@ -226,7 +226,7 @@ "birpc": ["birpc@0.2.19", "", {}, "sha512-5WeXXAvTmitV1RqJFppT5QtUiz2p1mRSYU000Jkft5ZUCLJIk4uQriYNO50HknxKwM6jd8utNc66K1qGIwwWBQ=="], - "bun-types": ["bun-types@1.2.19", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-uAOTaZSPuYsWIXRpj7o56Let0g/wjihKCkeRqUBhlLVM/Bt+Fj9xTo+LhC1OV1XDaGkz4hNC80et5xgy+9KTHQ=="], + "bun-types": ["bun-types@1.2.20", "", { "dependencies": { "@types/node": "*" }, "peerDependencies": { "@types/react": "^19" } }, "sha512-pxTnQYOrKvdOwyiyd/7sMt9yFOenN004Y6O4lCcCUoKVej48FS5cvTw9geRaEcB9TsDZaJKAxPTVvi8tFsVuXA=="], "ccount": ["ccount@2.0.1", "", {}, "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg=="], @@ -346,40 +346,20 @@ "vite": ["vite@5.4.14", "", { "dependencies": { "esbuild": "^0.21.3", "postcss": "^8.4.43", "rollup": "^4.20.0" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || >=20.0.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.4.0" }, "optionalPeers": ["@types/node", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser"], "bin": "bin/vite.js" }, "sha512-EK5cY7Q1D8JNhSaPKVK4pwBFvaTmZxEnoKXLG/U9gmdDcihQGNzFlgIvaxezFR4glP1LsuiedwMBqCXH3wZccA=="], - "vitepress": ["vitepress@1.6.3", "", { "dependencies": { "@docsearch/css": "3.8.2", "@docsearch/js": "3.8.2", "@iconify-json/simple-icons": "^1.2.21", "@shikijs/core": "^2.1.0", "@shikijs/transformers": "^2.1.0", "@shikijs/types": "^2.1.0", "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^5.2.1", "@vue/devtools-api": "^7.7.0", "@vue/shared": "^3.5.13", "@vueuse/core": "^12.4.0", "@vueuse/integrations": "^12.4.0", "focus-trap": "^7.6.4", "mark.js": "8.11.1", "minisearch": "^7.1.1", "shiki": "^2.1.0", "vite": "^5.4.14", "vue": "^3.5.13" }, "peerDependencies": { "markdown-it-mathjax3": "^4", "postcss": "^8" }, "optionalPeers": ["markdown-it-mathjax3"], "bin": "bin/vitepress.js" }, "sha512-fCkfdOk8yRZT8GD9BFqusW3+GggWYZ/rYncOfmgcDtP3ualNHCAg+Robxp2/6xfH1WwPHtGpPwv7mbA3qomtBw=="], + "vitepress": ["vitepress@1.6.4", "", { "dependencies": { "@docsearch/css": "3.8.2", "@docsearch/js": "3.8.2", "@iconify-json/simple-icons": "^1.2.21", "@shikijs/core": "^2.1.0", "@shikijs/transformers": "^2.1.0", "@shikijs/types": "^2.1.0", "@types/markdown-it": "^14.1.2", "@vitejs/plugin-vue": "^5.2.1", "@vue/devtools-api": "^7.7.0", "@vue/shared": "^3.5.13", "@vueuse/core": "^12.4.0", "@vueuse/integrations": "^12.4.0", "focus-trap": "^7.6.4", "mark.js": "8.11.1", "minisearch": "^7.1.1", "shiki": "^2.1.0", "vite": "^5.4.14", "vue": "^3.5.13" }, "peerDependencies": { "markdown-it-mathjax3": "^4", "postcss": "^8" }, "optionalPeers": ["markdown-it-mathjax3", "postcss"], "bin": { "vitepress": "bin/vitepress.js" } }, "sha512-+2ym1/+0VVrbhNyRoFFesVvBvHAVMZMK0rw60E3X/5349M1GuVdKeazuksqopEdvkKwKGs21Q729jX81/bkBJg=="], "vue": ["vue@3.5.18", "", { "dependencies": { "@vue/compiler-dom": "3.5.18", "@vue/compiler-sfc": "3.5.18", "@vue/runtime-dom": "3.5.18", "@vue/server-renderer": "3.5.18", "@vue/shared": "3.5.18" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-7W4Y4ZbMiQ3SEo+m9lnoNpV9xG7QVMLa+/0RFwwiAVkeYoyGXqWE85jabU4pllJNUzqfLShJ5YLptewhCWUgNA=="], "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], - "@vue/compiler-core/@vue/shared": ["@vue/shared@3.5.18", "", {}, "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA=="], - - "@vue/compiler-dom/@vue/shared": ["@vue/shared@3.5.18", "", {}, "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA=="], - - "@vue/compiler-sfc/@vue/shared": ["@vue/shared@3.5.18", "", {}, "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA=="], - "@vue/compiler-sfc/postcss": ["postcss@8.5.6", "", { "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", "source-map-js": "^1.2.1" } }, "sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg=="], - "@vue/compiler-ssr/@vue/shared": ["@vue/shared@3.5.18", "", {}, "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA=="], - - "@vue/reactivity/@vue/shared": ["@vue/shared@3.5.18", "", {}, "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA=="], - - "@vue/runtime-core/@vue/shared": ["@vue/shared@3.5.18", "", {}, "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA=="], - - "@vue/runtime-dom/@vue/shared": ["@vue/shared@3.5.18", "", {}, "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA=="], - - "@vue/server-renderer/@vue/shared": ["@vue/shared@3.5.18", "", {}, "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA=="], - "@vueuse/core/vue": ["vue@3.5.13", "", { "dependencies": { "@vue/compiler-dom": "3.5.13", "@vue/compiler-sfc": "3.5.13", "@vue/runtime-dom": "3.5.13", "@vue/server-renderer": "3.5.13", "@vue/shared": "3.5.13" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ=="], "@vueuse/integrations/vue": ["vue@3.5.13", "", { "dependencies": { "@vue/compiler-dom": "3.5.13", "@vue/compiler-sfc": "3.5.13", "@vue/runtime-dom": "3.5.13", "@vue/server-renderer": "3.5.13", "@vue/shared": "3.5.13" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ=="], "@vueuse/shared/vue": ["vue@3.5.13", "", { "dependencies": { "@vue/compiler-dom": "3.5.13", "@vue/compiler-sfc": "3.5.13", "@vue/runtime-dom": "3.5.13", "@vue/server-renderer": "3.5.13", "@vue/shared": "3.5.13" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ=="], - "vitepress/vue": ["vue@3.5.13", "", { "dependencies": { "@vue/compiler-dom": "3.5.13", "@vue/compiler-sfc": "3.5.13", "@vue/runtime-dom": "3.5.13", "@vue/server-renderer": "3.5.13", "@vue/shared": "3.5.13" }, "peerDependencies": { "typescript": "*" }, "optionalPeers": ["typescript"] }, "sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ=="], - - "vue/@vue/shared": ["@vue/shared@3.5.18", "", {}, "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA=="], - "@vue/compiler-sfc/postcss/nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="], "@vueuse/core/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.13", "", { "dependencies": { "@vue/compiler-core": "3.5.13", "@vue/shared": "3.5.13" } }, "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA=="], @@ -390,6 +370,8 @@ "@vueuse/core/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.13", "", { "dependencies": { "@vue/compiler-ssr": "3.5.13", "@vue/shared": "3.5.13" }, "peerDependencies": { "vue": "3.5.13" } }, "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA=="], + "@vueuse/core/vue/@vue/shared": ["@vue/shared@3.5.13", "", {}, "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ=="], + "@vueuse/integrations/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.13", "", { "dependencies": { "@vue/compiler-core": "3.5.13", "@vue/shared": "3.5.13" } }, "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA=="], "@vueuse/integrations/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.13", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/compiler-core": "3.5.13", "@vue/compiler-dom": "3.5.13", "@vue/compiler-ssr": "3.5.13", "@vue/shared": "3.5.13", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.48", "source-map-js": "^1.2.0" } }, "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ=="], @@ -398,6 +380,8 @@ "@vueuse/integrations/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.13", "", { "dependencies": { "@vue/compiler-ssr": "3.5.13", "@vue/shared": "3.5.13" }, "peerDependencies": { "vue": "3.5.13" } }, "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA=="], + "@vueuse/integrations/vue/@vue/shared": ["@vue/shared@3.5.13", "", {}, "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ=="], + "@vueuse/shared/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.13", "", { "dependencies": { "@vue/compiler-core": "3.5.13", "@vue/shared": "3.5.13" } }, "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA=="], "@vueuse/shared/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.13", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/compiler-core": "3.5.13", "@vue/compiler-dom": "3.5.13", "@vue/compiler-ssr": "3.5.13", "@vue/shared": "3.5.13", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.48", "source-map-js": "^1.2.0" } }, "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ=="], @@ -406,13 +390,7 @@ "@vueuse/shared/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.13", "", { "dependencies": { "@vue/compiler-ssr": "3.5.13", "@vue/shared": "3.5.13" }, "peerDependencies": { "vue": "3.5.13" } }, "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA=="], - "vitepress/vue/@vue/compiler-dom": ["@vue/compiler-dom@3.5.13", "", { "dependencies": { "@vue/compiler-core": "3.5.13", "@vue/shared": "3.5.13" } }, "sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA=="], - - "vitepress/vue/@vue/compiler-sfc": ["@vue/compiler-sfc@3.5.13", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/compiler-core": "3.5.13", "@vue/compiler-dom": "3.5.13", "@vue/compiler-ssr": "3.5.13", "@vue/shared": "3.5.13", "estree-walker": "^2.0.2", "magic-string": "^0.30.11", "postcss": "^8.4.48", "source-map-js": "^1.2.0" } }, "sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ=="], - - "vitepress/vue/@vue/runtime-dom": ["@vue/runtime-dom@3.5.13", "", { "dependencies": { "@vue/reactivity": "3.5.13", "@vue/runtime-core": "3.5.13", "@vue/shared": "3.5.13", "csstype": "^3.1.3" } }, "sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog=="], - - "vitepress/vue/@vue/server-renderer": ["@vue/server-renderer@3.5.13", "", { "dependencies": { "@vue/compiler-ssr": "3.5.13", "@vue/shared": "3.5.13" }, "peerDependencies": { "vue": "3.5.13" } }, "sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA=="], + "@vueuse/shared/vue/@vue/shared": ["@vue/shared@3.5.13", "", {}, "sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ=="], "@vueuse/core/vue/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.13", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.13", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q=="], @@ -456,20 +434,6 @@ "@vueuse/shared/vue/@vue/server-renderer/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.13", "", { "dependencies": { "@vue/compiler-dom": "3.5.13", "@vue/shared": "3.5.13" } }, "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA=="], - "vitepress/vue/@vue/compiler-dom/@vue/compiler-core": ["@vue/compiler-core@3.5.13", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.13", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q=="], - - "vitepress/vue/@vue/compiler-sfc/@babel/parser": ["@babel/parser@7.26.8", "", { "dependencies": { "@babel/types": "^7.26.8" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw=="], - - "vitepress/vue/@vue/compiler-sfc/@vue/compiler-core": ["@vue/compiler-core@3.5.13", "", { "dependencies": { "@babel/parser": "^7.25.3", "@vue/shared": "3.5.13", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" } }, "sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q=="], - - "vitepress/vue/@vue/compiler-sfc/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.13", "", { "dependencies": { "@vue/compiler-dom": "3.5.13", "@vue/shared": "3.5.13" } }, "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA=="], - - "vitepress/vue/@vue/runtime-dom/@vue/reactivity": ["@vue/reactivity@3.5.13", "", { "dependencies": { "@vue/shared": "3.5.13" } }, "sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg=="], - - "vitepress/vue/@vue/runtime-dom/@vue/runtime-core": ["@vue/runtime-core@3.5.13", "", { "dependencies": { "@vue/reactivity": "3.5.13", "@vue/shared": "3.5.13" } }, "sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw=="], - - "vitepress/vue/@vue/server-renderer/@vue/compiler-ssr": ["@vue/compiler-ssr@3.5.13", "", { "dependencies": { "@vue/compiler-dom": "3.5.13", "@vue/shared": "3.5.13" } }, "sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA=="], - "@vueuse/core/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser": ["@babel/parser@7.26.8", "", { "dependencies": { "@babel/types": "^7.26.8" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw=="], "@vueuse/core/vue/@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.26.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA=="], @@ -482,10 +446,6 @@ "@vueuse/shared/vue/@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.26.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA=="], - "vitepress/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser": ["@babel/parser@7.26.8", "", { "dependencies": { "@babel/types": "^7.26.8" }, "bin": { "parser": "bin/babel-parser.js" } }, "sha512-TZIQ25pkSoaKEYYaHbbxkfL36GNsQ6iFiBbeuzAkLnXayKR1yP1zFe+NxuZWWsUyvt8icPU9CCq0sgWGXR1GEw=="], - - "vitepress/vue/@vue/compiler-sfc/@babel/parser/@babel/types": ["@babel/types@7.26.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA=="], - "@vueuse/core/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types": ["@babel/types@7.26.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA=="], "@vueuse/core/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.9", "", {}, "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="], @@ -504,12 +464,6 @@ "@vueuse/shared/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="], - "vitepress/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types": ["@babel/types@7.26.8", "", { "dependencies": { "@babel/helper-string-parser": "^7.25.9", "@babel/helper-validator-identifier": "^7.25.9" } }, "sha512-eUuWapzEGWFEpHFxgEaBG8e3n6S8L3MSu0oda755rOfabWPnh0Our1AozNFVUxGFIhbKgd1ksprsoDGMinTOTA=="], - - "vitepress/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.9", "", {}, "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="], - - "vitepress/vue/@vue/compiler-sfc/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="], - "@vueuse/core/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.9", "", {}, "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="], "@vueuse/core/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="], @@ -521,9 +475,5 @@ "@vueuse/shared/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.9", "", {}, "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="], "@vueuse/shared/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="], - - "vitepress/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-string-parser": ["@babel/helper-string-parser@7.25.9", "", {}, "sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA=="], - - "vitepress/vue/@vue/compiler-dom/@vue/compiler-core/@babel/parser/@babel/types/@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.25.9", "", {}, "sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ=="], } } diff --git a/docs/en/about/benchmarks.md b/docs/en/about/benchmarks.md index 90b90cc..d0534de 100644 --- a/docs/en/about/benchmarks.md +++ b/docs/en/about/benchmarks.md @@ -7,19 +7,19 @@ Here, common Minecraft server software is compared against Pumpkin. > It's also important to consider that other servers have had years to optimize. > Vanilla forks, which don’t need to rewrite the entire Vanilla logic, can focus exclusively on optimizations. -![Screenshot From 2024-10-15 16-42-53](https://github.com/user-attachments/assets/e08fbb00-42fe-4479-a03b-11bb6886c91a) +![A screenshot showing 9 Minecraft game windows](https://github.com/user-attachments/assets/e08fbb00-42fe-4479-a03b-11bb6886c91a) ## Specifications -#### Technical +### Technical -**Software** +#### Software - Distribution: Manjaro Linux - Architecture: x86_64 (64-bit) - Kernel Version: 6.11.3-arch1-1 -**Hardware** +#### Hardware - Motherboard: MAG B650 TOMAHAWK WIFI - CPU: AMD Ryzen 7600X 6-Core @@ -27,12 +27,12 @@ Here, common Minecraft server software is compared against Pumpkin. - Storage: Samsung 990 PRO 1TB PCIe 4.0 M.2 SSD - Cooling: be quiet Dark Rock Elite -**Rust** +#### Rust - Toolchain: stable-x86_64-unknown-linux-gnu (1.81.0) - Rust Compiler: rustc 1.81.0 (eeb90cda1 2024-09-04) -**Java** +#### Java - JDK Version: OpenJDK 23 64-Bit 2024-09-17 - JRE Version: OpenJDK Runtime Environment (build 23+37) @@ -44,7 +44,7 @@ Here, common Minecraft server software is compared against Pumpkin. - View distance: 10 - Simulated distance: 10 - Online mode: false -- Rcon: false +- RCON: false Online mode was disabled for easier testing with non-premium accounts. @@ -80,7 +80,8 @@ Run args: Pumpkin does cache already loaded chunks, resulting in no extra RAM usage besides player data and minimal CPU usage. -#### Compile time +### Compile time + Compiling from nothing: **Debug:** sec @@ -135,7 +136,6 @@ Run args: `nogui` | 5 | GB | % | % | | 10 | GB | % | % | - ## Purpur Build: [2324](https://api.purpurmc.org/v2/purpur/1.21.1/2324/download) @@ -184,5 +184,4 @@ Run args: | 5 | MB | % | % | | 10 | MB | % | % | - Benchmarked at diff --git a/docs/en/config/authentication.md b/docs/en/config/authentication.md index 2824ac6..227ba3f 100644 --- a/docs/en/config/authentication.md +++ b/docs/en/config/authentication.md @@ -12,10 +12,12 @@ Servers authenthicate with Mojang's session servers in order to ensure the clien Whether authenthication is enabled or not. :::code-group + ```toml [features.toml] {2} [authentication] enabled = false ``` + ::: #### `prevent_proxy_connections`: Boolean @@ -23,33 +25,41 @@ enabled = false Whether to block proxy connections or not. :::code-group + ```toml [features.toml] {3} [authentication] enabled = true prevent_proxy_connections = true ``` + ::: #### `auth_url`: String (optional) -The URL to authenthicate with. Uses Mojang's session servers to authenthicate if not specified. + +The URL to authenthicate with. Uses Mojang's session servers to authenthicate if not specified. ##### Placeholders + | Placeholder | Description | | --------------- | ------------------ | | `{username}` | Player username | | `{server_hash}` | Hash of the server | :::code-group + ```toml [features.toml] {2} [authentication] auth_url = "[custom auth server here]" ``` + ::: #### `prevent_proxy_connection_auth_url`: String (optional) + The URL to authenthicate with if `prevent_proxy_connections` is enabled. Uses Mojang's session servers to authenthicate if not specified. ##### Placeholders + | Placeholder | Description | | --------------- | ------------------------ | | `{username}` | Player username | @@ -57,104 +67,132 @@ The URL to authenthicate with if `prevent_proxy_connections` is enabled. Uses Mo | `{ip}` | IP Address of the player | :::code-group + ```toml [features.toml] {2} [authentication] prevent_proxy_connection_auth_url = "[custom auth server here]" ``` + ::: ### Player Profile #### `allow_banned_players`: Boolean + Allow players flagged by Mojang. :::code-group + ```toml [features.toml] {2} [authentication.player_profile] allow_banned_players = true ``` + ::: #### `allowed_actions`: String Array + What actions are allowed if `allow_banned_players` is enabled. :::code-group + ```toml [features.toml] {3} [authentication.player_profile] allow_banned_players = true allowed_actions = ["FORCED_NAME_CHANGE", "USING_BANNED_SKIN"] ``` + ::: ### Textures #### `enabled`: Boolean + Whether to filter/validate player textures (e.g. skins/capes). :::code-group + ```toml [features.toml] {2} [authentication.textures] enabled = true ``` + ::: #### `allowed_url_schemes`: String Array + Allowed URL schemes for textures. :::code-group + ```toml [features.toml] {3} [authentication.textures] enabled = true allowed_url_schemes = ["http", "https"] ``` + ::: #### `allowed_url_domains`: String Array + Allowed URL domains for textures. :::code-group + ```toml [features.toml] {3} [authentication.textures] enabled = true allowed_url_domains = [".minecraft.net", ".mojang.com"] ``` + ::: ### Texture Types #### `skin`: Boolean + Whether to use player skins or not. :::code-group + ```toml [features.toml] {3} [authentication.textures.types] skin = true ``` + ::: #### `cape`: Boolean + Whether to use player capes or not. :::code-group + ```toml [features.toml] {3} [authentication.textures.types] cape = true ``` + ::: #### `elytra`: Boolean + Whether to use player elytras or not. :::code-group + ```toml [features.toml] {3} [authentication.textures.types] elytra = true ``` + ::: ## Default Config + By default, authentication is enabled and uses Mojang's servers. Here is the default config: :::code-group + ```toml [features.toml] [authentication] enabled = true @@ -174,4 +212,5 @@ skin = true cape = true elytra = true ``` + ::: diff --git a/docs/en/config/basic.md b/docs/en/config/basic.md index 908eb4a..6d64980 100644 --- a/docs/en/config/basic.md +++ b/docs/en/config/basic.md @@ -7,9 +7,11 @@ Representing `configuration.toml` The address to bind the server to. :::code-group + ```toml [configuration.toml] {2} server_address = "0.0.0.0:25565" ``` + ::: ## Seed @@ -17,9 +19,11 @@ server_address = "0.0.0.0:25565" The seed for world generation. :::code-group + ```toml [configuration.toml] {2} seed = "" ``` + ::: ## Max players @@ -27,9 +31,11 @@ seed = "" The maximum number of players allowed on the server. :::code-group + ```toml [configuration.toml] {2} max_players = 100000 ``` + ::: ## View distance @@ -37,9 +43,11 @@ max_players = 100000 The maximum view distance for players. :::code-group + ```toml [configuration.toml] {2} view_distance = 10 ``` + ::: ## Simulation distance @@ -47,9 +55,11 @@ view_distance = 10 The maximum simulation distance for players. :::code-group + ```toml [configuration.toml] {2} simulation_distance = 10 ``` + ::: ## Default difficulty @@ -57,11 +67,12 @@ simulation_distance = 10 The default game difficulty. :::code-group + ```toml [configuration.toml] {2} default_difficulty = "Normal" ``` -::: +::: ```toml Peaceful @@ -75,9 +86,11 @@ Hard The permission level assigned by the `/op` command. :::code-group + ```toml [configuration.toml] {2} op_permission_level = 4 ``` + ::: ## Allow nether @@ -85,9 +98,11 @@ op_permission_level = 4 Whether the Nether dimension is enabled. :::code-group + ```toml [configuration.toml] {2} allow_nether = true ``` + ::: ## Hardcore @@ -95,9 +110,11 @@ allow_nether = true Whether the server is in hardcore mode. :::code-group + ```toml [configuration.toml] {2} hardcore = false ``` + ::: ## Online Mode @@ -105,9 +122,11 @@ hardcore = false Whether online mode is enabled. Requires valid Minecraft accounts. :::code-group + ```toml [configuration.toml] {2} online_mode = true ``` + ::: ## Encryption @@ -118,9 +137,11 @@ Whether packet encryption is enabled. > Required when online mode is enabled. :::code-group + ```toml [configuration.toml] {2} encryption = true ``` + ::: ## MOTD @@ -128,9 +149,11 @@ encryption = true Message of the Day; the server's description displayed on the status screen. :::code-group + ```toml [configuration.toml] {2} motd = "A Blazing fast Pumpkin Server!" ``` + ::: ## TPS @@ -138,9 +161,11 @@ motd = "A Blazing fast Pumpkin Server!" The server's target tick rate. :::code-group + ```toml [configuration.toml] {2} tps = 20.0 ``` + ::: ## Default gamemode @@ -148,9 +173,11 @@ tps = 20.0 The default game mode for players. :::code-group + ```toml [configuration.toml] {2} default_gamemode = "Survival" ``` + ::: ```toml @@ -166,9 +193,11 @@ Spectator Whether to scrub players' IP addresses from logs. :::code-group + ```toml [configuration.toml] {2} scrub_ips = true ``` + ::: ## Use favicon @@ -176,9 +205,11 @@ scrub_ips = true Whether to use a server favicon or not. :::code-group + ```toml [configuration.toml] {2} use_favicon = true ``` + ::: ## Favicon path @@ -186,7 +217,9 @@ use_favicon = true The path to the server's favicon. :::code-group + ```toml [configuration.toml] {2} favicon_path = "icon.png" ``` + ::: diff --git a/docs/en/config/commands.md b/docs/en/config/commands.md index 01bbe64..e4d8b64 100644 --- a/docs/en/config/commands.md +++ b/docs/en/config/commands.md @@ -1,25 +1,33 @@ # Commands -Pumpkin supports Vanilla commands and allows you to configure where they can be ran from. + +Pumpkin supports Vanilla commands and allows you to configure where they can be ran from. ## Configuring Commands + #### `use_console`: Boolean + Whether commands from the console are accepted or not. :::code-group + ```toml [features.toml] {2} [commands] use_console = false ``` + ::: #### `log_console`: Boolean + Whether commands from players should be logged in the console or not. :::code-group + ```toml [features.toml] {2} [commands] log_console = false ``` + ::: ## Operation permission level @@ -27,20 +35,24 @@ log_console = false The default permission level for all players. :::code-group + ```toml [configuration.toml] {2} default_op_level = 0 ``` + ::: - ## Default Config + By default, Pumpkin will allow commands from console and log all commands run by players. :::code-group + ```toml [features.toml] [commands] use_console = true log_console = true default_op_level = 0 ``` + ::: diff --git a/docs/en/config/compression.md b/docs/en/config/compression.md index ede2109..56f1944 100644 --- a/docs/en/config/compression.md +++ b/docs/en/config/compression.md @@ -1,19 +1,23 @@ # Compression + Compression is used to reduce the size of packets. This is beneficial to reduce bandwidth server side and also to help players on slower internet connections. ## Configuring compression #### `enabled`: Boolean + Whether packet compression is enabled or not. > [!TIP] > It might be beneficial to disable compression if the server is behind a proxy. :::code-group + ```toml [features.toml] {2} [packet_compression] enabled = true ``` + ::: #### `threshold`: Integer (0-1024) @@ -24,10 +28,12 @@ The minimum packet size before the server attempts to compress the packet. > Increasing this value can hurt players on slower connections. :::code-group + ```toml [features.toml] {2} [packet_compression] threshold = 256 ``` + ::: #### `level`: Integer (0-9) @@ -35,10 +41,12 @@ threshold = 256 A value between 0 to 9: 0 to disable compression, 1 being the fastest compression (at the cost of size), and 9 being maximum compression (at the cost of speed). :::code-group + ```toml [features.toml] {2} [packet_compression] level = 4 ``` + ::: ## Default config @@ -46,10 +54,12 @@ level = 4 By default, compression is enabled. :::code-group + ```toml [features.toml] [packet_compression] enabled = true threshold = 256 level = 4 ``` + ::: diff --git a/docs/en/config/introduction.md b/docs/en/config/introduction.md index 55f82cd..ad39ed5 100644 --- a/docs/en/config/introduction.md +++ b/docs/en/config/introduction.md @@ -16,7 +16,7 @@ Pumpkin aims to support the latest Minecraft Version. If you want to host a Pump - Make sure to allow proxy connections. - Pumpkin and ViaProxy have no connection; don't submit issues regarding their code. Furthermore, this is a 3rd party proxy and Pumpkin does not take any responsibility for the good or the bad. -#### Key Features: +#### Key Features - Extensive Customization: Configure server settings, player behavior, world generation, and more. - Performance Optimization: Optimize server performance through configuration tweaks. diff --git a/docs/en/config/lan-broadcast.md b/docs/en/config/lan-broadcast.md index 58e5597..e946248 100644 --- a/docs/en/config/lan-broadcast.md +++ b/docs/en/config/lan-broadcast.md @@ -1,54 +1,67 @@ # LAN Broadcast + Pumpkin can advertise the server across the network in order to make it easier for local players to connect to the server easier. ## Configuring LAN Broadcast #### `enabled`: Boolean + Whether LAN broadcast is enabled or not. :::code-group + ```toml [features.toml] {2} [lan_broadcast] enabled = true ``` + ::: #### `motd`: String (optional) + The MOTD to broadcast out to clients; uses the server's MOTD by default. > [!CAUTION] > LAN broadcast MOTD does not support multiple lines, RGB colors, or gradients. Pumpkin does not verify the MOTD before broadcasting it. If the server MOTD is using these components, consider defining this field so that clients see a proper MOTD. :::code-group + ```toml [features.toml] {3} [lan_broadcast] enabled = true motd = "[your MOTD here]" ``` + ::: #### `port`: Integer (0-65535) (optional) + What port to bind to. If not specified, will bind to port 0 (any available port on the system). > [!IMPORTANT] > The protocol defines what port to broadcast to. This option only exists to specify which port to bind to on the host. This option purely exists so that the port can be predictable. :::code-group + ```toml [features.toml] {3} [lan_broadcast] enabled = true port = 46733 ``` + ::: ## Default Config + By default, LAN broadcast is disabled. :::code-group + ```toml [features.toml] [lan_broadcast] enabled = false motd = "[server MOTD here]" port = 0 ``` + ::: diff --git a/docs/en/config/logging.md b/docs/en/config/logging.md index 9d5a945..995ba14 100644 --- a/docs/en/config/logging.md +++ b/docs/en/config/logging.md @@ -1,20 +1,26 @@ # Logging + Pumpkin allows you to customize what you want in your logs. ## Configuring Logging #### `enabled`: Boolean + Whether logging is enabled or not. :::code-group + ```toml [features.toml] {2} [logging] enabled = true ``` + ::: #### `level`: Enum + The log verbosity level. Possible values are: + - Off - Error - Warn @@ -23,61 +29,77 @@ The log verbosity level. Possible values are: - Trace :::code-group + ```toml [features.toml] {3} [logging] enabled = true level = "Debug" ``` + ::: #### `env`: Boolean + Whether to allow choosing the log level by setting the `RUST_LOG` environment variable or not. :::code-group + ```toml [features.toml] {3} [logging] enabled = true env = true ``` + ::: #### `threads`: Boolean + Whether to print threads in the logging message or not. :::code-group + ```toml [features.toml] {3} [logging] enabled = true threads = false ``` + ::: #### `color`: Boolean + Whether to print to the console with color or not. :::code-group + ```toml [features.toml] {3} [logging] enabled = true color = false ``` + ::: #### `timestamp`: Boolean + Whether to print the timestamp in the message or not. :::code-group + ```toml [features.toml] {3} [logging] enabled = true timestamp = false ``` + ::: ## Default Config -By default, logging is enabled at the `Info` level and will print with color, threads, and timestamps. + +By default, logging is enabled at the `Info` level and will print with color, threads, and timestamps. :::code-group + ```toml [features.toml] [logging] enabled = true @@ -87,4 +109,5 @@ threads = true color = true timestamp = true ``` + ::: diff --git a/docs/en/config/proxy.md b/docs/en/config/proxy.md index b839183..e215a55 100644 --- a/docs/en/config/proxy.md +++ b/docs/en/config/proxy.md @@ -1,4 +1,5 @@ # Proxy + Many servers use proxies to manage connections and distribute players across servers. Pumpkin supports the following proxy protocols: - [Velocity](https://papermc.io/software/velocity) @@ -14,10 +15,12 @@ Many servers use proxies to manage connections and distribute players across ser Enables support for proxies. :::code-group + ```toml [features.toml]{2} [proxy] enabled = true ``` + ::: ### Velocity @@ -27,43 +30,52 @@ enabled = true Whether Velocity support is enabled or not. :::code-group + ```toml [features.toml]{2} [proxy.velocity] enabled = true ``` + ::: -#### `secret`: String +#### `secret`: String -The secret as configured in Velocity. +The secret as configured in Velocity. :::code-group + ```toml [features.toml]{3} [proxy.velocity] enabled = true secret = "[proxy secret here]" ``` + ::: ### BungeeCord #### `enabled`: Boolean + Whether BungeeCord support is enabled or not. :::code-group + ```toml [features.toml]{2} [proxy.bungeecord] enabled = true ``` + ::: > [!CAUTION] > BungeeCord can't verify if player info is from your proxy or an imposter. Ensure that the server's firewall is correctly configured. ## Default Config + By default, proxy support is disabled. Here is the default config: :::code-group + ```toml [features.toml] [proxy] enabled = false @@ -75,4 +87,5 @@ secret = "" [proxy.bungeecord] enabled = false ``` + ::: diff --git a/docs/en/config/pvp.md b/docs/en/config/pvp.md index 904fe84..3d1a7ed 100644 --- a/docs/en/config/pvp.md +++ b/docs/en/config/pvp.md @@ -1,62 +1,80 @@ # PVP + PVP is a core part of the Vanilla mechanics, with even the smallest change affecting gameplay. Pumpkin allows you to fully configure PVP. ## Configuring PVP #### `enabled`: Boolean + Whether PVP is enabled or not. :::code-group + ```toml [features.toml] {2} [pvp] enabled = true ``` + ::: #### `hurt_animation`: Boolean + Whether to show red hurt animation and FOV bobbing or not. :::code-group + ```toml [features.toml] {2} [pvp] hurt_animation = true ``` + ::: #### `protect_creative`: Boolean + Whether to protect players in creative against PVP or not. :::code-group + ```toml [features.toml] {2} [pvp] protect_creative = true ``` + ::: #### `knockback`: Boolean + Whether attacks should have knockback or not. :::code-group + ```toml [features.toml] {2} [pvp] knockback = true ``` + ::: #### `swing`: Boolean + Whether players should swing when attacking or not. :::code-group + ```toml [features.toml] {2} [pvp] swing = true ``` + ::: ## Default Config + By default, all PVP options are enabled in order to match vanilla behavior. :::code-group + ```toml [features.toml] [pvp] enabled = true @@ -65,4 +83,5 @@ protect_creative = true knockback = true swing = true ``` + ::: diff --git a/docs/en/config/query.md b/docs/en/config/query.md index a3cab87..b1bca6f 100644 --- a/docs/en/config/query.md +++ b/docs/en/config/query.md @@ -1,36 +1,46 @@ # Query + The Query protocol is a simple way to query the server about its status. Pumpkin fully supports the Query protocol. ## Configuring Query #### `enabled`: Boolean + Whether to listen for Query protocol requests or not. :::code-group + ```toml [features.toml] {2} [query] enabled = true ``` + ::: #### `port`: Integer (0-65535) (optional) + Which port to listen to Query protocol requests on. If not specified, it uses the same port as the server. :::code-group + ```toml [features.toml] {3} [query] enabled = true port = 12345 ``` + ::: ## Default Config + By default, Query is disabled. It will run on the server port if enabled unless specified explicitly. :::code-group + ```toml [features.toml] [query] enabled = true port = 25565 ``` + ::: diff --git a/docs/en/config/rcon.md b/docs/en/config/rcon.md index 577fec4..a9c72c2 100644 --- a/docs/en/config/rcon.md +++ b/docs/en/config/rcon.md @@ -1,4 +1,5 @@ # RCON + RCON is a protocol that allows you to remotely manage the server from a different device. Pumpkin has full support for RCON. ## Configuring RCON @@ -6,90 +7,116 @@ RCON is a protocol that allows you to remotely manage the server from a differen #### `enabled`: Boolean :::code-group + ```toml [features.toml] {2} [rcon] enabled = true ``` + ::: #### `address`: String + The address and port that RCON should listen to. :::code-group + ```toml [features.toml] {3} [rcon] enabled = true address = "0.0.0.0:25575" ``` + ::: #### `password`: String + The password to use for RCON authentication. :::code-group + ```toml [features.toml] {3} [rcon] enabled = true password = "[your safe password here]" ``` + ::: #### `max_connections`: Integer + The max number of RCON connections allowed at a single time. Set this to 0 to disable the limit. :::code-group + ```toml [features.toml] {3} [rcon] enabled = true max_connections = 5 ``` + ::: ### Logging + #### `log_logged_successfully`: Boolean + Whether successful logins should be logged to console or not. :::code-group + ```toml [features.toml] {2} [rcon.logging] log_logged_successfully = true ``` + ::: #### `log_wrong_password`: Boolean + Whether wrong password attempts should be logged to console or not. :::code-group + ```toml [features.toml] {2} [rcon.logging] log_logged_successfully = true ``` + ::: #### `log_commands`: Boolean + Whether to log commands ran from RCON to console or not. :::code-group + ```toml [features.toml] {2} [rcon.logging] log_commands = true ``` + ::: #### `log_quit`: Boolean + Whether RCON client quit should be logged or not. :::code-group + ```toml [features.toml] {2} [rcon.logging] log_quit = true ``` + ::: ## Default Config + By default, RCON is disabled. :::code-group + ```toml [features.toml] [rcon] enabled = false @@ -103,4 +130,5 @@ log_wrong_password = true log_commands = true log_quit = true ``` + ::: diff --git a/docs/en/config/resource-pack.md b/docs/en/config/resource-pack.md index 82e4980..2393675 100644 --- a/docs/en/config/resource-pack.md +++ b/docs/en/config/resource-pack.md @@ -1,4 +1,5 @@ # Resource Pack + Servers can send resource packs to clients in order to change the appearance of the game on the client. Pumpkin allows you to fully configure the resource pack. > [!TIP] @@ -7,30 +8,37 @@ Servers can send resource packs to clients in order to change the appearance of ## Configuring Resource Pack #### `enabled`: Boolean + Whether a resource pack is enabled or not. :::code-group + ```toml [features.toml] {2} [resource_pack] enabled = true ``` + ::: #### `resource_pack_url`: String -The direct download URL to the resource pack. + +The direct download URL to the resource pack. > [!TIP] > You can host the resource pack for free at [MCPacks](https://mc-packs.net/). :::code-group + ```toml [features.toml] {3} [resource_pack] enabled = true resource_pack_url = "[your download URL here]" ``` + ::: #### `resource_pack_sha1`: String + The SHA1 hash of the resource pack. > [!IMPORTANT] @@ -41,51 +49,65 @@ The SHA1 hash of the resource pack. ::: details How do I get the SHA1 hash of my resource pack? ::: code-group + ```powershell [Windows (PowerShell)] Get-FileHash [file] SHA1 ``` + ```shell [Mac OS] shasum -a 1 [file] ``` + ```shell [Linux] sha1sum [file] ``` + ::: :::code-group + ```toml [features.toml] {3} [resource_pack] enabled = true resource_pack_sha1 = "[your hash here]" ``` + ::: #### `prompt_message`: String + The message to show to the user when prompted to download the resource pack. :::code-group + ```toml [features.toml] {3} [resource_pack] enabled = true prompt_message = "[your message here]" ``` + ::: #### `force`: Boolean + Whether to force the client to download the resource pack or not. If the client declines the download, they will be kicked from the server. :::code-group + ```toml [features.toml] {3} [resource_pack] enabled = true force = false ``` + ::: ## Default Config + By default, no resource pack is sent to clients. :::code-group + ```toml [features.toml] [resource_pack] enabled = false @@ -94,4 +116,5 @@ resource_pack_sha1 = "" prompt_message = "" force = false ``` + ::: diff --git a/docs/en/developer/contributing.md b/docs/en/developer/contributing.md index 1ef6fd7..dd284e5 100644 --- a/docs/en/developer/contributing.md +++ b/docs/en/developer/contributing.md @@ -1,13 +1,17 @@ -### Contributing to Pumpkin +# Contributing to Pumpkin + We appreciate your interest in contributing to Pumpkin! This document outlines the guidelines for submitting bug reports, feature suggestions, and code changes. -### Getting Started +## Getting Started + The easiest way to get started is by asking for help in [our Discord server](https://discord.gg/wT8XjrjKkf). -### How to Contribute +## How to Contribute + There are several ways you can contribute to Pumpkin: -#### Reporting Bugs +### Reporting Bugs + If you encounter a bug, please search for existing issues on the issue tracker first. If you can't find a duplicate issue, open a new one. @@ -15,22 +19,23 @@ There are several ways you can contribute to Pumpkin: Follow the template and provide a clear description of the bug, including steps to reproduce it if possible. Screenshots, logs, or code snippets can also be helpful. -#### Suggesting Features +### Suggesting Features + Do you have an idea on how Pumpkin can be improved? Share your thoughts by opening an issue on the issue tracker. Describe the proposed feature in detail, including its benefits and potential implementation considerations. -#### Contributing Code +### Contributing Code + To get started with contributing code to Pumpkin, fork the repository on GitHub 1. First, create a GitHub account if you don't already have one - + 2. Go to Pumpkin's official [GitHub Organization](https://github.com/Pumpkin-MC) and press fork > Creating a fork means you now have your own copy of the Pumpkin source code (this does not mean you own the copyright). Now that you have a copy that you can edit, you will need a few tools. - 3. Install [git](https://git-scm.com/downloads) for your operating system - To get started with git, visit [Getting started with Git](https://docs.github.com/en/get-started/getting-started-with-git) @@ -46,16 +51,20 @@ There are several ways you can contribute to Pumpkin: - If you are wanting to contribute to documentation, install [NodeJS](https://nodejs.org/en) ### Decompiling Minecraft's code + When working at Pumpkin, we heavily rely on the official Minecraft client and utilize existing server logic. We often refer to Minecraft's official code. The easiest way to decompile Minecraft is by using Fabric Yarn. Make sure you have Gradle installed before running the following commands: -``` + +```shell git clone https://github.com/FabricMC/yarn.git cd yarn ./gradlew decompileVineflower ``` + After decompiling, you can find the source code located in `build/namedSrc`. ### Additional Information + We encourage you to comment on existing issues and pull requests to share your thoughts and provide feedback. Feel free to ask questions in the issue tracker or reach out to the project maintainers if you need assistance. diff --git a/docs/en/developer/introduction.md b/docs/en/developer/introduction.md index c3bd910..6f11d0b 100644 --- a/docs/en/developer/introduction.md +++ b/docs/en/developer/introduction.md @@ -1,8 +1,9 @@ -### Introduction +# Introduction Welcome to the Pumpkin Documentation! Whether you're an internal Pumpkin developer or working on a Pumpkin plugin, this documentation is your resource for everything Pumpkin. -#### Plugin Development +## Plugin Development + For a better documentation structure, plugin development docs have been moved to a [separate category](/plugin-dev/introduction). diff --git a/docs/en/developer/mobile.md b/docs/en/developer/mobile.md index 43995a4..2ee78e2 100644 --- a/docs/en/developer/mobile.md +++ b/docs/en/developer/mobile.md @@ -8,17 +8,20 @@ We recommend [Termux](https://github.com/termux/termux-app/releases) because it' Download the needed apk file for your device's architecture and install Termux. After this, you need to run some commands. We use Helix for its simplicity. + ```bash pkg update && pkg upgrade pkg install build-essential git rust rust-analyzer taplo helix helix-grammar nodejs ``` If you want to contribute, you need to install the GitHub software. + ```bash pkg install gh ``` We also recommend installing the fish shell because it's more friendly than bash. + ```bash pkg install fish chsh -s fish @@ -26,6 +29,7 @@ We also recommend installing the fish shell because it's more friendly than bash Now that you've installed basic tools, we need to do some setup. If you want to contribute, you need log into GitHub. + ```bash gh auth login ``` @@ -33,6 +37,7 @@ If you want to contribute, you need log into GitHub. Also setup git: change the editor to vim, edit your credentials, etc. After this, you need to clone the Pumpkin repo. (Before this, you can create a project directory with `mkdir proj`; it's useful) + ```bash git clone https://github.com/Pumpkin-MC/Pumpkin.git ``` @@ -41,29 +46,36 @@ If you want to contribute, you need to fork our repo and change `Pumpkin-MC` to Setup's all done now! Enjoy :) -# FAQ +## FAQ + +### How to use the text editor? -## How to use the text editor? Type `hx `. -## How to navigate through the project? +### How to navigate through the project? + You can use `ls`, `cd`, and other programs. You can also use `hx ` to browse your directory on startup. -## How can I type in the editor? +### How can I type in the editor? + Press `i` if you are in normal mode. -## HOW EXIT FROM EDITOR???? +### HOW EXIT FROM EDITOR???? + Press esc, then type `:q!` if you don't want to save, or `:wq` if you do want to save. -## Where can I learn how to use this editor? +### Where can I learn how to use this editor? + Run `hx --tutor` or go their official website. -## Why not use VS Code? +### Why not use VS Code? + 1) VS Code is hard to set up, and it works with limited functionality on web. 2) rust-analyzer doesn't work on it. Maybe an emulator can help with this, but that slows down code compilation. 3) With VS Code, it's highly desirable to have a mouse, while in Helix you only need a keyboard. 4) VS Code is laggy on some devices. -## Why is it so hard to type? +### Why is it so hard to type? + Buy a cheap bluetooth keyboard and see how much easier it becomes. diff --git a/docs/en/developer/networking/authentication.md b/docs/en/developer/networking/authentication.md index 39f90ce..ed8758f 100644 --- a/docs/en/developer/networking/authentication.md +++ b/docs/en/developer/networking/authentication.md @@ -1,28 +1,32 @@ -## Authentication -### Why authentication +# Authentication + +## Why authentication + Offline accounts, that is, accounts generated from a player's username without contacting an authorization or authentication server, can have any nickname chosen. This, without additional plugins, means that players can impersonate other players, including those with operator permissions. -### Offline server +## Offline server + By default, `online_mode` is enabled in the configuration. This enables authentication, disabling offline accounts. If you want to allow offline accounts, you can disable `online_mode` in `configuration.toml`. -### How Yggdrasil Auth works +## How Yggdrasil Auth works + 1. The client gets an authentication token and UUID from the launcher. 2. The client, during loading, fetches data from the authorization/authentication server using the authentication token, such as various signing keys and the list of blocked servers. 3. The client, when joining the server, sends a join request to the authorization/authentication servers. Mojang servers can deny this request if the account is banned. 4. The client sends its identification to the server in a packet. 5. The server, based on this identification, sends a `hasJoined` request to the authorization/authentication servers. If it succeeds, it obtains the player information, such as the skin. -### Custom Authentication Server +## Custom Authentication Server Pumpkin supports custom authentication servers. You can replace the authentication URL in `features.toml`. -#### How Pumpkin Authentication Works +### How Pumpkin Authentication Works 1. **GET Request:** Pumpkin sends a GET request to the specified authentication URL. 2. **Status Code 200:** If the authentication is successful, the server responds with a status code of 200. 3. **Parse JSON Game Profile:** Pumpkin parses the JSON game profile returned in the response. -#### Game Profile +### Game Profile ```rust struct GameProfile { @@ -33,7 +37,7 @@ struct GameProfile { } ``` -##### Property +#### Property ```rust struct Property { @@ -43,7 +47,7 @@ struct Property { } ``` -##### Profile Action +#### Profile Action ```rust enum ProfileAction { diff --git a/docs/en/developer/networking/networking.md b/docs/en/developer/networking/networking.md index 541497f..ef71d15 100644 --- a/docs/en/developer/networking/networking.md +++ b/docs/en/developer/networking/networking.md @@ -28,7 +28,7 @@ Packets in the Pumpkin protocol are organized by functionality and state. ### Minecraft Protocol -You can find all Minecraft Java packets at https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol. There you also can see which [state](#States) they are in. +You can find all Minecraft Java packets at . There you also can see which [state](#states) they are in. You can also can see all the information the packets have, which we can either read or write depending on whether they are serverbound or clientbound. ### Adding a Packet @@ -46,22 +46,20 @@ You can also can see all the information the packets have, which we can either r 2. Next, you have to make it known that your struct represents a packet. This automatically gets the packet ID from the JSON packets file. ```rust -// For clientbound packets: -#[client_packet("play:disconnect")] +use pumpkin_data::packet::clientbound::PLAY_DISCONNECT; -// For serverbound packets: -#[server_packet("login:move_player_pos")] +#[packet(PLAY_DISCONNECT)] ``` 3. Now you can create the `struct`. > [!IMPORTANT] > Please start the packet name with "C" or "S" for "Clientbound" or "Serverbound". -> Also, if it's a packet that can be sent in multiple [states](#States), please add the state to the name. For example, there are 3 different disconnect packets. +> Also, if it's a packet that can be sent in multiple [states](#states), please add the state to the name. For example, there are 3 different disconnect packets. > -> - `CLoginDisconnect` -> - `CConfigDisconnect` -> - `CPlayDisconnect` +> - `CLoginDisconnect` +> - `CConfigDisconnect` +> - `CPlayDisconnect` Create fields within your packet structure to represent the data that will be sent. @@ -98,7 +96,7 @@ impl CPlayDisconnect { ```rust #[derive(Serialize)] -#[client_packet("play:disconnect")] +#[packet(PLAY_DISCONNECT)] pub struct CPlayDisconnect { reason: TextComponent, } @@ -110,7 +108,7 @@ impl CPlayDisconnect { } #[derive(Deserialize)] -#[server_packet("login:move_player_pos")] +#[packet(PLAY_MOVE_PLAYER_POS)] pub struct SPlayerPosition { pub x: f64, pub feet_y: f64, @@ -148,17 +146,17 @@ pub struct SPlayerPosition { Pumpkin categorizes `Client`s and `Player`s separately. Everything that is not in the play state is a simple `Client`. Here are the differences: -**Client** +#### Client -- Can only be the states: Status, Login, Transfer, Config -- Is not a living entity -- Has small resource consumption +- Can only be the states: Status, Login, Transfer, Config +- Is not a living entity +- Has small resource consumption -**Player** +#### Player -- Can only be in the Play state -- Is a living entity in a world -- Has more data and consumes more resources +- Can only be in the Play state +- Is a living entity in a world +- Has more data and consumes more resources #### Sending Packets diff --git a/docs/en/developer/networking/rcon.md b/docs/en/developer/networking/rcon.md index faa5af3..1a4339e 100644 --- a/docs/en/developer/networking/rcon.md +++ b/docs/en/developer/networking/rcon.md @@ -1,25 +1,25 @@ -### RCON +# RCON (Remote Console) -### What is RCON +## What is RCON RCON (Remote Console) is a protocol designed by Valve to allow administrators to control and manage game servers remotely. It provides a way to execute commands on a server from a different location, such as a phone or a separate computer. -### Why RCON +## Why RCON - **Convenience:** Manage your server from anywhere with an internet connection. - **Flexibility:** Execute commands without needing to be physically present at the server's location. - **Efficiency:** Automate tasks and streamline server management. -### SSH vs RCON +## SSH vs RCON -**SSH** +### SSH - Offers strong encryption to protect data transmitted between the client and server. - Primarily designed for secure remote login and execution of commands on a remote machine. - Commonly used for managing Linux/Unix systems, configuring networks, and running scripts. - Provides a shell-like environment, allowing you to execute various commands and interact with the remote system. -**RCON** +### RCON - Specifically designed for remote administration of game servers, allowing you to control and manage the server's settings and operations. - Typically less secure than SSH, as it often relies on plain text passwords. diff --git a/docs/en/developer/world.md b/docs/en/developer/world.md index 58454c2..006169a 100644 --- a/docs/en/developer/world.md +++ b/docs/en/developer/world.md @@ -1,6 +1,6 @@ -### World Formats +# World Formats -#### Region File Format +## Region File Format Minecraft Beta 1.3 to Release 1.2 used a Minecraft format known as the "Region file format". @@ -8,7 +8,7 @@ The files stored in this format are `.mcr` files, each storing a group of 32x32 More details can be found on the [Minecraft Wiki](https://minecraft.wiki/w/Region_file_format). -#### Anvil File Format +## Anvil File Format Replacing the Region File Format after Minecraft Release 1.2, this is the file format used to store modern Vanilla Minecraft: Java Edition worlds. @@ -17,7 +17,7 @@ to a 256 height limit, then to 320, as well as a higher number of block IDs. More details can be found on the [Minecraft Wiki](https://minecraft.wiki/w/Anvil_file_format). -#### Linear File Format +## Linear File Format There is a more modern file format known as the Linear region file format. It saves on disk space and uses the zstd library instead of zlib. This is beneficial as zlib is extremely old and outdated. @@ -26,7 +26,7 @@ The files stored in this format are `.linear` files, and it saves about 50% of d More details can be found at the GitHub page for [LinearRegionFileFormatTools](https://github.com/xymb-endcrystalme/LinearRegionFileFormatTools). -#### Slime File Format +## Slime File Format Developed by Hypixel to fix many of the pitfalls of the Anvil file format, Slime also replaces zlib and saves space compared to Anvil. It saves the entire world in a single save file, and allows that file to be loaded into multiple instances. @@ -35,7 +35,7 @@ The files stored in this format are `.slime` files. More details can be found on the GitHub page for [Slime World Manager](https://github.com/cijaaimee/Slime-World-Manager#:~:text=Slime%20World%20Manager%20is%20a,worlds%20faster%20and%20save%20space.), as well as on [Dev Blog #5](https://hypixel.net/threads/dev-blog-5-storing-your-skyblock-island.2190753/) for Hypixel. -#### Schematic File Format +## Schematic File Format Unlike the other file formats listed, the Schematic File Format is not used for storing Minecraft worlds, but instead used within 3rd party programs such as MCEdit, WorldEdit, and Schematica. @@ -53,13 +53,13 @@ Pumpkin then calls for world generation: `AnvilChunkReader` is called to process the region files for the given save -- As stated above, region files store 32x32 chunks +- As stated above, region files store 32x32 chunks > Each region file is named corresponding to coordinates of where it is in the world > r.{}.{}.mca -- The location table is read from the save file, representing the chunk coordinates -- The timestamp table is read from the save file, representing the last time the chunk was modified +- The location table is read from the save file, representing the chunk coordinates +- The timestamp table is read from the save file, representing the last time the chunk was modified #### No Save Present @@ -67,17 +67,17 @@ The world seed is set to "0". In the future it will be set to the value in the " `PlainsGenerator` is called, as so far `Plains` is the only biome that has been implemented. -- `PerlinTerrainGenerator` is called to set chunk height -- Stone height is set 5 below chunk height -- Dirt height is set to 2 below chunk height -- Grass blocks appear at the top of dirt -- Bedrock is set at y = -64 -- Flowers and short grass are scattered about randomly +- `PerlinTerrainGenerator` is called to set chunk height +- Stone height is set 5 below chunk height +- Dirt height is set to 2 below chunk height +- Grass blocks appear at the top of dirt +- Bedrock is set at y = -64 +- Flowers and short grass are scattered about randomly `SuperflatGenerator` is also available, but is not currently callable. -- Bedrock is set at y = -64 -- Dirt is set two blocks up -- Grass blocks are set one more block up +- Bedrock is set at y = -64 +- Dirt is set two blocks up +- Grass blocks are set one more block up Blocks are able to be placed and broken, but changes are not able to be saved in any world format. Anvil worlds are currently read only. diff --git a/docs/en/index.md b/docs/en/index.md index 976539e..8d36156 100644 --- a/docs/en/index.md +++ b/docs/en/index.md @@ -7,7 +7,8 @@ Pre-release: Currently under development and not yet ready for official release. To run Pumpkin with Rust, ensure you have [Rust](https://www.rust-lang.org/tools/install) installed. -1. Clone the repository: +1. **Clone the repository** and navigate into the directory: + ```shell git clone https://github.com/Pumpkin-MC/Pumpkin.git cd Pumpkin @@ -25,6 +26,7 @@ cargo run --release ``` 4. **Optional:** If you want to use your CPU features, you can set the `target-cpu=native` Rust compiler flag. + ```shell RUSTFLAGS='-C target-cpu=native' cargo run --release ``` @@ -46,9 +48,10 @@ docker run --rm \ - ``: The port you want to connect to Pumpkin with, for example `25565`. - ``: The location where you want your server config and data to be stored, for example `./data`. -### Example +### Example To run Pumpkin on port `25565` and store data in a directory called `./data`, you would run the following command: + ```shell docker run --rm \ -p 25565:25565 \ @@ -57,12 +60,14 @@ docker run --rm \ ``` ## Test Server + Pumpkin has a test server maintained by @kralverde. Its runs on the latest commit of Pumpkin's master branch. - **IP:** pumpkin.kralverde.dev **Specs:** + - OS: Debian GNU/Linux bookworm 12.7 x86_64 - Kernel: Linux 6.1.0-21-cloud-amd64 - CPU: Intel Core (Haswell, no TSX) (2) @ 2.40 GHz -- RAM: 4GB DIMM \ No newline at end of file +- RAM: 4GB DIMM diff --git a/docs/en/plugin-dev/introduction.md b/docs/en/plugin-dev/introduction.md index 981b193..9b76001 100644 --- a/docs/en/plugin-dev/introduction.md +++ b/docs/en/plugin-dev/introduction.md @@ -1,4 +1,5 @@ # Pumpkin Plugin Development + ::: warning The Pumpkin Plugin API is still in a very early stage of development and may change at any time. If you run into any issues please reach out on [our Discord server](https://discord.gg/aaNuD6rFEe). @@ -7,4 +8,3 @@ If you run into any issues please reach out on [our Discord server](https://disc Pumpkin Plugins integrate with the server software on a very deep level allowing for many things that would not be possible on other server software. The Pumpkin Plugin API takes inspiration from the Spigot/Bukkit plugin API in many places, so if you have previous experience with these and have experience with Rust development, you should have a pretty easy time writing plugins for Pumpkin. :smile: - diff --git a/docs/en/plugin-dev/plugin-template/basic-logic.md b/docs/en/plugin-dev/plugin-template/basic-logic.md index 05d06e5..3e57df6 100644 --- a/docs/en/plugin-dev/plugin-template/basic-logic.md +++ b/docs/en/plugin-dev/plugin-template/basic-logic.md @@ -1,8 +1,11 @@ # Writing the basic logic + ## Plugin base + Even in a basic plugin, there is a lot going on under the hood, so to greatly simplify plugin development we will use the `pumpkin-api-macros` crate to create a basic empty plugin. :::code-group + ```rs:line-numbers [lib.rs] use pumpkin_api_macros::plugin_impl; @@ -21,20 +24,24 @@ impl Default for MyPlugin { } } ``` + ::: This will create an empty plugin and implement all the necessary methods for it to be loaded by Pumpkin. We can now try to compile our plugin for the first time. To do so, run this command in your project folder: + ```bash cargo build --release ``` + ::: tip NOTICE If you are using Windows, you **must** use the `--release` flag, or you will run into issues. If you are on another platform, you don't have to use it if you want to save on compile time. ::: The initial compilation will take a bit, but don't worry, later compilations will be faster. If all went well, you should be left with a message like this: + ```log ╰─ cargo build --release Compiling hello-pumpkin v0.1.0 (/home/vypal/Dokumenty/GitHub/hello-pumpkin) @@ -44,6 +51,7 @@ If all went well, you should be left with a message like this: Now you can go to the `./target/release` folder (or `./target/debug` if you didn't use `--release`) and locate your plugin binary. Depending on your operating system, the file will have one of three possible names: + - For Windows: `hello-pumpkin.dll` - For MacOS: `libhello-pumpkin.dylib` - For Linux: `libhello-pumpkin.so` @@ -55,23 +63,27 @@ If you used a different project name in the `Cargo.toml` file, look for a file w You can rename this file to whatever you like, however you must keep the file extension (`.dll`, `.dylib`, or `.so`) the same. ## Testing the plugin + Now that we have our plugin binary, we can go ahead and test it on the Pumpkin server. Installing a plugin is as simple as putting the plugin binary that we just built into the `plugins/` folder of your Pumpkin server! -Thanks to the `#[plugin_impl]` macro, the plugin will have its details (like the name, authors, version, and description) built into the binary so that the server can read them. +Thanks to the `#[plugin_impl]` macro, the plugin will have its details (like the name, authors, version, and description) built into the binary so that the server can read them. When you start up the server and run the `/plugins` command, you should see an output like this: -``` + +```text There is 1 plugin loaded: hello-pumpkin ``` ## Basic methods + The Pumpkin server currently uses two "methods" to tell the plugin about its state. These methods are `on_load` and `on_unload`. These methods don't have to be implemented, but you will usually implement at least the `on_load` method. In this method you get access to a `Context` object which can give the plugin access to information about the server, but also allows the plugin to register command handlers and events. -To make implementing these methods easier, there is another macro provided by the `pumpkin-api-macros` crate. +To make implementing these methods easier, there is another macro provided by the `pumpkin-api-macros` crate. :::code-group + ```rs [lib.rs] use pumpkin_api_macros::{plugin_impl, plugin_method}; // [!code ++:2] use pumpkin::plugin::Context; @@ -97,6 +109,7 @@ impl Default for MyPlugin { } } ``` + ::: ::: warning IMPORTANT @@ -105,32 +118,42 @@ It is important that you define any plugin methods before the `#[plugin_impl]` b This method gets a mutable reference to its plugin object (in this case the `MyPlugin` struct) which it can use to initialize any data stored in the plugin's main struct, and a reference to a `Context` object. This object is specifically constructed for this plugin based on the plugin's metadata. -### Methods implemented on the `Context` object: +### Methods implemented on the `Context` object + ```rs fn get_data_folder() -> String ``` + Returns the path to the folder dedicated to this plugin, which should be used for persistent data storage + ```rs async fn get_player_by_name(player_name: String) -> Option> ``` + If a player by the name `player_name` is found (has to be currently online), this function will return a reference to them. + ```rs async fn register_command(tree: CommandTree, permission: PermissionLvl) ``` + Registers a new command handler, with a minimum required permission level. + ```rs async fn register_event(handler: Arc, priority: EventPriority, blocking: bool) ``` + Registers a new event handler with a set priority and if it is blocking or not. By the way, `handler` is `Arc`, which means you can implement a lot of events on one handler, and then register it. ## Basic on-load method + For now we will only implement a very basic `on_load` method to be able to see that the plugin is running. Here we will set up the inner Pumpkin logger and set up a "Hello, Pumpkin!" so that we can see our plugin in action. Add this to the `on_load` method: :::code-group + ```rs [lib.rs] #[plugin_method] async fn on_load(&mut self, server: &Context) -> Result<(), String> { @@ -141,6 +164,7 @@ async fn on_load(&mut self, server: &Context) -> Result<(), String> { Ok(()) } ``` + ::: -If we build the plugin again and start up the server, you should now see "Hello, Pumpkin!" somewhere in the log. \ No newline at end of file +If we build the plugin again and start up the server, you should now see "Hello, Pumpkin!" somewhere in the log. diff --git a/docs/en/plugin-dev/plugin-template/creating-project.md b/docs/en/plugin-dev/plugin-template/creating-project.md index 666e8c9..8509bd3 100644 --- a/docs/en/plugin-dev/plugin-template/creating-project.md +++ b/docs/en/plugin-dev/plugin-template/creating-project.md @@ -1,24 +1,31 @@ # Creating a new project + Pumpkin plugins use the [Cargo](https://doc.rust-lang.org/book/ch01-03-hello-cargo.html) build system. The complete code for this plugin can be found as a [template on GitHub](https://github.com/vyPal/Hello-Pumpkin). ## Initializing a new crate + First we need to create a new project folder. You can do this by running this command in the folder you created: + ```bash cargo new --lib ``` + This will create a folder with a couple files in it. The folder structure should look like this: -``` + +```bash ├── Cargo.toml └── src └── lib.rs ``` ## Configuring the crate + Since Pumpkin plugins are loaded at runtime as dynamic libraries, we need to tell Cargo to build this crate as one. :::code-group -```toml [Cargo.toml] + +```toml [Cargo.toml] [package] name = "hello-pumpkin" version = "0.1.0" @@ -29,10 +36,12 @@ crate-type = ["cdylib"] [dependencies] ``` + ::: Next we need to add some basic dependencies. Since Pumpkin is still in early development, the internal crates aren't published to crates.io, so we need to tell Cargo to download the dependencies directly from GitHub. :::code-group + ```toml [Cargo.toml] [package] name = "hello-pumpkin" @@ -58,14 +67,17 @@ tokio = "1.42" # Logging log = "0.4" ``` + ::: For improved performance and smaller file sizes, we recommend enabling Link-Time Optimization (LTO). Be aware that this will increase compilation time. :::code-group + ```toml [Cargo.toml] [profile.release] // [!code ++:2] lto = true ``` + ::: Enables LTO only for release builds. diff --git a/docs/en/plugin-dev/plugin-template/introduction.md b/docs/en/plugin-dev/plugin-template/introduction.md index 62a9741..aef8de1 100644 --- a/docs/en/plugin-dev/plugin-template/introduction.md +++ b/docs/en/plugin-dev/plugin-template/introduction.md @@ -1,9 +1,11 @@ # Writing an Example Plugin + This tutorial will guide you through creating a new plugin. This tutorial expects that you have some experience with Rust and the command line. Topics described in this tutorial: + - Modifying the join message - Creating a rock-paper-scissors command - Saving plugin data in the plugin's directory (coming soon) diff --git a/docs/en/plugin-dev/plugin-template/inventories.md b/docs/en/plugin-dev/plugin-template/inventories.md index 960f164..9a952d3 100644 --- a/docs/en/plugin-dev/plugin-template/inventories.md +++ b/docs/en/plugin-dev/plugin-template/inventories.md @@ -1,9 +1,11 @@ # Opening a custom inventory ## Overview + The inventory system in Pumpkin provides a flexible way to manage item storage and manipulation. This guide explains how to create and implement custom inventories. ## Table of Contents + - [Opening a custom inventory](#opening-a-custom-inventory) - [Overview](#overview) - [Table of Contents](#table-of-contents) @@ -14,7 +16,6 @@ The inventory system in Pumpkin provides a flexible way to manage item storage a - [Screen Handlers](#screen-handlers) - [Using Generic Screen Handlers](#using-generic-screen-handlers) - [Creating Custom Screen Handlers](#creating-custom-screen-handlers) - - [Supported Window Types](#supported-window-types) - [Best Practices](#best-practices) - [Examples](#examples) - [Basic Inventory Usage](#basic-inventory-usage) @@ -321,4 +322,4 @@ let removed = inventory.remove_stack(0).await; // Check if inventory is empty let is_empty = inventory.is_empty().await; -``` \ No newline at end of file +``` diff --git a/docs/en/plugin-dev/plugin-template/join-event.md b/docs/en/plugin-dev/plugin-template/join-event.md index 9f7d533..fa777f3 100644 --- a/docs/en/plugin-dev/plugin-template/join-event.md +++ b/docs/en/plugin-dev/plugin-template/join-event.md @@ -1,5 +1,6 @@ # Writing a Event Handler -Event handlers are one of the main functions of plugins. They allow a plugin to tap into the internal workings of the server and alter its behavior to perform some other action. For a simple example, we will implement a handler for the `player_join` event. + +Event handlers are one of the main functions of plugins. They allow a plugin to tap into the internal workings of the server and alter its behavior to perform some other action. For a simple example, we will implement a handler for the `player_join` event. The Pumpkin plugin event system tries to copy the Bukkit/Spigot Event system, so that developers coming from there will have a easier time learning Pumpkin. However, Rust has different conceptions and rules, so it's not all like in Bukkit/Spigot. @@ -9,11 +10,15 @@ The event system uses traits to dynamically handle some events: `Event`, `Cancel Cancellable can also be an Event, because it's a trait. (TODO: verify this) ## Implementing the Join Event + Individual event handlers are just structs which implement the `EventHandler` trait (where `T` is a specific event implementation). ### What are blocking events? + The Pumpkin plugin event system differentiates between two types of events: blocking and non-blocking. Each have their benefits: + #### Blocking events + ```diff Pros: + Can modify the event (like editing the join message) @@ -23,7 +28,9 @@ Cons: - Are executed in sequence - Can slow down the server if not implemented well ``` + #### Non-blocking events + ```diff Pros: + Are executed concurrently @@ -36,10 +43,12 @@ Cons: ``` ### Writing a handler + Since our main aim here is to change the welcome message that the player sees when they join a server, we will be choosing the blocking event type with a low priority. Add this code above the `on_load` method: :::code-group + ```rs [lib.rs] use async_trait::async_trait; // [!code ++:7] use pumpkin_api_macros::with_runtime; @@ -61,9 +70,11 @@ impl EventHandler for MyJoinHandler { } } ``` + ::: **Explanation**: + - `struct MyJoinHandler;`: The struct for our event handler - `#[with_runtime(global)]`: Pumpkin uses the tokio async runtime, which acts in weird ways across the plugin boundary. Even though it is not necessary in this specific example, it is a good practice to wrap all async `impl`s that interact with async code with this macro. - `#[async_trait]`: Rust doesn't have full support for traits with async methods. So, we use the `async_trait` crate to allow this. @@ -74,8 +85,10 @@ It is important that the `#[with_runtime(global)]` macro is **above** the **`#[a ::: ### Registering the handler + Now that we have written the event handler, we need to tell the plugin to use it. We can do that by adding a single line into the `on_load` method: :::code-group + ```rs [lib.rs] use pumpkin::{ plugin::{player::player_join::PlayerJoinEvent, Context, EventHandler, EventPriority}, // [!code ++] @@ -97,5 +110,6 @@ async fn on_load(&mut self, server: &Context) -> Result<(), String> { Ok(()) } ``` + ::: Now if we build the plugin and join the server, we should see a green "Welcome" message with our username! diff --git a/docs/en/plugin-dev/plugin-template/rock-paper-scissors.md b/docs/en/plugin-dev/plugin-template/rock-paper-scissors.md index e7c5187..7fb7c46 100644 --- a/docs/en/plugin-dev/plugin-template/rock-paper-scissors.md +++ b/docs/en/plugin-dev/plugin-template/rock-paper-scissors.md @@ -1,4 +1,5 @@ # Writing a Command Handler + In Minecraft, commands are the primary way for both regular players and server operators to interact with the game on a lower level. They can be used to perform a wide range of tasks, from simple chat messages to complex server management commands. In this tutorial, we will create a basic Rock-Paper-Scissors command handler that allows players to play the game against the server. Pumpkin has its own system for handling commands, which is based around each command having a 'tree', which defines the exact structure of the command and its arguments. Each node in the tree represents a command or argument, and the tree is traversed to determine the command to execute and its parameters. @@ -8,7 +9,8 @@ Commands in Pumpkin are asynchronous, meaning that they do not block the main th We would also like to thank [ploxxxy](https://github.com/ploxxxy) for writing the original [Rock-Paper-Scissors plugin](https://github.com/ploxxxy/rock-paper-scissors-mc) from which this tutorial is based. ## Adding the basics -Each command in Pumpkin is defined as a structure that implements the `CommandExecutor` trait. This trait requires the implementation of a `execute` method, which takes the sender, server, and consumed arguments as parameters, and returns a ` -> Result<(), CommandError>`. Let's define this structure now: + +Each command in Pumpkin is defined as a structure that implements the `CommandExecutor` trait. This trait requires the implementation of a `execute` method, which takes the sender, server, and consumed arguments as parameters, and returns a `-> Result<(), CommandError>`. Let's define this structure now: ```rs use pumpkin::{ @@ -38,6 +40,7 @@ impl CommandExecutor for RockPaperScissorsExecutor { This code defines an empty structure `RockPaperScissorsExecutor` that implements the `CommandExecutor` trait. The `execute` method is defined to return `Ok(())` when called. ## Adding helper enums + To make our lives easier, we will also define a couple of enums to represent the possible choices and outcomes of the game, as well as well as a couple functions to generate random choices and check the outcome. Add these to your plugin's code. ```rs @@ -103,6 +106,7 @@ impl CommandExecutor for RockPaperScissorsExecutor { This code will allow us to later pass in the player's choice and use it in the game logic, as well as compare it with the computer's choice to determine the outcome of the game. ## Implementing the Game Logic + Now we can move on to actually implementing the game logic, and showing the outcome to the players. First we will show the player their and the computer's choice. Add this code to your plugin: @@ -181,6 +185,7 @@ impl CommandExecutor for RockPaperScissorsExecutor { And that's it! The core logic is done. Now we only have one last thing to do. ## Building and registering a command tree + As stated earlier, we need to build a command tree and register it with the server. This will allow players to execute our plugin's commands. Building a command tree isn't very hard, but you have to know the exact structure of the command and its arguments. In this case, we have a command named `rock-paper-scissors`, which will take one required argument (the player's choice). @@ -216,6 +221,6 @@ async fn on_load(&mut self, server: &Context) -> Result<(), String> { And that's it! If you compile the plugin, you can test it by running the following command: -``` +```bash /rps rock ``` diff --git a/docs/en/troubleshooting/common_issues.md b/docs/en/troubleshooting/common_issues.md index c7d8027..41325cc 100644 --- a/docs/en/troubleshooting/common_issues.md +++ b/docs/en/troubleshooting/common_issues.md @@ -1,6 +1,6 @@ -### Common Issues +# Common Issues -1. ### Failed to verify username +1. ## Failed to verify username **Issue:** Some players reported having issues logging into the server, including encountering a "Failed to verify username" error. diff --git a/docs/nl/about/benchmarks.md b/docs/nl/about/benchmarks.md index e7f2648..af438b5 100644 --- a/docs/nl/about/benchmarks.md +++ b/docs/nl/about/benchmarks.md @@ -7,7 +7,7 @@ Hier worden veelvoorkomende Minecraft-servers vergeleken met Pumpkin. > Het is ook belangrijk om te overwegen dat andere servers jaren hebben gehad voor optimalisatie. > Vanilla forks, die de volledige vanilla-logica niet hoeven te herschrijven, kunnen zich uitsluitend richten op optimalisaties. -![Screenshot From 2024-10-15 16-42-53](https://github.com/user-attachments/assets/e08fbb00-42fe-4479-a03b-11bb6886c91a) +![A screenshot showing 9 Minecraft game windows](https://github.com/user-attachments/assets/e08fbb00-42fe-4479-a03b-11bb6886c91a) ## Specificaties diff --git a/docs/nl/developer/networking/networking.md b/docs/nl/developer/networking/networking.md index c4c229e..d4007f3 100644 --- a/docs/nl/developer/networking/networking.md +++ b/docs/nl/developer/networking/networking.md @@ -39,10 +39,12 @@ You can also can see all the information the Packets have, which we can either W #[derive(Serialize)] ``` -2. Next, you have set the packet using the client_packet macro, This uses the Packet ID automatically sets the Packet ID from the JSON packets file +2. Next, you have set the packet using the packet macro ```rust -#[client_packet("play:disconnect")] +use pumpkin_data::packet::clientbound::PLAY_DISCONNECT; + +#[packet(PLAY_DISCONNECT)] ``` 3. Now you can create the Struct. @@ -85,7 +87,7 @@ impl CPlayDisconnect { ```rust #[derive(Serialize)] -#[client_packet("play:disconnect")] +#[packet(PLAY_DISCONNECT)] pub struct CPlayDisconnect { reason: TextComponent, } @@ -112,11 +114,13 @@ impl CPlayDisconnect { ### Adding a Serverbound Packet -1. Adding a Packet is easy. First, you have to derive serde Deserialize for packets. You should also use the `server_packet` macro to automatically parse the Packet ID +1. Adding a Packet is easy. First, you have to derive serde Deserialize for packets. ```rust +use pumpkin_data::packet::serverbound::PLAY_MOVE_PLAYER_POS; + #[derive(Deserialize)] -#[server_packet("login:move_player_pos")] +#[packet(PLAY_MOVE_PLAYER_POS)] ``` 2. Now you can create the Struct. @@ -145,7 +149,7 @@ pub struct SPlayerPosition { ```rust #[derive(Deserialize)] -#[server_packet("login:move_player_pos")] +#[packet(PLAY_MOVE_PLAYER_POS)] pub struct SPlayerPosition { pub x: f64, pub feet_y: f64, diff --git a/docs/pt/about/benchmarks.md b/docs/pt/about/benchmarks.md index 632411a..3a1b32d 100644 --- a/docs/pt/about/benchmarks.md +++ b/docs/pt/about/benchmarks.md @@ -7,7 +7,7 @@ Aqui, softwares de servidores Minecraft comuns são comparados com o Pumpkin. > Também é importante considerar que outros servidores tiveram anos para otimizar. > Forks do Vanilla, que não precisam reescrever toda a lógica do Vanilla, podem se concentrar exclusivamente em otimizações. -![Screenshot From 2024-10-15 16-42-53](https://github.com/user-attachments/assets/e08fbb00-42fe-4479-a03b-11bb6886c91a) +![A screenshot showing 9 Minecraft game windows](https://github.com/user-attachments/assets/e08fbb00-42fe-4479-a03b-11bb6886c91a) ## Especificações diff --git a/docs/pt/developer/networking/networking.md b/docs/pt/developer/networking/networking.md index 9c17860..bbf1a5d 100644 --- a/docs/pt/developer/networking/networking.md +++ b/docs/pt/developer/networking/networking.md @@ -45,11 +45,9 @@ Você pode encontrar todos os pacotes do Minecraft Java em [Minecraft Wiki](http 2. Em seguida, você deve deixar claro que sua struct representa um pacote. Isso automaticamente obterá o ID do pacote do arquivo JSON de pacotes. ```rust -// Para pacotes clientbound: -#[client_packet("play:disconnect")] +use pumpkin_data::packet::clientbound::PLAY_DISCONNECT; -// Para pacotes serverbound: -#[server_packet("login:move_player_pos")] +#[packet(PLAY_DISCONNECT)] ``` 3. Agora você pode criar a `struct`. @@ -97,7 +95,7 @@ impl CPlayDisconnect { ```rust #[derive(Serialize)] -#[client_packet("play:disconnect")] +#[packet(PLAY_DISCONNECT)] pub struct CPlayDisconnect { reason: TextComponent, } @@ -109,7 +107,7 @@ impl CPlayDisconnect { } #[derive(Deserialize)] -#[server_packet("login:move_player_pos")] +#[packet(PLAY_MOVE_PLAYER_POS)] pub struct SPlayerPosition { pub x: f64, pub feet_y: f64, diff --git a/docs/zh_cn/about/benchmarks.md b/docs/zh_cn/about/benchmarks.md index 5fa12e9..45c890b 100644 --- a/docs/zh_cn/about/benchmarks.md +++ b/docs/zh_cn/about/benchmarks.md @@ -7,7 +7,7 @@ > 同时也要考虑到其他服务器已经有多年的优化经验。 > 原版分支不需要重写整个原版逻辑,可以专注于优化。 -![Screenshot From 2024-10-15 16-42-53](https://github.com/user-attachments/assets/e08fbb00-42fe-4479-a03b-11bb6886c91a) +![A screenshot showing 9 Minecraft game windows](https://github.com/user-attachments/assets/e08fbb00-42fe-4479-a03b-11bb6886c91a) ## 规格 diff --git a/docs/zh_cn/developer/contributing.md b/docs/zh_cn/developer/contributing.md index 4d3c469..05f593d 100644 --- a/docs/zh_cn/developer/contributing.md +++ b/docs/zh_cn/developer/contributing.md @@ -1,13 +1,17 @@ ### 为 Pumpkin 做贡献 + 我们感谢您对 Pumpkin 贡献的兴趣!本文档概述了提交错误报告、功能建议和代码更改的指南。 ### 入门 + 最简单的入门方式是在[我们的 Discord 服务器](https://discord.gg/wT8XjrjKkf)上寻求帮助。 ### 如何贡献 + 您可以通过以下几种方式为 Pumpkin 做贡献: #### 报告错误 + 如果您遇到错误,请先在 issue tracker 上搜索现有问题。 如果找不到重复的 issue,请创建一个新 issue。 @@ -16,15 +20,17 @@ 屏幕截图、日志或代码片段也会有所帮助。 #### 建议功能 + 您对如何改进 Pumpkin 有想法吗?通过在问题跟踪器上打开一个问题来分享您的想法。 详细描述所提议的功能,包括其好处和潜在的实现考虑。 #### 贡献代码 + 要开始为 Pumpkin 贡献代码,请在 GitHub 上 fork 仓库 1. 首先,如果您还没有 GitHub 账户,请创建一个 - + 2. 前往 Pumpkin 的官方 [GitHub 组织](https://github.com/Pumpkin-MC) 并按下 fork 按钮 > 创建复刻意味着您现在拥有 Pumpkin 源代码的自己的副本(这并不意味着您拥有版权)。 @@ -46,18 +52,22 @@ - 如果您想为文档做贡献,请安装 [NodeJS](https://nodejs.org/en) ### 反编译 Minecraft 代码 + 在 Pumpkin 工作时,我们严重依赖官方 Minecraft 客户端并利用现有的服务器逻辑。我们经常参考 Minecraft 的官方代码。 反编译 Minecraft 最简单的方法是使用 Fabric Yarn。在运行以下命令之前,请确保已安装 Gradle: + ``` git clone https://github.com/FabricMC/yarn.git cd yarn ./gradlew decompileVineflower ``` + 反编译后,您可以在 `build/namedSrc` 目录中找到源代码。 ### 其他信息 + 我们鼓励您对现有 issue 和拉取请求发表评论,分享您的想法并提供反馈。 如果您需要帮助,请随时在问题跟踪器中提问或联系项目维护者。 -在提交大型贡献之前,请考虑打开一个问题或讨论,或者在我们的 Discord 上与我们交流以讨论您的方法。 \ No newline at end of file +在提交大型贡献之前,请考虑打开一个问题或讨论,或者在我们的 Discord 上与我们交流以讨论您的方法。 diff --git a/docs/zh_cn/developer/introduction.md b/docs/zh_cn/developer/introduction.md index 6b3c9d8..79b71fb 100644 --- a/docs/zh_cn/developer/introduction.md +++ b/docs/zh_cn/developer/introduction.md @@ -5,4 +5,5 @@ 无论您是 Pumpkin 内部开发者还是正在开发 Pumpkin 插件,本文档都是您了解 Pumpkin 所有内容的资源。 #### 插件开发 -为了更好的文档结构,插件开发文档已移至[单独的分类](/plugin-dev/introduction)。 \ No newline at end of file + +为了更好的文档结构,插件开发文档已移至[单独的分类](/plugin-dev/introduction)。 diff --git a/docs/zh_cn/developer/mobile.md b/docs/zh_cn/developer/mobile.md index f877908..3643b8d 100644 --- a/docs/zh_cn/developer/mobile.md +++ b/docs/zh_cn/developer/mobile.md @@ -8,17 +8,20 @@ 下载适合您设备架构的 apk 文件并安装 Termux。 安装后,您需要运行一些命令。我们使用 Helix 是因为它简单易用。 + ```bash pkg update && pkg upgrade pkg install build-essential git rust rust-analyzer taplo helix helix-grammar nodejs ``` 如果您想贡献代码,您需要安装 GitHub 软件。 + ```bash pkg install gh ``` 我们还推荐安装 fish shell,因为它比 bash 更友好。 + ```bash pkg install fish chsh -s fish @@ -26,6 +29,7 @@ 现在您已经安装了基本工具,我们需要进行一些设置。 如果您想贡献代码,您需要登录 GitHub。 + ```bash gh auth login ``` @@ -33,6 +37,7 @@ 还要设置 git:更改编辑器为 vim,编辑您的凭据等。 之后,您需要克隆 Pumpkin 仓库。(在此之前,您可以使用 `mkdir proj` 创建一个项目目录;这很有用) + ```bash git clone https://github.com/Pumpkin-MC/Pumpkin.git ``` @@ -44,26 +49,33 @@ # 常见问题 ## 如何使用文本编辑器? + 输入 `hx <路径>`。 ## 如何浏览项目? + 您可以使用 `ls`、`cd` 和其他程序。 您也可以使用 `hx <目录>` 在启动时浏览目录。 ## 如何在编辑器中输入? + 如果您处于普通模式,请按 `i`。 ## 如何退出编辑器???? + 按 esc,然后如果您不想保存,输入 `:q!`;如果想保存,输入 `:wq`。 ## 在哪里可以学习如何使用这个编辑器? + 运行 `hx --tutor` 或访问他们的官方网站。 ## 为什么不使用 VS Code? + 1) VS Code 设置困难,且在网页版上功能有限。 2) rust-analyzer 在其上不工作。也许模拟器可以解决这个问题,但那会减慢代码编译速度。 3) 使用 VS Code 强烈建议使用鼠标,而在 Helix 中您只需要键盘。 4) VS Code 在某些设备上运行缓慢。 ## 为什么输入这么困难? -购买一个便宜的蓝牙键盘,看看事情会变得多么简单。 \ No newline at end of file + +购买一个便宜的蓝牙键盘,看看事情会变得多么简单。 diff --git a/docs/zh_cn/developer/networking/authentication.md b/docs/zh_cn/developer/networking/authentication.md index 003fd26..6f150cb 100644 --- a/docs/zh_cn/developer/networking/authentication.md +++ b/docs/zh_cn/developer/networking/authentication.md @@ -1,11 +1,15 @@ ## 身份验证 + ### 为什么需要身份验证 + 离线账户,即从玩家用户名生成而不联系授权或身份验证服务器的账户,可以选择任何昵称。在没有额外插件的情况下,这意味着玩家可以冒充其他玩家,包括那些拥有操作员权限的玩家。 ### 离线服务器 + 默认情况下,配置中启用了 `online_mode`。这启用了身份验证,禁用离线账户。如果您想允许离线账户,可以在 `configuration.toml` 中禁用 `online_mode`。 ### Yggdrasil 身份验证的工作原理 + 1. 客户端从启动器获取身份验证令牌和 UUID。 2. 客户端在加载过程中,使用身份验证令牌从授权/身份验证服务器获取数据,如各种签名密钥和被阻止服务器的列表。 3. 客户端在加入服务器时,向授权/身份验证服务器发送加入请求。如果账户被封禁,Mojang 服务器可以拒绝此请求。 @@ -50,4 +54,4 @@ enum ProfileAction { FORCED_NAME_CHANGE, USING_BANNED_SKIN, } -``` \ No newline at end of file +``` diff --git a/docs/zh_cn/developer/networking/networking.md b/docs/zh_cn/developer/networking/networking.md index 13b49b8..4ee0ecd 100644 --- a/docs/zh_cn/developer/networking/networking.md +++ b/docs/zh_cn/developer/networking/networking.md @@ -28,7 +28,7 @@ Pumpkin 协议中的数据包按功能和状态组织。 ### Minecraft 协议 -您可以在 https://minecraft.wiki/w/Minecraft_Wiki:Projects/wiki.vg_merge/Protocol 找到所有 Minecraft Java 数据包。在那里,您还可以看到它们处于哪个[状态](#状态)。 +您可以在 找到所有 Minecraft Java 数据包。在那里,您还可以看到它们处于哪个[状态](#状态)。 您还可以看到数据包的所有信息,根据它们是服务器绑定还是客户端绑定,我们可以读取或写入这些信息。 ### 添加数据包 @@ -46,11 +46,9 @@ Pumpkin 协议中的数据包按功能和状态组织。 2. 接下来,您必须让系统知道您的结构表示一个数据包。这会自动从 JSON 数据包文件中获取数据包 ID。 ```rust -// 对于客户端绑定数据包: -#[client_packet("play:disconnect")] +use pumpkin_data::packet::clientbound::PLAY_DISCONNECT; -// 对于服务器绑定数据包: -#[server_packet("login:move_player_pos")] +#[packet(PLAY_DISCONNECT)] ``` 3. 现在您可以创建 `struct`。 @@ -59,9 +57,9 @@ Pumpkin 协议中的数据包按功能和状态组织。 > 请以 "C" 或 "S" 开始数据包名称,分别代表"客户端绑定"或"服务器绑定"。 > 此外,如果这是一个可以在多个[状态](#状态)下发送的数据包,请将状态添加到名称中。例如,有 3 个不同的断开连接数据包。 > -> - `CLoginDisconnect` -> - `CConfigDisconnect` -> - `CPlayDisconnect` +> - `CLoginDisconnect` +> - `CConfigDisconnect` +> - `CPlayDisconnect` 在您的数据包结构中创建字段,以表示将要发送的数据。 @@ -98,7 +96,7 @@ impl CPlayDisconnect { ```rust #[derive(Serialize)] -#[client_packet("play:disconnect")] +#[packet(PLAY_DISCONNECT)] pub struct CPlayDisconnect { reason: TextComponent, } @@ -110,7 +108,7 @@ impl CPlayDisconnect { } #[derive(Deserialize)] -#[server_packet("login:move_player_pos")] +#[packet(PLAY_MOVE_PLAYER_POS)] pub struct SPlayerPosition { pub x: f64, pub feet_y: f64, @@ -150,15 +148,15 @@ Pumpkin 将 `Client`(客户端)和 `Player`(玩家)分开分类。不在 **客户端** -- 只能处于状态:Status、Login、Transfer、Config -- 不是活动实体 -- 资源消耗小 +- 只能处于状态:Status、Login、Transfer、Config +- 不是活动实体 +- 资源消耗小 **玩家** -- 只能处于 Play 状态 -- 是世界中的一个活动实体 -- 有更多数据并消耗更多资源 +- 只能处于 Play 状态 +- 是世界中的一个活动实体 +- 有更多数据并消耗更多资源 #### 发送数据包 @@ -198,4 +196,4 @@ client.send_packet(&CStatusResponse::new("{ description: "A Description"}")); ); } }; -``` \ No newline at end of file +``` diff --git a/docs/zh_cn/developer/networking/rcon.md b/docs/zh_cn/developer/networking/rcon.md index d899bc2..2472feb 100644 --- a/docs/zh_cn/developer/networking/rcon.md +++ b/docs/zh_cn/developer/networking/rcon.md @@ -61,4 +61,4 @@ RCON是一个非常简单的协议,只有几个数据包。以下是RCON数据 2. **命令执行:** - 已验证的客户端现在可以发送命令执行数据包,每个数据包包含要执行的命令。 - - 服务器处理命令并发回包含结果或任何错误消息的输出数据包。 \ No newline at end of file + - 服务器处理命令并发回包含结果或任何错误消息的输出数据包。 diff --git a/docs/zh_cn/developer/world.md b/docs/zh_cn/developer/world.md index 76cd653..c678c6a 100644 --- a/docs/zh_cn/developer/world.md +++ b/docs/zh_cn/developer/world.md @@ -50,13 +50,13 @@ Minecraft Beta 1.3 到 Release 1.2 使用一种被称为"区域文件格式"的 调用 `AnvilChunkReader` 处理给定保存的区域文件 -- 如上所述,区域文件存储 32x32 个区块 +- 如上所述,区域文件存储 32x32 个区块 > 每个区域文件的命名对应于其在世界中的坐标 > r.{}.{}.mca -- 从保存文件中读取位置表,表示区块坐标 -- 从保存文件中读取时间戳表,表示区块最后修改的时间 +- 从保存文件中读取位置表,表示区块坐标 +- 从保存文件中读取时间戳表,表示区块最后修改的时间 #### 目前没有实现存档的保存 @@ -64,17 +64,17 @@ Minecraft Beta 1.3 到 Release 1.2 使用一种被称为"区域文件格式"的 调用 `PlainsGenerator`,因为到目前为止 `Plains`(平原)是唯一实现的生物群系。 -- 调用 `PerlinTerrainGenerator` 设置区块高度 -- 石头高度设置为区块高度下方 5 格 -- 泥土高度设置为区块高度下方 2 格 -- 草方块出现在泥土顶部 -- 基岩设置在y轴-64的高度 -- 花和矮草丛随机散布 +- 调用 `PerlinTerrainGenerator` 设置区块高度 +- 石头高度设置为区块高度下方 5 格 +- 泥土高度设置为区块高度下方 2 格 +- 草方块出现在泥土顶部 +- 基岩设置在y轴-64的高度 +- 花和矮草丛随机散布 `SuperflatGenerator`(超平坦生成器)也可用,但目前无法调用。 -- 基岩设置在y轴-64的高度 -- 泥土设置在基岩上方2层 -- 草方块在泥土上方1层 +- 基岩设置在y轴-64的高度 +- 泥土设置在基岩上方2层 +- 草方块在泥土上方1层 -可以放置和破坏方块,但无法将更改保存在任何世界格式中。Anvil 的存档文件目前是只读的。 \ No newline at end of file +可以放置和破坏方块,但无法将更改保存在任何世界格式中。Anvil 的存档文件目前是只读的。 diff --git a/docs/zh_cn/index.md b/docs/zh_cn/index.md index bd15caf..967f70f 100644 --- a/docs/zh_cn/index.md +++ b/docs/zh_cn/index.md @@ -8,6 +8,7 @@ 要使用 Rust 运行 Pumpkin,请确保您已安装 [Rust](https://www.rust-lang.org/tools/install)。 1. 克隆仓库: + ```shell git clone https://github.com/Pumpkin-MC/Pumpkin.git cd Pumpkin @@ -25,6 +26,7 @@ cargo run --release ``` 4. **可选:** 如果您想使用 CPU 特定功能,可以设置 `target-cpu=native` Rust 编译器标志。 + ```shell RUSTFLAGS='-C target-cpu=native' cargo run --release ``` @@ -46,9 +48,10 @@ docker run --rm \ - `<暴露端口>`:您想要连接 Pumpkin 的端口,例如 `25565`。 - `<服务器数据位置>`:您希望存储服务器配置和数据的位置,例如 `./data`。 -### 示例 +### 示例 要在端口 `25565` 上运行 Pumpkin 并将数据存储在名为 `./data` 的目录中,您可以运行以下命令: + ```shell docker run --rm \ -p 25565:25565 \ @@ -57,12 +60,14 @@ docker run --rm \ ``` ## 测试服务器 + Pumpkin 有一个由 @kralverde 维护的测试服务器。它运行在 Pumpkin master 分支的最新提交上。 - **IP:** pumpkin.kralverde.dev **配置:** + - 操作系统: Debian GNU/Linux bookworm 12.7 x86_64 - 内核: Linux 6.1.0-21-cloud-amd64 - CPU: Intel Core (Haswell, no TSX) (2) @ 2.40 GHz -- 内存: 4GB DIMM \ No newline at end of file +- 内存: 4GB DIMM diff --git a/docs/zh_cn/plugin-dev/introduction.md b/docs/zh_cn/plugin-dev/introduction.md index 6eafddf..7ab41f6 100644 --- a/docs/zh_cn/plugin-dev/introduction.md +++ b/docs/zh_cn/plugin-dev/introduction.md @@ -1,4 +1,5 @@ # Pumpkin 插件开发 + ::: warning Pumpkin 插件API仍处于非常早期的开发阶段,可能随时会发生变化。 如果您遇到任何问题,请在[我们的Discord服务器](https://discord.gg/aaNuD6rFEe)上联系我们。 @@ -6,4 +7,4 @@ Pumpkin 插件API仍处于非常早期的开发阶段,可能随时会发生变 Pumpkin 插件与服务器软件在很深的层次上集成,允许实现其他服务器软件无法实现的许多功能。 -Pumpkin 插件API在很多方面受到Spigot/Bukkit插件API的启发,因此如果您有这些API的使用经验并且熟悉Rust开发,您应该能够相对轻松地为Pumpkin 编写插件。 :smile: \ No newline at end of file +Pumpkin 插件API在很多方面受到Spigot/Bukkit插件API的启发,因此如果您有这些API的使用经验并且熟悉Rust开发,您应该能够相对轻松地为Pumpkin 编写插件。 :smile: diff --git a/docs/zh_cn/plugin-dev/plugin-template/basic-logic.md b/docs/zh_cn/plugin-dev/plugin-template/basic-logic.md index 2f30fb5..a96002a 100644 --- a/docs/zh_cn/plugin-dev/plugin-template/basic-logic.md +++ b/docs/zh_cn/plugin-dev/plugin-template/basic-logic.md @@ -1,8 +1,11 @@ # 编写基本逻辑 + ## 插件基础 + 即使在一个基本插件中,底层也有很多工作,因此为了大大简化插件开发,我们将使用`pumpkin-api-macros` crate来创建一个基本的空插件。 :::code-group + ```rs:line-numbers [lib.rs] use pumpkin_api_macros::plugin_impl; @@ -21,20 +24,24 @@ impl Default for MyPlugin { } } ``` + ::: 这将创建一个空插件并实现所有必要的方法,使其能够被 Pumpkin 加载。 现在我们可以尝试首次编译我们的插件。为此,在项目文件夹中运行以下命令: + ```bash cargo build --release ``` + ::: tip 注意 如果您使用的是Windows,您**必须**使用`--release`标志,否则会遇到问题。如果您使用的是其他平台,为了节省编译时间,可以不使用该标志。 ::: 初始编译会花费一些时间,但不用担心,后续编译会更快。 如果一切顺利,您应该会看到类似这样的消息: + ```log ╰─ cargo build --release Compiling hello-pumpkin v0.1.0 (/home/vypal/Dokumenty/GitHub/hello-pumpkin) @@ -44,6 +51,7 @@ cargo build --release 现在您可以前往`./target/release`文件夹(如果您没有使用`--release`,则为`./target/debug`)并找到您的插件二进制文件。 根据您的操作系统,文件名称可能是以下三种之一: + - Windows:`hello-pumpkin.dll` - MacOS:`libhello-pumpkin.dylib` - Linux:`libhello-pumpkin.so` @@ -55,23 +63,27 @@ cargo build --release 您可以将此文件重命名为任何您喜欢的名称,但必须保持文件扩展名(`.dll`、`.dylib`或`.so`)不变。 ## 测试插件 + 现在我们有了插件二进制文件,我们可以在 Pumpkin 服务器上进行测试。安装插件非常简单,只需将我们刚刚构建的插件二进制文件放入 Pumpkin 服务器的`plugins/`文件夹中! 由于`#[plugin_impl]`宏的作用,插件的详细信息(如名称、作者、版本和描述)会内置在二进制文件中,以便服务器能够读取它们。 当您启动服务器并运行`/plugins`命令时,您应该会看到类似这样的输出: -``` + +```bash 已加载1个插件: hello-pumpkin ``` ## 基本方法 + Pumpkin 服务器目前使用两个"方法"来告知插件其状态。这些方法是`on_load`和`on_unload`。 这些方法不是必须实现的,但您通常至少会实现`on_load`方法。在此方法中,您可以访问一个`Context`对象,该对象可以让插件访问有关服务器的信息,同时也允许插件注册命令处理器和事件。 为了使实现这些方法更容易,`pumpkin-api-macros` crate提供了另一个宏。 :::code-group + ```rs [lib.rs] use pumpkin_api_macros::{plugin_impl, plugin_method}; // [!code ++:2] use pumpkin::plugin::Context; @@ -97,6 +109,7 @@ impl Default for MyPlugin { } } ``` + ::: ::: warning 重要 @@ -105,32 +118,42 @@ impl Default for MyPlugin { 此方法获取对其插件对象(在本例中为`MyPlugin`结构)的可变引用,可用于初始化存储在插件主结构中的任何数据,以及对`Context`对象的引用。该对象是根据插件的元数据专门为该插件构建的。 -### `Context`对象上实现的方法: +### `Context`对象上实现的方法 + ```rs fn get_data_folder() -> String ``` + 返回专用于此插件的文件夹路径,应用于持久数据存储 + ```rs async fn get_player_by_name(player_name: String) -> Option> ``` + 如果找到名为`player_name`的玩家(必须当前在线),此函数将返回对该玩家的引用。 + ```rs async fn register_command(tree: CommandTree, permission: PermissionLvl) ``` + 注册一个新的命令处理器,具有最低所需权限级别。 + ```rs async fn register_event(handler: Arc, priority: EventPriority, blocking: bool) ``` + 注册一个新的事件处理器,具有设定的优先级,并指定是否为阻塞。 顺便说一下,`handler`是`Arc`,这意味着您可以在一个处理器上实现多个事件,然后注册它。 ## 基本on-load方法 + 现在我们将只实现一个非常基本的`on_load`方法,以便能够看到我们的插件正在运行。 在这里,我们将设置内部 Pumpkin 日志记录器,并设置一个"Hello, Pumpkin !"消息,以便我们能够看到我们的插件正在运行。 在`on_load`方法中添加以下内容: :::code-group + ```rs [lib.rs] #[plugin_method] async fn on_load(&mut self, server: &Context) -> Result<(), String> { @@ -141,6 +164,7 @@ async fn on_load(&mut self, server: &Context) -> Result<(), String> { Ok(()) } ``` + ::: -如果我们再次构建插件并启动服务器,您现在应该能在日志中看到"你好, Pumpkin !"的消息。 \ No newline at end of file +如果我们再次构建插件并启动服务器,您现在应该能在日志中看到"你好, Pumpkin !"的消息。 diff --git a/docs/zh_cn/plugin-dev/plugin-template/creating-project.md b/docs/zh_cn/plugin-dev/plugin-template/creating-project.md index 922f5ef..c316780 100644 --- a/docs/zh_cn/plugin-dev/plugin-template/creating-project.md +++ b/docs/zh_cn/plugin-dev/plugin-template/creating-project.md @@ -1,24 +1,31 @@ # 创建新项目 + Pumpkin 插件使用[Cargo](https://doc.rust-lang.org/book/ch01-03-hello-cargo.html)构建系统。 此插件的完整代码可以在[GitHub上的模板](https://github.com/vyPal/Hello-Pumpkin)中找到。 ## 初始化新的crate + 首先我们需要创建一个新的项目文件夹。您可以通过在您创建的文件夹中运行以下命令来完成: + ```bash cargo new <项目名称> --lib ``` + 这将创建一个包含几个文件的文件夹。文件夹结构应该如下所示: -``` + +```bash ├── Cargo.toml └── src └── lib.rs ``` ## 配置crate + 由于 Pumpkin 插件在运行时作为动态库加载,我们需要告诉Cargo将此crate构建为动态库。 :::code-group -```toml [Cargo.toml] + +```toml [Cargo.toml] [package] name = "hello-pumpkin" version = "0.1.0" @@ -29,10 +36,12 @@ crate-type = ["cdylib"] [dependencies] ``` + ::: 接下来我们需要添加一些基本依赖项。由于 Pumpkin 仍处于早期开发阶段,内部crate尚未发布到crates.io,所以我们需要告诉Cargo直接从GitHub下载依赖项。 :::code-group + ```toml [Cargo.toml] [package] name = "hello-pumpkin" @@ -58,14 +67,17 @@ tokio = "1.42" # 日志记录 log = "0.4" ``` + ::: 为了提高性能和减小文件大小,我们建议启用链接时优化(Link-Time Optimization,LTO)。 请注意,这将增加编译时间。 :::code-group + ```toml [Cargo.toml] [profile.release] // [!code ++:2] lto = true ``` + ::: -建议仅对发布版本启用LTO。 \ No newline at end of file +建议仅对发布版本启用LTO。 diff --git a/docs/zh_cn/plugin-dev/plugin-template/introduction.md b/docs/zh_cn/plugin-dev/plugin-template/introduction.md index d50e180..6e834ed 100644 --- a/docs/zh_cn/plugin-dev/plugin-template/introduction.md +++ b/docs/zh_cn/plugin-dev/plugin-template/introduction.md @@ -1,9 +1,11 @@ # 编写示例插件 + 本教程将指导您创建一个新的插件。 本教程假设您具有一定的Rust和命令行使用经验。 本教程涵盖的主题: + - 修改玩家加入消息 - 创建石头-剪刀-布命令(即将推出) -- 在插件目录中保存插件数据(即将推出) \ No newline at end of file +- 在插件目录中保存插件数据(即将推出) diff --git a/docs/zh_cn/plugin-dev/plugin-template/join-event.md b/docs/zh_cn/plugin-dev/plugin-template/join-event.md index 8c93fd7..4789398 100644 --- a/docs/zh_cn/plugin-dev/plugin-template/join-event.md +++ b/docs/zh_cn/plugin-dev/plugin-template/join-event.md @@ -1,4 +1,5 @@ # 编写事件处理器 + 事件处理器是插件的主要功能之一。它们允许插件接入服务器的内部工作并改变其行为,以执行其他操作。作为一个简单的例子,我们将实现一个`player_join`事件的处理器。 Pumpkin 插件事件系统尝试复制Bukkit/Spigot事件系统,以便来自那里的开发者能更容易地学习 Pumpkin 。 @@ -9,11 +10,15 @@ Rust没有继承;它只有组合。 Cancellable也可以是Event,因为它是一个特质。(待确认) ## 实现加入事件 + 单个事件处理器只是实现了`EventHandler`特质的结构体(其中`T`是特定的事件实现)。 ### 什么是阻塞事件? + Pumpkin 插件事件系统区分两种类型的事件:阻塞和非阻塞。每种都有其优势: + #### 阻塞事件 + ```diff 优点: + 可以修改事件(如编辑加入消息) @@ -23,7 +28,9 @@ Cancellable也可以是Event,因为它是一个特质。(待确认) - 按顺序执行 - 如果实现不好可能会减慢服务器速度 ``` + #### 非阻塞事件 + ```diff 优点: + 并发执行 @@ -36,10 +43,12 @@ Cancellable也可以是Event,因为它是一个特质。(待确认) ``` ### 编写处理器 + 由于我们的主要目标是更改玩家加入服务器时看到的欢迎消息,我们将选择具有低优先级的阻塞事件类型。 在`on_load`方法上方添加以下代码: :::code-group + ```rs [lib.rs] use async_trait::async_trait; // [!code ++:4] use pumpkin_api_macros::with_runtime; @@ -58,9 +67,11 @@ impl EventHandler for MyJoinHandler { } } ``` + ::: **解释**: + - `struct MyJoinHandler;`:我们事件处理器的结构体 - `#[with_runtime(global)]`: Pumpkin 使用 tokio 异步运行时,它在插件边界上会有奇怪的行为。虽然在这个特定例子中不是必需的,但最好用这个宏包装所有与异步代码交互的异步`impl`。 - `#[async_trait]`:Rust对具有异步方法的特质没有完全支持。因此,我们使用`async_trait`包来实现这一点。 @@ -71,8 +82,10 @@ impl EventHandler for MyJoinHandler { ::: ### 注册处理器 + 现在我们已经编写了事件处理器,我们需要告诉插件使用它。我们可以通过在`on_load`方法中添加一行代码来实现: :::code-group + ```rs [lib.rs] use pumpkin::plugin::{player::PlayerJoinEvent, Context, EventHandler, EventPriority}; // [!code ++] use pumpkin::plugin::{player::PlayerJoinEvent, Context, EventHandler}; // [!code --] @@ -88,5 +101,6 @@ async fn on_load(&mut self, server: &Context) -> Result<(), String> { Ok(()) } ``` + ::: -现在如果我们构建插件并加入服务器,我们应该能看到一个绿色的带有我们用户名的"欢迎"消息! \ No newline at end of file +现在如果我们构建插件并加入服务器,我们应该能看到一个绿色的带有我们用户名的"欢迎"消息! diff --git a/docs/zh_cn/troubleshooting/common_issues.md b/docs/zh_cn/troubleshooting/common_issues.md index 79a98f8..2ce522c 100644 --- a/docs/zh_cn/troubleshooting/common_issues.md +++ b/docs/zh_cn/troubleshooting/common_issues.md @@ -1,9 +1,9 @@ ### 常见问题 -1. ### 无法验证用户名 +1. ### 无法验证用户名 **问题:** 一些玩家报告在登录服务器时遇到问题,包括遇到"无法验证用户名"的错误。 **原因:** 这与身份验证有关,通常与`prevent_proxy_connections`设置有关。 - **解决方法:** 在`features.toml`中禁用`prevent_proxy_connections` \ No newline at end of file + **解决方法:** 在`features.toml`中禁用`prevent_proxy_connections` diff --git a/package.json b/package.json index 64a22d8..acadd31 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,8 @@ "preview": "vitepress preview docs" }, "devDependencies": { - "@types/bun": "^1.2.19", - "vitepress": "^1.6.3", + "@types/bun": "^1.2.20", + "vitepress": "^1.6.4", "vue": "^3.5.18" } } \ No newline at end of file