Add more docs

This commit is contained in:
Snowiiii 2024-10-29 23:21:04 +01:00
parent 9f70b95b9b
commit 14c8c7e362
7 changed files with 355 additions and 156 deletions

236
package-lock.json generated
View File

@ -5,7 +5,7 @@
"packages": { "packages": {
"": { "": {
"devDependencies": { "devDependencies": {
"vitepress": "^1.4.1", "vitepress": "^1.4.2",
"vue": "^3.5.12" "vue": "^3.5.12"
} }
}, },
@ -157,9 +157,9 @@
} }
}, },
"node_modules/@algolia/client-common": { "node_modules/@algolia/client-common": {
"version": "5.10.2", "version": "5.11.0",
"resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.10.2.tgz", "resolved": "https://registry.npmjs.org/@algolia/client-common/-/client-common-5.11.0.tgz",
"integrity": "sha512-eE4OaTlb5KZdCehWmDARq2KEmMF7DEeFLjKqFDcZNb56k1DMSsa9zCQRXZMovlf2AXLsx0A/1q+SGAEgzF7G3w==", "integrity": "sha512-6LAAQxMoxzYf3wk7HKee4YFNYYq56ifKz6g7JWAY2HGya20KQmDec2pQ8t4C90kUvGk69o8RVpHWoeT/wfBXbw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
@ -191,17 +191,17 @@
} }
}, },
"node_modules/@algolia/client-search": { "node_modules/@algolia/client-search": {
"version": "5.10.2", "version": "5.11.0",
"resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.10.2.tgz", "resolved": "https://registry.npmjs.org/@algolia/client-search/-/client-search-5.11.0.tgz",
"integrity": "sha512-rGX8uil2uvPycFgtS9Fzwvh4tgKvfFWG5RIh3E77W42HrO66bykCf9jHqhIIlCxdDJih1PuUqBYZIkIAAoSkww==", "integrity": "sha512-jP94/rojiSzUTilBqPQSfidNw8KZzzKkkrUL4kPeukTqpkZdWLB0W7OtDcqOLd4vBA7FXkEFGiRaj3WQemyLhw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@algolia/client-common": "5.10.2", "@algolia/client-common": "5.11.0",
"@algolia/requester-browser-xhr": "5.10.2", "@algolia/requester-browser-xhr": "5.11.0",
"@algolia/requester-fetch": "5.10.2", "@algolia/requester-fetch": "5.11.0",
"@algolia/requester-node-http": "5.10.2" "@algolia/requester-node-http": "5.11.0"
}, },
"engines": { "engines": {
"node": ">= 14.0.0" "node": ">= 14.0.0"
@ -288,14 +288,14 @@
} }
}, },
"node_modules/@algolia/requester-browser-xhr": { "node_modules/@algolia/requester-browser-xhr": {
"version": "5.10.2", "version": "5.11.0",
"resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.10.2.tgz", "resolved": "https://registry.npmjs.org/@algolia/requester-browser-xhr/-/requester-browser-xhr-5.11.0.tgz",
"integrity": "sha512-gzlfE/H05ggDiEWNi8WaDSRhpE5X8rD1JqYKPPeM31JRI3TutQIKAk3MSUsa1bHM/Di56r2Gm6L1g3ZlZv2ETA==", "integrity": "sha512-koy3lcWUrtUUfmMaDV/7zvZA7WGCFuBM+9t6KUfz93NTOmP6nQ6zcvAD66G0E1uapzj0S5Z6CA6Nd0Q5nVetcg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@algolia/client-common": "5.10.2" "@algolia/client-common": "5.11.0"
}, },
"engines": { "engines": {
"node": ">= 14.0.0" "node": ">= 14.0.0"
@ -309,28 +309,28 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@algolia/requester-fetch": { "node_modules/@algolia/requester-fetch": {
"version": "5.10.2", "version": "5.11.0",
"resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.10.2.tgz", "resolved": "https://registry.npmjs.org/@algolia/requester-fetch/-/requester-fetch-5.11.0.tgz",
"integrity": "sha512-Q27ciW9WRdq3pUITVlxpHIwe9QWOe+oPvgs8Z+gsv8vMkwXnLfANvSgeZCyQgx3SqzUPzhel0ozVq7Qoh8xIkg==", "integrity": "sha512-kuQGSBfDwSW0uXT0GqbwEsvQNDwmgsw2gZp1TG+IR61TExHmnL1nqgsoAIrxV86O2uXlwtrkrBDW0qDbGW4BHg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@algolia/client-common": "5.10.2" "@algolia/client-common": "5.11.0"
}, },
"engines": { "engines": {
"node": ">= 14.0.0" "node": ">= 14.0.0"
} }
}, },
"node_modules/@algolia/requester-node-http": { "node_modules/@algolia/requester-node-http": {
"version": "5.10.2", "version": "5.11.0",
"resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.10.2.tgz", "resolved": "https://registry.npmjs.org/@algolia/requester-node-http/-/requester-node-http-5.11.0.tgz",
"integrity": "sha512-WMUQ4iFhNnQXC4F1Yj51x8tgIvq5h8jtTLMBs7LbMiW6JhnLHfBVl7IVk6X1fZJO5YcvXW051HN8aFlfAb5QEw==", "integrity": "sha512-7XiZuTbLmPQM5zIIEqqABU1rvpN61+qSaMPfPAiB1hhARno8Ak6/GddR1OaRTPmV/GA72AQknxYocCqUxemwzg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"@algolia/client-common": "5.10.2" "@algolia/client-common": "5.11.0"
}, },
"engines": { "engines": {
"node": ">= 14.0.0" "node": ">= 14.0.0"
@ -848,9 +848,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/@rollup/rollup-android-arm-eabi": { "node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.3.tgz",
"integrity": "sha512-ufoveNTKDg9t/b7nqI3lwbCG/9IJMhADBNjjz/Jn6LxIZxD7T5L8l2uO/wD99945F1Oo8FvgbbZJRguyk/BdzA==", "integrity": "sha512-ufb2CH2KfBWPJok95frEZZ82LtDl0A6QKTa8MoM+cWwDZvVGl5/jNb79pIhRvAalUu+7LD91VYR0nwRD799HkQ==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -862,9 +862,9 @@
] ]
}, },
"node_modules/@rollup/rollup-android-arm64": { "node_modules/@rollup/rollup-android-arm64": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.3.tgz",
"integrity": "sha512-iZoYCiJz3Uek4NI0J06/ZxUgwAfNzqltK0MptPDO4OR0a88R4h0DSELMsflS6ibMCJ4PnLvq8f7O1d7WexUvIA==", "integrity": "sha512-iAHpft/eQk9vkWIV5t22V77d90CRofgR2006UiCjHcHJFVI1E0oBkQIAbz+pLtthFw3hWEmVB4ilxGyBf48i2Q==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -876,9 +876,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-arm64": { "node_modules/@rollup/rollup-darwin-arm64": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.3.tgz",
"integrity": "sha512-/UhrIxobHYCBfhi5paTkUDQ0w+jckjRZDZ1kcBL132WeHZQ6+S5v9jQPVGLVrLbNUebdIRpIt00lQ+4Z7ys4Rg==", "integrity": "sha512-QPW2YmkWLlvqmOa2OwrfqLJqkHm7kJCIMq9kOz40Zo9Ipi40kf9ONG5Sz76zszrmIZZ4hgRIkez69YnTHgEz1w==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -890,9 +890,9 @@
] ]
}, },
"node_modules/@rollup/rollup-darwin-x64": { "node_modules/@rollup/rollup-darwin-x64": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.3.tgz",
"integrity": "sha512-1F/jrfhxJtWILusgx63WeTvGTwE4vmsT9+e/z7cZLKU8sBMddwqw3UV5ERfOV+H1FuRK3YREZ46J4Gy0aP3qDA==", "integrity": "sha512-KO0pN5x3+uZm1ZXeIfDqwcvnQ9UEGN8JX5ufhmgH5Lz4ujjZMAnxQygZAVGemFWn+ZZC0FQopruV4lqmGMshow==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -904,9 +904,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-arm64": { "node_modules/@rollup/rollup-freebsd-arm64": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.24.3.tgz",
"integrity": "sha512-1YWOpFcGuC6iGAS4EI+o3BV2/6S0H+m9kFOIlyFtp4xIX5rjSnL3AwbTBxROX0c8yWtiWM7ZI6mEPTI7VkSpZw==", "integrity": "sha512-CsC+ZdIiZCZbBI+aRlWpYJMSWvVssPuWqrDy/zi9YfnatKKSLFCe6fjna1grHuo/nVaHG+kiglpRhyBQYRTK4A==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -918,9 +918,9 @@
] ]
}, },
"node_modules/@rollup/rollup-freebsd-x64": { "node_modules/@rollup/rollup-freebsd-x64": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.24.3.tgz",
"integrity": "sha512-3qAqTewYrCdnOD9Gl9yvPoAoFAVmPJsBvleabvx4bnu1Kt6DrB2OALeRVag7BdWGWLhP1yooeMLEi6r2nYSOjg==", "integrity": "sha512-F0nqiLThcfKvRQhZEzMIXOQG4EeX61im61VYL1jo4eBxv4aZRmpin6crnBJQ/nWnCsjH5F6J3W6Stdm0mBNqBg==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -932,9 +932,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-gnueabihf": { "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.3.tgz",
"integrity": "sha512-ArdGtPHjLqWkqQuoVQ6a5UC5ebdX8INPuJuJNWRe0RGa/YNhVvxeWmCTFQ7LdmNCSUzVZzxAvUznKaYx645Rig==", "integrity": "sha512-KRSFHyE/RdxQ1CSeOIBVIAxStFC/hnBgVcaiCkQaVC+EYDtTe4X7z5tBkFyRoBgUGtB6Xg6t9t2kulnX6wJc6A==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -946,9 +946,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm-musleabihf": { "node_modules/@rollup/rollup-linux-arm-musleabihf": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.3.tgz",
"integrity": "sha512-B6UHHeNnnih8xH6wRKB0mOcJGvjZTww1FV59HqJoTJ5da9LCG6R4SEBt6uPqzlawv1LoEXSS0d4fBlHNWl6iYw==", "integrity": "sha512-h6Q8MT+e05zP5BxEKz0vi0DhthLdrNEnspdLzkoFqGwnmOzakEHSlXfVyA4HJ322QtFy7biUAVFPvIDEDQa6rw==",
"cpu": [ "cpu": [
"arm" "arm"
], ],
@ -960,9 +960,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-gnu": { "node_modules/@rollup/rollup-linux-arm64-gnu": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.3.tgz",
"integrity": "sha512-kr3gqzczJjSAncwOS6i7fpb4dlqcvLidqrX5hpGBIM1wtt0QEVtf4wFaAwVv8QygFU8iWUMYEoJZWuWxyua4GQ==", "integrity": "sha512-fKElSyXhXIJ9pqiYRqisfirIo2Z5pTTve5K438URf08fsypXrEkVmShkSfM8GJ1aUyvjakT+fn2W7Czlpd/0FQ==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -974,9 +974,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-arm64-musl": { "node_modules/@rollup/rollup-linux-arm64-musl": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.3.tgz",
"integrity": "sha512-TDdHLKCWgPuq9vQcmyLrhg/bgbOvIQ8rtWQK7MRxJ9nvaxKx38NvY7/Lo6cYuEnNHqf6rMqnivOIPIQt6H2AoA==", "integrity": "sha512-YlddZSUk8G0px9/+V9PVilVDC6ydMz7WquxozToozSnfFK6wa6ne1ATUjUvjin09jp34p84milxlY5ikueoenw==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -988,9 +988,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-powerpc64le-gnu": { "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.3.tgz",
"integrity": "sha512-xv9vS648T3X4AxFFZGWeB5Dou8ilsv4VVqJ0+loOIgDO20zIhYfDLkk5xoQiej2RiSQkld9ijF/fhLeonrz2mw==", "integrity": "sha512-yNaWw+GAO8JjVx3s3cMeG5Esz1cKVzz8PkTJSfYzE5u7A+NvGmbVFEHP+BikTIyYWuz0+DX9kaA3pH9Sqxp69g==",
"cpu": [ "cpu": [
"ppc64" "ppc64"
], ],
@ -1002,9 +1002,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-riscv64-gnu": { "node_modules/@rollup/rollup-linux-riscv64-gnu": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.3.tgz",
"integrity": "sha512-tbtXwnofRoTt223WUZYiUnbxhGAOVul/3StZ947U4A5NNjnQJV5irKMm76G0LGItWs6y+SCjUn/Q0WaMLkEskg==", "integrity": "sha512-lWKNQfsbpv14ZCtM/HkjCTm4oWTKTfxPmr7iPfp3AHSqyoTz5AgLemYkWLwOBWc+XxBbrU9SCokZP0WlBZM9lA==",
"cpu": [ "cpu": [
"riscv64" "riscv64"
], ],
@ -1016,9 +1016,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-s390x-gnu": { "node_modules/@rollup/rollup-linux-s390x-gnu": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.3.tgz",
"integrity": "sha512-gc97UebApwdsSNT3q79glOSPdfwgwj5ELuiyuiMY3pEWMxeVqLGKfpDFoum4ujivzxn6veUPzkGuSYoh5deQ2Q==", "integrity": "sha512-HoojGXTC2CgCcq0Woc/dn12wQUlkNyfH0I1ABK4Ni9YXyFQa86Fkt2Q0nqgLfbhkyfQ6003i3qQk9pLh/SpAYw==",
"cpu": [ "cpu": [
"s390x" "s390x"
], ],
@ -1030,9 +1030,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-gnu": { "node_modules/@rollup/rollup-linux-x64-gnu": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.3.tgz",
"integrity": "sha512-jOG/0nXb3z+EM6SioY8RofqqmZ+9NKYvJ6QQaa9Mvd3RQxlH68/jcB/lpyVt4lCiqr04IyaC34NzhUqcXbB5FQ==", "integrity": "sha512-mnEOh4iE4USSccBOtcrjF5nj+5/zm6NcNhbSEfR3Ot0pxBwvEn5QVUXcuOwwPkapDtGZ6pT02xLoPaNv06w7KQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -1044,9 +1044,9 @@
] ]
}, },
"node_modules/@rollup/rollup-linux-x64-musl": { "node_modules/@rollup/rollup-linux-x64-musl": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.3.tgz",
"integrity": "sha512-XAo7cJec80NWx9LlZFEJQxqKOMz/lX3geWs2iNT5CHIERLFfd90f3RYLLjiCBm1IMaQ4VOX/lTC9lWfzzQm14Q==", "integrity": "sha512-rMTzawBPimBQkG9NKpNHvquIUTQPzrnPxPbCY1Xt+mFkW7pshvyIS5kYgcf74goxXOQk0CP3EoOC1zcEezKXhw==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -1058,9 +1058,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-arm64-msvc": { "node_modules/@rollup/rollup-win32-arm64-msvc": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.3.tgz",
"integrity": "sha512-A+JAs4+EhsTjnPQvo9XY/DC0ztaws3vfqzrMNMKlwQXuniBKOIIvAAI8M0fBYiTCxQnElYu7mLk7JrhlQ+HeOw==", "integrity": "sha512-2lg1CE305xNvnH3SyiKwPVsTVLCg4TmNCF1z7PSHX2uZY2VbUpdkgAllVoISD7JO7zu+YynpWNSKAtOrX3AiuA==",
"cpu": [ "cpu": [
"arm64" "arm64"
], ],
@ -1072,9 +1072,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-ia32-msvc": { "node_modules/@rollup/rollup-win32-ia32-msvc": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.3.tgz",
"integrity": "sha512-ZhcrakbqA1SCiJRMKSU64AZcYzlZ/9M5LaYil9QWxx9vLnkQ9Vnkve17Qn4SjlipqIIBFKjBES6Zxhnvh0EAEw==", "integrity": "sha512-9SjYp1sPyxJsPWuhOCX6F4jUMXGbVVd5obVpoVEi8ClZqo52ViZewA6eFz85y8ezuOA+uJMP5A5zo6Oz4S5rVQ==",
"cpu": [ "cpu": [
"ia32" "ia32"
], ],
@ -1086,9 +1086,9 @@
] ]
}, },
"node_modules/@rollup/rollup-win32-x64-msvc": { "node_modules/@rollup/rollup-win32-x64-msvc": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.2.tgz", "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.3.tgz",
"integrity": "sha512-2mLH46K1u3r6uwc95hU+OR9q/ggYMpnS7pSp83Ece1HUQgF9Nh/QwTK5rcgbFnV9j+08yBrU5sA/P0RK2MSBNA==", "integrity": "sha512-HGZgRFFYrMrP3TJlq58nR1xy8zHKId25vhmm5S9jETEfDf6xybPxsavFTJaufe2zgOGYJBskGlj49CwtEuFhWQ==",
"cpu": [ "cpu": [
"x64" "x64"
], ],
@ -1307,23 +1307,23 @@
} }
}, },
"node_modules/@vue/devtools-api": { "node_modules/@vue/devtools-api": {
"version": "7.5.4", "version": "7.5.6",
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.5.4.tgz", "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-7.5.6.tgz",
"integrity": "sha512-j9UC/KeYUNZ6AyCJxBROBCbogB5YHW6PZv9VnCNp2ntE4rq426Lfc8WP5B9V+rXBwqWmrgZTGYBa31CBSxdAUg==", "integrity": "sha512-/7ov2ioU80fYcYENEJXp88l88gX1PJCGJdMtQmUV3VQmGgQvKrpeUoPWgkpXPkUxmAquh6PZnVtXeDpTX5mmLg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/devtools-kit": "^7.5.4" "@vue/devtools-kit": "^7.5.6"
} }
}, },
"node_modules/@vue/devtools-kit": { "node_modules/@vue/devtools-kit": {
"version": "7.5.4", "version": "7.5.6",
"resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.5.4.tgz", "resolved": "https://registry.npmjs.org/@vue/devtools-kit/-/devtools-kit-7.5.6.tgz",
"integrity": "sha512-0i7WFgc1B2TL52tstn82zlb9opSA0aIiHfkUYFXtZb8CIpmlFMTkHtgwVl6PMWNBj3LNhYou1YJCLpCYvJYYoA==", "integrity": "sha512-44qr4/l9BsNP5hKETucueP8SKkyDZBHEurV4pQnRWs906OG9f2aYWhk4vL+27tsB4ZoWJM2h3RLhygzeeKZzWg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@vue/devtools-shared": "^7.5.4", "@vue/devtools-shared": "^7.5.6",
"birpc": "^0.2.19", "birpc": "^0.2.19",
"hookable": "^5.5.3", "hookable": "^5.5.3",
"mitt": "^3.0.1", "mitt": "^3.0.1",
@ -1333,9 +1333,9 @@
} }
}, },
"node_modules/@vue/devtools-shared": { "node_modules/@vue/devtools-shared": {
"version": "7.5.4", "version": "7.5.6",
"resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.5.4.tgz", "resolved": "https://registry.npmjs.org/@vue/devtools-shared/-/devtools-shared-7.5.6.tgz",
"integrity": "sha512-dwuq4YmwTyLc7eBOqX63s3JB8il7qnKsNgENglSMkUPwiItHkVAYYfPESN1rxSdYkl1RCux1l5TBidYqfUDNAA==", "integrity": "sha512-5iq/BF6f05JTcC7J/1DTUm4CpyVVB4KiyLAo/fDcoyWR7EulharWQVbr6W7ek5lO23f5mbnJ+adA5tfFTJt6Sw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -2164,9 +2164,9 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/rollup": { "node_modules/rollup": {
"version": "4.24.2", "version": "4.24.3",
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.2.tgz", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.24.3.tgz",
"integrity": "sha512-do/DFGq5g6rdDhdpPq5qb2ecoczeK6y+2UAjdJ5trjQJj5f1AiVdLRWRc9A9/fFukfvJRgM0UXzxBIYMovm5ww==", "integrity": "sha512-HBW896xR5HGmoksbi3JBDtmVzWiPAYqp7wip50hjQ67JbDz61nyoMPdqu1DvVW9asYb2M65Z20ZHsyJCMqMyDg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
@ -2180,24 +2180,24 @@
"npm": ">=8.0.0" "npm": ">=8.0.0"
}, },
"optionalDependencies": { "optionalDependencies": {
"@rollup/rollup-android-arm-eabi": "4.24.2", "@rollup/rollup-android-arm-eabi": "4.24.3",
"@rollup/rollup-android-arm64": "4.24.2", "@rollup/rollup-android-arm64": "4.24.3",
"@rollup/rollup-darwin-arm64": "4.24.2", "@rollup/rollup-darwin-arm64": "4.24.3",
"@rollup/rollup-darwin-x64": "4.24.2", "@rollup/rollup-darwin-x64": "4.24.3",
"@rollup/rollup-freebsd-arm64": "4.24.2", "@rollup/rollup-freebsd-arm64": "4.24.3",
"@rollup/rollup-freebsd-x64": "4.24.2", "@rollup/rollup-freebsd-x64": "4.24.3",
"@rollup/rollup-linux-arm-gnueabihf": "4.24.2", "@rollup/rollup-linux-arm-gnueabihf": "4.24.3",
"@rollup/rollup-linux-arm-musleabihf": "4.24.2", "@rollup/rollup-linux-arm-musleabihf": "4.24.3",
"@rollup/rollup-linux-arm64-gnu": "4.24.2", "@rollup/rollup-linux-arm64-gnu": "4.24.3",
"@rollup/rollup-linux-arm64-musl": "4.24.2", "@rollup/rollup-linux-arm64-musl": "4.24.3",
"@rollup/rollup-linux-powerpc64le-gnu": "4.24.2", "@rollup/rollup-linux-powerpc64le-gnu": "4.24.3",
"@rollup/rollup-linux-riscv64-gnu": "4.24.2", "@rollup/rollup-linux-riscv64-gnu": "4.24.3",
"@rollup/rollup-linux-s390x-gnu": "4.24.2", "@rollup/rollup-linux-s390x-gnu": "4.24.3",
"@rollup/rollup-linux-x64-gnu": "4.24.2", "@rollup/rollup-linux-x64-gnu": "4.24.3",
"@rollup/rollup-linux-x64-musl": "4.24.2", "@rollup/rollup-linux-x64-musl": "4.24.3",
"@rollup/rollup-win32-arm64-msvc": "4.24.2", "@rollup/rollup-win32-arm64-msvc": "4.24.3",
"@rollup/rollup-win32-ia32-msvc": "4.24.2", "@rollup/rollup-win32-ia32-msvc": "4.24.3",
"@rollup/rollup-win32-x64-msvc": "4.24.2", "@rollup/rollup-win32-x64-msvc": "4.24.3",
"fsevents": "~2.3.2" "fsevents": "~2.3.2"
} }
}, },
@ -2465,28 +2465,28 @@
} }
}, },
"node_modules/vitepress": { "node_modules/vitepress": {
"version": "1.4.1", "version": "1.4.2",
"resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.4.1.tgz", "resolved": "https://registry.npmjs.org/vitepress/-/vitepress-1.4.2.tgz",
"integrity": "sha512-C2rQ7PMlDVqgsaHOa0uJtgGGWaGv74QMaGL62lxKbtFkYtosJB5HAfZ8+pEbfzzvLemYaYwaiQdFLBlexK2sFw==", "integrity": "sha512-10v92Lqx0N4r7YC3cQLBvu+gRS2rHviE7vgdKiwlupUGfSWkyiQDqYccxM5iPStDGSi1Brnec1lf+lmhaQcZXw==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@docsearch/css": "^3.6.2", "@docsearch/css": "^3.6.2",
"@docsearch/js": "^3.6.2", "@docsearch/js": "^3.6.2",
"@shikijs/core": "^1.22.0", "@shikijs/core": "^1.22.2",
"@shikijs/transformers": "^1.22.0", "@shikijs/transformers": "^1.22.2",
"@shikijs/types": "^1.22.0", "@shikijs/types": "^1.22.2",
"@types/markdown-it": "^14.1.2", "@types/markdown-it": "^14.1.2",
"@vitejs/plugin-vue": "^5.1.4", "@vitejs/plugin-vue": "^5.1.4",
"@vue/devtools-api": "^7.4.6", "@vue/devtools-api": "^7.5.4",
"@vue/shared": "^3.5.12", "@vue/shared": "^3.5.12",
"@vueuse/core": "^11.1.0", "@vueuse/core": "^11.1.0",
"@vueuse/integrations": "^11.1.0", "@vueuse/integrations": "^11.1.0",
"focus-trap": "^7.6.0", "focus-trap": "^7.6.0",
"mark.js": "8.11.1", "mark.js": "8.11.1",
"minisearch": "^7.1.0", "minisearch": "^7.1.0",
"shiki": "^1.22.0", "shiki": "^1.22.2",
"vite": "^5.4.8", "vite": "^5.4.10",
"vue": "^3.5.12" "vue": "^3.5.12"
}, },
"bin": { "bin": {

View File

@ -5,7 +5,7 @@
"docs:preview": "vitepress preview docs" "docs:preview": "vitepress preview docs"
}, },
"devDependencies": { "devDependencies": {
"vitepress": "^1.4.1", "vitepress": "^1.4.2",
"vue": "^3.5.12" "vue": "^3.5.12"
} }
} }

