Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
424aa67b6e | ||
|
|
549a4ad81b | ||
|
|
7726b9aa4e | ||
|
|
a90aad5b67 | ||
|
|
806e023657 | ||
|
|
39fb971202 | ||
|
|
adc4245c71 | ||
|
|
a4a0b07dfb | ||
|
|
713957c382 | ||
|
|
16a1c283f2 | ||
|
|
f0cb770372 | ||
|
|
44b85b2c17 | ||
|
|
4b962cf55e | ||
|
|
867b7b3484 | ||
|
|
54c2bdc301 |
No files matched your search
@@ -17,7 +17,7 @@ jobs:
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
java-version: '21'
|
||||
|
||||
# Build plugin
|
||||
- name: Build with Maven
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: '17'
|
||||
java-version: '21'
|
||||
|
||||
# Build plugin
|
||||
- name: Build with Maven
|
||||
@@ -33,7 +33,14 @@ jobs:
|
||||
uses: actions/setup-java@v4
|
||||
with:
|
||||
distribution: 'temurin'
|
||||
java-version: ${{ startsWith(matrix.version, '1.16') && '11' || (startsWith(matrix.version, '1.17') && '16' || '17') }}
|
||||
java-version: |
|
||||
${{
|
||||
startsWith(matrix.version, '1.16') && '11' ||
|
||||
startsWith(matrix.version, '1.17') && '16' ||
|
||||
startsWith(matrix.version, '1.18') && '17' ||
|
||||
startsWith(matrix.version, '1.19') && '17' ||
|
||||
'21'
|
||||
}}
|
||||
|
||||
# Setup Node.js
|
||||
- name: Setup Node.js
|
||||
|
||||
Generated
+158
-193
@@ -6,43 +6,43 @@
|
||||
"": {
|
||||
"name": "@yamipa/automata",
|
||||
"dependencies": {
|
||||
"mineflayer": "^4.14.0",
|
||||
"rcon-client": "^4.2.3"
|
||||
"mineflayer": "^4.20.1",
|
||||
"rcon-client": "^4.2.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/msal-common": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.1.0.tgz",
|
||||
"integrity": "sha512-xphmhcfl5VL+uq5//VKMwQn+wfEZLMKNpFCcMi8Ur8ej5UT166g6chBsxgMzc9xo9Y24R9FB3m/tjDiV03xMIA==",
|
||||
"version": "14.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.10.0.tgz",
|
||||
"integrity": "sha512-Zk6DPDz7e1wPgLoLgAp0349Yay9RvcjPM5We/ehuenDNsz/t9QEFI7tRoHpp/e47I4p20XE3FiDlhKwAo3utDA==",
|
||||
"engines": {
|
||||
"node": ">=0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@azure/msal-node": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.2.0.tgz",
|
||||
"integrity": "sha512-aZZ1m7OATOR9kz7+/Kl+/LZrNEj+HYaEH84XZfnBtN/9JPRazngk1XTjvAkh7W1u/O/yQrlYiiSwSAKHnNBc8A==",
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.8.1.tgz",
|
||||
"integrity": "sha512-VcZZM+5VvCWRBTOF7SxMKaxrz+EXjntx2u5AQe7QE06e6FuPJElGBrImgNgCh5QmFaNCfVFO+3qNR7UoFD/Gfw==",
|
||||
"dependencies": {
|
||||
"@azure/msal-common": "14.1.0",
|
||||
"@azure/msal-common": "14.10.0",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"uuid": "^8.3.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "18 || 20"
|
||||
"node": ">=16"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/node": {
|
||||
"version": "20.8.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz",
|
||||
"integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==",
|
||||
"version": "20.12.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz",
|
||||
"integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==",
|
||||
"dependencies": {
|
||||
"undici-types": "~5.25.1"
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/readable-stream": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.3.tgz",
|
||||
"integrity": "sha512-Z8BOzyIj3UPpn3j5DmDNKIw4wPN9N8a1d1oyteiprWq+wxdgQNC0UfFAQwWjmjyA7uoj7mvoWgxWWH66zYtm4Q==",
|
||||
"version": "4.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.14.tgz",
|
||||
"integrity": "sha512-xZn/AuUbCMShGsqH/ehZtGDwQtbx00M9rZ2ENLe4tOjFZ/JFeWMhEZkk2fEe1jAUqqEAURIkFJ7Az/go8mM1/w==",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"safe-buffer": "~5.1.1"
|
||||
@@ -230,9 +230,9 @@
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
||||
},
|
||||
"node_modules/follow-redirects": {
|
||||
"version": "1.15.3",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
|
||||
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==",
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -273,9 +273,9 @@
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"node_modules/jose": {
|
||||
"version": "4.15.3",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.3.tgz",
|
||||
"integrity": "sha512-RZJdL9Qjd1sqNdyiVteRGV/bnWtik/+PJh1JP4kT6+x1QQMn+7ryueRys5BEueuayvSVY8CWGCisCDazeRLTuw==",
|
||||
"version": "4.15.5",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz",
|
||||
"integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg==",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/panva"
|
||||
}
|
||||
@@ -375,26 +375,15 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz",
|
||||
"integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw=="
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"dependencies": {
|
||||
"yallist": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/macaddress": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.5.3.tgz",
|
||||
"integrity": "sha512-vGBKTA+jwM4KgjGZ+S/8/Mkj9rWzePyGY6jManXPGhiWu63RYwW8dKPyk5koP+8qNVhPhHgFa1y/MJ4wrjsNrg=="
|
||||
},
|
||||
"node_modules/minecraft-data": {
|
||||
"version": "3.46.2",
|
||||
"resolved": "https://registry.npmjs.org/minecraft-data/-/minecraft-data-3.46.2.tgz",
|
||||
"integrity": "sha512-vunI/l5mqjU7FisB5iFxcNl6BkKLzELUvsP5P4gpUOAUtTWXEUYTnVg9jdIFOl7Y2zw3TxG2RHDa0h0ScnRCEA=="
|
||||
"version": "3.65.0",
|
||||
"resolved": "https://registry.npmjs.org/minecraft-data/-/minecraft-data-3.65.0.tgz",
|
||||
"integrity": "sha512-9K8dOrdrcpUklTdqKBtRcKur0gLZnguTvhM/1Xv52qzh8Unkto4290RJc4ueRIYo1VqN4zzQrRxO8lnqtkERDQ=="
|
||||
},
|
||||
"node_modules/minecraft-folder-path": {
|
||||
"version": "1.2.0",
|
||||
@@ -402,9 +391,9 @@
|
||||
"integrity": "sha512-qaUSbKWoOsH9brn0JQuBhxNAzTDMwrOXorwuRxdJKKKDYvZhtml+6GVCUrY5HRiEsieBEjCUnhVpDuQiKsiFaw=="
|
||||
},
|
||||
"node_modules/minecraft-protocol": {
|
||||
"version": "1.44.0",
|
||||
"resolved": "https://registry.npmjs.org/minecraft-protocol/-/minecraft-protocol-1.44.0.tgz",
|
||||
"integrity": "sha512-sYu4fFzUKt3spPG5tAdkaB9sNQPT0sV6fyS0sS7/nxdzFfjmLhF6BLNC+32ieK4/MhgNyHtH6xusD0Bi0Roq9w==",
|
||||
"version": "1.47.0",
|
||||
"resolved": "https://registry.npmjs.org/minecraft-protocol/-/minecraft-protocol-1.47.0.tgz",
|
||||
"integrity": "sha512-IHL8faXLLIWv1O+2v2NgyKlooilu/OiSL9orI8Kqed/rZvVOrFPzs2PwMAYjpQX9gxLPhiSU19KqZ8CjfNuqhg==",
|
||||
"dependencies": {
|
||||
"@types/readable-stream": "^4.0.0",
|
||||
"aes-js": "^3.1.2",
|
||||
@@ -413,12 +402,13 @@
|
||||
"endian-toggle": "^0.0.0",
|
||||
"lodash.get": "^4.1.2",
|
||||
"lodash.merge": "^4.3.0",
|
||||
"minecraft-data": "^3.37.0",
|
||||
"minecraft-data": "^3.55.0",
|
||||
"minecraft-folder-path": "^1.2.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"node-rsa": "^0.4.2",
|
||||
"prismarine-auth": "^2.2.0",
|
||||
"prismarine-nbt": "^2.0.0",
|
||||
"prismarine-chat": "^1.10.0",
|
||||
"prismarine-nbt": "^2.5.0",
|
||||
"prismarine-realms": "^1.2.0",
|
||||
"protodef": "^1.8.0",
|
||||
"readable-stream": "^4.1.0",
|
||||
@@ -430,12 +420,12 @@
|
||||
}
|
||||
},
|
||||
"node_modules/mineflayer": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/mineflayer/-/mineflayer-4.14.0.tgz",
|
||||
"integrity": "sha512-4EYzUmZNxH3Gpz3GkgO2eaR90ANb50nVhMCU2y6Rl1Ru8M6HqxID1Eg7tRgsodfAOD+AKh5SPwmPnISLcxvnOA==",
|
||||
"version": "4.20.1",
|
||||
"resolved": "https://registry.npmjs.org/mineflayer/-/mineflayer-4.20.1.tgz",
|
||||
"integrity": "sha512-QMMNPx4IyZE7ydAzjvGLQLCnQNUOfkk1qVZKxTTS9q3qPTAewz4GhsVUBtbQ8LSbHthe5RcQ1Sgxs4wlIma/Qw==",
|
||||
"dependencies": {
|
||||
"minecraft-data": "^3.44.0",
|
||||
"minecraft-protocol": "^1.44.0",
|
||||
"minecraft-data": "^3.56.0",
|
||||
"minecraft-protocol": "^1.47.0",
|
||||
"prismarine-biome": "^1.1.1",
|
||||
"prismarine-block": "^1.17.0",
|
||||
"prismarine-chat": "^1.7.1",
|
||||
@@ -446,14 +436,14 @@
|
||||
"prismarine-physics": "^1.8.0",
|
||||
"prismarine-recipe": "^1.3.0",
|
||||
"prismarine-registry": "^1.5.0",
|
||||
"prismarine-windows": "^2.8.0",
|
||||
"prismarine-windows": "^2.9.0",
|
||||
"prismarine-world": "^3.6.0",
|
||||
"protodef": "^1.14.0",
|
||||
"typed-emitter": "^1.0.0",
|
||||
"vec3": "^0.1.7"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=14"
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/mojangson": {
|
||||
@@ -523,9 +513,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prismarine-auth": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-auth/-/prismarine-auth-2.3.0.tgz",
|
||||
"integrity": "sha512-giKZiHwuQdpMJ7KX94UncOJqM3u+yqKIR2UI/rqmdmFUuQilV9vhlz/zehpVkvo7FE8gmZsuUMCUPhI+gtgd3A==",
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-auth/-/prismarine-auth-2.4.2.tgz",
|
||||
"integrity": "sha512-Cq4woGobnFYYfMBDh1WITW+Vs98toN91qAFBvBitwV7IwJaiSAh2Nl+WPUEGeg5eLBoSPpSyCVT8P2oi7Cav8g==",
|
||||
"dependencies": {
|
||||
"@azure/msal-node": "^2.0.2",
|
||||
"@xboxreplay/xboxlive-auth": "^3.3.3",
|
||||
@@ -546,9 +536,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prismarine-block": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-block/-/prismarine-block-1.17.0.tgz",
|
||||
"integrity": "sha512-GawzWU91pH4sLTtMvrRe2wiEbO8hgTRwViCBYoFmmqeJYLiblq4GfXOvclj3rEAEdAAVzRKCQxQHpLJhhLWssg==",
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-block/-/prismarine-block-1.17.1.tgz",
|
||||
"integrity": "sha512-r1TIn/b5v77BX4a+qd+Yv+4/vZpsC/Jp5ElYxd6++2wpCnqiuxVG7BlS2Eo14vez1M2gt3qoNEl54Hr8qox/rQ==",
|
||||
"dependencies": {
|
||||
"minecraft-data": "^3.38.0",
|
||||
"prismarine-biome": "^1.1.0",
|
||||
@@ -559,20 +549,19 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prismarine-chat": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-chat/-/prismarine-chat-1.8.0.tgz",
|
||||
"integrity": "sha512-hEz47GESIEP0W1KSHrK7ZSy0PqbQW7khYWenv8d5wvyAYnBs1E4KXDBJSWqyGIYinKGN9aes8v3xpQhgURK/Fg==",
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-chat/-/prismarine-chat-1.10.1.tgz",
|
||||
"integrity": "sha512-XukYcuueuhDxzEXG7r8BZyt6jOObrPPB4JESCgb+/XenB9nExoSHF8eTQWWj8faKPLqm1dRQaYwFJlNBlJZJUw==",
|
||||
"dependencies": {
|
||||
"mojangson": "^2.0.1",
|
||||
"prismarine-item": "^1.10.0",
|
||||
"prismarine-nbt": "^2.0.0",
|
||||
"prismarine-registry": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prismarine-chunk": {
|
||||
"version": "1.34.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-chunk/-/prismarine-chunk-1.34.0.tgz",
|
||||
"integrity": "sha512-5RuQk8w9Ot550G5mmUFZvjpHugEXozgEFXiAhynrBCHOKJ3mMQ7VvhWF2irtjx+d2t29yDAiSEiSS34vxAmODQ==",
|
||||
"version": "1.35.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-chunk/-/prismarine-chunk-1.35.0.tgz",
|
||||
"integrity": "sha512-Q1lElMUle7wWxWdQjbZo3j2/dLNG325j90IcbbMmBTnHdQSWIjWFe792XOz3RVBlvrhRJEiZk38S6/eQTQ9esw==",
|
||||
"dependencies": {
|
||||
"prismarine-biome": "^1.2.0",
|
||||
"prismarine-block": "^1.14.1",
|
||||
@@ -588,9 +577,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prismarine-entity": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-entity/-/prismarine-entity-2.3.1.tgz",
|
||||
"integrity": "sha512-HOv8l7IetHNf4hwZ7V/W4vM3GNl+e6VCtKDkH9h02TRq7jWngsggKtJV+VanCce/sNwtJUhJDjORGs728ep4MA==",
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-entity/-/prismarine-entity-2.4.0.tgz",
|
||||
"integrity": "sha512-DBwjmoCX1IYAhN99KwYkk2rMArn65JHTzuuGXchr4GLWQs7UN4Pf9tELqBwNOu4r57x3RaW0+9+0sI3FvJQWzQ==",
|
||||
"dependencies": {
|
||||
"prismarine-chat": "^1.4.1",
|
||||
"prismarine-item": "^1.11.2",
|
||||
@@ -608,9 +597,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prismarine-nbt": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-nbt/-/prismarine-nbt-2.2.1.tgz",
|
||||
"integrity": "sha512-Mb50c58CPnuZ+qvM31DBa08tf9UumlTq1LkvpMoUpKfCuN05GZHTqCUwER3lxTSHLL0GZKghIPbYR/JQkINijQ==",
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-nbt/-/prismarine-nbt-2.5.0.tgz",
|
||||
"integrity": "sha512-F0/8UAa9SDDnAGrBYqZc4nG8h2zj5cE2eAJU5xlDR/IsQQ3moVxkOjE3h3nMv6SbvZrvAcgX7waA/nd9LLHYdA==",
|
||||
"dependencies": {
|
||||
"protodef": "^1.9.0"
|
||||
}
|
||||
@@ -652,9 +641,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prismarine-windows": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-windows/-/prismarine-windows-2.8.0.tgz",
|
||||
"integrity": "sha512-9HVhJ8tfCeRubYwQzgz8oiHNAebMJ5hDdjm45PZwrOgewaislnR2HDsbPMWiCcyWkYL7J8bVLVoSzEzv5pH98g==",
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-windows/-/prismarine-windows-2.9.0.tgz",
|
||||
"integrity": "sha512-fm4kOLjGFPov7TEJRmXHoiPabxIQrG36r2mDjlNxfkcLfMHFb3/1ML6mp4iRQa7wL0GK4DIAyiBqCWoeWDxARg==",
|
||||
"dependencies": {
|
||||
"prismarine-item": "^1.12.2",
|
||||
"prismarine-registry": "^1.7.0",
|
||||
@@ -673,9 +662,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/prismarine-world": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-world/-/prismarine-world-3.6.2.tgz",
|
||||
"integrity": "sha512-xNNo3bd8EnCMjiPbVrh3jYa1Upa8Krkb13BgO7FOOfD5ZYf+iYDZewBtDbHYWzZZB2N0JlTtimMOHRhZhDJirw==",
|
||||
"version": "3.6.3",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-world/-/prismarine-world-3.6.3.tgz",
|
||||
"integrity": "sha512-zqdqPEYCDHzqi6hglJldEO63bOROXpbZeIdxBmoQq7o04Lf81t016LU6stFHo3E+bmp5+xU74eDFdOvzYNABkA==",
|
||||
"dependencies": {
|
||||
"vec3": "^0.1.7"
|
||||
},
|
||||
@@ -730,9 +719,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/punycode": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
|
||||
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@@ -755,9 +744,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/rcon-client": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/rcon-client/-/rcon-client-4.2.3.tgz",
|
||||
"integrity": "sha512-g+DEzI3O0Nl4Y3mPp6DHhSpYeiv+wTq8iKxCumFGO0/SMCsdNfx9bpT5RyHa7phR5dvspKfQK0ZYJp1YCtXNng==",
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/rcon-client/-/rcon-client-4.2.4.tgz",
|
||||
"integrity": "sha512-sTHYLbcu2qrrOX4TOD3rvcLZNs7xiAhTsnZZIvxviSpa0yeV63sPAVI0PeScn5IvhKOCMURGt1NmnQ8h/GxjtA==",
|
||||
"dependencies": {
|
||||
"typed-emitter": "^0.1.0"
|
||||
}
|
||||
@@ -768,9 +757,9 @@
|
||||
"integrity": "sha512-Tfay0l6gJMP5rkil8CzGbLthukn+9BN/VXWcABVFPjOoelJ+koW8BuPZYk+h/L+lEeIp1fSzVRiWRPIjKVjPdg=="
|
||||
},
|
||||
"node_modules/readable-stream": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz",
|
||||
"integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==",
|
||||
"version": "4.5.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz",
|
||||
"integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==",
|
||||
"dependencies": {
|
||||
"abort-controller": "^3.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
@@ -805,12 +794,9 @@
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"node_modules/semver": {
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
||||
"dependencies": {
|
||||
"lru-cache": "^6.0.0"
|
||||
},
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
|
||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==",
|
||||
"bin": {
|
||||
"semver": "bin/semver.js"
|
||||
},
|
||||
@@ -876,9 +862,9 @@
|
||||
"integrity": "sha512-lhEx78gdTwFWG+mt6cWAZD/R6qrIj0TTBeH5xwyuDJyswLNlGe+KVlUPQ6+mx5Ld332pS0AMUTo9hIly7YsWxQ=="
|
||||
},
|
||||
"node_modules/undici-types": {
|
||||
"version": "5.25.3",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
|
||||
"integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA=="
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||
},
|
||||
"node_modules/uri-js": {
|
||||
"version": "4.4.1",
|
||||
@@ -910,9 +896,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/vec3": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/vec3/-/vec3-0.1.8.tgz",
|
||||
"integrity": "sha512-LfKrP625Bsg/Tj52YdYPsHmpsJuo+tc6fLxZxXjEo9k2xSspKlPvoYTHehykKhp1FvV9nm+XU3Ehej5/9tpDCg=="
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/vec3/-/vec3-0.1.10.tgz",
|
||||
"integrity": "sha512-Sr1U3mYtMqCOonGd3LAN9iqy0qF6C+Gjil92awyK/i2OwiUo9bm7PnLgFpafymun50mOjnDcg4ToTgRssrlTcw=="
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
@@ -933,11 +919,6 @@
|
||||
"resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz",
|
||||
"integrity": "sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA=="
|
||||
},
|
||||
"node_modules/yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"node_modules/yggdrasil": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/yggdrasil/-/yggdrasil-1.7.0.tgz",
|
||||
@@ -950,32 +931,32 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@azure/msal-common": {
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.1.0.tgz",
|
||||
"integrity": "sha512-xphmhcfl5VL+uq5//VKMwQn+wfEZLMKNpFCcMi8Ur8ej5UT166g6chBsxgMzc9xo9Y24R9FB3m/tjDiV03xMIA=="
|
||||
"version": "14.10.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-14.10.0.tgz",
|
||||
"integrity": "sha512-Zk6DPDz7e1wPgLoLgAp0349Yay9RvcjPM5We/ehuenDNsz/t9QEFI7tRoHpp/e47I4p20XE3FiDlhKwAo3utDA=="
|
||||
},
|
||||
"@azure/msal-node": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.2.0.tgz",
|
||||
"integrity": "sha512-aZZ1m7OATOR9kz7+/Kl+/LZrNEj+HYaEH84XZfnBtN/9JPRazngk1XTjvAkh7W1u/O/yQrlYiiSwSAKHnNBc8A==",
|
||||
"version": "2.8.1",
|
||||
"resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-2.8.1.tgz",
|
||||
"integrity": "sha512-VcZZM+5VvCWRBTOF7SxMKaxrz+EXjntx2u5AQe7QE06e6FuPJElGBrImgNgCh5QmFaNCfVFO+3qNR7UoFD/Gfw==",
|
||||
"requires": {
|
||||
"@azure/msal-common": "14.1.0",
|
||||
"@azure/msal-common": "14.10.0",
|
||||
"jsonwebtoken": "^9.0.0",
|
||||
"uuid": "^8.3.0"
|
||||
}
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "20.8.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.6.tgz",
|
||||
"integrity": "sha512-eWO4K2Ji70QzKUqRy6oyJWUeB7+g2cRagT3T/nxYibYcT4y2BDL8lqolRXjTHmkZCdJfIPaY73KbJAZmcryxTQ==",
|
||||
"version": "20.12.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.12.tgz",
|
||||
"integrity": "sha512-eWLDGF/FOSPtAvEqeRAQ4C8LSA7M1I7i0ky1I8U7kD1J5ITyW3AsRhQrKVoWf5pFKZ2kILsEGJhsI9r93PYnOw==",
|
||||
"requires": {
|
||||
"undici-types": "~5.25.1"
|
||||
"undici-types": "~5.26.4"
|
||||
}
|
||||
},
|
||||
"@types/readable-stream": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.3.tgz",
|
||||
"integrity": "sha512-Z8BOzyIj3UPpn3j5DmDNKIw4wPN9N8a1d1oyteiprWq+wxdgQNC0UfFAQwWjmjyA7uoj7mvoWgxWWH66zYtm4Q==",
|
||||
"version": "4.0.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/readable-stream/-/readable-stream-4.0.14.tgz",
|
||||
"integrity": "sha512-xZn/AuUbCMShGsqH/ehZtGDwQtbx00M9rZ2ENLe4tOjFZ/JFeWMhEZkk2fEe1jAUqqEAURIkFJ7Az/go8mM1/w==",
|
||||
"requires": {
|
||||
"@types/node": "*",
|
||||
"safe-buffer": "~5.1.1"
|
||||
@@ -1108,9 +1089,9 @@
|
||||
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw=="
|
||||
},
|
||||
"follow-redirects": {
|
||||
"version": "1.15.3",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.3.tgz",
|
||||
"integrity": "sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q=="
|
||||
"version": "1.15.6",
|
||||
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA=="
|
||||
},
|
||||
"ieee754": {
|
||||
"version": "1.2.1",
|
||||
@@ -1123,9 +1104,9 @@
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
||||
},
|
||||
"jose": {
|
||||
"version": "4.15.3",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.3.tgz",
|
||||
"integrity": "sha512-RZJdL9Qjd1sqNdyiVteRGV/bnWtik/+PJh1JP4kT6+x1QQMn+7ryueRys5BEueuayvSVY8CWGCisCDazeRLTuw=="
|
||||
"version": "4.15.5",
|
||||
"resolved": "https://registry.npmjs.org/jose/-/jose-4.15.5.tgz",
|
||||
"integrity": "sha512-jc7BFxgKPKi94uOvEmzlSWFFe2+vASyXaKUpdQKatWAESU2MWjDfFf0fdfc83CDKcA5QecabZeNLyfhe3yKNkg=="
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
@@ -1218,23 +1199,15 @@
|
||||
"resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz",
|
||||
"integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw=="
|
||||
},
|
||||
"lru-cache": {
|
||||
"version": "6.0.0",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
|
||||
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
|
||||
"requires": {
|
||||
"yallist": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"macaddress": {
|
||||
"version": "0.5.3",
|
||||
"resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.5.3.tgz",
|
||||
"integrity": "sha512-vGBKTA+jwM4KgjGZ+S/8/Mkj9rWzePyGY6jManXPGhiWu63RYwW8dKPyk5koP+8qNVhPhHgFa1y/MJ4wrjsNrg=="
|
||||
},
|
||||
"minecraft-data": {
|
||||
"version": "3.46.2",
|
||||
"resolved": "https://registry.npmjs.org/minecraft-data/-/minecraft-data-3.46.2.tgz",
|
||||
"integrity": "sha512-vunI/l5mqjU7FisB5iFxcNl6BkKLzELUvsP5P4gpUOAUtTWXEUYTnVg9jdIFOl7Y2zw3TxG2RHDa0h0ScnRCEA=="
|
||||
"version": "3.65.0",
|
||||
"resolved": "https://registry.npmjs.org/minecraft-data/-/minecraft-data-3.65.0.tgz",
|
||||
"integrity": "sha512-9K8dOrdrcpUklTdqKBtRcKur0gLZnguTvhM/1Xv52qzh8Unkto4290RJc4ueRIYo1VqN4zzQrRxO8lnqtkERDQ=="
|
||||
},
|
||||
"minecraft-folder-path": {
|
||||
"version": "1.2.0",
|
||||
@@ -1242,9 +1215,9 @@
|
||||
"integrity": "sha512-qaUSbKWoOsH9brn0JQuBhxNAzTDMwrOXorwuRxdJKKKDYvZhtml+6GVCUrY5HRiEsieBEjCUnhVpDuQiKsiFaw=="
|
||||
},
|
||||
"minecraft-protocol": {
|
||||
"version": "1.44.0",
|
||||
"resolved": "https://registry.npmjs.org/minecraft-protocol/-/minecraft-protocol-1.44.0.tgz",
|
||||
"integrity": "sha512-sYu4fFzUKt3spPG5tAdkaB9sNQPT0sV6fyS0sS7/nxdzFfjmLhF6BLNC+32ieK4/MhgNyHtH6xusD0Bi0Roq9w==",
|
||||
"version": "1.47.0",
|
||||
"resolved": "https://registry.npmjs.org/minecraft-protocol/-/minecraft-protocol-1.47.0.tgz",
|
||||
"integrity": "sha512-IHL8faXLLIWv1O+2v2NgyKlooilu/OiSL9orI8Kqed/rZvVOrFPzs2PwMAYjpQX9gxLPhiSU19KqZ8CjfNuqhg==",
|
||||
"requires": {
|
||||
"@types/readable-stream": "^4.0.0",
|
||||
"aes-js": "^3.1.2",
|
||||
@@ -1253,12 +1226,13 @@
|
||||
"endian-toggle": "^0.0.0",
|
||||
"lodash.get": "^4.1.2",
|
||||
"lodash.merge": "^4.3.0",
|
||||
"minecraft-data": "^3.37.0",
|
||||
"minecraft-data": "^3.55.0",
|
||||
"minecraft-folder-path": "^1.2.0",
|
||||
"node-fetch": "^2.6.1",
|
||||
"node-rsa": "^0.4.2",
|
||||
"prismarine-auth": "^2.2.0",
|
||||
"prismarine-nbt": "^2.0.0",
|
||||
"prismarine-chat": "^1.10.0",
|
||||
"prismarine-nbt": "^2.5.0",
|
||||
"prismarine-realms": "^1.2.0",
|
||||
"protodef": "^1.8.0",
|
||||
"readable-stream": "^4.1.0",
|
||||
@@ -1267,12 +1241,12 @@
|
||||
}
|
||||
},
|
||||
"mineflayer": {
|
||||
"version": "4.14.0",
|
||||
"resolved": "https://registry.npmjs.org/mineflayer/-/mineflayer-4.14.0.tgz",
|
||||
"integrity": "sha512-4EYzUmZNxH3Gpz3GkgO2eaR90ANb50nVhMCU2y6Rl1Ru8M6HqxID1Eg7tRgsodfAOD+AKh5SPwmPnISLcxvnOA==",
|
||||
"version": "4.20.1",
|
||||
"resolved": "https://registry.npmjs.org/mineflayer/-/mineflayer-4.20.1.tgz",
|
||||
"integrity": "sha512-QMMNPx4IyZE7ydAzjvGLQLCnQNUOfkk1qVZKxTTS9q3qPTAewz4GhsVUBtbQ8LSbHthe5RcQ1Sgxs4wlIma/Qw==",
|
||||
"requires": {
|
||||
"minecraft-data": "^3.44.0",
|
||||
"minecraft-protocol": "^1.44.0",
|
||||
"minecraft-data": "^3.56.0",
|
||||
"minecraft-protocol": "^1.47.0",
|
||||
"prismarine-biome": "^1.1.1",
|
||||
"prismarine-block": "^1.17.0",
|
||||
"prismarine-chat": "^1.7.1",
|
||||
@@ -1283,7 +1257,7 @@
|
||||
"prismarine-physics": "^1.8.0",
|
||||
"prismarine-recipe": "^1.3.0",
|
||||
"prismarine-registry": "^1.5.0",
|
||||
"prismarine-windows": "^2.8.0",
|
||||
"prismarine-windows": "^2.9.0",
|
||||
"prismarine-world": "^3.6.0",
|
||||
"protodef": "^1.14.0",
|
||||
"typed-emitter": "^1.0.0",
|
||||
@@ -1336,9 +1310,9 @@
|
||||
}
|
||||
},
|
||||
"prismarine-auth": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-auth/-/prismarine-auth-2.3.0.tgz",
|
||||
"integrity": "sha512-giKZiHwuQdpMJ7KX94UncOJqM3u+yqKIR2UI/rqmdmFUuQilV9vhlz/zehpVkvo7FE8gmZsuUMCUPhI+gtgd3A==",
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-auth/-/prismarine-auth-2.4.2.tgz",
|
||||
"integrity": "sha512-Cq4woGobnFYYfMBDh1WITW+Vs98toN91qAFBvBitwV7IwJaiSAh2Nl+WPUEGeg5eLBoSPpSyCVT8P2oi7Cav8g==",
|
||||
"requires": {
|
||||
"@azure/msal-node": "^2.0.2",
|
||||
"@xboxreplay/xboxlive-auth": "^3.3.3",
|
||||
@@ -1356,9 +1330,9 @@
|
||||
"requires": {}
|
||||
},
|
||||
"prismarine-block": {
|
||||
"version": "1.17.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-block/-/prismarine-block-1.17.0.tgz",
|
||||
"integrity": "sha512-GawzWU91pH4sLTtMvrRe2wiEbO8hgTRwViCBYoFmmqeJYLiblq4GfXOvclj3rEAEdAAVzRKCQxQHpLJhhLWssg==",
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-block/-/prismarine-block-1.17.1.tgz",
|
||||
"integrity": "sha512-r1TIn/b5v77BX4a+qd+Yv+4/vZpsC/Jp5ElYxd6++2wpCnqiuxVG7BlS2Eo14vez1M2gt3qoNEl54Hr8qox/rQ==",
|
||||
"requires": {
|
||||
"minecraft-data": "^3.38.0",
|
||||
"prismarine-biome": "^1.1.0",
|
||||
@@ -1369,20 +1343,19 @@
|
||||
}
|
||||
},
|
||||
"prismarine-chat": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-chat/-/prismarine-chat-1.8.0.tgz",
|
||||
"integrity": "sha512-hEz47GESIEP0W1KSHrK7ZSy0PqbQW7khYWenv8d5wvyAYnBs1E4KXDBJSWqyGIYinKGN9aes8v3xpQhgURK/Fg==",
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-chat/-/prismarine-chat-1.10.1.tgz",
|
||||
"integrity": "sha512-XukYcuueuhDxzEXG7r8BZyt6jOObrPPB4JESCgb+/XenB9nExoSHF8eTQWWj8faKPLqm1dRQaYwFJlNBlJZJUw==",
|
||||
"requires": {
|
||||
"mojangson": "^2.0.1",
|
||||
"prismarine-item": "^1.10.0",
|
||||
"prismarine-nbt": "^2.0.0",
|
||||
"prismarine-registry": "^1.4.0"
|
||||
}
|
||||
},
|
||||
"prismarine-chunk": {
|
||||
"version": "1.34.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-chunk/-/prismarine-chunk-1.34.0.tgz",
|
||||
"integrity": "sha512-5RuQk8w9Ot550G5mmUFZvjpHugEXozgEFXiAhynrBCHOKJ3mMQ7VvhWF2irtjx+d2t29yDAiSEiSS34vxAmODQ==",
|
||||
"version": "1.35.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-chunk/-/prismarine-chunk-1.35.0.tgz",
|
||||
"integrity": "sha512-Q1lElMUle7wWxWdQjbZo3j2/dLNG325j90IcbbMmBTnHdQSWIjWFe792XOz3RVBlvrhRJEiZk38S6/eQTQ9esw==",
|
||||
"requires": {
|
||||
"prismarine-biome": "^1.2.0",
|
||||
"prismarine-block": "^1.14.1",
|
||||
@@ -1395,9 +1368,9 @@
|
||||
}
|
||||
},
|
||||
"prismarine-entity": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-entity/-/prismarine-entity-2.3.1.tgz",
|
||||
"integrity": "sha512-HOv8l7IetHNf4hwZ7V/W4vM3GNl+e6VCtKDkH9h02TRq7jWngsggKtJV+VanCce/sNwtJUhJDjORGs728ep4MA==",
|
||||
"version": "2.4.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-entity/-/prismarine-entity-2.4.0.tgz",
|
||||
"integrity": "sha512-DBwjmoCX1IYAhN99KwYkk2rMArn65JHTzuuGXchr4GLWQs7UN4Pf9tELqBwNOu4r57x3RaW0+9+0sI3FvJQWzQ==",
|
||||
"requires": {
|
||||
"prismarine-chat": "^1.4.1",
|
||||
"prismarine-item": "^1.11.2",
|
||||
@@ -1415,9 +1388,9 @@
|
||||
}
|
||||
},
|
||||
"prismarine-nbt": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-nbt/-/prismarine-nbt-2.2.1.tgz",
|
||||
"integrity": "sha512-Mb50c58CPnuZ+qvM31DBa08tf9UumlTq1LkvpMoUpKfCuN05GZHTqCUwER3lxTSHLL0GZKghIPbYR/JQkINijQ==",
|
||||
"version": "2.5.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-nbt/-/prismarine-nbt-2.5.0.tgz",
|
||||
"integrity": "sha512-F0/8UAa9SDDnAGrBYqZc4nG8h2zj5cE2eAJU5xlDR/IsQQ3moVxkOjE3h3nMv6SbvZrvAcgX7waA/nd9LLHYdA==",
|
||||
"requires": {
|
||||
"protodef": "^1.9.0"
|
||||
}
|
||||
@@ -1457,9 +1430,9 @@
|
||||
}
|
||||
},
|
||||
"prismarine-windows": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-windows/-/prismarine-windows-2.8.0.tgz",
|
||||
"integrity": "sha512-9HVhJ8tfCeRubYwQzgz8oiHNAebMJ5hDdjm45PZwrOgewaislnR2HDsbPMWiCcyWkYL7J8bVLVoSzEzv5pH98g==",
|
||||
"version": "2.9.0",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-windows/-/prismarine-windows-2.9.0.tgz",
|
||||
"integrity": "sha512-fm4kOLjGFPov7TEJRmXHoiPabxIQrG36r2mDjlNxfkcLfMHFb3/1ML6mp4iRQa7wL0GK4DIAyiBqCWoeWDxARg==",
|
||||
"requires": {
|
||||
"prismarine-item": "^1.12.2",
|
||||
"prismarine-registry": "^1.7.0",
|
||||
@@ -1477,9 +1450,9 @@
|
||||
}
|
||||
},
|
||||
"prismarine-world": {
|
||||
"version": "3.6.2",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-world/-/prismarine-world-3.6.2.tgz",
|
||||
"integrity": "sha512-xNNo3bd8EnCMjiPbVrh3jYa1Upa8Krkb13BgO7FOOfD5ZYf+iYDZewBtDbHYWzZZB2N0JlTtimMOHRhZhDJirw==",
|
||||
"version": "3.6.3",
|
||||
"resolved": "https://registry.npmjs.org/prismarine-world/-/prismarine-world-3.6.3.tgz",
|
||||
"integrity": "sha512-zqdqPEYCDHzqi6hglJldEO63bOROXpbZeIdxBmoQq7o04Lf81t016LU6stFHo3E+bmp5+xU74eDFdOvzYNABkA==",
|
||||
"requires": {
|
||||
"vec3": "^0.1.7"
|
||||
}
|
||||
@@ -1521,9 +1494,9 @@
|
||||
}
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
|
||||
"integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA=="
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
|
||||
"integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="
|
||||
},
|
||||
"railroad-diagrams": {
|
||||
"version": "1.0.0",
|
||||
@@ -1540,9 +1513,9 @@
|
||||
}
|
||||
},
|
||||
"rcon-client": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/rcon-client/-/rcon-client-4.2.3.tgz",
|
||||
"integrity": "sha512-g+DEzI3O0Nl4Y3mPp6DHhSpYeiv+wTq8iKxCumFGO0/SMCsdNfx9bpT5RyHa7phR5dvspKfQK0ZYJp1YCtXNng==",
|
||||
"version": "4.2.4",
|
||||
"resolved": "https://registry.npmjs.org/rcon-client/-/rcon-client-4.2.4.tgz",
|
||||
"integrity": "sha512-sTHYLbcu2qrrOX4TOD3rvcLZNs7xiAhTsnZZIvxviSpa0yeV63sPAVI0PeScn5IvhKOCMURGt1NmnQ8h/GxjtA==",
|
||||
"requires": {
|
||||
"typed-emitter": "^0.1.0"
|
||||
},
|
||||
@@ -1555,9 +1528,9 @@
|
||||
}
|
||||
},
|
||||
"readable-stream": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz",
|
||||
"integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==",
|
||||
"version": "4.5.2",
|
||||
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.5.2.tgz",
|
||||
"integrity": "sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g==",
|
||||
"requires": {
|
||||
"abort-controller": "^3.0.0",
|
||||
"buffer": "^6.0.3",
|
||||
@@ -1586,12 +1559,9 @@
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
|
||||
},
|
||||
"semver": {
|
||||
"version": "7.5.4",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
|
||||
"integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
|
||||
"requires": {
|
||||
"lru-cache": "^6.0.0"
|
||||
}
|
||||
"version": "7.6.2",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz",
|
||||
"integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w=="
|
||||
},
|
||||
"smart-buffer": {
|
||||
"version": "4.2.0",
|
||||
@@ -1635,9 +1605,9 @@
|
||||
"integrity": "sha512-lhEx78gdTwFWG+mt6cWAZD/R6qrIj0TTBeH5xwyuDJyswLNlGe+KVlUPQ6+mx5Ld332pS0AMUTo9hIly7YsWxQ=="
|
||||
},
|
||||
"undici-types": {
|
||||
"version": "5.25.3",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.25.3.tgz",
|
||||
"integrity": "sha512-Ga1jfYwRn7+cP9v8auvEXN1rX3sWqlayd4HP7OKk4mZWylEmu3KzXDUGrQUN6Ol7qo1gPvB2e5gX6udnyEPgdA=="
|
||||
"version": "5.26.5",
|
||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.4.1",
|
||||
@@ -1666,9 +1636,9 @@
|
||||
}
|
||||
},
|
||||
"vec3": {
|
||||
"version": "0.1.8",
|
||||
"resolved": "https://registry.npmjs.org/vec3/-/vec3-0.1.8.tgz",
|
||||
"integrity": "sha512-LfKrP625Bsg/Tj52YdYPsHmpsJuo+tc6fLxZxXjEo9k2xSspKlPvoYTHehykKhp1FvV9nm+XU3Ehej5/9tpDCg=="
|
||||
"version": "0.1.10",
|
||||
"resolved": "https://registry.npmjs.org/vec3/-/vec3-0.1.10.tgz",
|
||||
"integrity": "sha512-Sr1U3mYtMqCOonGd3LAN9iqy0qF6C+Gjil92awyK/i2OwiUo9bm7PnLgFpafymun50mOjnDcg4ToTgRssrlTcw=="
|
||||
},
|
||||
"webidl-conversions": {
|
||||
"version": "3.0.1",
|
||||
@@ -1689,11 +1659,6 @@
|
||||
"resolved": "https://registry.npmjs.org/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz",
|
||||
"integrity": "sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA=="
|
||||
},
|
||||
"yallist": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
|
||||
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
|
||||
},
|
||||
"yggdrasil": {
|
||||
"version": "1.7.0",
|
||||
"resolved": "https://registry.npmjs.org/yggdrasil/-/yggdrasil-1.7.0.tgz",
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"start": "node index.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"mineflayer": "^4.14.0",
|
||||
"rcon-client": "^4.2.3"
|
||||
"mineflayer": "^4.20.1",
|
||||
"rcon-client": "^4.2.4"
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>io.josemmo.bukkit.plugin</groupId>
|
||||
<artifactId>YamipaPlugin</artifactId>
|
||||
<version>1.3.0</version>
|
||||
<version>1.3.2-SNAPSHOT-b2</version>
|
||||
|
||||
<properties>
|
||||
<maven.compiler.source>8</maven.compiler.source>
|
||||
@@ -42,7 +42,7 @@
|
||||
<dependency>
|
||||
<groupId>org.spigotmc</groupId>
|
||||
<artifactId>spigot-api</artifactId>
|
||||
<version>1.20.4-R0.1-SNAPSHOT</version>
|
||||
<version>1.20.6-R0.1-SNAPSHOT</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.TechFortress</groupId>
|
||||
<artifactId>GriefPrevention</artifactId>
|
||||
<version>16.18.1</version>
|
||||
<version>16.18.3</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.TownyAdvanced</groupId>
|
||||
<artifactId>towny</artifactId>
|
||||
<version>0.100.0.9</version>
|
||||
<version>0.100.2.11</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
<dependency>
|
||||
<groupId>com.github.angeschossen</groupId>
|
||||
<artifactId>LandsAPI</artifactId>
|
||||
<version>6.42.0</version>
|
||||
<version>7.1.12</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
|
||||
@@ -76,16 +76,127 @@ public class WorldAreaId {
|
||||
return distance / 4;
|
||||
});
|
||||
|
||||
// Size 3 (16-chunks radius)
|
||||
// ···XXX···
|
||||
// ·XXXXXXX·
|
||||
// ·XXXXXXX·
|
||||
// XXXXXXXXX
|
||||
// Size 0 (1+1+1=3)
|
||||
// ·|·
|
||||
// XOX
|
||||
// ·|·
|
||||
if (size == 0) {
|
||||
neighborhood = new WorldAreaId[]{
|
||||
new WorldAreaId(world, x, z-1),
|
||||
|
||||
new WorldAreaId(world, x-1, z),
|
||||
this,
|
||||
new WorldAreaId(world, x+1, z),
|
||||
|
||||
new WorldAreaId(world, x, z+1),
|
||||
};
|
||||
return neighborhood;
|
||||
}
|
||||
|
||||
// Size 1 (2+1+2=5)
|
||||
// ·X|X·
|
||||
// XX|XX
|
||||
// XXOXX
|
||||
// XX|XX
|
||||
// ·X|X·
|
||||
if (size == 1) {
|
||||
neighborhood = new WorldAreaId[]{
|
||||
new WorldAreaId(world, x-1, z-2),
|
||||
new WorldAreaId(world, x, z-2),
|
||||
new WorldAreaId(world, x+1, z-2),
|
||||
|
||||
new WorldAreaId(world, x-2, z-1),
|
||||
new WorldAreaId(world, x-1, z-1),
|
||||
new WorldAreaId(world, x, z-1),
|
||||
new WorldAreaId(world, x+1, z-1),
|
||||
new WorldAreaId(world, x+2, z-1),
|
||||
|
||||
new WorldAreaId(world, x-2, z),
|
||||
new WorldAreaId(world, x-1, z),
|
||||
this,
|
||||
new WorldAreaId(world, x+1, z),
|
||||
new WorldAreaId(world, x+2, z),
|
||||
|
||||
new WorldAreaId(world, x-2, z+1),
|
||||
new WorldAreaId(world, x-1, z+1),
|
||||
new WorldAreaId(world, x, z+1),
|
||||
new WorldAreaId(world, x+1, z+1),
|
||||
new WorldAreaId(world, x+2, z+1),
|
||||
|
||||
new WorldAreaId(world, x-1, z+2),
|
||||
new WorldAreaId(world, x, z+2),
|
||||
new WorldAreaId(world, x+1, z+2),
|
||||
};
|
||||
return neighborhood;
|
||||
}
|
||||
|
||||
// Size 2 (3+1+3=7)
|
||||
// ··X|X··
|
||||
// ·XX|XX·
|
||||
// XXX|XXX
|
||||
// XXXOXXX
|
||||
// XXX|XXX
|
||||
// ·XX|XX·
|
||||
// ··X|X··
|
||||
if (size == 2) {
|
||||
neighborhood = new WorldAreaId[]{
|
||||
new WorldAreaId(world, x-1, z-3),
|
||||
new WorldAreaId(world, x, z-3),
|
||||
new WorldAreaId(world, x+1, z-3),
|
||||
|
||||
new WorldAreaId(world, x-2, z-2),
|
||||
new WorldAreaId(world, x-1, z-2),
|
||||
new WorldAreaId(world, x, z-2),
|
||||
new WorldAreaId(world, x+1, z-2),
|
||||
new WorldAreaId(world, x+2, z-2),
|
||||
|
||||
new WorldAreaId(world, x-3, z-1),
|
||||
new WorldAreaId(world, x-2, z-1),
|
||||
new WorldAreaId(world, x-1, z-1),
|
||||
new WorldAreaId(world, x, z-1),
|
||||
new WorldAreaId(world, x+1, z-1),
|
||||
new WorldAreaId(world, x+2, z-1),
|
||||
new WorldAreaId(world, x+3, z-1),
|
||||
|
||||
new WorldAreaId(world, x-3, z),
|
||||
new WorldAreaId(world, x-2, z),
|
||||
new WorldAreaId(world, x-1, z),
|
||||
this,
|
||||
new WorldAreaId(world, x+1, z),
|
||||
new WorldAreaId(world, x+2, z),
|
||||
new WorldAreaId(world, x+3, z),
|
||||
|
||||
new WorldAreaId(world, x-3, z+1),
|
||||
new WorldAreaId(world, x-2, z+1),
|
||||
new WorldAreaId(world, x-1, z+1),
|
||||
new WorldAreaId(world, x, z+1),
|
||||
new WorldAreaId(world, x+1, z+1),
|
||||
new WorldAreaId(world, x+2, z+1),
|
||||
new WorldAreaId(world, x+3, z+1),
|
||||
|
||||
new WorldAreaId(world, x-2, z+2),
|
||||
new WorldAreaId(world, x-1, z+2),
|
||||
new WorldAreaId(world, x, z+2),
|
||||
new WorldAreaId(world, x+1, z+2),
|
||||
new WorldAreaId(world, x+2, z+2),
|
||||
|
||||
new WorldAreaId(world, x-1, z+3),
|
||||
new WorldAreaId(world, x, z+3),
|
||||
new WorldAreaId(world, x+1, z+3),
|
||||
};
|
||||
return neighborhood;
|
||||
}
|
||||
|
||||
// Size 3 (4+1+4=9)
|
||||
// ···X|X···
|
||||
// ·XXX|XXX·
|
||||
// ·XXX|XXX·
|
||||
// XXXX|XXXX
|
||||
// XXXXOXXXX
|
||||
// XXXXXXXXX
|
||||
// ·XXXXXXX·
|
||||
// ·XXXXXXX·
|
||||
// ···XXX···
|
||||
// XXXX|XXXX
|
||||
// ·XXX|XXX·
|
||||
// ·XXX|XXX·
|
||||
// ···X|X···
|
||||
if (size == 3) {
|
||||
neighborhood = new WorldAreaId[]{
|
||||
new WorldAreaId(world, x-1, z-4),
|
||||
@@ -161,112 +272,126 @@ public class WorldAreaId {
|
||||
return neighborhood;
|
||||
}
|
||||
|
||||
// Size 2 (12-chunks radius)
|
||||
// ··XXX··
|
||||
// ·XXXXX·
|
||||
// XXXXXXX
|
||||
// XXXOXXX
|
||||
// XXXXXXX
|
||||
// ·XXXXX·
|
||||
// ··XXX··
|
||||
if (size == 2) {
|
||||
neighborhood = new WorldAreaId[]{
|
||||
new WorldAreaId(world, x-1, z-3),
|
||||
new WorldAreaId(world, x, z-3),
|
||||
new WorldAreaId(world, x+1, z-3),
|
||||
|
||||
new WorldAreaId(world, x-2, z-2),
|
||||
new WorldAreaId(world, x-1, z-2),
|
||||
new WorldAreaId(world, x, z-2),
|
||||
new WorldAreaId(world, x+1, z-2),
|
||||
new WorldAreaId(world, x+2, z-2),
|
||||
|
||||
new WorldAreaId(world, x-3, z-1),
|
||||
new WorldAreaId(world, x-2, z-1),
|
||||
new WorldAreaId(world, x-1, z-1),
|
||||
new WorldAreaId(world, x, z-1),
|
||||
new WorldAreaId(world, x+1, z-1),
|
||||
new WorldAreaId(world, x+2, z-1),
|
||||
new WorldAreaId(world, x+3, z-1),
|
||||
|
||||
new WorldAreaId(world, x-3, z),
|
||||
new WorldAreaId(world, x-2, z),
|
||||
new WorldAreaId(world, x-1, z),
|
||||
this,
|
||||
new WorldAreaId(world, x+1, z),
|
||||
new WorldAreaId(world, x+2, z),
|
||||
new WorldAreaId(world, x+3, z),
|
||||
|
||||
new WorldAreaId(world, x-3, z+1),
|
||||
new WorldAreaId(world, x-2, z+1),
|
||||
new WorldAreaId(world, x-1, z+1),
|
||||
new WorldAreaId(world, x, z+1),
|
||||
new WorldAreaId(world, x+1, z+1),
|
||||
new WorldAreaId(world, x+2, z+1),
|
||||
new WorldAreaId(world, x+3, z+1),
|
||||
|
||||
new WorldAreaId(world, x-2, z+2),
|
||||
new WorldAreaId(world, x-1, z+2),
|
||||
new WorldAreaId(world, x, z+2),
|
||||
new WorldAreaId(world, x+1, z+2),
|
||||
new WorldAreaId(world, x+2, z+2),
|
||||
|
||||
new WorldAreaId(world, x-1, z+3),
|
||||
new WorldAreaId(world, x, z+3),
|
||||
new WorldAreaId(world, x+1, z+3),
|
||||
};
|
||||
return neighborhood;
|
||||
}
|
||||
|
||||
//// Size 1 (8-chunks radius)
|
||||
// ·XXX·
|
||||
// XXXXX
|
||||
// XXOXX
|
||||
// XXXXX
|
||||
// ·XXX·
|
||||
if (size == 1) {
|
||||
neighborhood = new WorldAreaId[]{
|
||||
new WorldAreaId(world, x-1, z-2),
|
||||
new WorldAreaId(world, x, z-2),
|
||||
new WorldAreaId(world, x+1, z-2),
|
||||
|
||||
new WorldAreaId(world, x-2, z-1),
|
||||
new WorldAreaId(world, x-1, z-1),
|
||||
new WorldAreaId(world, x, z-1),
|
||||
new WorldAreaId(world, x+1, z-1),
|
||||
new WorldAreaId(world, x+2, z-1),
|
||||
|
||||
new WorldAreaId(world, x-2, z),
|
||||
new WorldAreaId(world, x-1, z),
|
||||
this,
|
||||
new WorldAreaId(world, x+1, z),
|
||||
new WorldAreaId(world, x+2, z),
|
||||
|
||||
new WorldAreaId(world, x-2, z+1),
|
||||
new WorldAreaId(world, x-1, z+1),
|
||||
new WorldAreaId(world, x, z+1),
|
||||
new WorldAreaId(world, x+1, z+1),
|
||||
new WorldAreaId(world, x+2, z+1),
|
||||
|
||||
new WorldAreaId(world, x-1, z+2),
|
||||
new WorldAreaId(world, x, z+2),
|
||||
new WorldAreaId(world, x+1, z+2),
|
||||
};
|
||||
return neighborhood;
|
||||
}
|
||||
|
||||
//// Size 0 (4x4 chunks)
|
||||
// ·X·
|
||||
// XOX
|
||||
// ·X·
|
||||
// Size ≥4 (5+1+5=11)
|
||||
// ···XX|XX···
|
||||
// ··XXX|XXX··
|
||||
// ·XXXX|XXXX·
|
||||
// XXXXX|XXXXX
|
||||
// XXXXX|XXXXX
|
||||
// XXXXXOXXXXX
|
||||
// XXXXX|XXXXX
|
||||
// XXXXX|XXXXX
|
||||
// ·XXXX|XXXX·
|
||||
// ··XXX|XXX··
|
||||
// ···XX|XX···
|
||||
neighborhood = new WorldAreaId[]{
|
||||
new WorldAreaId(world, x, z-1),
|
||||
new WorldAreaId(world, x-2, z-5),
|
||||
new WorldAreaId(world, x-1, z-5),
|
||||
new WorldAreaId(world, x, z-5),
|
||||
new WorldAreaId(world, x+1, z-5),
|
||||
new WorldAreaId(world, x+2, z-5),
|
||||
|
||||
new WorldAreaId(world, x-3, z-4),
|
||||
new WorldAreaId(world, x-2, z-4),
|
||||
new WorldAreaId(world, x-1, z-4),
|
||||
new WorldAreaId(world, x, z-4),
|
||||
new WorldAreaId(world, x+1, z-4),
|
||||
new WorldAreaId(world, x+2, z-4),
|
||||
new WorldAreaId(world, x+3, z-4),
|
||||
|
||||
new WorldAreaId(world, x-4, z-3),
|
||||
new WorldAreaId(world, x-3, z-3),
|
||||
new WorldAreaId(world, x-2, z-3),
|
||||
new WorldAreaId(world, x-1, z-3),
|
||||
new WorldAreaId(world, x, z-3),
|
||||
new WorldAreaId(world, x+1, z-3),
|
||||
new WorldAreaId(world, x+2, z-3),
|
||||
new WorldAreaId(world, x+3, z-3),
|
||||
new WorldAreaId(world, x+4, z-3),
|
||||
|
||||
new WorldAreaId(world, x-5, z-2),
|
||||
new WorldAreaId(world, x-4, z-2),
|
||||
new WorldAreaId(world, x-3, z-2),
|
||||
new WorldAreaId(world, x-2, z-2),
|
||||
new WorldAreaId(world, x-1, z-2),
|
||||
new WorldAreaId(world, x, z-2),
|
||||
new WorldAreaId(world, x+1, z-2),
|
||||
new WorldAreaId(world, x+2, z-2),
|
||||
new WorldAreaId(world, x+3, z-2),
|
||||
new WorldAreaId(world, x+4, z-2),
|
||||
new WorldAreaId(world, x+5, z-2),
|
||||
|
||||
new WorldAreaId(world, x-5, z-1),
|
||||
new WorldAreaId(world, x-4, z-1),
|
||||
new WorldAreaId(world, x-3, z-1),
|
||||
new WorldAreaId(world, x-2, z-1),
|
||||
new WorldAreaId(world, x-1, z-1),
|
||||
new WorldAreaId(world, x, z-1),
|
||||
new WorldAreaId(world, x+1, z-1),
|
||||
new WorldAreaId(world, x+2, z-1),
|
||||
new WorldAreaId(world, x+3, z-1),
|
||||
new WorldAreaId(world, x+4, z-1),
|
||||
new WorldAreaId(world, x+5, z-1),
|
||||
|
||||
new WorldAreaId(world, x-5, z),
|
||||
new WorldAreaId(world, x-4, z),
|
||||
new WorldAreaId(world, x-3, z),
|
||||
new WorldAreaId(world, x-2, z),
|
||||
new WorldAreaId(world, x-1, z),
|
||||
this,
|
||||
new WorldAreaId(world, x+1, z),
|
||||
new WorldAreaId(world, x+2, z),
|
||||
new WorldAreaId(world, x+3, z),
|
||||
new WorldAreaId(world, x+4, z),
|
||||
new WorldAreaId(world, x+5, z),
|
||||
|
||||
new WorldAreaId(world, x-5, z+1),
|
||||
new WorldAreaId(world, x-4, z+1),
|
||||
new WorldAreaId(world, x-3, z+1),
|
||||
new WorldAreaId(world, x-2, z+1),
|
||||
new WorldAreaId(world, x-1, z+1),
|
||||
new WorldAreaId(world, x, z+1),
|
||||
new WorldAreaId(world, x+1, z+1),
|
||||
new WorldAreaId(world, x+2, z+1),
|
||||
new WorldAreaId(world, x+3, z+1),
|
||||
new WorldAreaId(world, x+4, z+1),
|
||||
new WorldAreaId(world, x+5, z+1),
|
||||
|
||||
new WorldAreaId(world, x-5, z+2),
|
||||
new WorldAreaId(world, x-4, z+2),
|
||||
new WorldAreaId(world, x-3, z+2),
|
||||
new WorldAreaId(world, x-2, z+2),
|
||||
new WorldAreaId(world, x-1, z+2),
|
||||
new WorldAreaId(world, x, z+2),
|
||||
new WorldAreaId(world, x+1, z+2),
|
||||
new WorldAreaId(world, x+2, z+2),
|
||||
new WorldAreaId(world, x+3, z+2),
|
||||
new WorldAreaId(world, x+4, z+2),
|
||||
new WorldAreaId(world, x+5, z+2),
|
||||
|
||||
new WorldAreaId(world, x-4, z+3),
|
||||
new WorldAreaId(world, x-3, z+3),
|
||||
new WorldAreaId(world, x-2, z+3),
|
||||
new WorldAreaId(world, x-1, z+3),
|
||||
new WorldAreaId(world, x, z+3),
|
||||
new WorldAreaId(world, x+1, z+3),
|
||||
new WorldAreaId(world, x+2, z+3),
|
||||
new WorldAreaId(world, x+3, z+3),
|
||||
new WorldAreaId(world, x+4, z+3),
|
||||
|
||||
new WorldAreaId(world, x-3, z+4),
|
||||
new WorldAreaId(world, x-2, z+4),
|
||||
new WorldAreaId(world, x-1, z+4),
|
||||
new WorldAreaId(world, x, z+4),
|
||||
new WorldAreaId(world, x+1, z+4),
|
||||
new WorldAreaId(world, x+2, z+4),
|
||||
new WorldAreaId(world, x+3, z+4),
|
||||
|
||||
new WorldAreaId(world, x-2, z+5),
|
||||
new WorldAreaId(world, x-1, z+5),
|
||||
new WorldAreaId(world, x, z+5),
|
||||
new WorldAreaId(world, x+1, z+5),
|
||||
new WorldAreaId(world, x+2, z+5),
|
||||
};
|
||||
return neighborhood;
|
||||
}
|
||||
|
||||
@@ -114,6 +114,7 @@ public class CachedMapsFile extends SynchronizedFile {
|
||||
private void load() {
|
||||
// Try to load maps from disk
|
||||
if (exists() && getLastModified() > imageFile.getLastModified()) {
|
||||
LOGGER.fine("Found warm cache file \"" + path + "\"");
|
||||
try {
|
||||
loadFromDisk();
|
||||
return;
|
||||
@@ -125,6 +126,7 @@ public class CachedMapsFile extends SynchronizedFile {
|
||||
}
|
||||
|
||||
// Generate maps from image file
|
||||
LOGGER.fine("Missed cache file \"" + path + "\"");
|
||||
try {
|
||||
generateFromImage();
|
||||
tryToWriteToDisk();
|
||||
|
||||
@@ -0,0 +1,326 @@
|
||||
package io.josemmo.bukkit.plugin.storage;
|
||||
|
||||
import com.sun.nio.file.ExtendedWatchEventModifier;
|
||||
import io.josemmo.bukkit.plugin.utils.Logger;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.*;
|
||||
import java.nio.file.attribute.BasicFileAttributes;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Service for detecting file events inside a given directory.
|
||||
* <p>
|
||||
* It supports recursive storage (<i>e.g.,</i> nested directories) and watches for file system changes in realtime
|
||||
* when supported by the OS.
|
||||
*/
|
||||
public abstract class FileSystemWatcher {
|
||||
private static final int MAX_DEPTH = 32;
|
||||
private static final int POLLING_INTERVAL = 4000;
|
||||
private static final String PROBE_FILENAME = ".inotify_test";
|
||||
private static final Logger LOGGER = Logger.getLogger("FileSystemWatcher");
|
||||
protected final Path basePath;
|
||||
/** Map of existing directories with the files they contain and their last modification timestamps */
|
||||
private final SortedMap<Path, Map<Path, Long>> fileTree = new TreeMap<>();
|
||||
private @Nullable Thread watcherThread;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
* @param basePath Base path
|
||||
*/
|
||||
public FileSystemWatcher(@NotNull Path basePath) {
|
||||
this.basePath = basePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start watcher
|
||||
* @throws RuntimeException if failed to start
|
||||
*/
|
||||
protected void start() throws RuntimeException {
|
||||
// Prevent initializing more than once
|
||||
if (watcherThread != null) {
|
||||
throw new RuntimeException("File system watcher is already running");
|
||||
}
|
||||
|
||||
// Perform initial scan
|
||||
scan();
|
||||
|
||||
// Start watching files
|
||||
watcherThread = new WatcherThread();
|
||||
watcherThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop watcher
|
||||
*/
|
||||
protected void stop() {
|
||||
if (watcherThread != null) {
|
||||
watcherThread.interrupt();
|
||||
watcherThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* On file created
|
||||
* @param path File path
|
||||
*/
|
||||
protected abstract void onFileCreated(@NotNull Path path);
|
||||
|
||||
/**
|
||||
* On file modified
|
||||
* @param path File path
|
||||
*/
|
||||
protected abstract void onFileModified(@NotNull Path path);
|
||||
|
||||
/**
|
||||
* On file deleted
|
||||
* @param path File path
|
||||
*/
|
||||
protected abstract void onFileDeleted(@NotNull Path path);
|
||||
|
||||
/**
|
||||
* Scan base directory recursively
|
||||
*/
|
||||
private void scan() {
|
||||
synchronized (fileTree) {
|
||||
// Assume all directories and files have been deleted, will discard existing items afterward
|
||||
Set<Path> deletedDirectories = new HashSet<>(fileTree.keySet());
|
||||
Set<Path> deletedFiles = fileTree.values().stream()
|
||||
.map(Map::keySet)
|
||||
.flatMap(Set::stream)
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
// Traverse file tree
|
||||
Set<FileVisitOption> options = EnumSet.noneOf(FileVisitOption.class);
|
||||
try {
|
||||
Files.walkFileTree(basePath, options, MAX_DEPTH, new SimpleFileVisitor<Path>() {
|
||||
@Override
|
||||
public FileVisitResult preVisitDirectory(Path path, BasicFileAttributes attrs) {
|
||||
fileTree.putIfAbsent(path, new HashMap<>());
|
||||
deletedDirectories.remove(path);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public FileVisitResult visitFile(Path path, BasicFileAttributes attrs) {
|
||||
Map<Path, Long> subtree = fileTree.get(path.getParent());
|
||||
Long oldModifiedAt = subtree.get(path);
|
||||
long newModifiedAt = attrs.lastModifiedTime().toMillis();
|
||||
if (oldModifiedAt == null) {
|
||||
subtree.put(path, newModifiedAt);
|
||||
onFileCreated(path);
|
||||
} else if (newModifiedAt > oldModifiedAt) {
|
||||
subtree.put(path, newModifiedAt);
|
||||
onFileModified(path);
|
||||
}
|
||||
deletedFiles.remove(path);
|
||||
return FileVisitResult.CONTINUE;
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
LOGGER.severe("Failed to list files in directory", e);
|
||||
}
|
||||
|
||||
// Process deleted files and directories
|
||||
for (Path path : deletedFiles) {
|
||||
fileTree.get(path.getParent()).remove(path);
|
||||
onFileDeleted(path);
|
||||
}
|
||||
for (Path path : deletedDirectories) {
|
||||
fileTree.remove(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class WatcherThread extends Thread {
|
||||
private final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("win");
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
if (isInotifySupported()) {
|
||||
runWithFileSystemEvents();
|
||||
} else {
|
||||
LOGGER.warning("Device does not support inotify, detection of file changes will be slower");
|
||||
runWithPolling();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Is inotify supported
|
||||
* @return Whether inotify is supported
|
||||
*/
|
||||
@SuppressWarnings("ResultOfMethodCallIgnored")
|
||||
private boolean isInotifySupported() {
|
||||
try (WatchService watchService = FileSystems.getDefault().newWatchService()) {
|
||||
// Start listening for events
|
||||
basePath.register(
|
||||
watchService,
|
||||
StandardWatchEventKinds.ENTRY_CREATE,
|
||||
StandardWatchEventKinds.ENTRY_DELETE,
|
||||
StandardWatchEventKinds.ENTRY_MODIFY
|
||||
);
|
||||
|
||||
// Create and delete probe directory
|
||||
File testFile = basePath.resolve(PROBE_FILENAME).toFile();
|
||||
testFile.mkdir();
|
||||
testFile.delete();
|
||||
|
||||
// Check that at least one event was emitted
|
||||
WatchKey watchKey = watchService.poll();
|
||||
return (watchKey != null && !watchKey.pollEvents().isEmpty());
|
||||
} catch (IOException __) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run with polling
|
||||
*/
|
||||
@SuppressWarnings({"InfiniteLoopStatement", "BusyWait"})
|
||||
private void runWithPolling() {
|
||||
try {
|
||||
while (true) {
|
||||
Thread.sleep(POLLING_INTERVAL);
|
||||
scan();
|
||||
}
|
||||
} catch (InterruptedException __) {
|
||||
// Silently ignore exception, this is expected when service shuts down
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Run with file system events
|
||||
*/
|
||||
private void runWithFileSystemEvents() {
|
||||
try (WatchService watchService = FileSystems.getDefault().newWatchService()) {
|
||||
// Register initial directories
|
||||
synchronized (fileTree) {
|
||||
for (Path path : fileTree.keySet()) {
|
||||
registerDirectory(watchService, path);
|
||||
}
|
||||
}
|
||||
|
||||
// Listen for events
|
||||
WatchKey key;
|
||||
try {
|
||||
while ((key = watchService.take()) != null) {
|
||||
for (WatchEvent<?> event : key.pollEvents()) {
|
||||
WatchEvent.Kind<?> kind = event.kind();
|
||||
Path keyPath = (Path) key.watchable();
|
||||
Path path = keyPath.resolve((Path) event.context());
|
||||
handleWatchEvent(watchService, path, kind);
|
||||
}
|
||||
key.reset();
|
||||
}
|
||||
} catch (ClosedWatchServiceException | InterruptedException __) {
|
||||
// Silently ignore exception, this is expected when service shuts down
|
||||
}
|
||||
} catch (IOException e) {
|
||||
LOGGER.severe("Unexpected error at watch service", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle watch event
|
||||
* @param watchService Watch service
|
||||
* @param path File or directory path
|
||||
* @param kind Event kind
|
||||
*/
|
||||
private void handleWatchEvent(@NotNull WatchService watchService, @NotNull Path path, @NotNull WatchEvent.Kind<?> kind) {
|
||||
synchronized (fileTree) {
|
||||
Map<Path, Long> subtree = fileTree.computeIfAbsent(path.getParent(), k -> new HashMap<>());
|
||||
|
||||
// Handle deletion of files and directories
|
||||
if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
|
||||
if (subtree.containsKey(path)) {
|
||||
subtree.remove(path);
|
||||
onFileDeleted(path);
|
||||
} else {
|
||||
unregisterDirectory(path);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle creation of directories
|
||||
if (path.toFile().isDirectory()) {
|
||||
if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
|
||||
registerDirectory(watchService, path);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle creation and modification of files
|
||||
// NOTE: in Windows, some file creation events are reported as modifications
|
||||
Long oldModifiedAt = subtree.get(path);
|
||||
long newModifiedAt = path.toFile().lastModified();
|
||||
if (oldModifiedAt == null) {
|
||||
subtree.put(path, newModifiedAt);
|
||||
onFileCreated(path);
|
||||
} else if (newModifiedAt > oldModifiedAt) {
|
||||
subtree.put(path, newModifiedAt);
|
||||
onFileModified(path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register directory
|
||||
* @param watchService Watch service
|
||||
* @param path Directory path
|
||||
*/
|
||||
private void registerDirectory(@NotNull WatchService watchService, @NotNull Path path) {
|
||||
// Windows supports listing to events in the entire file tree,
|
||||
// in that case only allow registering the listener on the base path
|
||||
if (IS_WINDOWS && !path.equals(basePath)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Start watching directory for events
|
||||
try {
|
||||
WatchEvent.Kind<?>[] events = new WatchEvent.Kind[]{
|
||||
StandardWatchEventKinds.ENTRY_CREATE,
|
||||
StandardWatchEventKinds.ENTRY_DELETE,
|
||||
StandardWatchEventKinds.ENTRY_MODIFY
|
||||
};
|
||||
WatchEvent.Modifier[] modifiers = IS_WINDOWS ?
|
||||
new WatchEvent.Modifier[]{ExtendedWatchEventModifier.FILE_TREE} :
|
||||
new WatchEvent.Modifier[0];
|
||||
path.register(watchService, events, modifiers);
|
||||
LOGGER.fine("Started watching directory at \"" + path + "\"");
|
||||
} catch (IOException e) {
|
||||
LOGGER.severe("Failed to register directory", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister directory
|
||||
* @param path Directory path
|
||||
*/
|
||||
private void unregisterDirectory(@NotNull Path path) {
|
||||
synchronized (fileTree) {
|
||||
if (!fileTree.containsKey(path)) {
|
||||
// Already unregistered, can skip work
|
||||
return;
|
||||
}
|
||||
boolean foundFirst = false;
|
||||
Iterator<Map.Entry<Path, Map<Path, Long>>> iter = fileTree.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
Map.Entry<Path, Map<Path, Long>> entry = iter.next();
|
||||
if (entry.getKey().startsWith(path)) {
|
||||
for (Path childPath : entry.getValue().keySet()) {
|
||||
onFileDeleted(childPath);
|
||||
}
|
||||
foundFirst = true;
|
||||
iter.remove();
|
||||
} else if (foundFirst) {
|
||||
// We can break early because set is alphabetically sorted by key
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,11 @@
|
||||
package io.josemmo.bukkit.plugin.storage;
|
||||
|
||||
import com.sun.nio.file.ExtendedWatchEventModifier;
|
||||
import io.josemmo.bukkit.plugin.utils.Logger;
|
||||
import io.josemmo.bukkit.plugin.utils.Permissions;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.*;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
@@ -16,23 +13,18 @@ import java.util.regex.Pattern;
|
||||
import java.util.regex.PatternSyntaxException;
|
||||
|
||||
/**
|
||||
* A service whose purpose is to keep track of all available image files in a given directory.
|
||||
* It supports recursive storage (<i>e.g.</i>, nested directories) and watches for file system changes in realtime.
|
||||
* Service for keeping track of image images.
|
||||
* <p>
|
||||
* All files are indexed based on their <b>filename</b>.
|
||||
* Due to recursion, filenames can contain forward slashes (<i>i.e.</i>, "/") and act as relative paths to the base
|
||||
* Due to recursion, filenames can contain forward slashes (<i>i.e.,</i> "/") and act as relative paths to the base
|
||||
* directory.
|
||||
*/
|
||||
public class ImageStorage {
|
||||
private static final boolean IS_WINDOWS = System.getProperty("os.name").toLowerCase(Locale.ROOT).contains("win");
|
||||
public class ImageStorage extends FileSystemWatcher {
|
||||
private static final Logger LOGGER = Logger.getLogger("ImageStorage");
|
||||
/** Map of registered files indexed by filename */
|
||||
private final SortedMap<String, ImageFile> files = new TreeMap<>();
|
||||
private final Path basePath;
|
||||
private final Path cachePath;
|
||||
private final String allowedPaths;
|
||||
private @Nullable WatchService watchService;
|
||||
private @Nullable Thread watchServiceThread;
|
||||
|
||||
/**
|
||||
* Class constructor
|
||||
@@ -41,7 +33,7 @@ public class ImageStorage {
|
||||
* @param allowedPaths Allowed paths pattern
|
||||
*/
|
||||
public ImageStorage(@NotNull Path basePath, @NotNull Path cachePath, @NotNull String allowedPaths) {
|
||||
this.basePath = basePath;
|
||||
super(basePath);
|
||||
this.cachePath = cachePath;
|
||||
this.allowedPaths = allowedPaths;
|
||||
}
|
||||
@@ -64,15 +56,10 @@ public class ImageStorage {
|
||||
|
||||
/**
|
||||
* Start service
|
||||
* @throws IOException if failed to start watch service
|
||||
* @throws RuntimeException if already running
|
||||
* @throws RuntimeException if failed to start watch service
|
||||
*/
|
||||
public void start() throws IOException, RuntimeException {
|
||||
// Prevent initializing more than once
|
||||
if (watchService != null || watchServiceThread != null) {
|
||||
throw new RuntimeException("Service is already running");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws RuntimeException {
|
||||
// Create base directories if necessary
|
||||
if (basePath.toFile().mkdirs()) {
|
||||
LOGGER.info("Created images directory as it did not exist");
|
||||
@@ -81,33 +68,17 @@ public class ImageStorage {
|
||||
LOGGER.info("Created cache directory as it did not exist");
|
||||
}
|
||||
|
||||
// Start watching files
|
||||
watchService = FileSystems.getDefault().newWatchService();
|
||||
watchServiceThread = new WatcherThread();
|
||||
watchServiceThread.start();
|
||||
registerDirectory(basePath, true);
|
||||
// Start file system watcher
|
||||
super.start();
|
||||
LOGGER.fine("Found " + files.size() + " file(s) in images directory");
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop service
|
||||
*/
|
||||
@Override
|
||||
public void stop() {
|
||||
// Interrupt watch service thread
|
||||
if (watchServiceThread != null) {
|
||||
watchServiceThread.interrupt();
|
||||
watchServiceThread = null;
|
||||
}
|
||||
|
||||
// Close watch service
|
||||
if (watchService != null) {
|
||||
try {
|
||||
watchService.close();
|
||||
} catch (IOException e) {
|
||||
LOGGER.warning("Failed to close watch service", e);
|
||||
}
|
||||
watchService = null;
|
||||
}
|
||||
super.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,7 +111,7 @@ public class ImageStorage {
|
||||
* @return Whether sender is allowed to access path
|
||||
*/
|
||||
public boolean isPathAllowed(@NotNull Path path, @NotNull CommandSender sender) {
|
||||
return isPathAllowed(getFilename(path), sender);
|
||||
return isPathAllowed(pathToFilename(path), sender);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -191,58 +162,20 @@ public class ImageStorage {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register directory
|
||||
* @param path Path to directory
|
||||
* @param isBase Whether is base directory or not
|
||||
* Convert path to filename
|
||||
* @param path File path
|
||||
* @return Relative path used for indexing
|
||||
*/
|
||||
private synchronized void registerDirectory(@NotNull Path path, boolean isBase) {
|
||||
// Validate path
|
||||
if (!Files.isDirectory(path, LinkOption.NOFOLLOW_LINKS)) {
|
||||
LOGGER.warning("Cannot list files in \"" + path + "\" as it is not a valid directory");
|
||||
return;
|
||||
}
|
||||
|
||||
// Do initial directory listing
|
||||
for (File child : Objects.requireNonNull(path.toFile().listFiles())) {
|
||||
if (child.isDirectory()) {
|
||||
registerDirectory(child.toPath(), false);
|
||||
} else {
|
||||
registerFile(child.toPath());
|
||||
}
|
||||
}
|
||||
|
||||
// Start watching for files changes
|
||||
if (!IS_WINDOWS || isBase) {
|
||||
try {
|
||||
WatchEvent.Kind<?>[] events = new WatchEvent.Kind[]{
|
||||
StandardWatchEventKinds.ENTRY_CREATE,
|
||||
StandardWatchEventKinds.ENTRY_DELETE,
|
||||
StandardWatchEventKinds.ENTRY_MODIFY
|
||||
};
|
||||
WatchEvent.Modifier[] modifiers = IS_WINDOWS ?
|
||||
new WatchEvent.Modifier[]{ExtendedWatchEventModifier.FILE_TREE} :
|
||||
new WatchEvent.Modifier[0];
|
||||
path.register(Objects.requireNonNull(watchService), events, modifiers);
|
||||
LOGGER.fine("Started watching directory at \"" + path + "\"");
|
||||
} catch (IOException | NullPointerException e) {
|
||||
LOGGER.severe("Failed to register directory", e);
|
||||
}
|
||||
}
|
||||
private @NotNull String pathToFilename(@NotNull Path path) {
|
||||
return basePath.relativize(path).toString().replaceAll("\\\\", "/");
|
||||
}
|
||||
|
||||
/**
|
||||
* Register file
|
||||
* @param path Path to file
|
||||
* On file created
|
||||
* @param path File path
|
||||
*/
|
||||
private synchronized void registerFile(@NotNull Path path) {
|
||||
// Validate path
|
||||
if (!Files.isRegularFile(path, LinkOption.NOFOLLOW_LINKS)) {
|
||||
LOGGER.warning("Cannot register \"" + path + "\" as it is not a valid file");
|
||||
return;
|
||||
}
|
||||
|
||||
// Add file to map
|
||||
String filename = getFilename(path);
|
||||
protected synchronized void onFileCreated(@NotNull Path path) {
|
||||
String filename = pathToFilename(path);
|
||||
ImageFile imageFile = new ImageFile(filename, path);
|
||||
if (files.putIfAbsent(filename, imageFile) == null) {
|
||||
LOGGER.fine("Registered file \"" + filename + "\"");
|
||||
@@ -250,113 +183,28 @@ public class ImageStorage {
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister directory
|
||||
* @param filename Filename to directory
|
||||
* On file modified
|
||||
* @param path File path
|
||||
*/
|
||||
private synchronized void unregisterDirectory(@NotNull String filename) {
|
||||
boolean foundFirst = false;
|
||||
Iterator<Map.Entry<String, ImageFile>> iter = files.entrySet().iterator();
|
||||
while (iter.hasNext()) {
|
||||
String entryKey = iter.next().getKey();
|
||||
if (entryKey.startsWith(filename+"/")) {
|
||||
foundFirst = true;
|
||||
iter.remove();
|
||||
LOGGER.fine("Unregistered file \"" + entryKey + "\"");
|
||||
} else if (foundFirst) {
|
||||
// We can break early because set is alphabetically sorted by key
|
||||
break;
|
||||
}
|
||||
protected synchronized void onFileModified(@NotNull Path path) {
|
||||
String filename = pathToFilename(path);
|
||||
ImageFile imageFile = files.get(filename);
|
||||
if (imageFile != null) {
|
||||
imageFile.invalidate();
|
||||
LOGGER.fine("Invalidated file \"" + filename + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister file
|
||||
* @param filename Filename to file
|
||||
* On file deleted
|
||||
* @param path File path
|
||||
*/
|
||||
private synchronized void unregisterFile(@NotNull String filename) {
|
||||
protected synchronized void onFileDeleted(@NotNull Path path) {
|
||||
String filename = pathToFilename(path);
|
||||
ImageFile imageFile = files.remove(filename);
|
||||
if (imageFile != null) {
|
||||
imageFile.invalidate();
|
||||
LOGGER.fine("Unregistered file \"" + filename + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate file
|
||||
* @param filename Filename to file
|
||||
*/
|
||||
private synchronized void invalidateFile(@NotNull String filename) {
|
||||
ImageFile imageFile = files.get(filename);
|
||||
if (imageFile != null) {
|
||||
imageFile.invalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle watch event
|
||||
* @param path Path to file or directory
|
||||
* @param kind Event kind
|
||||
*/
|
||||
private synchronized void handleWatchEvent(@NotNull Path path, WatchEvent.Kind<?> kind) {
|
||||
// Check whether file currently exists in file system (for CREATE and UPDATE events)
|
||||
// or is registered in the file list (for DELETE event)
|
||||
String filename = getFilename(path);
|
||||
boolean isFile = path.toFile().isFile() || files.containsKey(filename);
|
||||
|
||||
// Handle creation event
|
||||
if (kind == StandardWatchEventKinds.ENTRY_CREATE) {
|
||||
if (isFile) {
|
||||
registerFile(path);
|
||||
} else {
|
||||
registerDirectory(path, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle deletion event
|
||||
if (kind == StandardWatchEventKinds.ENTRY_DELETE) {
|
||||
if (isFile) {
|
||||
unregisterFile(filename);
|
||||
} else {
|
||||
unregisterDirectory(filename);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle modification event
|
||||
if (kind == StandardWatchEventKinds.ENTRY_MODIFY && isFile) {
|
||||
invalidateFile(filename);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get filename from path
|
||||
* @param path Path to file
|
||||
* @return Relative path used for indexing
|
||||
*/
|
||||
private @NotNull String getFilename(@NotNull Path path) {
|
||||
return basePath.relativize(path).toString().replaceAll("\\\\", "/");
|
||||
}
|
||||
|
||||
private class WatcherThread extends Thread {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
WatchKey key;
|
||||
while ((key = Objects.requireNonNull(watchService).take()) != null) {
|
||||
for (WatchEvent<?> event : key.pollEvents()) {
|
||||
WatchEvent.Kind<?> kind = event.kind();
|
||||
Path keyPath = (Path) key.watchable();
|
||||
Path path = keyPath.resolve((Path) event.context());
|
||||
handleWatchEvent(path, kind);
|
||||
}
|
||||
key.reset();
|
||||
}
|
||||
} catch (ClosedWatchServiceException | InterruptedException __) {
|
||||
// Silently ignore exception, this is expected when service shuts down
|
||||
} catch (NullPointerException e) {
|
||||
LOGGER.severe("Watch service was stopped before watcher thread", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,9 @@ import org.jetbrains.annotations.Blocking;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import java.io.IOException;
|
||||
import java.io.RandomAccessFile;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.nio.channels.FileLock;
|
||||
import java.nio.channels.OverlappingFileLockException;
|
||||
import java.nio.file.Path;
|
||||
|
||||
/**
|
||||
@@ -17,10 +20,29 @@ public class SynchronizedFileStream extends RandomAccessFile {
|
||||
* @param readOnly Whether to open stream in read-only mode
|
||||
* @throws IOException if failed to acquire lock
|
||||
*/
|
||||
@Blocking
|
||||
public SynchronizedFileStream(@NotNull Path path, boolean readOnly) throws IOException {
|
||||
super(path.toFile(), readOnly ? "r" : "rw");
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
getChannel().lock(0L, Long.MAX_VALUE, readOnly);
|
||||
waitForLock(readOnly);
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for lock to be released
|
||||
* @param readOnly Whether to acquire read-only (shared) lock
|
||||
*/
|
||||
@Blocking
|
||||
private void waitForLock(boolean readOnly) throws IOException {
|
||||
FileChannel channel = getChannel();
|
||||
FileLock lock = null;
|
||||
while (lock == null) {
|
||||
try {
|
||||
lock = channel.lock(0L, Long.MAX_VALUE, readOnly);
|
||||
} catch (OverlappingFileLockException e) {
|
||||
try {
|
||||
Thread.sleep(20);
|
||||
} catch (InterruptedException __) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,7 @@ import org.bukkit.Server;
|
||||
import org.bukkit.command.CommandMap;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@@ -13,7 +14,7 @@ public class Internals {
|
||||
public static final float MINECRAFT_VERSION;
|
||||
private static final CommandDispatcher<?> DISPATCHER;
|
||||
private static final CommandMap COMMAND_MAP;
|
||||
private static final Method GET_BUKKIT_SENDER_METHOD;
|
||||
private static @Nullable Method GET_BUKKIT_SENDER_METHOD = null;
|
||||
|
||||
static {
|
||||
try {
|
||||
@@ -30,24 +31,30 @@ public class Internals {
|
||||
Object nmsInstance = obcClass.getDeclaredMethod("getServer").invoke(obcInstance);
|
||||
Class<?> nmsClass = nmsInstance.getClass().getSuperclass();
|
||||
|
||||
// Get "net.minecraft.server.CommandDispatcher" references
|
||||
Object nmsDispatcherInstance = nmsClass.getDeclaredField("vanillaCommandDispatcher").get(nmsInstance);
|
||||
Class<?> nmsDispatcherClass = nmsDispatcherInstance.getClass();
|
||||
if (MINECRAFT_VERSION >= 20.6) {
|
||||
// Get "net.minecraft.commands.Commands" references
|
||||
Object nmsCommandsInstance = nmsClass.getDeclaredMethod("getCommands").invoke(nmsInstance);
|
||||
Class<?> nmsCommandsClass = nmsCommandsInstance.getClass();
|
||||
|
||||
// Get Brigadier dispatcher instance
|
||||
Method getDispatcherMethod = nmsDispatcherClass.getDeclaredMethod("a");
|
||||
getDispatcherMethod.setAccessible(true);
|
||||
DISPATCHER = (CommandDispatcher<?>) getDispatcherMethod.invoke(nmsDispatcherInstance);
|
||||
// Get "com.mojang.brigadier.CommandDispatcher" instance
|
||||
Field nmsDispatcherField = nmsCommandsClass.getDeclaredField("dispatcher");
|
||||
nmsDispatcherField.setAccessible(true);
|
||||
DISPATCHER = (CommandDispatcher<?>) nmsDispatcherField.get(nmsCommandsInstance);
|
||||
} else {
|
||||
// Get "net.minecraft.server.CommandDispatcher" references
|
||||
Object nmsDispatcherInstance = nmsClass.getDeclaredField("vanillaCommandDispatcher").get(nmsInstance);
|
||||
Class<?> nmsDispatcherClass = nmsDispatcherInstance.getClass();
|
||||
|
||||
// Get "com.mojang.brigadier.CommandDispatcher" instance
|
||||
Method getDispatcherMethod = nmsDispatcherClass.getDeclaredMethod("a");
|
||||
getDispatcherMethod.setAccessible(true);
|
||||
DISPATCHER = (CommandDispatcher<?>) getDispatcherMethod.invoke(nmsDispatcherInstance);
|
||||
}
|
||||
|
||||
// Get command map instance
|
||||
Field commandMapField = obcClass.getDeclaredField("commandMap");
|
||||
commandMapField.setAccessible(true);
|
||||
COMMAND_MAP = (CommandMap) commandMapField.get(obcInstance);
|
||||
|
||||
// Get CommandListenerWrapper.getBukkitSender() method
|
||||
Class<?> clwClass = Class.forName(nmsDispatcherClass.getPackage().getName() + ".CommandListenerWrapper");
|
||||
GET_BUKKIT_SENDER_METHOD = clwClass.getDeclaredMethod("getBukkitSender");
|
||||
GET_BUKKIT_SENDER_METHOD.setAccessible(true);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to get internal classes due to incompatible Minecraft server", e);
|
||||
}
|
||||
@@ -76,9 +83,12 @@ public class Internals {
|
||||
*/
|
||||
public static @NotNull CommandSender getBukkitSender(@NotNull Object source) {
|
||||
try {
|
||||
if (GET_BUKKIT_SENDER_METHOD == null) {
|
||||
GET_BUKKIT_SENDER_METHOD = source.getClass().getDeclaredMethod("getBukkitSender");
|
||||
}
|
||||
return (CommandSender) GET_BUKKIT_SENDER_METHOD.invoke(source);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException("Failed to extract bukkit sender from source", e);
|
||||
throw new RuntimeException("Failed to extract Bukkit sender from source", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,14 @@ main: io.josemmo.bukkit.plugin.YamipaPlugin
|
||||
api-version: 1.16
|
||||
depend: [ProtocolLib]
|
||||
softdepend:
|
||||
- BentoBox
|
||||
- GriefPrevention
|
||||
- GroupManager
|
||||
- Hyperverse
|
||||
- LuckPerms
|
||||
- Multiverse-Core
|
||||
- My_Worlds
|
||||
- PhantomWorlds
|
||||
- Towny
|
||||
- WorldGuard
|
||||
|
||||
|
||||
Reference in new issue
Block a user