Compare commits

..

9 Commits

159 changed files with 2751 additions and 1622 deletions

View File

@ -8,7 +8,7 @@ body:
value: | value: |
Thanks for taking the time to fill out this bug report for PlotSquared! Fill out the following form to your best ability to help us fix the problem. Thanks for taking the time to fill out this bug report for PlotSquared! Fill out the following form to your best ability to help us fix the problem.
Only use this if you're absolutely sure that you found a bug and can reproduce it. For anything else, use: [our Discord server](https://discord.gg/intellectualsites) or [the wiki](https://intellectualsites.github.io/plotsquared-documentation/). Only use this if you're absolutely sure that you found a bug and can reproduce it. For anything else, use: [our Discord server](https://discord.gg/intellectualsites) or [the wiki](https://intellectualsites.github.io/plotsquared-documentation/).
Do NOT use the public issue tracker to report security vulnerabilities! They are disclosed using [this](https://github.com/IntellectualSites/PlotSquared/security/policy) GitHub form! Do NOT use the public issue tracker to report security vulnerabilities! They are disclosed using [this](https://forms.gle/btgdRn9yhGtzEiGW8) form!
- type: dropdown - type: dropdown
attributes: attributes:
@ -27,9 +27,6 @@ body:
description: Which server version version you using? If your server version is not listed, it is not supported. Update to a supported version first. description: Which server version version you using? If your server version is not listed, it is not supported. Update to a supported version first.
multiple: false multiple: false
options: options:
- '1.20.1'
- '1.20'
- '1.19.4'
- '1.19.3' - '1.19.3'
- '1.19.2' - '1.19.2'
- '1.19.1' - '1.19.1'

View File

@ -2,6 +2,7 @@ name: Announce release on discord
on: on:
release: release:
types: [published] types: [published]
jobs: jobs:
send_announcement: send_announcement:
runs-on: ubuntu-latest runs-on: ubuntu-latest

View File

@ -1,5 +1,7 @@
name: Build PR name: Build PR
on: [ pull_request ] on: [ pull_request ]
jobs: jobs:
build_pr: build_pr:
if: github.repository_owner == 'IntellectualSites' if: github.repository_owner == 'IntellectualSites'

View File

@ -1,8 +1,10 @@
name: build name: build
on: on:
push: push:
branches: branches:
- main - v7
jobs: jobs:
build: build:
if: github.repository_owner == 'IntellectualSites' if: github.repository_owner == 'IntellectualSites'
@ -28,7 +30,7 @@ jobs:
echo "STATUS=release" >> $GITHUB_ENV echo "STATUS=release" >> $GITHUB_ENV
fi fi
- name: Publish Release - name: Publish Release
if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main'}} if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v7'}}
run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository
env: env:
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }} ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }}
@ -36,13 +38,14 @@ jobs:
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGNING_KEY }} ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGNING_KEY }}
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGNING_PASSWORD }} ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGNING_PASSWORD }}
- name: Publish Snapshot - name: Publish Snapshot
if: ${{ runner.os == 'Linux' && env.STATUS != 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main' }} if: ${{ runner.os == 'Linux' && env.STATUS != 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v7' }}
run: ./gradlew publishToSonatype run: ./gradlew publishToSonatype
env: env:
ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }} ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }}
ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }} ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }}
- name: Publish core javadoc - name: Publish core javadoc
# if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main'}} # if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v7'}}
if: ${{ runner.os == 'Linux' && env.STATUS == 'snapshot' && github.event_name == 'push' && github.ref == 'refs/heads/v7'}}
uses: cpina/github-action-push-to-another-repository@main uses: cpina/github-action-push-to-another-repository@main
env: env:
SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }} SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
@ -54,7 +57,8 @@ jobs:
target-branch: main target-branch: main
target-directory: v7/core target-directory: v7/core
- name: Publish bukkit javadoc - name: Publish bukkit javadoc
# if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main'}} # if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v7'}}
if: ${{ runner.os == 'Linux' && env.STATUS == 'snapshot' && github.event_name == 'push' && github.ref == 'refs/heads/v7'}}
uses: cpina/github-action-push-to-another-repository@main uses: cpina/github-action-push-to-another-repository@main
env: env:
SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }} SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}

View File

@ -1,10 +1,11 @@
name: "CodeQL" name: "CodeQL"
on: on:
push: push:
branches: [ main ] branches: [ v7 ]
pull_request: pull_request:
# The branches below must be a subset of the branches above # The branches below must be a subset of the branches above
branches: [ main ] branches: [ v7 ]
jobs: jobs:
analyze: analyze:
@ -14,23 +15,23 @@ jobs:
actions: read actions: read
contents: read contents: read
security-events: write security-events: write
strategy: strategy:
fail-fast: false fail-fast: false
matrix: matrix:
language: [ 'java' ] language: [ 'java' ]
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v3 uses: actions/checkout@v3
- name: Setup Java
uses: actions/setup-java@v3
with:
distribution: temurin
java-version: 17
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v2 uses: github/codeql-action/init@v2
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v2 uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v2 uses: github/codeql-action/analyze@v2

View File

@ -1,12 +1,14 @@
name: draft release name: draft release
on: on:
push: push:
branches: branches:
- main - v6
pull_request: pull_request:
types: [ opened, reopened, synchronize ] types: [ opened, reopened, synchronize ]
pull_request_target: pull_request_target:
types: [ opened, reopened, synchronize ] types: [ opened, reopened, synchronize ]
jobs: jobs:
update_release_draft: update_release_draft:
if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }} if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}

4
.gitignore vendored
View File

@ -137,7 +137,3 @@ docs/
build/ build/
.DS_Store .DS_Store
# Ignore run folders
run-[0-0].[0-9]/
run-[0-0].[0-9].[0-9]/

154
.idea/icon.svg generated
View File