View File

@ -156,7 +156,32 @@ impl Client {
client_packets_queue.push_back(packet); client_packets_queue.push_back(packet);
} }
/// Sets the Packet encryption /// Enables or disables packet encryption for the connection.
///
/// This function takes an optional shared secret as input. If the shared secret is provided,
/// the connection's encryption is enabled using the provided secret key. Otherwise, encryption is disabled.
///
/// # Arguments
///
/// * `shared_secret`: An optional **already decrypted** shared secret key used for encryption.
///
/// # Returns
///
/// A `Result` indicating whether the encryption was set successfully.
///
/// # Errors
///
/// Returns an `EncryptionError` if the shared secret has an incorrect length.
///
/// # Examples
/// ```
/// let shared_secret = server.decrypt(&encryption_response.shared_secret).unwrap();
///
/// if let Err(error) = self.set_encryption(Some(&shared_secret)).await {
/// self.kick(&error.to_string()).await;
/// return;
/// }
/// ```
pub async fn set_encryption( pub async fn set_encryption(
&self, &self,
shared_secret: Option<&[u8]>, // decrypted shared_secret: Option<&[u8]>, // decrypted
@ -176,13 +201,24 @@ impl Client {
Ok(()) Ok(())
} }
/// Sets the Packet compression /// Enables or disables packet compression for the connection.
///
/// This function takes an optional `CompressionInfo` struct as input. If the `CompressionInfo` is provided,
/// packet compression is enabled with the specified threshold. Otherwise, compression is disabled.
///
/// # Arguments
///
/// * `compression`: An optional `CompressionInfo` struct containing the compression threshold and compression level.
pub async fn set_compression(&self, compression: Option<CompressionInfo>) { pub async fn set_compression(&self, compression: Option<CompressionInfo>) {
self.dec.lock().await.set_compression(compression.is_some()); self.dec.lock().await.set_compression(compression.is_some());
self.enc.lock().await.set_compression(compression); self.enc.lock().await.set_compression(compression);
} }
/// Send a Clientbound Packet to the Client /// Sends a clientbound packet to the connected client.
///
/// # Arguments
///
/// * `packet`: A reference to a packet object implementing the `ClientPacket` trait.
pub async fn send_packet<P: ClientPacket>(&self, packet: &P) { pub async fn send_packet<P: ClientPacket>(&self, packet: &P) {
//log::debug!("Sending packet with id {} to {}", P::PACKET_ID, self.id); //log::debug!("Sending packet with id {} to {}", P::PACKET_ID, self.id);
// assert!(!self.closed); // assert!(!self.closed);
@ -216,6 +252,19 @@ impl Client {
*/ */
} }
/// Sends a clientbound packet to the connected client.
///
/// # Arguments
///
/// * `packet`: A reference to a packet object implementing the `ClientPacket` trait.
///
/// # Returns
///
/// A `Result` indicating whether the Packet was Send successfully.
///
/// # Errors
///
/// Returns an `PacketError` if the could not be Send.
pub async fn try_send_packet<P: ClientPacket>(&self, packet: &P) -> Result<(), PacketError> { pub async fn try_send_packet<P: ClientPacket>(&self, packet: &P) -> Result<(), PacketError> {
// assert!(!self.closed); // assert!(!self.closed);
/* /*
@ -244,7 +293,19 @@ impl Client {
Ok(()) Ok(())
} }
/// Processes all packets send by the client /// Processes all packets received from the connected client in a loop.
///
/// This function continuously dequeues packets from the client's packet queue and processes them.
/// Processing involves calling the `handle_packet` function with the server instance and the packet itself.
///
/// The loop exits when:
///
/// - The connection is closed (checked before processing each packet).
/// - An error occurs while processing a packet (client is kicked with an error message).
///
/// # Arguments
///
/// * `server`: A reference to the `Arc<Server>` instance.
pub async fn process_packets(&self, server: &Arc<Server>) { pub async fn process_packets(&self, server: &Arc<Server>) {
let mut packet_queue = self.client_packets_queue.lock().await; let mut packet_queue = self.client_packets_queue.lock().await;
while let Some(mut packet) = packet_queue.pop_front() { while let Some(mut packet) = packet_queue.pop_front() {
@ -264,7 +325,30 @@ impl Client {
} }
} }
/// Handles an incoming decoded not Play state Packet /// Handles an incoming packet, routing it to the appropriate handler based on the current connection state.
///
/// This function takes a `RawPacket` and routes it to the corresponding handler based on the current connection state.
/// It supports the following connection states:
///
/// - **Handshake:** Handles handshake packets.
/// - **Status:** Handles status request and ping packets.
/// - **Login/Transfer:** Handles login and transfer packets.
/// - **Config:** Handles configuration packets.
///
/// For the `Play` state, an error is logged as it indicates an invalid state for packet processing.
///
/// # Arguments
///
/// * `server`: A reference to the `Arc<Server>` instance.
/// * `packet`: A mutable reference to the `RawPacket` to be processed.
///
/// # Returns
///
/// A `Result` indicating whether the packet was read and handled successfully.
///
/// # Errors
///
/// Returns a `DeserializerError` if an error occurs during packet deserialization.
pub async fn handle_packet( pub async fn handle_packet(
&self, &self,
server: &Arc<Server>, server: &Arc<Server>,
@ -463,7 +547,13 @@ impl Client {
} }
} }
/// Kicks the Client with a reason depending on the connection state /// Disconnects a client from the server with a specified reason.
///
/// This function kicks a client identified by its ID from the server. The appropriate disconnect packet is sent based on the client's current connection state.
///
/// # Arguments
///
/// * `reason`: A string describing the reason for kicking the client.
pub async fn kick(&self, reason: &str) { pub async fn kick(&self, reason: &str) {
log::info!("Kicking Client id {} for {}", self.id, reason); log::info!("Kicking Client id {} for {}", self.id, reason);
let result = match self.connection_state.load() { let result = match self.connection_state.load() {
@ -491,7 +581,15 @@ impl Client {
self.close(); self.close();
} }
/// You should prefer to use `kick` when you can /// Closes the connection to the client.
///
/// This function marks the connection as closed using an atomic flag. It's generally preferable
/// to use the `kick` function if you want to send a specific message to the client explaining the reason for the closure.
/// However, use `close` in scenarios where sending a message is not critical or might not be possible (e.g., sudden connection drop).
///
/// # Notes
///
/// This function does not attempt to send any disconnect packets to the client.
pub fn close(&self) { pub fn close(&self) {
self.closed self.closed
.store(true, std::sync::atomic::Ordering::Relaxed); .store(true, std::sync::atomic::Ordering::Relaxed);

View File

@ -5,12 +5,17 @@ use pumpkin_protocol::client::play::{CEntityStatus, CSetEntityMetadata, Metadata
use super::Entity; use super::Entity;
/// Represents a Living Entity (e.g. Player, Zombie, Enderman...) /// Represents a living entity within the game world.
///
/// This struct encapsulates the core properties and behaviors of living entities, including players, mobs, and other creatures.
pub struct LivingEntity { pub struct LivingEntity {
/// The underlying entity object, providing basic entity information and functionality.
pub entity: Entity, pub entity: Entity,
/// Tracks the remaining time until the entity can regenerate health.
pub time_until_regen: AtomicI32, pub time_until_regen: AtomicI32,
/// Stores the amount of damage the entity last received.
pub last_damage_taken: AtomicCell<f32>, pub last_damage_taken: AtomicCell<f32>,
/// The entity's current health level. /// The current health level of the entity.
pub health: AtomicCell<f32>, pub health: AtomicCell<f32>,
} }

View File

@ -26,27 +26,22 @@ pub struct Entity {
/// The world in which the entity exists. /// The world in which the entity exists.
pub world: Arc<World>, pub world: Arc<World>,
/// The entity's current health level. /// The entity's current health level.
/// The entity's current position in the world /// The entity's current position in the world
pub pos: AtomicCell<Vector3<f64>>, pub pos: AtomicCell<Vector3<f64>>,
/// The entity's position rounded to the nearest block coordinates /// The entity's position rounded to the nearest block coordinates
pub block_pos: AtomicCell<WorldPosition>, pub block_pos: AtomicCell<WorldPosition>,
/// The chunk coordinates of the entity's current position /// The chunk coordinates of the entity's current position
pub chunk_pos: AtomicCell<Vector2<i32>>, pub chunk_pos: AtomicCell<Vector2<i32>>,
/// Indicates whether the entity is sneaking /// Indicates whether the entity is sneaking
pub sneaking: AtomicBool, pub sneaking: AtomicBool,
/// Indicates whether the entity is sprinting /// Indicates whether the entity is sprinting
pub sprinting: AtomicBool, pub sprinting: AtomicBool,
/// Indicates whether the entity is flying due to a fall /// Indicates whether the entity is flying due to a fall
pub fall_flying: AtomicBool, pub fall_flying: AtomicBool,
/// The entity's current velocity vector, aka Knockback /// The entity's current velocity vector, aka Knockback
pub velocity: AtomicCell<Vector3<f64>>, pub velocity: AtomicCell<Vector3<f64>>,
/// Indicates whether the entity is on the ground (may not always be accurate). /// Indicates whether the entity is on the ground (may not always be accurate).
pub on_ground: AtomicBool, pub on_ground: AtomicBool,
/// The entity's yaw rotation (horizontal rotation) ← → /// The entity's yaw rotation (horizontal rotation) ← →
pub yaw: AtomicCell<f32>, pub yaw: AtomicCell<f32>,
/// The entity's head yaw rotation (horizontal rotation of the head) /// The entity's head yaw rotation (horizontal rotation of the head)

View File

@ -34,22 +34,26 @@ pub mod ticker;
pub const CURRENT_MC_VERSION: &str = "1.21.3"; pub const CURRENT_MC_VERSION: &str = "1.21.3";
/// Represents a Minecraft server instance.
pub struct Server { pub struct Server {
/// Handles cryptographic keys for secure communication.
key_store: KeyStore, key_store: KeyStore,
/// Manages server status information.
server_listing: Mutex<CachedStatus>, server_listing: Mutex<CachedStatus>,
/// Saves server branding information.
server_branding: CachedBranding, server_branding: CachedBranding,
/// Saves and Dispatches commands to appropriate handlers.
pub command_dispatcher: Arc<CommandDispatcher<'static>>, pub command_dispatcher: Arc<CommandDispatcher<'static>>,
/// Manages multiple worlds within the server.
pub worlds: Vec<Arc<World>>, pub worlds: Vec<Arc<World>>,
/// Caches game registries for efficient access.
/// Cache the registry so we don't have to parse it every time a player joins
pub cached_registry: Vec<Registry>, pub cached_registry: Vec<Registry>,
pub open_containers: RwLock<HashMap<u64, OpenContainer>>, pub open_containers: RwLock<HashMap<u64, OpenContainer>>,
/// Tracks open containers used for item interactions.
pub drag_handler: DragHandler, pub drag_handler: DragHandler,
/// Assigns unique IDs to entities.
entity_id: AtomicI32, entity_id: AtomicI32,
/// Manages authentication with a authentication server, if enabled.
/// Used for Authentication, None is Online mode is disabled
pub auth_client: Option<reqwest::Client>, pub auth_client: Option<reqwest::Client>,
} }
@ -92,6 +96,31 @@ impl Server {
} }
} }
/// Adds a new player to the server.
/// This function takes an `Arc<Client>` representing the connected client and performs the following actions:
///
/// 1. Generates a new entity ID for the player.
/// 2. Determines the player's gamemode (defaulting to Survival if not specified in configuration).
/// 3. **(TODO: Select default from config)** Selects the world for the player (currently uses the first world).
/// 4. Creates a new `Player` instance using the provided information.
/// 5. Adds the player to the chosen world.
/// 6. **(TODO: Config if we want increase online)** Optionally updates server listing information based on player's configuration.
///
/// # Arguments
///
/// * `client`: An `Arc<Client>` representing the connected client.
/// # Returns
///
/// A tuple containing:
///
/// - `Arc<Player>`: A reference to the newly created player object.
/// - `Arc<World>`: A reference to the world the player was added to.
///
/// # Note
///
/// You still have to spawn the Player in the World to make then to let them Join and make them Visible
pub async fn add_player(&self, client: Arc<Client>) -> (Arc<Player>, Arc<World>) { pub async fn add_player(&self, client: Arc<Client>) -> (Arc<Player>, Arc<World>) {
let entity_id = self.new_entity_id(); let entity_id = self.new_entity_id();
let gamemode = match BASIC_CONFIG.default_gamemode { let gamemode = match BASIC_CONFIG.default_gamemode {
@ -134,7 +163,13 @@ impl Server {
.cloned() .cloned()
} }
/// Sends a Packet to all Players in all worlds /// Broadcasts a packet to all players in all worlds.
///
/// This function sends the specified packet to every connected player in every world managed by the server.
///
/// # Arguments
///
/// * `packet`: A reference to the packet to be broadcast. The packet must implement the `ClientPacket` trait.
pub async fn broadcast_packet_all<P>(&self, packet: &P) pub async fn broadcast_packet_all<P>(&self, packet: &P)
where where
P: ClientPacket, P: ClientPacket,
@ -144,7 +179,18 @@ impl Server {
} }
} }
/// Searches every world for a player by username /// Searches for a player by their username across all worlds.
///
/// This function iterates through each world managed by the server and attempts to find a player with the specified username.
/// If a player is found in any world, it returns an `Arc<Player>` reference to that player. Otherwise, it returns `None`.
///
/// # Arguments
///
/// * `name`: The username of the player to search for.
///
/// # Returns
///
/// An `Option<Arc<Player>>` containing the player if found, or `None` if not found.
pub async fn get_player_by_name(&self, name: &str) -> Option<Arc<Player>> { pub async fn get_player_by_name(&self, name: &str) -> Option<Arc<Player>> {
for world in &self.worlds { for world in &self.worlds {
if let Some(player) = world.get_player_by_name(name).await { if let Some(player) = world.get_player_by_name(name).await {
@ -154,7 +200,18 @@ impl Server {
None None
} }
/// Searches every world for a player by UUID /// Searches for a player by their UUID across all worlds.
///
/// This function iterates through each world managed by the server and attempts to find a player with the specified UUID.
/// If a player is found in any world, it returns an `Arc<Player>` reference to that player. Otherwise, it returns `None`.
///
/// # Arguments
///
/// * `id`: The UUID of the player to search for.
///
/// # Returns
///
/// An `Option<Arc<Player>>` containing the player if found, or `None` if not found.
pub async fn get_player_by_uuid(&self, id: uuid::Uuid) -> Option<Arc<Player>> { pub async fn get_player_by_uuid(&self, id: uuid::Uuid) -> Option<Arc<Player>> {
for world in &self.worlds { for world in &self.worlds {
if let Some(player) = world.get_player_by_uuid(id).await { if let Some(player) = world.get_player_by_uuid(id).await {
@ -164,7 +221,13 @@ impl Server {
None None
} }
/// Get the player count sum in all worlds /// Counts the total number of players across all worlds.
///
/// This function iterates through each world and sums up the number of players currently connected to that world.
///
/// # Returns
///
/// The total number of players connected to the server.
pub async fn get_player_count(&self) -> usize { pub async fn get_player_count(&self) -> usize {
let mut count = 0; let mut count = 0;
for world in &self.worlds { for world in &self.worlds {

View File

@ -59,9 +59,11 @@ type ChunkReceiver = (
pub struct World { pub struct World {
/// The underlying level, responsible for chunk management and terrain generation. /// The underlying level, responsible for chunk management and terrain generation.
pub level: Arc<Level>, pub level: Arc<Level>,
/// A map of active players within the world, keyed by their unique token. /// A map of active players within the world, keyed by their unique UUID.
pub current_players: Arc<Mutex<HashMap<uuid::Uuid, Arc<Player>>>>, pub current_players: Arc<Mutex<HashMap<uuid::Uuid, Arc<Player>>>>,
/// The world's scoreboard, used for tracking scores, objectives, and display information.
pub scoreboard: Mutex<Scoreboard>, pub scoreboard: Mutex<Scoreboard>,
/// The world's worldborder, defining the playable area and controlling its expansion or contraction.
pub worldborder: Mutex<Worldborder>, pub worldborder: Mutex<Worldborder>,
// TODO: entities // TODO: entities
} }
@ -486,32 +488,67 @@ impl World {
None None
} }
/// Gets a Player by UUID /// Retrieves a player by their unique UUID.
///
/// This function searches the world's active player list for a player with the specified UUID.
/// If found, it returns an `Arc<Player>` reference to the player. Otherwise, it returns `None`.
///
/// # Arguments
///
/// * `id`: The UUID of the player to retrieve.
///
/// # Returns
///
/// An `Option<Arc<Player>>` containing the player if found, or `None` if not.
pub async fn get_player_by_uuid(&self, id: uuid::Uuid) -> Option<Arc<Player>> { pub async fn get_player_by_uuid(&self, id: uuid::Uuid) -> Option<Arc<Player>> {
return self.current_players.lock().await.get(&id).cloned(); return self.current_players.lock().await.get(&id).cloned();
} }
/// Adds a player to the world and broadcasts a join message if enabled.
///
/// This function takes a player's UUID and an `Arc<Player>` reference.
/// It inserts the player into the world's `current_players` map using the UUID as the key.
/// Additionally, it may broadcasts a join message to all connected players in the world.
///
/// # Arguments
///
/// * `uuid`: The unique UUID of the player to add.
/// * `player`: An `Arc<Player>` reference to the player object.
pub async fn add_player(&self, uuid: uuid::Uuid, player: Arc<Player>) { pub async fn add_player(&self, uuid: uuid::Uuid, player: Arc<Player>) {
self.current_players let mut current_players = self.current_players.lock().await;
.lock() current_players.insert(uuid, player.clone());
.await
.insert(uuid, player.clone());
// Handle join message // Handle join message
// TODO: Config
let msg_txt = format!("{} joined the game.", player.gameprofile.name.as_str()); let msg_txt = format!("{} joined the game.", player.gameprofile.name.as_str());
let msg_comp = TextComponent::text(msg_txt.as_str()).color_named(NamedColor::Yellow); let msg_comp = TextComponent::text(msg_txt.as_str()).color_named(NamedColor::Yellow);
for player in self.current_players.lock().await.values() { for player in current_players.values() {
player.send_system_message(&msg_comp).await; player.send_system_message(&msg_comp).await;
} }
log::info!("{}", msg_comp.to_pretty_console()); log::info!("{}", msg_comp.to_pretty_console());
} }
/// Removes a player from the world and broadcasts a disconnect message if enabled.
///
/// This function removes a player from the world based on their `Player` reference.
/// It performs the following actions:
///
/// 1. Removes the player from the `current_players` map using their UUID.
/// 2. Broadcasts a `CRemovePlayerInfo` packet to all connected players to inform them about the player leaving.
/// 3. Removes the player's entity from the world using its entity ID.
/// 4. Optionally sends a disconnect message to all other players notifying them about the player leaving.
///
/// # Arguments
///
/// * `player`: A reference to the `Player` object to be removed.
///
/// # Notes
///
/// - This function assumes `broadcast_packet_expect` and `remove_entity` are defined elsewhere.
/// - The disconnect message sending is currently optional. Consider making it a configurable option.
pub async fn remove_player(&self, player: &Player) { pub async fn remove_player(&self, player: &Player) {
self.current_players let mut current_players = self.current_players.lock().await;
.lock() current_players.remove(&player.gameprofile.id).unwrap();
.await
.remove(&player.gameprofile.id)
.unwrap();
let uuid = player.gameprofile.id; let uuid = player.gameprofile.id;
self.broadcast_packet_expect( self.broadcast_packet_expect(
&[player.gameprofile.id], &[player.gameprofile.id],
@ -521,10 +558,11 @@ impl World {
self.remove_entity(&player.living_entity.entity).await; self.remove_entity(&player.living_entity.entity).await;
// Send disconnect message / quit message to players in the same world // Send disconnect message / quit message to players in the same world
// TODO: Config
let disconn_msg_txt = format!("{} left the game.", player.gameprofile.name.as_str()); let disconn_msg_txt = format!("{} left the game.", player.gameprofile.name.as_str());
let disconn_msg_cmp = let disconn_msg_cmp =
TextComponent::text(disconn_msg_txt.as_str()).color_named(NamedColor::Yellow); TextComponent::text(disconn_msg_txt.as_str()).color_named(NamedColor::Yellow);
for player in self.current_players.lock().await.values() { for player in current_players.values() {
player.send_system_message(&disconn_msg_cmp).await; player.send_system_message(&disconn_msg_cmp).await;
} }
log::info!("{}", disconn_msg_cmp.to_pretty_console()); log::info!("{}", disconn_msg_cmp.to_pretty_console());