@ -1,144 +1,48 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg <svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" version="1.1" id="svg2" xml:space="preserve" width="4000" height="3333.3333" viewBox="0 0 4000 3333.3333" sodipodi:docname="PlotSquared.ai">
version="1.1" <metadata id="metadata8">
id="svg2"
xml:space="preserve"
width="512"
height="512"
viewBox="0 0 512 512.00001"
sodipodi:docname="icon.svg"
inkscape:version="1.1.2 (b8e25be8, 2022-02-05)"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/">
<metadata
id="metadata8">
<rdf:RDF> <rdf:RDF>
<cc:Work <cc:Work rdf:about="">
rdf:about="">
<dc:format>image/svg+xml</dc:format> <dc:format>image/svg+xml</dc:format>
<dc:type <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
</cc:Work> </cc:Work>
</rdf:RDF> </rdf:RDF>
</metadata> </metadata>
<defs <defs id="defs6">
id="defs6"> <clipPath clipPathUnits="userSpaceOnUse" id="clipPath18">
<clipPath <path d="M 0,2500 H 3000 V 0 H 0 Z" id="path16" />
clipPathUnits="userSpaceOnUse"
id="clipPath18">
<path
d="M 0,2500 H 3000 V 0 H 0 Z"
id="path16" />
</clipPath> </clipPath>
</defs> </defs>
<sodipodi:namedview <sodipodi:namedview pagecolor="#ffffff" bordercolor="#666666" borderopacity="1" objecttolerance="10" gridtolerance="10" guidetolerance="10" inkscape:pageopacity="0" inkscape:pageshadow="2" inkscape:window-width="640" inkscape:window-height="480" id="namedview4" />
pagecolor="#ffffff" <g id="g10" inkscape:groupmode="layer" inkscape:label="PlotSquared" transform="matrix(1.3333333,0,0,-1.3333333,0,3333.3333)">
bordercolor="#666666" <g id="g12">
borderopacity="1" <g id="g14" clip-path="url(#clipPath18)">
objecttolerance="10" <g id="g20" transform="translate(1486.1511,2242.6453)">
gridtolerance="10" <path d="m 0,0 c 16.533,10.846 33.211,21.453 50.104,31.699 78.972,-48.281 153.985,-102.704 227.269,-159.144 148.61,-115.422 287.884,-243.01 414.393,-382.333 111.39,-122.861 212.751,-255.152 298.898,-396.971 52.744,-87.322 100.544,-177.884 139.514,-272.214 -11.638,-3.551 -23.108,-7.655 -34.362,-12.286 l -0.24,0.288 c -11.135,12.982 -24.141,24.212 -34.915,37.506 -22.557,23.013 -45.425,45.737 -68.03,68.678 -19.725,20.253 -40.601,39.45 -58.958,60.974 -36.355,36.451 -72.517,73.093 -108.944,109.471 -22.628,26.013 -48.064,49.385 -71.965,74.197 -19.029,19.485 -38.706,38.346 -57.519,57.999 -12.166,14.998 -26.684,27.716 -39.93,41.658 -27.668,27.524 -54.903,55.479 -82.571,82.979 -23.924,27.956 -51.664,52.264 -76.692,79.164 -4.68,4.487 -8.855,10.774 -15.886,11.326 -22.34,34.027 -58.311,57.327 -97.377,67.502 -104.312,99.153 -215.487,191.202 -332.661,274.782 -117.942,-83.94 -229.476,-176.781 -334.484,-276.39 -26.684,-0.024 -53.368,0.024 -80.076,-0.024 0.024,-26.564 0.048,-53.104 0,-79.668 -72.229,-73.021 -139.491,-150.937 -202.385,-232.092 -63.758,-82.619 -121.973,-169.51 -173.541,-260.264 131.932,-69.061 257.864,-149.521 375.926,-240.275 0.096,-26.444 -0.12,-52.888 0.096,-79.332 l 0.744,-0.984 c 20.109,-24.14 43.409,-45.233 65.126,-67.861 15.118,-15.382 30.571,-30.404 45.569,-45.881 17.565,-20.733 37.698,-39.042 56.607,-58.503 19.917,-20.781 41.25,-40.218 59.967,-62.151 29.156,-29.299 58.167,-58.815 87.515,-87.922 29.155,-33.043 61.502,-63.111 92.169,-94.738 13.726,-12.67 25.124,-27.571 38.634,-40.457 25.029,-25.365 50.129,-50.657 75.325,-75.853 -37.914,-51.208 -73.741,-103.952 -107.192,-158.183 -167.83,273.317 -397.235,507.305 -662.37,687.158 -81.875,55.335 -167.23,105.584 -255.681,149.641 -52.815,26.276 -106.831,50.248 -162.239,70.381 99.393,233.628 242.795,446.715 410.289,636.79 93.562,106.088 194.634,205.433 301.466,298.13 C -217.335,-155.808 -111.439,-73.789 0,0" style="fill:#062f4c;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path22" />
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1440"
inkscape:window-height="900"
id="namedview4"
inkscape:pagecheckerboard="0"
showgrid="false"
inkscape:zoom="0.1632"
inkscape:cx="1087.6225"
inkscape:cy="1666.6666"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
inkscape:current-layer="g10" />
<g
id="g10"
inkscape:groupmode="layer"
inkscape:label="PlotSquared"
transform="matrix(1.3333333,0,0,-1.3333333,0,3333.3333)">
<g
id="g12"
transform="matrix(0.16955078,0,0,0.16955078,-68.456969,2101.8529)">
<g
id="g14"
clip-path="url(#clipPath18)">
<g
id="g20"
transform="translate(1486.1511,2242.6453)">
<path
d="m 0,0 c 16.533,10.846 33.211,21.453 50.104,31.699 78.972,-48.281 153.985,-102.704 227.269,-159.144 148.61,-115.422 287.884,-243.01 414.393,-382.333 111.39,-122.861 212.751,-255.152 298.898,-396.971 52.744,-87.322 100.544,-177.884 139.514,-272.214 -11.638,-3.551 -23.108,-7.655 -34.362,-12.286 l -0.24,0.288 c -11.135,12.982 -24.141,24.212 -34.915,37.506 -22.557,23.013 -45.425,45.737 -68.03,68.678 -19.725,20.253 -40.601,39.45 -58.958,60.974 -36.355,36.451 -72.517,73.093 -108.944,109.471 -22.628,26.013 -48.064,49.385 -71.965,74.197 -19.029,19.485 -38.706,38.346 -57.519,57.999 -12.166,14.998 -26.684,27.716 -39.93,41.658 -27.668,27.524 -54.903,55.479 -82.571,82.979 -23.924,27.956 -51.664,52.264 -76.692,79.164 -4.68,4.487 -8.855,10.774 -15.886,11.326 -22.34,34.027 -58.311,57.327 -97.377,67.502 -104.312,99.153 -215.487,191.202 -332.661,274.782 -117.942,-83.94 -229.476,-176.781 -334.484,-276.39 -26.684,-0.024 -53.368,0.024 -80.076,-0.024 0.024,-26.564 0.048,-53.104 0,-79.668 -72.229,-73.021 -139.491,-150.937 -202.385,-232.092 -63.758,-82.619 -121.973,-169.51 -173.541,-260.264 131.932,-69.061 257.864,-149.521 375.926,-240.275 0.096,-26.444 -0.12,-52.888 0.096,-79.332 l 0.744,-0.984 c 20.109,-24.14 43.409,-45.233 65.126,-67.861 15.118,-15.382 30.571,-30.404 45.569,-45.881 17.565,-20.733 37.698,-39.042 56.607,-58.503 19.917,-20.781 41.25,-40.218 59.967,-62.151 29.156,-29.299 58.167,-58.815 87.515,-87.922 29.155,-33.043 61.502,-63.111 92.169,-94.738 13.726,-12.67 25.124,-27.571 38.634,-40.457 25.029,-25.365 50.129,-50.657 75.325,-75.853 -37.914,-51.208 -73.741,-103.952 -107.192,-158.183 -167.83,273.317 -397.235,507.305 -662.37,687.158 -81.875,55.335 -167.23,105.584 -255.681,149.641 -52.815,26.276 -106.831,50.248 -162.239,70.381 99.393,233.628 242.795,446.715 410.289,636.79 93.562,106.088 194.634,205.433 301.466,298.13 C -217.335,-155.808 -111.439,-73.789 0,0"
style="fill:#062f4c;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path22" />
</g> </g>
<g <g id="g24" transform="translate(1201.7948,1741.5303)">
id="g24" <path d="M 0,0 C 105.008,99.609 216.543,192.45 334.485,276.39 451.659,192.81 562.833,100.76 667.146,1.608 c -34.987,8.83 -71.51,9.718 -107.264,6.431 -41.202,-4.296 -82.907,-19.077 -112.543,-48.953 -33.019,-32.155 -49.456,-77.604 -55.311,-122.501 -28.124,27.908 -56.104,55.983 -84.035,84.083 -2.976,2.976 -6.839,4.823 -10.391,6.911 -19.029,26.348 -45.953,46.673 -76.62,57.495 C 187.555,-2.472 151.513,-0.12 116.166,0 Z" style="fill:#4c8fcc;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path26" />
transform="translate(1201.7948,1741.5303)">
<path
d="M 0,0 C 105.008,99.609 216.543,192.45 334.485,276.39 451.659,192.81 562.833,100.76 667.146,1.608 c -34.987,8.83 -71.51,9.718 -107.264,6.431 -41.202,-4.296 -82.907,-19.077 -112.543,-48.953 -33.019,-32.155 -49.456,-77.604 -55.311,-122.501 -28.124,27.908 -56.104,55.983 -84.035,84.083 -2.976,2.976 -6.839,4.823 -10.391,6.911 -19.029,26.348 -45.953,46.673 -76.62,57.495 C 187.555,-2.472 151.513,-0.12 116.166,0 Z"
style="fill:#4c8fcc;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path26" />
</g> </g>
<g <g id="g28" transform="translate(919.3342,1429.7462)">
id="g28" <path d="m 0,0 c 62.894,81.156 130.156,159.072 202.385,232.092 0.048,-244.21 0.024,-488.421 0,-732.631 C 84.323,-409.785 -41.61,-329.325 -173.541,-260.264 -121.973,-169.51 -63.758,-82.619 0,0" style="fill:#4c8fcc;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path30" />
transform="translate(919.3342,1429.7462)">
<path
d="m 0,0 c 62.894,81.156 130.156,159.072 202.385,232.092 0.048,-244.21 0.024,-488.421 0,-732.631 C 84.323,-409.785 -41.61,-329.325 -173.541,-260.264 -121.973,-169.51 -63.758,-82.619 0,0"
style="fill:#4c8fcc;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path30" />
</g> </g>
<g <g id="g32" transform="translate(1649.134,1700.6166)">
id="g32" <path d="m 0,0 c 29.635,29.875 71.341,44.657 112.543,48.952 35.754,3.288 72.277,2.4 107.263,-6.431 39.066,-10.174 75.037,-33.474 97.377,-67.501 11.879,-17.661 20.181,-37.411 26.42,-57.687 10.871,-38.802 11.95,-79.356 11.446,-119.358 -44.345,-0.072 -88.69,0.048 -133.035,-0.072 -1.032,30.907 3.263,63.686 -10.175,92.626 -9.526,20.325 -32.107,31.243 -53.751,32.131 -21.453,1.44 -45.065,-4.32 -59.175,-21.597 -12.79,-15.861 -15.382,-37.002 -16.558,-56.655 -1.295,-29.132 3.696,-59.031 17.518,-84.923 16.821,-30.619 39.378,-57.783 64.526,-81.9 31.387,-32.634 67.501,-60.374 97.857,-94.041 27.332,-28.988 51.256,-61.479 68.005,-97.785 20.541,-41.13 26.972,-87.827 25.82,-133.372 -0.912,-32.107 -5.231,-64.406 -16.149,-94.737 -11.59,-31.699 -31.123,-61.047 -58.335,-81.371 -25.124,-19.125 -55.696,-29.852 -86.651,-34.771 -49.552,-6.743 -101.888,-4.847 -148.465,14.854 -35.227,14.829 -64.238,42.689 -81.708,76.548 -20.996,40.242 -27.115,86.339 -27.259,131.212 0.048,17.829 0,35.658 0.048,53.463 44.345,0.048 88.69,-0.023 133.059,0.048 1.728,-35.538 -4.055,-72.06 5.663,-106.807 5.783,-22.173 26.204,-37.794 48.185,-41.754 20.733,-3.431 43.577,-2.015 61.622,9.791 15.502,9.43 23.949,26.78 26.78,44.225 5.903,35.922 1.872,74.293 -15.381,106.688 -16.918,30.595 -39.474,57.711 -64.55,81.899 -33.187,34.099 -71.173,63.254 -102.585,99.081 -26.756,28.867 -49.408,61.646 -65.486,97.641 -24.572,52.48 -26.731,112.422 -20.18,169.102 C -49.456,-77.604 -33.019,-32.155 0,0" style="fill:#feeeee;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path34" />
transform="translate(1649.134,1700.6166)">
<path
d="m 0,0 c 29.635,29.875 71.341,44.657 112.543,48.952 35.754,3.288 72.277,2.4 107.263,-6.431 39.066,-10.174 75.037,-33.474 97.377,-67.501 11.879,-17.661 20.181,-37.411 26.42,-57.687 10.871,-38.802 11.95,-79.356 11.446,-119.358 -44.345,-0.072 -88.69,0.048 -133.035,-0.072 -1.032,30.907 3.263,63.686 -10.175,92.626 -9.526,20.325 -32.107,31.243 -53.751,32.131 -21.453,1.44 -45.065,-4.32 -59.175,-21.597 -12.79,-15.861 -15.382,-37.002 -16.558,-56.655 -1.295,-29.132 3.696,-59.031 17.518,-84.923 16.821,-30.619 39.378,-57.783 64.526,-81.9 31.387,-32.634 67.501,-60.374 97.857,-94.041 27.332,-28.988 51.256,-61.479 68.005,-97.785 20.541,-41.13 26.972,-87.827 25.82,-133.372 -0.912,-32.107 -5.231,-64.406 -16.149,-94.737 -11.59,-31.699 -31.123,-61.047 -58.335,-81.371 -25.124,-19.125 -55.696,-29.852 -86.651,-34.771 -49.552,-6.743 -101.888,-4.847 -148.465,14.854 -35.227,14.829 -64.238,42.689 -81.708,76.548 -20.996,40.242 -27.115,86.339 -27.259,131.212 0.048,17.829 0,35.658 0.048,53.463 44.345,0.048 88.69,-0.023 133.059,0.048 1.728,-35.538 -4.055,-72.06 5.663,-106.807 5.783,-22.173 26.204,-37.794 48.185,-41.754 20.733,-3.431 43.577,-2.015 61.622,9.791 15.502,9.43 23.949,26.78 26.78,44.225 5.903,35.922 1.872,74.293 -15.381,106.688 -16.918,30.595 -39.474,57.711 -64.55,81.899 -33.187,34.099 -71.173,63.254 -102.585,99.081 -26.756,28.867 -49.408,61.646 -65.486,97.641 -24.572,52.48 -26.731,112.422 -20.18,169.102 C -49.456,-77.604 -33.019,-32.155 0,0"
style="fill:#feeeee;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path34" />
</g> </g>
<g <g id="g36" transform="translate(1262.7214,1613.126)">
id="g36" <path d="m 0,0 v -301.13 c 23.204,0.024 46.409,-0.048 69.613,0.024 18.525,0.288 38.202,6.575 50.153,21.429 12.43,17.277 13.917,39.522 14.613,60.111 0.024,43.985 -0.048,87.994 0.024,131.979 -0.48,23.637 -0.983,50.369 -17.277,69.23 C 104.864,-5.711 86.867,-0.24 69.589,0 46.385,0.048 23.204,0.024 0,0 m -141.002,128.38 c 26.708,0.048 53.392,0 80.075,0.024 H 55.24 c 35.346,-0.12 71.389,-2.471 104.815,-14.925 30.668,-10.823 57.592,-31.148 76.621,-57.496 26.852,-39.09 36.69,-87.202 38.058,-133.947 0.024,-48.833 0.096,-97.689 -0.024,-146.521 -1.728,-47.993 -11.974,-97.953 -41.514,-136.971 -22.748,-30.644 -57.495,-50.801 -94.281,-59.583 -45.377,-11.878 -92.578,-6.791 -138.891,-7.847 -0.072,-111.799 0,-223.574 -0.024,-335.373 -13.942,0 -27.86,0.024 -41.778,-0.024 -32.802,0.072 -65.605,0 -98.384,0.048 l -0.744,0.984 c -0.216,26.444 0,52.888 -0.096,79.332 0.024,244.211 0.048,488.421 0,732.632 0.048,26.563 0.024,53.103 0,79.667" style="fill:#feeeee;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path38" />
transform="translate(1262.7214,1613.126)">
<path
d="m 0,0 v -301.13 c 23.204,0.024 46.409,-0.048 69.613,0.024 18.525,0.288 38.202,6.575 50.153,21.429 12.43,17.277 13.917,39.522 14.613,60.111 0.024,43.985 -0.048,87.994 0.024,131.979 -0.48,23.637 -0.983,50.369 -17.277,69.23 C 104.864,-5.711 86.867,-0.24 69.589,0 46.385,0.048 23.204,0.024 0,0 m -141.002,128.38 c 26.708,0.048 53.392,0 80.075,0.024 H 55.24 c 35.346,-0.12 71.389,-2.471 104.815,-14.925 30.668,-10.823 57.592,-31.148 76.621,-57.496 26.852,-39.09 36.69,-87.202 38.058,-133.947 0.024,-48.833 0.096,-97.689 -0.024,-146.521 -1.728,-47.993 -11.974,-97.953 -41.514,-136.971 -22.748,-30.644 -57.495,-50.801 -94.281,-59.583 -45.377,-11.878 -92.578,-6.791 -138.891,-7.847 -0.072,-111.799 0,-223.574 -0.024,-335.373 -13.942,0 -27.86,0.024 -41.778,-0.024 -32.802,0.072 -65.605,0 -98.384,0.048 l -0.744,0.984 c -0.216,26.444 0,52.888 -0.096,79.332 0.024,244.211 0.048,488.421 0,732.632 0.048,26.563 0.024,53.103 0,79.667"
style="fill:#feeeee;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path38" />
</g> </g>
<g <g id="g40" transform="translate(1966.3174,1675.6364)">
id="g40" <path d="m 0,0 c 7.031,-0.552 11.206,-6.839 15.885,-11.326 25.029,-26.9 52.768,-51.208 76.693,-79.164 27.667,-27.5 54.903,-55.456 82.571,-82.979 13.246,-13.942 27.764,-26.66 39.93,-41.658 18.813,-19.653 38.49,-38.514 57.519,-57.999 23.9,-24.812 49.337,-48.185 71.965,-74.197 36.427,-36.378 72.589,-73.02 108.943,-109.471 18.358,-21.524 39.234,-40.722 58.959,-60.974 22.605,-22.941 45.473,-45.665 68.03,-68.678 10.774,-13.294 23.78,-24.524 34.914,-37.506 -103.904,-41.97 -203.488,-94.114 -298.922,-152.761 -246.994,-152.28 -466.224,-350.298 -639.333,-583.398 -25.197,25.196 -50.297,50.488 -75.325,75.852 -13.51,12.886 -24.908,27.788 -38.634,40.458 -30.667,31.627 -63.014,61.695 -92.17,94.738 -29.347,29.107 -58.359,58.623 -87.514,87.922 -18.717,21.933 -40.05,41.37 -59.967,62.151 -18.909,19.461 -39.042,37.77 -56.607,58.503 -14.998,15.477 -30.452,30.499 -45.569,45.88 -21.717,22.629 -45.017,43.722 -65.126,67.862 32.779,-0.048 65.582,0.024 98.384,-0.048 114.391,-98.097 220.407,-205.984 315.384,-322.99 92.914,114.318 196.242,220.022 307.753,316.271 30.955,4.919 61.526,15.646 86.65,34.771 27.212,20.325 46.745,49.672 58.335,81.371 107.312,77.988 219.327,149.929 337.509,210.376 -35.299,64.67 -75.829,126.437 -118.254,186.643 C 176.253,-228.037 104.24,-140.115 26.42,-57.687 20.181,-37.41 11.878,-17.661 0,0" style="fill:#042338;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path42" />
transform="translate(1966.3174,1675.6364)">
<path
d="m 0,0 c 7.031,-0.552 11.206,-6.839 15.885,-11.326 25.029,-26.9 52.768,-51.208 76.693,-79.164 27.667,-27.5 54.903,-55.456 82.571,-82.979 13.246,-13.942 27.764,-26.66 39.93,-41.658 18.813,-19.653 38.49,-38.514 57.519,-57.999 23.9,-24.812 49.337,-48.185 71.965,-74.197 36.427,-36.378 72.589,-73.02 108.943,-109.471 18.358,-21.524 39.234,-40.722 58.959,-60.974 22.605,-22.941 45.473,-45.665 68.03,-68.678 10.774,-13.294 23.78,-24.524 34.914,-37.506 -103.904,-41.97 -203.488,-94.114 -298.922,-152.761 -246.994,-152.28 -466.224,-350.298 -639.333,-583.398 -25.197,25.196 -50.297,50.488 -75.325,75.852 -13.51,12.886 -24.908,27.788 -38.634,40.458 -30.667,31.627 -63.014,61.695 -92.17,94.738 -29.347,29.107 -58.359,58.623 -87.514,87.922 -18.717,21.933 -40.05,41.37 -59.967,62.151 -18.909,19.461 -39.042,37.77 -56.607,58.503 -14.998,15.477 -30.452,30.499 -45.569,45.88 -21.717,22.629 -45.017,43.722 -65.126,67.862 32.779,-0.048 65.582,0.024 98.384,-0.048 114.391,-98.097 220.407,-205.984 315.384,-322.99 92.914,114.318 196.242,220.022 307.753,316.271 30.955,4.919 61.526,15.646 86.65,34.771 27.212,20.325 46.745,49.672 58.335,81.371 107.312,77.988 219.327,149.929 337.509,210.376 -35.299,64.67 -75.829,126.437 -118.254,186.643 C 176.253,-228.037 104.24,-140.115 26.42,-57.687 20.181,-37.41 11.878,-17.661 0,0"
style="fill:#042338;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path42" />
</g> </g>
<g <g id="g44" transform="translate(1499.3971,1669.1094)">
id="g44" <path d="m 0,0 c 3.551,-2.088 7.415,-3.935 10.39,-6.911 27.932,-28.1 55.912,-56.175 84.036,-84.083 -6.551,-56.679 -4.392,-116.622 20.18,-169.102 16.078,-35.994 38.73,-68.774 65.486,-97.641 31.412,-35.826 69.398,-64.982 102.585,-99.081 25.076,-24.188 47.632,-51.304 64.55,-81.899 17.253,-32.395 21.284,-70.765 15.381,-106.688 -2.831,-17.445 -11.278,-34.794 -26.78,-44.225 -18.045,-11.806 -40.889,-13.222 -61.622,-9.79 -21.981,3.959 -42.402,19.58 -48.185,41.753 -9.718,34.747 -3.935,71.269 -5.663,106.808 -44.369,-0.072 -88.714,0 -133.059,-0.048 -0.048,-17.806 0,-35.635 -0.048,-53.464 0.144,-44.873 6.263,-90.97 27.259,-131.212 17.47,-33.859 46.481,-61.718 81.708,-76.548 46.577,-19.701 98.913,-21.597 148.465,-14.854 -111.511,-96.249 -214.839,-201.953 -307.753,-316.271 -94.977,117.006 -200.993,224.893 -315.383,322.99 13.918,0.048 27.836,0.024 41.777,0.024 0.024,111.799 -0.048,223.574 0.024,335.372 46.313,1.056 93.514,-4.031 138.891,7.847 36.786,8.783 71.533,28.94 94.282,59.583 29.539,39.018 39.785,88.978 41.513,136.971 0.12,48.833 0.048,97.689 0.024,146.522 C 36.69,-87.203 26.852,-39.09 0,0" style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path46" />
transform="translate(1499.3971,1669.1094)">
<path
d="m 0,0 c 3.551,-2.088 7.415,-3.935 10.39,-6.911 27.932,-28.1 55.912,-56.175 84.036,-84.083 -6.551,-56.679 -4.392,-116.622 20.18,-169.102 16.078,-35.994 38.73,-68.774 65.486,-97.641 31.412,-35.826 69.398,-64.982 102.585,-99.081 25.076,-24.188 47.632,-51.304 64.55,-81.899 17.253,-32.395 21.284,-70.765 15.381,-106.688 -2.831,-17.445 -11.278,-34.794 -26.78,-44.225 -18.045,-11.806 -40.889,-13.222 -61.622,-9.79 -21.981,3.959 -42.402,19.58 -48.185,41.753 -9.718,34.747 -3.935,71.269 -5.663,106.808 -44.369,-0.072 -88.714,0 -133.059,-0.048 -0.048,-17.806 0,-35.635 -0.048,-53.464 0.144,-44.873 6.263,-90.97 27.259,-131.212 17.47,-33.859 46.481,-61.718 81.708,-76.548 46.577,-19.701 98.913,-21.597 148.465,-14.854 -111.511,-96.249 -214.839,-201.953 -307.753,-316.271 -94.977,117.006 -200.993,224.893 -315.383,322.99 13.918,0.048 27.836,0.024 41.777,0.024 0.024,111.799 -0.048,223.574 0.024,335.372 46.313,1.056 93.514,-4.031 138.891,7.847 36.786,8.783 71.533,28.94 94.282,59.583 29.539,39.018 39.785,88.978 41.513,136.971 0.12,48.833 0.048,97.689 0.024,146.522 C 36.69,-87.203 26.852,-39.09 0,0"
style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path46" />
</g> </g>
<g <g id="g48" transform="translate(1748.0469,1601.6797)">
id="g48" <path d="M 0,0 C 14.11,17.277 37.722,23.036 59.175,21.597 80.82,20.709 103.4,9.791 112.927,-10.534 c 13.438,-28.94 9.142,-61.719 10.174,-92.626 44.345,0.12 88.691,0 133.036,0.072 0.504,40.002 -0.576,80.556 -11.447,119.358 77.82,-82.428 149.833,-170.35 215.583,-262.664 42.426,-60.207 82.956,-121.973 118.254,-186.643 -118.182,-60.447 -230.196,-132.388 -337.508,-210.376 10.918,30.331 15.238,62.63 16.149,94.737 1.152,45.545 -5.279,92.242 -25.82,133.372 -16.749,36.306 -40.673,68.797 -68.005,97.785 -30.355,33.667 -66.47,61.406 -97.857,94.041 -25.148,24.117 -47.705,51.28 -64.526,81.9 -13.822,25.892 -18.813,55.791 -17.517,84.923 C -15.382,-37.002 -12.79,-15.862 0,0" style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path50" />
transform="translate(1748.0469,1601.6797)">
<path
d="M 0,0 C 14.11,17.277 37.722,23.036 59.175,21.597 80.82,20.709 103.4,9.791 112.927,-10.534 c 13.438,-28.94 9.142,-61.719 10.174,-92.626 44.345,0.12 88.691,0 133.036,0.072 0.504,40.002 -0.576,80.556 -11.447,119.358 77.82,-82.428 149.833,-170.35 215.583,-262.664 42.426,-60.207 82.956,-121.973 118.254,-186.643 -118.182,-60.447 -230.196,-132.388 -337.508,-210.376 10.918,30.331 15.238,62.63 16.149,94.737 1.152,45.545 -5.279,92.242 -25.82,133.372 -16.749,36.306 -40.673,68.797 -68.005,97.785 -30.355,33.667 -66.47,61.406 -97.857,94.041 -25.148,24.117 -47.705,51.28 -64.526,81.9 -13.822,25.892 -18.813,55.791 -17.517,84.923 C -15.382,-37.002 -12.79,-15.862 0,0"
style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path50" />
</g> </g>
<g <g id="g52" transform="translate(1262.7214,1613.126)">
id="g52" <path d="m 0,0 c 23.204,0.024 46.385,0.048 69.589,0 17.278,-0.24 35.275,-5.711 47.537,-18.357 16.294,-18.861 16.797,-45.593 17.277,-69.23 -0.072,-43.985 0,-87.994 -0.024,-131.979 -0.696,-20.589 -2.183,-42.834 -14.613,-60.111 -11.951,-14.854 -31.628,-21.141 -50.153,-21.429 -23.204,-0.072 -46.409,0 -69.613,-0.024 z" style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none" id="path54" />
transform="translate(1262.7214,1613.126)">
<path
d="m 0,0 c 23.204,0.024 46.385,0.048 69.589,0 17.278,-0.24 35.275,-5.711 47.537,-18.357 16.294,-18.861 16.797,-45.593 17.277,-69.23 -0.072,-43.985 0,-87.994 -0.024,-131.979 -0.696,-20.589 -2.183,-42.834 -14.613,-60.111 -11.951,-14.854 -31.628,-21.141 -50.153,-21.429 -23.204,-0.072 -46.409,0 -69.613,-0.024 z"
style="fill:#1c72ba;fill-opacity:1;fill-rule:nonzero;stroke:none"
id="path54" />
</g> </g>
</g> </g>
</g> </g>

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -18,7 +18,7 @@ repositories {
} }
dependencies { dependencies {
api(projects.plotsquaredCore) api(projects.plotSquaredCore)
// Metrics // Metrics
implementation("org.bstats:bstats-bukkit") implementation("org.bstats:bstats-bukkit")
@ -53,6 +53,10 @@ dependencies {
// Adventure // Adventure
implementation("net.kyori:adventure-platform-bukkit") implementation("net.kyori:adventure-platform-bukkit")
// Cloud
implementation(libs.cloudPaper)
implementation(libs.cloudMinecraftExtras)
} }
tasks.processResources { tasks.processResources {
@ -62,7 +66,6 @@ tasks.processResources {
} }
tasks.named<ShadowJar>("shadowJar") { tasks.named<ShadowJar>("shadowJar") {
dependsOn(":plotsquared-core:shadowJar")
dependencies { dependencies {
exclude(dependency("org.checkerframework:")) exclude(dependency("org.checkerframework:"))
} }
@ -103,7 +106,7 @@ tasks {
opt.links("https://jd.papermc.io/paper/1.19/") opt.links("https://jd.papermc.io/paper/1.19/")
opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-bukkit/" + libs.worldeditBukkit.get().versionConstraint.toString()) opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-bukkit/" + libs.worldeditBukkit.get().versionConstraint.toString())
opt.links("https://intellectualsites.github.io/plotsquared-javadocs/core/") opt.links("https://intellectualsites.github.io/plotsquared-javadocs/core/")
opt.links("https://jd.advntr.dev/api/4.14.0/") opt.links("https://jd.adventure.kyori.net/api/4.12.0/")
opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/") opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/")
opt.links("https://checkerframework.org/api/") opt.links("https://checkerframework.org/api/")
opt.isLinkSource = true opt.isLinkSource = true

View File

@ -49,6 +49,7 @@ import com.plotsquared.bukkit.player.BukkitPlayerManager;
import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.bukkit.util.BukkitWorld; import com.plotsquared.bukkit.util.BukkitWorld;
import com.plotsquared.bukkit.util.SetGenCB; import com.plotsquared.bukkit.util.SetGenCB;
import com.plotsquared.bukkit.util.UpdateUtility;
import com.plotsquared.bukkit.util.TranslationUpdateManager; import com.plotsquared.bukkit.util.TranslationUpdateManager;
import com.plotsquared.bukkit.util.task.BukkitTaskManager; import com.plotsquared.bukkit.util.task.BukkitTaskManager;
import com.plotsquared.bukkit.util.task.PaperTimeConverter; import com.plotsquared.bukkit.util.task.PaperTimeConverter;
@ -62,6 +63,7 @@ import com.plotsquared.bukkit.uuid.SquirrelIdUUIDService;
import com.plotsquared.core.PlotPlatform; import com.plotsquared.core.PlotPlatform;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.backup.BackupManager; import com.plotsquared.core.backup.BackupManager;
import com.plotsquared.core.commands.PlotSquaredCommandManager;
import com.plotsquared.core.components.ComponentPresetManager; import com.plotsquared.core.components.ComponentPresetManager;
import com.plotsquared.core.configuration.ConfigurationNode; import com.plotsquared.core.configuration.ConfigurationNode;
import com.plotsquared.core.configuration.ConfigurationSection; import com.plotsquared.core.configuration.ConfigurationSection;
@ -214,6 +216,8 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
@Inject @Inject
private PlatformWorldManager<World> worldManager; private PlatformWorldManager<World> worldManager;
private Locale serverLocale; private Locale serverLocale;
@Inject
private PlotSquaredCommandManager commandManager;
@SuppressWarnings("StringSplitter") @SuppressWarnings("StringSplitter")
@Override @Override
@ -302,11 +306,9 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
this.serverLocale = Locale.forLanguageTag(Settings.Enabled_Components.DEFAULT_LOCALE); this.serverLocale = Locale.forLanguageTag(Settings.Enabled_Components.DEFAULT_LOCALE);
/* TODO Enable update checker before v7 is released to GA
if (PremiumVerification.isPremium() && Settings.Enabled_Components.UPDATE_NOTIFICATIONS) { if (PremiumVerification.isPremium() && Settings.Enabled_Components.UPDATE_NOTIFICATIONS) {
injector.getInstance(UpdateUtility.class).updateChecker(); injector.getInstance(UpdateUtility.class).updateChecker();
} }
*/
if (PremiumVerification.isPremium()) { if (PremiumVerification.isPremium()) {
LOGGER.info("PlotSquared version licensed to Spigot user {}", getUserID()); LOGGER.info("PlotSquared version licensed to Spigot user {}", getUserID());
@ -383,6 +385,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
// Commands // Commands
if (Settings.Enabled_Components.COMMANDS) { if (Settings.Enabled_Components.COMMANDS) {
this.registerCommands(); this.registerCommands();
this.commandManager.initializeCommands();
} }
// Permissions // Permissions
@ -1186,17 +1189,9 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
public @NonNull String worldEditImplementations() { public @NonNull String worldEditImplementations() {
StringBuilder msg = new StringBuilder(); StringBuilder msg = new StringBuilder();
if (Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null) { if (Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null) {
msg.append("FastAsyncWorldEdit: ").append(Bukkit msg.append("FastAsyncWorldEdit: ").append(Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit").getDescription().getVersion());
.getPluginManager()
.getPlugin("FastAsyncWorldEdit")
.getDescription()
.getVersion());
} else if (Bukkit.getPluginManager().getPlugin("AsyncWorldEdit") != null) { } else if (Bukkit.getPluginManager().getPlugin("AsyncWorldEdit") != null) {
msg.append("AsyncWorldEdit: ").append(Bukkit msg.append("AsyncWorldEdit: ").append(Bukkit.getPluginManager().getPlugin("AsyncWorldEdit").getDescription().getVersion()).append("\n");
.getPluginManager()
.getPlugin("AsyncWorldEdit")
.getDescription()
.getVersion()).append("\n");
msg.append("WorldEdit: ").append(Bukkit.getPluginManager().getPlugin("WorldEdit").getDescription().getVersion()); msg.append("WorldEdit: ").append(Bukkit.getPluginManager().getPlugin("WorldEdit").getDescription().getVersion());
} else { } else {
msg.append("WorldEdit: ").append(Bukkit.getPluginManager().getPlugin("WorldEdit").getDescription().getVersion()); msg.append("WorldEdit: ").append(Bukkit.getPluginManager().getPlugin("WorldEdit").getDescription().getVersion());

View File

@ -101,26 +101,50 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.noGravity = true; this.noGravity = true;
} }
switch (entity.getType().toString()) { switch (entity.getType().toString()) {
case "BOAT" -> { case "BOAT":
Boat boat = (Boat) entity; Boat boat = (Boat) entity;
this.dataByte = getOrdinal(TreeSpecies.values(), boat.getWoodType()); this.dataByte = getOrdinal(TreeSpecies.values(), boat.getWoodType());
return; return;
} case "ARROW":
case "ARROW", "EGG", "ENDER_CRYSTAL", "ENDER_PEARL", "ENDER_SIGNAL", "EXPERIENCE_ORB", "FALLING_BLOCK", "FIREBALL", case "EGG":
"FIREWORK", "FISHING_HOOK", "LEASH_HITCH", "LIGHTNING", "MINECART", "MINECART_COMMAND", "MINECART_MOB_SPAWNER", case "ENDER_CRYSTAL":
"MINECART_TNT", "PLAYER", "PRIMED_TNT", "SLIME", "SMALL_FIREBALL", "SNOWBALL", "MINECART_FURNACE", "SPLASH_POTION", case "ENDER_PEARL":
"THROWN_EXP_BOTTLE", "WITHER_SKULL", "UNKNOWN", "SPECTRAL_ARROW", "SHULKER_BULLET", "DRAGON_FIREBALL", "AREA_EFFECT_CLOUD", case "ENDER_SIGNAL":
"TRIDENT", "LLAMA_SPIT" -> { case "EXPERIENCE_ORB":
case "FALLING_BLOCK":
case "FIREBALL":
case "FIREWORK":
case "FISHING_HOOK":
case "LEASH_HITCH":
case "LIGHTNING":
case "MINECART":
case "MINECART_COMMAND":
case "MINECART_MOB_SPAWNER":
case "MINECART_TNT":
case "PLAYER":
case "PRIMED_TNT":
case "SLIME":
case "SMALL_FIREBALL":
case "SNOWBALL":
case "MINECART_FURNACE":
case "SPLASH_POTION":
case "THROWN_EXP_BOTTLE":
case "WITHER_SKULL":
case "UNKNOWN":
case "SPECTRAL_ARROW":
case "SHULKER_BULLET":
case "DRAGON_FIREBALL":
case "AREA_EFFECT_CLOUD":
case "TRIDENT":
case "LLAMA_SPIT":
// Do this stuff later // Do this stuff later
return; return;
}
// MISC // // MISC //
case "DROPPED_ITEM" -> { case "DROPPED_ITEM":
Item item = (Item) entity; Item item = (Item) entity;
this.stack = item.getItemStack(); this.stack = item.getItemStack();
return; return;
} case "ITEM_FRAME":
case "ITEM_FRAME" -> {
this.x = Math.floor(this.getX()); this.x = Math.floor(this.getX());
this.y = Math.floor(this.getY()); this.y = Math.floor(this.getY());
this.z = Math.floor(this.getZ()); this.z = Math.floor(this.getZ());
@ -128,8 +152,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.dataByte = getOrdinal(Rotation.values(), itemFrame.getRotation()); this.dataByte = getOrdinal(Rotation.values(), itemFrame.getRotation());
this.stack = itemFrame.getItem().clone(); this.stack = itemFrame.getItem().clone();
return; return;
} case "PAINTING":
case "PAINTING" -> {
this.x = Math.floor(this.getX()); this.x = Math.floor(this.getX());
this.y = Math.floor(this.getY()); this.y = Math.floor(this.getY());
this.z = Math.floor(this.getZ()); this.z = Math.floor(this.getZ());
@ -142,17 +165,20 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
this.dataString = art.name(); this.dataString = art.name();
return; return;
}
// END MISC // // END MISC //
// INVENTORY HOLDER // // INVENTORY HOLDER //
case "MINECART_CHEST", "MINECART_HOPPER" -> { case "MINECART_CHEST":
case "MINECART_HOPPER":
storeInventory((InventoryHolder) entity); storeInventory((InventoryHolder) entity);
return; return;
}
// START LIVING ENTITY // // START LIVING ENTITY //
// START AGEABLE // // START AGEABLE //
// START TAMEABLE // // START TAMEABLE //
case "HORSE", "DONKEY", "LLAMA", "MULE", "SKELETON_HORSE" -> { case "HORSE":
case "DONKEY":
case "LLAMA":
case "MULE":
case "SKELETON_HORSE":
AbstractHorse horse = (AbstractHorse) entity; AbstractHorse horse = (AbstractHorse) entity;
this.horse = new HorseStats(); this.horse = new HorseStats();
this.horse.jump = horse.getJumpStrength(); this.horse.jump = horse.getJumpStrength();
@ -168,17 +194,16 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
storeLiving(horse); storeLiving(horse);
storeInventory(horse); storeInventory(horse);
return; return;
}
// END INVENTORY HOLDER // // END INVENTORY HOLDER //
case "WOLF", "OCELOT" -> { case "WOLF":
case "OCELOT":
storeTameable((Tameable) entity); storeTameable((Tameable) entity);
storeAgeable((Ageable) entity); storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
}
// END TAMEABLE // // END TAMEABLE //
//todo fix sheep //todo fix sheep
case "SHEEP" -> { case "SHEEP":
Sheep sheep = (Sheep) entity; Sheep sheep = (Sheep) entity;
if (sheep.isSheared()) { if (sheep.isSheared()) {
this.dataByte = (byte) 1; this.dataByte = (byte) 1;
@ -189,20 +214,23 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
storeAgeable(sheep); storeAgeable(sheep);
storeLiving(sheep); storeLiving(sheep);
return; return;
} case "VILLAGER":
case "VILLAGER", "CHICKEN", "COW", "MUSHROOM_COW", "PIG", "TURTLE", "POLAR_BEAR" -> { case "CHICKEN":
case "COW":
case "MUSHROOM_COW":
case "PIG":
case "TURTLE":
case "POLAR_BEAR":
storeAgeable((Ageable) entity); storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
} case "RABBIT":
case "RABBIT" -> {
this.dataByte = getOrdinal(Rabbit.Type.values(), ((Rabbit) entity).getRabbitType()); this.dataByte = getOrdinal(Rabbit.Type.values(), ((Rabbit) entity).getRabbitType());
storeAgeable((Ageable) entity); storeAgeable((Ageable) entity);
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
}
// END AGEABLE // // END AGEABLE //
case "ARMOR_STAND" -> { case "ARMOR_STAND":
ArmorStand stand = (ArmorStand) entity; ArmorStand stand = (ArmorStand) entity;
this.inventory = this.inventory =
new ItemStack[]{stand.getItemInHand().clone(), stand.getHelmet().clone(), new ItemStack[]{stand.getItemInHand().clone(), stand.getHelmet().clone(),
@ -210,30 +238,37 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
stand.getBoots().clone()}; stand.getBoots().clone()};
storeLiving(stand); storeLiving(stand);
this.stand = new ArmorStandStats(); this.stand = new ArmorStandStats();
EulerAngle head = stand.getHeadPose(); EulerAngle head = stand.getHeadPose();
this.stand.head[0] = (float) head.getX(); this.stand.head[0] = (float) head.getX();
this.stand.head[1] = (float) head.getY(); this.stand.head[1] = (float) head.getY();
this.stand.head[2] = (float) head.getZ(); this.stand.head[2] = (float) head.getZ();
EulerAngle body = stand.getBodyPose(); EulerAngle body = stand.getBodyPose();
this.stand.body[0] = (float) body.getX(); this.stand.body[0] = (float) body.getX();
this.stand.body[1] = (float) body.getY(); this.stand.body[1] = (float) body.getY();
this.stand.body[2] = (float) body.getZ(); this.stand.body[2] = (float) body.getZ();
EulerAngle leftLeg = stand.getLeftLegPose(); EulerAngle leftLeg = stand.getLeftLegPose();
this.stand.leftLeg[0] = (float) leftLeg.getX(); this.stand.leftLeg[0] = (float) leftLeg.getX();
this.stand.leftLeg[1] = (float) leftLeg.getY(); this.stand.leftLeg[1] = (float) leftLeg.getY();
this.stand.leftLeg[2] = (float) leftLeg.getZ(); this.stand.leftLeg[2] = (float) leftLeg.getZ();
EulerAngle rightLeg = stand.getRightLegPose(); EulerAngle rightLeg = stand.getRightLegPose();
this.stand.rightLeg[0] = (float) rightLeg.getX(); this.stand.rightLeg[0] = (float) rightLeg.getX();
this.stand.rightLeg[1] = (float) rightLeg.getY(); this.stand.rightLeg[1] = (float) rightLeg.getY();
this.stand.rightLeg[2] = (float) rightLeg.getZ(); this.stand.rightLeg[2] = (float) rightLeg.getZ();
EulerAngle leftArm = stand.getLeftArmPose(); EulerAngle leftArm = stand.getLeftArmPose();
this.stand.leftArm[0] = (float) leftArm.getX(); this.stand.leftArm[0] = (float) leftArm.getX();
this.stand.leftArm[1] = (float) leftArm.getY(); this.stand.leftArm[1] = (float) leftArm.getY();
this.stand.leftArm[2] = (float) leftArm.getZ(); this.stand.leftArm[2] = (float) leftArm.getZ();
EulerAngle rightArm = stand.getRightArmPose(); EulerAngle rightArm = stand.getRightArmPose();
this.stand.rightArm[0] = (float) rightArm.getX(); this.stand.rightArm[0] = (float) rightArm.getX();
this.stand.rightArm[1] = (float) rightArm.getY(); this.stand.rightArm[1] = (float) rightArm.getY();
this.stand.rightArm[2] = (float) rightArm.getZ(); this.stand.rightArm[2] = (float) rightArm.getZ();
if (stand.hasArms()) { if (stand.hasArms()) {
this.stand.arms = true; this.stand.arms = true;
} }
@ -247,37 +282,52 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
this.stand.small = true; this.stand.small = true;
} }
return; return;
} case "ENDERMITE":
case "ENDERMITE" -> {
return; return;
} case "BAT":
case "BAT" -> {
if (((Bat) entity).isAwake()) { if (((Bat) entity).isAwake()) {
this.dataByte = (byte) 1; this.dataByte = (byte) 1;
} else { } else {
this.dataByte = (byte) 0; this.dataByte = (byte) 0;
} }
return; return;
} case "ENDER_DRAGON":
case "ENDER_DRAGON" -> {
EnderDragon entity1 = (EnderDragon) entity; EnderDragon entity1 = (EnderDragon) entity;
this.dataByte = (byte) entity1.getPhase().ordinal(); this.dataByte = (byte) entity1.getPhase().ordinal();
return; return;
} case "SKELETON":
case "SKELETON", "WITHER_SKELETON", "GUARDIAN", "ELDER_GUARDIAN", "GHAST", "MAGMA_CUBE", "SQUID", "PIG_ZOMBIE", "HOGLIN", case "WITHER_SKELETON":
"ZOMBIFIED_PIGLIN", "PIGLIN", "PIGLIN_BRUTE", "ZOMBIE", "WITHER", "WITCH", "SPIDER", "CAVE_SPIDER", "SILVERFISH", case "GUARDIAN":
"GIANT", "ENDERMAN", "CREEPER", "BLAZE", "SHULKER", "SNOWMAN" -> { case "ELDER_GUARDIAN":
case "GHAST":
case "MAGMA_CUBE":
case "SQUID":
case "PIG_ZOMBIE":
case "HOGLIN":
case "ZOMBIFIED_PIGLIN":
case "PIGLIN":
case "PIGLIN_BRUTE":
case "ZOMBIE":
case "WITHER":
case "WITCH":
case "SPIDER":
case "CAVE_SPIDER":
case "SILVERFISH":
case "GIANT":
case "ENDERMAN":
case "CREEPER":
case "BLAZE":
case "SHULKER":
case "SNOWMAN":
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
return; return;
} case "IRON_GOLEM":
case "IRON_GOLEM" -> {
if (((IronGolem) entity).isPlayerCreated()) { if (((IronGolem) entity).isPlayerCreated()) {
this.dataByte = (byte) 1; this.dataByte = (byte) 1;
} else { } else {
this.dataByte = (byte) 0; this.dataByte = (byte) 0;
} }
storeLiving((LivingEntity) entity); storeLiving((LivingEntity) entity);
}
// END LIVING // // END LIVING //
} }
} }
@ -415,15 +465,20 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
Entity entity; Entity entity;
switch (this.getType().toString()) { switch (this.getType().toString()) {
case "DROPPED_ITEM" -> { case "DROPPED_ITEM":
return world.dropItem(location, this.stack); return world.dropItem(location, this.stack);
} case "PLAYER":
case "PLAYER", "LEASH_HITCH" -> { case "LEASH_HITCH":
return null; return null;
} case "ITEM_FRAME":
case "ITEM_FRAME" -> entity = world.spawn(location, ItemFrame.class); entity = world.spawn(location, ItemFrame.class);
case "PAINTING" -> entity = world.spawn(location, Painting.class); break;
default -> entity = world.spawnEntity(location, this.getType()); case "PAINTING":
entity = world.spawn(location, Painting.class);
break;
default:
entity = world.spawnEntity(location, this.getType());
break;
} }
if (this.depth == 0) { if (this.depth == 0) {
return entity; return entity;
@ -451,46 +506,72 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
entity.setGravity(false); entity.setGravity(false);
} }
switch (entity.getType().toString()) { switch (entity.getType().toString()) {
case "BOAT" -> { case "BOAT":
Boat boat = (Boat) entity; Boat boat = (Boat) entity;
boat.setWoodType(TreeSpecies.values()[dataByte]); boat.setWoodType(TreeSpecies.values()[dataByte]);
return entity; return entity;
} case "SLIME":
case "SLIME" -> {
((Slime) entity).setSize(this.dataByte); ((Slime) entity).setSize(this.dataByte);
return entity; return entity;
} case "ARROW":
case "ARROW", "EGG", "ENDER_CRYSTAL", "ENDER_PEARL", "ENDER_SIGNAL", "DROPPED_ITEM", "EXPERIENCE_ORB", "FALLING_BLOCK", case "EGG":
"FIREBALL", "FIREWORK", "FISHING_HOOK", "LEASH_HITCH", "LIGHTNING", "MINECART", "MINECART_COMMAND", case "ENDER_CRYSTAL":
"MINECART_MOB_SPAWNER", "MINECART_TNT", "PLAYER", "PRIMED_TNT", "SMALL_FIREBALL", "SNOWBALL", case "ENDER_PEARL":
"SPLASH_POTION", "THROWN_EXP_BOTTLE", "SPECTRAL_ARROW", "SHULKER_BULLET", "AREA_EFFECT_CLOUD", case "ENDER_SIGNAL":
"DRAGON_FIREBALL", "WITHER_SKULL", "MINECART_FURNACE", "LLAMA_SPIT", "TRIDENT", "UNKNOWN" -> { case "DROPPED_ITEM":
case "EXPERIENCE_ORB":
case "FALLING_BLOCK":
case "FIREBALL":
case "FIREWORK":
case "FISHING_HOOK":
case "LEASH_HITCH":
case "LIGHTNING":
case "MINECART":
case "MINECART_COMMAND":
case "MINECART_MOB_SPAWNER":
case "MINECART_TNT":
case "PLAYER":
case "PRIMED_TNT":
case "SMALL_FIREBALL":
case "SNOWBALL":
case "SPLASH_POTION":
case "THROWN_EXP_BOTTLE":
case "SPECTRAL_ARROW":
case "SHULKER_BULLET":
case "AREA_EFFECT_CLOUD":
case "DRAGON_FIREBALL":
case "WITHER_SKULL":
case "MINECART_FURNACE":
case "LLAMA_SPIT":
case "TRIDENT":
case "UNKNOWN":
// Do this stuff later // Do this stuff later
return entity; return entity;
}
// MISC // // MISC //
case "ITEM_FRAME" -> { case "ITEM_FRAME":
ItemFrame itemframe = (ItemFrame) entity; ItemFrame itemframe = (ItemFrame) entity;
itemframe.setRotation(Rotation.values()[this.dataByte]); itemframe.setRotation(Rotation.values()[this.dataByte]);
itemframe.setItem(this.stack); itemframe.setItem(this.stack);
return entity; return entity;
} case "PAINTING":
case "PAINTING" -> {
Painting painting = (Painting) entity; Painting painting = (Painting) entity;
painting.setFacingDirection(BlockFace.values()[this.dataByte], true); painting.setFacingDirection(BlockFace.values()[this.dataByte], true);
painting.setArt(Art.getByName(this.dataString), true); painting.setArt(Art.getByName(this.dataString), true);
return entity; return entity;
}
// END MISC // // END MISC //
// INVENTORY HOLDER // // INVENTORY HOLDER //
case "MINECART_CHEST", "MINECART_HOPPER" -> { case "MINECART_CHEST":
case "MINECART_HOPPER":
restoreInventory((InventoryHolder) entity); restoreInventory((InventoryHolder) entity);
return entity; return entity;
}
// START LIVING ENTITY // // START LIVING ENTITY //
// START AGEABLE // // START AGEABLE //
// START TAMEABLE // // START TAMEABLE //
case "HORSE", "LLAMA", "SKELETON_HORSE", "DONKEY", "MULE" -> { case "HORSE":
case "LLAMA":
case "SKELETON_HORSE":
case "DONKEY":
case "MULE":
AbstractHorse horse = (AbstractHorse) entity; AbstractHorse horse = (AbstractHorse) entity;
horse.setJumpStrength(this.horse.jump); horse.setJumpStrength(this.horse.jump);
if (horse instanceof ChestedHorse) { if (horse instanceof ChestedHorse) {
@ -505,16 +586,15 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
restoreLiving(horse); restoreLiving(horse);
restoreInventory(horse); restoreInventory(horse);
return entity; return entity;
}
// END INVENTORY HOLDER // // END INVENTORY HOLDER //
case "WOLF", "OCELOT" -> { case "WOLF":
case "OCELOT":
restoreTameable((Tameable) entity); restoreTameable((Tameable) entity);
restoreAgeable((Ageable) entity); restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
}
// END AGEABLE // // END AGEABLE //
case "SHEEP" -> { case "SHEEP":
Sheep sheep = (Sheep) entity; Sheep sheep = (Sheep) entity;
if (this.dataByte == 1) { if (this.dataByte == 1) {
sheep.setSheared(true); sheep.setSheared(true);
@ -525,22 +605,25 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
restoreAgeable(sheep); restoreAgeable(sheep);
restoreLiving(sheep); restoreLiving(sheep);
return sheep; return sheep;
} case "VILLAGER":
case "VILLAGER", "CHICKEN", "COW", "TURTLE", "POLAR_BEAR", "MUSHROOM_COW", "PIG" -> { case "CHICKEN":
case "COW":
case "TURTLE":
case "POLAR_BEAR":
case "MUSHROOM_COW":
case "PIG":
restoreAgeable((Ageable) entity); restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
}
// END AGEABLE // // END AGEABLE //
case "RABBIT" -> { case "RABBIT":
if (this.dataByte != 0) { if (this.dataByte != 0) {
((Rabbit) entity).setRabbitType(Rabbit.Type.values()[this.dataByte]); ((Rabbit) entity).setRabbitType(Rabbit.Type.values()[this.dataByte]);
} }
restoreAgeable((Ageable) entity); restoreAgeable((Ageable) entity);
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
} case "ARMOR_STAND":
case "ARMOR_STAND" -> {
// CHECK positions // CHECK positions
ArmorStand stand = (ArmorStand) entity; ArmorStand stand = (ArmorStand) entity;
if (this.inventory[0] != null) { if (this.inventory[0] != null) {
@ -610,38 +693,56 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
} }
restoreLiving(stand); restoreLiving(stand);
return stand; return stand;
} case "BAT":
case "BAT" -> {
if (this.dataByte != 0) { if (this.dataByte != 0) {
((Bat) entity).setAwake(true); ((Bat) entity).setAwake(true);
} }
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
} case "ENDER_DRAGON":
case "ENDER_DRAGON" -> {
if (this.dataByte != 0) { if (this.dataByte != 0) {
((EnderDragon) entity).setPhase(EnderDragon.Phase.values()[this.dataByte]); ((EnderDragon) entity).setPhase(EnderDragon.Phase.values()[this.dataByte]);
} }
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
} case "ENDERMITE":
case "ENDERMITE", "GHAST", "MAGMA_CUBE", "SQUID", "PIG_ZOMBIE", "HOGLIN", "PIGLIN", "ZOMBIFIED_PIGLIN", "PIGLIN_BRUTE", "ZOMBIE", "WITHER", "WITCH", "SPIDER", "CAVE_SPIDER", "SILVERFISH", "GIANT", "ENDERMAN", "CREEPER", "BLAZE", "SNOWMAN", "SHULKER", "GUARDIAN", "ELDER_GUARDIAN", "SKELETON", "WITHER_SKELETON" -> { case "GHAST":
case "MAGMA_CUBE":
case "SQUID":
case "PIG_ZOMBIE":
case "HOGLIN":
case "PIGLIN":
case "ZOMBIFIED_PIGLIN":
case "PIGLIN_BRUTE":
case "ZOMBIE":
case "WITHER":
case "WITCH":
case "SPIDER":
case "CAVE_SPIDER":
case "SILVERFISH":
case "GIANT":
case "ENDERMAN":
case "CREEPER":
case "BLAZE":
case "SNOWMAN":
case "SHULKER":
case "GUARDIAN":
case "ELDER_GUARDIAN":
case "SKELETON":
case "WITHER_SKELETON":
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
} case "IRON_GOLEM":
case "IRON_GOLEM" -> {
if (this.dataByte != 0) { if (this.dataByte != 0) {
((IronGolem) entity).setPlayerCreated(true); ((IronGolem) entity).setPlayerCreated(true);
} }
restoreLiving((LivingEntity) entity); restoreLiving((LivingEntity) entity);
return entity; return entity;
} default:
default -> {
if (Settings.DEBUG) { if (Settings.DEBUG) {
LOGGER.info("Could not identify entity: {}", entity.getType()); LOGGER.info("Could not identify entity: {}", entity.getType());
} }
return entity; return entity;
}
// END LIVING // END LIVING
} }
} }

View File

@ -37,8 +37,6 @@ import com.sk89q.worldedit.math.BlockVector2;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.HeightMap; import org.bukkit.HeightMap;
import org.bukkit.NamespacedKey;
import org.bukkit.Registry;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Biome; import org.bukkit.block.Biome;
import org.bukkit.generator.BiomeProvider; import org.bukkit.generator.BiomeProvider;
@ -50,14 +48,10 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.List; import java.util.List;
import java.util.Random; import java.util.Random;
import java.util.Set; import java.util.Set;
import static java.util.function.Predicate.not;
public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrapper<ChunkGenerator> { public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrapper<ChunkGenerator> {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + BukkitPlotGenerator.class.getSimpleName()); private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + BukkitPlotGenerator.class.getSimpleName());
@ -191,6 +185,12 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
world.setWaterAnimalSpawnLimit(limit); world.setWaterAnimalSpawnLimit(limit);
} }
/**
* The entire method is deprecated, but kept for compatibility with versions lower than or equal to 1.16.2.
* The method will be removed in future versions, because WorldEdit and FastAsyncWorldEdit only support the latest point
* release.
*/
@Deprecated(forRemoval = true, since = "6.11.0")
@Override @Override
public void generateNoise( public void generateNoise(
@NotNull final WorldInfo worldInfo, @NotNull final WorldInfo worldInfo,
@ -283,14 +283,9 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
return super.getBaseHeight(worldInfo, random, x, z, heightMap); return super.getBaseHeight(worldInfo, random, x, z, heightMap);
} }
/**
* The entire method is deprecated, but kept for compatibility with versions lower than or equal to 1.16.2.
* The method will be removed in future versions, because WorldEdit and FastAsyncWorldEdit only support the latest point
* release.
*/
@SuppressWarnings("deprecation") // The entire method is deprecated, but kept for compatibility with <=1.16.2 @SuppressWarnings("deprecation") // The entire method is deprecated, but kept for compatibility with <=1.16.2
@Override @Override
@Deprecated(since = "7.0.0") @Deprecated(since = "TODO")
public @NonNull ChunkData generateChunkData( public @NonNull ChunkData generateChunkData(
@NonNull World world, @NonNull Random random, int x, int z, @NonNull BiomeGrid biome @NonNull World world, @NonNull Random random, int x, int z, @NonNull BiomeGrid biome
) { ) {
@ -298,8 +293,8 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
if (this.platformGenerator != this) { if (this.platformGenerator != this) {
return this.platformGenerator.generateChunkData(world, random, x, z, biome); return this.platformGenerator.generateChunkData(world, random, x, z, biome);
} else { } else {
// Throw exception to be caught by the server that indicates the new generation API is being used. // Return super as it will throw an exception caught by the server that will mean this method is no longer used.
throw new UnsupportedOperationException("Using new generation methods. This method is unsupported."); return super.generateChunkData(world, random, x, z, biome);
} }
} }
@ -422,8 +417,7 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
} }
PlotArea area = UncheckedWorldLocation.at(name, chunkX << 4, 0, chunkZ << 4).getPlotArea(); PlotArea area = UncheckedWorldLocation.at(name, chunkX << 4, 0, chunkZ << 4).getPlotArea();
if (area == null) { if (area == null) {
throw new IllegalStateException(String.format( throw new IllegalStateException(String.format("Cannot generate chunk that does not belong to a plot area. World: %s",
"Cannot generate chunk that does not belong to a plot area. World: %s",
name name
)); ));
} }
@ -440,16 +434,9 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
private static final List<Biome> BIOMES; private static final List<Biome> BIOMES;
static { static {
Set<Biome> disabledBiomes = EnumSet.of(Biome.CUSTOM); ArrayList<Biome> biomes = new ArrayList<>(List.of(Biome.values()));
if (PlotSquared.platform().serverVersion()[1] <= 19) { biomes.remove(Biome.CUSTOM);
final Biome cherryGrove = Registry.BIOME.get(NamespacedKey.minecraft("cherry_grove")); BIOMES = List.copyOf(biomes);
if (cherryGrove != null) {
disabledBiomes.add(cherryGrove);
}
}
BIOMES = Arrays.stream(Biome.values())
.filter(not(disabledBiomes::contains))
.toList();
} }
@Override @Override

View File

@ -18,12 +18,16 @@
*/ */
package com.plotsquared.bukkit.inject; package com.plotsquared.bukkit.inject;
import cloud.commandframework.CommandManager;
import cloud.commandframework.execution.AsynchronousCommandExecutionCoordinator;
import cloud.commandframework.paper.PaperCommandManager;
import com.google.inject.AbstractModule; import com.google.inject.AbstractModule;
import com.google.inject.Provides; import com.google.inject.Provides;
import com.google.inject.Singleton; import com.google.inject.Singleton;
import com.google.inject.assistedinject.FactoryModuleBuilder; import com.google.inject.assistedinject.FactoryModuleBuilder;
import com.plotsquared.bukkit.BukkitPlatform; import com.plotsquared.bukkit.BukkitPlatform;
import com.plotsquared.bukkit.listener.SingleWorldListener; import com.plotsquared.bukkit.listener.SingleWorldListener;
import com.plotsquared.bukkit.player.BukkitPlayer;
import com.plotsquared.bukkit.player.BukkitPlayerManager; import com.plotsquared.bukkit.player.BukkitPlayerManager;
import com.plotsquared.bukkit.queue.BukkitChunkCoordinator; import com.plotsquared.bukkit.queue.BukkitChunkCoordinator;
import com.plotsquared.bukkit.queue.BukkitQueueCoordinator; import com.plotsquared.bukkit.queue.BukkitQueueCoordinator;
@ -47,6 +51,8 @@ import com.plotsquared.core.inject.factory.ChunkCoordinatorBuilderFactory;
import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory; import com.plotsquared.core.inject.factory.ChunkCoordinatorFactory;
import com.plotsquared.core.inject.factory.HybridPlotWorldFactory; import com.plotsquared.core.inject.factory.HybridPlotWorldFactory;
import com.plotsquared.core.inject.factory.ProgressSubscriberFactory; import com.plotsquared.core.inject.factory.ProgressSubscriberFactory;
import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.world.DefaultPlotAreaManager; import com.plotsquared.core.plot.world.DefaultPlotAreaManager;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.plot.world.SinglePlotAreaManager; import com.plotsquared.core.plot.world.SinglePlotAreaManager;
@ -68,10 +74,14 @@ import com.sk89q.worldedit.extension.platform.Actor;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender; import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.function.Function;
public class BukkitModule extends AbstractModule { public class BukkitModule extends AbstractModule {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + BukkitModule.class.getSimpleName()); private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + BukkitModule.class.getSimpleName());
@ -145,4 +155,27 @@ public class BukkitModule extends AbstractModule {
return EconHandler.nullEconHandler(); return EconHandler.nullEconHandler();
} }
@Provides
@Singleton
@NonNull CommandManager<PlotPlayer<?>> provideCommandManager() throws Exception {
final Function<PlotPlayer<?>, CommandSender> plotToPlatform = plotPlayer -> {
if (plotPlayer instanceof BukkitPlayer bukkitPlayer) {
return bukkitPlayer.getPlatformPlayer();
}
return Bukkit.getConsoleSender();
};
final Function<CommandSender, PlotPlayer<?>> platformToPlot = commandSender -> {
if (commandSender instanceof Player player) {
return BukkitUtil.adapt(player);
}
return ConsolePlayer.getConsole();
};
return new PaperCommandManager<>(
this.bukkitPlatform,
AsynchronousCommandExecutionCoordinator.<PlotPlayer<?>>builder().withSynchronousParsing().build(),
platformToPlot,
plotToPlatform
);
}
} }

View File

@ -72,7 +72,6 @@ import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState; import org.bukkit.block.BlockState;
import org.bukkit.block.data.BlockData; import org.bukkit.block.data.BlockData;
import org.bukkit.block.data.type.Dispenser; import org.bukkit.block.data.type.Dispenser;
import org.bukkit.block.data.type.Farmland;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.Fireball; import org.bukkit.entity.Fireball;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -747,37 +746,22 @@ public class BlockEventListener implements Listener {
Block block = event.getBlock(); Block block = event.getBlock();
Location location = BukkitUtil.adapt(block.getLocation()); Location location = BukkitUtil.adapt(block.getLocation());
PlotArea area = location.getPlotArea(); PlotArea area = location.getPlotArea();
if (area == null) { if (area == null) {
return; return;
} }
Plot plot = area.getOwnedPlot(location); Plot plot = area.getOwnedPlot(location);
if (plot == null) { if (plot == null) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
Material blockType = block.getType();
if (block.getBlockData() instanceof Farmland farmland && event if (blockType == Material.FARMLAND) {
.getNewState() if (!plot.getFlag(SoilDryFlag.class)) {
.getBlockData() instanceof Farmland newFarmland) {
int currentMoisture = farmland.getMoisture();
int newMoisture = newFarmland.getMoisture();
// farmland gets moisturizes
if (newMoisture > currentMoisture) {
return;
}
if (plot.getFlag(SoilDryFlag.class)) {
return;
}
plot.debug("Soil could not dry because soil-dry = false"); plot.debug("Soil could not dry because soil-dry = false");
event.setCancelled(true); event.setCancelled(true);
} }
} }
}
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
public void onChange(BlockFromToEvent event) { public void onChange(BlockFromToEvent event) {
@ -1116,7 +1100,6 @@ public class BlockEventListener implements Listener {
if (plot != null) { if (plot != null) {
plot.debug("Explosion was cancelled because explosion = false"); plot.debug("Explosion was cancelled because explosion = false");
} }
return;
} }
event.blockList().removeIf(blox -> !plot.equals(area.getOwnedPlot(BukkitUtil.adapt(blox.getLocation())))); event.blockList().removeIf(blox -> !plot.equals(area.getOwnedPlot(BukkitUtil.adapt(blox.getLocation()))));
} }

View File

@ -26,7 +26,6 @@ import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.flag.implementations.CopperOxideFlag; import com.plotsquared.core.plot.flag.implementations.CopperOxideFlag;
import com.plotsquared.core.plot.flag.implementations.MiscInteractFlag; import com.plotsquared.core.plot.flag.implementations.MiscInteractFlag;
import com.plotsquared.core.plot.flag.implementations.SculkSensorInteractFlag;
import com.plotsquared.core.util.PlotFlagUtil; import com.plotsquared.core.util.PlotFlagUtil;
import org.bukkit.Material; import org.bukkit.Material;
import org.bukkit.block.Block; import org.bukkit.block.Block;
@ -93,16 +92,12 @@ public class BlockEventListener117 implements Listener {
} }
Plot plot = location.getOwnedPlot(); Plot plot = location.getOwnedPlot();
if (plot == null && !PlotFlagUtil.isAreaRoadFlagsAndFlagEquals( if (plot == null && !PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, MiscInteractFlag.class, true) || plot != null && !plot.getFlag(
area, MiscInteractFlag.class)) {
MiscInteractFlag.class,
true
) || plot != null && (!plot.getFlag(MiscInteractFlag.class) || !plot.getFlag(SculkSensorInteractFlag.class))) {
if (plotPlayer != null) { if (plotPlayer != null) {
if (plot != null) { if (plot != null) {
if (!plot.isAdded(plotPlayer.getUUID())) { if (!plot.isAdded(plotPlayer.getUUID())) {
plot.debug(plotPlayer.getName() + " couldn't trigger sculk sensors because both " + plot.debug(plotPlayer.getName() + " couldn't trigger sculk sensors because misc-interact = false");
"sculk-sensor-interact and misc-interact = false");
event.setCancelled(true); event.setCancelled(true);
} }
} }
@ -113,15 +108,13 @@ public class BlockEventListener117 implements Listener {
if (plot != null) { if (plot != null) {
if (itemThrower == null && (itemThrower = item.getOwner()) == null) { if (itemThrower == null && (itemThrower = item.getOwner()) == null) {
plot.debug( plot.debug(
"A thrown item couldn't trigger sculk sensors because both sculk-sensor-interact and " + "A thrown item couldn't trigger sculk sensors because misc-interact = false and the item's owner could not be resolved.");
"misc-interact = false and the item's owner could not be resolved.");
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
if (!plot.isAdded(itemThrower)) { if (!plot.isAdded(itemThrower)) {
if (!plot.isAdded(itemThrower)) { if (!plot.isAdded(itemThrower)) {
plot.debug("A thrown item couldn't trigger sculk sensors because both sculk-sensor-interact and " + plot.debug("A thrown item couldn't trigger sculk sensors because misc-interact = false");
"misc-interact = false");
event.setCancelled(true); event.setCancelled(true);
} }
} }
@ -140,6 +133,7 @@ public class BlockEventListener117 implements Listener {
if (area == null) { if (area == null) {
for (int i = blocks.size() - 1; i >= 0; i--) { for (int i = blocks.size() - 1; i >= 0; i--) {
Location blockLocation = BukkitUtil.adapt(blocks.get(i).getLocation()); Location blockLocation = BukkitUtil.adapt(blocks.get(i).getLocation());
blockLocation = BukkitUtil.adapt(blocks.get(i).getLocation());
if (blockLocation.isPlotArea()) { if (blockLocation.isPlotArea()) {
blocks.remove(i); blocks.remove(i);
} }

View File

@ -234,8 +234,7 @@ public class ChunkListener implements Listener {
Chunk chunk = event.getChunk(); Chunk chunk = event.getChunk();
if (Settings.Chunk_Processor.AUTO_TRIM) { if (Settings.Chunk_Processor.AUTO_TRIM) {
String world = chunk.getWorld().getName(); String world = chunk.getWorld().getName();
if ((!Settings.Enabled_Components.WORLDS || !SinglePlotArea.isSinglePlotWorld(world)) && this.plotAreaManager.hasPlotArea( if ((!Settings.Enabled_Components.WORLDS || !SinglePlotArea.isSinglePlotWorld(world)) && this.plotAreaManager.hasPlotArea(world)) {
world)) {
if (unloadChunk(world, chunk, true)) { if (unloadChunk(world, chunk, true)) {
return; return;
} }

View File

@ -145,37 +145,54 @@ public class EntityEventListener implements Listener {
} }
CreatureSpawnEvent.SpawnReason reason = event.getSpawnReason(); CreatureSpawnEvent.SpawnReason reason = event.getSpawnReason();
switch (reason.toString()) { switch (reason.toString()) {
case "DISPENSE_EGG", "EGG", "OCELOT_BABY", "SPAWNER_EGG" -> { case "DISPENSE_EGG":
case "EGG":
case "OCELOT_BABY":
case "SPAWNER_EGG":
if (!area.isSpawnEggs()) { if (!area.isSpawnEggs()) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
} break;
case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL", case "REINFORCEMENTS":
"TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN" -> { case "NATURAL":
case "MOUNT":
case "PATROL":
case "RAID":
case "SHEARED":
case "SILVERFISH_BLOCK":
case "ENDER_PEARL":
case "TRAP":
case "VILLAGE_DEFENSE":
case "VILLAGE_INVASION":
case "BEEHIVE":
case "CHUNK_GEN":
if (!area.isMobSpawning()) { if (!area.isMobSpawning()) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
} break;
case "BREEDING" -> { case "BREEDING":
if (!area.isSpawnBreeding()) { if (!area.isSpawnBreeding()) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
} break;
case "BUILD_IRONGOLEM", "BUILD_SNOWMAN", "BUILD_WITHER", "CUSTOM" -> { case "BUILD_IRONGOLEM":
case "BUILD_SNOWMAN":
case "BUILD_WITHER":
case "CUSTOM":
if (!area.isSpawnCustom() && entity.getType() != EntityType.ARMOR_STAND) { if (!area.isSpawnCustom() && entity.getType() != EntityType.ARMOR_STAND) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
} break;
case "SPAWNER" -> { case "SPAWNER":
if (!area.isMobSpawnerSpawning()) { if (!area.isMobSpawnerSpawning()) {
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
} break;
} }
Plot plot = area.getOwnedPlotAbs(location); Plot plot = area.getOwnedPlotAbs(location);
if (plot == null) { if (plot == null) {

View File

@ -43,10 +43,10 @@ import com.plotsquared.core.plot.flag.implementations.DoneFlag;
import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag; import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag;
import com.plotsquared.core.plot.flag.types.BooleanFlag; import com.plotsquared.core.plot.flag.types.BooleanFlag;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.util.PlotFlagUtil;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import com.plotsquared.core.util.PlotFlagUtil;
import org.bukkit.Chunk; import org.bukkit.Chunk;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.TileState; import org.bukkit.block.TileState;
@ -178,41 +178,59 @@ public class PaperListener implements Listener {
} }
CreatureSpawnEvent.SpawnReason reason = event.getReason(); CreatureSpawnEvent.SpawnReason reason = event.getReason();
switch (reason.toString()) { switch (reason.toString()) {
case "DISPENSE_EGG", "EGG", "OCELOT_BABY", "SPAWNER_EGG" -> { case "DISPENSE_EGG":
case "EGG":
case "OCELOT_BABY":
case "SPAWNER_EGG":
if (!area.isSpawnEggs()) { if (!area.isSpawnEggs()) {
event.setShouldAbortSpawn(true); event.setShouldAbortSpawn(true);
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
} break;
case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL", "TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN" -> { case "REINFORCEMENTS":
case "NATURAL":
case "MOUNT":
case "PATROL":
case "RAID":
case "SHEARED":
case "SILVERFISH_BLOCK":
case "ENDER_PEARL":
case "TRAP":
case "VILLAGE_DEFENSE":
case "VILLAGE_INVASION":
case "BEEHIVE":
case "CHUNK_GEN":
if (!area.isMobSpawning()) { if (!area.isMobSpawning()) {
event.setShouldAbortSpawn(true); event.setShouldAbortSpawn(true);
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
} break;
case "BREEDING" -> { case "BREEDING":
if (!area.isSpawnBreeding()) { if (!area.isSpawnBreeding()) {
event.setShouldAbortSpawn(true); event.setShouldAbortSpawn(true);
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
} break;
case "BUILD_IRONGOLEM", "BUILD_SNOWMAN", "BUILD_WITHER", "CUSTOM" -> { case "BUILD_IRONGOLEM":
case "BUILD_SNOWMAN":
case "BUILD_WITHER":
case "CUSTOM":
if (!area.isSpawnCustom() && event.getType() != EntityType.ARMOR_STAND) { if (!area.isSpawnCustom() && event.getType() != EntityType.ARMOR_STAND) {
event.setShouldAbortSpawn(true); event.setShouldAbortSpawn(true);
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
} break;
case "SPAWNER" -> { case "SPAWNER":
if (!area.isMobSpawnerSpawning()) { if (!area.isMobSpawnerSpawning()) {
event.setShouldAbortSpawn(true); event.setShouldAbortSpawn(true);
event.setCancelled(true); event.setCancelled(true);
return; return;
} }
} break;
} }
Plot plot = location.getOwnedPlotAbs(); Plot plot = location.getOwnedPlotAbs();
if (plot == null) { if (plot == null) {
@ -439,11 +457,9 @@ public class PaperListener implements Listener {
} }
} }
private boolean getBooleanFlagValue( private boolean getBooleanFlagValue(@NonNull FlagContainer container,
@NonNull FlagContainer container,
@NonNull Class<? extends BooleanFlag<?>> flagClass, @NonNull Class<? extends BooleanFlag<?>> flagClass,
boolean defaultValue boolean defaultValue) {
) {
BooleanFlag<?> flag = container.getFlag(flagClass); BooleanFlag<?> flag = container.getFlag(flagClass);
return flag == null ? defaultValue : flag.getValue(); return flag == null ? defaultValue : flag.getValue();
} }

View File

@ -273,7 +273,8 @@ public class PlayerEventListener implements Listener {
Plot plot = plotPlayer.getCurrentPlot(); Plot plot = plotPlayer.getCurrentPlot();
// Check WorldEdit // Check WorldEdit
switch (parts[0]) { switch (parts[0]) {
case "up", "worldedit:up" -> { case "up":
case "worldedit:up":
if (plot == null || (!plot.isAdded(plotPlayer.getUUID()) && !plotPlayer.hasPermission( if (plot == null || (!plot.isAdded(plotPlayer.getUUID()) && !plotPlayer.hasPermission(
Permission.PERMISSION_ADMIN_BUILD_OTHER, Permission.PERMISSION_ADMIN_BUILD_OTHER,
true true
@ -282,7 +283,6 @@ public class PlayerEventListener implements Listener {
return; return;
} }
} }
}
if (plot == null && !area.isRoadFlags()) { if (plot == null && !area.isRoadFlags()) {
return; return;
} }
@ -572,8 +572,7 @@ public class PlayerEventListener implements Listener {
if (now == null) { if (now == null) {
try (final MetaDataAccess<Boolean> kickAccess = try (final MetaDataAccess<Boolean> kickAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) { pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse( if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) {
false)) {
pp.sendMessage( pp.sendMessage(
TranslatableCaption.of("permission.no_permission_event"), TranslatableCaption.of("permission.no_permission_event"),
TagResolver.resolver( TagResolver.resolver(
@ -666,8 +665,7 @@ public class PlayerEventListener implements Listener {
if (plot == null) { if (plot == null) {
try (final MetaDataAccess<Boolean> kickAccess = try (final MetaDataAccess<Boolean> kickAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) { pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse( if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) {
false)) {
pp.sendMessage( pp.sendMessage(
TranslatableCaption.of("permission.no_permission_event"), TranslatableCaption.of("permission.no_permission_event"),
TagResolver.resolver( TagResolver.resolver(
@ -1116,13 +1114,13 @@ public class PlayerEventListener implements Listener {
Location location = BukkitUtil.adapt(block.getLocation()); Location location = BukkitUtil.adapt(block.getLocation());
Action action = event.getAction(); Action action = event.getAction();
switch (action) { switch (action) {
case PHYSICAL -> { case PHYSICAL: {
eventType = PlayerBlockEventType.TRIGGER_PHYSICAL; eventType = PlayerBlockEventType.TRIGGER_PHYSICAL;
blocktype1 = BukkitAdapter.asBlockType(block.getType()); blocktype1 = BukkitAdapter.asBlockType(block.getType());
break;
} }
//todo rearrange the right click code. it is all over the place. //todo rearrange the right click code. it is all over the place.
case RIGHT_CLICK_BLOCK -> { case RIGHT_CLICK_BLOCK: {
Material blockType = block.getType(); Material blockType = block.getType();
eventType = PlayerBlockEventType.INTERACT_BLOCK; eventType = PlayerBlockEventType.INTERACT_BLOCK;
blocktype1 = BukkitAdapter.asBlockType(block.getType()); blocktype1 = BukkitAdapter.asBlockType(block.getType());
@ -1144,17 +1142,22 @@ public class PlayerEventListener implements Listener {
// in the following, lb needs to have the material of the item in hand i.e. type // in the following, lb needs to have the material of the item in hand i.e. type
switch (type.toString()) { switch (type.toString()) {
case "REDSTONE", "STRING", "PUMPKIN_SEEDS", "MELON_SEEDS", "COCOA_BEANS", "WHEAT_SEEDS", "BEETROOT_SEEDS", case "REDSTONE":
"SWEET_BERRIES", "GLOW_BERRIES" -> { case "STRING":
case "PUMPKIN_SEEDS":
case "MELON_SEEDS":
case "COCOA_BEANS":
case "WHEAT_SEEDS":
case "BEETROOT_SEEDS":
case "SWEET_BERRIES":
case "GLOW_BERRIES":
return; return;
} default:
default -> {
//eventType = PlayerBlockEventType.PLACE_BLOCK; //eventType = PlayerBlockEventType.PLACE_BLOCK;
if (type.isBlock()) { if (type.isBlock()) {
return; return;
} }
} }
}
if (PaperLib.isPaper()) { if (PaperLib.isPaper()) {
if (MaterialTags.SPAWN_EGGS.isTagged(type) || Material.EGG.equals(type)) { if (MaterialTags.SPAWN_EGGS.isTagged(type) || Material.EGG.equals(type)) {
eventType = PlayerBlockEventType.SPAWN_MOB; eventType = PlayerBlockEventType.SPAWN_MOB;
@ -1186,8 +1189,9 @@ public class PlayerEventListener implements Listener {
eventType = PlayerBlockEventType.READ; eventType = PlayerBlockEventType.READ;
break; break;
} }
break;
} }
case LEFT_CLICK_BLOCK -> { case LEFT_CLICK_BLOCK: {
Material blockType = block.getType(); Material blockType = block.getType();
// todo: when the code above is rearranged, it would be great to beautify this as well. // todo: when the code above is rearranged, it would be great to beautify this as well.
@ -1198,11 +1202,11 @@ public class PlayerEventListener implements Listener {
eventType = PlayerBlockEventType.INTERACT_BLOCK; eventType = PlayerBlockEventType.INTERACT_BLOCK;
blocktype1 = BukkitAdapter.asBlockType(block.getType()); blocktype1 = BukkitAdapter.asBlockType(block.getType());
break;
} }
default -> { default:
return; return;
} }
}
if (this.worldEdit != null && pp.getAttribute("worldedit")) { if (this.worldEdit != null && pp.getAttribute("worldedit")) {
if (event.getMaterial() == Material.getMaterial(this.worldEdit.getConfiguration().wandItem)) { if (event.getMaterial() == Material.getMaterial(this.worldEdit.getConfiguration().wandItem)) {
return; return;

View File

@ -30,9 +30,9 @@ import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.PlotHandler; import com.plotsquared.core.plot.PlotHandler;
import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag; import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.util.PlotFlagUtil;
import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import com.plotsquared.core.util.PlotFlagUtil;
import org.bukkit.entity.Entity; import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity; import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;

View File

@ -0,0 +1,63 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.managers;
/*
import com.google.inject.Singleton;
import org.bukkit.World;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import se.hyperver.hyperverse.Hyperverse;
import se.hyperver.hyperverse.world.WorldConfiguration;
import se.hyperver.hyperverse.world.WorldConfigurationBuilder;
import se.hyperver.hyperverse.world.WorldFeatures;
import se.hyperver.hyperverse.world.WorldType;
Hyperverse implementation is currently put on ice until Hyperverse is released on a stable line and deployed to the central
repository.
@Singleton
public class HyperverseWorldManager extends BukkitWorldManager {
@Override
public @Nullable World handleWorldCreation(@NonNull String worldName, @Nullable String generator) {
// First let Bukkit register the world
this.setGenerator(worldName, generator);
// Create the world
final WorldConfigurationBuilder worldConfigurationBuilder = WorldConfiguration.builder()
.setName(worldName).setType(WorldType.OVER_WORLD);
if (generator != null) {
worldConfigurationBuilder.setGenerator(generator).setWorldFeatures(WorldFeatures.FLATLAND);
}
try {
return Hyperverse.getApi().createWorld(worldConfigurationBuilder.createWorldConfiguration())
.getBukkitWorld();
} catch (final Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public String getName() {
return "bukkit-hyperverse";
}
}
*/

View File

@ -52,7 +52,7 @@ public class MVdWPlaceholders {
@Subscribe @Subscribe
public void onNewPlaceholder(final PlaceholderRegistry.@NonNull PlaceholderAddedEvent event) { public void onNewPlaceholder(final PlaceholderRegistry.@NonNull PlaceholderAddedEvent event) {
this.addPlaceholder(event.placeholder()); this.addPlaceholder(event.getPlaceholder());
} }
private void addPlaceholder(final @NonNull Placeholder placeholder) { private void addPlaceholder(final @NonNull Placeholder placeholder) {

View File

@ -176,10 +176,6 @@ public class BukkitPlayer extends PlotPlayer<Player> {
final Set<PermissionAttachmentInfo> effective = player.getEffectivePermissions(); final Set<PermissionAttachmentInfo> effective = player.getEffectivePermissions();
if (!effective.isEmpty()) { if (!effective.isEmpty()) {
for (PermissionAttachmentInfo attach : effective) { for (PermissionAttachmentInfo attach : effective) {
// Ignore all "false" permissions
if (!attach.getValue()) {
continue;
}
String permStr = attach.getPermission(); String permStr = attach.getPermission();
if (permStr.startsWith(stubPlus)) { if (permStr.startsWith(stubPlus)) {
hasAny = true; hasAny = true;

View File

@ -62,6 +62,7 @@ public class GenChunk extends ZeroedDelegateScopedQueueCoordinator {
/** /**
* @param minY minimum world Y, inclusive * @param minY minimum world Y, inclusive
* @param maxY maximum world Y, inclusive * @param maxY maximum world Y, inclusive
*
* @since 6.6.0 * @since 6.6.0
*/ */
public GenChunk(int minY, int maxY) { public GenChunk(int minY, int maxY) {
@ -109,9 +110,9 @@ public class GenChunk extends ZeroedDelegateScopedQueueCoordinator {
*/ */
public void setChunk(@NonNull ChunkWrapper wrap) { public void setChunk(@NonNull ChunkWrapper wrap) {
chunk = null; chunk = null;
world = wrap.world(); world = wrap.world;
chunkX = wrap.x(); chunkX = wrap.x;
chunkZ = wrap.z(); chunkZ = wrap.z;
} }
@Override @Override

View File

@ -18,8 +18,6 @@
*/ */
package com.plotsquared.bukkit.schematic; package com.plotsquared.bukkit.schematic;
import com.destroystokyo.paper.profile.PlayerProfile;
import com.destroystokyo.paper.profile.ProfileProperty;
import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitUtil;
import com.sk89q.jnbt.ByteTag; import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
@ -30,20 +28,13 @@ import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.BukkitAdapter; import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.item.ItemType; import com.sk89q.worldedit.world.item.ItemType;
import io.papermc.lib.PaperLib;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.ChatColor; import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Banner;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.Container; import org.bukkit.block.Container;
import org.bukkit.block.Sign; import org.bukkit.block.Sign;
import org.bukkit.block.Skull; import org.bukkit.block.Skull;
import org.bukkit.block.banner.Pattern;
import org.bukkit.block.banner.PatternType;
import org.bukkit.enchantments.Enchantment; import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.Inventory; import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack; import org.bukkit.inventory.ItemStack;
@ -54,15 +45,11 @@ import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.Objects;
import java.util.UUID;
public class StateWrapper { public class StateWrapper {
public CompoundTag tag; public org.bukkit.block.BlockState state = null;
public CompoundTag tag = null;
private boolean paperErrorTextureSent = false;
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + StateWrapper.class.getSimpleName());
public StateWrapper(CompoundTag tag) { public StateWrapper(CompoundTag tag) {
this.tag = tag; this.tag = tag;
@ -240,8 +227,9 @@ public class StateWrapper {
return true; return true;
} }
String player = skullOwner.getString("Name"); String player = skullOwner.getString("Name");
if (player == null || player.isEmpty()) {
if (player != null && !player.isEmpty()) { return false;
}
try { try {
skull.setOwningPlayer(Bukkit.getOfflinePlayer(player)); skull.setOwningPlayer(Bukkit.getOfflinePlayer(player));
skull.update(true); skull.update(true);
@ -250,56 +238,6 @@ public class StateWrapper {
} }
return true; return true;
} }
final CompoundTag properties = (CompoundTag) skullOwner.getValue().get("Properties");
if (properties == null) {
return false;
}
final ListTag textures = properties.getListTag("textures");
if (textures.getValue().isEmpty()) {
return false;
}
final CompoundTag textureCompound = (CompoundTag) textures.getValue().get(0);
if (textureCompound == null) {
return false;
}
String textureValue = textureCompound.getString("Value");
if (textureValue == null) {
return false;
}
if (!PaperLib.isPaper()) {
if (!paperErrorTextureSent) {
paperErrorTextureSent = true;
LOGGER.error("Failed to populate skull data in your road schematic - This is a Spigot limitation.");
}
return false;
}
final PlayerProfile profile = Bukkit.createProfile(UUID.randomUUID());
profile.setProperty(new ProfileProperty("textures", textureValue));
skull.setPlayerProfile(profile);
skull.update(true);
return true;
}
return false;
}
case "banner" -> {
if (state instanceof Banner banner) {
List<Tag> patterns = this.tag.getListTag("Patterns").getValue();
if (patterns == null || patterns.isEmpty()) {
return false;
}
banner.setPatterns(patterns.stream().map(t -> (CompoundTag) t).map(compoundTag -> {
DyeColor color = DyeColor.getByWoolData((byte) compoundTag.getInt("Color"));
PatternType patternType = PatternType.getByIdentifier(compoundTag.getString("Pattern"));
if (color == null || patternType == null) {
return null;
}
return new Pattern(color, patternType);
}).filter(Objects::nonNull).toList());
banner.update(true);
return true;
}
return false; return false;
} }
} }

View File

@ -124,7 +124,7 @@ public class BukkitSetupUtils extends SetupUtils {
public String setupWorld(PlotAreaBuilder builder) { public String setupWorld(PlotAreaBuilder builder) {
this.updateGenerators(false); this.updateGenerators(false);
ConfigurationNode[] steps = builder.settingsNodesWrapper() == null ? ConfigurationNode[] steps = builder.settingsNodesWrapper() == null ?
new ConfigurationNode[0] : builder.settingsNodesWrapper().settingsNodes(); new ConfigurationNode[0] : builder.settingsNodesWrapper().getSettingsNodes();
String world = builder.worldName(); String world = builder.worldName();
PlotAreaType type = builder.plotAreaType(); PlotAreaType type = builder.plotAreaType();
String worldPath = "worlds." + builder.worldName(); String worldPath = "worlds." + builder.worldName();

View File

@ -28,32 +28,24 @@ import java.nio.file.Paths;
import java.util.stream.Stream; import java.util.stream.Stream;
/** /**
* This is a helper class which replaces older syntax no longer supported by MiniMessage with replacements in messages_%.json. * This is a helper class which replaces occurrences of 'suggest_command' with 'run_command' in messages_%.json.
* MiniMessage changed the syntax between major releases. To warrant a smooth upgrade, we attempt to replace any occurrences * MiniMessage changed the syntax between major releases. To warrant a smooth upgrade, we attempt to replace any occurrences
* while loading PlotSquared. * while loading PlotSquared.
* *
* @since 7.0.0 * @since TODO
*/ */
@NotPublic @NotPublic
public class TranslationUpdateManager { public class TranslationUpdateManager {
public static void upgradeTranslationFile() throws IOException { public static void upgradeTranslationFile() throws IOException {
String suggestCommand = "suggest_command"; String searchText = "suggest_command";
String suggestCommandReplacement = "run_command"; String replacementText = "run_command";
String minHeight = "minHeight";
String minheightReplacement = "minheight";
String maxHeight = "maxHeight";
String maxheightReplacement = "maxheight";
try (Stream<Path> paths = Files.walk(Paths.get(PlotSquared.platform().getDirectory().toPath().resolve("lang").toUri()))) { try (Stream<Path> paths = Files.walk(Paths.get(PlotSquared.platform().getDirectory().toPath().resolve("lang").toUri()))) {
paths paths
.filter(Files::isRegularFile) .filter(Files::isRegularFile)
.filter(p -> p.getFileName().toString().matches("messages_[a-z]{2}\\.json")) .filter(p -> p.getFileName().toString().matches("messages_[a-z]{2}\\.json"))
.forEach(p -> { .forEach(p -> replaceInFile(p, searchText, replacementText));
replaceInFile(p, suggestCommand, suggestCommandReplacement);
replaceInFile(p, minHeight, minheightReplacement);
replaceInFile(p, maxHeight, maxheightReplacement);
});
} }
} }
@ -68,5 +60,4 @@ public class TranslationUpdateManager {
e.printStackTrace(); e.printStackTrace();
} }
} }
} }

View File

@ -54,8 +54,7 @@ public class UpdateUtility implements Listener {
internalVersion = PlotSquared.get().getVersion(); internalVersion = PlotSquared.get().getVersion();
} }
@SuppressWarnings({"deprecation", "DefaultCharset"}) @SuppressWarnings({"deprecation", "DefaultCharset"}) // Suppress Json deprecation, we can't use features from gson 2.8.1 and newer yet
// Suppress Json deprecation, we can't use features from gson 2.8.1 and newer yet
public void updateChecker() { public void updateChecker() {
task = Bukkit.getScheduler().runTaskTimerAsynchronously(this.javaPlugin, () -> { task = Bukkit.getScheduler().runTaskTimerAsynchronously(this.javaPlugin, () -> {
try { try {

View File

@ -111,8 +111,8 @@ public class SQLiteUUIDService implements UUIDService, Consumer<List<UUIDMapping
try (final PreparedStatement statement = getConnection() try (final PreparedStatement statement = getConnection()
.prepareStatement("INSERT OR REPLACE INTO `usercache` (`uuid`, `username`) VALUES(?, ?)")) { .prepareStatement("INSERT OR REPLACE INTO `usercache` (`uuid`, `username`) VALUES(?, ?)")) {
for (final UUIDMapping mapping : uuidWrappers) { for (final UUIDMapping mapping : uuidWrappers) {
statement.setString(1, mapping.uuid().toString()); statement.setString(1, mapping.getUuid().toString());
statement.setString(2, mapping.username()); statement.setString(2, mapping.getUsername());
statement.executeUpdate(); statement.executeUpdate();
} }
} catch (SQLException e) { } catch (SQLException e) {

View File

@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
## Enforcement ## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at contact<at>intellectualsites.com. All reported by contacting the project team at contact@intellectualsites.com. All
complaints will be reviewed and investigated and will result in a response that complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident. obligated to maintain confidentiality with regard to the reporter of an incident.

View File

@ -15,6 +15,11 @@ dependencies {
api("net.kyori:adventure-api") api("net.kyori:adventure-api")
api("net.kyori:adventure-text-minimessage") api("net.kyori:adventure-text-minimessage")
// Cloud
api(libs.cloudServices)
api(libs.cloudCore)
api(libs.cloudAnnotations)
// Guice // Guice
api(libs.guice) { api(libs.guice) {
exclude(group = "com.google.guava") exclude(group = "com.google.guava")
@ -40,7 +45,6 @@ dependencies {
// Other libraries // Other libraries
api(libs.prtree) api(libs.prtree)
api(libs.aopalliance) api(libs.aopalliance)
api(libs.cloudServices)
api(libs.arkitektonika) api(libs.arkitektonika)
api("com.intellectualsites.paster:Paster") api("com.intellectualsites.paster:Paster")
api("com.intellectualsites.informative-annotations:informative-annotations") api("com.intellectualsites.informative-annotations:informative-annotations")
@ -68,8 +72,8 @@ tasks {
val isRelease = if (rootProject.version.toString().endsWith("-SNAPSHOT")) "TODO" else rootProject.version.toString() val isRelease = if (rootProject.version.toString().endsWith("-SNAPSHOT")) "TODO" else rootProject.version.toString()
val opt = options as StandardJavadocDocletOptions val opt = options as StandardJavadocDocletOptions
opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-core/" + libs.worldeditCore.get().versionConstraint.toString()) opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-core/" + libs.worldeditCore.get().versionConstraint.toString())
opt.links("https://jd.advntr.dev/api/4.14.0/") opt.links("https://jd.adventure.kyori.net/api/4.12.0/")
opt.links("https://jd.advntr.dev/text-minimessage/4.14.0/") opt.links("https://jd.adventure.kyori.net/text-minimessage/4.12.0/")
opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/") opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/")
opt.links("https://checkerframework.org/api/") opt.links("https://checkerframework.org/api/")
opt.links("https://javadoc.io/doc/com.intellectualsites.informative-annotations/informative-annotations/latest/") opt.links("https://javadoc.io/doc/com.intellectualsites.informative-annotations/informative-annotations/latest/")

View File

@ -270,11 +270,7 @@ public class PlotSquared {
captionMap = this.captionLoader.loadAll(this.platform.getDirectory().toPath().resolve("lang")); captionMap = this.captionLoader.loadAll(this.platform.getDirectory().toPath().resolve("lang"));
} else { } else {
String fileName = "messages_" + Settings.Enabled_Components.DEFAULT_LOCALE + ".json"; String fileName = "messages_" + Settings.Enabled_Components.DEFAULT_LOCALE + ".json";
captionMap = this.captionLoader.loadOrCreateSingle(this.platform captionMap = this.captionLoader.loadOrCreateSingle(this.platform.getDirectory().toPath().resolve("lang").resolve(fileName));
.getDirectory()
.toPath()
.resolve("lang")
.resolve(fileName));
} }
this.captionMaps.put(TranslatableCaption.DEFAULT_NAMESPACE, captionMap); this.captionMaps.put(TranslatableCaption.DEFAULT_NAMESPACE, captionMap);
LOGGER.info( LOGGER.info(
@ -1015,7 +1011,7 @@ public class PlotSquared {
/** /**
* Setup the configuration for a plot world based on world arguments. * Setup the configuration for a plot world based on world arguments.
* <p> *
* *
* <i>e.g. /mv create &lt;world&gt; normal -g PlotSquared:&lt;args&gt;</i> * <i>e.g. /mv create &lt;world&gt; normal -g PlotSquared:&lt;args&gt;</i>
* *

View File

@ -136,9 +136,13 @@ public class SimpleBackupManager implements BackupManager {
return this.backupLimit; return this.backupLimit;
} }
private record PlotCacheKey( private static final class PlotCacheKey {
Plot plot
) { private final Plot plot;
private PlotCacheKey(Plot plot) {
this.plot = plot;
}
@Override @Override
public boolean equals(final Object o) { public boolean equals(final Object o) {

View File

@ -1,173 +0,0 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.command;
import com.google.inject.Inject;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.util.PlayerManager;
import com.plotsquared.core.util.TabCompletions;
import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeoutException;
@CommandDeclaration(command = "add",
usage = "/plot add <player | *>",
category = CommandCategory.SETTINGS,
permission = "plots.add",
requiredType = RequiredType.PLAYER)
public class Add extends Command {
private final EventDispatcher eventDispatcher;
@Inject
public Add(final @NonNull EventDispatcher eventDispatcher) {
super(MainCommand.getInstance(), true);
this.eventDispatcher = eventDispatcher;
}
@Override
public CompletableFuture<Boolean> execute(
final PlotPlayer<?> player,
String[] args,
RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone
) throws CommandException {
final Plot plot = check(player.getCurrentPlot(), TranslatableCaption.of("errors.not_in_plot"));
checkTrue(plot.hasOwner(), TranslatableCaption.of("info.plot_unowned"));
checkTrue(
plot.isOwner(player.getUUID()) || player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_TRUST),
TranslatableCaption.of("permission.no_plot_perms")
);
checkTrue(
args.length == 1,
TranslatableCaption.of("commandconfig.command_syntax"),
TagResolver.resolver("value", Tag.inserting(Component.text("/plot add <player | *>")))
);
final CompletableFuture<Boolean> future = new CompletableFuture<>();
PlayerManager.getUUIDsFromString(args[0], (uuids, throwable) -> {
if (throwable != null) {
if (throwable instanceof TimeoutException) {
player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout"));
} else {
player.sendMessage(
TranslatableCaption.of("errors.invalid_player"),
TagResolver.resolver("value", Tag.inserting(Component.text(args[0])))
);
}
future.completeExceptionally(throwable);
return;
} else {
try {
checkTrue(!uuids.isEmpty(), TranslatableCaption.of("errors.invalid_player"),
TagResolver.resolver("value", Tag.inserting(Component.text(args[0])))
);
Iterator<UUID> iterator = uuids.iterator();
int size = plot.getTrusted().size() + plot.getMembers().size();
while (iterator.hasNext()) {
UUID uuid = iterator.next();
if (uuid == DBFunc.EVERYONE && !(player.hasPermission(Permission.PERMISSION_TRUST_EVERYONE) || player.hasPermission(
Permission.PERMISSION_ADMIN_COMMAND_TRUST))) {
player.sendMessage(
TranslatableCaption.of("errors.invalid_player"),
TagResolver.resolver("value", Tag.inserting(
PlayerManager.resolveName(uuid).toComponent(player)
))
);
iterator.remove();
continue;
}
if (plot.isOwner(uuid)) {
player.sendMessage(
TranslatableCaption.of("member.already_added"),
TagResolver.resolver("player", Tag.inserting(
PlayerManager.resolveName(uuid).toComponent(player)
))
);
iterator.remove();
continue;
}
if (plot.getMembers().contains(uuid)) {
player.sendMessage(
TranslatableCaption.of("member.already_added"),
TagResolver.resolver("player", Tag.inserting(
PlayerManager.resolveName(uuid).toComponent(player)
))
);
iterator.remove();
continue;
}
size += plot.getTrusted().contains(uuid) ? 0 : 1;
}
checkTrue(!uuids.isEmpty(), null);
int localAddSize = plot.getMembers().size();
int maxAddSize = player.hasPermissionRange(Permission.PERMISSION_ADD, Settings.Limit.MAX_PLOTS);
if (localAddSize >= maxAddSize) {
player.sendMessage(
TranslatableCaption.of("members.plot_max_members_added"),
TagResolver.resolver("amount", Tag.inserting(Component.text(localAddSize)))
);
return;
}
// Success
confirm.run(this, () -> {
for (UUID uuid : uuids) {
if (uuid != DBFunc.EVERYONE) {
if (!plot.removeTrusted(uuid)) {
if (plot.getDenied().contains(uuid)) {
plot.removeDenied(uuid);
}
}
}
plot.addMember(uuid);
this.eventDispatcher.callMember(player, plot, uuid, true);
player.sendMessage(TranslatableCaption.of("member.member_added"));
}
}, null);
} catch (final Throwable exception) {
future.completeExceptionally(exception);
return;
}
}
future.complete(true);
});
return future;
}
@Override
public Collection<Command> tab(final PlotPlayer<?> player, final String[] args, final boolean space) {
return TabCompletions.completePlayers(player, String.join(",", args).trim(), Collections.emptyList());
}
}

View File

@ -1,210 +0,0 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.command;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.query.PlotQuery;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeoutException;
@CommandDeclaration(command = "alias",
permission = "plots.alias",
usage = "/plot alias <set | remove> <alias>",
aliases = {"setalias", "sa", "name", "rename", "setname", "seta", "nameplot"},
category = CommandCategory.SETTINGS,
requiredType = RequiredType.PLAYER)
public class Alias extends SubCommand {
private static final Command SET_COMMAND = new Command(null, false, "set", null, RequiredType.NONE, null) {
};
private static final Command REMOVE_COMMAND = new Command(null, false, "remove", null, RequiredType.NONE, null) {
};
@Override
public boolean onCommand(PlotPlayer<?> player, String[] args) {
if (args.length == 0) {
sendUsage(player);
return false;
}
Location location = player.getLocation();
Plot plot = location.getPlotAbs();
if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false;
}
if (!plot.hasOwner()) {
player.sendMessage(TranslatableCaption.of("working.plot_not_claimed"));
return false;
}
boolean result = false;
boolean owner = plot.isOwner(player.getUUID());
boolean permission;
boolean admin;
switch (args[0].toLowerCase()) {
case "set" -> {
if (args.length != 2) {
sendUsage(player);
return false;
}
permission = isPermitted(player, Permission.PERMISSION_ALIAS_SET);
admin = isPermitted(player, Permission.PERMISSION_ADMIN_ALIAS_SET);
if (!admin && !owner) {
player.sendMessage(TranslatableCaption.of("permission.no_plot_perms"));
return false;
}
if (permission) { // is either admin or owner
setAlias(player, plot, args[1]);
return true;
} else {
player.sendMessage(
TranslatableCaption.of("permission.no_permission"),
TagResolver.resolver(
"node",
Tag.inserting(Permission.PERMISSION_ALIAS_SET)
)
);
}
}
case "remove" -> {
permission = isPermitted(player, Permission.PERMISSION_ALIAS_REMOVE);
admin = isPermitted(player, Permission.PERMISSION_ADMIN_ALIAS_REMOVE);
if (!admin && !owner) {
player.sendMessage(TranslatableCaption.of("permission.no_plot_perms"));
return false;
}
if (permission) {
result = removeAlias(player, plot);
} else {
player.sendMessage(
TranslatableCaption.of("permission.no_permission"),
TagResolver.resolver(
"node",
Tag.inserting(Permission.PERMISSION_ALIAS_REMOVE)
)
);
}
}
default -> {
sendUsage(player);
result = false;
}
}
return result;
}
@Override
public Collection<Command> tab(PlotPlayer<?> player, String[] args, boolean space) {
final List<Command> commands = new ArrayList<>(2);
if (args.length == 1) {
if ("set".startsWith(args[0])) {
commands.add(SET_COMMAND);
}
if ("remove".startsWith(args[0])) {
commands.add(REMOVE_COMMAND);
}
return commands;
}
return Collections.emptySet();
}
private void setAlias(PlotPlayer<?> player, Plot plot, String alias) {
if (alias.isEmpty()) {
sendUsage(player);
} else if (alias.length() >= 50) {
player.sendMessage(TranslatableCaption.of("alias.alias_too_long"));
} else if (MathMan.isInteger(alias)) {
player.sendMessage(TranslatableCaption.of("flag.not_valid_value")); // TODO this is obviously wrong
} else {
if (PlotQuery.newQuery().inArea(plot.getArea())
.withAlias(alias)
.anyMatch()) {
player.sendMessage(
TranslatableCaption.of("alias.alias_is_taken"),
TagResolver.resolver("alias", Tag.inserting(Component.text(alias)))
);
return;
}
if (Settings.UUID.OFFLINE) {
plot.setAlias(alias);
player.sendMessage(
TranslatableCaption.of("alias.alias_set_to"),
TagResolver.resolver("alias", Tag.inserting(Component.text(alias)))
);
return;
}
PlotSquared.get().getImpromptuUUIDPipeline().getSingle(alias, ((uuid, throwable) -> {
if (throwable instanceof TimeoutException) {
player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout"));
} else if (uuid != null) {
player.sendMessage(
TranslatableCaption.of("alias.alias_is_taken"),
TagResolver.resolver("alias", Tag.inserting(Component.text(alias)))
);
} else {
plot.setAlias(alias);
player.sendMessage(
TranslatableCaption.of("alias.alias_set_to"),
TagResolver.resolver("alias", Tag.inserting(Component.text(alias)))
);
}
}));
}
}
private boolean removeAlias(PlotPlayer<?> player, Plot plot) {
String alias = plot.getAlias();
if (!plot.getAlias().isEmpty()) {
player.sendMessage(
TranslatableCaption.of("alias.alias_removed"),
TagResolver.resolver("alias", Tag.inserting(Component.text(alias)))
);
} else {
player.sendMessage(
TranslatableCaption.of("alias.no_alias_set")
);
}
plot.setAlias(null);
return true;
}
private boolean isPermitted(PlotPlayer<?> player, Permission permission) {
return player.hasPermission(permission);
}
}

View File

@ -35,7 +35,6 @@ import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
import com.plotsquared.core.plot.world.PlotAreaManager; import com.plotsquared.core.plot.world.PlotAreaManager;
import com.plotsquared.core.services.plots.AutoQuery;
import com.plotsquared.core.services.plots.AutoService; import com.plotsquared.core.services.plots.AutoService;
import com.plotsquared.core.util.EconHandler; import com.plotsquared.core.util.EconHandler;
import com.plotsquared.core.util.EventDispatcher; import com.plotsquared.core.util.EventDispatcher;
@ -296,13 +295,10 @@ public class Auto extends SubCommand {
} }
if (this.econHandler != null && plotarea.useEconomy()) { if (this.econHandler != null && plotarea.useEconomy()) {
PlotExpression costExp = plotarea.getPrices().get("claim"); PlotExpression costExp = plotarea.getPrices().get("claim");
PlotExpression mergeCostExp = plotarea.getPrices().get("merge");
int size = sizeX * sizeZ;
double mergeCost = size <= 1 || mergeCostExp == null ? 0d : mergeCostExp.evaluate(size);
double cost = costExp.evaluate(Settings.Limit.GLOBAL ? double cost = costExp.evaluate(Settings.Limit.GLOBAL ?
player.getPlotCount() : player.getPlotCount() :
player.getPlotCount(plotarea.getWorldName())); player.getPlotCount(plotarea.getWorldName()));
cost = size * cost + mergeCost; cost = (sizeX * sizeZ) * cost;
if (cost > 0d) { if (cost > 0d) {
if (!this.econHandler.isSupported()) { if (!this.econHandler.isSupported()) {
player.sendMessage(TranslatableCaption.of("economy.vault_or_consumer_null")); player.sendMessage(TranslatableCaption.of("economy.vault_or_consumer_null"));
@ -330,7 +326,7 @@ public class Auto extends SubCommand {
} }
List<Plot> plots = this.servicePipeline List<Plot> plots = this.servicePipeline
.pump(new AutoQuery(player, null, sizeX, sizeZ, plotarea)) .pump(new AutoService.AutoQuery(player, null, sizeX, sizeZ, plotarea))
.through(AutoService.class) .through(AutoService.class)
.getResult(); .getResult();

View File

@ -107,7 +107,9 @@ public class Clear extends Command {
} }
BackupManager.backup(player, plot, () -> { BackupManager.backup(player, plot, () -> {
final long start = System.currentTimeMillis(); final long start = System.currentTimeMillis();
boolean result = plot.getPlotModificationManager().clear(true, false, player, () -> TaskManager.runTask(() -> { boolean result = plot.getPlotModificationManager().clear(true, false, player, () -> {
plot.getPlotModificationManager().unlink();
TaskManager.runTask(() -> {
plot.removeRunning(); plot.removeRunning();
// If the state changes, then mark it as no longer done // If the state changes, then mark it as no longer done
if (DoneFlag.isDone(plot)) { if (DoneFlag.isDone(plot)) {
@ -135,7 +137,8 @@ public class Clear extends Command {
.tag("plot", Tag.inserting(Component.text(plot.getId().toString()))) .tag("plot", Tag.inserting(Component.text(plot.getId().toString())))
.build() .build()
); );
})); });
});
if (!result) { if (!result) {
player.sendMessage(TranslatableCaption.of("errors.wait_for_timer")); player.sendMessage(TranslatableCaption.of("errors.wait_for_timer"));
} else { } else {

View File

@ -46,7 +46,6 @@ import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Objects;
import java.util.Set; import java.util.Set;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeoutException; import java.util.concurrent.TimeoutException;
@ -78,7 +77,8 @@ public class Cluster extends SubCommand {
} }
String sub = args[0].toLowerCase(); String sub = args[0].toLowerCase();
switch (sub) { switch (sub) {
case "l", "list" -> { case "l":
case "list": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_LIST)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_LIST)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -133,7 +133,8 @@ public class Cluster extends SubCommand {
} }
return true; return true;
} }
case "c", "create" -> { case "c":
case "create": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_CREATE)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_CREATE)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -268,7 +269,9 @@ public class Cluster extends SubCommand {
); );
return true; return true;
} }
case "disband", "del", "delete" -> { case "disband":
case "del":
case "delete": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_DELETE)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_DELETE)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -327,7 +330,8 @@ public class Cluster extends SubCommand {
)); ));
return true; return true;
} }
case "res", "resize" -> { case "res":
case "resize": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_RESIZE)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_RESIZE)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -448,7 +452,9 @@ public class Cluster extends SubCommand {
player.sendMessage(TranslatableCaption.of("cluster.cluster_resized")); player.sendMessage(TranslatableCaption.of("cluster.cluster_resized"));
return true; return true;
} }
case "add", "inv", "invite" -> { case "add":
case "inv":
case "invite": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_INVITE)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_INVITE)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -517,7 +523,9 @@ public class Cluster extends SubCommand {
}); });
return true; return true;
} }
case "k", "remove", "kick" -> { case "k":
case "remove":
case "kick": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_KICK)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_KICK)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -597,7 +605,8 @@ public class Cluster extends SubCommand {
}); });
return true; return true;
} }
case "quit", "leave" -> { case "quit":
case "leave": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_LEAVE)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_LEAVE)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -658,7 +667,7 @@ public class Cluster extends SubCommand {
removePlayerPlots(cluster, uuid, player.getLocation().getWorldName()); removePlayerPlots(cluster, uuid, player.getLocation().getWorldName());
return true; return true;
} }
case "members" -> { case "members": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_HELPERS)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_HELPERS)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -719,7 +728,9 @@ public class Cluster extends SubCommand {
}); });
return true; return true;
} }
case "spawn", "home", "tp" -> { case "spawn":
case "home":
case "tp": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_TP)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_TP)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -767,7 +778,10 @@ public class Cluster extends SubCommand {
player.sendMessage(TranslatableCaption.of("cluster.cluster_teleporting")); player.sendMessage(TranslatableCaption.of("cluster.cluster_teleporting"));
return true; return true;
} }
case "i", "info", "show", "information" -> { case "i":
case "info":
case "show":
case "information": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_INFO)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_INFO)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),
@ -814,7 +828,11 @@ public class Cluster extends SubCommand {
player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout")); player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout"));
} else { } else {
final String owner; final String owner;
owner = Objects.requireNonNullElse(username, "unknown"); if (username == null) {
owner = "unknown";
} else {
owner = username;
}
String name = cluster.getName(); String name = cluster.getName();
String size = (cluster.getP2().getX() - cluster.getP1().getX() + 1) + "x" + ( String size = (cluster.getP2().getX() - cluster.getP1().getX() + 1) + "x" + (
cluster.getP2().getY() - cluster.getP1().getY() + 1); cluster.getP2().getY() - cluster.getP1().getY() + 1);
@ -832,7 +850,9 @@ public class Cluster extends SubCommand {
}); });
return true; return true;
} }
case "sh", "setspawn", "sethome" -> { case "sh":
case "setspawn":
case "sethome": {
if (!player.hasPermission(Permission.PERMISSION_CLUSTER_SETHOME)) { if (!player.hasPermission(Permission.PERMISSION_CLUSTER_SETHOME)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.no_permission"), TranslatableCaption.of("permission.no_permission"),

View File

@ -559,10 +559,9 @@ public abstract class Command {
public Collection<Command> tab(PlotPlayer<?> player, String[] args, boolean space) { public Collection<Command> tab(PlotPlayer<?> player, String[] args, boolean space) {
switch (args.length) { switch (args.length) {
case 0 -> { case 0:
return this.allCommands; return this.allCommands;
} case 1:
case 1 -> {
String arg = args[0].toLowerCase(); String arg = args[0].toLowerCase();
if (space) { if (space) {
Command cmd = getCommand(arg); Command cmd = getCommand(arg);
@ -581,8 +580,7 @@ public abstract class Command {
} }
return commands; return commands;
} }
} default:
default -> {
Command cmd = getCommand(args[0]); Command cmd = getCommand(args[0]);
if (cmd != null) { if (cmd != null) {
return cmd.tab(player, Arrays.copyOfRange(args, 1, args.length), space); return cmd.tab(player, Arrays.copyOfRange(args, 1, args.length), space);
@ -591,7 +589,6 @@ public abstract class Command {
} }
} }
} }
}
@Override @Override
public String toString() { public String toString() {

View File

@ -69,8 +69,7 @@ public class Copy extends SubCommand {
plot1.getPlotModificationManager().copy(plot2, player).thenAccept(result -> { plot1.getPlotModificationManager().copy(plot2, player).thenAccept(result -> {
if (result) { if (result) {
player.sendMessage( player.sendMessage(TranslatableCaption.of("move.copy_success"),
TranslatableCaption.of("move.copy_success"),
TagResolver.builder() TagResolver.builder()
.tag("origin", Tag.inserting(Component.text(plot1.toString()))) .tag("origin", Tag.inserting(Component.text(plot1.toString())))
.tag("target", Tag.inserting(Component.text(plot2.toString()))) .tag("target", Tag.inserting(Component.text(plot2.toString())))

View File

@ -75,13 +75,11 @@ public class DebugRoadRegen extends SubCommand {
} }
String kind = args[0].toLowerCase(); String kind = args[0].toLowerCase();
switch (kind) { switch (kind) {
case "plot" -> { case "plot":
return regenPlot(player); return regenPlot(player);
} case "region":
case "region" -> {
return regenRegion(player, Arrays.copyOfRange(args, 1, args.length)); return regenRegion(player, Arrays.copyOfRange(args, 1, args.length));
} default:
default -> {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("commandconfig.command_syntax"), TranslatableCaption.of("commandconfig.command_syntax"),
TagResolver.resolver("value", Tag.inserting(Component.text(DebugRoadRegen.USAGE))) TagResolver.resolver("value", Tag.inserting(Component.text(DebugRoadRegen.USAGE)))
@ -89,7 +87,6 @@ public class DebugRoadRegen extends SubCommand {
return false; return false;
} }
} }
}
public boolean regenPlot(PlotPlayer<?> player) { public boolean regenPlot(PlotPlayer<?> player) {
Location location = player.getLocation(); Location location = player.getLocation();

View File

@ -103,7 +103,7 @@ public class Done extends SubCommand {
public void run(PlotAnalysis value) { public void run(PlotAnalysis value) {
plot.removeRunning(); plot.removeRunning();
boolean result = boolean result =
value.getComplexity(doneRequirements) >= doneRequirements.THRESHOLD; value.getComplexity(doneRequirements) <= doneRequirements.THRESHOLD;
finish(plot, player, result); finish(plot, player, result);
} }
}); });

View File

@ -185,11 +185,8 @@ public class Download extends SubCommand {
if (Settings.Web.LEGACY_WEBINTERFACE) { if (Settings.Web.LEGACY_WEBINTERFACE) {
schematicHandler schematicHandler
.getCompoundTag(plot) .getCompoundTag(plot)
.whenComplete((compoundTag, throwable) -> schematicHandler.upload( .whenComplete((compoundTag, throwable) -> {
compoundTag, schematicHandler.upload(compoundTag, null, null, new RunnableVal<>() {
null,
null,
new RunnableVal<>() {
@Override @Override
public void run(URL value) { public void run(URL value) {
plot.removeRunning(); plot.removeRunning();
@ -202,8 +199,8 @@ public class Download extends SubCommand {
); );
player.sendMessage(StaticCaption.of(value.toString())); player.sendMessage(StaticCaption.of(value.toString()));
} }
} });
)); });
return; return;
} }
// TODO legacy support // TODO legacy support

View File

@ -60,10 +60,9 @@ public class Help extends Command {
RunnableVal2<Command, CommandResult> whenDone RunnableVal2<Command, CommandResult> whenDone
) { ) {
switch (args.length) { switch (args.length) {
case 0 -> { case 0:
return displayHelp(player, null, 0); return displayHelp(player, null, 0);
} case 1:
case 1 -> {
if (MathMan.isInteger(args[0])) { if (MathMan.isInteger(args[0])) {
try { try {
return displayHelp(player, null, Integer.parseInt(args[0])); return displayHelp(player, null, Integer.parseInt(args[0]));
@ -73,8 +72,7 @@ public class Help extends Command {
} else { } else {
return displayHelp(player, args[0], 1); return displayHelp(player, args[0], 1);
} }
} case 2:
case 2 -> {
if (MathMan.isInteger(args[1])) { if (MathMan.isInteger(args[1])) {
try { try {
return displayHelp(player, args[0], Integer.parseInt(args[1])); return displayHelp(player, args[0], Integer.parseInt(args[1]));
@ -83,8 +81,8 @@ public class Help extends Command {
} }
} }
return CompletableFuture.completedFuture(false); return CompletableFuture.completedFuture(false);
} default:
default -> sendUsage(player); sendUsage(player);
} }
return CompletableFuture.completedFuture(true); return CompletableFuture.completedFuture(true);
} }
@ -134,12 +132,7 @@ public class Help extends Command {
TagResolver.builder() TagResolver.builder()
.tag("command", Tag.inserting(Component.text("/plot help"))) .tag("command", Tag.inserting(Component.text("/plot help")))
.tag("category", Tag.inserting(Component.text("all"))) .tag("category", Tag.inserting(Component.text("all")))
.tag( .tag("category_desc", Tag.inserting(TranslatableCaption.of("help.help_display_all_commands").toComponent(player)))
"category_desc",
Tag.inserting(TranslatableCaption
.of("help.help_display_all_commands")
.toComponent(player))
)
.build() .build()
)); ));
builder.append(Component.newline()).append(MINI_MESSAGE.deserialize(TranslatableCaption builder.append(Component.newline()).append(MINI_MESSAGE.deserialize(TranslatableCaption

View File

@ -85,24 +85,24 @@ public class Inbox extends SubCommand {
for (int x = page * 12; x < max; x++) { for (int x = page * 12; x < max; x++) {
PlotComment comment = comments[x]; PlotComment comment = comments[x];
Component commentColored; Component commentColored;
if (player.getName().equals(comment.senderName())) { if (player.getName().equals(comment.senderName)) {
commentColored = MINI_MESSAGE commentColored = MINI_MESSAGE
.deserialize( .deserialize(
TranslatableCaption.of("list.comment_list_by_lister").getComponent(player), TranslatableCaption.of("list.comment_list_by_lister").getComponent(player),
TagResolver.resolver("comment", Tag.inserting(Component.text(comment.comment()))) TagResolver.resolver("comment", Tag.inserting(Component.text(comment.comment)))
); );
} else { } else {
commentColored = MINI_MESSAGE commentColored = MINI_MESSAGE
.deserialize( .deserialize(
TranslatableCaption.of("list.comment_list_by_other").getComponent(player), TranslatableCaption.of("list.comment_list_by_other").getComponent(player),
TagResolver.resolver("comment", Tag.inserting(Component.text(comment.comment()))) TagResolver.resolver("comment", Tag.inserting(Component.text(comment.comment)))
); );
} }
TagResolver resolver = TagResolver.builder() TagResolver resolver = TagResolver.builder()
.tag("number", Tag.inserting(Component.text(x))) .tag("number", Tag.inserting(Component.text(x)))
.tag("world", Tag.inserting(Component.text(comment.world()))) .tag("world", Tag.inserting(Component.text(comment.world)))
.tag("plot_id", Tag.inserting(Component.text(comment.id().getX() + ";" + comment.id().getY()))) .tag("plot_id", Tag.inserting(Component.text(comment.id.getX() + ";" + comment.id.getY())))
.tag("commenter", Tag.inserting(Component.text(comment.senderName()))) .tag("commenter", Tag.inserting(Component.text(comment.senderName)))
.tag("comment", Tag.inserting(commentColored)) .tag("comment", Tag.inserting(commentColored))
.build(); .build();
builder.append(MINI_MESSAGE builder.append(MINI_MESSAGE
@ -137,7 +137,7 @@ public class Inbox extends SubCommand {
int unread = 0; int unread = 0;
for (PlotComment comment : value) { for (PlotComment comment : value) {
total++; total++;
if (comment.timestamp() > CommentManager if (comment.timestamp > CommentManager
.getTimestamp(player, inbox.toString())) { .getTimestamp(player, inbox.toString())) {
unread++; unread++;
} }
@ -190,7 +190,7 @@ public class Inbox extends SubCommand {
final int page; final int page;
if (args.length > 1) { if (args.length > 1) {
switch (args[1].toLowerCase()) { switch (args[1].toLowerCase()) {
case "delete" -> { case "delete":
if (!inbox.canModify(plot, player)) { if (!inbox.canModify(plot, player)) {
player.sendMessage(TranslatableCaption.of("comment.no_perm_inbox_modify")); player.sendMessage(TranslatableCaption.of("comment.no_perm_inbox_modify"));
return false; return false;
@ -225,6 +225,7 @@ public class Inbox extends SubCommand {
); );
return false; return false;
} }
if (!inbox.getComments(plot, new RunnableVal<>() { if (!inbox.getComments(plot, new RunnableVal<>() {
@Override @Override
public void run(List<PlotComment> value) { public void run(List<PlotComment> value) {
@ -241,7 +242,7 @@ public class Inbox extends SubCommand {
if (success) { if (success) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("comment.comment_removed_success"), TranslatableCaption.of("comment.comment_removed_success"),
TagResolver.resolver("value", Tag.inserting(Component.text(comment.comment()))) TagResolver.resolver("value", Tag.inserting(Component.text(comment.comment)))
); );
} else { } else {
player.sendMessage( player.sendMessage(
@ -253,8 +254,7 @@ public class Inbox extends SubCommand {
return false; return false;
} }
return true; return true;
} case "clear":
case "clear" -> {
if (!inbox.canModify(plot, player)) { if (!inbox.canModify(plot, player)) {
player.sendMessage(TranslatableCaption.of("comment.no_perm_inbox_modify")); player.sendMessage(TranslatableCaption.of("comment.no_perm_inbox_modify"));
} }
@ -268,8 +268,7 @@ public class Inbox extends SubCommand {
plot.getPlotCommentContainer().removeComments(comments); plot.getPlotCommentContainer().removeComments(comments);
} }
return true; return true;
} default:
default -> {
try { try {
page = Integer.parseInt(args[1]); page = Integer.parseInt(args[1]);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
@ -277,7 +276,6 @@ public class Inbox extends SubCommand {
return false; return false;
} }
} }
}
} else { } else {
page = 1; page = 1;
} }

View File

@ -52,8 +52,7 @@ public class Info extends SubCommand {
arg = args[0]; arg = args[0];
switch (arg) { switch (arg) {
// TODO: (re?)implement /plot info inv. (it was never properly implemented) // TODO: (re?)implement /plot info inv. (it was never properly implemented)
case "trusted", "alias", "biome", "denied", "flags", "id", "size", "members", "creationdate", "seen", "owner", "rating", "likes" -> case "trusted", "alias", "biome", "denied", "flags", "id", "size", "members", "creationdate", "seen", "owner", "rating", "likes" -> plot = Plot
plot = Plot
.getPlotFromString(player, null, false); .getPlotFromString(player, null, false);
default -> { default -> {
plot = Plot.getPlotFromString(player, arg, false); plot = Plot.getPlotFromString(player, arg, false);

View File

@ -112,15 +112,15 @@ public class Kick extends SubCommand {
for (PlotPlayer<?> player2 : players) { for (PlotPlayer<?> player2 : players) {
if (!plot.equals(player2.getCurrentPlot())) { if (!plot.equals(player2.getCurrentPlot())) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("kick.player_not_in_plot"), TranslatableCaption.of("errors.invalid_player"),
TagResolver.resolver("player", Tag.inserting(Component.text(player2.getName()))) TagResolver.resolver("value", Tag.inserting(Component.text(args[0])))
); );
return; return;
} }
if (player2.hasPermission(Permission.PERMISSION_ADMIN_ENTRY_DENIED)) { if (player2.hasPermission(Permission.PERMISSION_ADMIN_ENTRY_DENIED)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("kick.cannot_kick_player"), TranslatableCaption.of("cluster.cannot_kick_player"),
TagResolver.resolver("player", Tag.inserting(Component.text(player2.getName()))) TagResolver.resolver("name", Tag.inserting(Component.text(player2.getName())))
); );
return; return;
} }

View File

@ -474,20 +474,20 @@ public class ListCmd extends SubCommand {
final List<UUIDMapping> names = PlotSquared.get().getImpromptuUUIDPipeline().getNames(plot.getOwners()) final List<UUIDMapping> names = PlotSquared.get().getImpromptuUUIDPipeline().getNames(plot.getOwners())
.get(Settings.UUID.BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS); .get(Settings.UUID.BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS);
for (final UUIDMapping uuidMapping : names) { for (final UUIDMapping uuidMapping : names) {
PlotPlayer<?> pp = PlotSquared.platform().playerManager().getPlayerIfExists(uuidMapping.uuid()); PlotPlayer<?> pp = PlotSquared.platform().playerManager().getPlayerIfExists(uuidMapping.getUuid());
TagResolver resolver = TagResolver.builder() TagResolver resolver = TagResolver.builder()
.tag("prefix", Tag.inserting(Component.text(prefix))) .tag("prefix", Tag.inserting(Component.text(prefix)))
.tag("player", Tag.inserting(Component.text(uuidMapping.username()))) .tag("player", Tag.inserting(Component.text(uuidMapping.getUsername())))
.build(); .build();
if (pp != null) { if (pp != null) {
builder.append(MINI_MESSAGE.deserialize(online, resolver)); builder.append(MINI_MESSAGE.deserialize(online, resolver));
} else if (uuidMapping.username().equalsIgnoreCase("unknown")) { } else if (uuidMapping.getUsername().equalsIgnoreCase("unknown")) {
TagResolver unknownResolver = TagResolver.resolver( TagResolver unknownResolver = TagResolver.resolver(
"info.unknown", "info.unknown",
Tag.inserting(TranslatableCaption.of("info.unknown").toComponent(player)) Tag.inserting(TranslatableCaption.of("info.unknown").toComponent(player))
); );
builder.append(MINI_MESSAGE.deserialize(unknown, unknownResolver)); builder.append(MINI_MESSAGE.deserialize(unknown, unknownResolver));
} else if (uuidMapping.uuid().equals(DBFunc.EVERYONE)) { } else if (uuidMapping.getUuid().equals(DBFunc.EVERYONE)) {
TagResolver everyoneResolver = TagResolver.resolver( TagResolver everyoneResolver = TagResolver.resolver(
"info.everyone", "info.everyone",
Tag.inserting(TranslatableCaption.of("info.everyone").toComponent(player)) Tag.inserting(TranslatableCaption.of("info.everyone").toComponent(player))

View File

@ -86,7 +86,6 @@ public class MainCommand extends Command {
commands.add(CreateRoadSchematic.class); commands.add(CreateRoadSchematic.class);
commands.add(DebugAllowUnsafe.class); commands.add(DebugAllowUnsafe.class);
commands.add(RegenAllRoads.class); commands.add(RegenAllRoads.class);
commands.add(Claim.class);
commands.add(Auto.class); commands.add(Auto.class);
commands.add(HomeCommand.class); commands.add(HomeCommand.class);
commands.add(Visit.class); commands.add(Visit.class);
@ -94,7 +93,6 @@ public class MainCommand extends Command {
commands.add(Clear.class); commands.add(Clear.class);
commands.add(Delete.class); commands.add(Delete.class);
commands.add(Trust.class); commands.add(Trust.class);
commands.add(Add.class);
commands.add(Leave.class); commands.add(Leave.class);
commands.add(Deny.class); commands.add(Deny.class);
commands.add(Remove.class); commands.add(Remove.class);
@ -130,7 +128,6 @@ public class MainCommand extends Command {
commands.add(Owner.class); commands.add(Owner.class);
commands.add(Desc.class); commands.add(Desc.class);
commands.add(Biome.class); commands.add(Biome.class);
commands.add(Alias.class);
commands.add(SetHome.class); commands.add(SetHome.class);
commands.add(Cluster.class); commands.add(Cluster.class);
commands.add(DebugImportWorlds.class); commands.add(DebugImportWorlds.class);

View File

@ -56,7 +56,7 @@ public class Music extends SubCommand {
.asList("music_disc_13", "music_disc_cat", "music_disc_blocks", "music_disc_chirp", .asList("music_disc_13", "music_disc_cat", "music_disc_blocks", "music_disc_chirp",
"music_disc_far", "music_disc_mall", "music_disc_mellohi", "music_disc_stal", "music_disc_far", "music_disc_mall", "music_disc_mellohi", "music_disc_stal",
"music_disc_strad", "music_disc_ward", "music_disc_11", "music_disc_wait", "music_disc_otherside", "music_disc_strad", "music_disc_ward", "music_disc_11", "music_disc_wait", "music_disc_otherside",
"music_disc_pigstep", "music_disc_5", "music_disc_relic" "music_disc_pigstep", "music_disc_5"
); );
private final InventoryUtil inventoryUtil; private final InventoryUtil inventoryUtil;

View File

@ -90,8 +90,12 @@ public class Purge extends SubCommand {
return false; return false;
} }
switch (split[0].toLowerCase()) { switch (split[0].toLowerCase()) {
case "world", "w" -> world = split[1]; case "world":
case "area", "a" -> { case "w":
world = split[1];
break;
case "area":
case "a":
area = this.plotAreaManager.getPlotAreaByString(split[1]); area = this.plotAreaManager.getPlotAreaByString(split[1]);
if (area == null) { if (area == null) {
player.sendMessage( player.sendMessage(
@ -100,8 +104,9 @@ public class Purge extends SubCommand {
); );
return false; return false;
} }
} break;
case "plotid", "id" -> { case "plotid":
case "id":
try { try {
id = PlotId.fromString(split[1]); id = PlotId.fromString(split[1]);
} catch (IllegalArgumentException ignored) { } catch (IllegalArgumentException ignored) {
@ -111,8 +116,9 @@ public class Purge extends SubCommand {
); );
return false; return false;
} }
} break;
case "owner", "o" -> { case "owner":
case "o":
UUIDMapping ownerMapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(split[1]); UUIDMapping ownerMapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(split[1]);
if (ownerMapping == null) { if (ownerMapping == null) {
player.sendMessage( player.sendMessage(
@ -121,9 +127,10 @@ public class Purge extends SubCommand {
); );
return false; return false;
} }
owner = ownerMapping.uuid(); owner = ownerMapping.getUuid();
} break;
case "shared", "s" -> { case "shared":
case "s":
UUIDMapping addedMapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(split[1]); UUIDMapping addedMapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(split[1]);
if (addedMapping == null) { if (addedMapping == null) {
player.sendMessage( player.sendMessage(
@ -132,16 +139,25 @@ public class Purge extends SubCommand {
); );
return false; return false;
} }
added = addedMapping.uuid(); added = addedMapping.getUuid();
} break;
case "clear", "c", "delete", "d", "del" -> clear = Boolean.parseBoolean(split[1]); case "clear":
case "unknown", "?", "u" -> unknown = Boolean.parseBoolean(split[1]); case "c":
default -> { case "delete":
case "d":
case "del":
clear = Boolean.parseBoolean(split[1]);
break;
case "unknown":
case "?":
case "u":
unknown = Boolean.parseBoolean(split[1]);
break;
default:
sendUsage(player); sendUsage(player);
return false; return false;
} }
} }
}
final HashSet<Plot> toDelete = new HashSet<>(); final HashSet<Plot> toDelete = new HashSet<>();
for (Plot plot : PlotQuery.newQuery().whereBasePlot()) { for (Plot plot : PlotQuery.newQuery().whereBasePlot()) {
if (world != null && !plot.getWorldName().equalsIgnoreCase(world)) { if (world != null && !plot.getWorldName().equalsIgnoreCase(world)) {
@ -220,9 +236,9 @@ public class Purge extends SubCommand {
try { try {
ids.add(plot.temp); ids.add(plot.temp);
if (finalClear) { if (finalClear) {
plot.getPlotModificationManager().clear(false, true, player, plot.getPlotModificationManager().clear(false, true, player, () -> {
() -> LOGGER.info("Plot {} cleared by purge", plot.getId()) LOGGER.info("Plot {} cleared by purge", plot.getId());
); });
} else { } else {
plot.getPlotModificationManager().removeSign(); plot.getPlotModificationManager().removeSign();
} }

View File

@ -156,9 +156,9 @@ public class Template extends SubCommand {
ZipOutputStream zos = new ZipOutputStream(fos)) { ZipOutputStream zos = new ZipOutputStream(fos)) {
for (FileBytes file : files) { for (FileBytes file : files) {
ZipEntry ze = new ZipEntry(file.path()); ZipEntry ze = new ZipEntry(file.path);
zos.putNextEntry(ze); zos.putNextEntry(ze);
zos.write(file.data()); zos.write(file.data);
} }
zos.closeEntry(); zos.closeEntry();
} }

View File

@ -0,0 +1,104 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands;
import cloud.commandframework.annotations.Argument;
import cloud.commandframework.annotations.CommandMethod;
import cloud.commandframework.annotations.CommandPermission;
import com.google.inject.Inject;
import com.plotsquared.core.commands.arguments.PlotMember;
import com.plotsquared.core.commands.requirements.Requirement;
import com.plotsquared.core.commands.requirements.CommandRequirement;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.util.PlayerManager;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull;
class CommandAdd implements PlotSquaredCommandContainer {
private final EventDispatcher eventDispatcher;
@Inject
CommandAdd(final @NonNull EventDispatcher eventDispatcher) {
this.eventDispatcher = eventDispatcher;
}
@Requirement(CommandRequirement.PLAYER)
@Requirement(CommandRequirement.IS_OWNER)
@CommandPermission("plots.add")
@CommandMethod("${command.prefix} add [target]")
public void commandAdd(
final @NonNull PlotPlayer<?> sender,
@Argument("target") final PlotMember target,
final @NonNull Plot plot
) {
if (target instanceof PlotMember.Everyone) {
if (!sender.hasPermission(Permission.PERMISSION_TRUST_EVERYONE) && !sender.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_TRUST)) {
sender.sendMessage(
TranslatableCaption.of("errors.invalid_player"),
TagResolver.resolver("value", Tag.inserting(
PlayerManager.resolveName(target.uuid()).toComponent(sender)
))
);
return;
}
} else if (plot.isOwner(target.uuid())) {
sender.sendMessage(
TranslatableCaption.of("member.already_added"),
TagResolver.resolver("player", Tag.inserting(
PlayerManager.resolveName(target.uuid()).toComponent(sender)
))
);
return;
} else if (plot.getMembers().contains(target.uuid())) {
sender.sendMessage(
TranslatableCaption.of("member.already_added"),
TagResolver.resolver("player", Tag.inserting(
PlayerManager.resolveName(target.uuid()).toComponent(sender)
))
);
return;
} else if (plot.getMembers().size() >= sender.hasPermissionRange(Permission.PERMISSION_ADD, Settings.Limit.MAX_PLOTS)) {
sender.sendMessage(
TranslatableCaption.of("members.plot_max_members_added"),
TagResolver.resolver("amount", Tag.inserting(Component.text(plot.getMembers().size())))
);
return;
}
if (target instanceof PlotMember.Player) {
if (!plot.removeTrusted(target.uuid())) {
if (plot.getDenied().contains(target.uuid())) {
plot.removeDenied(target.uuid());
}
}
}
plot.addMember(target.uuid());
this.eventDispatcher.callMember(sender, plot, target.uuid(), true);
sender.sendMessage(TranslatableCaption.of("member.member_added"));
}
}

View File

@ -0,0 +1,136 @@
package com.plotsquared.core.commands;
import cloud.commandframework.annotations.Argument;
import cloud.commandframework.annotations.CommandMethod;
import cloud.commandframework.annotations.CommandPermission;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.commands.requirements.CommandRequirement;
import com.plotsquared.core.commands.requirements.Requirement;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.query.PlotQuery;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.concurrent.TimeoutException;
public class CommandAlias implements PlotSquaredCommandContainer {
@Requirement(CommandRequirement.PLAYER)
@Requirement(CommandRequirement.PLOT_HAS_OWNER)
@CommandPermission("plots.alias")
@CommandMethod("${command.prefix} alias set <alias>")
public void commandAliasSet(
final @NonNull PlotPlayer<?> sender,
final @NonNull Plot plot,
@Argument("alias") final @NonNull String alias
) {
final boolean isOwner = plot.isOwner(sender.getUUID());
if (!isOwner && !sender.hasPermission(Permission.PERMISSION_ADMIN_ALIAS_SET)) {
sender.sendMessage(TranslatableCaption.of("permission.no_plot_perms"));
return;
} else if (!sender.hasPermission(Permission.PERMISSION_ALIAS_SET)) {
sender.sendMessage(
TranslatableCaption.of("permission.no_permission"),
TagResolver.resolver(
"node",
Tag.inserting(Permission.PERMISSION_ALIAS_SET)
)
);
return;
}
if (alias.length() >= 50) {
sender.sendMessage(TranslatableCaption.of("alias.alias_too_long"));
return;
}
if (MathMan.isInteger(alias)) {
sender.sendMessage(TranslatableCaption.of("flag.not_valid_value")); // TODO this is obviously wrong
return;
}
if (PlotQuery.newQuery().inArea(plot.getArea())
.withAlias(alias)
.anyMatch()) {
sender.sendMessage(
TranslatableCaption.of("alias.alias_is_taken"),
TagResolver.resolver("alias", Tag.inserting(Component.text(alias)))
);
return;
}
if (Settings.UUID.OFFLINE) {
plot.setAlias(alias);
sender.sendMessage(
TranslatableCaption.of("alias.alias_set_to"),
TagResolver.resolver("alias", Tag.inserting(Component.text(alias)))
);
return;
}
PlotSquared.get().getImpromptuUUIDPipeline().getSingle(alias, ((uuid, throwable) -> {
if (throwable instanceof TimeoutException) {
sender.sendMessage(TranslatableCaption.of("players.fetching_players_timeout"));
} else if (uuid != null) {
sender.sendMessage(
TranslatableCaption.of("alias.alias_is_taken"),
TagResolver.resolver("alias", Tag.inserting(Component.text(alias)))
);
} else {
plot.setAlias(alias);
sender.sendMessage(
TranslatableCaption.of("alias.alias_set_to"),
TagResolver.resolver("alias", Tag.inserting(Component.text(alias)))
);
}
}));
}
@Requirement(CommandRequirement.PLAYER)
@Requirement(CommandRequirement.PLOT_HAS_OWNER)
@CommandPermission("plots.alias")
@CommandMethod("${command.prefix} alias remove")
public void commandAliasRemove(
final @NonNull PlotPlayer<?> sender,
final @NonNull Plot plot
) {
final boolean isOwner = plot.isOwner(sender.getUUID());
if (!isOwner && !sender.hasPermission(Permission.PERMISSION_ADMIN_ALIAS_REMOVE)) {
sender.sendMessage(TranslatableCaption.of("permission.no_plot_perms"));
return;
} else if (!sender.hasPermission(Permission.PERMISSION_ALIAS_REMOVE)) {
sender.sendMessage(
TranslatableCaption.of("permission.no_permission"),
TagResolver.resolver(
"node",
Tag.inserting(Permission.PERMISSION_ALIAS_REMOVE)
)
);
return;
}
if (plot.getAlias().isEmpty()) {
sender.sendMessage(
TranslatableCaption.of("alias.no_alias_set")
);
return;
}
final String currentAlias = plot.getAlias();
plot.setAlias(null);
sender.sendMessage(
TranslatableCaption.of("alias.alias_removed"),
TagResolver.resolver("alias", Tag.inserting(Component.text(currentAlias)))
);
}
}

View File

@ -1,24 +1,11 @@
/* package com.plotsquared.core.commands;
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.command;
import cloud.commandframework.annotations.Argument;
import cloud.commandframework.annotations.CommandMethod;
import cloud.commandframework.annotations.CommandPermission;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.commands.requirements.CommandRequirement;
import com.plotsquared.core.commands.requirements.Requirement;
import com.plotsquared.core.configuration.Settings; import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.database.DBFunc; import com.plotsquared.core.database.DBFunc;
@ -26,7 +13,6 @@ import com.plotsquared.core.events.PlayerClaimPlotEvent;
import com.plotsquared.core.events.PlotMergeEvent; import com.plotsquared.core.events.PlotMergeEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.location.Direction; import com.plotsquared.core.location.Direction;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.MetaDataAccess; import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys; import com.plotsquared.core.player.PlayerMetaDataKeys;
@ -43,22 +29,17 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
@CommandDeclaration( public class CommandClaim implements PlotSquaredCommandContainer {
command = "claim",
aliases = "c",
category = CommandCategory.CLAIMING,
requiredType = RequiredType.PLAYER, permission = "plots.claim",
usage = "/plot claim")
public class Claim extends SubCommand {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Claim.class.getSimpleName()); private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + CommandClaim.class.getSimpleName());
private final EventDispatcher eventDispatcher; private final EventDispatcher eventDispatcher;
private final EconHandler econHandler; private final EconHandler econHandler;
@Inject @Inject
public Claim( CommandClaim(
final @NonNull EventDispatcher eventDispatcher, final @NonNull EventDispatcher eventDispatcher,
final @NonNull EconHandler econHandler final @NonNull EconHandler econHandler
) { ) {
@ -66,124 +47,132 @@ public class Claim extends SubCommand {
this.econHandler = econHandler; this.econHandler = econHandler;
} }
@Override @Requirement(CommandRequirement.PLAYER)
public boolean onCommand(final PlotPlayer<?> player, String[] args) { @Requirement(CommandRequirement.IN_PLOT)
String schematic = null; @CommandPermission("plots.add")
if (args.length >= 1) { @CommandMethod("${command.prefix} claim [schematic]")
schematic = args[0]; public void commandClaim(
} final @NonNull PlotPlayer<?> sender,
Location location = player.getLocation(); final @NonNull Plot plot,
Plot plot = location.getPlotAbs(); @Argument("schematic") final @Nullable String schematic
if (plot == null) { ) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); final PlayerClaimPlotEvent event = this.eventDispatcher.callClaim(sender, plot, schematic);
return false;
}
final PlayerClaimPlotEvent event = this.eventDispatcher.callClaim(player, plot, schematic);
schematic = event.getSchematic();
if (event.getEventResult() == Result.DENY) { if (event.getEventResult() == Result.DENY) {
player.sendMessage( sender.sendMessage(
TranslatableCaption.of("events.event_denied"), TranslatableCaption.of("events.event_denied"),
TagResolver.resolver("value", Tag.inserting(Component.text("Claim"))) TagResolver.resolver("value", Tag.inserting(Component.text("Claim")))
); );
return true; return;
} }
boolean force = event.getEventResult() == Result.FORCE;
int currentPlots = Settings.Limit.GLOBAL ?
player.getPlotCount() :
player.getPlotCount(location.getWorldName());
final boolean forceClaim = event.getEventResult() == Result.FORCE;
final int currentPlots = Settings.Limit.GLOBAL ?
sender.getPlotCount() :
sender.getPlotCount(sender.getLocation().getWorldName());
final PlotArea area = plot.getArea(); final PlotArea area = plot.getArea();
try (final MetaDataAccess<Integer> metaDataAccess = player.accessPersistentMetaData(PlayerMetaDataKeys.PERSISTENT_GRANTED_PLOTS)) { try (final MetaDataAccess<Integer> metaDataAccess = sender.accessPersistentMetaData(
PlayerMetaDataKeys.PERSISTENT_GRANTED_PLOTS
)) {
int grants = 0; int grants = 0;
if (currentPlots >= player.getAllowedPlots() && !force) { if (currentPlots >= sender.getAllowedPlots() && !forceClaim) {
if (metaDataAccess.isPresent()) { if (metaDataAccess.isPresent()) {
grants = metaDataAccess.get().orElse(0); grants = metaDataAccess.get().orElse(0);
if (grants <= 0) { if (grants <= 0) {
player.sendMessage( sender.sendMessage(
TranslatableCaption.of("permission.cant_claim_more_plots"), TranslatableCaption.of("permission.cant_claim_more_plots"),
TagResolver.resolver("amount", Tag.inserting(Component.text(grants))) TagResolver.resolver("amount", Tag.inserting(Component.text(grants)))
); );
metaDataAccess.remove(); metaDataAccess.remove();
} }
} else { } else {
player.sendMessage( sender.sendMessage(
TranslatableCaption.of("permission.cant_claim_more_plots"), TranslatableCaption.of("permission.cant_claim_more_plots"),
TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots()))) TagResolver.resolver("amount", Tag.inserting(Component.text(sender.getAllowedPlots())))
); );
return false; return;
} }
} }
if (!plot.canClaim(player)) { if (!plot.canClaim(sender)) {
player.sendMessage(TranslatableCaption.of("working.plot_is_claimed")); sender.sendMessage(TranslatableCaption.of("working.plot_is_claimed"));
return false; return;
} }
if (schematic != null && !schematic.isEmpty()) { if (schematic != null && !schematic.isEmpty()) {
if (area.isSchematicClaimSpecify()) { if (area.isSchematicClaimSpecify()) {
if (!area.hasSchematic(schematic)) { if (!area.hasSchematic(schematic)) {
player.sendMessage( sender.sendMessage(
TranslatableCaption.of("schematics.schematic_invalid_named"), TranslatableCaption.of("schematics.schematic_invalid_named"),
TagResolver.builder() TagResolver.builder()
.tag("schemname", Tag.inserting(Component.text(schematic))) .tag("schemname", Tag.inserting(Component.text(schematic)))
.tag("reason", Tag.inserting(Component.text("non-existent"))) .tag("reason", Tag.inserting(Component.text("non-existent")))
.build() .build()
); );
return;
} }
if (!player.hasPermission(Permission.PERMISSION_CLAIM_SCHEMATIC
.format(schematic)) && !player.hasPermission( if (!sender.hasPermission(
Permission.PERMISSION_CLAIM_SCHEMATIC.format(schematic)
) && !sender.hasPermission(
"plots.admin.command.schematic" "plots.admin.command.schematic"
) && !force) { ) && !forceClaim) {
player.sendMessage( sender.sendMessage(
TranslatableCaption.of("permission.no_schematic_permission"), TranslatableCaption.of("permission.no_schematic_permission"),
TagResolver.resolver("value", Tag.inserting(Component.text(schematic))) TagResolver.resolver("value", Tag.inserting(Component.text(schematic)))
); );
return;
} }
} }
} }
if (this.econHandler.isEnabled(area) && !force) {
PlotExpression costExr = area.getPrices().get("claim"); if (this.econHandler.isEnabled(area) && !forceClaim) {
double cost = costExr.evaluate(currentPlots); final PlotExpression costExr = area.getPrices().get("claim");
final double cost = costExr.evaluate(currentPlots);
if (cost > 0d) { if (cost > 0d) {
if (!this.econHandler.isSupported()) { if (!this.econHandler.isSupported()) {
player.sendMessage(TranslatableCaption.of("economy.vault_or_consumer_null")); sender.sendMessage(TranslatableCaption.of("economy.vault_or_consumer_null"));
return false; return;
} }
if (this.econHandler.getMoney(player) < cost) { if (this.econHandler.getMoney(sender) < cost) {
player.sendMessage( sender.sendMessage(
TranslatableCaption.of("economy.cannot_afford_plot"), TranslatableCaption.of("economy.cannot_afford_plot"),
TagResolver.builder() TagResolver.builder()
.tag("money", Tag.inserting(Component.text(this.econHandler.format(cost)))) .tag("money", Tag.inserting(Component.text(this.econHandler.format(cost))))
.tag( .tag(
"balance", "balance",
Tag.inserting(Component.text(this.econHandler.format(this.econHandler.getMoney( Tag.inserting(
player)))) Component.text(this.econHandler.format(this.econHandler.getMoney(sender)))
)
) )
.build() .build()
); );
return false; return;
} }
this.econHandler.withdrawMoney(player, cost); this.econHandler.withdrawMoney(sender, cost);
player.sendMessage( sender.sendMessage(
TranslatableCaption.of("economy.removed_balance"), TranslatableCaption.of("economy.removed_balance"),
TagResolver.builder() TagResolver.builder()
.tag("money", Tag.inserting(Component.text(this.econHandler.format(cost)))) .tag("money", Tag.inserting(Component.text(this.econHandler.format(cost))))
.tag( .tag(
"balance", "balance",
Tag.inserting(Component.text(this.econHandler.format(this.econHandler.getMoney( Tag.inserting(
player)))) Component.text(this.econHandler.format(this.econHandler.getMoney(sender)))
)
) )
.build() .build()
); );
} }
} }
if (grants > 0) { if (grants > 0) {
if (grants == 1) { if (grants == 1) {
metaDataAccess.remove(); metaDataAccess.remove();
} else { } else {
metaDataAccess.set(grants - 1); metaDataAccess.set(grants - 1);
} }
player.sendMessage( sender.sendMessage(
TranslatableCaption.of("economy.removed_granted_plot"), TranslatableCaption.of("economy.removed_granted_plot"),
TagResolver.builder() TagResolver.builder()
.tag("usedGrants", Tag.inserting(Component.text(grants - 1))) .tag("usedGrants", Tag.inserting(Component.text(grants - 1)))
@ -192,27 +181,34 @@ public class Claim extends SubCommand {
); );
} }
} }
if (!player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_BORDER)) {
int border = area.getBorder(); if (!sender.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_BORDER)) {
if (border != Integer.MAX_VALUE && plot.getDistanceFromOrigin() > border && !force) { final int border = area.getBorder();
player.sendMessage(TranslatableCaption.of("border.denied")); if (border != Integer.MAX_VALUE && plot.getDistanceFromOrigin() > border && !forceClaim) {
return false; sender.sendMessage(TranslatableCaption.of("border.denied"));
return;
} }
} }
plot.setOwnerAbs(player.getUUID());
final String finalSchematic = schematic; // Actually update the owner :)
plot.setOwnerAbs(sender.getUUID());
DBFunc.createPlotSafe(plot, () -> { DBFunc.createPlotSafe(plot, () -> {
try { try {
TaskManager.getPlatformImplementation().sync(() -> { TaskManager.getPlatformImplementation().sync(() -> {
if (!plot.claim(player, true, finalSchematic, false, false)) { if (!plot.claim(sender, true, event.getSchematic(), false, false)) {
LOGGER.info("Failed to claim plot {}", plot.getId().toCommaSeparatedString()); LOGGER.info("Failed to claim plot {}", plot.getId().toCommaSeparatedString());
player.sendMessage(TranslatableCaption.of("working.plot_not_claimed")); sender.sendMessage(TranslatableCaption.of("working.plot_not_claimed"));
plot.setOwnerAbs(null); plot.setOwnerAbs(null);
} else if (area.isAutoMerge()) { } else if (area.isAutoMerge()) {
PlotMergeEvent mergeEvent = Claim.this.eventDispatcher final PlotMergeEvent mergeEvent = this.eventDispatcher.callMerge(
.callMerge(plot, Direction.ALL, Integer.MAX_VALUE, player); plot,
Direction.ALL,
Integer.MAX_VALUE,
sender
);
if (mergeEvent.getEventResult() == Result.DENY) { if (mergeEvent.getEventResult() == Result.DENY) {
player.sendMessage( sender.sendMessage(
TranslatableCaption.of("events.event_denied"), TranslatableCaption.of("events.event_denied"),
TagResolver.resolver("value", Tag.inserting(Component.text("Auto merge on claim"))) TagResolver.resolver("value", Tag.inserting(Component.text("Auto merge on claim")))
); );
@ -220,11 +216,11 @@ public class Claim extends SubCommand {
if (plot.getPlotModificationManager().autoMerge( if (plot.getPlotModificationManager().autoMerge(
mergeEvent.getDir(), mergeEvent.getDir(),
mergeEvent.getMax(), mergeEvent.getMax(),
player.getUUID(), sender.getUUID(),
player, sender,
true true
)) { )) {
eventDispatcher.callPostMerge(player, plot); eventDispatcher.callPostMerge(sender, plot);
} }
} }
} }
@ -235,10 +231,8 @@ public class Claim extends SubCommand {
} }
}, () -> { }, () -> {
LOGGER.info("Failed to add plot to database: {}", plot.getId().toCommaSeparatedString()); LOGGER.info("Failed to add plot to database: {}", plot.getId().toCommaSeparatedString());
player.sendMessage(TranslatableCaption.of("working.plot_not_claimed")); sender.sendMessage(TranslatableCaption.of("working.plot_not_claimed"));
plot.setOwnerAbs(null); plot.setOwnerAbs(null);
}); });
return true;
} }
} }

View File

@ -0,0 +1,26 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands;
import cloud.commandframework.captions.Caption;
public final class PlotSquaredCaptionKeys {
public static final Caption ARGUMENT_PARSE_FAILURE_TARGET = Caption.of("argument.parse.failure.target");
}

View File

@ -0,0 +1,26 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands;
/**
* Indicates that a class contains commands.
*/
public interface PlotSquaredCommandContainer {
}

View File

@ -0,0 +1,82 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands;
import cloud.commandframework.CommandManager;
import cloud.commandframework.annotations.AnnotationParser;
import cloud.commandframework.meta.SimpleCommandMeta;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.plotsquared.core.commands.parsers.PlotMemberParser;
import com.plotsquared.core.commands.requirements.CommandRequirementBuilderModifier;
import com.plotsquared.core.commands.requirements.CommandRequirementPostProcessor;
import com.plotsquared.core.commands.requirements.Requirements;
import com.plotsquared.core.player.PlotPlayer;
import io.leangen.geantyref.TypeToken;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.stream.Stream;
public class PlotSquaredCommandManager {
private final Injector injector;
private final CommandManager<PlotPlayer<?>> commandManager;
private final AnnotationParser<PlotPlayer<?>> annotationParser;
@Inject
public PlotSquaredCommandManager(
final @NonNull Injector injector,
final @NonNull CommandManager<PlotPlayer<?>> commandManager
) {
this.injector = injector;
this.commandManager = commandManager;
this.annotationParser = new AnnotationParser<PlotPlayer<?>>(
this.commandManager,
new TypeToken<PlotPlayer<?>>() {
},
parameters -> SimpleCommandMeta.empty()
);
this.annotationParser.registerBuilderModifier(Requirements.class, new CommandRequirementBuilderModifier());
this.commandManager.registerCommandPostProcessor(new CommandRequirementPostProcessor());
}
/**
* Scans the given {@code instance} for commands, and registers them.
*
* @param instance the instance to scan
*/
public void scanClass(final @NonNull Object instance) {
this.annotationParser.parse(instance);
}
/**
* Initializes all the known commands.
*/
public void initializeCommands() {
// We start by scanning the parsers.
Stream.of(
PlotMemberParser.class
).map(this.injector::getInstance).forEach(this::scanClass);
// Then we scan the commands.
Stream.of(
CommandAdd.class,
CommandClaim.class
).map(this.injector::getInstance).forEach(this::scanClass);
}
}

View File

@ -0,0 +1,94 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.arguments;
import cloud.commandframework.context.CommandContext;
import com.plotsquared.core.commands.parsers.PlotMemberParser;
import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.player.PlotPlayer;
import org.checkerframework.checker.nullness.qual.MonotonicNonNull;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.UUID;
public sealed interface PlotMember {
PlotMember EVERYONE = new Everyone();
default @NonNull UUID uuid(@NonNull CommandContext<PlotPlayer<?>> context) {
return this.uuid();
}
@NonNull UUID uuid();
sealed interface PlayerLike extends PlotMember {
}
record Player(@NonNull UUID uuid) implements PlayerLike {
}
final class LazyPlayer implements PlayerLike {
private final String candidate;
private final UuidSupplier uuidSupplier;
private @MonotonicNonNull UUID cachedUuid = null;
public LazyPlayer(
final @NonNull String candidate,
final @NonNull UuidSupplier uuidSupplier
) {
this.candidate = candidate;
this.uuidSupplier = uuidSupplier;
}
public @NonNull UUID uuid() {
throw new UnsupportedOperationException();
}
@Override
public synchronized @NonNull UUID uuid(final @NonNull CommandContext<PlotPlayer<?>> context) {
if (this.cachedUuid == null) {
try {
this.cachedUuid = this.uuidSupplier.uuid();
} catch (Exception ignored) {
}
// The player didn't exist :-(
if (this.cachedUuid == null) {
throw new PlotMemberParser.TargetParseException(this.candidate, context);
}
}
return this.cachedUuid;
}
@FunctionalInterface
public interface UuidSupplier {
@Nullable UUID uuid() throws Exception;
}
}
final class Everyone implements PlotMember {
@Override
public @NonNull UUID uuid() {
return DBFunc.EVERYONE;
}
}
}

View File

@ -0,0 +1,124 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.parsers;
import cloud.commandframework.annotations.parsers.Parser;
import cloud.commandframework.captions.CaptionVariable;
import cloud.commandframework.context.CommandContext;
import cloud.commandframework.exceptions.parsing.NoInputProvidedException;
import cloud.commandframework.exceptions.parsing.ParserException;
import com.google.inject.Inject;
import com.plotsquared.core.commands.PlotSquaredCaptionKeys;
import com.plotsquared.core.commands.arguments.PlotMember;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.inject.annotations.ImpromptuPipeline;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.uuid.UUIDMapping;
import com.plotsquared.core.uuid.UUIDPipeline;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.io.Serial;
import java.util.Queue;
import java.util.UUID;
public class PlotMemberParser {
private final UUIDPipeline uuidPipeline;
@Inject
public PlotMemberParser(@ImpromptuPipeline final @NonNull UUIDPipeline uuidPipeline) {
this.uuidPipeline = uuidPipeline;
}
@Parser
public @NonNull PlotMember parse(
final @NonNull CommandContext<PlotPlayer<?>> context,
final @NonNull Queue<@NonNull String> input
) {
final var candidate = input.peek();
if (candidate == null) {
throw new NoInputProvidedException(this.getClass(), context);
}
if ("*".equals(candidate)) {
return PlotMember.EVERYONE;
} else if (candidate.length() > 16) {
try {
return new PlotMember.Player(UUID.fromString(candidate));
} catch (IllegalArgumentException ignored) {
throw new TargetParseException(candidate, context);
}
}
if (Settings.Paper_Components.PAPER_LISTENERS) {
try {
return this.uuidPipeline.getUUID(candidate, Settings.UUID.NON_BLOCKING_TIMEOUT)
.get()
.map(UUIDMapping::getUuid)
.map(PlotMember.Player::new)
.orElseThrow();
} catch (Exception e) {
throw new TargetParseException(candidate, context);
}
} else {
return new PlotMember.LazyPlayer(
candidate,
() -> this.uuidPipeline.getUUID(candidate, Settings.UUID.NON_BLOCKING_TIMEOUT)
.get()
.map(UUIDMapping::getUuid)
.orElse(null)
);
}
}
public static final class TargetParseException extends ParserException {
@Serial
private static final long serialVersionUID = 927476591631527552L;
private final String input;
/**
* Construct a new Player parse exception
*
* @param input String input
* @param context Command context
*/
public TargetParseException(
final @NonNull String input,
final @NonNull CommandContext<?> context
) {
super(
PlotMemberParser.class,
context,
PlotSquaredCaptionKeys.ARGUMENT_PARSE_FAILURE_TARGET,
CaptionVariable.of("input", input)
);
this.input = input;
}
/**
* Get the supplied input
*
* @return String value
*/
public @NonNull String getInput() {
return this.input;
}
}
}

View File

@ -0,0 +1,88 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.requirements;
import cloud.commandframework.meta.CommandMeta;
import com.plotsquared.core.configuration.caption.Caption;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.player.PlotPlayer;
import io.leangen.geantyref.TypeToken;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;
public enum CommandRequirement {
PLAYER(
"",
player -> !(player instanceof ConsolePlayer)
),
IN_PLOT(
"errors.not_in_plot",
player -> player.getCurrentPlot() != null
),
PLOT_HAS_OWNER(
"info.plot_unowned",
player -> Objects.requireNonNull(player.getCurrentPlot()).hasOwner(),
IN_PLOT
),
IS_OWNER(
"permission.no_plot_perms",
player -> Objects.requireNonNull(player.getCurrentPlot()).isOwner(player.getUUID()),
PLOT_HAS_OWNER
);
public static final CommandMeta.Key<List<CommandRequirement>> COMMAND_REQUIREMENTS_KEY = CommandMeta.Key.of(
new TypeToken<List<CommandRequirement>>() {
},
"command_requirements"
);
private final @NonNull Caption caption;
private final @NonNull Predicate<@NonNull PlotPlayer<?>> requirementPredicate;
private final @NonNull Set<@NonNull CommandRequirement> inheritedRequirements;
CommandRequirement(
final @NonNull String caption,
final @NonNull Predicate<@NonNull PlotPlayer<?>> requirementPredicate,
final @NonNull CommandRequirement... inheritedRequirements
) {
this.caption = TranslatableCaption.of(caption);
this.requirementPredicate = requirementPredicate;
this.inheritedRequirements = EnumSet.copyOf(Arrays.asList(inheritedRequirements));
}
public @NonNull Set<@NonNull CommandRequirement> inheritedRequirements() {
return Collections.unmodifiableSet(this.inheritedRequirements);
}
public @NonNull Caption caption() {
return this.caption;
}
public boolean checkRequirement(final @NonNull PlotPlayer<?> player) {
return this.requirementPredicate.test(player);
}
}

View File

@ -0,0 +1,61 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.requirements;
import cloud.commandframework.Command;
import com.plotsquared.core.player.PlotPlayer;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.EnumSet;
import java.util.List;
import java.util.Set;
import java.util.function.BiFunction;
public class CommandRequirementBuilderModifier implements BiFunction<
@NonNull Requirements,
Command.@NonNull Builder<PlotPlayer<?>>,
Command.@NonNull Builder<PlotPlayer<?>>
> {
@Override
public Command.@NonNull Builder<PlotPlayer<?>> apply(
final @NonNull Requirements requirements,
final Command.@NonNull Builder<PlotPlayer<?>> builder
) {
// We use a list, because we want them to be evaluated in order.
final Set<CommandRequirement> commandRequirements = EnumSet.noneOf(CommandRequirement.class);
for (final Requirement requirement : requirements.value()) {
this.addRequirements(commandRequirements, requirement.value());
}
// We then sort the requirements.
final List<CommandRequirement> sortedRequirements = commandRequirements.stream().sorted().toList();
// We then register all the types in the command metadata.
return builder.meta(CommandRequirement.COMMAND_REQUIREMENTS_KEY, sortedRequirements);
}
private void addRequirements(
final @NonNull Set<@NonNull CommandRequirement> requirements,
final @NonNull CommandRequirement requirement
) {
for (final CommandRequirement inheritedRequirement : requirement.inheritedRequirements()) {
addRequirements(requirements, inheritedRequirement);
}
requirements.add(requirement);
}
}

View File

@ -0,0 +1,54 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.requirements;
import cloud.commandframework.Command;
import cloud.commandframework.execution.postprocessor.CommandPostprocessingContext;
import cloud.commandframework.execution.postprocessor.CommandPostprocessor;
import cloud.commandframework.services.types.ConsumerService;
import com.plotsquared.core.player.PlotPlayer;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.List;
public class CommandRequirementPostProcessor implements CommandPostprocessor<PlotPlayer<?>> {
@Override
public void accept(
@NonNull final CommandPostprocessingContext<PlotPlayer<?>> context
) {
final Command<PlotPlayer<?>> command = context.getCommand();
final PlotPlayer<?> player = context.getCommandContext().getSender();;
final List<CommandRequirement> commandRequirements = command.getCommandMeta().get(
CommandRequirement.COMMAND_REQUIREMENTS_KEY
).orElse(List.of());
for (final CommandRequirement requirement : commandRequirements) {
if (requirement.checkRequirement(player)) {
continue;
}
// They failed the requirement =(
player.sendMessage(requirement.caption());
// Then we interrupt to make sure the command isn't executed.
ConsumerService.interrupt();
}
}
}

View File

@ -16,24 +16,20 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
package com.plotsquared.core.plot.flag.implementations; package com.plotsquared.core.commands.requirements;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.plot.flag.types.BooleanFlag;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
public class SculkSensorInteractFlag extends BooleanFlag<SculkSensorInteractFlag> { import java.lang.annotation.ElementType;
import java.lang.annotation.Repeatable;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public static final SculkSensorInteractFlag SCULK_SENSOR_INTERACT_TRUE = new SculkSensorInteractFlag(true); @Repeatable(Requirements.class)
public static final SculkSensorInteractFlag SCULK_SENSOR_INTERACT_FALSE = new SculkSensorInteractFlag(false); @Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
private SculkSensorInteractFlag(boolean value) { public @interface Requirement {
super(value, TranslatableCaption.of("flags.flag_description_sculk_sensor_interact"));
}
@Override
protected SculkSensorInteractFlag flagOf(@NonNull Boolean value) {
return value ? SCULK_SENSOR_INTERACT_TRUE : SCULK_SENSOR_INTERACT_FALSE;
}
@NonNull CommandRequirement value();
} }

View File

@ -0,0 +1,33 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.commands.requirements;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Requirements {
@NonNull Requirement @NonNull[] value();
}

View File

@ -35,22 +35,34 @@ import java.util.Map;
* the component GUI * the component GUI
*/ */
@SerializableAs("preset") @SerializableAs("preset")
public record ComponentPreset( public class ComponentPreset implements ConfigurationSerializable {
ClassicPlotManagerComponent component,
String pattern, private final ClassicPlotManagerComponent component;
double cost, private final String pattern;
String permission, private final double cost;
String displayName, private final String permission;
List<String> description, private final String displayName;
ItemType icon private final List<String> description;
) implements ConfigurationSerializable { private final ItemType icon;
public ComponentPreset(
ClassicPlotManagerComponent component, String pattern, double cost,
String permission, String displayName, List<String> description, final ItemType icon
) {
this.component = component;
this.pattern = pattern;
this.cost = cost;
this.permission = permission;
this.displayName = displayName;
this.description = description;
this.icon = icon;
}
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
public static ComponentPreset deserialize(final @NonNull Map<String, Object> map) { public static ComponentPreset deserialize(final @NonNull Map<String, Object> map) {
final ClassicPlotManagerComponent classicPlotManagerComponent = ClassicPlotManagerComponent final ClassicPlotManagerComponent classicPlotManagerComponent = ClassicPlotManagerComponent
.fromString(map.getOrDefault("component", "").toString()).orElseThrow(() -> .fromString(map.getOrDefault("component", "").toString()).orElseThrow(() ->
new IllegalArgumentException("The preset in components.yml needs a valid target component, got: " + map.get( new IllegalArgumentException("The preset in components.yml needs a valid target component, got: " + map.get("component")));
"component")));
final String pattern = map.getOrDefault("pattern", "").toString(); final String pattern = map.getOrDefault("pattern", "").toString();
final double cost = Double.parseDouble(map.getOrDefault("cost", "0.0").toString()); final double cost = Double.parseDouble(map.getOrDefault("cost", "0.0").toString());
final String permission = map.getOrDefault("permission", "").toString(); final String permission = map.getOrDefault("permission", "").toString();
@ -62,6 +74,34 @@ public record ComponentPreset(
); );
} }
public ClassicPlotManagerComponent getComponent() {
return this.component;
}
public String getPattern() {
return this.pattern;
}
public double getCost() {
return this.cost;
}
public String getPermission() {
return this.permission;
}
public String getDisplayName() {
return this.displayName;
}
public List<String> getDescription() {
return this.description;
}
public ItemType getIcon() {
return this.icon;
}
@Override @Override
public Map<String, Object> serialize() { public Map<String, Object> serialize() {
final Map<String, Object> map = new HashMap<>(); final Map<String, Object> map = new HashMap<>();

View File

@ -165,8 +165,8 @@ public class ComponentPresetManager {
final List<ComponentPreset> allowedPresets = new ArrayList<>(this.presets.size()); final List<ComponentPreset> allowedPresets = new ArrayList<>(this.presets.size());
for (final ComponentPreset componentPreset : this.presets) { for (final ComponentPreset componentPreset : this.presets) {
if (!componentPreset.permission().isEmpty() && !player.hasPermission( if (!componentPreset.getPermission().isEmpty() && !player.hasPermission(
componentPreset.permission() componentPreset.getPermission()
)) { )) {
continue; continue;
} }
@ -200,30 +200,30 @@ public class ComponentPresetManager {
return false; return false;
} }
final Pattern pattern = PatternUtil.parse(null, componentPreset.pattern(), false); final Pattern pattern = PatternUtil.parse(null, componentPreset.getPattern(), false);
if (pattern == null) { if (pattern == null) {
getPlayer().sendMessage(TranslatableCaption.of("preset.preset_invalid")); getPlayer().sendMessage(TranslatableCaption.of("preset.preset_invalid"));
return false; return false;
} }
if (componentPreset.cost() > 0.0D) { if (componentPreset.getCost() > 0.0D) {
if (!econHandler.isEnabled(plot.getArea())) { if (!econHandler.isEnabled(plot.getArea())) {
getPlayer().sendMessage( getPlayer().sendMessage(
TranslatableCaption.of("preset.economy_disabled"), TranslatableCaption.of("preset.economy_disabled"),
TagResolver.resolver("preset", Tag.inserting(Component.text(componentPreset.displayName()))) TagResolver.resolver("preset", Tag.inserting(Component.text(componentPreset.getDisplayName())))
); );
return false; return false;
} }
if (econHandler.getMoney(getPlayer()) < componentPreset.cost()) { if (econHandler.getMoney(getPlayer()) < componentPreset.getCost()) {
getPlayer().sendMessage(TranslatableCaption.of("preset.preset_cannot_afford")); getPlayer().sendMessage(TranslatableCaption.of("preset.preset_cannot_afford"));
return false; return false;
} else { } else {
econHandler.withdrawMoney(getPlayer(), componentPreset.cost()); econHandler.withdrawMoney(getPlayer(), componentPreset.getCost());
getPlayer().sendMessage( getPlayer().sendMessage(
TranslatableCaption.of("economy.removed_balance"), TranslatableCaption.of("economy.removed_balance"),
TagResolver.resolver( TagResolver.resolver(
"money", "money",
Tag.inserting(Component.text(econHandler.format(componentPreset.cost()))) Tag.inserting(Component.text(econHandler.format(componentPreset.getCost())))
) )
); );
} }
@ -235,7 +235,7 @@ public class ComponentPresetManager {
queue.setCompleteTask(plot::removeRunning); queue.setCompleteTask(plot::removeRunning);
for (Plot current : plot.getConnectedPlots()) { for (Plot current : plot.getConnectedPlots()) {
current.getPlotModificationManager().setComponent( current.getPlotModificationManager().setComponent(
componentPreset.component().name(), componentPreset.getComponent().name(),
pattern, pattern,
player, player,
queue queue
@ -252,32 +252,32 @@ public class ComponentPresetManager {
for (int i = 0; i < allowedPresets.size(); i++) { for (int i = 0; i < allowedPresets.size(); i++) {
final ComponentPreset preset = allowedPresets.get(i); final ComponentPreset preset = allowedPresets.get(i);
final List<String> lore = new ArrayList<>(); final List<String> lore = new ArrayList<>();
if (preset.cost() > 0) { if (preset.getCost() > 0) {
if (!this.econHandler.isEnabled(plot.getArea())) { if (!this.econHandler.isEnabled(plot.getArea())) {
lore.add(MINI_MESSAGE.serialize(MINI_MESSAGE.deserialize( lore.add(MINI_MESSAGE.serialize(MINI_MESSAGE.deserialize(
TranslatableCaption.of("preset.preset_lore_economy_disabled").getComponent(player)))); TranslatableCaption.of("preset.preset_lore_economy_disabled").getComponent(player))));
} else { } else {
lore.add(MINI_MESSAGE.serialize(MINI_MESSAGE.deserialize( lore.add(MINI_MESSAGE.serialize(MINI_MESSAGE.deserialize(
TranslatableCaption.of("preset.preset_lore_cost").getComponent(player), TranslatableCaption.of("preset.preset_lore_cost").getComponent(player),
TagResolver.resolver("cost", Tag.inserting(Component.text(String.format("%.2f", preset.cost())))) TagResolver.resolver("cost", Tag.inserting(Component.text(String.format("%.2f", preset.getCost()))))
))); )));
} }
} }
lore.add(MINI_MESSAGE.serialize(MINI_MESSAGE.deserialize( lore.add(MINI_MESSAGE.serialize(MINI_MESSAGE.deserialize(
TranslatableCaption.of("preset.preset_lore_component").getComponent(player), TranslatableCaption.of("preset.preset_lore_component").getComponent(player),
TagResolver.builder() TagResolver.builder()
.tag("component", Tag.inserting(Component.text(preset.component().name().toLowerCase()))) .tag("component", Tag.inserting(Component.text(preset.getComponent().name().toLowerCase())))
.tag("prefix", Tag.inserting(TranslatableCaption.of("core.prefix").toComponent(player))) .tag("prefix", Tag.inserting(TranslatableCaption.of("core.prefix").toComponent(player)))
.build() .build()
))); )));
lore.removeIf(String::isEmpty); lore.removeIf(String::isEmpty);
lore.addAll(preset.description()); lore.addAll(preset.getDescription());
plotInventory.setItem( plotInventory.setItem(
i, i,
new PlotItemStack( new PlotItemStack(
preset.icon().getId().replace("minecraft:", ""), preset.getIcon().getId().replace("minecraft:", ""),
1, 1,
preset.displayName(), preset.getDisplayName(),
lore.toArray(new String[0]) lore.toArray(new String[0])
) )
); );

View File

@ -42,6 +42,32 @@ public class Config {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Config.class.getSimpleName()); private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Config.class.getSimpleName());
/**
* Get the value for a node<br>
* Probably throws some error if you try to get a non existent key
*
* @param key configuration key
* @param root configuration class
* @param <T> value type
* @return value
*/
@SuppressWarnings("unchecked")
public static <T> T get(String key, Class<?> root) {
String[] split = key.split("\\.");
Object instance = getInstance(split, root);
if (instance != null) {
Field field = getField(split, instance);
if (field != null) {
try {
return (T) field.get(instance);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
return null;
}
/** /**
* Set the value of a specific node<br> * Set the value of a specific node<br>
* Probably throws some error if you supply non existing keys or invalid values * Probably throws some error if you supply non existing keys or invalid values
@ -233,6 +259,7 @@ public class Config {
* *
* @param split the node (split by period) * @param split the node (split by period)
* @param instance the instance * @param instance the instance
* @return
*/ */
private static Field getField(String[] split, Object instance) { private static Field getField(String[] split, Object instance) {
try { try {
@ -418,6 +445,10 @@ public class Config {
return INSTANCES.values(); return INSTANCES.values();
} }
public Collection<String> getSections() {
return INSTANCES.keySet();
}
private Map<String, T> getRaw() { private Map<String, T> getRaw() {
return INSTANCES; return INSTANCES;
} }

View File

@ -40,7 +40,7 @@ public interface Caption {
* *
* @param localeHolder Locale holder * @param localeHolder Locale holder
* @return {@link ComponentLike} * @return {@link ComponentLike}
* @since 7.0.0 * @since TODO
*/ */
@NonNull Component toComponent(@NonNull LocaleHolder localeHolder); @NonNull Component toComponent(@NonNull LocaleHolder localeHolder);

View File

@ -51,7 +51,7 @@ public class CaptionHolder {
* Get the {@link TagResolver}s to use when resolving tags in the {@link Caption}. * Get the {@link TagResolver}s to use when resolving tags in the {@link Caption}.
* *
* @return The tag resolvers to use. * @return The tag resolvers to use.
* @since 7.0.0 * @since TODO
*/ */
public TagResolver[] getTagResolvers() { public TagResolver[] getTagResolvers() {
return this.tagResolvers; return this.tagResolvers;
@ -61,7 +61,7 @@ public class CaptionHolder {
* Set the {@link TagResolver}s to use when resolving tags in the {@link Caption}. * Set the {@link TagResolver}s to use when resolving tags in the {@link Caption}.
* *
* @param tagResolvers The tag resolvers to use. * @param tagResolvers The tag resolvers to use.
* @since 7.0.0 * @since TODO
*/ */
public void setTagResolvers(TagResolver... tagResolvers) { public void setTagResolvers(TagResolver... tagResolvers) {
this.tagResolvers = tagResolvers; this.tagResolvers = tagResolvers;

View File

@ -28,20 +28,16 @@ import com.plotsquared.core.plot.flag.implementations.PlotTitleFlag;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.event.ClickEvent; import net.kyori.adventure.text.event.ClickEvent;
import net.kyori.adventure.text.minimessage.MiniMessage; import net.kyori.adventure.text.minimessage.MiniMessage;
import net.kyori.adventure.text.minimessage.ParsingException;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.Set; import java.util.Set;
import java.util.regex.Pattern;
import static com.plotsquared.core.configuration.caption.ComponentTransform.nested; import static com.plotsquared.core.configuration.caption.ComponentTransform.nested;
import static com.plotsquared.core.configuration.caption.ComponentTransform.stripClicks; import static com.plotsquared.core.configuration.caption.ComponentTransform.stripClicks;
public class CaptionUtility { public class CaptionUtility {
private static final Pattern LEGACY_FORMATTING = Pattern.compile("§[a-gklmnor0-9]");
// flags which values are parsed by minimessage // flags which values are parsed by minimessage
private static final Set<Class<? extends PlotFlag<?, ?>>> MINI_MESSAGE_FLAGS = Set.of( private static final Set<Class<? extends PlotFlag<?, ?>>> MINI_MESSAGE_FLAGS = Set.of(
GreetingFlag.class, GreetingFlag.class,
@ -104,14 +100,7 @@ public class CaptionUtility {
*/ */
public static String stripClickEvents(final @NonNull String miniMessageString) { public static String stripClickEvents(final @NonNull String miniMessageString) {
// parse, transform and serialize again // parse, transform and serialize again
Component component; Component component = MiniMessage.miniMessage().deserialize(miniMessageString);
try {
component = MiniMessage.miniMessage().deserialize(miniMessageString);
} catch (ParsingException e) {
// if the String cannot be parsed, we try stripping legacy colors
String legacyStripped = LEGACY_FORMATTING.matcher(miniMessageString).replaceAll("");
component = MiniMessage.miniMessage().deserialize(legacyStripped);
}
component = CLICK_STRIP_TRANSFORM.transform(component); component = CLICK_STRIP_TRANSFORM.transform(component);
return MiniMessage.miniMessage().serialize(component); return MiniMessage.miniMessage().serialize(component);
} }

View File

@ -56,8 +56,7 @@ final class ClassLoaderCaptionProvider implements DefaultCaptionProvider {
LOGGER.info("No resource for locale '{}' found in the plugin file." + LOGGER.info("No resource for locale '{}' found in the plugin file." +
"Please ensure you have placed the latest version of the file messages_{}.json in the 'lang' folder." + "Please ensure you have placed the latest version of the file messages_{}.json in the 'lang' folder." +
"You may be able to find completed translations at https://intellectualsites.crowdin.com/plotsquared", "You may be able to find completed translations at https://intellectualsites.crowdin.com/plotsquared",
locale, locale locale, locale);
);
return null; return null;
} }
try (final BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) { try (final BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {

View File

@ -19,7 +19,6 @@
package com.plotsquared.core.configuration.file; package com.plotsquared.core.configuration.file;
import com.plotsquared.core.configuration.serialization.ConfigurationSerialization; import com.plotsquared.core.configuration.serialization.ConfigurationSerialization;
import org.yaml.snakeyaml.LoaderOptions;
import org.yaml.snakeyaml.constructor.SafeConstructor; import org.yaml.snakeyaml.constructor.SafeConstructor;
import org.yaml.snakeyaml.error.YAMLException; import org.yaml.snakeyaml.error.YAMLException;
import org.yaml.snakeyaml.nodes.Node; import org.yaml.snakeyaml.nodes.Node;
@ -31,7 +30,6 @@ import java.util.Map;
public class YamlConstructor extends SafeConstructor { public class YamlConstructor extends SafeConstructor {
YamlConstructor() { YamlConstructor() {
super(new LoaderOptions());
yamlConstructors.put(Tag.MAP, new ConstructCustomObject()); yamlConstructors.put(Tag.MAP, new ConstructCustomObject());
} }

View File

@ -21,7 +21,6 @@ package com.plotsquared.core.configuration.file;
import com.plotsquared.core.configuration.ConfigurationSection; import com.plotsquared.core.configuration.ConfigurationSection;
import com.plotsquared.core.configuration.serialization.ConfigurationSerializable; import com.plotsquared.core.configuration.serialization.ConfigurationSerializable;
import com.plotsquared.core.configuration.serialization.ConfigurationSerialization; import com.plotsquared.core.configuration.serialization.ConfigurationSerialization;
import org.yaml.snakeyaml.DumperOptions;
import org.yaml.snakeyaml.nodes.Node; import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.representer.Representer; import org.yaml.snakeyaml.representer.Representer;
@ -31,7 +30,6 @@ import java.util.Map;
class YamlRepresenter extends Representer { class YamlRepresenter extends Representer {
YamlRepresenter() { YamlRepresenter() {
super(new DumperOptions());
this.multiRepresenters.put(ConfigurationSection.class, new RepresentConfigurationSection()); this.multiRepresenters.put(ConfigurationSection.class, new RepresentConfigurationSection());
this.multiRepresenters this.multiRepresenters
.put(ConfigurationSerializable.class, new RepresentConfigurationSerializable()); .put(ConfigurationSerializable.class, new RepresentConfigurationSerializable());

View File

@ -2400,13 +2400,13 @@ public class SQLManager implements AbstractDB {
if (plot != null) { if (plot != null) {
statement.setString(1, plot.getArea().toString()); statement.setString(1, plot.getArea().toString());
statement.setInt(2, plot.getId().hashCode()); statement.setInt(2, plot.getId().hashCode());
statement.setString(3, comment.comment()); statement.setString(3, comment.comment);
statement.setString(4, comment.inbox()); statement.setString(4, comment.inbox);
statement.setString(5, comment.senderName()); statement.setString(5, comment.senderName);
} else { } else {
statement.setString(1, comment.comment()); statement.setString(1, comment.comment);
statement.setString(2, comment.inbox()); statement.setString(2, comment.inbox);
statement.setString(3, comment.senderName()); statement.setString(3, comment.senderName);
} }
} }
@ -2518,10 +2518,10 @@ public class SQLManager implements AbstractDB {
public void set(PreparedStatement statement) throws SQLException { public void set(PreparedStatement statement) throws SQLException {
statement.setString(1, plot.getArea().toString()); statement.setString(1, plot.getArea().toString());
statement.setInt(2, plot.getId().hashCode()); statement.setInt(2, plot.getId().hashCode());
statement.setString(3, comment.comment()); statement.setString(3, comment.comment);
statement.setString(4, comment.inbox()); statement.setString(4, comment.inbox);
statement.setInt(5, (int) (comment.timestamp() / 1000)); statement.setInt(5, (int) (comment.timestamp / 1000));
statement.setString(6, comment.senderName()); statement.setString(6, comment.senderName);
} }
@Override @Override
@ -3414,10 +3414,15 @@ public class SQLManager implements AbstractDB {
} }
} }
private record LegacySettings( private static class LegacySettings {
int id,
PlotSettings settings public final int id;
) { public final PlotSettings settings;
public LegacySettings(int id, PlotSettings settings) {
this.id = id;
this.settings = settings;
}
} }

View File

@ -22,7 +22,7 @@ import com.sk89q.worldedit.entity.Entity;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
/** /**
* @since 6.11.1 * @since TODO
*/ */
public abstract class EntityEvent { public abstract class EntityEvent {
@ -53,8 +53,7 @@ public abstract class EntityEvent {
* @return the event class name * @return the event class name
* @since 6.11.0 * @since 6.11.0
*/ */
@NonNull @NonNull public String getEventName() {
public String getEventName() {
if (this.name == null) { if (this.name == null) {
this.name = this.getClass().getSimpleName(); this.name = this.getClass().getSimpleName();
} }

View File

@ -18,7 +18,6 @@
*/ */
package com.plotsquared.core.events; package com.plotsquared.core.events;
import com.plotsquared.core.command.Claim;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;

View File

@ -18,7 +18,6 @@
*/ */
package com.plotsquared.core.events; package com.plotsquared.core.events;
import com.plotsquared.core.command.Claim;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;

View File

@ -379,11 +379,10 @@ public class ClassicPlotManager extends SquarePlotManager {
} }
} }
int yStart = classicPlotWorld.getMinBuildHeight() + (classicPlotWorld.PLOT_BEDROCK ? 1 : 0);
if (!plot.isMerged(Direction.NORTH)) { if (!plot.isMerged(Direction.NORTH)) {
int z = bot.getZ(); int z = bot.getZ();
for (int x = bot.getX(); x < top.getX(); x++) { for (int x = bot.getX(); x < top.getX(); x++) {
for (int y = yStart; y <= classicPlotWorld.WALL_HEIGHT; y++) { for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) {
queue.setBlock(x, y, z, blocks); queue.setBlock(x, y, z, blocks);
} }
} }
@ -391,7 +390,7 @@ public class ClassicPlotManager extends SquarePlotManager {
if (!plot.isMerged(Direction.WEST)) { if (!plot.isMerged(Direction.WEST)) {
int x = bot.getX(); int x = bot.getX();
for (int z = bot.getZ(); z < top.getZ(); z++) { for (int z = bot.getZ(); z < top.getZ(); z++) {
for (int y = yStart; y <= classicPlotWorld.WALL_HEIGHT; y++) { for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) {
queue.setBlock(x, y, z, blocks); queue.setBlock(x, y, z, blocks);
} }
} }
@ -399,7 +398,7 @@ public class ClassicPlotManager extends SquarePlotManager {
if (!plot.isMerged(Direction.SOUTH)) { if (!plot.isMerged(Direction.SOUTH)) {
int z = top.getZ(); int z = top.getZ();
for (int x = bot.getX(); x < top.getX() + (plot.isMerged(Direction.EAST) ? 0 : 1); x++) { for (int x = bot.getX(); x < top.getX() + (plot.isMerged(Direction.EAST) ? 0 : 1); x++) {
for (int y = yStart; y <= classicPlotWorld.WALL_HEIGHT; y++) { for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) {
queue.setBlock(x, y, z, blocks); queue.setBlock(x, y, z, blocks);
} }
} }
@ -407,7 +406,7 @@ public class ClassicPlotManager extends SquarePlotManager {
if (!plot.isMerged(Direction.EAST)) { if (!plot.isMerged(Direction.EAST)) {
int x = top.getX(); int x = top.getX();
for (int z = bot.getZ(); z < top.getZ() + (plot.isMerged(Direction.SOUTH) ? 0 : 1); z++) { for (int z = bot.getZ(); z < top.getZ() + (plot.isMerged(Direction.SOUTH) ? 0 : 1); z++) {
for (int y = yStart; y <= classicPlotWorld.WALL_HEIGHT; y++) { for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) {
queue.setBlock(x, y, z, blocks); queue.setBlock(x, y, z, blocks);
} }
} }

View File

@ -38,7 +38,6 @@ import javax.annotation.Nullable;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public abstract class ClassicPlotWorld extends SquarePlotWorld { public abstract class ClassicPlotWorld extends SquarePlotWorld {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + ClassicPlotWorld.class.getSimpleName()); private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + ClassicPlotWorld.class.getSimpleName());
public int ROAD_HEIGHT = 62; public int ROAD_HEIGHT = 62;
@ -65,21 +64,6 @@ public abstract class ClassicPlotWorld extends SquarePlotWorld {
super(worldName, id, generator, min, max, worldConfiguration, blockQueue); super(worldName, id, generator, min, max, worldConfiguration, blockQueue);
} }
private static BlockBucket createCheckedBlockBucket(String input, BlockBucket def) {
final BlockBucket bucket = new BlockBucket(input);
Pattern pattern = null;
try {
pattern = bucket.toPattern();
} catch (Exception ignore) {
}
if (pattern == null) {
LOGGER.error("Failed to parse pattern '{}', check your worlds.yml", input);
LOGGER.error("Falling back to {}", def);
return def;
}
return bucket;
}
/** /**
* CONFIG NODE | DEFAULT VALUE | DESCRIPTION | CONFIGURATION TYPE | REQUIRED FOR INITIAL SETUP. * CONFIG NODE | DEFAULT VALUE | DESCRIPTION | CONFIGURATION TYPE | REQUIRED FOR INITIAL SETUP.
* *
@ -160,4 +144,19 @@ public abstract class ClassicPlotWorld extends SquarePlotWorld {
return Math.min(WALL_HEIGHT, plotRoadMin); return Math.min(WALL_HEIGHT, plotRoadMin);
} }
private static BlockBucket createCheckedBlockBucket(String input, BlockBucket def) {
final BlockBucket bucket = new BlockBucket(input);
Pattern pattern = null;
try {
pattern = bucket.toPattern();
} catch (Exception ignore) {
}
if (pattern == null) {
LOGGER.error("Failed to parse pattern '{}', check your worlds.yml", input);
LOGGER.error("Falling back to {}", def);
return def;
}
return bucket;
}
} }

View File

@ -341,10 +341,7 @@ public class HybridGen extends IndependentPlotGenerator {
for (Entity entity : hybridPlotWorld.getPlotSchematicEntities()) { for (Entity entity : hybridPlotWorld.getPlotSchematicEntities()) {
if (region.contains(entity.getLocation().toVector().toBlockPoint())) { if (region.contains(entity.getLocation().toVector().toBlockPoint())) {
Vector3 pos = (entity.getLocation().toVector() Vector3 pos = (entity.getLocation().toVector()
.subtract(region .subtract(region.getMinimumPoint().withY(hybridPlotWorld.getPlotSchematicMinPoint().getY()).toVector3()))
.getMinimumPoint()
.withY(hybridPlotWorld.getPlotSchematicMinPoint().getY())
.toVector3()))
.add(min.getBlockVector3().withY(hybridPlotWorld.SCHEM_Y).toVector3()); .add(min.getBlockVector3().withY(hybridPlotWorld.SCHEM_Y).toVector3());
result.setEntity(new PopulatingEntity( result.setEntity(new PopulatingEntity(
entity, entity,
@ -402,12 +399,6 @@ public class HybridGen extends IndependentPlotGenerator {
return biome == null ? hybridPlotWorld.getPlotBiome() : biome; return biome == null ? hybridPlotWorld.getPlotBiome() : biome;
} }
private enum SchematicFeature {
BIOMES,
ROAD,
POPULATING
}
/** /**
* Wrapper to allow a WorldEdit {@link Entity} to effectively have a mutable location as the location in its NBT should be changed * Wrapper to allow a WorldEdit {@link Entity} to effectively have a mutable location as the location in its NBT should be changed
* when set to the world. * when set to the world.
@ -462,4 +453,10 @@ public class HybridGen extends IndependentPlotGenerator {
} }
private enum SchematicFeature {
BIOMES,
ROAD,
POPULATING
}
} }

View File

@ -141,11 +141,7 @@ public class HybridPlotManager extends ClassicPlotManager {
(pos1.getX() + pos2.getX()) / 2, (pos1.getX() + pos2.getX()) / 2,
(pos1.getZ() + pos2.getZ()) / 2 (pos1.getZ() + pos2.getZ()) / 2
), biome)) { ), biome)) {
WorldUtil.setBiome( WorldUtil.setBiome(hybridPlotWorld.getWorldName(), new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()), biome);
hybridPlotWorld.getWorldName(),
new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()),
biome
);
} }
} }
@ -207,18 +203,8 @@ public class HybridPlotManager extends ClassicPlotManager {
PlotId id2 = PlotId.of(id.getX(), id.getY() + 1); PlotId id2 = PlotId.of(id.getX(), id.getY() + 1);
Location bot = getPlotBottomLocAbs(id2); Location bot = getPlotBottomLocAbs(id2);
Location top = getPlotTopLocAbs(id); Location top = getPlotTopLocAbs(id);
Location pos1 = Location.at( Location pos1 = Location.at(hybridPlotWorld.getWorldName(), bot.getX() - 1, hybridPlotWorld.getMinGenHeight(), top.getZ() + 1);
hybridPlotWorld.getWorldName(), Location pos2 = Location.at(hybridPlotWorld.getWorldName(), top.getX() + 1, hybridPlotWorld.getMaxGenHeight(), bot.getZ());
bot.getX() - 1,
hybridPlotWorld.getMinGenHeight(),
top.getZ() + 1
);
Location pos2 = Location.at(
hybridPlotWorld.getWorldName(),
top.getX() + 1,
hybridPlotWorld.getMaxGenHeight(),
bot.getZ()
);
this.resetBiome(hybridPlotWorld, pos1, pos2); this.resetBiome(hybridPlotWorld, pos1, pos2);
if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) {
return true; return true;
@ -288,13 +274,6 @@ public class HybridPlotManager extends ClassicPlotManager {
queue.setCompleteTask(whenDone); queue.setCompleteTask(whenDone);
} }
if (!canRegen) { if (!canRegen) {
if (hybridPlotWorld.getMinBuildHeight() < hybridPlotWorld.getMinGenHeight()) {
queue.setCuboid(
pos1.withY(hybridPlotWorld.getMinBuildHeight()),
pos2.withY(hybridPlotWorld.getMinGenHeight()),
BlockTypes.AIR.getDefaultState()
);
}
queue.setCuboid( queue.setCuboid(
pos1.withY(hybridPlotWorld.getMinGenHeight()), pos1.withY(hybridPlotWorld.getMinGenHeight()),
pos2.withY(hybridPlotWorld.getMinGenHeight()), pos2.withY(hybridPlotWorld.getMinGenHeight()),
@ -312,13 +291,6 @@ public class HybridPlotManager extends ClassicPlotManager {
pos2.withY(hybridPlotWorld.getMaxGenHeight()), pos2.withY(hybridPlotWorld.getMaxGenHeight()),
BlockTypes.AIR.getDefaultState() BlockTypes.AIR.getDefaultState()
); );
if (hybridPlotWorld.getMaxGenHeight() < hybridPlotWorld.getMaxBuildHeight() - 1) {
queue.setCuboid(
pos1.withY(hybridPlotWorld.getMaxGenHeight()),
pos2.withY(hybridPlotWorld.getMaxBuildHeight() - 1),
BlockTypes.AIR.getDefaultState()
);
}
queue.setBiomeCuboid(pos1, pos2, biome); queue.setBiomeCuboid(pos1, pos2, biome);
} else { } else {
queue.setRegenRegion(new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3())); queue.setRegenRegion(new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()));

View File

@ -323,7 +323,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
short w3 = (short) d3.getX(); short w3 = (short) d3.getX();
short l3 = (short) d3.getZ(); short l3 = (short) d3.getZ();
short h3 = (short) d3.getY(); short h3 = (short) d3.getY();
if (w3 > PLOT_WIDTH || l3 > PLOT_WIDTH) { if (w3 > PLOT_WIDTH || h3 > PLOT_WIDTH) {
this.ROAD_SCHEMATIC_ENABLED = true; this.ROAD_SCHEMATIC_ENABLED = true;
} }
int centerShiftZ; int centerShiftZ;
@ -378,7 +378,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
} }
if ((schematic1 == null && schematic2 == null) || this.ROAD_WIDTH == 0) { if ((schematic1 == null && schematic2 == null) || this.ROAD_WIDTH == 0) {
if (Settings.DEBUG) { if (Settings.DEBUG) {
LOGGER.info("- road schematic: false"); LOGGER.info("- schematic: false");
} }
return; return;
} }
@ -544,6 +544,14 @@ public class HybridPlotWorld extends ClassicPlotWorld {
return schem1PopulationNeeded || schem2PopulationNeeded || schem3PopulationNeeded; return schem1PopulationNeeded || schem2PopulationNeeded || schem3PopulationNeeded;
} }
/**
* @deprecated in favour of {@link HybridPlotWorld#getSchematicRoot()}
*/
@Deprecated(forRemoval = true, since = "6.9.0")
public File getRoot() {
return this.root;
}
/** /**
* Get the root folder for this world's generation schematics. May be null if schematics not initialised via * Get the root folder for this world's generation schematics. May be null if schematics not initialised via
* {@link HybridPlotWorld#setupSchematics()} * {@link HybridPlotWorld#setupSchematics()}

View File

@ -63,6 +63,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
import java.io.File; import java.io.File;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections; import java.util.Collections;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
@ -379,6 +380,22 @@ public class HybridUtils {
run.run(); run.run();
} }
public int checkModified(QueueCoordinator queue, int x1, int x2, int y1, int y2, int z1, int z2, BlockState[] blocks) {
int count = 0;
for (int y = y1; y <= y2; y++) {
for (int x = x1; x <= x2; x++) {
for (int z = z1; z <= z2; z++) {
BlockState block = queue.getBlock(x, y, z);
boolean same = Arrays.stream(blocks).anyMatch(p -> this.worldUtil.isBlockSame(block, p));
if (!same) {
count++;
}
}
}
}
return count;
}
public final ArrayList<BlockVector2> getChunks(BlockVector2 region) { public final ArrayList<BlockVector2> getChunks(BlockVector2 region) {
ArrayList<BlockVector2> chunks = new ArrayList<>(); ArrayList<BlockVector2> chunks = new ArrayList<>();
int sx = region.getX() << 5; int sx = region.getX() << 5;

View File

@ -46,7 +46,7 @@ public abstract class IndependentPlotGenerator {
* @param result Queue to write to * @param result Queue to write to
* @param settings PlotArea (settings) * @param settings PlotArea (settings)
* @param biomes If biomes should be generated * @param biomes If biomes should be generated
* @since 7.0.0 * @since TODO
*/ */
public abstract void generateChunk(ZeroedDelegateScopedQueueCoordinator result, PlotArea settings, boolean biomes); public abstract void generateChunk(ZeroedDelegateScopedQueueCoordinator result, PlotArea settings, boolean biomes);
@ -55,10 +55,9 @@ public abstract class IndependentPlotGenerator {
* *
* @param result Queue to write to * @param result Queue to write to
* @param setting PlotArea (settings) * @param setting PlotArea (settings)
* @since 7.0.0 * @since TODO
*/ */
public void populateChunk(ZeroedDelegateScopedQueueCoordinator result, PlotArea setting) { public void populateChunk(ZeroedDelegateScopedQueueCoordinator result, PlotArea setting) {}
}
/** /**
* Return a new PlotArea object. * Return a new PlotArea object.
@ -108,7 +107,7 @@ public abstract class IndependentPlotGenerator {
* @param y World y position * @param y World y position
* @param z World z position * @param z World z position
* @return Biome type to be generated * @return Biome type to be generated
* @since 7.0.0 * @since TODO
*/ */
public abstract BiomeType getBiome(PlotArea settings, int x, int y, int z); public abstract BiomeType getBiome(PlotArea settings, int x, int y, int z);

View File

@ -185,39 +185,31 @@ public abstract class SquarePlotManager extends GridPlotManager {
return null; return null;
} }
switch (hash) { switch (hash) {
case 8 -> { case 8:
// north // north
return plot.isMerged(Direction.NORTH) ? id : null; return plot.isMerged(Direction.NORTH) ? id : null;
} case 4:
case 4 -> {
// east // east
return plot.isMerged(Direction.EAST) ? id : null; return plot.isMerged(Direction.EAST) ? id : null;
} case 2:
case 2 -> {
// south // south
return plot.isMerged(Direction.SOUTH) ? id : null; return plot.isMerged(Direction.SOUTH) ? id : null;
} case 1:
case 1 -> {
// west // west
return plot.isMerged(Direction.WEST) ? id : null; return plot.isMerged(Direction.WEST) ? id : null;
} case 12:
case 12 -> {
// northeast // northeast
return plot.isMerged(Direction.NORTHEAST) ? id : null; return plot.isMerged(Direction.NORTHEAST) ? id : null;
} case 6:
case 6 -> {
// southeast // southeast
return plot.isMerged(Direction.SOUTHEAST) ? id : null; return plot.isMerged(Direction.SOUTHEAST) ? id : null;
} case 3:
case 3 -> {
// southwest // southwest
return plot.isMerged(Direction.SOUTHWEST) ? id : null; return plot.isMerged(Direction.SOUTHWEST) ? id : null;
} case 9:
case 9 -> {
// northwest // northwest
return plot.isMerged(Direction.NORTHWEST) ? id : null; return plot.isMerged(Direction.NORTHWEST) ? id : null;
} }
}
} catch (Exception ignored) { } catch (Exception ignored) {
LOGGER.error("Invalid plot / road width in settings.yml for world: {}", squarePlotWorld.getWorldName()); LOGGER.error("Invalid plot / road width in settings.yml for world: {}", squarePlotWorld.getWorldName());
} }

View File

@ -142,9 +142,7 @@ public class PlotListener {
Map.Entry<UUID, List<StatusEffect>> entry = iterator.next(); Map.Entry<UUID, List<StatusEffect>> entry = iterator.next();
List<StatusEffect> effects = entry.getValue(); List<StatusEffect> effects = entry.getValue();
effects.removeIf(effect -> currentTime > effect.expiresAt); effects.removeIf(effect -> currentTime > effect.expiresAt);
if (effects.isEmpty()) { if (effects.isEmpty()) iterator.remove();
iterator.remove();
}
} }
} }
}, TaskTime.seconds(1L)); }, TaskTime.seconds(1L));
@ -343,14 +341,14 @@ public class PlotListener {
} }
TimedFlag.Timed<Integer> feed = plot.getFlag(FeedFlag.class); TimedFlag.Timed<Integer> feed = plot.getFlag(FeedFlag.class);
if (feed.interval() != 0 && feed.value() != 0) { if (feed.getInterval() != 0 && feed.getValue() != 0) {
feedRunnable feedRunnable
.put(player.getUUID(), new Interval(feed.interval(), feed.value(), 20)); .put(player.getUUID(), new Interval(feed.getInterval(), feed.getValue(), 20));
} }
TimedFlag.Timed<Integer> heal = plot.getFlag(HealFlag.class); TimedFlag.Timed<Integer> heal = plot.getFlag(HealFlag.class);
if (heal.interval() != 0 && heal.value() != 0) { if (heal.getInterval() != 0 && heal.getValue() != 0) {
healRunnable healRunnable
.put(player.getUUID(), new Interval(heal.interval(), heal.value(), 20)); .put(player.getUUID(), new Interval(heal.getInterval(), heal.getValue(), 20));
} }
return true; return true;
} }
@ -488,7 +486,6 @@ public class PlotListener {
/** /**
* Marks an effect as a status effect that will be removed on leaving a plot * Marks an effect as a status effect that will be removed on leaving a plot
*
* @param uuid The uuid of the player the effect belongs to * @param uuid The uuid of the player the effect belongs to
* @param name The name of the status effect * @param name The name of the status effect
* @param expiresAt The time when the effect expires * @param expiresAt The time when the effect expires

View File

@ -21,11 +21,17 @@ package com.plotsquared.core.location;
import com.plotsquared.core.util.MathMan; import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.StringMan; import com.plotsquared.core.util.StringMan;
public record ChunkWrapper( public class ChunkWrapper {
String world,
int x, public final int x;
int z public final int z;
) { public final String world;
public ChunkWrapper(String world, int x, int z) {
this.world = world;
this.x = x;
this.z = z;
}
@Override @Override
public int hashCode() { public int hashCode() {

View File

@ -51,6 +51,7 @@ public final class UncheckedWorldLocation extends Location {
* @param y Y coordinate * @param y Y coordinate
* @param z Z coordinate * @param z Z coordinate
* @return New location * @return New location
*
* @since 6.9.0 * @since 6.9.0
*/ */
@DoNotUse @DoNotUse

View File

@ -288,7 +288,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
* *
* @return the plot the player is standing on or null if standing on a road or not in a {@link PlotArea} * @return the plot the player is standing on or null if standing on a road or not in a {@link PlotArea}
*/ */
public Plot getCurrentPlot() { public @Nullable Plot getCurrentPlot() {
try (final MetaDataAccess<Plot> lastPlotAccess = try (final MetaDataAccess<Plot> lastPlotAccess =
this.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) { this.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
if (lastPlotAccess.get().orElse(null) == null && !Settings.Enabled_Components.EVENTS) { if (lastPlotAccess.get().orElse(null) == null && !Settings.Enabled_Components.EVENTS) {

View File

@ -215,11 +215,17 @@ public final class BlockBucket implements ConfigurationSerializable {
return result; return result;
} }
private record Range( private static final class Range {
int min,
int max, private final int min;
boolean automatic private final int max;
) { private final boolean automatic;
public Range(int min, int max, boolean automatic) {
this.min = min;
this.max = max;
this.automatic = automatic;
}
public int getWeight() { public int getWeight() {
return max - min; return max - min;
@ -229,6 +235,46 @@ public final class BlockBucket implements ConfigurationSerializable {
return num <= max && num >= min; return num <= max && num >= min;
} }
public int getMin() {
return this.min;
}
public int getMax() {
return this.max;
}
public boolean equals(final Object o) {
if (o == this) {
return true;
}
if (!(o instanceof final Range other)) {
return false;
}
if (this.getMin() != other.getMin()) {
return false;
}
if (this.getMax() != other.getMax()) {
return false;
}
if (this.isAutomatic() != other.isAutomatic()) {
return false;
}
return true;
}
public int hashCode() {
final int PRIME = 59;
int result = 1;
result = result * PRIME + this.getMin();
result = result * PRIME + this.getMax();
result = result * PRIME + (this.isAutomatic() ? 79 : 97);
return result;
}
public boolean isAutomatic() {
return this.automatic;
}
} }
} }

View File

@ -20,6 +20,7 @@ package com.plotsquared.core.plot;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.command.Like; import com.plotsquared.core.command.Like;
@ -2417,6 +2418,7 @@ public class Plot {
if (!this.isMerged()) { if (!this.isMerged()) {
Location pos1 = this.getBottomAbs().withY(getArea().getMinBuildHeight()); Location pos1 = this.getBottomAbs().withY(getArea().getMinBuildHeight());
Location pos2 = this.getTopAbs().withY(getArea().getMaxBuildHeight()); Location pos2 = this.getTopAbs().withY(getArea().getMaxBuildHeight());
this.connectedCache = Sets.newHashSet(this);
CuboidRegion rg = new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()); CuboidRegion rg = new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3());
return Collections.singleton(rg); return Collections.singleton(rg);
} }

View File

@ -657,11 +657,9 @@ public abstract class PlotArea implements ComponentLike {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("height.height_limit"), TranslatableCaption.of("height.height_limit"),
TagResolver.builder() TagResolver.builder()
.tag("minheight", Tag.inserting(Component.text(minBuildHeight))) .tag("minHeight", Tag.inserting(Component.text(minBuildHeight)))
.tag( .tag("maxHeight",
"maxheight", Tag.inserting(Component.text(maxBuildHeight))).build()
Tag.inserting(Component.text(maxBuildHeight))
).build()
); );
// Return true if "failed" as the method will always be inverted otherwise // Return true if "failed" as the method will always be inverted otherwise
return true; return true;

View File

@ -79,6 +79,14 @@ public class PlotSettings {
this.ratings = ratings; this.ratings = ratings;
} }
public boolean setMerged(int direction, boolean merged) {
if (this.merged[direction] != merged) {
this.merged[direction] = merged;
return true;
}
return false;
}
public boolean setMerged(Direction direction, boolean merged) { public boolean setMerged(Direction direction, boolean merged) {
if (Direction.ALL == direction) { if (Direction.ALL == direction) {
throw new IllegalArgumentException("You cannot use Direction.ALL in this method!"); throw new IllegalArgumentException("You cannot use Direction.ALL in this method!");
@ -105,12 +113,13 @@ public class PlotSettings {
this.position = position; this.position = position;
} }
@SuppressWarnings({"UnstableApiUsage"})
public List<PlotComment> getComments(String inbox) { public List<PlotComment> getComments(String inbox) {
if (this.comments == null) { if (this.comments == null) {
return Collections.emptyList(); return Collections.emptyList();
} }
return this.comments.stream().filter(comment -> comment.inbox().equals(inbox)) return this.comments.stream().filter(comment -> comment.inbox.equals(inbox))
.collect(ImmutableList.toImmutableList()); .collect(ImmutableList.toImmutableList());
} }

View File

@ -58,7 +58,7 @@ public class CommentManager {
if (value != null) { if (value != null) {
int num = 0; int num = 0;
for (PlotComment comment : value) { for (PlotComment comment : value) {
if (comment.timestamp() > getTimestamp(player, inbox.toString())) { if (comment.timestamp > getTimestamp(player, inbox.toString())) {
num++; num++;
} }
} }

View File

@ -20,13 +20,25 @@ package com.plotsquared.core.plot.comment;
import com.plotsquared.core.plot.PlotId; import com.plotsquared.core.plot.PlotId;
public record PlotComment( public class PlotComment {
String world,
PlotId id, public final String comment;
String comment, public final String inbox;
String senderName, public final String senderName;
String inbox, public final PlotId id;
public final String world;
public final long timestamp;
public PlotComment(
String world, PlotId id, String comment, String senderName, String inbox,
long timestamp long timestamp
) { ) {
this.world = world;
this.id = id;
this.comment = comment;
this.senderName = senderName;
this.inbox = inbox;
this.timestamp = timestamp;
}
} }

View File

@ -154,7 +154,6 @@ public class ExpiryTask {
/** /**
* Returns {@code true} if this task respects unknown owners * Returns {@code true} if this task respects unknown owners
*
* @return {@code true} if unknown owners should be counted as never online * @return {@code true} if unknown owners should be counted as never online
* @since 6.4.0 * @since 6.4.0
*/ */

View File

@ -91,7 +91,6 @@ import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag;
import com.plotsquared.core.plot.flag.implementations.PveFlag; import com.plotsquared.core.plot.flag.implementations.PveFlag;
import com.plotsquared.core.plot.flag.implementations.PvpFlag; import com.plotsquared.core.plot.flag.implementations.PvpFlag;
import com.plotsquared.core.plot.flag.implementations.RedstoneFlag; import com.plotsquared.core.plot.flag.implementations.RedstoneFlag;
import com.plotsquared.core.plot.flag.implementations.SculkSensorInteractFlag;
import com.plotsquared.core.plot.flag.implementations.ServerPlotFlag; import com.plotsquared.core.plot.flag.implementations.ServerPlotFlag;
import com.plotsquared.core.plot.flag.implementations.SnowFormFlag; import com.plotsquared.core.plot.flag.implementations.SnowFormFlag;
import com.plotsquared.core.plot.flag.implementations.SnowMeltFlag; import com.plotsquared.core.plot.flag.implementations.SnowMeltFlag;
@ -173,7 +172,6 @@ public final class GlobalFlagContainer extends FlagContainer {
this.addFlag(MobBreakFlag.MOB_BREAK_FALSE); this.addFlag(MobBreakFlag.MOB_BREAK_FALSE);
this.addFlag(MobPlaceFlag.MOB_PLACE_FALSE); this.addFlag(MobPlaceFlag.MOB_PLACE_FALSE);
this.addFlag(MiscInteractFlag.MISC_INTERACT_FALSE); this.addFlag(MiscInteractFlag.MISC_INTERACT_FALSE);
this.addFlag(SculkSensorInteractFlag.SCULK_SENSOR_INTERACT_FALSE);
this.addFlag(MiscPlaceFlag.MISC_PLACE_FALSE); this.addFlag(MiscPlaceFlag.MISC_PLACE_FALSE);
this.addFlag(MycelGrowFlag.MYCEL_GROW_TRUE); this.addFlag(MycelGrowFlag.MYCEL_GROW_TRUE);
this.addFlag(NotifyEnterFlag.NOTIFY_ENTER_FALSE); this.addFlag(NotifyEnterFlag.NOTIFY_ENTER_FALSE);

View File

@ -88,7 +88,7 @@ public abstract class PlotFlag<T, F extends PlotFlag<T, F>> {
* Gets the flag name as a Kyori {@link Component} * Gets the flag name as a Kyori {@link Component}
* *
* @see #getFlagName(Class) * @see #getFlagName(Class)
* @since 7.0.0 * @since TODO
*/ */
public static <T, F extends PlotFlag<T, F>> Component getFlagNameComponent(Class<F> flagClass) { public static <T, F extends PlotFlag<T, F>> Component getFlagNameComponent(Class<F> flagClass) {
return Component.text(getFlagName(flagClass)); return Component.text(getFlagName(flagClass));

View File

@ -57,16 +57,25 @@ public class DenyTeleportFlag extends PlotFlag<DenyTeleportFlag.DeniedGroup, Den
} }
final boolean result; final boolean result;
switch (value) { switch (value) {
case TRUSTED -> result = !plot.getTrusted().contains(player.getUUID()); case TRUSTED:
case MEMBERS -> result = !plot.getMembers().contains(player.getUUID()); result = !plot.getTrusted().contains(player.getUUID());
case NONMEMBERS -> result = plot.isAdded(player.getUUID()); break;
case NONTRUSTED -> result = case MEMBERS:
result = !plot.getMembers().contains(player.getUUID());
break;
case NONMEMBERS:
result = plot.isAdded(player.getUUID());
break;
case NONTRUSTED:
result =
plot.getTrusted().contains(player.getUUID()) || plot.isOwner(player.getUUID()); plot.getTrusted().contains(player.getUUID()) || plot.isOwner(player.getUUID());
case NONOWNERS -> result = plot.isOwner(player.getUUID()); break;
default -> { case NONOWNERS:
result = plot.isOwner(player.getUUID());
break;
default:
return true; return true;
} }
}
return result || player.hasPermission("plots.admin.entry.denied"); return result || player.hasPermission("plots.admin.entry.denied");
} }

Some files were not shown because too many files have changed in this diff Show More