mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-11-03 02:33:43 +01:00 
			
		
		
		
	Compare commits
	
		
			150 Commits
		
	
	
		
			shadow-deb
			...
			feature/v7
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					2e216f3aa3 | ||
| 
						 | 
					e718dd32af | ||
| 
						 | 
					f45064c4c4 | ||
| 
						 | 
					af32399dd2 | ||
| 
						 | 
					f3c03348d9 | ||
| 
						 | 
					a53330e39b | ||
| 
						 | 
					e2ba93dab9 | ||
| 
						 | 
					9d43434e40 | ||
| 
						 | 
					4f421167d1 | ||
| 
						 | 
					94f4619c2c | ||
| 
						 | 
					9885d3e506 | ||
| 
						 | 
					a54276d3b2 | ||
| 
						 | 
					cbb284b0fd | ||
| 
						 | 
					ed22b22e9c | ||
| 
						 | 
					444ccda807 | ||
| 
						 | 
					db361cc420 | ||
| 
						 | 
					079dc02cfe | ||
| 
						 | 
					e98791c865 | ||
| 
						 | 
					7c3112f30f | ||
| 
						 | 
					c01f5f5c7d | ||
| 
						 | 
					95caa19505 | ||
| 
						 | 
					b8055201df | ||
| 
						 | 
					81daefae4a | ||
| 
						 | 
					02437a8c72 | ||
| 
						 | 
					958c66b28f | ||
| 
						 | 
					c656190e14 | ||
| 
						 | 
					e914cb210e | ||
| 
						 | 
					94c6af74d2 | ||
| 
						 | 
					ebb82bd66d | ||
| 
						 | 
					66f907eb5d | ||
| 
						 | 
					9ffede2c5c | ||
| 
						 | 
					97172df0dc | ||
| 
						 | 
					c9746b182c | ||
| 
						 | 
					10a2b80ffc | ||
| 
						 | 
					ca0f38255d | ||
| 
						 | 
					0484ac73af | ||
| 
						 | 
					1a712ad3c1 | ||
| 
						 | 
					2d1f483469 | ||
| 
						 | 
					91830e233b | ||
| 
						 | 
					561edb83bf | ||
| 
						 | 
					0e09cf223a | ||
| 
						 | 
					d78360d6eb | ||
| 
						 | 
					1464804c11 | ||
| 
						 | 
					8629eae5fc | ||
| 
						 | 
					7b8ba7c3ac | ||
| 
						 | 
					77c7466c17 | ||
| 
						 | 
					82fe76fd37 | ||
| 
						 | 
					3f81ea4ef8 | ||
| 
						 | 
					745b06a008 | ||
| 
						 | 
					77b2bd166a | ||
| 
						 | 
					8e02336c44 | ||
| 
						 | 
					3adfbde45a | ||
| 
						 | 
					e6db8e2750 | ||
| 
						 | 
					9cd0ee9b49 | ||
| 
						 | 
					d455d1fcd7 | ||
| 
						 | 
					ea19ff783f | ||
| 
						 | 
					447e4c7d58 | ||
| 
						 | 
					89031447f2 | ||
| 
						 | 
					4210a3a555 | ||
| 
						 | 
					42e146b8c7 | ||
| 
						 | 
					a5fdcda673 | ||
| 
						 | 
					52823f5024 | ||
| 
						 | 
					1326c257a0 | ||
| 
						 | 
					fc3137cd96 | ||
| 
						 | 
					a5c53a96d1 | ||
| 
						 | 
					c46cc73f52 | ||
| 
						 | 
					276e619caa | ||
| 
						 | 
					f11acacedd | ||
| 
						 | 
					f636a5ec63 | ||
| 
						 | 
					d1bac90745 | ||
| 
						 | 
					785362c576 | ||
| 
						 | 
					e98f628d34 | ||
| 
						 | 
					b2ab61559c | ||
| 
						 | 
					dd6eb8e74f | ||
| 
						 | 
					97cdd03ea4 | ||
| 
						 | 
					f5118e6802 | ||
| 
						 | 
					94ca5cf679 | ||
| 
						 | 
					5a55a1f602 | ||
| 
						 | 
					1e7ba7d173 | ||
| 
						 | 
					ed33635a15 | ||
| 
						 | 
					888682e5d0 | ||
| 
						 | 
					72bb5f00b0 | ||
| 
						 | 
					773fd6f59f | ||
| 
						 | 
					aa784e98f8 | ||
| 
						 | 
					5cce86d924 | ||
| 
						 | 
					84567bcb00 | ||
| 
						 | 
					d7c2ab1d16 | ||
| 
						 | 
					0d359ade0c | ||
| 
						 | 
					ffbec24290 | ||
| 
						 | 
					586474c8e6 | ||
| 
						 | 
					70b6636f50 | ||
| 
						 | 
					ab357deb48 | ||
| 
						 | 
					bd62d1a1c7 | ||
| 
						 | 
					6130c3dfa5 | ||
| 
						 | 
					26692d6633 | ||
| 
						 | 
					bb0f200429 | ||
| 
						 | 
					5787588500 | ||
| 
						 | 
					bed62edc02 | ||
| 
						 | 
					ee0f389c78 | ||
| 
						 | 
					b40383b5a4 | ||
| 
						 | 
					be8903128d | ||
| 
						 | 
					08800ec16d | ||
| 
						 | 
					83e274ff9f | ||
| 
						 | 
					0dd8b1053c | ||
| 
						 | 
					0558fcf5d5 | ||
| 
						 | 
					5af8be4293 | ||
| 
						 | 
					cbacdd67eb | ||
| 
						 | 
					c45bbe3ec5 | ||
| 
						 | 
					746028afbc | ||
| 
						 | 
					b79537ebbc | ||
| 
						 | 
					6efd581500 | ||
| 
						 | 
					07e598e48f | ||
| 
						 | 
					f6f00dfcda | ||
| 
						 | 
					63a6bdc1d6 | ||
| 
						 | 
					1448d8d4af | ||
| 
						 | 
					8d9a387587 | ||
| 
						 | 
					0707aa47c9 | ||
| 
						 | 
					8c57d616cf | ||
| 
						 | 
					66660507e0 | ||
| 
						 | 
					a12490c3eb | ||
| 
						 | 
					36e5f36660 | ||
| 
						 | 
					350eae7813 | ||
| 
						 | 
					12dc198a86 | ||
| 
						 | 
					fb2533d66a | ||
| 
						 | 
					37d6dcc7ea | ||
| 
						 | 
					530fcc0fea | ||
| 
						 | 
					7135bdd6aa | ||
| 
						 | 
					3198c3b081 | ||
| 
						 | 
					7669e79da1 | ||
| 
						 | 
					c0bfa297bb | ||
| 
						 | 
					75fd9b2631 | ||
| 
						 | 
					6b680fb2c0 | ||
| 
						 | 
					27ffe4fcdc | ||
| 
						 | 
					8afcaccb8a | ||
| 
						 | 
					c83b13e374 | ||
| 
						 | 
					23360057b9 | ||
| 
						 | 
					60f7113105 | ||
| 
						 | 
					26c0c1b7cd | ||
| 
						 | 
					764c94c9cc | ||
| 
						 | 
					3d87ee41b3 | ||
| 
						 | 
					fd8832ac98 | ||
| 
						 | 
					228acc196c | ||
| 
						 | 
					62197f3deb | ||
| 
						 | 
					daa9348993 | ||
| 
						 | 
					7e4499e092 | ||
| 
						 | 
					396a1575d2 | ||
| 
						 | 
					953d57d1b5 | ||
| 
						 | 
					b53d2d03a4 | ||
| 
						 | 
					c1431c0971 | ||
| 
						 | 
					62ee60a76c | 
							
								
								
									
										5
									
								
								.github/ISSUE_TEMPLATE/bug_report.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.github/ISSUE_TEMPLATE/bug_report.yml
									
									
									
									
										vendored
									
									
								
							@@ -8,7 +8,7 @@ body:
 | 
			
		||||
      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.
 | 
			
		||||
        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://forms.gle/btgdRn9yhGtzEiGW8) form!
 | 
			
		||||
        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!
 | 
			
		||||
 | 
			
		||||
  - type: dropdown
 | 
			
		||||
    attributes:
 | 
			
		||||
@@ -27,6 +27,9 @@ 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.
 | 
			
		||||
      multiple: false
 | 
			
		||||
      options:
 | 
			
		||||
        - '1.20.1'
 | 
			
		||||
        - '1.20'
 | 
			
		||||
        - '1.19.4'
 | 
			
		||||
        - '1.19.3'
 | 
			
		||||
        - '1.19.2'
 | 
			
		||||
        - '1.19.1'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										7
									
								
								renovate.json → .github/renovate.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										7
									
								
								renovate.json → .github/renovate.json
									
									
									
									
										vendored
									
									
								
							@@ -4,6 +4,9 @@
 | 
			
		||||
    "config:base",
 | 
			
		||||
    ":semanticCommitsDisabled"
 | 
			
		||||
  ],
 | 
			
		||||
  "labels": ["Renovate"],
 | 
			
		||||
  "rebaseWhen": "conflicted"
 | 
			
		||||
  "labels": [
 | 
			
		||||
    "dependencies"
 | 
			
		||||
  ],
 | 
			
		||||
  "rebaseWhen": "conflicted",
 | 
			
		||||
  "schedule": ["on the first day of the month"]
 | 
			
		||||
}
 | 
			
		||||
@@ -1,8 +1,7 @@
 | 
			
		||||
name: Announce release on discord
 | 
			
		||||
on:
 | 
			
		||||
  release:
 | 
			
		||||
    types: [published]
 | 
			
		||||
 | 
			
		||||
    types: [ published ]
 | 
			
		||||
jobs:
 | 
			
		||||
  send_announcement:
 | 
			
		||||
    runs-on: ubuntu-latest
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								.github/workflows/build-pr.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build-pr.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,7 +1,5 @@
 | 
			
		||||
name: Build PR
 | 
			
		||||
 | 
			
		||||
on: [ pull_request ]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  build_pr:
 | 
			
		||||
    if: github.repository_owner == 'IntellectualSites'
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										16
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										16
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,10 +1,8 @@
 | 
			
		||||
name: build
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - v6
 | 
			
		||||
 | 
			
		||||
      - main
 | 
			
		||||
jobs:
 | 
			
		||||
  build:
 | 
			
		||||
    if: github.repository_owner == 'IntellectualSites'
 | 
			
		||||
@@ -30,7 +28,7 @@ jobs:
 | 
			
		||||
            echo "STATUS=release" >> $GITHUB_ENV
 | 
			
		||||
          fi
 | 
			
		||||
      - name: Publish Release
 | 
			
		||||
        if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v6'}}
 | 
			
		||||
        if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main'}}
 | 
			
		||||
        run: ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository
 | 
			
		||||
        env:
 | 
			
		||||
          ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }}
 | 
			
		||||
@@ -38,13 +36,13 @@ jobs:
 | 
			
		||||
          ORG_GRADLE_PROJECT_signingKey: ${{ secrets.SIGNING_KEY }}
 | 
			
		||||
          ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.SIGNING_PASSWORD }}
 | 
			
		||||
      - name: Publish Snapshot
 | 
			
		||||
        if: ${{ runner.os == 'Linux' && env.STATUS != 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v6' }}
 | 
			
		||||
        if: ${{ runner.os == 'Linux' && env.STATUS != 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main' }}
 | 
			
		||||
        run: ./gradlew publishToSonatype
 | 
			
		||||
        env:
 | 
			
		||||
          ORG_GRADLE_PROJECT_sonatypeUsername: ${{ secrets.SONATYPE_USERNAME }}
 | 
			
		||||
          ORG_GRADLE_PROJECT_sonatypePassword: ${{ secrets.SONATYPE_PASSWORD }}
 | 
			
		||||
      - name: Publish core javadoc
 | 
			
		||||
        if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v6'}}
 | 
			
		||||
       # if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main'}}
 | 
			
		||||
        uses: cpina/github-action-push-to-another-repository@main
 | 
			
		||||
        env:
 | 
			
		||||
          SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
 | 
			
		||||
@@ -54,9 +52,9 @@ jobs:
 | 
			
		||||
          destination-repository-name: 'plotsquared-javadocs'
 | 
			
		||||
          user-email: ${{ secrets.USER_EMAIL }}
 | 
			
		||||
          target-branch: main
 | 
			
		||||
          target-directory: core
 | 
			
		||||
          target-directory: v7/core
 | 
			
		||||
      - name: Publish bukkit javadoc
 | 
			
		||||
        if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/v6'}}
 | 
			
		||||
      #  if: ${{ runner.os == 'Linux' && env.STATUS == 'release' && github.event_name == 'push' && github.ref == 'refs/heads/main'}}
 | 
			
		||||
        uses: cpina/github-action-push-to-another-repository@main
 | 
			
		||||
        env:
 | 
			
		||||
          SSH_DEPLOY_KEY: ${{ secrets.SSH_DEPLOY_KEY }}
 | 
			
		||||
@@ -66,4 +64,4 @@ jobs:
 | 
			
		||||
          destination-repository-name: 'plotsquared-javadocs'
 | 
			
		||||
          user-email: ${{ secrets.USER_EMAIL }}
 | 
			
		||||
          target-branch: main
 | 
			
		||||
          target-directory: bukkit
 | 
			
		||||
          target-directory: v7/bukkit
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										15
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,9 +1,10 @@
 | 
			
		||||
name: "CodeQL"
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches: [ main ]
 | 
			
		||||
  pull_request:
 | 
			
		||||
    # The branches below must be a subset of the branches above
 | 
			
		||||
    branches: [ v6 ]
 | 
			
		||||
    branches: [ main ]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  analyze:
 | 
			
		||||
@@ -13,23 +14,23 @@ jobs:
 | 
			
		||||
      actions: read
 | 
			
		||||
      contents: read
 | 
			
		||||
      security-events: write
 | 
			
		||||
 | 
			
		||||
    strategy:
 | 
			
		||||
      fail-fast: false
 | 
			
		||||
      matrix:
 | 
			
		||||
        language: [ 'java' ]
 | 
			
		||||
 | 
			
		||||
    steps:
 | 
			
		||||
      - name: Checkout repository
 | 
			
		||||
        uses: actions/checkout@v3
 | 
			
		||||
 | 
			
		||||
      - name: Setup Java
 | 
			
		||||
        uses: actions/setup-java@v3
 | 
			
		||||
        with:
 | 
			
		||||
          distribution: temurin
 | 
			
		||||
          java-version: 17
 | 
			
		||||
      - name: Initialize CodeQL
 | 
			
		||||
        uses: github/codeql-action/init@v2
 | 
			
		||||
        with:
 | 
			
		||||
          languages: ${{ matrix.language }}
 | 
			
		||||
 | 
			
		||||
      - name: Autobuild
 | 
			
		||||
        uses: github/codeql-action/autobuild@v2
 | 
			
		||||
 | 
			
		||||
      - name: Perform CodeQL Analysis
 | 
			
		||||
        uses: github/codeql-action/analyze@v2
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								.github/workflows/release-drafter.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.github/workflows/release-drafter.yml
									
									
									
									
										vendored
									
									
								
							@@ -1,14 +1,12 @@
 | 
			
		||||
name: draft release
 | 
			
		||||
 | 
			
		||||
on:
 | 
			
		||||
  push:
 | 
			
		||||
    branches:
 | 
			
		||||
      - v6
 | 
			
		||||
      - main
 | 
			
		||||
  pull_request:
 | 
			
		||||
    types: [ opened, reopened, synchronize ]
 | 
			
		||||
  pull_request_target:
 | 
			
		||||
    types: [ opened, reopened, synchronize ]
 | 
			
		||||
 | 
			
		||||
jobs:
 | 
			
		||||
  update_release_draft:
 | 
			
		||||
    if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										4
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@@ -137,3 +137,7 @@ docs/
 | 
			
		||||
build/
 | 
			
		||||
 | 
			
		||||
.DS_Store
 | 
			
		||||
# Ignore run folders
 | 
			
		||||
run-[0-0].[0-9]/
 | 
			
		||||
run-[0-0].[0-9].[0-9]/
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										154
									
								
								.idea/icon.svg
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										154
									
								
								.idea/icon.svg
									
									
									
										generated
									
									
									
								
							@@ -1,48 +1,144 @@
 | 
			
		||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 | 
			
		||||
<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">
 | 
			
		||||
		<metadata id="metadata8">
 | 
			
		||||
<svg
 | 
			
		||||
   version="1.1"
 | 
			
		||||
   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>
 | 
			
		||||
				<cc:Work rdf:about="">
 | 
			
		||||
				<cc:Work
 | 
			
		||||
   rdf:about="">
 | 
			
		||||
					<dc:format>image/svg+xml</dc:format>
 | 
			
		||||
                    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
                    <dc:type
 | 
			
		||||
   rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
 | 
			
		||||
				</cc:Work>
 | 
			
		||||
			</rdf:RDF>
 | 
			
		||||
		</metadata>
 | 
			
		||||
    <defs id="defs6">
 | 
			
		||||
			<clipPath clipPathUnits="userSpaceOnUse" id="clipPath18">
 | 
			
		||||
				<path d="M 0,2500 H 3000 V 0 H 0 Z" id="path16" />
 | 
			
		||||
    <defs
 | 
			
		||||
   id="defs6">
 | 
			
		||||
			<clipPath
 | 
			
		||||
   clipPathUnits="userSpaceOnUse"
 | 
			
		||||
   id="clipPath18">
 | 
			
		||||
				<path
 | 
			
		||||
   d="M 0,2500 H 3000 V 0 H 0 Z"
 | 
			
		||||
   id="path16" />
 | 
			
		||||
			</clipPath>
 | 
			
		||||
		</defs>
 | 
			
		||||
    <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" />
 | 
			
		||||
    <g id="g10" inkscape:groupmode="layer" inkscape:label="PlotSquared" transform="matrix(1.3333333,0,0,-1.3333333,0,3333.3333)">
 | 
			
		||||
			<g id="g12">
 | 
			
		||||
				<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" />
 | 
			
		||||
    <sodipodi:namedview
 | 
			
		||||
   pagecolor="#ffffff"
 | 
			
		||||
   bordercolor="#666666"
 | 
			
		||||
   borderopacity="1"
 | 
			
		||||
   objecttolerance="10"
 | 
			
		||||
   gridtolerance="10"
 | 
			
		||||
   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 id="g24" 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
 | 
			
		||||
   id="g24"
 | 
			
		||||
   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 id="g28" 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
 | 
			
		||||
   id="g28"
 | 
			
		||||
   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 id="g32" 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
 | 
			
		||||
   id="g32"
 | 
			
		||||
   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 id="g36" 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
 | 
			
		||||
   id="g36"
 | 
			
		||||
   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 id="g40" 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
 | 
			
		||||
   id="g40"
 | 
			
		||||
   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 id="g44" 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
 | 
			
		||||
   id="g44"
 | 
			
		||||
   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 id="g48" 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
 | 
			
		||||
   id="g48"
 | 
			
		||||
   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 id="g52" 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
 | 
			
		||||
   id="g52"
 | 
			
		||||
   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>
 | 
			
		||||
 
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 12 KiB  | 
@@ -18,7 +18,7 @@ repositories {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    api(projects.plotSquaredCore)
 | 
			
		||||
    api(projects.plotsquaredCore)
 | 
			
		||||
 | 
			
		||||
    // Metrics
 | 
			
		||||
    implementation("org.bstats:bstats-bukkit")
 | 
			
		||||
@@ -48,7 +48,6 @@ dependencies {
 | 
			
		||||
 | 
			
		||||
    // Our libraries
 | 
			
		||||
    implementation(libs.arkitektonika)
 | 
			
		||||
    implementation(libs.http4j)
 | 
			
		||||
    implementation("com.intellectualsites.paster:Paster")
 | 
			
		||||
    implementation("com.intellectualsites.informative-annotations:informative-annotations")
 | 
			
		||||
 | 
			
		||||
@@ -63,6 +62,7 @@ tasks.processResources {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
tasks.named<ShadowJar>("shadowJar") {
 | 
			
		||||
    dependsOn(":plotsquared-core:shadowJar")
 | 
			
		||||
    dependencies {
 | 
			
		||||
        exclude(dependency("org.checkerframework:"))
 | 
			
		||||
    }
 | 
			
		||||
@@ -88,7 +88,7 @@ tasks.named<ShadowJar>("shadowJar") {
 | 
			
		||||
    relocate("javax.inject", "com.plotsquared.core.annotation.inject")
 | 
			
		||||
    relocate("net.jcip", "com.plotsquared.core.annotations.jcip")
 | 
			
		||||
    relocate("edu.umd.cs.findbugs", "com.plotsquared.core.annotations.findbugs")
 | 
			
		||||
    relocate("com.intellectualsites.informative-annotations", "com.plotsquared.core.annotation.informative")
 | 
			
		||||
    relocate("com.intellectualsites.annotations", "com.plotsquared.core.annotations.informative")
 | 
			
		||||
 | 
			
		||||
    // Get rid of all the libs which are 100% unused.
 | 
			
		||||
    minimize()
 | 
			
		||||
@@ -100,10 +100,10 @@ tasks {
 | 
			
		||||
    withType<Javadoc> {
 | 
			
		||||
        val isRelease = if (rootProject.version.toString().endsWith("-SNAPSHOT")) "TODO" else rootProject.version.toString()
 | 
			
		||||
        val opt = options as StandardJavadocDocletOptions
 | 
			
		||||
        opt.links("https://jd.papermc.io/paper/1.18/")
 | 
			
		||||
        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://intellectualsites.github.io/plotsquared-javadocs/core/")
 | 
			
		||||
        opt.links("https://jd.adventure.kyori.net/api/4.9.3/")
 | 
			
		||||
        opt.links("https://jd.advntr.dev/api/4.14.0/")
 | 
			
		||||
        opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/")
 | 
			
		||||
        opt.links("https://checkerframework.org/api/")
 | 
			
		||||
        opt.isLinkSource = true
 | 
			
		||||
 
 | 
			
		||||
@@ -49,7 +49,7 @@ import com.plotsquared.bukkit.player.BukkitPlayerManager;
 | 
			
		||||
import com.plotsquared.bukkit.util.BukkitUtil;
 | 
			
		||||
import com.plotsquared.bukkit.util.BukkitWorld;
 | 
			
		||||
import com.plotsquared.bukkit.util.SetGenCB;
 | 
			
		||||
import com.plotsquared.bukkit.util.UpdateUtility;
 | 
			
		||||
import com.plotsquared.bukkit.util.TranslationUpdateManager;
 | 
			
		||||
import com.plotsquared.bukkit.util.task.BukkitTaskManager;
 | 
			
		||||
import com.plotsquared.bukkit.util.task.PaperTimeConverter;
 | 
			
		||||
import com.plotsquared.bukkit.util.task.SpigotTimeConverter;
 | 
			
		||||
@@ -71,6 +71,8 @@ import com.plotsquared.core.configuration.Storage;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.ChatFormatter;
 | 
			
		||||
import com.plotsquared.core.configuration.file.YamlConfiguration;
 | 
			
		||||
import com.plotsquared.core.database.DBFunc;
 | 
			
		||||
import com.plotsquared.core.events.RemoveRoadEntityEvent;
 | 
			
		||||
import com.plotsquared.core.events.Result;
 | 
			
		||||
import com.plotsquared.core.generator.GeneratorWrapper;
 | 
			
		||||
import com.plotsquared.core.generator.IndependentPlotGenerator;
 | 
			
		||||
import com.plotsquared.core.generator.SingleWorldGenerator;
 | 
			
		||||
@@ -109,6 +111,7 @@ import com.plotsquared.core.uuid.CacheUUIDService;
 | 
			
		||||
import com.plotsquared.core.uuid.UUIDPipeline;
 | 
			
		||||
import com.plotsquared.core.uuid.offline.OfflineModeUUIDService;
 | 
			
		||||
import com.sk89q.worldedit.WorldEdit;
 | 
			
		||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
 | 
			
		||||
import io.papermc.lib.PaperLib;
 | 
			
		||||
import net.kyori.adventure.audience.Audience;
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
@@ -137,6 +140,7 @@ import org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
import org.incendo.serverlib.ServerLib;
 | 
			
		||||
 | 
			
		||||
import java.io.File;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.lang.reflect.Method;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
@@ -290,11 +294,19 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
 | 
			
		||||
                );
 | 
			
		||||
        this.injector.injectMembers(this);
 | 
			
		||||
 | 
			
		||||
        try {
 | 
			
		||||
            this.injector.getInstance(TranslationUpdateManager.class).upgradeTranslationFile();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            throw new RuntimeException(e);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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) {
 | 
			
		||||
            injector.getInstance(UpdateUtility.class).updateChecker();
 | 
			
		||||
        }
 | 
			
		||||
         */
 | 
			
		||||
 | 
			
		||||
        if (PremiumVerification.isPremium()) {
 | 
			
		||||
            LOGGER.info("PlotSquared version licensed to Spigot user {}", getUserID());
 | 
			
		||||
@@ -355,7 +367,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
 | 
			
		||||
            getServer().getPluginManager().registerEvents(injector().getInstance(ServerListener.class), this);
 | 
			
		||||
            getServer().getPluginManager().registerEvents(injector().getInstance(EntitySpawnListener.class), this);
 | 
			
		||||
            if (PaperLib.isPaper() && Settings.Paper_Components.PAPER_LISTENERS) {
 | 
			
		||||
                    getServer().getPluginManager().registerEvents(injector().getInstance(PaperListener.class), this);
 | 
			
		||||
                getServer().getPluginManager().registerEvents(injector().getInstance(PaperListener.class), this);
 | 
			
		||||
            } else {
 | 
			
		||||
                getServer().getPluginManager().registerEvents(injector().getInstance(SpigotListener.class), this);
 | 
			
		||||
            }
 | 
			
		||||
@@ -810,8 +822,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
 | 
			
		||||
                                        if (entity.hasMetadata("ps-tmp-teleport")) {
 | 
			
		||||
                                            continue;
 | 
			
		||||
                                        }
 | 
			
		||||
                                        iterator.remove();
 | 
			
		||||
                                        entity.remove();
 | 
			
		||||
                                        this.removeRoadEntity(entity, iterator);
 | 
			
		||||
                                    }
 | 
			
		||||
                                    continue;
 | 
			
		||||
                                }
 | 
			
		||||
@@ -824,8 +835,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
 | 
			
		||||
                                    if (entity.hasMetadata("ps-tmp-teleport")) {
 | 
			
		||||
                                        continue;
 | 
			
		||||
                                    }
 | 
			
		||||
                                    iterator.remove();
 | 
			
		||||
                                    entity.remove();
 | 
			
		||||
                                    this.removeRoadEntity(entity, iterator);
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            continue;
 | 
			
		||||
@@ -835,7 +845,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
 | 
			
		||||
                        case "DROPPED_ITEM":
 | 
			
		||||
                            if (Settings.Enabled_Components.KILL_ROAD_ITEMS
 | 
			
		||||
                                    && plotArea.getOwnedPlotAbs(BukkitUtil.adapt(entity.getLocation())) == null) {
 | 
			
		||||
                                entity.remove();
 | 
			
		||||
                                this.removeRoadEntity(entity, iterator);
 | 
			
		||||
                            }
 | 
			
		||||
                            // dropped item
 | 
			
		||||
                            continue;
 | 
			
		||||
@@ -866,8 +876,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
 | 
			
		||||
                                                if (entity.hasMetadata("ps-tmp-teleport")) {
 | 
			
		||||
                                                    continue;
 | 
			
		||||
                                                }
 | 
			
		||||
                                                iterator.remove();
 | 
			
		||||
                                                entity.remove();
 | 
			
		||||
                                                this.removeRoadEntity(entity, iterator);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -972,8 +981,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
 | 
			
		||||
                                                if (entity.hasMetadata("ps-tmp-teleport")) {
 | 
			
		||||
                                                    continue;
 | 
			
		||||
                                                }
 | 
			
		||||
                                                iterator.remove();
 | 
			
		||||
                                                entity.remove();
 | 
			
		||||
                                                this.removeRoadEntity(entity, iterator);
 | 
			
		||||
                                            }
 | 
			
		||||
                                        }
 | 
			
		||||
                                    } else {
 | 
			
		||||
@@ -984,8 +992,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
 | 
			
		||||
                                            if (entity.hasMetadata("ps-tmp-teleport")) {
 | 
			
		||||
                                                continue;
 | 
			
		||||
                                            }
 | 
			
		||||
                                            iterator.remove();
 | 
			
		||||
                                            entity.remove();
 | 
			
		||||
                                            this.removeRoadEntity(entity, iterator);
 | 
			
		||||
                                        }
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
@@ -999,6 +1006,17 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
 | 
			
		||||
        }), TaskTime.seconds(1L));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void removeRoadEntity(Entity entity, Iterator<Entity> entityIterator) {
 | 
			
		||||
        RemoveRoadEntityEvent event = eventDispatcher.callRemoveRoadEntity(BukkitAdapter.adapt(entity));
 | 
			
		||||
 | 
			
		||||
        if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        entityIterator.remove();
 | 
			
		||||
        entity.remove();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public @Nullable
 | 
			
		||||
    final ChunkGenerator getDefaultWorldGenerator(
 | 
			
		||||
@@ -1168,9 +1186,17 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
 | 
			
		||||
    public @NonNull String worldEditImplementations() {
 | 
			
		||||
        StringBuilder msg = new StringBuilder();
 | 
			
		||||
        if (Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null) {
 | 
			
		||||
            msg.append("FastAsyncWorldEdit: ").append(Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit").getDescription().getVersion());
 | 
			
		||||
            msg.append("FastAsyncWorldEdit: ").append(Bukkit
 | 
			
		||||
                    .getPluginManager()
 | 
			
		||||
                    .getPlugin("FastAsyncWorldEdit")
 | 
			
		||||
                    .getDescription()
 | 
			
		||||
                    .getVersion());
 | 
			
		||||
        } else if (Bukkit.getPluginManager().getPlugin("AsyncWorldEdit") != null) {
 | 
			
		||||
            msg.append("AsyncWorldEdit: ").append(Bukkit.getPluginManager().getPlugin("AsyncWorldEdit").getDescription().getVersion()).append("\n");
 | 
			
		||||
            msg.append("AsyncWorldEdit: ").append(Bukkit
 | 
			
		||||
                    .getPluginManager()
 | 
			
		||||
                    .getPlugin("AsyncWorldEdit")
 | 
			
		||||
                    .getDescription()
 | 
			
		||||
                    .getVersion()).append("\n");
 | 
			
		||||
            msg.append("WorldEdit: ").append(Bukkit.getPluginManager().getPlugin("WorldEdit").getDescription().getVersion());
 | 
			
		||||
        } else {
 | 
			
		||||
            msg.append("WorldEdit: ").append(Bukkit.getPluginManager().getPlugin("WorldEdit").getDescription().getVersion());
 | 
			
		||||
 
 | 
			
		||||
@@ -101,50 +101,26 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
 | 
			
		||||
            this.noGravity = true;
 | 
			
		||||
        }
 | 
			
		||||
        switch (entity.getType().toString()) {
 | 
			
		||||
            case "BOAT":
 | 
			
		||||
            case "BOAT" -> {
 | 
			
		||||
                Boat boat = (Boat) entity;
 | 
			
		||||
                this.dataByte = getOrdinal(TreeSpecies.values(), boat.getWoodType());
 | 
			
		||||
                return;
 | 
			
		||||
            case "ARROW":
 | 
			
		||||
            case "EGG":
 | 
			
		||||
            case "ENDER_CRYSTAL":
 | 
			
		||||
            case "ENDER_PEARL":
 | 
			
		||||
            case "ENDER_SIGNAL":
 | 
			
		||||
            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":
 | 
			
		||||
            }
 | 
			
		||||
            case "ARROW", "EGG", "ENDER_CRYSTAL", "ENDER_PEARL", "ENDER_SIGNAL", "EXPERIENCE_ORB", "FALLING_BLOCK", "FIREBALL",
 | 
			
		||||
                    "FIREWORK", "FISHING_HOOK", "LEASH_HITCH", "LIGHTNING", "MINECART", "MINECART_COMMAND", "MINECART_MOB_SPAWNER",
 | 
			
		||||
                    "MINECART_TNT", "PLAYER", "PRIMED_TNT", "SLIME", "SMALL_FIREBALL", "SNOWBALL", "MINECART_FURNACE", "SPLASH_POTION",
 | 
			
		||||
                    "THROWN_EXP_BOTTLE", "WITHER_SKULL", "UNKNOWN", "SPECTRAL_ARROW", "SHULKER_BULLET", "DRAGON_FIREBALL", "AREA_EFFECT_CLOUD",
 | 
			
		||||
                    "TRIDENT", "LLAMA_SPIT" -> {
 | 
			
		||||
                // Do this stuff later
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            // MISC //
 | 
			
		||||
            case "DROPPED_ITEM":
 | 
			
		||||
            case "DROPPED_ITEM" -> {
 | 
			
		||||
                Item item = (Item) entity;
 | 
			
		||||
                this.stack = item.getItemStack();
 | 
			
		||||
                return;
 | 
			
		||||
            case "ITEM_FRAME":
 | 
			
		||||
            }
 | 
			
		||||
            case "ITEM_FRAME" -> {
 | 
			
		||||
                this.x = Math.floor(this.getX());
 | 
			
		||||
                this.y = Math.floor(this.getY());
 | 
			
		||||
                this.z = Math.floor(this.getZ());
 | 
			
		||||
@@ -152,7 +128,8 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
 | 
			
		||||
                this.dataByte = getOrdinal(Rotation.values(), itemFrame.getRotation());
 | 
			
		||||
                this.stack = itemFrame.getItem().clone();
 | 
			
		||||
                return;
 | 
			
		||||
            case "PAINTING":
 | 
			
		||||
            }
 | 
			
		||||
            case "PAINTING" -> {
 | 
			
		||||
                this.x = Math.floor(this.getX());
 | 
			
		||||
                this.y = Math.floor(this.getY());
 | 
			
		||||
                this.z = Math.floor(this.getZ());
 | 
			
		||||
@@ -165,20 +142,17 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
 | 
			
		||||
                }
 | 
			
		||||
                this.dataString = art.name();
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            // END MISC //
 | 
			
		||||
            // INVENTORY HOLDER //
 | 
			
		||||
            case "MINECART_CHEST":
 | 
			
		||||
            case "MINECART_HOPPER":
 | 
			
		||||
            case "MINECART_CHEST", "MINECART_HOPPER" -> {
 | 
			
		||||
                storeInventory((InventoryHolder) entity);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            // START LIVING ENTITY //
 | 
			
		||||
            // START AGEABLE //
 | 
			
		||||
            // START TAMEABLE //
 | 
			
		||||
            case "HORSE":
 | 
			
		||||
            case "DONKEY":
 | 
			
		||||
            case "LLAMA":
 | 
			
		||||
            case "MULE":
 | 
			
		||||
            case "SKELETON_HORSE":
 | 
			
		||||
            case "HORSE", "DONKEY", "LLAMA", "MULE", "SKELETON_HORSE" -> {
 | 
			
		||||
                AbstractHorse horse = (AbstractHorse) entity;
 | 
			
		||||
                this.horse = new HorseStats();
 | 
			
		||||
                this.horse.jump = horse.getJumpStrength();
 | 
			
		||||
@@ -194,16 +168,17 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
 | 
			
		||||
                storeLiving(horse);
 | 
			
		||||
                storeInventory(horse);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            // END INVENTORY HOLDER //
 | 
			
		||||
            case "WOLF":
 | 
			
		||||
            case "OCELOT":
 | 
			
		||||
            case "WOLF", "OCELOT" -> {
 | 
			
		||||
                storeTameable((Tameable) entity);
 | 
			
		||||
                storeAgeable((Ageable) entity);
 | 
			
		||||
                storeLiving((LivingEntity) entity);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            // END TAMEABLE //
 | 
			
		||||
            //todo fix sheep
 | 
			
		||||
            case "SHEEP":
 | 
			
		||||
            case "SHEEP" -> {
 | 
			
		||||
                Sheep sheep = (Sheep) entity;
 | 
			
		||||
                if (sheep.isSheared()) {
 | 
			
		||||
                    this.dataByte = (byte) 1;
 | 
			
		||||
@@ -214,23 +189,20 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
 | 
			
		||||
                storeAgeable(sheep);
 | 
			
		||||
                storeLiving(sheep);
 | 
			
		||||
                return;
 | 
			
		||||
            case "VILLAGER":
 | 
			
		||||
            case "CHICKEN":
 | 
			
		||||
            case "COW":
 | 
			
		||||
            case "MUSHROOM_COW":
 | 
			
		||||
            case "PIG":
 | 
			
		||||
            case "TURTLE":
 | 
			
		||||
            case "POLAR_BEAR":
 | 
			
		||||
            }
 | 
			
		||||
            case "VILLAGER", "CHICKEN", "COW", "MUSHROOM_COW", "PIG", "TURTLE", "POLAR_BEAR" -> {
 | 
			
		||||
                storeAgeable((Ageable) entity);
 | 
			
		||||
                storeLiving((LivingEntity) entity);
 | 
			
		||||
                return;
 | 
			
		||||
            case "RABBIT":
 | 
			
		||||
            }
 | 
			
		||||
            case "RABBIT" -> {
 | 
			
		||||
                this.dataByte = getOrdinal(Rabbit.Type.values(), ((Rabbit) entity).getRabbitType());
 | 
			
		||||
                storeAgeable((Ageable) entity);
 | 
			
		||||
                storeLiving((LivingEntity) entity);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            // END AGEABLE //
 | 
			
		||||
            case "ARMOR_STAND":
 | 
			
		||||
            case "ARMOR_STAND" -> {
 | 
			
		||||
                ArmorStand stand = (ArmorStand) entity;
 | 
			
		||||
                this.inventory =
 | 
			
		||||
                        new ItemStack[]{stand.getItemInHand().clone(), stand.getHelmet().clone(),
 | 
			
		||||
@@ -238,37 +210,30 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
 | 
			
		||||
                                stand.getBoots().clone()};
 | 
			
		||||
                storeLiving(stand);
 | 
			
		||||
                this.stand = new ArmorStandStats();
 | 
			
		||||
 | 
			
		||||
                EulerAngle head = stand.getHeadPose();
 | 
			
		||||
                this.stand.head[0] = (float) head.getX();
 | 
			
		||||
                this.stand.head[1] = (float) head.getY();
 | 
			
		||||
                this.stand.head[2] = (float) head.getZ();
 | 
			
		||||
 | 
			
		||||
                EulerAngle body = stand.getBodyPose();
 | 
			
		||||
                this.stand.body[0] = (float) body.getX();
 | 
			
		||||
                this.stand.body[1] = (float) body.getY();
 | 
			
		||||
                this.stand.body[2] = (float) body.getZ();
 | 
			
		||||
 | 
			
		||||
                EulerAngle leftLeg = stand.getLeftLegPose();
 | 
			
		||||
                this.stand.leftLeg[0] = (float) leftLeg.getX();
 | 
			
		||||
                this.stand.leftLeg[1] = (float) leftLeg.getY();
 | 
			
		||||
                this.stand.leftLeg[2] = (float) leftLeg.getZ();
 | 
			
		||||
 | 
			
		||||
                EulerAngle rightLeg = stand.getRightLegPose();
 | 
			
		||||
                this.stand.rightLeg[0] = (float) rightLeg.getX();
 | 
			
		||||
                this.stand.rightLeg[1] = (float) rightLeg.getY();
 | 
			
		||||
                this.stand.rightLeg[2] = (float) rightLeg.getZ();
 | 
			
		||||
 | 
			
		||||
                EulerAngle leftArm = stand.getLeftArmPose();
 | 
			
		||||
                this.stand.leftArm[0] = (float) leftArm.getX();
 | 
			
		||||
                this.stand.leftArm[1] = (float) leftArm.getY();
 | 
			
		||||
                this.stand.leftArm[2] = (float) leftArm.getZ();
 | 
			
		||||
 | 
			
		||||
                EulerAngle rightArm = stand.getRightArmPose();
 | 
			
		||||
                this.stand.rightArm[0] = (float) rightArm.getX();
 | 
			
		||||
                this.stand.rightArm[1] = (float) rightArm.getY();
 | 
			
		||||
                this.stand.rightArm[2] = (float) rightArm.getZ();
 | 
			
		||||
 | 
			
		||||
                if (stand.hasArms()) {
 | 
			
		||||
                    this.stand.arms = true;
 | 
			
		||||
                }
 | 
			
		||||
@@ -282,53 +247,38 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
 | 
			
		||||
                    this.stand.small = true;
 | 
			
		||||
                }
 | 
			
		||||
                return;
 | 
			
		||||
            case "ENDERMITE":
 | 
			
		||||
            }
 | 
			
		||||
            case "ENDERMITE" -> {
 | 
			
		||||
                return;
 | 
			
		||||
            case "BAT":
 | 
			
		||||
            }
 | 
			
		||||
            case "BAT" -> {
 | 
			
		||||
                if (((Bat) entity).isAwake()) {
 | 
			
		||||
                    this.dataByte = (byte) 1;
 | 
			
		||||
                } else {
 | 
			
		||||
                    this.dataByte = (byte) 0;
 | 
			
		||||
                }
 | 
			
		||||
                return;
 | 
			
		||||
            case "ENDER_DRAGON":
 | 
			
		||||
            }
 | 
			
		||||
            case "ENDER_DRAGON" -> {
 | 
			
		||||
                EnderDragon entity1 = (EnderDragon) entity;
 | 
			
		||||
                this.dataByte = (byte) entity1.getPhase().ordinal();
 | 
			
		||||
                return;
 | 
			
		||||
            case "SKELETON":
 | 
			
		||||
            case "WITHER_SKELETON":
 | 
			
		||||
            case "GUARDIAN":
 | 
			
		||||
            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":
 | 
			
		||||
            }
 | 
			
		||||
            case "SKELETON", "WITHER_SKELETON", "GUARDIAN", "ELDER_GUARDIAN", "GHAST", "MAGMA_CUBE", "SQUID", "PIG_ZOMBIE", "HOGLIN",
 | 
			
		||||
                    "ZOMBIFIED_PIGLIN", "PIGLIN", "PIGLIN_BRUTE", "ZOMBIE", "WITHER", "WITCH", "SPIDER", "CAVE_SPIDER", "SILVERFISH",
 | 
			
		||||
                    "GIANT", "ENDERMAN", "CREEPER", "BLAZE", "SHULKER", "SNOWMAN" -> {
 | 
			
		||||
                storeLiving((LivingEntity) entity);
 | 
			
		||||
                return;
 | 
			
		||||
            case "IRON_GOLEM":
 | 
			
		||||
            }
 | 
			
		||||
            case "IRON_GOLEM" -> {
 | 
			
		||||
                if (((IronGolem) entity).isPlayerCreated()) {
 | 
			
		||||
                    this.dataByte = (byte) 1;
 | 
			
		||||
                } else {
 | 
			
		||||
                    this.dataByte = (byte) 0;
 | 
			
		||||
                }
 | 
			
		||||
                storeLiving((LivingEntity) entity);
 | 
			
		||||
                // END LIVING //
 | 
			
		||||
            }
 | 
			
		||||
            // END LIVING //
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -465,20 +415,15 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
 | 
			
		||||
        }
 | 
			
		||||
        Entity entity;
 | 
			
		||||
        switch (this.getType().toString()) {
 | 
			
		||||
            case "DROPPED_ITEM":
 | 
			
		||||
            case "DROPPED_ITEM" -> {
 | 
			
		||||
                return world.dropItem(location, this.stack);
 | 
			
		||||
            case "PLAYER":
 | 
			
		||||
            case "LEASH_HITCH":
 | 
			
		||||
            }
 | 
			
		||||
            case "PLAYER", "LEASH_HITCH" -> {
 | 
			
		||||
                return null;
 | 
			
		||||
            case "ITEM_FRAME":
 | 
			
		||||
                entity = world.spawn(location, ItemFrame.class);
 | 
			
		||||
                break;
 | 
			
		||||
            case "PAINTING":
 | 
			
		||||
                entity = world.spawn(location, Painting.class);
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                entity = world.spawnEntity(location, this.getType());
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case "ITEM_FRAME" -> entity = world.spawn(location, ItemFrame.class);
 | 
			
		||||
            case "PAINTING" -> entity = world.spawn(location, Painting.class);
 | 
			
		||||
            default -> entity = world.spawnEntity(location, this.getType());
 | 
			
		||||
        }
 | 
			
		||||
        if (this.depth == 0) {
 | 
			
		||||
            return entity;
 | 
			
		||||
@@ -506,72 +451,46 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
 | 
			
		||||
            entity.setGravity(false);
 | 
			
		||||
        }
 | 
			
		||||
        switch (entity.getType().toString()) {
 | 
			
		||||
            case "BOAT":
 | 
			
		||||
            case "BOAT" -> {
 | 
			
		||||
                Boat boat = (Boat) entity;
 | 
			
		||||
                boat.setWoodType(TreeSpecies.values()[dataByte]);
 | 
			
		||||
                return entity;
 | 
			
		||||
            case "SLIME":
 | 
			
		||||
            }
 | 
			
		||||
            case "SLIME" -> {
 | 
			
		||||
                ((Slime) entity).setSize(this.dataByte);
 | 
			
		||||
                return entity;
 | 
			
		||||
            case "ARROW":
 | 
			
		||||
            case "EGG":
 | 
			
		||||
            case "ENDER_CRYSTAL":
 | 
			
		||||
            case "ENDER_PEARL":
 | 
			
		||||
            case "ENDER_SIGNAL":
 | 
			
		||||
            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":
 | 
			
		||||
            }
 | 
			
		||||
            case "ARROW", "EGG", "ENDER_CRYSTAL", "ENDER_PEARL", "ENDER_SIGNAL", "DROPPED_ITEM", "EXPERIENCE_ORB", "FALLING_BLOCK",
 | 
			
		||||
                    "FIREBALL", "FIREWORK", "FISHING_HOOK", "LEASH_HITCH", "LIGHTNING", "MINECART", "MINECART_COMMAND",
 | 
			
		||||
                    "MINECART_MOB_SPAWNER", "MINECART_TNT", "PLAYER", "PRIMED_TNT", "SMALL_FIREBALL", "SNOWBALL",
 | 
			
		||||
                    "SPLASH_POTION", "THROWN_EXP_BOTTLE", "SPECTRAL_ARROW", "SHULKER_BULLET", "AREA_EFFECT_CLOUD",
 | 
			
		||||
                    "DRAGON_FIREBALL", "WITHER_SKULL", "MINECART_FURNACE", "LLAMA_SPIT", "TRIDENT", "UNKNOWN" -> {
 | 
			
		||||
                // Do this stuff later
 | 
			
		||||
                return entity;
 | 
			
		||||
            }
 | 
			
		||||
            // MISC //
 | 
			
		||||
            case "ITEM_FRAME":
 | 
			
		||||
            case "ITEM_FRAME" -> {
 | 
			
		||||
                ItemFrame itemframe = (ItemFrame) entity;
 | 
			
		||||
                itemframe.setRotation(Rotation.values()[this.dataByte]);
 | 
			
		||||
                itemframe.setItem(this.stack);
 | 
			
		||||
                return entity;
 | 
			
		||||
            case "PAINTING":
 | 
			
		||||
            }
 | 
			
		||||
            case "PAINTING" -> {
 | 
			
		||||
                Painting painting = (Painting) entity;
 | 
			
		||||
                painting.setFacingDirection(BlockFace.values()[this.dataByte], true);
 | 
			
		||||
                painting.setArt(Art.getByName(this.dataString), true);
 | 
			
		||||
                return entity;
 | 
			
		||||
            }
 | 
			
		||||
            // END MISC //
 | 
			
		||||
            // INVENTORY HOLDER //
 | 
			
		||||
            case "MINECART_CHEST":
 | 
			
		||||
            case "MINECART_HOPPER":
 | 
			
		||||
            case "MINECART_CHEST", "MINECART_HOPPER" -> {
 | 
			
		||||
                restoreInventory((InventoryHolder) entity);
 | 
			
		||||
                return entity;
 | 
			
		||||
            }
 | 
			
		||||
            // START LIVING ENTITY //
 | 
			
		||||
            // START AGEABLE //
 | 
			
		||||
            // START TAMEABLE //
 | 
			
		||||
            case "HORSE":
 | 
			
		||||
            case "LLAMA":
 | 
			
		||||
            case "SKELETON_HORSE":
 | 
			
		||||
            case "DONKEY":
 | 
			
		||||
            case "MULE":
 | 
			
		||||
            case "HORSE", "LLAMA", "SKELETON_HORSE", "DONKEY", "MULE" -> {
 | 
			
		||||
                AbstractHorse horse = (AbstractHorse) entity;
 | 
			
		||||
                horse.setJumpStrength(this.horse.jump);
 | 
			
		||||
                if (horse instanceof ChestedHorse) {
 | 
			
		||||
@@ -586,15 +505,16 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
 | 
			
		||||
                restoreLiving(horse);
 | 
			
		||||
                restoreInventory(horse);
 | 
			
		||||
                return entity;
 | 
			
		||||
            }
 | 
			
		||||
            // END INVENTORY HOLDER //
 | 
			
		||||
            case "WOLF":
 | 
			
		||||
            case "OCELOT":
 | 
			
		||||
            case "WOLF", "OCELOT" -> {
 | 
			
		||||
                restoreTameable((Tameable) entity);
 | 
			
		||||
                restoreAgeable((Ageable) entity);
 | 
			
		||||
                restoreLiving((LivingEntity) entity);
 | 
			
		||||
                return entity;
 | 
			
		||||
            }
 | 
			
		||||
            // END AGEABLE //
 | 
			
		||||
            case "SHEEP":
 | 
			
		||||
            case "SHEEP" -> {
 | 
			
		||||
                Sheep sheep = (Sheep) entity;
 | 
			
		||||
                if (this.dataByte == 1) {
 | 
			
		||||
                    sheep.setSheared(true);
 | 
			
		||||
@@ -605,25 +525,22 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
 | 
			
		||||
                restoreAgeable(sheep);
 | 
			
		||||
                restoreLiving(sheep);
 | 
			
		||||
                return sheep;
 | 
			
		||||
            case "VILLAGER":
 | 
			
		||||
            case "CHICKEN":
 | 
			
		||||
            case "COW":
 | 
			
		||||
            case "TURTLE":
 | 
			
		||||
            case "POLAR_BEAR":
 | 
			
		||||
            case "MUSHROOM_COW":
 | 
			
		||||
            case "PIG":
 | 
			
		||||
            }
 | 
			
		||||
            case "VILLAGER", "CHICKEN", "COW", "TURTLE", "POLAR_BEAR", "MUSHROOM_COW", "PIG" -> {
 | 
			
		||||
                restoreAgeable((Ageable) entity);
 | 
			
		||||
                restoreLiving((LivingEntity) entity);
 | 
			
		||||
                return entity;
 | 
			
		||||
            }
 | 
			
		||||
            // END AGEABLE //
 | 
			
		||||
            case "RABBIT":
 | 
			
		||||
            case "RABBIT" -> {
 | 
			
		||||
                if (this.dataByte != 0) {
 | 
			
		||||
                    ((Rabbit) entity).setRabbitType(Rabbit.Type.values()[this.dataByte]);
 | 
			
		||||
                }
 | 
			
		||||
                restoreAgeable((Ageable) entity);
 | 
			
		||||
                restoreLiving((LivingEntity) entity);
 | 
			
		||||
                return entity;
 | 
			
		||||
            case "ARMOR_STAND":
 | 
			
		||||
            }
 | 
			
		||||
            case "ARMOR_STAND" -> {
 | 
			
		||||
                // CHECK positions
 | 
			
		||||
                ArmorStand stand = (ArmorStand) entity;
 | 
			
		||||
                if (this.inventory[0] != null) {
 | 
			
		||||
@@ -693,56 +610,38 @@ public final class ReplicatingEntityWrapper extends EntityWrapper {
 | 
			
		||||
                }
 | 
			
		||||
                restoreLiving(stand);
 | 
			
		||||
                return stand;
 | 
			
		||||
            case "BAT":
 | 
			
		||||
            }
 | 
			
		||||
            case "BAT" -> {
 | 
			
		||||
                if (this.dataByte != 0) {
 | 
			
		||||
                    ((Bat) entity).setAwake(true);
 | 
			
		||||
                }
 | 
			
		||||
                restoreLiving((LivingEntity) entity);
 | 
			
		||||
                return entity;
 | 
			
		||||
            case "ENDER_DRAGON":
 | 
			
		||||
            }
 | 
			
		||||
            case "ENDER_DRAGON" -> {
 | 
			
		||||
                if (this.dataByte != 0) {
 | 
			
		||||
                    ((EnderDragon) entity).setPhase(EnderDragon.Phase.values()[this.dataByte]);
 | 
			
		||||
                }
 | 
			
		||||
                restoreLiving((LivingEntity) entity);
 | 
			
		||||
                return entity;
 | 
			
		||||
            case "ENDERMITE":
 | 
			
		||||
            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":
 | 
			
		||||
            }
 | 
			
		||||
            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" -> {
 | 
			
		||||
                restoreLiving((LivingEntity) entity);
 | 
			
		||||
                return entity;
 | 
			
		||||
            case "IRON_GOLEM":
 | 
			
		||||
            }
 | 
			
		||||
            case "IRON_GOLEM" -> {
 | 
			
		||||
                if (this.dataByte != 0) {
 | 
			
		||||
                    ((IronGolem) entity).setPlayerCreated(true);
 | 
			
		||||
                }
 | 
			
		||||
                restoreLiving((LivingEntity) entity);
 | 
			
		||||
                return entity;
 | 
			
		||||
            default:
 | 
			
		||||
            }
 | 
			
		||||
            default -> {
 | 
			
		||||
                if (Settings.DEBUG) {
 | 
			
		||||
                    LOGGER.info("Could not identify entity: {}", entity.getType());
 | 
			
		||||
                }
 | 
			
		||||
                return entity;
 | 
			
		||||
            }
 | 
			
		||||
            // END LIVING
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,8 @@ import com.plotsquared.core.generator.IndependentPlotGenerator;
 | 
			
		||||
import com.plotsquared.core.location.Location;
 | 
			
		||||
import com.plotsquared.core.location.UncheckedWorldLocation;
 | 
			
		||||
import com.plotsquared.core.plot.PlotArea;
 | 
			
		||||
import com.plotsquared.core.plot.world.PlotAreaManager;
 | 
			
		||||
import com.plotsquared.core.plot.world.SinglePlotArea;
 | 
			
		||||
import com.plotsquared.core.queue.ScopedQueueCoordinator;
 | 
			
		||||
import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator;
 | 
			
		||||
import org.bukkit.generator.BlockPopulator;
 | 
			
		||||
import org.bukkit.generator.LimitedRegion;
 | 
			
		||||
import org.bukkit.generator.WorldInfo;
 | 
			
		||||
@@ -47,17 +46,6 @@ final class BlockStatePopulator extends BlockPopulator {
 | 
			
		||||
        this.plotGenerator = plotGenerator;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @deprecated Use {@link BlockStatePopulator#BlockStatePopulator(IndependentPlotGenerator)} as plotAreManager is unused
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated(forRemoval = true, since = "6.9.0")
 | 
			
		||||
    public BlockStatePopulator(
 | 
			
		||||
            final @NonNull IndependentPlotGenerator plotGenerator,
 | 
			
		||||
            final @NonNull PlotAreaManager plotAreaManager
 | 
			
		||||
    ) {
 | 
			
		||||
        this.plotGenerator = plotGenerator;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void populate(
 | 
			
		||||
            @NonNull final WorldInfo worldInfo,
 | 
			
		||||
@@ -80,7 +68,7 @@ final class BlockStatePopulator extends BlockPopulator {
 | 
			
		||||
                worldInfo.getMaxHeight(),
 | 
			
		||||
                (chunkZ << 4) + 15
 | 
			
		||||
        );
 | 
			
		||||
        ScopedQueueCoordinator offsetChunkQueue = new ScopedQueueCoordinator(wrapped, min, max);
 | 
			
		||||
        ZeroedDelegateScopedQueueCoordinator offsetChunkQueue = new ZeroedDelegateScopedQueueCoordinator(wrapped, min, max);
 | 
			
		||||
        this.plotGenerator.populateChunk(offsetChunkQueue, area);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -22,28 +22,46 @@ import com.plotsquared.bukkit.queue.GenChunk;
 | 
			
		||||
import com.plotsquared.bukkit.util.BukkitUtil;
 | 
			
		||||
import com.plotsquared.bukkit.util.BukkitWorld;
 | 
			
		||||
import com.plotsquared.core.PlotSquared;
 | 
			
		||||
import com.plotsquared.core.generator.ClassicPlotWorld;
 | 
			
		||||
import com.plotsquared.core.generator.GeneratorWrapper;
 | 
			
		||||
import com.plotsquared.core.generator.IndependentPlotGenerator;
 | 
			
		||||
import com.plotsquared.core.generator.SingleWorldGenerator;
 | 
			
		||||
import com.plotsquared.core.location.ChunkWrapper;
 | 
			
		||||
import com.plotsquared.core.location.UncheckedWorldLocation;
 | 
			
		||||
import com.plotsquared.core.plot.PlotArea;
 | 
			
		||||
import com.plotsquared.core.plot.world.PlotAreaManager;
 | 
			
		||||
import com.plotsquared.core.queue.ScopedQueueCoordinator;
 | 
			
		||||
import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator;
 | 
			
		||||
import com.plotsquared.core.util.ChunkManager;
 | 
			
		||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
 | 
			
		||||
import com.sk89q.worldedit.math.BlockVector2;
 | 
			
		||||
import org.apache.logging.log4j.LogManager;
 | 
			
		||||
import org.apache.logging.log4j.Logger;
 | 
			
		||||
import org.bukkit.HeightMap;
 | 
			
		||||
import org.bukkit.NamespacedKey;
 | 
			
		||||
import org.bukkit.Registry;
 | 
			
		||||
import org.bukkit.World;
 | 
			
		||||
import org.bukkit.block.Biome;
 | 
			
		||||
import org.bukkit.generator.BiomeProvider;
 | 
			
		||||
import org.bukkit.generator.BlockPopulator;
 | 
			
		||||
import org.bukkit.generator.ChunkGenerator;
 | 
			
		||||
import org.bukkit.generator.WorldInfo;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		||||
import org.jetbrains.annotations.NotNull;
 | 
			
		||||
import org.jetbrains.annotations.Nullable;
 | 
			
		||||
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
import java.util.EnumSet;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Random;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
 | 
			
		||||
import static java.util.function.Predicate.not;
 | 
			
		||||
 | 
			
		||||
public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrapper<ChunkGenerator> {
 | 
			
		||||
 | 
			
		||||
    private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + BukkitPlotGenerator.class.getSimpleName());
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings("unused")
 | 
			
		||||
    public final boolean PAPER_ASYNC_SAFE = true;
 | 
			
		||||
 | 
			
		||||
@@ -52,9 +70,15 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
 | 
			
		||||
    private final ChunkGenerator platformGenerator;
 | 
			
		||||
    private final boolean full;
 | 
			
		||||
    private final String levelName;
 | 
			
		||||
    private final boolean useNewGenerationMethods;
 | 
			
		||||
    private final BiomeProvider biomeProvider;
 | 
			
		||||
    private List<BlockPopulator> populators;
 | 
			
		||||
    private boolean loaded = false;
 | 
			
		||||
 | 
			
		||||
    private PlotArea lastPlotArea;
 | 
			
		||||
    private int lastChunkX = Integer.MIN_VALUE;
 | 
			
		||||
    private int lastChunkZ = Integer.MIN_VALUE;
 | 
			
		||||
 | 
			
		||||
    public BukkitPlotGenerator(
 | 
			
		||||
            final @NonNull String name,
 | 
			
		||||
            final @NonNull IndependentPlotGenerator generator,
 | 
			
		||||
@@ -72,18 +96,23 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
 | 
			
		||||
            this.populators.add(new LegacyBlockStatePopulator(this.plotGenerator));
 | 
			
		||||
        }
 | 
			
		||||
        this.full = true;
 | 
			
		||||
        this.useNewGenerationMethods = PlotSquared.platform().serverVersion()[1] >= 19;
 | 
			
		||||
        this.biomeProvider = new BukkitPlotBiomeProvider();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public BukkitPlotGenerator(final String world, final ChunkGenerator cg, final @NonNull PlotAreaManager plotAreaManager) {
 | 
			
		||||
        if (cg instanceof BukkitPlotGenerator) {
 | 
			
		||||
            throw new IllegalArgumentException("ChunkGenerator: " + cg.getClass().getName()
 | 
			
		||||
                    + " is already a BukkitPlotGenerator!");
 | 
			
		||||
            throw new IllegalArgumentException("ChunkGenerator: " + cg
 | 
			
		||||
                    .getClass()
 | 
			
		||||
                    .getName() + " is already a BukkitPlotGenerator!");
 | 
			
		||||
        }
 | 
			
		||||
        this.plotAreaManager = plotAreaManager;
 | 
			
		||||
        this.levelName = world;
 | 
			
		||||
        this.full = false;
 | 
			
		||||
        this.platformGenerator = cg;
 | 
			
		||||
        this.plotGenerator = new DelegatePlotGenerator(cg, world);
 | 
			
		||||
        this.useNewGenerationMethods = PlotSquared.platform().serverVersion()[1] >= 19;
 | 
			
		||||
        this.biomeProvider = null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
@@ -111,7 +140,7 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
 | 
			
		||||
        try {
 | 
			
		||||
            checkLoaded(world);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            LOGGER.error("Error attempting to load world into PlotSquared.", e);
 | 
			
		||||
        }
 | 
			
		||||
        ArrayList<BlockPopulator> toAdd = new ArrayList<>();
 | 
			
		||||
        List<BlockPopulator> existing = world.getPopulators();
 | 
			
		||||
@@ -128,6 +157,7 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
 | 
			
		||||
        return toAdd;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Extracted to synchronized method for thread-safety, preventing multiple internal world load calls
 | 
			
		||||
    private synchronized void checkLoaded(@NonNull World world) {
 | 
			
		||||
        // Do not attempt to load configurations until WorldEdit has a platform ready.
 | 
			
		||||
        if (!PlotSquared.get().isWeInitialised()) {
 | 
			
		||||
@@ -153,7 +183,7 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings("deprecation")
 | 
			
		||||
    @SuppressWarnings("deprecation") // Kept for compatibility with <=1.17.1
 | 
			
		||||
    private void setSpawnLimits(@NonNull World world, int limit) {
 | 
			
		||||
        world.setAmbientSpawnLimit(limit);
 | 
			
		||||
        world.setAnimalSpawnLimit(limit);
 | 
			
		||||
@@ -162,10 +192,117 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public @NonNull ChunkData generateChunkData(
 | 
			
		||||
            @NonNull World world, @NonNull Random random, int x, int z,
 | 
			
		||||
            @NonNull BiomeGrid biome
 | 
			
		||||
    public void generateNoise(
 | 
			
		||||
            @NotNull final WorldInfo worldInfo,
 | 
			
		||||
            @NotNull final Random random,
 | 
			
		||||
            final int chunkX,
 | 
			
		||||
            final int chunkZ,
 | 
			
		||||
            @NotNull final ChunkData chunkData
 | 
			
		||||
    ) {
 | 
			
		||||
        if (this.platformGenerator != this) {
 | 
			
		||||
            this.platformGenerator.generateNoise(worldInfo, random, chunkX, chunkZ, chunkData);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        int minY = chunkData.getMinHeight();
 | 
			
		||||
        int maxY = chunkData.getMaxHeight();
 | 
			
		||||
        GenChunk result = new GenChunk(minY, maxY);
 | 
			
		||||
        // Set the chunk location
 | 
			
		||||
        result.setChunk(new ChunkWrapper(worldInfo.getName(), chunkX, chunkZ));
 | 
			
		||||
        // Set the result data
 | 
			
		||||
        result.setChunkData(chunkData);
 | 
			
		||||
        result.result = null;
 | 
			
		||||
 | 
			
		||||
        // Catch any exceptions (as exceptions usually thrown)
 | 
			
		||||
        try {
 | 
			
		||||
            generate(BlockVector2.at(chunkX, chunkZ), worldInfo.getName(), result, false);
 | 
			
		||||
        } catch (Throwable e) {
 | 
			
		||||
            LOGGER.error("Error attempting to generate chunk.", e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void generateSurface(
 | 
			
		||||
            @NotNull final WorldInfo worldInfo,
 | 
			
		||||
            @NotNull final Random random,
 | 
			
		||||
            final int chunkX,
 | 
			
		||||
            final int chunkZ,
 | 
			
		||||
            @NotNull final ChunkData chunkData
 | 
			
		||||
    ) {
 | 
			
		||||
        if (platformGenerator != this) {
 | 
			
		||||
            platformGenerator.generateSurface(worldInfo, random, chunkX, chunkZ, chunkData);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void generateBedrock(
 | 
			
		||||
            @NotNull final WorldInfo worldInfo,
 | 
			
		||||
            @NotNull final Random random,
 | 
			
		||||
            final int chunkX,
 | 
			
		||||
            final int chunkZ,
 | 
			
		||||
            @NotNull final ChunkData chunkData
 | 
			
		||||
    ) {
 | 
			
		||||
        if (platformGenerator != this) {
 | 
			
		||||
            platformGenerator.generateBedrock(worldInfo, random, chunkX, chunkZ, chunkData);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void generateCaves(
 | 
			
		||||
            @NotNull final WorldInfo worldInfo,
 | 
			
		||||
            @NotNull final Random random,
 | 
			
		||||
            final int chunkX,
 | 
			
		||||
            final int chunkZ,
 | 
			
		||||
            @NotNull final ChunkData chunkData
 | 
			
		||||
    ) {
 | 
			
		||||
        if (platformGenerator != this) {
 | 
			
		||||
            platformGenerator.generateCaves(worldInfo, random, chunkX, chunkZ, chunkData);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public @Nullable BiomeProvider getDefaultBiomeProvider(@NotNull final WorldInfo worldInfo) {
 | 
			
		||||
        if (platformGenerator != this) {
 | 
			
		||||
            return platformGenerator.getDefaultBiomeProvider(worldInfo);
 | 
			
		||||
        }
 | 
			
		||||
        return biomeProvider;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public int getBaseHeight(
 | 
			
		||||
            @NotNull final WorldInfo worldInfo,
 | 
			
		||||
            @NotNull final Random random,
 | 
			
		||||
            final int x,
 | 
			
		||||
            final int z,
 | 
			
		||||
            @NotNull final HeightMap heightMap
 | 
			
		||||
    ) {
 | 
			
		||||
        PlotArea area = getPlotArea(worldInfo.getName(), x, z);
 | 
			
		||||
        if (area instanceof ClassicPlotWorld cpw) {
 | 
			
		||||
            // Default to plot height being the heighest point before decoration (i.e. roads, walls etc.)
 | 
			
		||||
            return cpw.PLOT_HEIGHT;
 | 
			
		||||
        }
 | 
			
		||||
        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
 | 
			
		||||
    @Override
 | 
			
		||||
    @Deprecated(since = "7.0.0")
 | 
			
		||||
    public @NonNull ChunkData generateChunkData(
 | 
			
		||||
            @NonNull World world, @NonNull Random random, int x, int z, @NonNull BiomeGrid biome
 | 
			
		||||
    ) {
 | 
			
		||||
        if (useNewGenerationMethods) {
 | 
			
		||||
            if (this.platformGenerator != this) {
 | 
			
		||||
                return this.platformGenerator.generateChunkData(world, random, x, z, biome);
 | 
			
		||||
            } else {
 | 
			
		||||
                // Throw exception to be caught by the server that indicates the new generation API is being used.
 | 
			
		||||
                throw new UnsupportedOperationException("Using new generation methods. This method is unsupported.");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        int minY = BukkitWorld.getMinWorldHeight(world);
 | 
			
		||||
        int maxY = BukkitWorld.getMaxWorldHeight(world);
 | 
			
		||||
        GenChunk result = new GenChunk(minY, maxY);
 | 
			
		||||
@@ -175,7 +312,6 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
 | 
			
		||||
                    for (int chunkZ = 0; chunkZ < 16; chunkZ++) {
 | 
			
		||||
                        for (int y = minY; y < maxY; y++) {
 | 
			
		||||
                            biome.setBiome(chunkX, y, chunkZ, Biome.PLAINS);
 | 
			
		||||
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -195,35 +331,32 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
 | 
			
		||||
            if (this.platformGenerator != this) {
 | 
			
		||||
                return this.platformGenerator.generateChunkData(world, random, x, z, biome);
 | 
			
		||||
            } else {
 | 
			
		||||
                generate(BlockVector2.at(x, z), world, result);
 | 
			
		||||
                generate(BlockVector2.at(x, z), world.getName(), result, true);
 | 
			
		||||
            }
 | 
			
		||||
        } catch (Throwable e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            LOGGER.error("Error attempting to load world into PlotSquared.", e);
 | 
			
		||||
        }
 | 
			
		||||
        // Return the result data
 | 
			
		||||
        return result.getChunkData();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void generate(BlockVector2 loc, World world, ScopedQueueCoordinator result) {
 | 
			
		||||
    private void generate(BlockVector2 loc, String world, ZeroedDelegateScopedQueueCoordinator result, boolean biomes) {
 | 
			
		||||
        // Load if improperly loaded
 | 
			
		||||
        if (!this.loaded) {
 | 
			
		||||
            checkLoaded(world);
 | 
			
		||||
            synchronized (this) {
 | 
			
		||||
                PlotSquared.get().loadWorld(world, this);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        // Process the chunk
 | 
			
		||||
        if (ChunkManager.preProcessChunk(loc, result)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        PlotArea area = this.plotAreaManager.getPlotArea(world.getName(), null);
 | 
			
		||||
        if (area == null && (area = this.plotAreaManager.getPlotArea(this.levelName, null)) == null) {
 | 
			
		||||
            throw new IllegalStateException(
 | 
			
		||||
                    "Cannot regenerate chunk that does not belong to a plot area." + " Location: " + loc
 | 
			
		||||
                            + ", world: " + world);
 | 
			
		||||
        }
 | 
			
		||||
        PlotArea area = getPlotArea(world, loc.getX(), loc.getZ());
 | 
			
		||||
        try {
 | 
			
		||||
            this.plotGenerator.generateChunk(result, area);
 | 
			
		||||
            this.plotGenerator.generateChunk(result, area, biomes);
 | 
			
		||||
        } catch (Throwable e) {
 | 
			
		||||
            // Recover from generator error
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
            LOGGER.error("Error attempting to generate chunk.", e);
 | 
			
		||||
        }
 | 
			
		||||
        ChunkManager.postProcessChunk(loc, result);
 | 
			
		||||
    }
 | 
			
		||||
@@ -277,4 +410,59 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
 | 
			
		||||
        return this.levelName;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private synchronized PlotArea getPlotArea(String name, int chunkX, int chunkZ) {
 | 
			
		||||
        // Load if improperly loaded
 | 
			
		||||
        if (!this.loaded) {
 | 
			
		||||
            PlotSquared.get().loadWorld(name, this);
 | 
			
		||||
            // Do not set loaded to true as we want to ensure spawn limits are set when "loading" is actually able to be
 | 
			
		||||
            // completed properly.
 | 
			
		||||
        }
 | 
			
		||||
        if (lastPlotArea != null && name.equals(this.levelName) && chunkX == lastChunkX && chunkZ == lastChunkZ) {
 | 
			
		||||
            return lastPlotArea;
 | 
			
		||||
        }
 | 
			
		||||
        PlotArea area = UncheckedWorldLocation.at(name, chunkX << 4, 0, chunkZ << 4).getPlotArea();
 | 
			
		||||
        if (area == null) {
 | 
			
		||||
            throw new IllegalStateException(String.format(
 | 
			
		||||
                    "Cannot generate chunk that does not belong to a plot area. World: %s",
 | 
			
		||||
                    name
 | 
			
		||||
            ));
 | 
			
		||||
        }
 | 
			
		||||
        this.lastChunkX = chunkX;
 | 
			
		||||
        this.lastChunkZ = chunkZ;
 | 
			
		||||
        return this.lastPlotArea = area;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Biome provider should never need to be accessed outside of this class.
 | 
			
		||||
     */
 | 
			
		||||
    private final class BukkitPlotBiomeProvider extends BiomeProvider {
 | 
			
		||||
 | 
			
		||||
        private static final List<Biome> BIOMES;
 | 
			
		||||
 | 
			
		||||
        static {
 | 
			
		||||
            Set<Biome> disabledBiomes = EnumSet.of(Biome.CUSTOM);
 | 
			
		||||
            if (PlotSquared.platform().serverVersion()[1] <= 19) {
 | 
			
		||||
                final Biome cherryGrove = Registry.BIOME.get(NamespacedKey.minecraft("cherry_grove"));
 | 
			
		||||
                if (cherryGrove != null) {
 | 
			
		||||
                    disabledBiomes.add(cherryGrove);
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            BIOMES = Arrays.stream(Biome.values())
 | 
			
		||||
                    .filter(not(disabledBiomes::contains))
 | 
			
		||||
                    .toList();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public @NotNull Biome getBiome(@NotNull final WorldInfo worldInfo, final int x, final int y, final int z) {
 | 
			
		||||
            PlotArea area = getPlotArea(worldInfo.getName(), x >> 4, z >> 4);
 | 
			
		||||
            return BukkitAdapter.adapt(plotGenerator.getBiome(area, x, y, z));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public @NotNull List<Biome> getBiomes(@NotNull final WorldInfo worldInfo) {
 | 
			
		||||
            return BIOMES; // Allow all biomes
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -24,9 +24,10 @@ import com.plotsquared.core.generator.IndependentPlotGenerator;
 | 
			
		||||
import com.plotsquared.core.location.Location;
 | 
			
		||||
import com.plotsquared.core.plot.PlotArea;
 | 
			
		||||
import com.plotsquared.core.plot.PlotId;
 | 
			
		||||
import com.plotsquared.core.queue.ScopedQueueCoordinator;
 | 
			
		||||
import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator;
 | 
			
		||||
import com.plotsquared.core.util.MathMan;
 | 
			
		||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
 | 
			
		||||
import com.sk89q.worldedit.world.biome.BiomeType;
 | 
			
		||||
import org.bukkit.World;
 | 
			
		||||
import org.bukkit.block.Biome;
 | 
			
		||||
import org.bukkit.generator.BlockPopulator;
 | 
			
		||||
@@ -49,6 +50,11 @@ final class DelegatePlotGenerator extends IndependentPlotGenerator {
 | 
			
		||||
    public void initialize(PlotArea area) {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public BiomeType getBiome(final PlotArea settings, final int x, final int y, final int z) {
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String getName() {
 | 
			
		||||
        return this.chunkGenerator.getClass().getName();
 | 
			
		||||
@@ -60,7 +66,7 @@ final class DelegatePlotGenerator extends IndependentPlotGenerator {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void generateChunk(final ScopedQueueCoordinator result, PlotArea settings) {
 | 
			
		||||
    public void generateChunk(final ZeroedDelegateScopedQueueCoordinator result, PlotArea settings, boolean biomes) {
 | 
			
		||||
        World world = BukkitUtil.getWorld(this.world);
 | 
			
		||||
        Location min = result.getMin();
 | 
			
		||||
        int chunkX = min.getX() >> 4;
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,7 @@ import com.plotsquared.core.location.UncheckedWorldLocation;
 | 
			
		||||
import com.plotsquared.core.plot.PlotArea;
 | 
			
		||||
import com.plotsquared.core.plot.world.SinglePlotArea;
 | 
			
		||||
import com.plotsquared.core.queue.QueueCoordinator;
 | 
			
		||||
import com.plotsquared.core.queue.ScopedQueueCoordinator;
 | 
			
		||||
import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator;
 | 
			
		||||
import com.sk89q.worldedit.bukkit.BukkitWorld;
 | 
			
		||||
import com.sk89q.worldedit.util.SideEffectSet;
 | 
			
		||||
import org.bukkit.Chunk;
 | 
			
		||||
@@ -65,7 +65,7 @@ final class LegacyBlockStatePopulator extends BlockPopulator {
 | 
			
		||||
        queue.setChunkObject(source);
 | 
			
		||||
        Location min = UncheckedWorldLocation.at(world.getName(), chunkMinX, world.getMinHeight(), chunkMinZ);
 | 
			
		||||
        Location max = UncheckedWorldLocation.at(world.getName(), chunkMinX + 15, world.getMaxHeight(), chunkMinZ + 15);
 | 
			
		||||
        ScopedQueueCoordinator offsetChunkQueue = new ScopedQueueCoordinator(queue, min, max);
 | 
			
		||||
        ZeroedDelegateScopedQueueCoordinator offsetChunkQueue = new ZeroedDelegateScopedQueueCoordinator(queue, min, max);
 | 
			
		||||
        this.plotGenerator.populateChunk(offsetChunkQueue, area);
 | 
			
		||||
        queue.enqueue();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -61,16 +61,18 @@ import com.plotsquared.core.util.task.TaskTime;
 | 
			
		||||
import com.sk89q.worldedit.WorldEdit;
 | 
			
		||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
 | 
			
		||||
import com.sk89q.worldedit.world.block.BlockType;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.GameMode;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.Tag;
 | 
			
		||||
import org.bukkit.block.Block;
 | 
			
		||||
import org.bukkit.block.BlockFace;
 | 
			
		||||
import org.bukkit.block.BlockState;
 | 
			
		||||
import org.bukkit.block.data.BlockData;
 | 
			
		||||
import org.bukkit.block.data.type.Dispenser;
 | 
			
		||||
import org.bukkit.block.data.type.Farmland;
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
import org.bukkit.entity.Fireball;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
@@ -98,6 +100,7 @@ import org.bukkit.event.block.BlockSpreadEvent;
 | 
			
		||||
import org.bukkit.event.block.CauldronLevelChangeEvent;
 | 
			
		||||
import org.bukkit.event.block.EntityBlockFormEvent;
 | 
			
		||||
import org.bukkit.event.block.LeavesDecayEvent;
 | 
			
		||||
import org.bukkit.event.block.MoistureChangeEvent;
 | 
			
		||||
import org.bukkit.event.block.SpongeAbsorbEvent;
 | 
			
		||||
import org.bukkit.event.world.StructureGrowEvent;
 | 
			
		||||
import org.bukkit.projectiles.BlockProjectileSource;
 | 
			
		||||
@@ -112,6 +115,10 @@ import java.util.UUID;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import java.util.stream.Stream;
 | 
			
		||||
 | 
			
		||||
import static org.bukkit.Tag.CORALS;
 | 
			
		||||
import static org.bukkit.Tag.CORAL_BLOCKS;
 | 
			
		||||
import static org.bukkit.Tag.WALL_CORALS;
 | 
			
		||||
 | 
			
		||||
@SuppressWarnings("unused")
 | 
			
		||||
public class BlockEventListener implements Listener {
 | 
			
		||||
 | 
			
		||||
@@ -274,13 +281,23 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
        if (plot != null) {
 | 
			
		||||
            if (area.notifyIfOutsideBuildArea(pp, location.getY())) {
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("height.height_limit"),
 | 
			
		||||
                        TagResolver.builder()
 | 
			
		||||
                                .tag("minheight", Tag.inserting(Component.text(area.getMinBuildHeight())))
 | 
			
		||||
                                .tag("maxheight", Tag.inserting(Component.text(area.getMaxBuildHeight())))
 | 
			
		||||
                                .build()
 | 
			
		||||
                );
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (!plot.hasOwner()) {
 | 
			
		||||
                if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_UNOWNED)) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_UNOWNED))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_UNOWNED)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
@@ -297,7 +314,10 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
                if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_OTHER)) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_OTHER))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_OTHER)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    plot.debug(player.getName() + " could not place " + event.getBlock().getType()
 | 
			
		||||
@@ -324,7 +344,10 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
        } else if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_ROAD)) {
 | 
			
		||||
            pp.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_ROAD))
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "node",
 | 
			
		||||
                            Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_ROAD)
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
        }
 | 
			
		||||
@@ -346,13 +369,23 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
                if (!plotPlayer.hasPermission(Permission.PERMISSION_ADMIN_DESTROY_GROUNDLEVEL)) {
 | 
			
		||||
                    plotPlayer.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_DESTROY_GROUNDLEVEL))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_DESTROY_GROUNDLEVEL)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            } else if (area.notifyIfOutsideBuildArea(plotPlayer, location.getY())) {
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
                plotPlayer.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("height.height_limit"),
 | 
			
		||||
                        TagResolver.builder()
 | 
			
		||||
                                .tag("minheight", Tag.inserting(Component.text(area.getMinBuildHeight())))
 | 
			
		||||
                                .tag("maxheight", Tag.inserting(Component.text(area.getMaxBuildHeight())))
 | 
			
		||||
                                .build()
 | 
			
		||||
                );
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (!plot.hasOwner()) {
 | 
			
		||||
@@ -375,7 +408,10 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
                }
 | 
			
		||||
                plotPlayer.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_DESTROY_OTHER))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_ADMIN_DESTROY_OTHER)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            } else if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot)) {
 | 
			
		||||
@@ -401,7 +437,10 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
        }
 | 
			
		||||
        pp.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_DESTROY_ROAD))
 | 
			
		||||
                TagResolver.resolver(
 | 
			
		||||
                        "node",
 | 
			
		||||
                        Tag.inserting(Permission.PERMISSION_ADMIN_DESTROY_ROAD)
 | 
			
		||||
                )
 | 
			
		||||
        );
 | 
			
		||||
        event.setCancelled(true);
 | 
			
		||||
    }
 | 
			
		||||
@@ -534,14 +573,14 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (SNOW.contains(event.getNewState().getType())) {
 | 
			
		||||
        if (org.bukkit.Tag.SNOW.isTagged(event.getNewState().getType())) {
 | 
			
		||||
            if (!plot.getFlag(SnowFormFlag.class)) {
 | 
			
		||||
                plot.debug("Snow could not form because snow-form = false");
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (Tag.ICE.isTagged(event.getNewState().getType())) {
 | 
			
		||||
        if (org.bukkit.Tag.ICE.isTagged(event.getNewState().getType())) {
 | 
			
		||||
            if (!plot.getFlag(IceFormFlag.class)) {
 | 
			
		||||
                plot.debug("Ice could not form because ice-form = false");
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
@@ -566,9 +605,9 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        Class<? extends BooleanFlag<?>> flag;
 | 
			
		||||
        if (SNOW.contains(event.getNewState().getType())) {
 | 
			
		||||
        if (org.bukkit.Tag.SNOW.isTagged(event.getNewState().getType())) {
 | 
			
		||||
            flag = SnowFormFlag.class;
 | 
			
		||||
        } else if (Tag.ICE.isTagged(event.getNewState().getType())) {
 | 
			
		||||
        } else if (org.bukkit.Tag.ICE.isTagged(event.getNewState().getType())) {
 | 
			
		||||
            flag = IceFormFlag.class;
 | 
			
		||||
        } else {
 | 
			
		||||
            return;
 | 
			
		||||
@@ -674,14 +713,14 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        Material blockType = block.getType();
 | 
			
		||||
        if (Tag.ICE.isTagged(blockType)) {
 | 
			
		||||
        if (org.bukkit.Tag.ICE.isTagged(blockType)) {
 | 
			
		||||
            if (!plot.getFlag(IceMeltFlag.class)) {
 | 
			
		||||
                plot.debug("Ice could not melt because ice-melt = false");
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (SNOW.contains(blockType)) {
 | 
			
		||||
        if (org.bukkit.Tag.SNOW.isTagged(blockType)) {
 | 
			
		||||
            if (!plot.getFlag(SnowMeltFlag.class)) {
 | 
			
		||||
                plot.debug("Snow could not melt because snow-melt = false");
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
@@ -695,7 +734,7 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        if (Tag.CORAL_BLOCKS.isTagged(blockType) || Tag.CORALS.isTagged(blockType) || Tag.WALL_CORALS.isTagged(blockType)) {
 | 
			
		||||
        if (CORAL_BLOCKS.isTagged(blockType) || CORALS.isTagged(blockType) || WALL_CORALS.isTagged(blockType)) {
 | 
			
		||||
            if (!plot.getFlag(CoralDryFlag.class)) {
 | 
			
		||||
                plot.debug("Coral could not dry because coral-dry = false");
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
@@ -703,6 +742,43 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
 | 
			
		||||
    public void onMoistureChange(MoistureChangeEvent event) {
 | 
			
		||||
        Block block = event.getBlock();
 | 
			
		||||
        Location location = BukkitUtil.adapt(block.getLocation());
 | 
			
		||||
        PlotArea area = location.getPlotArea();
 | 
			
		||||
 | 
			
		||||
        if (area == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Plot plot = area.getOwnedPlot(location);
 | 
			
		||||
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (block.getBlockData() instanceof Farmland farmland && event
 | 
			
		||||
                .getNewState()
 | 
			
		||||
                .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");
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
 | 
			
		||||
    public void onChange(BlockFromToEvent event) {
 | 
			
		||||
        Block fromBlock = event.getBlock();
 | 
			
		||||
@@ -748,7 +824,10 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (toPlot != null) {
 | 
			
		||||
            if (!toArea.contains(fromLocation.getX(), fromLocation.getZ()) || !Objects.equals(toPlot, toArea.getOwnedPlot(fromLocation))) {
 | 
			
		||||
            if (!toArea.contains(fromLocation.getX(), fromLocation.getZ()) || !Objects.equals(
 | 
			
		||||
                    toPlot,
 | 
			
		||||
                    toArea.getOwnedPlot(fromLocation)
 | 
			
		||||
            )) {
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
@@ -764,7 +843,10 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
                toPlot.debug("Liquid could not flow because liquid-flow = disabled");
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (!toArea.contains(fromLocation.getX(), fromLocation.getZ()) || !Objects.equals(null, toArea.getOwnedPlot(fromLocation))) {
 | 
			
		||||
        } else if (!toArea.contains(fromLocation.getX(), fromLocation.getZ()) || !Objects.equals(
 | 
			
		||||
                null,
 | 
			
		||||
                toArea.getOwnedPlot(fromLocation)
 | 
			
		||||
        )) {
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
        } else if (event.getBlock().isLiquid()) {
 | 
			
		||||
            final org.bukkit.Location location = event.getBlock().getLocation();
 | 
			
		||||
@@ -1034,6 +1116,7 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
            if (plot != null) {
 | 
			
		||||
                plot.debug("Explosion was cancelled because explosion = false");
 | 
			
		||||
            }
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        event.blockList().removeIf(blox -> !plot.equals(area.getOwnedPlot(BukkitUtil.adapt(blox.getLocation()))));
 | 
			
		||||
    }
 | 
			
		||||
@@ -1087,7 +1170,10 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
                )) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_ROAD))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_ROAD)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
@@ -1097,7 +1183,10 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
                )) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_UNOWNED))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_UNOWNED)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
@@ -1105,7 +1194,10 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
                if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_OTHER)) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_OTHER))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_OTHER)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
@@ -1231,16 +1323,29 @@ public class BlockEventListener implements Listener {
 | 
			
		||||
            ) && !(Objects.equals(currentLocation.getPlot(), plot))) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_ROAD))
 | 
			
		||||
                        TagResolver.resolver("node", Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_ROAD))
 | 
			
		||||
                );
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            if (area.notifyIfOutsideBuildArea(pp, currentLocation.getY())) {
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
                break;
 | 
			
		||||
            if (pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_HEIGHT_LIMIT)) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            if (currentLocation.getY() >= area.getMaxBuildHeight() || currentLocation.getY() < area.getMinBuildHeight()) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("height.height_limit"),
 | 
			
		||||
                        TagResolver.builder()
 | 
			
		||||
                                .tag("minheight", Tag.inserting(Component.text(area.getMinBuildHeight())))
 | 
			
		||||
                                .tag("maxheight", Tag.inserting(Component.text(area.getMaxBuildHeight())))
 | 
			
		||||
                                .build()
 | 
			
		||||
                );
 | 
			
		||||
                if (area.notifyIfOutsideBuildArea(pp, currentLocation.getY())) {
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,6 +26,7 @@ import com.plotsquared.core.plot.Plot;
 | 
			
		||||
import com.plotsquared.core.plot.PlotArea;
 | 
			
		||||
import com.plotsquared.core.plot.flag.implementations.CopperOxideFlag;
 | 
			
		||||
import com.plotsquared.core.plot.flag.implementations.MiscInteractFlag;
 | 
			
		||||
import com.plotsquared.core.plot.flag.implementations.SculkSensorInteractFlag;
 | 
			
		||||
import com.plotsquared.core.util.PlotFlagUtil;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.block.Block;
 | 
			
		||||
@@ -92,12 +93,16 @@ public class BlockEventListener117 implements Listener {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        Plot plot = location.getOwnedPlot();
 | 
			
		||||
        if (plot == null && !PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, MiscInteractFlag.class, true) || plot != null && !plot.getFlag(
 | 
			
		||||
                MiscInteractFlag.class)) {
 | 
			
		||||
        if (plot == null && !PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(
 | 
			
		||||
                area,
 | 
			
		||||
                MiscInteractFlag.class,
 | 
			
		||||
                true
 | 
			
		||||
        ) || plot != null && (!plot.getFlag(MiscInteractFlag.class) || !plot.getFlag(SculkSensorInteractFlag.class))) {
 | 
			
		||||
            if (plotPlayer != null) {
 | 
			
		||||
                if (plot != null) {
 | 
			
		||||
                    if (!plot.isAdded(plotPlayer.getUUID())) {
 | 
			
		||||
                        plot.debug(plotPlayer.getName() + " couldn't trigger sculk sensors because misc-interact = false");
 | 
			
		||||
                        plot.debug(plotPlayer.getName() + " couldn't trigger sculk sensors because both " +
 | 
			
		||||
                                "sculk-sensor-interact and misc-interact = false");
 | 
			
		||||
                        event.setCancelled(true);
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -108,13 +113,15 @@ public class BlockEventListener117 implements Listener {
 | 
			
		||||
                if (plot != null) {
 | 
			
		||||
                    if (itemThrower == null && (itemThrower = item.getOwner()) == null) {
 | 
			
		||||
                        plot.debug(
 | 
			
		||||
                                "A thrown item couldn't trigger sculk sensors because misc-interact = false and the item's owner could not be resolved.");
 | 
			
		||||
                                "A thrown item couldn't trigger sculk sensors because both sculk-sensor-interact and " +
 | 
			
		||||
                                        "misc-interact = false and the item's owner could not be resolved.");
 | 
			
		||||
                        event.setCancelled(true);
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!plot.isAdded(itemThrower)) {
 | 
			
		||||
                        if (!plot.isAdded(itemThrower)) {
 | 
			
		||||
                            plot.debug("A thrown item couldn't trigger sculk sensors because misc-interact = false");
 | 
			
		||||
                            plot.debug("A thrown item couldn't trigger sculk sensors because both sculk-sensor-interact and " +
 | 
			
		||||
                                    "misc-interact = false");
 | 
			
		||||
                            event.setCancelled(true);
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
@@ -133,7 +140,6 @@ public class BlockEventListener117 implements Listener {
 | 
			
		||||
        if (area == null) {
 | 
			
		||||
            for (int i = blocks.size() - 1; i >= 0; i--) {
 | 
			
		||||
                Location blockLocation = BukkitUtil.adapt(blocks.get(i).getLocation());
 | 
			
		||||
                blockLocation = BukkitUtil.adapt(blocks.get(i).getLocation());
 | 
			
		||||
                if (blockLocation.isPlotArea()) {
 | 
			
		||||
                    blocks.remove(i);
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -234,7 +234,8 @@ public class ChunkListener implements Listener {
 | 
			
		||||
        Chunk chunk = event.getChunk();
 | 
			
		||||
        if (Settings.Chunk_Processor.AUTO_TRIM) {
 | 
			
		||||
            String world = chunk.getWorld().getName();
 | 
			
		||||
            if ((!Settings.Enabled_Components.WORLDS || !SinglePlotArea.isSinglePlotWorld(world)) && this.plotAreaManager.hasPlotArea(world)) {
 | 
			
		||||
            if ((!Settings.Enabled_Components.WORLDS || !SinglePlotArea.isSinglePlotWorld(world)) && this.plotAreaManager.hasPlotArea(
 | 
			
		||||
                    world)) {
 | 
			
		||||
                if (unloadChunk(world, chunk, true)) {
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
 
 | 
			
		||||
@@ -145,54 +145,37 @@ public class EntityEventListener implements Listener {
 | 
			
		||||
        }
 | 
			
		||||
        CreatureSpawnEvent.SpawnReason reason = event.getSpawnReason();
 | 
			
		||||
        switch (reason.toString()) {
 | 
			
		||||
            case "DISPENSE_EGG":
 | 
			
		||||
            case "EGG":
 | 
			
		||||
            case "OCELOT_BABY":
 | 
			
		||||
            case "SPAWNER_EGG":
 | 
			
		||||
            case "DISPENSE_EGG", "EGG", "OCELOT_BABY", "SPAWNER_EGG" -> {
 | 
			
		||||
                if (!area.isSpawnEggs()) {
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            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":
 | 
			
		||||
            }
 | 
			
		||||
            case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL",
 | 
			
		||||
                    "TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN" -> {
 | 
			
		||||
                if (!area.isMobSpawning()) {
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case "BREEDING":
 | 
			
		||||
            }
 | 
			
		||||
            case "BREEDING" -> {
 | 
			
		||||
                if (!area.isSpawnBreeding()) {
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case "BUILD_IRONGOLEM":
 | 
			
		||||
            case "BUILD_SNOWMAN":
 | 
			
		||||
            case "BUILD_WITHER":
 | 
			
		||||
            case "CUSTOM":
 | 
			
		||||
            }
 | 
			
		||||
            case "BUILD_IRONGOLEM", "BUILD_SNOWMAN", "BUILD_WITHER", "CUSTOM" -> {
 | 
			
		||||
                if (!area.isSpawnCustom() && entity.getType() != EntityType.ARMOR_STAND) {
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case "SPAWNER":
 | 
			
		||||
            }
 | 
			
		||||
            case "SPAWNER" -> {
 | 
			
		||||
                if (!area.isMobSpawnerSpawning()) {
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Plot plot = area.getOwnedPlotAbs(location);
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
 
 | 
			
		||||
@@ -44,7 +44,9 @@ import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag;
 | 
			
		||||
import com.plotsquared.core.plot.flag.types.BooleanFlag;
 | 
			
		||||
import com.plotsquared.core.plot.world.PlotAreaManager;
 | 
			
		||||
import com.plotsquared.core.util.PlotFlagUtil;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.bukkit.Chunk;
 | 
			
		||||
import org.bukkit.block.Block;
 | 
			
		||||
import org.bukkit.block.TileState;
 | 
			
		||||
@@ -176,59 +178,41 @@ public class PaperListener implements Listener {
 | 
			
		||||
        }
 | 
			
		||||
        CreatureSpawnEvent.SpawnReason reason = event.getReason();
 | 
			
		||||
        switch (reason.toString()) {
 | 
			
		||||
            case "DISPENSE_EGG":
 | 
			
		||||
            case "EGG":
 | 
			
		||||
            case "OCELOT_BABY":
 | 
			
		||||
            case "SPAWNER_EGG":
 | 
			
		||||
            case "DISPENSE_EGG", "EGG", "OCELOT_BABY", "SPAWNER_EGG" -> {
 | 
			
		||||
                if (!area.isSpawnEggs()) {
 | 
			
		||||
                    event.setShouldAbortSpawn(true);
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            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":
 | 
			
		||||
            }
 | 
			
		||||
            case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL", "TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN" -> {
 | 
			
		||||
                if (!area.isMobSpawning()) {
 | 
			
		||||
                    event.setShouldAbortSpawn(true);
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case "BREEDING":
 | 
			
		||||
            }
 | 
			
		||||
            case "BREEDING" -> {
 | 
			
		||||
                if (!area.isSpawnBreeding()) {
 | 
			
		||||
                    event.setShouldAbortSpawn(true);
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case "BUILD_IRONGOLEM":
 | 
			
		||||
            case "BUILD_SNOWMAN":
 | 
			
		||||
            case "BUILD_WITHER":
 | 
			
		||||
            case "CUSTOM":
 | 
			
		||||
            }
 | 
			
		||||
            case "BUILD_IRONGOLEM", "BUILD_SNOWMAN", "BUILD_WITHER", "CUSTOM" -> {
 | 
			
		||||
                if (!area.isSpawnCustom() && event.getType() != EntityType.ARMOR_STAND) {
 | 
			
		||||
                    event.setShouldAbortSpawn(true);
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            case "SPAWNER":
 | 
			
		||||
            }
 | 
			
		||||
            case "SPAWNER" -> {
 | 
			
		||||
                if (!area.isMobSpawnerSpawning()) {
 | 
			
		||||
                    event.setShouldAbortSpawn(true);
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        Plot plot = location.getOwnedPlotAbs();
 | 
			
		||||
        if (plot == null) {
 | 
			
		||||
@@ -302,7 +286,7 @@ public class PaperListener implements Listener {
 | 
			
		||||
            final PlotPlayer<?> plotPlayer = BukkitUtil.adapt(event.getPlayer());
 | 
			
		||||
            plotPlayer.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("errors.tile_entity_cap_reached"),
 | 
			
		||||
                    Template.of("amount", String.valueOf(Settings.Chunk_Processor.MAX_TILES))
 | 
			
		||||
                    TagResolver.resolver("amount", Tag.inserting(Component.text(Settings.Chunk_Processor.MAX_TILES)))
 | 
			
		||||
            );
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
            event.setBuild(false);
 | 
			
		||||
@@ -339,7 +323,10 @@ public class PaperListener implements Listener {
 | 
			
		||||
            )) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_PROJECTILE_ROAD))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_ADMIN_PROJECTILE_ROAD)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                entity.remove();
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
@@ -348,7 +335,10 @@ public class PaperListener implements Listener {
 | 
			
		||||
            if (!pp.hasPermission(Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED)) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                entity.remove();
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
@@ -358,7 +348,10 @@ public class PaperListener implements Listener {
 | 
			
		||||
                if (!pp.hasPermission(Permission.PERMISSION_ADMIN_PROJECTILE_OTHER)) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_PROJECTILE_OTHER))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_PROJECTILE_OTHER)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    entity.remove();
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
@@ -446,9 +439,11 @@ public class PaperListener implements Listener {
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private boolean getBooleanFlagValue(@NonNull FlagContainer container,
 | 
			
		||||
                                        @NonNull Class<? extends BooleanFlag<?>> flagClass,
 | 
			
		||||
                                        boolean defaultValue) {
 | 
			
		||||
    private boolean getBooleanFlagValue(
 | 
			
		||||
            @NonNull FlagContainer container,
 | 
			
		||||
            @NonNull Class<? extends BooleanFlag<?>> flagClass,
 | 
			
		||||
            boolean defaultValue
 | 
			
		||||
    ) {
 | 
			
		||||
        BooleanFlag<?> flag = container.getFlag(flagClass);
 | 
			
		||||
        return flag == null ? defaultValue : flag.getValue();
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -1,91 +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.bukkit.listener;
 | 
			
		||||
 | 
			
		||||
import com.google.inject.Inject;
 | 
			
		||||
import com.plotsquared.bukkit.util.BukkitUtil;
 | 
			
		||||
import com.plotsquared.core.configuration.Settings;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
 | 
			
		||||
import com.plotsquared.core.location.Location;
 | 
			
		||||
import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import com.plotsquared.core.plot.PlotArea;
 | 
			
		||||
import com.plotsquared.core.plot.world.PlotAreaManager;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import org.bukkit.block.Banner;
 | 
			
		||||
import org.bukkit.block.Beacon;
 | 
			
		||||
import org.bukkit.block.BlockState;
 | 
			
		||||
import org.bukkit.block.CommandBlock;
 | 
			
		||||
import org.bukkit.block.Comparator;
 | 
			
		||||
import org.bukkit.block.Conduit;
 | 
			
		||||
import org.bukkit.block.Container;
 | 
			
		||||
import org.bukkit.block.CreatureSpawner;
 | 
			
		||||
import org.bukkit.block.DaylightDetector;
 | 
			
		||||
import org.bukkit.block.EnchantingTable;
 | 
			
		||||
import org.bukkit.block.EndGateway;
 | 
			
		||||
import org.bukkit.block.EnderChest;
 | 
			
		||||
import org.bukkit.block.Jukebox;
 | 
			
		||||
import org.bukkit.block.Sign;
 | 
			
		||||
import org.bukkit.block.Skull;
 | 
			
		||||
import org.bukkit.block.Structure;
 | 
			
		||||
import org.bukkit.block.data.type.Bed;
 | 
			
		||||
import org.bukkit.event.EventHandler;
 | 
			
		||||
import org.bukkit.event.block.BlockPlaceEvent;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @deprecated P2 effectively no longer supports 1.13
 | 
			
		||||
 */
 | 
			
		||||
@Deprecated(forRemoval = true, since = "6.10.4")
 | 
			
		||||
public class PaperListener113 extends PaperListener {
 | 
			
		||||
 | 
			
		||||
    @Inject
 | 
			
		||||
    public PaperListener113(@NonNull PlotAreaManager plotAreaManager) {
 | 
			
		||||
        super(plotAreaManager);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @EventHandler
 | 
			
		||||
    public void onBlockPlace(BlockPlaceEvent event) {
 | 
			
		||||
        if (!Settings.Paper_Components.TILE_ENTITY_CHECK || !Settings.Enabled_Components.CHUNK_PROCESSOR) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        BlockState state = event.getBlock().getState(false);
 | 
			
		||||
        if (!(state instanceof Banner || state instanceof Beacon || state instanceof Bed || state instanceof CommandBlock
 | 
			
		||||
                || state instanceof Comparator || state instanceof Conduit || state instanceof Container || state instanceof CreatureSpawner
 | 
			
		||||
                || state instanceof DaylightDetector || state instanceof EnchantingTable || state instanceof EnderChest || state instanceof EndGateway
 | 
			
		||||
                || state instanceof Jukebox || state instanceof Sign || state instanceof Skull || state instanceof Structure)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        final Location location = BukkitUtil.adapt(event.getBlock().getLocation());
 | 
			
		||||
        final PlotArea plotArea = location.getPlotArea();
 | 
			
		||||
        if (plotArea == null) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        final int tileEntityCount = event.getBlock().getChunk().getTileEntities(false).length;
 | 
			
		||||
        if (tileEntityCount >= Settings.Chunk_Processor.MAX_TILES) {
 | 
			
		||||
            final PlotPlayer<?> plotPlayer = BukkitUtil.adapt(event.getPlayer());
 | 
			
		||||
            plotPlayer.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("errors.tile_entity_cap_reached"),
 | 
			
		||||
                    Template.of("amount", String.valueOf(Settings.Chunk_Processor.MAX_TILES))
 | 
			
		||||
            );
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
            event.setBuild(false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -77,12 +77,13 @@ import com.sk89q.worldedit.bukkit.BukkitAdapter;
 | 
			
		||||
import com.sk89q.worldedit.world.block.BlockType;
 | 
			
		||||
import io.papermc.lib.PaperLib;
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.MiniMessage;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.Tag;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.standard.StandardTags;
 | 
			
		||||
import org.bukkit.Bukkit;
 | 
			
		||||
import org.bukkit.ChatColor;
 | 
			
		||||
import org.bukkit.FluidCollisionMode;
 | 
			
		||||
import org.bukkit.Material;
 | 
			
		||||
import org.bukkit.Tag;
 | 
			
		||||
import org.bukkit.block.Block;
 | 
			
		||||
import org.bukkit.block.BlockFace;
 | 
			
		||||
import org.bukkit.block.BlockState;
 | 
			
		||||
@@ -272,8 +273,7 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
        Plot plot = plotPlayer.getCurrentPlot();
 | 
			
		||||
        // Check WorldEdit
 | 
			
		||||
        switch (parts[0]) {
 | 
			
		||||
            case "up":
 | 
			
		||||
            case "worldedit:up":
 | 
			
		||||
            case "up", "worldedit:up" -> {
 | 
			
		||||
                if (plot == null || (!plot.isAdded(plotPlayer.getUUID()) && !plotPlayer.hasPermission(
 | 
			
		||||
                        Permission.PERMISSION_ADMIN_BUILD_OTHER,
 | 
			
		||||
                        true
 | 
			
		||||
@@ -281,6 +281,7 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (plot == null && !area.isRoadFlags()) {
 | 
			
		||||
            return;
 | 
			
		||||
@@ -398,11 +399,15 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                && PremiumVerification.isPremium() && UpdateUtility.hasUpdate) {
 | 
			
		||||
            Caption boundary = TranslatableCaption.of("update.update_boundary");
 | 
			
		||||
            Caption updateNotification = TranslatableCaption.of("update.update_notification");
 | 
			
		||||
            Template internalVersion = Template.of("p2version", UpdateUtility.internalVersion.versionString());
 | 
			
		||||
            Template spigotVersion = Template.of("spigotversion", UpdateUtility.spigotVersion);
 | 
			
		||||
            Template downloadUrl = Template.of("downloadurl", "https://www.spigotmc.org/resources/77506/updates");
 | 
			
		||||
            pp.sendMessage(boundary);
 | 
			
		||||
            pp.sendMessage(updateNotification, internalVersion, spigotVersion, downloadUrl);
 | 
			
		||||
            pp.sendMessage(
 | 
			
		||||
                    updateNotification,
 | 
			
		||||
                    TagResolver.builder()
 | 
			
		||||
                            .tag("p2version", Tag.inserting(Component.text(UpdateUtility.internalVersion.versionString())))
 | 
			
		||||
                            .tag("spigotversion", Tag.inserting(Component.text(UpdateUtility.spigotVersion)))
 | 
			
		||||
                            .tag("downloadurl", Tag.preProcessParsed("https://www.spigotmc.org/resources/77506/updates"))
 | 
			
		||||
                            .build()
 | 
			
		||||
            );
 | 
			
		||||
            pp.sendMessage(boundary);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -454,7 +459,7 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                            .equals(BukkitUtil.adaptComplete(to)))) {
 | 
			
		||||
                        pp.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("deny.no_enter"),
 | 
			
		||||
                                Template.of("plot", plot.toString())
 | 
			
		||||
                                TagResolver.resolver("plot", Tag.inserting(Component.text(plot.toString())))
 | 
			
		||||
                        );
 | 
			
		||||
                        event.setCancelled(true);
 | 
			
		||||
                    }
 | 
			
		||||
@@ -567,10 +572,14 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            if (now == null) {
 | 
			
		||||
                try (final MetaDataAccess<Boolean> kickAccess =
 | 
			
		||||
                             pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
 | 
			
		||||
                    if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) {
 | 
			
		||||
                    if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(
 | 
			
		||||
                            false)) {
 | 
			
		||||
                        pp.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                                Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_EXIT_DENIED))
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_ADMIN_EXIT_DENIED)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        this.tmpTeleport = false;
 | 
			
		||||
                        if (lastPlot.equals(BukkitUtil.adapt(from).getPlot())) {
 | 
			
		||||
@@ -588,7 +597,7 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            } else if (!plotListener.plotEntry(pp, now) && this.tmpTeleport) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("deny.no_enter"),
 | 
			
		||||
                        Template.of("plot", now.toString())
 | 
			
		||||
                        TagResolver.resolver("plot", Tag.inserting(Component.text(now.toString())))
 | 
			
		||||
                );
 | 
			
		||||
                this.tmpTeleport = false;
 | 
			
		||||
                to.setX(from.getBlockX());
 | 
			
		||||
@@ -657,10 +666,14 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            if (plot == null) {
 | 
			
		||||
                try (final MetaDataAccess<Boolean> kickAccess =
 | 
			
		||||
                             pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
 | 
			
		||||
                    if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(false)) {
 | 
			
		||||
                    if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(
 | 
			
		||||
                            false)) {
 | 
			
		||||
                        pp.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                                Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_EXIT_DENIED))
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_ADMIN_EXIT_DENIED)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        this.tmpTeleport = false;
 | 
			
		||||
                        if (lastPlot.equals(BukkitUtil.adapt(from).getPlot())) {
 | 
			
		||||
@@ -678,7 +691,7 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            } else if (!plotListener.plotEntry(pp, plot) && this.tmpTeleport) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("deny.no_enter"),
 | 
			
		||||
                        Template.of("plot", plot.toString())
 | 
			
		||||
                        TagResolver.resolver("plot", Tag.inserting(Component.text(plot.toString())))
 | 
			
		||||
                );
 | 
			
		||||
                this.tmpTeleport = false;
 | 
			
		||||
                player.teleport(from);
 | 
			
		||||
@@ -762,46 +775,34 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
        PlotId id = plot.getId();
 | 
			
		||||
        String worldName = plot.getWorldName();
 | 
			
		||||
        Caption msg = TranslatableCaption.of("chat.plot_chat_format");
 | 
			
		||||
        Template msgTemplate;
 | 
			
		||||
        Template worldNameTemplate = Template.of("world", worldName);
 | 
			
		||||
        Template plotTemplate = Template.of("plot_id", id.toString());
 | 
			
		||||
        Template senderTemplate = Template.of("sender", sender);
 | 
			
		||||
        // If we do/don't want colour, we need to be careful about how to go about it, as players could attempt either <gold></gold> or &6 etc.
 | 
			
		||||
        // In both cases, we want to use a Component Template to ensure that the player cannot use any placeholders in their message on purpose
 | 
			
		||||
        //  or accidentally, as component templates are done at the end. We also need to deserialize from legacy color codes to a Component if
 | 
			
		||||
        //  allowing colour.
 | 
			
		||||
        TagResolver.Builder builder = TagResolver.builder();
 | 
			
		||||
        builder.tag("world", Tag.inserting(Component.text(worldName)));
 | 
			
		||||
        builder.tag("plot_id", Tag.inserting(Component.text(id.toString())));
 | 
			
		||||
        builder.tag("sender", Tag.inserting(Component.text(sender)));
 | 
			
		||||
        if (plotPlayer.hasPermission("plots.chat.color")) {
 | 
			
		||||
            msgTemplate = Template
 | 
			
		||||
                    .of(
 | 
			
		||||
                            "msg",
 | 
			
		||||
                            BukkitUtil.LEGACY_COMPONENT_SERIALIZER.deserialize(ChatColor.translateAlternateColorCodes(
 | 
			
		||||
                                    '&',
 | 
			
		||||
                                    message
 | 
			
		||||
                            ))
 | 
			
		||||
                    );
 | 
			
		||||
            builder.tag("msg", Tag.inserting(MiniMessage.miniMessage().deserialize(
 | 
			
		||||
                    message,
 | 
			
		||||
                    TagResolver.resolver(StandardTags.color(), StandardTags.gradient(),
 | 
			
		||||
                            StandardTags.rainbow(), StandardTags.decorations()
 | 
			
		||||
                    )
 | 
			
		||||
            )));
 | 
			
		||||
        } else {
 | 
			
		||||
            msgTemplate = Template.of("msg", BukkitUtil.MINI_MESSAGE.deserialize(
 | 
			
		||||
                    ChatColor.stripColor(BukkitUtil.LEGACY_COMPONENT_SERIALIZER.serialize(Component.text(message)))));
 | 
			
		||||
            builder.tag("msg", Tag.inserting(Component.text(message)));
 | 
			
		||||
        }
 | 
			
		||||
        for (PlotPlayer<?> receiver : plotRecipients) {
 | 
			
		||||
            receiver.sendMessage(msg, worldNameTemplate, msgTemplate, plotTemplate, senderTemplate);
 | 
			
		||||
            receiver.sendMessage(msg, builder.build());
 | 
			
		||||
        }
 | 
			
		||||
        if (!spies.isEmpty()) {
 | 
			
		||||
            Caption spymsg = TranslatableCaption.of("chat.plot_chat_spy_format");
 | 
			
		||||
            Template plotidTemplate = Template.of("plot_id", id.getX() + ";" + id.getY());
 | 
			
		||||
            Template spysenderTemplate = Template.of("sender", sender);
 | 
			
		||||
            Template spymessageTemplate = Template.of("msg", Component.text(message));
 | 
			
		||||
            for (PlotPlayer<?> player : spies) {
 | 
			
		||||
                player.sendMessage(spymsg, worldNameTemplate, plotidTemplate, spysenderTemplate, spymessageTemplate);
 | 
			
		||||
                player.sendMessage(spymsg, builder.tag("message", Tag.inserting(Component.text(message))).build());
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (Settings.Chat.LOG_PLOTCHAT_TO_CONSOLE) {
 | 
			
		||||
            Caption spymsg = TranslatableCaption.of("chat.plot_chat_spy_format");
 | 
			
		||||
            Template plotidTemplate = Template.of("plot_id", id.getX() + ";" + id.getY());
 | 
			
		||||
            Template spysenderTemplate = Template.of("sender", sender);
 | 
			
		||||
            Template spymessageTemplate = Template.of("msg", Component.text(message));
 | 
			
		||||
            ConsolePlayer.getConsole().sendMessage(spymsg, worldNameTemplate, plotidTemplate, spysenderTemplate,
 | 
			
		||||
                    spymessageTemplate
 | 
			
		||||
            ConsolePlayer.getConsole().sendMessage(
 | 
			
		||||
                    spymsg,
 | 
			
		||||
                    builder.tag("message", Tag.inserting(Component.text(message))).build()
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
@@ -945,7 +946,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            if (!pp.hasPermission(Permission.PERMISSION_ADMIN_INTERACT_ROAD)) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_INTERACT_ROAD))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_ADMIN_INTERACT_ROAD)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                cancelled = true;
 | 
			
		||||
            }
 | 
			
		||||
@@ -953,7 +957,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            if (!pp.hasPermission(Permission.PERMISSION_ADMIN_INTERACT_UNOWNED)) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_INTERACT_UNOWNED))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_ADMIN_INTERACT_UNOWNED)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                cancelled = true;
 | 
			
		||||
            }
 | 
			
		||||
@@ -963,7 +970,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                if (!pp.hasPermission(Permission.PERMISSION_ADMIN_INTERACT_OTHER)) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_INTERACT_OTHER))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_INTERACT_OTHER)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    cancelled = true;
 | 
			
		||||
                }
 | 
			
		||||
@@ -1002,7 +1012,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            )) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_INTERACT_ROAD))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_ADMIN_INTERACT_ROAD)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                e.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
@@ -1018,7 +1031,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                if (!pp.hasPermission("plots.admin.interact.unowned")) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_INTERACT_UNOWNED))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_INTERACT_UNOWNED)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    e.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
@@ -1033,7 +1049,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                if (!pp.hasPermission(Permission.PERMISSION_ADMIN_INTERACT_OTHER)) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_INTERACT_OTHER))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_INTERACT_OTHER)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    e.setCancelled(true);
 | 
			
		||||
                    plot.debug(pp.getName() + " could not interact with " + entity.getType()
 | 
			
		||||
@@ -1097,13 +1116,13 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
        Location location = BukkitUtil.adapt(block.getLocation());
 | 
			
		||||
        Action action = event.getAction();
 | 
			
		||||
        switch (action) {
 | 
			
		||||
            case PHYSICAL: {
 | 
			
		||||
            case PHYSICAL -> {
 | 
			
		||||
                eventType = PlayerBlockEventType.TRIGGER_PHYSICAL;
 | 
			
		||||
                blocktype1 = BukkitAdapter.asBlockType(block.getType());
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            //todo rearrange the right click code. it is all over the place.
 | 
			
		||||
            case RIGHT_CLICK_BLOCK: {
 | 
			
		||||
            case RIGHT_CLICK_BLOCK -> {
 | 
			
		||||
                Material blockType = block.getType();
 | 
			
		||||
                eventType = PlayerBlockEventType.INTERACT_BLOCK;
 | 
			
		||||
                blocktype1 = BukkitAdapter.asBlockType(block.getType());
 | 
			
		||||
@@ -1125,21 +1144,16 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
 | 
			
		||||
                // in the following, lb needs to have the material of the item in hand i.e. type
 | 
			
		||||
                switch (type.toString()) {
 | 
			
		||||
                    case "REDSTONE":
 | 
			
		||||
                    case "STRING":
 | 
			
		||||
                    case "PUMPKIN_SEEDS":
 | 
			
		||||
                    case "MELON_SEEDS":
 | 
			
		||||
                    case "COCOA_BEANS":
 | 
			
		||||
                    case "WHEAT_SEEDS":
 | 
			
		||||
                    case "BEETROOT_SEEDS":
 | 
			
		||||
                    case "SWEET_BERRIES":
 | 
			
		||||
                    case "GLOW_BERRIES":
 | 
			
		||||
                    case "REDSTONE", "STRING", "PUMPKIN_SEEDS", "MELON_SEEDS", "COCOA_BEANS", "WHEAT_SEEDS", "BEETROOT_SEEDS",
 | 
			
		||||
                            "SWEET_BERRIES", "GLOW_BERRIES" -> {
 | 
			
		||||
                        return;
 | 
			
		||||
                    default:
 | 
			
		||||
                    }
 | 
			
		||||
                    default -> {
 | 
			
		||||
                        //eventType = PlayerBlockEventType.PLACE_BLOCK;
 | 
			
		||||
                        if (type.isBlock()) {
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (PaperLib.isPaper()) {
 | 
			
		||||
                    if (MaterialTags.SPAWN_EGGS.isTagged(type) || Material.EGG.equals(type)) {
 | 
			
		||||
@@ -1160,7 +1174,7 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                    location = BukkitUtil.adapt(block.getRelative(event.getBlockFace()).getLocation());
 | 
			
		||||
                    eventType = PlayerBlockEventType.PLACE_MISC;
 | 
			
		||||
                }
 | 
			
		||||
                if (Tag.ITEMS_BOATS.isTagged(type) || MINECARTS.contains(type)) {
 | 
			
		||||
                if (org.bukkit.Tag.ITEMS_BOATS.isTagged(type) || MINECARTS.contains(type)) {
 | 
			
		||||
                    eventType = PlayerBlockEventType.PLACE_VEHICLE;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
@@ -1172,9 +1186,8 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                    eventType = PlayerBlockEventType.READ;
 | 
			
		||||
                    break;
 | 
			
		||||
                }
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            case LEFT_CLICK_BLOCK: {
 | 
			
		||||
            case LEFT_CLICK_BLOCK -> {
 | 
			
		||||
                Material blockType = block.getType();
 | 
			
		||||
 | 
			
		||||
                // todo: when the code above is rearranged, it would be great to beautify this as well.
 | 
			
		||||
@@ -1185,10 +1198,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
 | 
			
		||||
                eventType = PlayerBlockEventType.INTERACT_BLOCK;
 | 
			
		||||
                blocktype1 = BukkitAdapter.asBlockType(block.getType());
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
            default:
 | 
			
		||||
            default -> {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (this.worldEdit != null && pp.getAttribute("worldedit")) {
 | 
			
		||||
            if (event.getMaterial() == Material.getMaterial(this.worldEdit.getConfiguration().wandItem)) {
 | 
			
		||||
@@ -1260,7 +1273,7 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            }
 | 
			
		||||
            pp.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_ROAD))
 | 
			
		||||
                    TagResolver.resolver("node", Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_ROAD))
 | 
			
		||||
            );
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
        } else if (!plot.hasOwner()) {
 | 
			
		||||
@@ -1269,7 +1282,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            }
 | 
			
		||||
            pp.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_UNOWNED))
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "node",
 | 
			
		||||
                            Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_UNOWNED)
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
        } else if (!plot.isAdded(pp.getUUID())) {
 | 
			
		||||
@@ -1278,7 +1294,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            }
 | 
			
		||||
            pp.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_OTHER))
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "node",
 | 
			
		||||
                            Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_OTHER)
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
        } else if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot)) {
 | 
			
		||||
@@ -1325,7 +1344,7 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            }
 | 
			
		||||
            plotPlayer.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_ROAD))
 | 
			
		||||
                    TagResolver.resolver("node", Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_ROAD))
 | 
			
		||||
            );
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
        } else if (!plot.hasOwner()) {
 | 
			
		||||
@@ -1334,7 +1353,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            }
 | 
			
		||||
            plotPlayer.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_UNOWNED))
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "node",
 | 
			
		||||
                            Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_UNOWNED)
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
        } else if (!plot.isAdded(plotPlayer.getUUID())) {
 | 
			
		||||
@@ -1343,7 +1365,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            }
 | 
			
		||||
            plotPlayer.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_OTHER))
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "node",
 | 
			
		||||
                            Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_OTHER)
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
            event.setCancelled(true);
 | 
			
		||||
        } else if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot)) {
 | 
			
		||||
@@ -1375,7 +1400,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_ROAD)) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_ROAD))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_ROAD)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
@@ -1384,7 +1412,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_UNOWNED)) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_UNOWNED))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_UNOWNED)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
@@ -1395,7 +1426,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                    if (!pp.hasPermission(Permission.PERMISSION_ADMIN_BUILD_OTHER)) {
 | 
			
		||||
                        pp.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                                Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BUILD_OTHER))
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_ADMIN_BUILD_OTHER)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        event.setCancelled(true);
 | 
			
		||||
                    }
 | 
			
		||||
@@ -1424,7 +1458,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                if (!pp.hasPermission(Permission.PERMISSION_ADMIN_DESTROY_ROAD)) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_DESTROY_ROAD))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_DESTROY_ROAD)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
@@ -1432,7 +1469,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                if (!pp.hasPermission(Permission.PERMISSION_ADMIN_DESTROY_UNOWNED)) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_DESTROY_UNOWNED))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_DESTROY_UNOWNED)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
@@ -1443,7 +1483,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                if (!pp.hasPermission(Permission.PERMISSION_ADMIN_DESTROY_OTHER)) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_DESTROY_OTHER))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_DESTROY_OTHER)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                    plot.debug(p.getName()
 | 
			
		||||
@@ -1464,7 +1507,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                        if (!player.hasPermission(Permission.PERMISSION_ADMIN_DESTROY_UNOWNED)) {
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                                    Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_DESTROY_UNOWNED))
 | 
			
		||||
                                    TagResolver.resolver(
 | 
			
		||||
                                            "node",
 | 
			
		||||
                                            Tag.inserting(Permission.PERMISSION_ADMIN_DESTROY_UNOWNED)
 | 
			
		||||
                                    )
 | 
			
		||||
                            );
 | 
			
		||||
                            event.setCancelled(true);
 | 
			
		||||
                        }
 | 
			
		||||
@@ -1473,7 +1519,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                            if (!player.hasPermission(Permission.PERMISSION_ADMIN_DESTROY_OTHER)) {
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_DESTROY_OTHER))
 | 
			
		||||
                                        TagResolver.resolver(
 | 
			
		||||
                                                "node",
 | 
			
		||||
                                                Tag.inserting(Permission.PERMISSION_ADMIN_DESTROY_OTHER)
 | 
			
		||||
                                        )
 | 
			
		||||
                                );
 | 
			
		||||
                                event.setCancelled(true);
 | 
			
		||||
                                plot.debug(player.getName()
 | 
			
		||||
@@ -1505,7 +1554,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            if (!pp.hasPermission(Permission.PERMISSION_ADMIN_INTERACT_ROAD)) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_INTERACT_ROAD))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_ADMIN_INTERACT_ROAD)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
@@ -1513,7 +1565,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            if (!pp.hasPermission(Permission.PERMISSION_ADMIN_INTERACT_UNOWNED)) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_INTERACT_UNOWNED))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_ADMIN_INTERACT_UNOWNED)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
@@ -1571,7 +1626,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
            if (!pp.hasPermission(Permission.PERMISSION_ADMIN_INTERACT_OTHER)) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_INTERACT_OTHER))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_ADMIN_INTERACT_OTHER)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
            }
 | 
			
		||||
@@ -1595,7 +1653,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                )) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_DESTROY_VEHICLE_ROAD))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_DESTROY_VEHICLE_ROAD)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
                }
 | 
			
		||||
@@ -1604,7 +1665,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                    if (!pp.hasPermission(Permission.PERMISSION_ADMIN_DESTROY_VEHICLE_UNOWNED)) {
 | 
			
		||||
                        pp.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                                Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_DESTROY_VEHICLE_UNOWNED))
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_ADMIN_DESTROY_VEHICLE_UNOWNED)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        event.setCancelled(true);
 | 
			
		||||
                        return;
 | 
			
		||||
@@ -1618,7 +1682,10 @@ public class PlayerEventListener implements Listener {
 | 
			
		||||
                    if (!pp.hasPermission(Permission.PERMISSION_ADMIN_DESTROY_VEHICLE_OTHER)) {
 | 
			
		||||
                        pp.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                                Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_DESTROY_VEHICLE_OTHER))
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_ADMIN_DESTROY_VEHICLE_OTHER)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        event.setCancelled(true);
 | 
			
		||||
                        plot.debug(pp.getName()
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,8 @@ import com.plotsquared.core.plot.PlotHandler;
 | 
			
		||||
import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag;
 | 
			
		||||
import com.plotsquared.core.plot.world.PlotAreaManager;
 | 
			
		||||
import com.plotsquared.core.util.PlotFlagUtil;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.Tag;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
import org.bukkit.entity.LivingEntity;
 | 
			
		||||
import org.bukkit.entity.Player;
 | 
			
		||||
@@ -110,7 +111,10 @@ public class ProjectileEventListener implements Listener {
 | 
			
		||||
            )) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_PROJECTILE_ROAD))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_ADMIN_PROJECTILE_ROAD)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                entity.remove();
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
@@ -119,7 +123,10 @@ public class ProjectileEventListener implements Listener {
 | 
			
		||||
            if (!pp.hasPermission(Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED)) {
 | 
			
		||||
                pp.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                entity.remove();
 | 
			
		||||
                event.setCancelled(true);
 | 
			
		||||
@@ -129,7 +136,10 @@ public class ProjectileEventListener implements Listener {
 | 
			
		||||
                if (!pp.hasPermission(Permission.PERMISSION_ADMIN_PROJECTILE_OTHER)) {
 | 
			
		||||
                    pp.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_PROJECTILE_OTHER))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ADMIN_PROJECTILE_OTHER)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    entity.remove();
 | 
			
		||||
                    event.setCancelled(true);
 | 
			
		||||
 
 | 
			
		||||
@@ -1,63 +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.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";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 */
 | 
			
		||||
@@ -52,7 +52,7 @@ public class MVdWPlaceholders {
 | 
			
		||||
 | 
			
		||||
    @Subscribe
 | 
			
		||||
    public void onNewPlaceholder(final PlaceholderRegistry.@NonNull PlaceholderAddedEvent event) {
 | 
			
		||||
        this.addPlaceholder(event.getPlaceholder());
 | 
			
		||||
        this.addPlaceholder(event.placeholder());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void addPlaceholder(final @NonNull Placeholder placeholder) {
 | 
			
		||||
 
 | 
			
		||||
@@ -43,7 +43,7 @@ public class BukkitOfflinePlayer implements OfflinePlotPlayer {
 | 
			
		||||
     */
 | 
			
		||||
    public BukkitOfflinePlayer(
 | 
			
		||||
            final @NonNull OfflinePlayer player, final @NonNull
 | 
			
		||||
            PermissionHandler permissionHandler
 | 
			
		||||
    PermissionHandler permissionHandler
 | 
			
		||||
    ) {
 | 
			
		||||
        this.player = player;
 | 
			
		||||
        this.permissionProfile = permissionHandler.getPermissionProfile(this)
 | 
			
		||||
 
 | 
			
		||||
@@ -71,31 +71,11 @@ public class BukkitPlayer extends PlotPlayer<Player> {
 | 
			
		||||
     * @param eventDispatcher   EventDispatcher instance
 | 
			
		||||
     * @param player            Bukkit player instance
 | 
			
		||||
     * @param permissionHandler PermissionHandler instance
 | 
			
		||||
     *
 | 
			
		||||
     * @deprecated Please do not use this method. Instead use {@link BukkitUtil#adapt(Player)}, as it caches player objects.
 | 
			
		||||
     * This method will be made private in a future release.
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated(forRemoval = true, since = "TODO")
 | 
			
		||||
    public BukkitPlayer(
 | 
			
		||||
            final @NonNull PlotAreaManager plotAreaManager, final @NonNull EventDispatcher eventDispatcher,
 | 
			
		||||
            final @NonNull Player player, final @NonNull PermissionHandler permissionHandler
 | 
			
		||||
    ) {
 | 
			
		||||
        this(plotAreaManager, eventDispatcher, player, false, permissionHandler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @param plotAreaManager   PlotAreaManager instance
 | 
			
		||||
     * @param eventDispatcher   EventDispatcher instance
 | 
			
		||||
     * @param player            Bukkit player instance
 | 
			
		||||
     * @param permissionHandler PermissionHandler instance
 | 
			
		||||
     *
 | 
			
		||||
     * @deprecated Please do not use this method. Instead use {@link BukkitUtil#adapt(Player)}, as it caches player objects.
 | 
			
		||||
     * This method will be made private in a future release.
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated(forRemoval = true, since = "TODO")
 | 
			
		||||
    public BukkitPlayer(
 | 
			
		||||
            final @NonNull PlotAreaManager plotAreaManager, final @NonNull
 | 
			
		||||
            EventDispatcher eventDispatcher, final @NonNull Player player,
 | 
			
		||||
    BukkitPlayer(
 | 
			
		||||
            final @NonNull PlotAreaManager plotAreaManager,
 | 
			
		||||
            final @NonNull EventDispatcher eventDispatcher,
 | 
			
		||||
            final @NonNull Player player,
 | 
			
		||||
            final boolean realPlayer,
 | 
			
		||||
            final @NonNull PermissionHandler permissionHandler
 | 
			
		||||
    ) {
 | 
			
		||||
@@ -196,6 +176,10 @@ public class BukkitPlayer extends PlotPlayer<Player> {
 | 
			
		||||
            final Set<PermissionAttachmentInfo> effective = player.getEffectivePermissions();
 | 
			
		||||
            if (!effective.isEmpty()) {
 | 
			
		||||
                for (PermissionAttachmentInfo attach : effective) {
 | 
			
		||||
                    // Ignore all "false" permissions
 | 
			
		||||
                    if (!attach.getValue()) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    String permStr = attach.getPermission();
 | 
			
		||||
                    if (permStr.startsWith(stubPlus)) {
 | 
			
		||||
                        hasAny = true;
 | 
			
		||||
 
 | 
			
		||||
@@ -54,7 +54,6 @@ public class BukkitPlayerManager extends PlayerManager<BukkitPlayer, Player> {
 | 
			
		||||
 | 
			
		||||
    @NonNull
 | 
			
		||||
    @Override
 | 
			
		||||
    @SuppressWarnings("deprecation")
 | 
			
		||||
    public BukkitPlayer getPlayer(final @NonNull Player object) {
 | 
			
		||||
        if (object.getUniqueId().version() == 2) { // not a real player
 | 
			
		||||
            return new BukkitPlayer(this.plotAreaManager, this.eventDispatcher, object, false, this.permissionHandler);
 | 
			
		||||
@@ -66,13 +65,12 @@ public class BukkitPlayerManager extends PlayerManager<BukkitPlayer, Player> {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @SuppressWarnings("deprecation")
 | 
			
		||||
    public @NonNull BukkitPlayer createPlayer(final @NonNull UUID uuid) {
 | 
			
		||||
        final Player player = Bukkit.getPlayer(uuid);
 | 
			
		||||
        if (player == null || !player.isOnline()) {
 | 
			
		||||
            throw new NoSuchPlayerException(uuid);
 | 
			
		||||
        }
 | 
			
		||||
        return new BukkitPlayer(this.plotAreaManager, this.eventDispatcher, player, this.permissionHandler);
 | 
			
		||||
        return new BukkitPlayer(this.plotAreaManager, this.eventDispatcher, player, false, this.permissionHandler);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Nullable
 | 
			
		||||
 
 | 
			
		||||
@@ -239,9 +239,11 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator {
 | 
			
		||||
     * server's main thread.
 | 
			
		||||
     */
 | 
			
		||||
    private void processChunk(final @NonNull Chunk chunk) {
 | 
			
		||||
        /* Chunk#isLoaded does not necessarily return true shortly after PaperLib#getChunkAtAsync completes, but the chunk is
 | 
			
		||||
        still loaded.
 | 
			
		||||
        if (!chunk.isLoaded()) {
 | 
			
		||||
            throw new IllegalArgumentException(String.format("Chunk %d;%d is is not loaded", chunk.getX(), chunk.getZ()));
 | 
			
		||||
        }
 | 
			
		||||
            throw new IllegalArgumentException(String.format("Chunk %d;%d is is not loaded", chunk.getX(), chunk.getZ());
 | 
			
		||||
        }*/
 | 
			
		||||
        if (finished) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -270,7 +270,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
 | 
			
		||||
            if (getChunkObject() instanceof Chunk chunkObject) {
 | 
			
		||||
                existing = chunkObject.getBlock(x & 15, y, z & 15);
 | 
			
		||||
            } else {
 | 
			
		||||
                 existing = getBukkitWorld().getBlockAt(x, y, z);
 | 
			
		||||
                existing = getBukkitWorld().getBlockAt(x, y, z);
 | 
			
		||||
            }
 | 
			
		||||
            final BlockState existingBaseBlock = BukkitAdapter.adapt(existing.getBlockData());
 | 
			
		||||
            if (BukkitBlockUtil.get(existing).equals(existingBaseBlock) && existing.getBlockData().matches(blockData)) {
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,7 @@ import com.plotsquared.bukkit.util.BukkitBlockUtil;
 | 
			
		||||
import com.plotsquared.bukkit.util.BukkitUtil;
 | 
			
		||||
import com.plotsquared.core.location.ChunkWrapper;
 | 
			
		||||
import com.plotsquared.core.location.Location;
 | 
			
		||||
import com.plotsquared.core.queue.ScopedQueueCoordinator;
 | 
			
		||||
import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator;
 | 
			
		||||
import com.plotsquared.core.util.ChunkUtil;
 | 
			
		||||
import com.plotsquared.core.util.PatternUtil;
 | 
			
		||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
 | 
			
		||||
@@ -44,8 +44,11 @@ import org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Internal use only. Subject to changes at any time.
 | 
			
		||||
 */
 | 
			
		||||
@DoNotUse
 | 
			
		||||
public class GenChunk extends ScopedQueueCoordinator {
 | 
			
		||||
public class GenChunk extends ZeroedDelegateScopedQueueCoordinator {
 | 
			
		||||
 | 
			
		||||
    public final Biome[] biomes;
 | 
			
		||||
    public BlockState[][] result;
 | 
			
		||||
@@ -59,7 +62,6 @@ public class GenChunk extends ScopedQueueCoordinator {
 | 
			
		||||
    /**
 | 
			
		||||
     * @param minY minimum world Y, inclusive
 | 
			
		||||
     * @param maxY maximum world Y, inclusive
 | 
			
		||||
     *
 | 
			
		||||
     * @since 6.6.0
 | 
			
		||||
     */
 | 
			
		||||
    public GenChunk(int minY, int maxY) {
 | 
			
		||||
@@ -107,9 +109,9 @@ public class GenChunk extends ScopedQueueCoordinator {
 | 
			
		||||
     */
 | 
			
		||||
    public void setChunk(@NonNull ChunkWrapper wrap) {
 | 
			
		||||
        chunk = null;
 | 
			
		||||
        world = wrap.world;
 | 
			
		||||
        chunkX = wrap.x;
 | 
			
		||||
        chunkZ = wrap.z;
 | 
			
		||||
        world = wrap.world();
 | 
			
		||||
        chunkX = wrap.x();
 | 
			
		||||
        chunkZ = wrap.z();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,8 @@
 | 
			
		||||
 */
 | 
			
		||||
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.sk89q.jnbt.ByteTag;
 | 
			
		||||
import com.sk89q.jnbt.CompoundTag;
 | 
			
		||||
@@ -28,16 +30,22 @@ import com.sk89q.jnbt.Tag;
 | 
			
		||||
import com.sk89q.worldedit.blocks.BaseItemStack;
 | 
			
		||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
 | 
			
		||||
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.ChatColor;
 | 
			
		||||
import org.bukkit.DyeColor;
 | 
			
		||||
import org.bukkit.World;
 | 
			
		||||
import org.bukkit.block.Banner;
 | 
			
		||||
import org.bukkit.block.Block;
 | 
			
		||||
import org.bukkit.block.Container;
 | 
			
		||||
import org.bukkit.block.Sign;
 | 
			
		||||
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.inventory.Inventory;
 | 
			
		||||
import org.bukkit.inventory.InventoryHolder;
 | 
			
		||||
import org.bukkit.inventory.ItemStack;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		||||
 | 
			
		||||
@@ -46,20 +54,15 @@ import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Map.Entry;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
 | 
			
		||||
public class StateWrapper {
 | 
			
		||||
 | 
			
		||||
    public org.bukkit.block.BlockState state = null;
 | 
			
		||||
    public CompoundTag tag = null;
 | 
			
		||||
    public CompoundTag tag;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @deprecated in favour of using WE methods for obtaining NBT, specifically by obtaining a
 | 
			
		||||
     *         {@link com.sk89q.worldedit.world.block.BaseBlock} and then using {@link com.sk89q.worldedit.world.block.BaseBlock#getNbtData()}
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated(forRemoval = true, since = "6.9.0")
 | 
			
		||||
    public StateWrapper(org.bukkit.block.BlockState state) {
 | 
			
		||||
        this.state = state;
 | 
			
		||||
    }
 | 
			
		||||
    private boolean paperErrorTextureSent = false;
 | 
			
		||||
    private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + StateWrapper.class.getSimpleName());
 | 
			
		||||
 | 
			
		||||
    public StateWrapper(CompoundTag tag) {
 | 
			
		||||
        this.tag = tag;
 | 
			
		||||
@@ -237,15 +240,64 @@ public class StateWrapper {
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    String player = skullOwner.getString("Name");
 | 
			
		||||
                    if (player == null || player.isEmpty()) {
 | 
			
		||||
 | 
			
		||||
                    if (player != null && !player.isEmpty()) {
 | 
			
		||||
                        try {
 | 
			
		||||
                            skull.setOwningPlayer(Bukkit.getOfflinePlayer(player));
 | 
			
		||||
                            skull.update(true);
 | 
			
		||||
                        } catch (Exception e) {
 | 
			
		||||
                            e.printStackTrace();
 | 
			
		||||
                        }
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    final CompoundTag properties = (CompoundTag) skullOwner.getValue().get("Properties");
 | 
			
		||||
                    if (properties == null) {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    try {
 | 
			
		||||
                        skull.setOwningPlayer(Bukkit.getOfflinePlayer(player));
 | 
			
		||||
                        skull.update(true);
 | 
			
		||||
                    } catch (Exception e) {
 | 
			
		||||
                        e.printStackTrace();
 | 
			
		||||
                    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;
 | 
			
		||||
@@ -254,26 +306,6 @@ public class StateWrapper {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Get a CompoundTag of the contents of a block's inventory (chest, furnace, etc.).
 | 
			
		||||
     *
 | 
			
		||||
     * @deprecated in favour of using WorldEdit methods for obtaining NBT, specifically by obtaining a
 | 
			
		||||
     *         {@link com.sk89q.worldedit.world.block.BaseBlock} and then using {@link com.sk89q.worldedit.world.block.BaseBlock#getNbtData()}
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated(forRemoval = true, since = "6.9.0")
 | 
			
		||||
    public CompoundTag getTag() {
 | 
			
		||||
        if (this.tag != null) {
 | 
			
		||||
            return this.tag;
 | 
			
		||||
        }
 | 
			
		||||
        if (this.state instanceof InventoryHolder inv) {
 | 
			
		||||
            ItemStack[] contents = inv.getInventory().getContents();
 | 
			
		||||
            Map<String, Tag> values = new HashMap<>();
 | 
			
		||||
            values.put("Items", new ListTag(CompoundTag.class, serializeInventory(contents)));
 | 
			
		||||
            return new CompoundTag(values);
 | 
			
		||||
        }
 | 
			
		||||
        return null;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String getId() {
 | 
			
		||||
        String tileid = this.tag.getString("id").toLowerCase();
 | 
			
		||||
        if (tileid.startsWith("minecraft:")) {
 | 
			
		||||
 
 | 
			
		||||
@@ -42,7 +42,9 @@ import com.plotsquared.core.plot.flag.implementations.VehicleCapFlag;
 | 
			
		||||
import com.plotsquared.core.util.EntityUtil;
 | 
			
		||||
import com.plotsquared.core.util.entity.EntityCategories;
 | 
			
		||||
import com.sk89q.worldedit.bukkit.BukkitAdapter;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.bukkit.entity.Arrow;
 | 
			
		||||
import org.bukkit.entity.Creature;
 | 
			
		||||
import org.bukkit.entity.Entity;
 | 
			
		||||
@@ -179,7 +181,10 @@ public class BukkitEntityUtil {
 | 
			
		||||
                if (!plotPlayer.hasPermission(Permission.PERMISSION_ADMIN_DESTROY + "." + stub)) {
 | 
			
		||||
                    plotPlayer.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_ADMIN_DESTROY + "." + stub)
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Component.text(Permission.PERMISSION_ADMIN_DESTROY + "." + stub))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -191,7 +196,10 @@ public class BukkitEntityUtil {
 | 
			
		||||
                if (!plotPlayer.hasPermission(Permission.PERMISSION_ADMIN_DESTROY + "." + stub)) {
 | 
			
		||||
                    plotPlayer.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_ADMIN_DESTROY + "." + stub)
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Component.text(Permission.PERMISSION_ADMIN_DESTROY + "." + stub))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    if (plot != null) {
 | 
			
		||||
                        plot.debug(player.getName()
 | 
			
		||||
@@ -212,7 +220,10 @@ public class BukkitEntityUtil {
 | 
			
		||||
                if (!plotPlayer.hasPermission(Permission.PERMISSION_ADMIN_PVE + "." + stub)) {
 | 
			
		||||
                    plotPlayer.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_ADMIN_PVE + "." + stub)
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Component.text(Permission.PERMISSION_ADMIN_PVE + "." + stub))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    if (plot != null) {
 | 
			
		||||
                        plot.debug(player.getName() + " could not attack " + entityType
 | 
			
		||||
@@ -233,7 +244,10 @@ public class BukkitEntityUtil {
 | 
			
		||||
                if (!plotPlayer.hasPermission(Permission.PERMISSION_ADMIN_PVE + "." + stub)) {
 | 
			
		||||
                    plotPlayer.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_ADMIN_PVE + "." + stub)
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Component.text(Permission.PERMISSION_ADMIN_PVE + "." + stub))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    if (plot != null) {
 | 
			
		||||
                        plot.debug(player.getName() + " could not attack " + entityType
 | 
			
		||||
@@ -246,7 +260,10 @@ public class BukkitEntityUtil {
 | 
			
		||||
                    if (!plot.getFlag(PvpFlag.class) && !plotPlayer.hasPermission(Permission.PERMISSION_ADMIN_PVP + "." + stub)) {
 | 
			
		||||
                        plotPlayer.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                                Template.of("node", Permission.PERMISSION_ADMIN_PVP + "." + stub)
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Component.text(Permission.PERMISSION_ADMIN_PVP + "." + stub))
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        plot.debug(player.getName() + " could not attack " + entityType
 | 
			
		||||
                                + " because pve = false");
 | 
			
		||||
@@ -260,7 +277,10 @@ public class BukkitEntityUtil {
 | 
			
		||||
                if (!plotPlayer.hasPermission(Permission.PERMISSION_ADMIN_PVP + "." + stub)) {
 | 
			
		||||
                    plotPlayer.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_ADMIN_PVP + "." + stub)
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Component.text(Permission.PERMISSION_ADMIN_PVP + "." + stub))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -277,7 +297,10 @@ public class BukkitEntityUtil {
 | 
			
		||||
                if (!plotPlayer.hasPermission(Permission.PERMISSION_ADMIN_PVE + "." + stub)) {
 | 
			
		||||
                    plotPlayer.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_ADMIN_PVE + "." + stub)
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Component.text(Permission.PERMISSION_ADMIN_PVE + "." + stub))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    if (plot != null) {
 | 
			
		||||
                        plot.debug(player.getName() + " could not attack " + entityType
 | 
			
		||||
@@ -299,7 +322,10 @@ public class BukkitEntityUtil {
 | 
			
		||||
                if (!plotPlayer.hasPermission(Permission.PERMISSION_ADMIN_PVE + "." + stub)) {
 | 
			
		||||
                    plotPlayer.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission_event"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_ADMIN_PVE + "." + stub)
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Component.text(Permission.PERMISSION_ADMIN_PVE + "." + stub))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    if (plot != null) {
 | 
			
		||||
                        plot.debug(player.getName() + " could not attack " + entityType
 | 
			
		||||
 
 | 
			
		||||
@@ -56,7 +56,7 @@ public class BukkitInventoryUtil extends InventoryUtil {
 | 
			
		||||
        ItemMeta meta = null;
 | 
			
		||||
        if (item.getName() != null) {
 | 
			
		||||
            meta = stack.getItemMeta();
 | 
			
		||||
            Component nameComponent = BukkitUtil.MINI_MESSAGE.parse(item.getName());
 | 
			
		||||
            Component nameComponent = BukkitUtil.MINI_MESSAGE.deserialize(item.getName());
 | 
			
		||||
            meta.setDisplayName(BukkitUtil.LEGACY_COMPONENT_SERIALIZER.serialize(nameComponent));
 | 
			
		||||
        }
 | 
			
		||||
        if (item.getLore() != null) {
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ import com.plotsquared.core.plot.PlotArea;
 | 
			
		||||
import com.plotsquared.core.plot.PlotManager;
 | 
			
		||||
import com.plotsquared.core.queue.GlobalBlockQueue;
 | 
			
		||||
import com.plotsquared.core.queue.QueueCoordinator;
 | 
			
		||||
import com.plotsquared.core.queue.ScopedQueueCoordinator;
 | 
			
		||||
import com.plotsquared.core.queue.ZeroedDelegateScopedQueueCoordinator;
 | 
			
		||||
import com.plotsquared.core.util.ChunkManager;
 | 
			
		||||
import com.plotsquared.core.util.RegionManager;
 | 
			
		||||
import com.plotsquared.core.util.WorldUtil;
 | 
			
		||||
@@ -70,7 +70,7 @@ public class BukkitRegionManager extends RegionManager {
 | 
			
		||||
    @Inject
 | 
			
		||||
    public BukkitRegionManager(
 | 
			
		||||
            @NonNull WorldUtil worldUtil, @NonNull GlobalBlockQueue blockQueue, @NonNull
 | 
			
		||||
            ProgressSubscriberFactory subscriberFactory
 | 
			
		||||
    ProgressSubscriberFactory subscriberFactory
 | 
			
		||||
    ) {
 | 
			
		||||
        super(worldUtil, blockQueue, subscriberFactory);
 | 
			
		||||
        this.blockQueue = blockQueue;
 | 
			
		||||
@@ -257,9 +257,9 @@ public class BukkitRegionManager extends RegionManager {
 | 
			
		||||
            map.saveEntitiesOut(Bukkit.getWorld(world.getName()).getChunkAt(x, z), currentPlotClear);
 | 
			
		||||
            AugmentedUtils.bypass(
 | 
			
		||||
                    ignoreAugment,
 | 
			
		||||
                    () -> ChunkManager.setChunkInPlotArea(null, new RunnableVal<ScopedQueueCoordinator>() {
 | 
			
		||||
                    () -> ChunkManager.setChunkInPlotArea(null, new RunnableVal<ZeroedDelegateScopedQueueCoordinator>() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run(ScopedQueueCoordinator value) {
 | 
			
		||||
                        public void run(ZeroedDelegateScopedQueueCoordinator value) {
 | 
			
		||||
                            Location min = value.getMin();
 | 
			
		||||
                            int bx = min.getX();
 | 
			
		||||
                            int bz = min.getZ();
 | 
			
		||||
 
 | 
			
		||||
@@ -124,7 +124,7 @@ public class BukkitSetupUtils extends SetupUtils {
 | 
			
		||||
    public String setupWorld(PlotAreaBuilder builder) {
 | 
			
		||||
        this.updateGenerators(false);
 | 
			
		||||
        ConfigurationNode[] steps = builder.settingsNodesWrapper() == null ?
 | 
			
		||||
                new ConfigurationNode[0] : builder.settingsNodesWrapper().getSettingsNodes();
 | 
			
		||||
                new ConfigurationNode[0] : builder.settingsNodesWrapper().settingsNodes();
 | 
			
		||||
        String world = builder.worldName();
 | 
			
		||||
        PlotAreaType type = builder.plotAreaType();
 | 
			
		||||
        String worldPath = "worlds." + builder.worldName();
 | 
			
		||||
 
 | 
			
		||||
@@ -45,7 +45,7 @@ import com.sk89q.worldedit.world.block.BlockTypes;
 | 
			
		||||
import io.papermc.lib.PaperLib;
 | 
			
		||||
import net.kyori.adventure.platform.bukkit.BukkitAudiences;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.MiniMessage;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
 | 
			
		||||
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
 | 
			
		||||
import org.apache.logging.log4j.LogManager;
 | 
			
		||||
import org.apache.logging.log4j.Logger;
 | 
			
		||||
@@ -333,7 +333,7 @@ public class BukkitUtil extends WorldUtil {
 | 
			
		||||
    @SuppressWarnings("deprecation")
 | 
			
		||||
    public void setSign(
 | 
			
		||||
            final @NonNull Location location, final @NonNull Caption[] lines,
 | 
			
		||||
            final @NonNull Template... replacements
 | 
			
		||||
            final @NonNull TagResolver... replacements
 | 
			
		||||
    ) {
 | 
			
		||||
        ensureLoaded(location.getWorldName(), location.getX(), location.getZ(), chunk -> {
 | 
			
		||||
            PlotArea area = location.getPlotArea();
 | 
			
		||||
@@ -366,8 +366,9 @@ public class BukkitUtil extends WorldUtil {
 | 
			
		||||
            final org.bukkit.block.BlockState blockstate = block.getState();
 | 
			
		||||
            if (blockstate instanceof final Sign sign) {
 | 
			
		||||
                for (int i = 0; i < lines.length; i++) {
 | 
			
		||||
                    sign.setLine(i, LEGACY_COMPONENT_SERIALIZER
 | 
			
		||||
                            .serialize(MINI_MESSAGE.parse(lines[i].getComponent(LocaleHolder.console()), replacements)));
 | 
			
		||||
                    sign.setLine(i, LEGACY_COMPONENT_SERIALIZER.serialize(
 | 
			
		||||
                            MINI_MESSAGE.deserialize(lines[i].getComponent(LocaleHolder.console()), replacements)
 | 
			
		||||
                    ));
 | 
			
		||||
                }
 | 
			
		||||
                sign.update(true, false);
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -132,14 +132,6 @@ public class BukkitWorld implements World<org.bukkit.World> {
 | 
			
		||||
        return world.hashCode();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @deprecated This method is not meant to be invoked or overridden, with no replacement.
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated(forRemoval = true, since = "6.6.0")
 | 
			
		||||
    protected boolean canEqual(final Object other) {
 | 
			
		||||
        return other instanceof BukkitWorld;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public String toString() {
 | 
			
		||||
        return "BukkitWorld(world=" + this.world + ")";
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -0,0 +1,72 @@
 | 
			
		||||
/*
 | 
			
		||||
 * 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.util;
 | 
			
		||||
 | 
			
		||||
import com.intellectualsites.annotations.NotPublic;
 | 
			
		||||
import com.plotsquared.core.PlotSquared;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.nio.file.Files;
 | 
			
		||||
import java.nio.file.Path;
 | 
			
		||||
import java.nio.file.Paths;
 | 
			
		||||
import java.util.stream.Stream;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * This is a helper class which replaces older syntax no longer supported by MiniMessage with replacements in messages_%.json.
 | 
			
		||||
 * MiniMessage changed the syntax between major releases. To warrant a smooth upgrade, we attempt to replace any occurrences
 | 
			
		||||
 * while loading PlotSquared.
 | 
			
		||||
 *
 | 
			
		||||
 * @since 7.0.0
 | 
			
		||||
 */
 | 
			
		||||
@NotPublic
 | 
			
		||||
public class TranslationUpdateManager {
 | 
			
		||||
 | 
			
		||||
    public static void upgradeTranslationFile() throws IOException {
 | 
			
		||||
        String suggestCommand = "suggest_command";
 | 
			
		||||
        String suggestCommandReplacement = "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()))) {
 | 
			
		||||
            paths
 | 
			
		||||
                    .filter(Files::isRegularFile)
 | 
			
		||||
                    .filter(p -> p.getFileName().toString().matches("messages_[a-z]{2}\\.json"))
 | 
			
		||||
                    .forEach(p -> {
 | 
			
		||||
                        replaceInFile(p, suggestCommand, suggestCommandReplacement);
 | 
			
		||||
                        replaceInFile(p, minHeight, minheightReplacement);
 | 
			
		||||
                        replaceInFile(p, maxHeight, maxheightReplacement);
 | 
			
		||||
                    });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static void replaceInFile(Path path, String searchText, String replacementText) {
 | 
			
		||||
        try {
 | 
			
		||||
            String content = Files.readString(path);
 | 
			
		||||
            if (content.contains(searchText)) {
 | 
			
		||||
                content = content.replaceAll(searchText, replacementText);
 | 
			
		||||
                Files.writeString(path, content);
 | 
			
		||||
            }
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            e.printStackTrace();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -54,7 +54,8 @@ public class UpdateUtility implements Listener {
 | 
			
		||||
        internalVersion = PlotSquared.get().getVersion();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @SuppressWarnings({"deprecation", "DefaultCharset"}) // Suppress Json deprecation, we can't use features from gson 2.8.1 and newer yet
 | 
			
		||||
    @SuppressWarnings({"deprecation", "DefaultCharset"})
 | 
			
		||||
    // Suppress Json deprecation, we can't use features from gson 2.8.1 and newer yet
 | 
			
		||||
    public void updateChecker() {
 | 
			
		||||
        task = Bukkit.getScheduler().runTaskTimerAsynchronously(this.javaPlugin, () -> {
 | 
			
		||||
            try {
 | 
			
		||||
 
 | 
			
		||||
@@ -94,11 +94,6 @@ public class FaweRegionManager extends BukkitRegionManager {
 | 
			
		||||
        delegate.swap(pos1, pos2, swapPos, whenDone);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setBiome(CuboidRegion region, int extendBiome, BiomeType biome, String world, Runnable whenDone) {
 | 
			
		||||
        delegate.setBiome(region, extendBiome, biome, world, whenDone);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void setBiome(CuboidRegion region, int extendBiome, BiomeType biome, PlotArea area, Runnable whenDone) {
 | 
			
		||||
        delegate.setBiome(region, extendBiome, biome, area.getWorldName(), whenDone);
 | 
			
		||||
 
 | 
			
		||||
@@ -111,8 +111,8 @@ public class SQLiteUUIDService implements UUIDService, Consumer<List<UUIDMapping
 | 
			
		||||
        try (final PreparedStatement statement = getConnection()
 | 
			
		||||
                .prepareStatement("INSERT OR REPLACE INTO `usercache` (`uuid`, `username`) VALUES(?, ?)")) {
 | 
			
		||||
            for (final UUIDMapping mapping : uuidWrappers) {
 | 
			
		||||
                statement.setString(1, mapping.getUuid().toString());
 | 
			
		||||
                statement.setString(2, mapping.getUsername());
 | 
			
		||||
                statement.setString(1, mapping.uuid().toString());
 | 
			
		||||
                statement.setString(2, mapping.username());
 | 
			
		||||
                statement.executeUpdate();
 | 
			
		||||
            }
 | 
			
		||||
        } catch (SQLException e) {
 | 
			
		||||
 
 | 
			
		||||
@@ -4,16 +4,16 @@ api-version: "1.13"
 | 
			
		||||
version: "${version}"
 | 
			
		||||
load: STARTUP
 | 
			
		||||
description: "Easy, yet powerful Plot World generation and management."
 | 
			
		||||
authors: [Citymonstret, Empire92, MattBDev, dordsor21, NotMyFault, SirYwell]
 | 
			
		||||
authors: [ Citymonstret, Empire92, MattBDev, dordsor21, NotMyFault, SirYwell ]
 | 
			
		||||
website: https://www.spigotmc.org/resources/77506/
 | 
			
		||||
softdepend: [Vault, PlaceholderAPI, Essentials, LuckPerms, BungeePerms, MVdWPlaceholderAPI]
 | 
			
		||||
loadbefore: [MultiWorld, Multiverse-Core]
 | 
			
		||||
depend: [WorldEdit]
 | 
			
		||||
softdepend: [ Vault, PlaceholderAPI, Essentials, LuckPerms, BungeePerms, MVdWPlaceholderAPI ]
 | 
			
		||||
loadbefore: [ MultiWorld, Multiverse-Core ]
 | 
			
		||||
depend: [ WorldEdit ]
 | 
			
		||||
database: false
 | 
			
		||||
commands:
 | 
			
		||||
  plots:
 | 
			
		||||
    description: Plot command.
 | 
			
		||||
    aliases: [p,plot,ps,plotsquared,p2,2,plotme]
 | 
			
		||||
    aliases: [ p,plot,ps,plotsquared,p2,2,plotme ]
 | 
			
		||||
    permission: plots.use
 | 
			
		||||
    permission-message: "You are lacking the permission node 'plots.use'"
 | 
			
		||||
permissions:
 | 
			
		||||
 
 | 
			
		||||
@@ -23,13 +23,13 @@ include:
 | 
			
		||||
Examples of unacceptable behavior by participants include:
 | 
			
		||||
 | 
			
		||||
* The use of sexualized language or imagery and unwelcome sexual attention or
 | 
			
		||||
 advances
 | 
			
		||||
  advances
 | 
			
		||||
* Trolling, insulting/derogatory comments, and personal or political attacks
 | 
			
		||||
* Public or private harassment
 | 
			
		||||
* Publishing others' private information, such as a physical or electronic
 | 
			
		||||
 address, without explicit permission
 | 
			
		||||
  address, without explicit permission
 | 
			
		||||
* Other conduct which could reasonably be considered inappropriate in a
 | 
			
		||||
 professional setting
 | 
			
		||||
  professional setting
 | 
			
		||||
 | 
			
		||||
## Our Responsibilities
 | 
			
		||||
 | 
			
		||||
@@ -55,7 +55,7 @@ further defined and clarified by project maintainers.
 | 
			
		||||
## Enforcement
 | 
			
		||||
 | 
			
		||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
 | 
			
		||||
reported by contacting the project team at contact@intellectualsites.com. All
 | 
			
		||||
reported by contacting the project team at contact<at>intellectualsites.com. All
 | 
			
		||||
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
 | 
			
		||||
obligated to maintain confidentiality with regard to the reporter of an incident.
 | 
			
		||||
 
 | 
			
		||||
@@ -68,7 +68,8 @@ tasks {
 | 
			
		||||
        val isRelease = if (rootProject.version.toString().endsWith("-SNAPSHOT")) "TODO" else rootProject.version.toString()
 | 
			
		||||
        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://jd.adventure.kyori.net/api/4.9.3/")
 | 
			
		||||
        opt.links("https://jd.advntr.dev/api/4.14.0/")
 | 
			
		||||
        opt.links("https://jd.advntr.dev/text-minimessage/4.14.0/")
 | 
			
		||||
        opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/")
 | 
			
		||||
        opt.links("https://checkerframework.org/api/")
 | 
			
		||||
        opt.links("https://javadoc.io/doc/com.intellectualsites.informative-annotations/informative-annotations/latest/")
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,7 @@ import com.plotsquared.core.util.ChunkManager;
 | 
			
		||||
import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import com.plotsquared.core.util.SchematicHandler;
 | 
			
		||||
import com.plotsquared.core.util.query.PlotQuery;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
 | 
			
		||||
@@ -145,7 +145,7 @@ public class PlotAPI {
 | 
			
		||||
     */
 | 
			
		||||
    public void sendConsoleMessage(
 | 
			
		||||
            final @NonNull String message,
 | 
			
		||||
            final @NonNull Template @NonNull ... replacements
 | 
			
		||||
            final @NonNull TagResolver @NonNull ... replacements
 | 
			
		||||
    ) {
 | 
			
		||||
        ConsolePlayer.getConsole().sendMessage(StaticCaption.of(message), replacements);
 | 
			
		||||
    }
 | 
			
		||||
@@ -158,7 +158,7 @@ public class PlotAPI {
 | 
			
		||||
     */
 | 
			
		||||
    public void sendConsoleMessage(
 | 
			
		||||
            final @NonNull Caption caption,
 | 
			
		||||
            final @NonNull Template @NonNull ... replacements
 | 
			
		||||
            final @NonNull TagResolver @NonNull ... replacements
 | 
			
		||||
    ) {
 | 
			
		||||
        ConsolePlayer.getConsole().sendMessage(caption, replacements);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -270,7 +270,11 @@ public class PlotSquared {
 | 
			
		||||
            captionMap = this.captionLoader.loadAll(this.platform.getDirectory().toPath().resolve("lang"));
 | 
			
		||||
        } else {
 | 
			
		||||
            String fileName = "messages_" + Settings.Enabled_Components.DEFAULT_LOCALE + ".json";
 | 
			
		||||
            captionMap = this.captionLoader.loadOrCreateSingle(this.platform.getDirectory().toPath().resolve("lang").resolve(fileName));
 | 
			
		||||
            captionMap = this.captionLoader.loadOrCreateSingle(this.platform
 | 
			
		||||
                    .getDirectory()
 | 
			
		||||
                    .toPath()
 | 
			
		||||
                    .resolve("lang")
 | 
			
		||||
                    .resolve(fileName));
 | 
			
		||||
        }
 | 
			
		||||
        this.captionMaps.put(TranslatableCaption.DEFAULT_NAMESPACE, captionMap);
 | 
			
		||||
        LOGGER.info(
 | 
			
		||||
@@ -790,7 +794,9 @@ public class PlotSquared {
 | 
			
		||||
        if (world.equals("CheckingPlotSquaredGenerator")) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        this.getPlotAreaManager().addWorld(world);
 | 
			
		||||
        if (!this.getPlotAreaManager().addWorld(world)) {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        Set<String> worlds;
 | 
			
		||||
        if (this.worldConfiguration.contains("worlds")) {
 | 
			
		||||
            worlds = this.worldConfiguration.getConfigurationSection("worlds").getKeys(false);
 | 
			
		||||
@@ -1009,7 +1015,7 @@ public class PlotSquared {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Setup the configuration for a plot world based on world arguments.
 | 
			
		||||
     *
 | 
			
		||||
     * <p>
 | 
			
		||||
     *
 | 
			
		||||
     * <i>e.g. /mv create <world> normal -g PlotSquared:<args></i>
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -200,7 +200,7 @@ public class PlayerBackupProfile implements BackupProfile {
 | 
			
		||||
                                    if (value) {
 | 
			
		||||
                                        future.complete(null);
 | 
			
		||||
                                    } else {
 | 
			
		||||
                                        future.completeExceptionally(new RuntimeException(MINI_MESSAGE.stripTokens(
 | 
			
		||||
                                        future.completeExceptionally(new RuntimeException(MINI_MESSAGE.escapeTags(
 | 
			
		||||
                                                TranslatableCaption
 | 
			
		||||
                                                        .of("schematics.schematic_paste_failed")
 | 
			
		||||
                                                        .getComponent(ConsolePlayer.getConsole()))));
 | 
			
		||||
 
 | 
			
		||||
@@ -24,13 +24,14 @@ import com.google.inject.Inject;
 | 
			
		||||
import com.google.inject.Singleton;
 | 
			
		||||
import com.plotsquared.core.PlotSquared;
 | 
			
		||||
import com.plotsquared.core.configuration.Settings;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.Templates;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
 | 
			
		||||
import com.plotsquared.core.inject.factory.PlayerBackupProfileFactory;
 | 
			
		||||
import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import com.plotsquared.core.plot.Plot;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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 org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
 | 
			
		||||
@@ -100,7 +101,7 @@ public class SimpleBackupManager implements BackupManager {
 | 
			
		||||
            if (player != null) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("backups.backup_automatic_started"),
 | 
			
		||||
                        Template.of("plot", plot.getId().toString())
 | 
			
		||||
                        TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString())))
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            profile.createBackup().whenComplete((backup, throwable) -> {
 | 
			
		||||
@@ -108,7 +109,7 @@ public class SimpleBackupManager implements BackupManager {
 | 
			
		||||
                    if (player != null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("backups.backup_automatic_failure"),
 | 
			
		||||
                                Templates.of("reason", throwable.getMessage())
 | 
			
		||||
                                TagResolver.resolver("reason", Tag.inserting(Component.text(throwable.getMessage())))
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    throwable.printStackTrace();
 | 
			
		||||
@@ -135,13 +136,9 @@ public class SimpleBackupManager implements BackupManager {
 | 
			
		||||
        return this.backupLimit;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private static final class PlotCacheKey {
 | 
			
		||||
 | 
			
		||||
        private final Plot plot;
 | 
			
		||||
 | 
			
		||||
        private PlotCacheKey(Plot plot) {
 | 
			
		||||
            this.plot = plot;
 | 
			
		||||
        }
 | 
			
		||||
    private record PlotCacheKey(
 | 
			
		||||
            Plot plot
 | 
			
		||||
    ) {
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public boolean equals(final Object o) {
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,9 @@ 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.minimessage.Template;
 | 
			
		||||
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;
 | 
			
		||||
@@ -71,7 +73,7 @@ public class Add extends Command {
 | 
			
		||||
        checkTrue(
 | 
			
		||||
                args.length == 1,
 | 
			
		||||
                TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                Template.of("value", "/plot add <player | *>")
 | 
			
		||||
                TagResolver.resolver("value", Tag.inserting(Component.text("/plot add <player | *>")))
 | 
			
		||||
        );
 | 
			
		||||
        final CompletableFuture<Boolean> future = new CompletableFuture<>();
 | 
			
		||||
        PlayerManager.getUUIDsFromString(args[0], (uuids, throwable) -> {
 | 
			
		||||
@@ -81,7 +83,7 @@ public class Add extends Command {
 | 
			
		||||
                } else {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                            Template.of("value", args[0])
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text(args[0])))
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                future.completeExceptionally(throwable);
 | 
			
		||||
@@ -89,7 +91,7 @@ public class Add extends Command {
 | 
			
		||||
            } else {
 | 
			
		||||
                try {
 | 
			
		||||
                    checkTrue(!uuids.isEmpty(), TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                            Template.of("value", args[0])
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text(args[0])))
 | 
			
		||||
                    );
 | 
			
		||||
                    Iterator<UUID> iterator = uuids.iterator();
 | 
			
		||||
                    int size = plot.getTrusted().size() + plot.getMembers().size();
 | 
			
		||||
@@ -99,7 +101,9 @@ public class Add extends Command {
 | 
			
		||||
                                Permission.PERMISSION_ADMIN_COMMAND_TRUST))) {
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                                    Template.of("value", PlayerManager.resolveName(uuid).getComponent(player))
 | 
			
		||||
                                    TagResolver.resolver("value", Tag.inserting(
 | 
			
		||||
                                            PlayerManager.resolveName(uuid).toComponent(player)
 | 
			
		||||
                                    ))
 | 
			
		||||
                            );
 | 
			
		||||
                            iterator.remove();
 | 
			
		||||
                            continue;
 | 
			
		||||
@@ -107,7 +111,9 @@ public class Add extends Command {
 | 
			
		||||
                        if (plot.isOwner(uuid)) {
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("member.already_added"),
 | 
			
		||||
                                    Template.of("player", PlayerManager.resolveName(uuid).getComponent(player))
 | 
			
		||||
                                    TagResolver.resolver("player", Tag.inserting(
 | 
			
		||||
                                            PlayerManager.resolveName(uuid).toComponent(player)
 | 
			
		||||
                                    ))
 | 
			
		||||
                            );
 | 
			
		||||
                            iterator.remove();
 | 
			
		||||
                            continue;
 | 
			
		||||
@@ -115,7 +121,9 @@ public class Add extends Command {
 | 
			
		||||
                        if (plot.getMembers().contains(uuid)) {
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("member.already_added"),
 | 
			
		||||
                                    Template.of("player", PlayerManager.resolveName(uuid).getComponent(player))
 | 
			
		||||
                                    TagResolver.resolver("player", Tag.inserting(
 | 
			
		||||
                                            PlayerManager.resolveName(uuid).toComponent(player)
 | 
			
		||||
                                    ))
 | 
			
		||||
                            );
 | 
			
		||||
                            iterator.remove();
 | 
			
		||||
                            continue;
 | 
			
		||||
@@ -128,7 +136,7 @@ public class Add extends Command {
 | 
			
		||||
                    if (localAddSize >= maxAddSize) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("members.plot_max_members_added"),
 | 
			
		||||
                                Template.of("amount", String.valueOf(localAddSize))
 | 
			
		||||
                                TagResolver.resolver("amount", Tag.inserting(Component.text(localAddSize)))
 | 
			
		||||
                        );
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,9 @@ 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.minimessage.Template;
 | 
			
		||||
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;
 | 
			
		||||
@@ -91,7 +93,10 @@ public class Alias extends SubCommand {
 | 
			
		||||
                } else {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ALIAS_SET))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ALIAS_SET)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -107,7 +112,10 @@ public class Alias extends SubCommand {
 | 
			
		||||
                } else {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_ALIAS_REMOVE))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_ALIAS_REMOVE)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -148,13 +156,16 @@ public class Alias extends SubCommand {
 | 
			
		||||
                    .anyMatch()) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("alias.alias_is_taken"),
 | 
			
		||||
                        Template.of("alias", alias)
 | 
			
		||||
                        TagResolver.resolver("alias", Tag.inserting(Component.text(alias)))
 | 
			
		||||
                );
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            if (Settings.UUID.OFFLINE) {
 | 
			
		||||
                plot.setAlias(alias);
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("alias.alias_set_to"), Template.of("alias", 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) -> {
 | 
			
		||||
@@ -163,13 +174,13 @@ public class Alias extends SubCommand {
 | 
			
		||||
                } else if (uuid != null) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("alias.alias_is_taken"),
 | 
			
		||||
                            Template.of("alias", alias)
 | 
			
		||||
                            TagResolver.resolver("alias", Tag.inserting(Component.text(alias)))
 | 
			
		||||
                    );
 | 
			
		||||
                } else {
 | 
			
		||||
                    plot.setAlias(alias);
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("alias.alias_set_to"),
 | 
			
		||||
                            Template.of("alias", alias)
 | 
			
		||||
                            TagResolver.resolver("alias", Tag.inserting(Component.text(alias)))
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            }));
 | 
			
		||||
@@ -181,7 +192,7 @@ public class Alias extends SubCommand {
 | 
			
		||||
        if (!plot.getAlias().isEmpty()) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("alias.alias_removed"),
 | 
			
		||||
                    Template.of("alias", alias)
 | 
			
		||||
                    TagResolver.resolver("alias", Tag.inserting(Component.text(alias)))
 | 
			
		||||
            );
 | 
			
		||||
        } else {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,6 @@ import com.plotsquared.core.configuration.ConfigurationSection;
 | 
			
		||||
import com.plotsquared.core.configuration.ConfigurationUtil;
 | 
			
		||||
import com.plotsquared.core.configuration.Settings;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.CaptionHolder;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.Templates;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
 | 
			
		||||
import com.plotsquared.core.configuration.file.YamlConfiguration;
 | 
			
		||||
import com.plotsquared.core.events.TeleportCause;
 | 
			
		||||
@@ -56,6 +55,7 @@ import com.plotsquared.core.util.TabCompletions;
 | 
			
		||||
import com.plotsquared.core.util.WorldUtil;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal3;
 | 
			
		||||
import com.sk89q.worldedit.EditSession;
 | 
			
		||||
import com.sk89q.worldedit.EditSessionBuilder;
 | 
			
		||||
import com.sk89q.worldedit.LocalSession;
 | 
			
		||||
import com.sk89q.worldedit.WorldEdit;
 | 
			
		||||
import com.sk89q.worldedit.entity.Player;
 | 
			
		||||
@@ -68,7 +68,9 @@ import com.sk89q.worldedit.math.BlockVector3;
 | 
			
		||||
import com.sk89q.worldedit.regions.CuboidRegion;
 | 
			
		||||
import com.sk89q.worldedit.regions.Region;
 | 
			
		||||
import com.sk89q.worldedit.world.World;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.io.File;
 | 
			
		||||
@@ -140,14 +142,17 @@ public class Area extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_AREA_CREATE)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_AREA_CREATE))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_AREA_CREATE)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length < 2) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("single.single_area_needs_name"),
 | 
			
		||||
                            Template.of("command", "/plot area single <name>")
 | 
			
		||||
                            TagResolver.resolver("command", Tag.inserting(Component.text("/plot area single <name>")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -228,10 +233,9 @@ public class Area extends SubCommand {
 | 
			
		||||
                try (final ClipboardWriter clipboardWriter = BuiltInClipboardFormat.SPONGE_SCHEMATIC.getWriter(new FileOutputStream(
 | 
			
		||||
                        file))) {
 | 
			
		||||
                    final BlockArrayClipboard clipboard = new BlockArrayClipboard(selectedRegion);
 | 
			
		||||
                    final EditSession editSession = WorldEdit
 | 
			
		||||
                            .getInstance()
 | 
			
		||||
                            .getEditSessionFactory()
 | 
			
		||||
                            .getEditSession(selectedRegion.getWorld(), -1);
 | 
			
		||||
                    EditSessionBuilder editSessionBuilder = WorldEdit.getInstance().newEditSessionBuilder();
 | 
			
		||||
                    editSessionBuilder.world(selectedRegion.getWorld());
 | 
			
		||||
                    final EditSession editSession = editSessionBuilder.build();
 | 
			
		||||
                    final ForwardExtentCopy forwardExtentCopy =
 | 
			
		||||
                            new ForwardExtentCopy(editSession, selectedRegion, clipboard, selectedRegion.getMinimumPoint());
 | 
			
		||||
                    forwardExtentCopy.setCopyingBiomes(true);
 | 
			
		||||
@@ -279,7 +283,7 @@ public class Area extends SubCommand {
 | 
			
		||||
                    } else {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("errors.error_create"),
 | 
			
		||||
                                Template.of("world", hybridPlotWorld.getWorldName())
 | 
			
		||||
                                TagResolver.resolver("world", Tag.inserting(Component.text(hybridPlotWorld.getWorldName())))
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                };
 | 
			
		||||
@@ -290,7 +294,10 @@ public class Area extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_AREA_CREATE)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_AREA_CREATE))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_AREA_CREATE)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -298,7 +305,10 @@ public class Area extends SubCommand {
 | 
			
		||||
                    case 1:
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                                Templates.of("value", "/plot area create [world[:id]] [<modifier>=<value>]...")
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "value",
 | 
			
		||||
                                        Tag.inserting(Component.text("/plot area create [world[:id]] [<modifier>=<value>]..."))
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    case 2:
 | 
			
		||||
@@ -312,7 +322,11 @@ public class Area extends SubCommand {
 | 
			
		||||
                                if (area == null) {
 | 
			
		||||
                                    player.sendMessage(
 | 
			
		||||
                                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                                            Templates.of("value", "/plot area create [world[:id]] [<modifier>=<value>]...")
 | 
			
		||||
                                            TagResolver.resolver(
 | 
			
		||||
                                                    "value",
 | 
			
		||||
                                                    Tag.inserting(Component.text(
 | 
			
		||||
                                                            "/plot area create [world[:id]] [<modifier>=<value>]..."))
 | 
			
		||||
                                            )
 | 
			
		||||
                                    );
 | 
			
		||||
                                    return false;
 | 
			
		||||
                                }
 | 
			
		||||
@@ -323,12 +337,18 @@ public class Area extends SubCommand {
 | 
			
		||||
                                );
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("set.set_attribute"),
 | 
			
		||||
                                        Template.of("attribute", "area_pos1"),
 | 
			
		||||
                                        Template.of("value", location.getX() + "," + location.getZ())
 | 
			
		||||
                                        TagResolver.builder()
 | 
			
		||||
                                                .tag("attribute", Tag.inserting(Component.text("area_pos1")))
 | 
			
		||||
                                                .tag("value", Tag.inserting(
 | 
			
		||||
                                                        Component.text(location.getX())
 | 
			
		||||
                                                                .append(Component.text(","))
 | 
			
		||||
                                                                .append(Component.text(location.getZ()))
 | 
			
		||||
                                                ))
 | 
			
		||||
                                                .build()
 | 
			
		||||
                                );
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("area.set_pos2"),
 | 
			
		||||
                                        Template.of("command", "/plot area create pos2")
 | 
			
		||||
                                        TagResolver.resolver("command", Tag.inserting(Component.text("/plot area create pos2")))
 | 
			
		||||
                                );
 | 
			
		||||
                                return true;
 | 
			
		||||
                            }
 | 
			
		||||
@@ -342,7 +362,11 @@ public class Area extends SubCommand {
 | 
			
		||||
                                if (area == null) {
 | 
			
		||||
                                    player.sendMessage(
 | 
			
		||||
                                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                                            Templates.of("value", "/plot area create [world[:id]] [<modifier>=<value>]...")
 | 
			
		||||
                                            TagResolver.resolver(
 | 
			
		||||
                                                    "value",
 | 
			
		||||
                                                    Tag.inserting(Component.text(
 | 
			
		||||
                                                            "/plot area create [world[:id]] [<modifier>=<value>]..."))
 | 
			
		||||
                                            )
 | 
			
		||||
                                    );
 | 
			
		||||
                                    return false;
 | 
			
		||||
                                }
 | 
			
		||||
@@ -369,7 +393,10 @@ public class Area extends SubCommand {
 | 
			
		||||
                                if (!areas.isEmpty()) {
 | 
			
		||||
                                    player.sendMessage(
 | 
			
		||||
                                            TranslatableCaption.of("cluster.cluster_intersection"),
 | 
			
		||||
                                            Template.of("cluster", areas.iterator().next().toString())
 | 
			
		||||
                                            TagResolver.resolver(
 | 
			
		||||
                                                    "cluster",
 | 
			
		||||
                                                    Tag.inserting(areas.iterator().next())
 | 
			
		||||
                                            )
 | 
			
		||||
                                    );
 | 
			
		||||
                                    return false;
 | 
			
		||||
                                }
 | 
			
		||||
@@ -395,8 +422,7 @@ public class Area extends SubCommand {
 | 
			
		||||
                                        player.sendMessage(TranslatableCaption.of("setup.setup_finished"));
 | 
			
		||||
                                        if (area.getTerrain() != PlotAreaTerrainType.ALL) {
 | 
			
		||||
                                            QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(world));
 | 
			
		||||
                                            queue.setChunkConsumer(chunk -> AugmentedUtils.generate(
 | 
			
		||||
                                                    null,
 | 
			
		||||
                                            queue.setChunkConsumer(chunk -> AugmentedUtils.generateChunk(
 | 
			
		||||
                                                    world,
 | 
			
		||||
                                                    chunk.getX(),
 | 
			
		||||
                                                    chunk.getZ(),
 | 
			
		||||
@@ -408,7 +434,7 @@ public class Area extends SubCommand {
 | 
			
		||||
                                    } else {
 | 
			
		||||
                                        player.sendMessage(
 | 
			
		||||
                                                TranslatableCaption.of("errors.error_create"),
 | 
			
		||||
                                                Template.of("world", area.getWorldName())
 | 
			
		||||
                                                TagResolver.resolver("world", Tag.inserting(Component.text(area.getWorldName())))
 | 
			
		||||
                                        );
 | 
			
		||||
                                    }
 | 
			
		||||
                                };
 | 
			
		||||
@@ -442,7 +468,7 @@ public class Area extends SubCommand {
 | 
			
		||||
                        if (other != null && Objects.equals(pa.getId(), other.getId())) {
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("setup.setup_world_taken"),
 | 
			
		||||
                                    Template.of("value", pa.toString())
 | 
			
		||||
                                    TagResolver.resolver("value", Tag.inserting(Component.text(pa.getId())))
 | 
			
		||||
                            );
 | 
			
		||||
                            return false;
 | 
			
		||||
                        }
 | 
			
		||||
@@ -457,8 +483,13 @@ public class Area extends SubCommand {
 | 
			
		||||
                            if (pair.length != 2) {
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("commandconfig.command_syntax_extended"),
 | 
			
		||||
                                        Template.of("value1,", getCommandString()),
 | 
			
		||||
                                        Template.of("value2", " create [world[:id]] [<modifier>=<value>]...")
 | 
			
		||||
                                        TagResolver.builder()
 | 
			
		||||
                                                .tag("value1", Tag.inserting(Component.text(getCommandString())))
 | 
			
		||||
                                                .tag(
 | 
			
		||||
                                                        "value2",
 | 
			
		||||
                                                        Tag.inserting(Component.text("create [world[:id]] [<modifier>=<value>]..."))
 | 
			
		||||
                                                )
 | 
			
		||||
                                                .build()
 | 
			
		||||
                                );
 | 
			
		||||
                                return false;
 | 
			
		||||
                            }
 | 
			
		||||
@@ -494,8 +525,14 @@ public class Area extends SubCommand {
 | 
			
		||||
                                default -> {
 | 
			
		||||
                                    player.sendMessage(
 | 
			
		||||
                                            TranslatableCaption.of("commandconfig.command_syntax_extended"),
 | 
			
		||||
                                            Template.of("value1", getCommandString()),
 | 
			
		||||
                                            Template.of("value2", " create [world[:id]] [<modifier>=<value>]...")
 | 
			
		||||
                                            TagResolver.builder()
 | 
			
		||||
                                                    .tag("value1", Tag.inserting(Component.text(getCommandString())))
 | 
			
		||||
                                                    .tag(
 | 
			
		||||
                                                            "value2",
 | 
			
		||||
                                                            Tag.inserting(Component.text(
 | 
			
		||||
                                                                    " create [world[:id]] [<modifier>=<value>]..."))
 | 
			
		||||
                                                    )
 | 
			
		||||
                                                    .build()
 | 
			
		||||
                                    );
 | 
			
		||||
                                    return false;
 | 
			
		||||
                                }
 | 
			
		||||
@@ -505,7 +542,7 @@ public class Area extends SubCommand {
 | 
			
		||||
                            if (this.worldUtil.isWorld(pa.getWorldName())) {
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("setup.setup_world_taken"),
 | 
			
		||||
                                        Template.of("value", pa.getWorldName())
 | 
			
		||||
                                        TagResolver.resolver("value", Tag.inserting(Component.text(pa.getWorldName())))
 | 
			
		||||
                                );
 | 
			
		||||
                                return false;
 | 
			
		||||
                            }
 | 
			
		||||
@@ -526,7 +563,7 @@ public class Area extends SubCommand {
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    player.sendMessage(
 | 
			
		||||
                                            TranslatableCaption.of("errors.error_create"),
 | 
			
		||||
                                            Template.of("world", pa.getWorldName())
 | 
			
		||||
                                            TagResolver.resolver("world", Tag.inserting(Component.text(pa.getWorldName())))
 | 
			
		||||
                                    );
 | 
			
		||||
                                }
 | 
			
		||||
                                try {
 | 
			
		||||
@@ -545,12 +582,18 @@ public class Area extends SubCommand {
 | 
			
		||||
                        if (pa.getId() == null) {
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                                    Template.of("value", getUsage())
 | 
			
		||||
                                    TagResolver.resolver("value", Tag.inserting(Component.text(getUsage())))
 | 
			
		||||
                            );
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("commandconfig.command_syntax_extended"),
 | 
			
		||||
                                    Template.of("value1", getCommandString()),
 | 
			
		||||
                                    Template.of("value2", " create [world[:id]] [<modifier>=<value>]...")
 | 
			
		||||
                                    TagResolver.builder()
 | 
			
		||||
                                            .tag("value1", Tag.inserting(Component.text(getCommandString())))
 | 
			
		||||
                                            .tag(
 | 
			
		||||
                                                    "value2",
 | 
			
		||||
                                                    Tag.inserting(Component.text(
 | 
			
		||||
                                                            " create [world[:id]] [<modifier>=<value>]..."))
 | 
			
		||||
                                            )
 | 
			
		||||
                                            .build()
 | 
			
		||||
                            );
 | 
			
		||||
                            return false;
 | 
			
		||||
                        }
 | 
			
		||||
@@ -567,7 +610,7 @@ public class Area extends SubCommand {
 | 
			
		||||
                        metaData.computeIfAbsent(player.getUUID(), missingUUID -> new HashMap<>()).put("area_create_area", pa);
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("single.get_position"),
 | 
			
		||||
                                Template.of("command", getCommandString())
 | 
			
		||||
                                TagResolver.resolver("command", Tag.inserting(Component.text(getCommandString())))
 | 
			
		||||
                        );
 | 
			
		||||
                        break;
 | 
			
		||||
                }
 | 
			
		||||
@@ -577,7 +620,10 @@ public class Area extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_AREA_INFO)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_AREA_INFO))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_AREA_INFO)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -588,15 +634,20 @@ public class Area extends SubCommand {
 | 
			
		||||
                    default -> {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("commandconfig.command_syntax_extended"),
 | 
			
		||||
                                Template.of("value1", getCommandString()),
 | 
			
		||||
                                Template.of("value2", " info [area]")
 | 
			
		||||
                                TagResolver.builder()
 | 
			
		||||
                                        .tag("value1", Tag.inserting(Component.text(getCommandString())))
 | 
			
		||||
                                        .tag("value2", Tag.inserting(Component.text(" info [area]")))
 | 
			
		||||
                                        .build()
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                if (area == null) {
 | 
			
		||||
                    if (args.length == 2) {
 | 
			
		||||
                        player.sendMessage(TranslatableCaption.of("errors.not_valid_plot_world"), Template.of("value", args[1]));
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("errors.not_valid_plot_world"),
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(args[1])))
 | 
			
		||||
                        );
 | 
			
		||||
                    } else {
 | 
			
		||||
                        player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world"));
 | 
			
		||||
                    }
 | 
			
		||||
@@ -620,42 +671,35 @@ public class Area extends SubCommand {
 | 
			
		||||
                    percent = claimed == 0 ? 0 : 100d * claimed / Integer.MAX_VALUE;
 | 
			
		||||
                    region = "N/A";
 | 
			
		||||
                }
 | 
			
		||||
                Template headerTemplate = Template.of(
 | 
			
		||||
                        "header",
 | 
			
		||||
                        TranslatableCaption.of("info.plot_info_header").getComponent(player)
 | 
			
		||||
                );
 | 
			
		||||
                Template nameTemplate = Template.of("name", name);
 | 
			
		||||
                Template typeTemplate = Template.of("type", area.getType().name());
 | 
			
		||||
                Template terrainTemplate = Template.of("terrain", area.getTerrain().name());
 | 
			
		||||
                Template usageTemplate = Template.of("usage", String.format("%.2f", percent));
 | 
			
		||||
                Template claimedTemplate = Template.of("claimed", String.valueOf(claimed));
 | 
			
		||||
                Template clustersTemplate = Template.of("clusters", String.valueOf(clusters));
 | 
			
		||||
                Template regionTemplate = Template.of("region", region);
 | 
			
		||||
                Template generatorTemplate = Template.of("generator", generator);
 | 
			
		||||
                Template footerTemplate = Template.of(
 | 
			
		||||
                        "footer",
 | 
			
		||||
                        TranslatableCaption.of("info.plot_info_footer").getComponent(player)
 | 
			
		||||
                );
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("info.area_info_format"),
 | 
			
		||||
                        headerTemplate,
 | 
			
		||||
                        nameTemplate,
 | 
			
		||||
                        typeTemplate,
 | 
			
		||||
                        terrainTemplate,
 | 
			
		||||
                        usageTemplate,
 | 
			
		||||
                        claimedTemplate,
 | 
			
		||||
                        clustersTemplate,
 | 
			
		||||
                        regionTemplate,
 | 
			
		||||
                        generatorTemplate,
 | 
			
		||||
                        footerTemplate
 | 
			
		||||
                );
 | 
			
		||||
                TagResolver resolver = TagResolver.builder()
 | 
			
		||||
                        .tag(
 | 
			
		||||
                                "header",
 | 
			
		||||
                                Tag.inserting(TranslatableCaption.of("info.plot_info_header").toComponent(player))
 | 
			
		||||
                        )
 | 
			
		||||
                        .tag("name", Tag.inserting(Component.text(name)))
 | 
			
		||||
                        .tag("type", Tag.inserting(Component.text(area.getType().name())))
 | 
			
		||||
                        .tag("terrain", Tag.inserting(Component.text(area.getTerrain().name())))
 | 
			
		||||
                        .tag("usage", Tag.inserting(Component.text(String.format("%.2f", percent))))
 | 
			
		||||
                        .tag("claimed", Tag.inserting(Component.text(claimed)))
 | 
			
		||||
                        .tag("clusters", Tag.inserting(Component.text(clusters)))
 | 
			
		||||
                        .tag("region", Tag.inserting(Component.text(region)))
 | 
			
		||||
                        .tag("generator", Tag.inserting(Component.text(generator)))
 | 
			
		||||
                        .tag(
 | 
			
		||||
                                "footer",
 | 
			
		||||
                                Tag.inserting(TranslatableCaption.of("info.plot_info_footer").toComponent(player))
 | 
			
		||||
                        )
 | 
			
		||||
                        .build();
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("info.area_info_format"), resolver);
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "l", "list" -> {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_AREA_LIST)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_AREA_LIST))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_AREA_LIST)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -672,8 +716,10 @@ public class Area extends SubCommand {
 | 
			
		||||
                    default:
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("commandconfig.command_syntax_extended"),
 | 
			
		||||
                                Template.of("value1", getCommandString()),
 | 
			
		||||
                                Template.of("value2", " list [#]")
 | 
			
		||||
                                TagResolver.builder()
 | 
			
		||||
                                        .tag("value1", Tag.inserting(Component.text(getCommandString())))
 | 
			
		||||
                                        .tag("value2", Tag.inserting(Component.text(" list [#]")))
 | 
			
		||||
                                        .build()
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -699,37 +745,27 @@ public class Area extends SubCommand {
 | 
			
		||||
                            percent = claimed == 0 ? 0 : (double) claimed / Short.MAX_VALUE * Short.MAX_VALUE;
 | 
			
		||||
                            region = "N/A";
 | 
			
		||||
                        }
 | 
			
		||||
                        Template claimedTemplate = Template.of("claimed", String.valueOf(claimed));
 | 
			
		||||
                        Template usageTemplate = Template.of("usage", String.format("%.2f", percent) + "%");
 | 
			
		||||
                        Template clustersTemplate = Template.of("clusters", String.valueOf(clusters));
 | 
			
		||||
                        Template regionTemplate = Template.of("region", region);
 | 
			
		||||
                        Template generatorTemplate = Template.of("generator", generator);
 | 
			
		||||
                        String tooltip = MINI_MESSAGE.serialize(MINI_MESSAGE
 | 
			
		||||
                                .parse(
 | 
			
		||||
                                        TranslatableCaption.of("info.area_list_tooltip").getComponent(player),
 | 
			
		||||
                                        claimedTemplate,
 | 
			
		||||
                                        usageTemplate,
 | 
			
		||||
                                        clustersTemplate,
 | 
			
		||||
                                        regionTemplate,
 | 
			
		||||
                                        generatorTemplate
 | 
			
		||||
                                ));
 | 
			
		||||
                        Template tooltipTemplate = Template.of("hover_info", tooltip);
 | 
			
		||||
                        Template visitcmdTemplate = Template.of("command_tp", "/plot area tp " + area);
 | 
			
		||||
                        Template infocmdTemplate = Template.of("command_info", "/plot area info " + area);
 | 
			
		||||
                        Template numberTemplate = Template.of("number", String.valueOf(i));
 | 
			
		||||
                        Template nameTemplate = Template.of("area_name", name);
 | 
			
		||||
                        Template typeTemplate = Template.of("area_type", area.getType().name());
 | 
			
		||||
                        Template terrainTemplate = Template.of("area_terrain", area.getTerrain().name());
 | 
			
		||||
                        caption.set(TranslatableCaption.of("info.area_list_item"));
 | 
			
		||||
                        caption.setTemplates(
 | 
			
		||||
                                tooltipTemplate,
 | 
			
		||||
                                visitcmdTemplate,
 | 
			
		||||
                                numberTemplate,
 | 
			
		||||
                                nameTemplate,
 | 
			
		||||
                                typeTemplate,
 | 
			
		||||
                                terrainTemplate,
 | 
			
		||||
                                infocmdTemplate
 | 
			
		||||
                        Component tooltip = MINI_MESSAGE.deserialize(
 | 
			
		||||
                                TranslatableCaption.of("info.area_list_tooltip").getComponent(player),
 | 
			
		||||
                                TagResolver.builder()
 | 
			
		||||
                                        .tag("claimed", Tag.inserting(Component.text(claimed)))
 | 
			
		||||
                                        .tag("usage", Tag.inserting(Component.text(String.format("%.2f", percent) + "%")))
 | 
			
		||||
                                        .tag("clusters", Tag.inserting(Component.text(clusters)))
 | 
			
		||||
                                        .tag("region", Tag.inserting(Component.text(region)))
 | 
			
		||||
                                        .tag("generator", Tag.inserting(Component.text(generator)))
 | 
			
		||||
                                        .build()
 | 
			
		||||
                        );
 | 
			
		||||
                        TagResolver resolver = TagResolver.builder()
 | 
			
		||||
                                .tag("hover_info", Tag.inserting(tooltip))
 | 
			
		||||
                                .tag("command_tp", Tag.preProcessParsed("/plot area tp " + name))
 | 
			
		||||
                                .tag("command_info", Tag.preProcessParsed("/plot area info " + name))
 | 
			
		||||
                                .tag("number", Tag.inserting(Component.text(i)))
 | 
			
		||||
                                .tag("area_name", Tag.inserting(Component.text(name)))
 | 
			
		||||
                                .tag("area_type", Tag.inserting(Component.text(area.getType().name())))
 | 
			
		||||
                                .tag("area_terrain", Tag.inserting(Component.text(area.getTerrain().name())))
 | 
			
		||||
                                .build();
 | 
			
		||||
                        caption.set(TranslatableCaption.of("info.area_list_item"));
 | 
			
		||||
                        caption.setTagResolvers(resolver);
 | 
			
		||||
                    }
 | 
			
		||||
                }, "/plot area list", TranslatableCaption.of("list.area_list_header_paged"));
 | 
			
		||||
                return true;
 | 
			
		||||
@@ -738,7 +774,10 @@ public class Area extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_AREA_REGEN)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_AREA_REGEN))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_AREA_REGEN)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -750,13 +789,12 @@ public class Area extends SubCommand {
 | 
			
		||||
                if (area.getType() != PlotAreaType.PARTIAL) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("single.delete_world_region"),
 | 
			
		||||
                            Template.of("world", area.getWorldName())
 | 
			
		||||
                            TagResolver.resolver("world", Tag.inserting(Component.text(area.getWorldName())))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName()));
 | 
			
		||||
                queue.setChunkConsumer(chunk -> AugmentedUtils.generate(
 | 
			
		||||
                        null,
 | 
			
		||||
                queue.setChunkConsumer(chunk -> AugmentedUtils.generateChunk(
 | 
			
		||||
                        area.getWorldName(),
 | 
			
		||||
                        chunk.getX(),
 | 
			
		||||
                        chunk.getZ(),
 | 
			
		||||
@@ -771,20 +809,23 @@ public class Area extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_AREA_TP)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_AREA_TP))
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Permission.PERMISSION_AREA_TP))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 2) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot area tp [area]")
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text("/plot area tp [area]")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                PlotArea area = this.plotAreaManager.getPlotAreaByString(args[1]);
 | 
			
		||||
                if (area == null) {
 | 
			
		||||
                    player.sendMessage(TranslatableCaption.of("errors.not_valid_plot_world"), Template.of("value", args[1]));
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("errors.not_valid_plot_world"),
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text(args[1])))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                Location center;
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,7 @@ import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import com.plotsquared.core.plot.Plot;
 | 
			
		||||
import com.plotsquared.core.plot.PlotArea;
 | 
			
		||||
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.util.EconHandler;
 | 
			
		||||
import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
@@ -43,7 +44,9 @@ import com.plotsquared.core.util.task.AutoClaimFinishTask;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import io.leangen.geantyref.TypeToken;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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 org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
 | 
			
		||||
@@ -109,13 +112,13 @@ public class Auto extends SubCommand {
 | 
			
		||||
                    if (diff < 0 && grantedPlots < sizeX * sizeZ) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.cant_claim_more_plots"),
 | 
			
		||||
                                Template.of("amount", String.valueOf(diff + grantedPlots))
 | 
			
		||||
                                TagResolver.resolver("amount", Tag.inserting(Component.text(diff + grantedPlots)))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    } else if (diff >= 0 && grantedPlots + diff < sizeX * sizeZ) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.cant_claim_more_plots"),
 | 
			
		||||
                                Template.of("amount", String.valueOf(diff + grantedPlots))
 | 
			
		||||
                                TagResolver.resolver("amount", Tag.inserting(Component.text(diff + grantedPlots)))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    } else {
 | 
			
		||||
@@ -127,15 +130,16 @@ public class Auto extends SubCommand {
 | 
			
		||||
                        }
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("economy.removed_granted_plot"),
 | 
			
		||||
                                Template.of("usedGrants", String.valueOf(grantedPlots - left)),
 | 
			
		||||
                                Template.of("remainingGrants", String.valueOf(left))
 | 
			
		||||
                                TagResolver.builder()
 | 
			
		||||
                                        .tag("usedGrants", Tag.inserting(Component.text(grantedPlots - left)))
 | 
			
		||||
                                        .tag("remainingGrants", Tag.inserting(Component.text(left)))
 | 
			
		||||
                                        .build()
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.cant_claim_more_plots"),
 | 
			
		||||
                            Template.of("amount", String.valueOf(player.getAllowedPlots())
 | 
			
		||||
                            )
 | 
			
		||||
                            TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots())))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -214,7 +218,7 @@ public class Auto extends SubCommand {
 | 
			
		||||
                } else {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", getUsage())
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text(getUsage())))
 | 
			
		||||
                    );
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
@@ -237,7 +241,7 @@ public class Auto extends SubCommand {
 | 
			
		||||
        if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                    Template.of("value", "Auto claim")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("Auto claim")))
 | 
			
		||||
            );
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
@@ -248,14 +252,14 @@ public class Auto extends SubCommand {
 | 
			
		||||
        if (!force && mega && !player.hasPermission(Permission.PERMISSION_AUTO_MEGA)) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_AUTO_MEGA))
 | 
			
		||||
                    TagResolver.resolver("node", Tag.inserting(Permission.PERMISSION_AUTO_MEGA))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        if (!force && sizeX * sizeZ > Settings.Claim.MAX_AUTO_AREA) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.cant_claim_more_plots_num"),
 | 
			
		||||
                    Template.of("amount", String.valueOf(Settings.Claim.MAX_AUTO_AREA))
 | 
			
		||||
                    TagResolver.resolver("amount", Tag.inserting(Component.text(Settings.Claim.MAX_AUTO_AREA)))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -273,8 +277,10 @@ public class Auto extends SubCommand {
 | 
			
		||||
            if (!plotarea.hasSchematic(schematic)) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("schematics.schematic_invalid_named"),
 | 
			
		||||
                        Template.of("schemname", schematic),
 | 
			
		||||
                        Template.of("reason", "non-existent")
 | 
			
		||||
                        TagResolver.builder()
 | 
			
		||||
                                .tag("schemname", Tag.inserting(Component.text(schematic)))
 | 
			
		||||
                                .tag("reason", Tag.inserting(Component.text("non-existent")))
 | 
			
		||||
                                .build()
 | 
			
		||||
                );
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
@@ -283,17 +289,20 @@ public class Auto extends SubCommand {
 | 
			
		||||
            ) && !player.hasPermission("plots.admin.command.schematic")) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                        Template.of("node", "plots.claim.%s0")
 | 
			
		||||
                        TagResolver.resolver("node", Tag.inserting(Component.text("plots.claim.%s0")))
 | 
			
		||||
                );
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (this.econHandler != null && plotarea.useEconomy()) {
 | 
			
		||||
            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 ?
 | 
			
		||||
                    player.getPlotCount() :
 | 
			
		||||
                    player.getPlotCount(plotarea.getWorldName()));
 | 
			
		||||
            cost = (sizeX * sizeZ) * cost;
 | 
			
		||||
            cost = size * cost + mergeCost;
 | 
			
		||||
            if (cost > 0d) {
 | 
			
		||||
                if (!this.econHandler.isSupported()) {
 | 
			
		||||
                    player.sendMessage(TranslatableCaption.of("economy.vault_or_consumer_null"));
 | 
			
		||||
@@ -302,21 +311,26 @@ public class Auto extends SubCommand {
 | 
			
		||||
                if (!force && this.econHandler.getMoney(player) < cost) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("economy.cannot_afford_plot"),
 | 
			
		||||
                            Template.of("money", this.econHandler.format(cost)),
 | 
			
		||||
                            Template.of("balance", this.econHandler.format(this.econHandler.getMoney(player)))
 | 
			
		||||
                            TagResolver.builder()
 | 
			
		||||
                                    .tag("money", Tag.inserting(Component.text(this.econHandler.format(cost))))
 | 
			
		||||
                                    .tag(
 | 
			
		||||
                                            "balance",
 | 
			
		||||
                                            Tag.inserting(Component.text(this.econHandler.format(this.econHandler.getMoney(player))))
 | 
			
		||||
                                    )
 | 
			
		||||
                                    .build()
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                this.econHandler.withdrawMoney(player, cost);
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("economy.removed_balance"),
 | 
			
		||||
                        Template.of("money", this.econHandler.format(cost))
 | 
			
		||||
                        TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(cost))))
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        List<Plot> plots = this.servicePipeline
 | 
			
		||||
                .pump(new AutoService.AutoQuery(player, null, sizeX, sizeZ, plotarea))
 | 
			
		||||
                .pump(new AutoQuery(player, null, sizeX, sizeZ, plotarea))
 | 
			
		||||
                .through(AutoService.class)
 | 
			
		||||
                .getResult();
 | 
			
		||||
 | 
			
		||||
@@ -344,7 +358,7 @@ public class Auto extends SubCommand {
 | 
			
		||||
            if (!force && mergeEvent.getEventResult() == Result.DENY) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                        Template.of("value", "Auto merge")
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text("Auto merge")))
 | 
			
		||||
                );
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,9 @@ import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import com.plotsquared.core.plot.Plot;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal2;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal3;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.nio.file.Files;
 | 
			
		||||
@@ -66,7 +68,7 @@ public final class Backup extends Command {
 | 
			
		||||
    private static boolean sendMessage(PlotPlayer<?> player) {
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                Template.of("value", "/plot backup <save | list | load>")
 | 
			
		||||
                TagResolver.resolver("value", Tag.inserting(Component.text("/plot backup <save | list | load>")))
 | 
			
		||||
        );
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
@@ -134,33 +136,44 @@ public final class Backup extends Command {
 | 
			
		||||
        } else if (!plot.hasOwner()) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("backups.backup_impossible"),
 | 
			
		||||
                    Template.of("plot", TranslatableCaption.of("generic.generic_unowned").getComponent(player))
 | 
			
		||||
                    TagResolver.resolver("plot", Tag.inserting(
 | 
			
		||||
                            TranslatableCaption.of("generic.generic_unowned").toComponent(player)
 | 
			
		||||
                    ))
 | 
			
		||||
            );
 | 
			
		||||
        } else if (plot.getVolume() > Integer.MAX_VALUE) {
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("schematics.schematic_too_large"));
 | 
			
		||||
        } else if (plot.isMerged()) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("backups.backup_impossible"),
 | 
			
		||||
                    Template.of("plot", TranslatableCaption.of("generic.generic_merged").getComponent(player))
 | 
			
		||||
                    TagResolver.resolver("plot", Tag.inserting(
 | 
			
		||||
                            TranslatableCaption.of("generic.generic_merged").toComponent(player)
 | 
			
		||||
                    ))
 | 
			
		||||
            );
 | 
			
		||||
        } else if (!plot.isOwner(player.getUUID()) && !player.hasPermission(Permission.PERMISSION_ADMIN_BACKUP_OTHER)) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BACKUP_OTHER))
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "node",
 | 
			
		||||
                            Tag.inserting(Permission.PERMISSION_ADMIN_BACKUP_OTHER)
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
        } else {
 | 
			
		||||
            final BackupProfile backupProfile = Objects.requireNonNull(this.backupManager.getProfile(plot));
 | 
			
		||||
            if (backupProfile instanceof NullBackupProfile) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("backups.backup_impossible"),
 | 
			
		||||
                        Template.of("plot", TranslatableCaption.of("generic.generic_other").getComponent(player))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "plot", Tag.inserting(TranslatableCaption
 | 
			
		||||
                                        .of("generic.generic_other")
 | 
			
		||||
                                        .toComponent(player))
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                backupProfile.createBackup().whenComplete((backup, throwable) -> {
 | 
			
		||||
                    if (throwable != null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("backups.backup_save_failed"),
 | 
			
		||||
                                Template.of("reason", throwable.getMessage())
 | 
			
		||||
                                TagResolver.resolver("reason", Tag.inserting(Component.text(throwable.getMessage())))
 | 
			
		||||
                        );
 | 
			
		||||
                        throwable.printStackTrace();
 | 
			
		||||
                    } else {
 | 
			
		||||
@@ -187,49 +200,64 @@ public final class Backup extends Command {
 | 
			
		||||
        } else if (!plot.hasOwner()) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("backups.backup_impossible"),
 | 
			
		||||
                    Template.of("plot", TranslatableCaption.of("generic.generic_unowned").getComponent(player))
 | 
			
		||||
                    TagResolver.resolver("plot", Tag.inserting(
 | 
			
		||||
                            TranslatableCaption.of("generic.generic_unowned").toComponent(player)
 | 
			
		||||
                    ))
 | 
			
		||||
            );
 | 
			
		||||
        } else if (plot.isMerged()) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("backups.backup_impossible"),
 | 
			
		||||
                    Template.of("plot", TranslatableCaption.of("generic.generic_merged").getComponent(player))
 | 
			
		||||
                    TagResolver.resolver("plot", Tag.inserting(
 | 
			
		||||
                            TranslatableCaption.of("generic.generic_merged").toComponent(player)
 | 
			
		||||
                    ))
 | 
			
		||||
            );
 | 
			
		||||
        } else if (plot.getVolume() > Integer.MAX_VALUE) {
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("schematics.schematic_too_large"));
 | 
			
		||||
        } else if (!plot.isOwner(player.getUUID()) && !player.hasPermission(Permission.PERMISSION_ADMIN_BACKUP_OTHER)) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BACKUP_OTHER))
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "node",
 | 
			
		||||
                            Tag.inserting(Permission.PERMISSION_ADMIN_BACKUP_OTHER)
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
        } else {
 | 
			
		||||
            final BackupProfile backupProfile = Objects.requireNonNull(this.backupManager.getProfile(plot));
 | 
			
		||||
            if (backupProfile instanceof NullBackupProfile) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("backups.backup_impossible"),
 | 
			
		||||
                        Template.of("plot", TranslatableCaption.of("generic.generic_other").getComponent(player))
 | 
			
		||||
                        TagResolver.resolver("plot", Tag.inserting(
 | 
			
		||||
                                TranslatableCaption.of("generic.generic_other").toComponent(player)
 | 
			
		||||
                        ))
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                backupProfile.listBackups().whenComplete((backups, throwable) -> {
 | 
			
		||||
                    if (throwable != null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("backups.backup_list_failed"),
 | 
			
		||||
                                Template.of("reason", throwable.getMessage())
 | 
			
		||||
                                TagResolver.resolver("reason", Tag.inserting(Component.text(throwable.getMessage())))
 | 
			
		||||
                        );
 | 
			
		||||
                        throwable.printStackTrace();
 | 
			
		||||
                    } else {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("backups.backup_list_header"),
 | 
			
		||||
                                Template.of("plot", plot.getId().toCommaSeparatedString())
 | 
			
		||||
                                TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toCommaSeparatedString())))
 | 
			
		||||
                        );
 | 
			
		||||
                        try {
 | 
			
		||||
                            for (int i = 0; i < backups.size(); i++) {
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("backups.backup_list_entry"),
 | 
			
		||||
                                        Template.of("number", Integer.toString(i + 1)),
 | 
			
		||||
                                        Template.of("value", DateTimeFormatter.RFC_1123_DATE_TIME.format(ZonedDateTime.ofInstant(
 | 
			
		||||
                                                Instant.ofEpochMilli(backups.get(i).getCreationTime()),
 | 
			
		||||
                                                ZoneId.systemDefault()
 | 
			
		||||
                                        )))
 | 
			
		||||
                                        TagResolver.builder()
 | 
			
		||||
                                                .tag("number", Tag.inserting(Component.text(i + 1)))
 | 
			
		||||
                                                .tag(
 | 
			
		||||
                                                        "value",
 | 
			
		||||
                                                        Tag.inserting(Component.text(DateTimeFormatter.RFC_1123_DATE_TIME.format(
 | 
			
		||||
                                                                ZonedDateTime.ofInstant(
 | 
			
		||||
                                                                        Instant.ofEpochMilli(backups.get(i).getCreationTime()),
 | 
			
		||||
                                                                        ZoneId.systemDefault()
 | 
			
		||||
                                                                ))))
 | 
			
		||||
                                                )
 | 
			
		||||
                                                .build()
 | 
			
		||||
                                );
 | 
			
		||||
                            }
 | 
			
		||||
                        } catch (final Exception e) {
 | 
			
		||||
@@ -257,24 +285,31 @@ public final class Backup extends Command {
 | 
			
		||||
        } else if (!plot.hasOwner()) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("backups.backup_impossible"),
 | 
			
		||||
                    Template.of("plot", TranslatableCaption.of("generic.generic_unowned").getComponent(player))
 | 
			
		||||
                    TagResolver.resolver("plot", Tag.inserting(
 | 
			
		||||
                            TranslatableCaption.of("generic.generic_unowned").toComponent(player)
 | 
			
		||||
                    ))
 | 
			
		||||
            );
 | 
			
		||||
        } else if (plot.isMerged()) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("backups.backup_impossible"),
 | 
			
		||||
                    Template.of("plot", TranslatableCaption.of("generic.generic_merged").getComponent(player))
 | 
			
		||||
                    TagResolver.resolver("plot", Tag.inserting(
 | 
			
		||||
                            TranslatableCaption.of("generic.generic_merged").toComponent(player)
 | 
			
		||||
                    ))
 | 
			
		||||
            );
 | 
			
		||||
        } else if (plot.getVolume() > Integer.MAX_VALUE) {
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("schematics.schematic_too_large"));
 | 
			
		||||
        } else if (!plot.isOwner(player.getUUID()) && !player.hasPermission(Permission.PERMISSION_ADMIN_BACKUP_OTHER)) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_BACKUP_OTHER))
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "node",
 | 
			
		||||
                            Tag.inserting(Permission.PERMISSION_ADMIN_BACKUP_OTHER)
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
        } else if (args.length == 0) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", "Usage: /plot backup save/list/load")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("Usage: /plot backup save/list/load")))
 | 
			
		||||
            );
 | 
			
		||||
        } else {
 | 
			
		||||
            final int number;
 | 
			
		||||
@@ -283,7 +318,7 @@ public final class Backup extends Command {
 | 
			
		||||
            } catch (final Exception e) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("invalid.not_a_number"),
 | 
			
		||||
                        Template.of("value", args[0])
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text(args[0])))
 | 
			
		||||
                );
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
@@ -291,23 +326,27 @@ public final class Backup extends Command {
 | 
			
		||||
            if (backupProfile instanceof NullBackupProfile) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("backups.backup_impossible"),
 | 
			
		||||
                        Template.of("plot", TranslatableCaption.of("generic.generic_other").getComponent(player))
 | 
			
		||||
                        TagResolver.resolver("plot", Tag.inserting(
 | 
			
		||||
                                TranslatableCaption.of("generic.generic_other").toComponent(player)
 | 
			
		||||
                        ))
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                backupProfile.listBackups().whenComplete((backups, throwable) -> {
 | 
			
		||||
                    if (throwable != null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("backups.backup_load_failure"),
 | 
			
		||||
                                Template.of("reason", throwable.getMessage())
 | 
			
		||||
                                TagResolver.resolver("reason", Tag.inserting(Component.text(throwable.getMessage())))
 | 
			
		||||
                        );
 | 
			
		||||
                        throwable.printStackTrace();
 | 
			
		||||
                    } else {
 | 
			
		||||
                        if (number < 1 || number > backups.size()) {
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("backups.backup_impossible"),
 | 
			
		||||
                                    Template.of(
 | 
			
		||||
                                    TagResolver.resolver(
 | 
			
		||||
                                            "plot",
 | 
			
		||||
                                            TranslatableCaption.of("generic.generic_invalid_choice").getComponent(player)
 | 
			
		||||
                                            Tag.inserting(TranslatableCaption
 | 
			
		||||
                                                    .of("generic.generic_invalid_choice")
 | 
			
		||||
                                                    .toComponent(player))
 | 
			
		||||
                                    )
 | 
			
		||||
                            );
 | 
			
		||||
                        } else {
 | 
			
		||||
@@ -317,9 +356,11 @@ public final class Backup extends Command {
 | 
			
		||||
                                    .exists(backup.getFile())) {
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("backups.backup_impossible"),
 | 
			
		||||
                                        Template.of(
 | 
			
		||||
                                        TagResolver.resolver(
 | 
			
		||||
                                                "plot",
 | 
			
		||||
                                                TranslatableCaption.of("generic.generic_invalid_choice").getComponent(player)
 | 
			
		||||
                                                Tag.inserting(TranslatableCaption
 | 
			
		||||
                                                        .of("generic.generic_invalid_choice")
 | 
			
		||||
                                                        .toComponent(player))
 | 
			
		||||
                                        )
 | 
			
		||||
                                );
 | 
			
		||||
                            } else {
 | 
			
		||||
@@ -329,7 +370,10 @@ public final class Backup extends Command {
 | 
			
		||||
                                                    if (error != null) {
 | 
			
		||||
                                                        player.sendMessage(
 | 
			
		||||
                                                                TranslatableCaption.of("backups.backup_load_failure"),
 | 
			
		||||
                                                                Template.of("reason", error.getMessage())
 | 
			
		||||
                                                                TagResolver.resolver(
 | 
			
		||||
                                                                        "reason",
 | 
			
		||||
                                                                        Tag.inserting(Component.text(error.getMessage()))
 | 
			
		||||
                                                                )
 | 
			
		||||
                                                        );
 | 
			
		||||
                                                    } else {
 | 
			
		||||
                                                        player.sendMessage(TranslatableCaption.of("backups.backup_load_success"));
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@
 | 
			
		||||
 */
 | 
			
		||||
package com.plotsquared.core.command;
 | 
			
		||||
 | 
			
		||||
import com.plotsquared.core.configuration.caption.StaticCaption;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
 | 
			
		||||
import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import com.plotsquared.core.plot.Plot;
 | 
			
		||||
@@ -25,7 +26,9 @@ import com.plotsquared.core.util.StringMan;
 | 
			
		||||
import com.sk89q.worldedit.command.util.SuggestionHelper;
 | 
			
		||||
import com.sk89q.worldedit.world.biome.BiomeType;
 | 
			
		||||
import com.sk89q.worldedit.world.biome.BiomeTypes;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.Collection;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
@@ -47,16 +50,13 @@ public class Biome extends SetCommand {
 | 
			
		||||
        } catch (final Exception ignore) {
 | 
			
		||||
        }
 | 
			
		||||
        if (biome == null) {
 | 
			
		||||
            String biomes = StringMan.join(
 | 
			
		||||
                    BiomeType.REGISTRY.values(),
 | 
			
		||||
                    MINI_MESSAGE.serialize(MINI_MESSAGE.parse(TranslatableCaption
 | 
			
		||||
                            .of("blocklist.block_list_separator")
 | 
			
		||||
                            .getComponent(player)))
 | 
			
		||||
            );
 | 
			
		||||
            String separator = TranslatableCaption.of("blocklist.block_list_separator").getComponent(player);
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("biome.need_biome"));
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.subcommand_set_options_header"),
 | 
			
		||||
                    Template.of("values", biomes)
 | 
			
		||||
                    StaticCaption.of(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.subcommand_set_options_header_only").getComponent(player)
 | 
			
		||||
                                    + StringMan.join(BiomeType.REGISTRY.values(), separator)
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -73,7 +73,7 @@ public class Biome extends SetCommand {
 | 
			
		||||
            plot.removeRunning();
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("biome.biome_set_to"),
 | 
			
		||||
                    Template.of("value", value.toLowerCase())
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text(value.toLowerCase())))
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        return true;
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,9 @@ import com.plotsquared.core.util.EconHandler;
 | 
			
		||||
import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal2;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal3;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.Set;
 | 
			
		||||
@@ -84,7 +86,7 @@ public class Buy extends Command {
 | 
			
		||||
        checkTrue(
 | 
			
		||||
                player.getPlotCount() + plots.size() <= player.getAllowedPlots(),
 | 
			
		||||
                TranslatableCaption.of("permission.cant_claim_more_plots"),
 | 
			
		||||
                Template.of("amount", String.valueOf(player.getAllowedPlots()))
 | 
			
		||||
                TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots())))
 | 
			
		||||
        );
 | 
			
		||||
        double price = plot.getFlag(PriceFlag.class);
 | 
			
		||||
        if (price <= 0) {
 | 
			
		||||
@@ -97,8 +99,10 @@ public class Buy extends Command {
 | 
			
		||||
        checkTrue(
 | 
			
		||||
                this.econHandler.getMoney(player) >= price,
 | 
			
		||||
                TranslatableCaption.of("economy.cannot_afford_plot"),
 | 
			
		||||
                Template.of("money", this.econHandler.format(price)),
 | 
			
		||||
                Template.of("balance", this.econHandler.format(this.econHandler.getMoney(player)))
 | 
			
		||||
                TagResolver.builder()
 | 
			
		||||
                        .tag("money", Tag.inserting(Component.text(this.econHandler.format(price))))
 | 
			
		||||
                        .tag("balance", Tag.inserting(Component.text(this.econHandler.format(this.econHandler.getMoney(player)))))
 | 
			
		||||
                        .build()
 | 
			
		||||
        );
 | 
			
		||||
        this.econHandler.withdrawMoney(player, price);
 | 
			
		||||
        // Failure
 | 
			
		||||
@@ -106,7 +110,7 @@ public class Buy extends Command {
 | 
			
		||||
        confirm.run(this, () -> {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("economy.removed_balance"),
 | 
			
		||||
                    Template.of("money", this.econHandler.format(price))
 | 
			
		||||
                    TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price))))
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
            this.econHandler.depositMoney(PlotSquared.platform().playerManager().getOfflinePlayer(plot.getOwnerAbs()), price);
 | 
			
		||||
@@ -115,9 +119,11 @@ public class Buy extends Command {
 | 
			
		||||
            if (owner != null) {
 | 
			
		||||
                owner.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("economy.plot_sold"),
 | 
			
		||||
                        Template.of("plot", plot.getId().toString()),
 | 
			
		||||
                        Template.of("player", player.getName()),
 | 
			
		||||
                        Template.of("price", this.econHandler.format(price))
 | 
			
		||||
                        TagResolver.builder()
 | 
			
		||||
                                .tag("plot", Tag.inserting(Component.text(plot.getId().toString())))
 | 
			
		||||
                                .tag("player", Tag.inserting(Component.text(player.getName())))
 | 
			
		||||
                                .tag("price", Tag.inserting(Component.text(this.econHandler.format(price))))
 | 
			
		||||
                                .build()
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            PlotFlag<?, ?> plotFlag = plot.getFlagContainer().getFlag(PriceFlag.class);
 | 
			
		||||
@@ -129,7 +135,7 @@ public class Buy extends Command {
 | 
			
		||||
            plot.getPlotModificationManager().setSign(player.getName());
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("working.claimed"),
 | 
			
		||||
                    Template.of("plot", plot.getId().toString())
 | 
			
		||||
                    TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString())))
 | 
			
		||||
            );
 | 
			
		||||
            whenDone.run(Buy.this, CommandResult.SUCCESS);
 | 
			
		||||
        }, () -> {
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,10 @@ import com.plotsquared.core.plot.flag.implementations.HostileCapFlag;
 | 
			
		||||
import com.plotsquared.core.plot.flag.implementations.MiscCapFlag;
 | 
			
		||||
import com.plotsquared.core.plot.flag.implementations.MobCapFlag;
 | 
			
		||||
import com.plotsquared.core.plot.flag.implementations.VehicleCapFlag;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
import net.kyori.adventure.text.ComponentLike;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.Tag;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
 | 
			
		||||
 | 
			
		||||
import static com.plotsquared.core.util.entity.EntityCategories.CAP_ANIMAL;
 | 
			
		||||
import static com.plotsquared.core.util.entity.EntityCategories.CAP_ENTITY;
 | 
			
		||||
@@ -53,7 +56,7 @@ public class Caps extends SubCommand {
 | 
			
		||||
        if (!plot.isAdded(player.getUUID()) && !player.hasPermission(Permission.PERMISSION_ADMIN_CAPS_OTHER)) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_CAPS_OTHER))
 | 
			
		||||
                    TagResolver.resolver("node", Tag.inserting(Permission.PERMISSION_ADMIN_CAPS_OTHER))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -80,15 +83,17 @@ public class Caps extends SubCommand {
 | 
			
		||||
        final int current = countedEntities[type];
 | 
			
		||||
        final int max = plot.getFlag(capFlag);
 | 
			
		||||
        final String percentage = String.format("%.1f", 100 * ((float) current / max));
 | 
			
		||||
        String maxBeautified = max >= Integer.MAX_VALUE
 | 
			
		||||
                ? TranslatableCaption.of("info.infinite").getComponent(player)
 | 
			
		||||
                : String.valueOf(max);
 | 
			
		||||
        ComponentLike maxBeautified = max >= Integer.MAX_VALUE
 | 
			
		||||
                ? TranslatableCaption.of("info.infinite").toComponent(player)
 | 
			
		||||
                : Component.text(max);
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("info.plot_caps_format"),
 | 
			
		||||
                Template.of("cap", name),
 | 
			
		||||
                Template.of("current", String.valueOf(current)),
 | 
			
		||||
                Template.of("limit", maxBeautified),
 | 
			
		||||
                Template.of("percentage", percentage)
 | 
			
		||||
                TagResolver.builder()
 | 
			
		||||
                        .tag("cap", Tag.inserting(Component.text(name)))
 | 
			
		||||
                        .tag("current", Tag.inserting(Component.text(current)))
 | 
			
		||||
                        .tag("limit", Tag.inserting(maxBeautified))
 | 
			
		||||
                        .tag("percentage", Tag.inserting(Component.text(percentage)))
 | 
			
		||||
                        .build()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,54 +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.configuration.caption.TranslatableCaption;
 | 
			
		||||
import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import com.plotsquared.core.plot.PlotArea;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @deprecated In favor of "/plot toggle chat" and
 | 
			
		||||
 *         scheduled for removal within the next major release.
 | 
			
		||||
 */
 | 
			
		||||
@Deprecated(forRemoval = true, since = "6.0.0")
 | 
			
		||||
@CommandDeclaration(command = "chat",
 | 
			
		||||
        usage = "/plot chat",
 | 
			
		||||
        permission = "plots.chat",
 | 
			
		||||
        category = CommandCategory.CHAT,
 | 
			
		||||
        requiredType = RequiredType.PLAYER)
 | 
			
		||||
public class Chat extends SubCommand {
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onCommand(PlotPlayer<?> player, String[] args) {
 | 
			
		||||
        PlotArea area = player.getPlotAreaAbs();
 | 
			
		||||
        check(area, TranslatableCaption.of("errors.not_in_plot_world"));
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("errors.deprecated_commands"),
 | 
			
		||||
                Template.of("replacement", "/plot toggle chat")
 | 
			
		||||
        );
 | 
			
		||||
        if (player.getPlotAreaAbs().isForcingPlotChat()) {
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("chat.plot_chat_forced"));
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
        MainCommand.getInstance().toggle.chat(this, player, args, null, null);
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
@@ -37,7 +37,9 @@ import com.plotsquared.core.util.EconHandler;
 | 
			
		||||
import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import com.plotsquared.core.util.PlotExpression;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.apache.logging.log4j.LogManager;
 | 
			
		||||
import org.apache.logging.log4j.Logger;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		||||
@@ -81,7 +83,7 @@ public class Claim extends SubCommand {
 | 
			
		||||
        if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                    Template.of("value", "Claim")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("Claim")))
 | 
			
		||||
            );
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
@@ -100,14 +102,14 @@ public class Claim extends SubCommand {
 | 
			
		||||
                    if (grants <= 0) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.cant_claim_more_plots"),
 | 
			
		||||
                                Template.of("amount", String.valueOf(grants))
 | 
			
		||||
                                TagResolver.resolver("amount", Tag.inserting(Component.text(grants)))
 | 
			
		||||
                        );
 | 
			
		||||
                        metaDataAccess.remove();
 | 
			
		||||
                    }
 | 
			
		||||
                } else {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.cant_claim_more_plots"),
 | 
			
		||||
                            Template.of("amount", String.valueOf(player.getAllowedPlots()))
 | 
			
		||||
                            TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots())))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -122,8 +124,10 @@ public class Claim extends SubCommand {
 | 
			
		||||
                    if (!area.hasSchematic(schematic)) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("schematics.schematic_invalid_named"),
 | 
			
		||||
                                Template.of("schemname", schematic),
 | 
			
		||||
                                Template.of("reason", "non-existent")
 | 
			
		||||
                                TagResolver.builder()
 | 
			
		||||
                                        .tag("schemname", Tag.inserting(Component.text(schematic)))
 | 
			
		||||
                                        .tag("reason", Tag.inserting(Component.text("non-existent")))
 | 
			
		||||
                                        .build()
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!player.hasPermission(Permission.PERMISSION_CLAIM_SCHEMATIC
 | 
			
		||||
@@ -132,7 +136,7 @@ public class Claim extends SubCommand {
 | 
			
		||||
                    ) && !force) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_schematic_permission"),
 | 
			
		||||
                                Template.of("value", schematic)
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(schematic)))
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -148,16 +152,28 @@ public class Claim extends SubCommand {
 | 
			
		||||
                    if (this.econHandler.getMoney(player) < cost) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("economy.cannot_afford_plot"),
 | 
			
		||||
                                Template.of("money", this.econHandler.format(cost)),
 | 
			
		||||
                                Template.of("balance", this.econHandler.format(this.econHandler.getMoney(player)))
 | 
			
		||||
                                TagResolver.builder()
 | 
			
		||||
                                        .tag("money", Tag.inserting(Component.text(this.econHandler.format(cost))))
 | 
			
		||||
                                        .tag(
 | 
			
		||||
                                                "balance",
 | 
			
		||||
                                                Tag.inserting(Component.text(this.econHandler.format(this.econHandler.getMoney(
 | 
			
		||||
                                                        player))))
 | 
			
		||||
                                        )
 | 
			
		||||
                                        .build()
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    this.econHandler.withdrawMoney(player, cost);
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("economy.removed_balance"),
 | 
			
		||||
                            Template.of("money", this.econHandler.format(cost)),
 | 
			
		||||
                            Template.of("balance", this.econHandler.format(this.econHandler.getMoney(player)))
 | 
			
		||||
                            TagResolver.builder()
 | 
			
		||||
                                    .tag("money", Tag.inserting(Component.text(this.econHandler.format(cost))))
 | 
			
		||||
                                    .tag(
 | 
			
		||||
                                            "balance",
 | 
			
		||||
                                            Tag.inserting(Component.text(this.econHandler.format(this.econHandler.getMoney(
 | 
			
		||||
                                                    player))))
 | 
			
		||||
                                    )
 | 
			
		||||
                                    .build()
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
@@ -169,8 +185,10 @@ public class Claim extends SubCommand {
 | 
			
		||||
                }
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("economy.removed_granted_plot"),
 | 
			
		||||
                        Template.of("usedGrants", String.valueOf((grants - 1))),
 | 
			
		||||
                        Template.of("remainingGrants", String.valueOf(grants))
 | 
			
		||||
                        TagResolver.builder()
 | 
			
		||||
                                .tag("usedGrants", Tag.inserting(Component.text(grants - 1)))
 | 
			
		||||
                                .tag("remainingGrants", Tag.inserting(Component.text(grants)))
 | 
			
		||||
                                .build()
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
@@ -196,7 +214,7 @@ public class Claim extends SubCommand {
 | 
			
		||||
                        if (mergeEvent.getEventResult() == Result.DENY) {
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                                    Template.of("value", "Auto merge on claim")
 | 
			
		||||
                                    TagResolver.resolver("value", Tag.inserting(Component.text("Auto merge on claim")))
 | 
			
		||||
                            );
 | 
			
		||||
                        } else {
 | 
			
		||||
                            if (plot.getPlotModificationManager().autoMerge(
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,9 @@ import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal2;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal3;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.CompletableFuture;
 | 
			
		||||
@@ -78,7 +80,7 @@ public class Clear extends Command {
 | 
			
		||||
        if (eventResult == Result.DENY) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                    Template.of("value", "Clear")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("Clear")))
 | 
			
		||||
            );
 | 
			
		||||
            return CompletableFuture.completedFuture(true);
 | 
			
		||||
        }
 | 
			
		||||
@@ -105,36 +107,35 @@ public class Clear extends Command {
 | 
			
		||||
            }
 | 
			
		||||
            BackupManager.backup(player, plot, () -> {
 | 
			
		||||
                final long start = System.currentTimeMillis();
 | 
			
		||||
                boolean result = plot.getPlotModificationManager().clear(true, false, player, () -> {
 | 
			
		||||
                    plot.getPlotModificationManager().unlink();
 | 
			
		||||
                    TaskManager.runTask(() -> {
 | 
			
		||||
                        plot.removeRunning();
 | 
			
		||||
                        // If the state changes, then mark it as no longer done
 | 
			
		||||
                        if (DoneFlag.isDone(plot)) {
 | 
			
		||||
                            PlotFlag<?, ?> plotFlag =
 | 
			
		||||
                                    plot.getFlagContainer().getFlag(DoneFlag.class);
 | 
			
		||||
                            PlotFlagRemoveEvent event = this.eventDispatcher
 | 
			
		||||
                                    .callFlagRemove(plotFlag, plot);
 | 
			
		||||
                            if (event.getEventResult() != Result.DENY) {
 | 
			
		||||
                                plot.removeFlag(event.getFlag());
 | 
			
		||||
                            }
 | 
			
		||||
                boolean result = plot.getPlotModificationManager().clear(true, false, player, () -> TaskManager.runTask(() -> {
 | 
			
		||||
                    plot.removeRunning();
 | 
			
		||||
                    // If the state changes, then mark it as no longer done
 | 
			
		||||
                    if (DoneFlag.isDone(plot)) {
 | 
			
		||||
                        PlotFlag<?, ?> plotFlag =
 | 
			
		||||
                                plot.getFlagContainer().getFlag(DoneFlag.class);
 | 
			
		||||
                        PlotFlagRemoveEvent event = this.eventDispatcher
 | 
			
		||||
                                .callFlagRemove(plotFlag, plot);
 | 
			
		||||
                        if (event.getEventResult() != Result.DENY) {
 | 
			
		||||
                            plot.removeFlag(event.getFlag());
 | 
			
		||||
                        }
 | 
			
		||||
                        if (!plot.getFlag(AnalysisFlag.class).isEmpty()) {
 | 
			
		||||
                            PlotFlag<?, ?> plotFlag =
 | 
			
		||||
                                    plot.getFlagContainer().getFlag(AnalysisFlag.class);
 | 
			
		||||
                            PlotFlagRemoveEvent event = this.eventDispatcher
 | 
			
		||||
                                    .callFlagRemove(plotFlag, plot);
 | 
			
		||||
                            if (event.getEventResult() != Result.DENY) {
 | 
			
		||||
                                plot.removeFlag(event.getFlag());
 | 
			
		||||
                            }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!plot.getFlag(AnalysisFlag.class).isEmpty()) {
 | 
			
		||||
                        PlotFlag<?, ?> plotFlag =
 | 
			
		||||
                                plot.getFlagContainer().getFlag(AnalysisFlag.class);
 | 
			
		||||
                        PlotFlagRemoveEvent event = this.eventDispatcher
 | 
			
		||||
                                .callFlagRemove(plotFlag, plot);
 | 
			
		||||
                        if (event.getEventResult() != Result.DENY) {
 | 
			
		||||
                            plot.removeFlag(event.getFlag());
 | 
			
		||||
                        }
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("working.clearing_done"),
 | 
			
		||||
                                Template.of("amount", String.valueOf(System.currentTimeMillis() - start)),
 | 
			
		||||
                                Template.of("plot", plot.getId().toString())
 | 
			
		||||
                        );
 | 
			
		||||
                    });
 | 
			
		||||
                });
 | 
			
		||||
                    }
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("working.clearing_done"),
 | 
			
		||||
                            TagResolver.builder()
 | 
			
		||||
                                    .tag("amount", Tag.inserting(Component.text(System.currentTimeMillis() - start)))
 | 
			
		||||
                                    .tag("plot", Tag.inserting(Component.text(plot.getId().toString())))
 | 
			
		||||
                                    .build()
 | 
			
		||||
                    );
 | 
			
		||||
                }));
 | 
			
		||||
                if (!result) {
 | 
			
		||||
                    player.sendMessage(TranslatableCaption.of("errors.wait_for_timer"));
 | 
			
		||||
                } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -32,19 +32,26 @@ import com.plotsquared.core.plot.Plot;
 | 
			
		||||
import com.plotsquared.core.plot.PlotArea;
 | 
			
		||||
import com.plotsquared.core.plot.PlotCluster;
 | 
			
		||||
import com.plotsquared.core.plot.PlotId;
 | 
			
		||||
import com.plotsquared.core.util.ComponentHelper;
 | 
			
		||||
import com.plotsquared.core.util.TabCompletions;
 | 
			
		||||
import com.plotsquared.core.util.query.PlotQuery;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
import net.kyori.adventure.text.format.NamedTextColor;
 | 
			
		||||
import net.kyori.adventure.text.format.Style;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.Tag;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashSet;
 | 
			
		||||
import java.util.LinkedList;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
import java.util.Set;
 | 
			
		||||
import java.util.UUID;
 | 
			
		||||
import java.util.concurrent.TimeoutException;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import java.util.stream.Stream;
 | 
			
		||||
 | 
			
		||||
@CommandDeclaration(command = "cluster",
 | 
			
		||||
        aliases = "clusters",
 | 
			
		||||
@@ -53,36 +60,39 @@ import java.util.stream.Collectors;
 | 
			
		||||
        permission = "plots.cluster")
 | 
			
		||||
public class Cluster extends SubCommand {
 | 
			
		||||
 | 
			
		||||
    private static final Component[] AVAILABLE_ARGS = Stream.of(
 | 
			
		||||
            "list", "create", "delete", "resize", "invite", "kick", "leave", "helpers", "tp", "sethome"
 | 
			
		||||
    ).map(s -> Component.text(s).style(Style.style(NamedTextColor.DARK_AQUA))).toArray(Component[]::new);
 | 
			
		||||
    private static final Component SEPARATOR = Component.text(", ").style(Style.style(NamedTextColor.GRAY));
 | 
			
		||||
 | 
			
		||||
    // list, create, delete, resize, invite, kick, leave, helpers, tp, sethome
 | 
			
		||||
    @Override
 | 
			
		||||
    public boolean onCommand(PlotPlayer<?> player, String[] args) {
 | 
			
		||||
 | 
			
		||||
        // list, create, delete, resize, invite, kick, leave, helpers, tp, sethome
 | 
			
		||||
        if (args.length == 0) {
 | 
			
		||||
            // return arguments
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("cluster.cluster_available_args"),
 | 
			
		||||
                    Template.of(
 | 
			
		||||
                            "list",
 | 
			
		||||
                            "<dark_aqua>list</dark_aqua><gray>, </gray><dark_aqua>create</dark_aqua><gray>, </gray><dark_aqua>delete</dark_aqua><gray>, </gray><dark_aqua>resize</dark_aqua><gray>, </gray><dark_aqua>invite</dark_aqua><gray>, </gray><dark_aqua>kick</dark_aqua><gray>, </gray><dark_aqua>leave</dark_aqua><gray>, </gray><dark_aqua>members</dark_aqua><gray>, </gray><dark_aqua>info</dark_aqua><gray>, </gray><dark_aqua>tp</dark_aqua><gray>, </gray><dark_aqua>sethome</dark_aqua>"
 | 
			
		||||
                    )
 | 
			
		||||
                    TagResolver.resolver("list", Tag.inserting(ComponentHelper.join(AVAILABLE_ARGS, SEPARATOR)))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        String sub = args[0].toLowerCase();
 | 
			
		||||
        switch (sub) {
 | 
			
		||||
            case "l":
 | 
			
		||||
            case "list": {
 | 
			
		||||
            case "l", "list" -> {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_CLUSTER_LIST)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_CLUSTER_LIST))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_CLUSTER_LIST)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 1) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot cluster list")
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text("/plot cluster list")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -94,7 +104,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                Set<PlotCluster> clusters = area.getClusters();
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("cluster.cluster_list_heading"),
 | 
			
		||||
                        Template.of("amount", clusters.size() + "")
 | 
			
		||||
                        TagResolver.resolver("amount", Tag.inserting(Component.text(clusters.size())))
 | 
			
		||||
                );
 | 
			
		||||
                for (PlotCluster cluster : clusters) {
 | 
			
		||||
                    // Ignore unmanaged clusters
 | 
			
		||||
@@ -102,33 +112,35 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                    if (player.getUUID().equals(cluster.owner)) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("cluster.cluster_list_element_owner"),
 | 
			
		||||
                                Template.of("cluster", name)
 | 
			
		||||
                                TagResolver.resolver("cluster", Tag.inserting(Component.text(name)))
 | 
			
		||||
                        );
 | 
			
		||||
                    } else if (cluster.helpers.contains(player.getUUID())) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("cluster.cluster_list_element_helpers"),
 | 
			
		||||
                                Template.of("cluster", name)
 | 
			
		||||
                                TagResolver.resolver("cluster", Tag.inserting(Component.text(name)))
 | 
			
		||||
                        );
 | 
			
		||||
                    } else if (cluster.invited.contains(player.getUUID())) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("cluster.cluster_list_element_invited"),
 | 
			
		||||
                                Template.of("cluster", name)
 | 
			
		||||
                                TagResolver.resolver("cluster", Tag.inserting(Component.text(name)))
 | 
			
		||||
                        );
 | 
			
		||||
                    } else {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("cluster.cluster_list_element"),
 | 
			
		||||
                                Template.of("cluster", cluster.toString())
 | 
			
		||||
                                TagResolver.resolver("cluster", Tag.inserting(Component.text(cluster.toString())))
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "c":
 | 
			
		||||
            case "create": {
 | 
			
		||||
            case "c", "create" -> {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_CLUSTER_CREATE)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_CLUSTER_CREATE))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_CLUSTER_CREATE)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -140,7 +152,10 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                if (args.length != 4) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot cluster create <name> <id-bot> <id-top>")
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "value",
 | 
			
		||||
                                    Tag.inserting(Component.text("/plot cluster create <name> <id-bot> <id-top>"))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -150,7 +165,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                if (currentClusters >= player.getAllowedPlots()) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.cant_claim_more_clusters"),
 | 
			
		||||
                            Template.of("amount", String.valueOf(player.getAllowedPlots()))
 | 
			
		||||
                            TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots())))
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                PlotId pos1;
 | 
			
		||||
@@ -168,7 +183,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                if (area.getCluster(name) != null) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("alias.alias_is_taken"),
 | 
			
		||||
                            Template.of("alias", name)
 | 
			
		||||
                            TagResolver.resolver("alias", Tag.inserting(Component.text(name)))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -182,7 +197,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                if (cluster != null) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("cluster.cluster_intersection"),
 | 
			
		||||
                            Template.of("cluster", cluster.getName())
 | 
			
		||||
                            TagResolver.resolver("cluster", Tag.inserting(Component.text(cluster.getName())))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -190,7 +205,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                if (!area.contains(pos1) || !area.contains(pos2)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("cluster.cluster_outside"),
 | 
			
		||||
                            Template.of("area", String.valueOf(area))
 | 
			
		||||
                            TagResolver.resolver("area", Tag.inserting(Component.text(area.toString())))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -202,7 +217,10 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                            if (!plot.isOwner(uuid)) {
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                        Template.of("node", String.valueOf(Permission.PERMISSION_CLUSTER_CREATE_OTHER))
 | 
			
		||||
                                        TagResolver.resolver(
 | 
			
		||||
                                                "node",
 | 
			
		||||
                                                Tag.inserting(Permission.PERMISSION_CLUSTER_CREATE_OTHER)
 | 
			
		||||
                                        )
 | 
			
		||||
                                );
 | 
			
		||||
                                return false;
 | 
			
		||||
                            }
 | 
			
		||||
@@ -224,7 +242,10 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                if (current + cluster.getArea() > allowed) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_CLUSTER_SIZE + "." + (current + cluster.getArea()))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Component.text(Permission.PERMISSION_CLUSTER_SIZE + "." + (current + cluster.getArea())))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -243,24 +264,25 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                }
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("cluster.cluster_created"),
 | 
			
		||||
                        Template.of("name", name)
 | 
			
		||||
                        TagResolver.resolver("name", Tag.inserting(Component.text(name)))
 | 
			
		||||
                );
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "disband":
 | 
			
		||||
            case "del":
 | 
			
		||||
            case "delete": {
 | 
			
		||||
            case "disband", "del", "delete" -> {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_CLUSTER_DELETE)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_CLUSTER_DELETE))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_CLUSTER_DELETE)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 1 && args.length != 2) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot cluster delete [name]")
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text("/plot cluster delete [name]")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -275,7 +297,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                    if (cluster == null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("cluster.invalid_cluster_name"),
 | 
			
		||||
                                Template.of("cluster", args[1])
 | 
			
		||||
                                TagResolver.resolver("cluster", Tag.inserting(Component.text(args[1])))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -290,31 +312,36 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                    if (!player.hasPermission(Permission.PERMISSION_CLUSTER_DELETE_OTHER)) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                Template.of("node", String.valueOf(Permission.PERMISSION_CLUSTER_DELETE_OTHER))
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_CLUSTER_DELETE_OTHER)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                DBFunc.delete(cluster);
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("cluster.cluster_deleted"), Template.of(
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("cluster.cluster_deleted"), TagResolver.resolver(
 | 
			
		||||
                        "cluster",
 | 
			
		||||
                        String.valueOf(cluster)
 | 
			
		||||
                        Tag.inserting(Component.text(cluster.toString()))
 | 
			
		||||
                ));
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "res":
 | 
			
		||||
            case "resize": {
 | 
			
		||||
            case "res", "resize" -> {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_CLUSTER_RESIZE)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_CLUSTER_RESIZE))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_CLUSTER_RESIZE)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 3) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot cluster resize [name]")
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text("/plot cluster resize [name]")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -347,7 +374,10 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                    if (!player.hasPermission(Permission.PERMISSION_CLUSTER_RESIZE_OTHER)) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                Template.of("node", String.valueOf(Permission.PERMISSION_CLUSTER_RESIZE_OTHER))
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_CLUSTER_RESIZE_OTHER)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -357,13 +387,12 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                if (intersect != null) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("cluster.cluster_intersection"),
 | 
			
		||||
                            Template.of("cluster", intersect.getName())
 | 
			
		||||
                            TagResolver.resolver("cluster", Tag.inserting(Component.text(intersect.getName())))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                Set<Plot> existing = area.getPlotSelectionOwned(cluster.getP1(), cluster.getP2());
 | 
			
		||||
                Set<Plot> newPlots = area.getPlotSelectionOwned(pos1, pos2);
 | 
			
		||||
                // Set<Plot> removed = (HashSet<Plot>) existing.clone();
 | 
			
		||||
                Set<Plot> removed = new HashSet<>(existing);
 | 
			
		||||
 | 
			
		||||
                removed.removeAll(newPlots);
 | 
			
		||||
@@ -372,7 +401,10 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                    if (!player.hasPermission(Permission.PERMISSION_CLUSTER_RESIZE_SHRINK)) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                Template.of("node", String.valueOf(Permission.PERMISSION_CLUSTER_RESIZE_SHRINK))
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_CLUSTER_RESIZE_SHRINK)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -382,7 +414,10 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                    if (!player.hasPermission(Permission.PERMISSION_CLUSTER_RESIZE_EXPAND)) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                Template.of("node", String.valueOf(Permission.PERMISSION_CLUSTER_RESIZE_EXPAND))
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_CLUSTER_RESIZE_EXPAND)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -402,7 +437,9 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                if (current + cluster.getArea() > allowed) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_CLUSTER + "." + (current + cluster.getArea()))
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text(
 | 
			
		||||
                                    Permission.PERMISSION_CLUSTER + "." + (current + cluster.getArea())
 | 
			
		||||
                            )))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -411,20 +448,21 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("cluster.cluster_resized"));
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "add":
 | 
			
		||||
            case "inv":
 | 
			
		||||
            case "invite": {
 | 
			
		||||
            case "add", "inv", "invite" -> {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_CLUSTER_INVITE)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", String.valueOf(Permission.PERMISSION_CLUSTER_INVITE))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_CLUSTER_INVITE)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 2) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot cluster invite <player>")
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text("/plot cluster invite <player>")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -442,7 +480,10 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                    if (!player.hasPermission(Permission.PERMISSION_CLUSTER_INVITE_OTHER)) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                Template.of("node", Permission.PERMISSION_CLUSTER_INVITE_OTHER.toString())
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_CLUSTER_INVITE_OTHER)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -455,7 +496,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                            } else if (throwable != null) {
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                                        Template.of("value", args[1])
 | 
			
		||||
                                        TagResolver.resolver("value", Tag.inserting(Component.text(args[1])))
 | 
			
		||||
                                );
 | 
			
		||||
                            } else {
 | 
			
		||||
                                if (!cluster.isAdded(uuid)) {
 | 
			
		||||
@@ -467,7 +508,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                                    if (otherPlayer != null) {
 | 
			
		||||
                                        player.sendMessage(
 | 
			
		||||
                                                TranslatableCaption.of("cluster.cluster_invited"),
 | 
			
		||||
                                                Template.of("cluster", cluster.getName())
 | 
			
		||||
                                                TagResolver.resolver("cluster", Tag.inserting(Component.text(cluster.getName())))
 | 
			
		||||
                                        );
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
@@ -476,20 +517,21 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                        });
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "k":
 | 
			
		||||
            case "remove":
 | 
			
		||||
            case "kick": {
 | 
			
		||||
            case "k", "remove", "kick" -> {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_CLUSTER_KICK)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_CLUSTER_KICK.toString())
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_CLUSTER_KICK)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 2) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot cluster kick <player>")
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text("/plot cluster kick <player>")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -506,7 +548,10 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                    if (!player.hasPermission(Permission.PERMISSION_CLUSTER_KICK_OTHER)) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                Template.of("node", Permission.PERMISSION_CLUSTER_KICK_OTHER.toString())
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_CLUSTER_KICK_OTHER)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -519,7 +564,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                            } else if (throwable != null) {
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                                        Template.of("value", args[1])
 | 
			
		||||
                                        TagResolver.resolver("value", Tag.inserting(Component.text(args[1])))
 | 
			
		||||
                                );
 | 
			
		||||
                            } else {
 | 
			
		||||
                                // Can't kick if the player is yourself, the owner, or not added to the cluster
 | 
			
		||||
@@ -527,7 +572,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                                        || !cluster.isAdded(uuid)) {
 | 
			
		||||
                                    player.sendMessage(
 | 
			
		||||
                                            TranslatableCaption.of("cluster.cannot_kick_player"),
 | 
			
		||||
                                            Template.of("value", cluster.getName())
 | 
			
		||||
                                            TagResolver.resolver("value", Tag.inserting(Component.text(cluster.getName())))
 | 
			
		||||
                                    );
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    if (cluster.helpers.contains(uuid)) {
 | 
			
		||||
@@ -542,7 +587,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                                    if (player2 != null) {
 | 
			
		||||
                                        player.sendMessage(
 | 
			
		||||
                                                TranslatableCaption.of("cluster.cluster_removed"),
 | 
			
		||||
                                                Template.of("cluster", cluster.getName())
 | 
			
		||||
                                                TagResolver.resolver("cluster", Tag.inserting(Component.text(cluster.getName())))
 | 
			
		||||
                                        );
 | 
			
		||||
                                    }
 | 
			
		||||
                                    removePlayerPlots(cluster, uuid, player2.getLocation().getWorldName());
 | 
			
		||||
@@ -552,19 +597,21 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                        });
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "quit":
 | 
			
		||||
            case "leave": {
 | 
			
		||||
            case "quit", "leave" -> {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_CLUSTER_LEAVE)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_CLUSTER_LEAVE.toString())
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_CLUSTER_LEAVE)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 1 && args.length != 2) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot cluster leave [name]")
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text("/plot cluster leave [name]")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -578,7 +625,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                    if (cluster == null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("cluster.invalid_cluster_name"),
 | 
			
		||||
                                Template.of("cluster", args[1])
 | 
			
		||||
                                TagResolver.resolver("cluster", Tag.inserting(Component.text(args[1])))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -606,23 +653,29 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                DBFunc.removeInvited(cluster, uuid);
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("cluster.cluster_removed"),
 | 
			
		||||
                        Template.of("cluster", cluster.getName())
 | 
			
		||||
                        TagResolver.resolver("cluster", Tag.inserting(Component.text(cluster.getName())))
 | 
			
		||||
                );
 | 
			
		||||
                removePlayerPlots(cluster, uuid, player.getLocation().getWorldName());
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "members": {
 | 
			
		||||
            case "members" -> {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_CLUSTER_HELPERS)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_CLUSTER_HELPERS.toString())
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Component.text(Permission.PERMISSION_CLUSTER_HELPERS.toString()))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 3) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot cluster members <add | remove> <player>")
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "value",
 | 
			
		||||
                                    Tag.inserting(Component.text("/plot cluster members <add | remove> <player>"))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -643,7 +696,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                            } else if (throwable != null) {
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                                        Template.of("value", args[2])
 | 
			
		||||
                                        TagResolver.resolver("value", Tag.inserting(Component.text(args[2])))
 | 
			
		||||
                                );
 | 
			
		||||
                            } else {
 | 
			
		||||
                                if (args[1].equalsIgnoreCase("add")) {
 | 
			
		||||
@@ -657,27 +710,30 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    player.sendMessage(
 | 
			
		||||
                                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                                            Template.of("value", "/plot cluster members <add | remove> <player>")
 | 
			
		||||
                                            TagResolver.resolver("value", Tag.inserting(Component.text(
 | 
			
		||||
                                                    "/plot cluster members <add | remove> <player>"
 | 
			
		||||
                                            )))
 | 
			
		||||
                                    );
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        });
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "spawn":
 | 
			
		||||
            case "home":
 | 
			
		||||
            case "tp": {
 | 
			
		||||
            case "spawn", "home", "tp" -> {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_CLUSTER_TP)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_CLUSTER_TP.toString())
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_CLUSTER_TP)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 2) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot cluster tp <name>")
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text("/plot cluster tp <name>")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -690,7 +746,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                if (cluster == null) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("cluster.invalid_cluster_name"),
 | 
			
		||||
                            Template.of("cluster", args[1])
 | 
			
		||||
                            TagResolver.resolver("cluster", Tag.inserting(Component.text(args[1])))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -699,7 +755,10 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                    if (!player.hasPermission(Permission.PERMISSION_CLUSTER_TP_OTHER)) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                Template.of("node", Permission.PERMISSION_CLUSTER_TP_OTHER.toString())
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_CLUSTER_TP_OTHER)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -708,21 +767,21 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("cluster.cluster_teleporting"));
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "i":
 | 
			
		||||
            case "info":
 | 
			
		||||
            case "show":
 | 
			
		||||
            case "information": {
 | 
			
		||||
            case "i", "info", "show", "information" -> {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_CLUSTER_INFO)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_CLUSTER_TP.toString())
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    Tag.inserting(Permission.PERMISSION_CLUSTER_TP)
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 1 && args.length != 2) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot cluster info [name]")
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text("/plot cluster info [name]")))
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                PlotArea area = player.getApplicablePlotArea();
 | 
			
		||||
@@ -736,7 +795,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                    if (cluster == null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("cluster.invalid_cluster_name"),
 | 
			
		||||
                                Template.of("cluster", args[1])
 | 
			
		||||
                                TagResolver.resolver("cluster", Tag.inserting(Component.text(args[1])))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -755,47 +814,36 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                                player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout"));
 | 
			
		||||
                            } else {
 | 
			
		||||
                                final String owner;
 | 
			
		||||
                                if (username == null) {
 | 
			
		||||
                                    owner = "unknown";
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    owner = username;
 | 
			
		||||
                                }
 | 
			
		||||
                                owner = Objects.requireNonNullElse(username, "unknown");
 | 
			
		||||
                                String name = cluster.getName();
 | 
			
		||||
                                String size = (cluster.getP2().getX() - cluster.getP1().getX() + 1) + "x" + (
 | 
			
		||||
                                        cluster.getP2().getY() - cluster.getP1().getY() + 1);
 | 
			
		||||
                                String rights = cluster.isAdded(player.getUUID()) + "";
 | 
			
		||||
                                Caption message = TranslatableCaption.of("cluster.cluster_info");
 | 
			
		||||
                                Template idTemplate = Template.of("id", id);
 | 
			
		||||
                                Template ownerTemplate = Template.of("owner", owner);
 | 
			
		||||
                                Template nameTemplate = Template.of("name", name);
 | 
			
		||||
                                Template sizeTemplate = Template.of("size", size);
 | 
			
		||||
                                Template rightsTemplate = Template.of("rights", rights);
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        message,
 | 
			
		||||
                                        idTemplate,
 | 
			
		||||
                                        ownerTemplate,
 | 
			
		||||
                                        nameTemplate,
 | 
			
		||||
                                        sizeTemplate,
 | 
			
		||||
                                        rightsTemplate
 | 
			
		||||
                                );
 | 
			
		||||
                                TagResolver resolver = TagResolver.builder()
 | 
			
		||||
                                        .tag("id", Tag.inserting(Component.text(id)))
 | 
			
		||||
                                        .tag("owner", Tag.inserting(Component.text(owner)))
 | 
			
		||||
                                        .tag("name", Tag.inserting(Component.text(name)))
 | 
			
		||||
                                        .tag("size", Tag.inserting(Component.text(size)))
 | 
			
		||||
                                        .tag("rights", Tag.inserting(Component.text(rights)))
 | 
			
		||||
                                        .build();
 | 
			
		||||
                                player.sendMessage(message, resolver);
 | 
			
		||||
                            }
 | 
			
		||||
                        });
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
            case "sh":
 | 
			
		||||
            case "setspawn":
 | 
			
		||||
            case "sethome": {
 | 
			
		||||
            case "sh", "setspawn", "sethome" -> {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_CLUSTER_SETHOME)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_CLUSTER_SETHOME.toString())
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Permission.PERMISSION_CLUSTER_SETHOME))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length != 1 && args.length != 2) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot cluster sethome")
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text("/plot cluster sethome")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -812,7 +860,10 @@ public class Cluster extends SubCommand {
 | 
			
		||||
                    if (!player.hasPermission(Permission.PERMISSION_CLUSTER_SETHOME_OTHER)) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                Template.of("node", Permission.PERMISSION_CLUSTER_SETHOME_OTHER.toString())
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_CLUSTER_SETHOME_OTHER)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -831,10 +882,7 @@ public class Cluster extends SubCommand {
 | 
			
		||||
        }
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("cluster.cluster_available_args"),
 | 
			
		||||
                Template.of(
 | 
			
		||||
                        "list",
 | 
			
		||||
                        "<dark_aqua>list</dark_aqua><gray>, </gray><dark_aqua>create</dark_aqua><gray>, </gray><dark_aqua>delete</dark_aqua><gray>, </gray><dark_aqua>resize</dark_aqua><gray>, </gray><dark_aqua>invite</dark_aqua><gray>, </gray><dark_aqua>kick</dark_aqua><gray>, </gray><dark_aqua>leave</dark_aqua><gray>, </gray><dark_aqua>members</dark_aqua><gray>, </gray><dark_aqua>info</dark_aqua><gray>, </gray><dark_aqua>tp</dark_aqua><gray>, </gray><dark_aqua>sethome</dark_aqua>"
 | 
			
		||||
                )
 | 
			
		||||
                TagResolver.resolver("list", Tag.inserting(ComponentHelper.join(AVAILABLE_ARGS, SEPARATOR)))
 | 
			
		||||
        );
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,9 @@ import com.plotsquared.core.player.PlayerMetaDataKeys;
 | 
			
		||||
import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskTime;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.Nullable;
 | 
			
		||||
 | 
			
		||||
public class CmdConfirm {
 | 
			
		||||
@@ -52,9 +54,11 @@ public class CmdConfirm {
 | 
			
		||||
        if (commandStr != null) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("confirm.requires_confirm"),
 | 
			
		||||
                    Template.of("command", commandStr),
 | 
			
		||||
                    Template.of("timeout", String.valueOf(Settings.Confirmation.CONFIRMATION_TIMEOUT_SECONDS)),
 | 
			
		||||
                    Template.of("value", "/plot confirm")
 | 
			
		||||
                    TagResolver.builder()
 | 
			
		||||
                            .tag("command", Tag.inserting(Component.text(commandStr)))
 | 
			
		||||
                            .tag("timeout", Tag.inserting(Component.text(Settings.Confirmation.CONFIRMATION_TIMEOUT_SECONDS)))
 | 
			
		||||
                            .tag("value", Tag.inserting(Component.text("/plot confirm")))
 | 
			
		||||
                            .build()
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        TaskManager.runTaskLater(() -> {
 | 
			
		||||
 
 | 
			
		||||
@@ -29,8 +29,10 @@ import com.plotsquared.core.util.StringComparison;
 | 
			
		||||
import com.plotsquared.core.util.StringMan;
 | 
			
		||||
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.MiniMessage;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.Tag;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
 | 
			
		||||
import java.lang.reflect.InvocationTargetException;
 | 
			
		||||
@@ -255,10 +257,14 @@ public abstract class Command {
 | 
			
		||||
            max = c.size();
 | 
			
		||||
        }
 | 
			
		||||
        // Send the header
 | 
			
		||||
        Template curTemplate = Template.of("cur", String.valueOf(page + 1));
 | 
			
		||||
        Template maxTemplate = Template.of("max", String.valueOf(totalPages + 1));
 | 
			
		||||
        Template amountTemplate = Template.of("amount", String.valueOf(c.size()));
 | 
			
		||||
        player.sendMessage(header, curTemplate, maxTemplate, amountTemplate);
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                header,
 | 
			
		||||
                TagResolver.builder()
 | 
			
		||||
                        .tag("cur", Tag.inserting(Component.text(page + 1)))
 | 
			
		||||
                        .tag("max", Tag.inserting(Component.text(totalPages + 1)))
 | 
			
		||||
                        .tag("amount", Tag.inserting(Component.text(c.size())))
 | 
			
		||||
                        .build()
 | 
			
		||||
        );
 | 
			
		||||
        // Send the page content
 | 
			
		||||
        List<T> subList = c.subList(page * size, max);
 | 
			
		||||
        int i = page * size;
 | 
			
		||||
@@ -266,13 +272,24 @@ public abstract class Command {
 | 
			
		||||
            i++;
 | 
			
		||||
            final CaptionHolder msg = new CaptionHolder();
 | 
			
		||||
            add.run(i, obj, msg);
 | 
			
		||||
            player.sendMessage(msg.get(), msg.getTemplates());
 | 
			
		||||
            player.sendMessage(msg.get(), msg.getTagResolvers());
 | 
			
		||||
        }
 | 
			
		||||
        // Send the footer
 | 
			
		||||
        Template command1 = Template.of("command1", baseCommand + " " + page);
 | 
			
		||||
        Template command2 = Template.of("command2", baseCommand + " " + (page + 2));
 | 
			
		||||
        Template clickable = Template.of("clickable", TranslatableCaption.of("list.clickable").getComponent(player));
 | 
			
		||||
        player.sendMessage(TranslatableCaption.of("list.page_turn"), command1, command2, clickable);
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("list.page_turn"),
 | 
			
		||||
                TagResolver.builder()
 | 
			
		||||
                        .tag("cur", Tag.inserting(Component.text(page + 1)))
 | 
			
		||||
                        .tag(
 | 
			
		||||
                                "command1",
 | 
			
		||||
                                Tag.preProcessParsed(baseCommand + " " + page)
 | 
			
		||||
                        )
 | 
			
		||||
                        .tag("command2", Tag.preProcessParsed(baseCommand + " " + (page + 2)))
 | 
			
		||||
                        .tag(
 | 
			
		||||
                                "clickable",
 | 
			
		||||
                                Tag.inserting(TranslatableCaption.of("list.clickable").toComponent(player))
 | 
			
		||||
                        )
 | 
			
		||||
                        .build()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -324,7 +341,7 @@ public abstract class Command {
 | 
			
		||||
            if (commands.isEmpty()) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("commandconfig.did_you_mean"),
 | 
			
		||||
                        Template.of("value", MainCommand.getInstance().help.getUsage())
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text(MainCommand.getInstance().help.getUsage())))
 | 
			
		||||
                );
 | 
			
		||||
                return CompletableFuture.completedFuture(false);
 | 
			
		||||
            }
 | 
			
		||||
@@ -345,7 +362,7 @@ public abstract class Command {
 | 
			
		||||
            }
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.did_you_mean"),
 | 
			
		||||
                    Template.of("value", cmd.getUsage())
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text(cmd.getUsage())))
 | 
			
		||||
            );
 | 
			
		||||
            return CompletableFuture.completedFuture(false);
 | 
			
		||||
        }
 | 
			
		||||
@@ -380,7 +397,7 @@ public abstract class Command {
 | 
			
		||||
                // TODO improve or remove the Argument system
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                        Template.of("value", StringMan.join(fullSplit, " "))
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text(StringMan.join(fullSplit, " "))))
 | 
			
		||||
                );
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
@@ -469,7 +486,7 @@ public abstract class Command {
 | 
			
		||||
            if (message) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                        Template.of("node", getPermission())
 | 
			
		||||
                        TagResolver.resolver("node", Tag.inserting(Component.text(getPermission())))
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
@@ -494,7 +511,7 @@ public abstract class Command {
 | 
			
		||||
    public void sendUsage(PlotPlayer<?> player) {
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                Template.of("value", getUsage())
 | 
			
		||||
                TagResolver.resolver("value", Tag.inserting(Component.text(getUsage())))
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -542,9 +559,10 @@ public abstract class Command {
 | 
			
		||||
 | 
			
		||||
    public Collection<Command> tab(PlotPlayer<?> player, String[] args, boolean space) {
 | 
			
		||||
        switch (args.length) {
 | 
			
		||||
            case 0:
 | 
			
		||||
            case 0 -> {
 | 
			
		||||
                return this.allCommands;
 | 
			
		||||
            case 1:
 | 
			
		||||
            }
 | 
			
		||||
            case 1 -> {
 | 
			
		||||
                String arg = args[0].toLowerCase();
 | 
			
		||||
                if (space) {
 | 
			
		||||
                    Command cmd = getCommand(arg);
 | 
			
		||||
@@ -563,13 +581,15 @@ public abstract class Command {
 | 
			
		||||
                    }
 | 
			
		||||
                    return commands;
 | 
			
		||||
                }
 | 
			
		||||
            default:
 | 
			
		||||
            }
 | 
			
		||||
            default -> {
 | 
			
		||||
                Command cmd = getCommand(args[0]);
 | 
			
		||||
                if (cmd != null) {
 | 
			
		||||
                    return cmd.tab(player, Arrays.copyOfRange(args, 1, args.length), space);
 | 
			
		||||
                } else {
 | 
			
		||||
                    return null;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -598,13 +618,13 @@ public abstract class Command {
 | 
			
		||||
        return this.getFullId().hashCode();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void checkTrue(boolean mustBeTrue, Caption message, Template... args) {
 | 
			
		||||
    public void checkTrue(boolean mustBeTrue, Caption message, TagResolver... args) {
 | 
			
		||||
        if (!mustBeTrue) {
 | 
			
		||||
            throw new CommandException(message, args);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public <T> T check(T object, Caption message, Template... args) {
 | 
			
		||||
    public <T> T check(T object, Caption message, TagResolver... args) {
 | 
			
		||||
        if (object == null) {
 | 
			
		||||
            throw new CommandException(message, args);
 | 
			
		||||
        }
 | 
			
		||||
@@ -620,10 +640,10 @@ public abstract class Command {
 | 
			
		||||
 | 
			
		||||
    public static class CommandException extends RuntimeException {
 | 
			
		||||
 | 
			
		||||
        private final Template[] args;
 | 
			
		||||
        private final Caption message;
 | 
			
		||||
        private final TagResolver[] args;
 | 
			
		||||
 | 
			
		||||
        public CommandException(final @Nullable Caption message, final Template... args) {
 | 
			
		||||
        public CommandException(final @Nullable Caption message, final TagResolver... args) {
 | 
			
		||||
            this.message = message;
 | 
			
		||||
            this.args = args;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -19,7 +19,7 @@
 | 
			
		||||
package com.plotsquared.core.command;
 | 
			
		||||
 | 
			
		||||
import com.plotsquared.core.configuration.caption.Caption;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -34,7 +34,7 @@ public interface CommandCaller {
 | 
			
		||||
     * @param caption      Caption to send
 | 
			
		||||
     * @param replacements Variable replacements
 | 
			
		||||
     */
 | 
			
		||||
    void sendMessage(@NonNull Caption caption, @NonNull Template... replacements);
 | 
			
		||||
    void sendMessage(@NonNull Caption caption, @NonNull TagResolver... replacements);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Check the player's permissions. <i>Will be cached if permission caching is enabled.</i>
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,8 @@ import com.plotsquared.core.configuration.caption.Caption;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.LocaleHolder;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
 | 
			
		||||
import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.MiniMessage;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@@ -90,6 +92,11 @@ public enum CommandCategory implements Caption {
 | 
			
		||||
        return this.caption.getComponent(localeHolder);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public @NonNull Component toComponent(@NonNull final LocaleHolder localeHolder) {
 | 
			
		||||
        return MiniMessage.miniMessage().deserialize(getComponent(localeHolder));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Checks if a player has access to this command category
 | 
			
		||||
     *
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,9 @@ import com.plotsquared.core.plot.comment.CommentInbox;
 | 
			
		||||
import com.plotsquared.core.plot.comment.CommentManager;
 | 
			
		||||
import com.plotsquared.core.plot.comment.PlotComment;
 | 
			
		||||
import com.plotsquared.core.util.StringMan;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.Arrays;
 | 
			
		||||
import java.util.Locale;
 | 
			
		||||
@@ -44,8 +46,10 @@ public class Comment extends SubCommand {
 | 
			
		||||
        if (args.length < 2) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("comment.comment_syntax"),
 | 
			
		||||
                    Template.of("command", "/plot comment [X;Z]"),
 | 
			
		||||
                    Template.of("list", StringMan.join(CommentManager.inboxes.keySet(), "|"))
 | 
			
		||||
                    TagResolver.builder()
 | 
			
		||||
                            .tag("command", Tag.inserting(Component.text("/plot comment [X;Z]")))
 | 
			
		||||
                            .tag("list", Tag.inserting(Component.text(StringMan.join(CommentManager.inboxes.keySet(), "|"))))
 | 
			
		||||
                            .build()
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -64,8 +68,10 @@ public class Comment extends SubCommand {
 | 
			
		||||
            if (args.length < 3) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("comment.comment_syntax"),
 | 
			
		||||
                        Template.of("command", "/plot comment [X;Z]"),
 | 
			
		||||
                        Template.of("list", StringMan.join(CommentManager.inboxes.keySet(), "|"))
 | 
			
		||||
                        TagResolver.builder()
 | 
			
		||||
                                .tag("command", Tag.inserting(Component.text("/plot comment [X;Z]")))
 | 
			
		||||
                                .tag("list", Tag.inserting(Component.text(StringMan.join(CommentManager.inboxes.keySet(), "|"))))
 | 
			
		||||
                                .build()
 | 
			
		||||
                );
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
@@ -76,8 +82,10 @@ public class Comment extends SubCommand {
 | 
			
		||||
        if (inbox == null) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("comment.comment_syntax"),
 | 
			
		||||
                    Template.of("command", "/plot comment [X;Z]"),
 | 
			
		||||
                    Template.of("list", StringMan.join(CommentManager.inboxes.keySet(), "|"))
 | 
			
		||||
                    TagResolver.builder()
 | 
			
		||||
                            .tag("command", Tag.inserting(Component.text("/plot comment [X;Z]")))
 | 
			
		||||
                            .tag("list", Tag.inserting(Component.text(StringMan.join(CommentManager.inboxes.keySet(), "|"))))
 | 
			
		||||
                            .build()
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -97,8 +105,10 @@ public class Comment extends SubCommand {
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("comment.no_plot_inbox"));
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("comment.comment_syntax"),
 | 
			
		||||
                    Template.of("command", "/plot comment [X;Z]"),
 | 
			
		||||
                    Template.of("list", StringMan.join(CommentManager.inboxes.keySet(), "|"))
 | 
			
		||||
                    TagResolver.builder()
 | 
			
		||||
                            .tag("command", Tag.inserting(Component.text("/plot comment [X;Z]")))
 | 
			
		||||
                            .tag("list", Tag.inserting(Component.text(StringMan.join(CommentManager.inboxes.keySet(), "|"))))
 | 
			
		||||
                            .build()
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,9 @@ import com.plotsquared.core.util.MathMan;
 | 
			
		||||
import com.plotsquared.core.util.WorldUtil;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskTime;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.ArrayList;
 | 
			
		||||
@@ -68,7 +70,9 @@ public class Condense extends SubCommand {
 | 
			
		||||
        if (args.length != 2 && args.length != 3) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", "/plot condense <area> <start | stop | info> [radius]")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text(
 | 
			
		||||
                            "/plot condense <area> <start | stop | info> [radius]"
 | 
			
		||||
                    )))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -82,7 +86,10 @@ public class Condense extends SubCommand {
 | 
			
		||||
                if (args.length == 2) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot condense" + area + " start <radius>")
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "value",
 | 
			
		||||
                                    Tag.inserting(Component.text("/plot condense" + area + " start " + "<radius>"))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -181,8 +188,10 @@ public class Condense extends SubCommand {
 | 
			
		||||
                                    if (result.get()) {
 | 
			
		||||
                                        player.sendMessage(
 | 
			
		||||
                                                TranslatableCaption.of("condense.moving"),
 | 
			
		||||
                                                Template.of("origin", String.valueOf(origin)),
 | 
			
		||||
                                                Template.of("possible", String.valueOf(possible))
 | 
			
		||||
                                                TagResolver.builder()
 | 
			
		||||
                                                        .tag("origin", Tag.inserting(Component.text(origin.toString())))
 | 
			
		||||
                                                        .tag("possible", Tag.inserting(Component.text(possible.toString())))
 | 
			
		||||
                                                        .build()
 | 
			
		||||
                                        );
 | 
			
		||||
                                        TaskManager.runTaskLater(task, TaskTime.ticks(1L));
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -202,7 +211,7 @@ public class Condense extends SubCommand {
 | 
			
		||||
                        if (i >= free.size()) {
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("condense.skipping"),
 | 
			
		||||
                                    Template.of("plot", String.valueOf(origin))
 | 
			
		||||
                                    TagResolver.resolver("plot", Tag.inserting(Component.text(origin.toString())))
 | 
			
		||||
                            );
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
@@ -223,7 +232,10 @@ public class Condense extends SubCommand {
 | 
			
		||||
                if (args.length == 2) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Template.of("value", "/plot condense " + area + " info <radius>")
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "value",
 | 
			
		||||
                                    Tag.inserting(Component.text("/plot condense " + area + " info <radius>"))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -244,20 +256,20 @@ public class Condense extends SubCommand {
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("condense.default_eval"));
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("condense.minimum_radius"),
 | 
			
		||||
                        Template.of("minimumRadius", String.valueOf(minimumRadius))
 | 
			
		||||
                        TagResolver.resolver("minimumRadius", Tag.inserting(Component.text(minimumRadius)))
 | 
			
		||||
                );
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("condense.minimum_radius"),
 | 
			
		||||
                        Template.of("maxMove", String.valueOf(maxMove))
 | 
			
		||||
                        TranslatableCaption.of("condense.maximum_moved"),
 | 
			
		||||
                        TagResolver.resolver("maxMove", Tag.inserting(Component.text(maxMove)))
 | 
			
		||||
                );
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("condense.input_eval"));
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("condense.input_radius"),
 | 
			
		||||
                        Template.of("radius", String.valueOf(radius))
 | 
			
		||||
                        TagResolver.resolver("radius", Tag.inserting(Component.text(radius)))
 | 
			
		||||
                );
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("condense.estimated_moves"),
 | 
			
		||||
                        Template.of("userMove", String.valueOf(userMove))
 | 
			
		||||
                        TagResolver.resolver("userMove", Tag.inserting(Component.text(userMove)))
 | 
			
		||||
                );
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("condense.eta"));
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("condense.radius_measured"));
 | 
			
		||||
@@ -266,7 +278,10 @@ public class Condense extends SubCommand {
 | 
			
		||||
        }
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                Template.of("value", "/plot condense " + area.getWorldName() + " <start | stop | info> [radius]")
 | 
			
		||||
                TagResolver.resolver(
 | 
			
		||||
                        "value",
 | 
			
		||||
                        Tag.inserting(Component.text("/plot condense " + area.getWorldName() + " <start | stop | info> [radius]"))
 | 
			
		||||
                )
 | 
			
		||||
        );
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,9 @@ import com.plotsquared.core.plot.Plot;
 | 
			
		||||
import com.plotsquared.core.plot.flag.PlotFlag;
 | 
			
		||||
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
 | 
			
		||||
import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
@CommandDeclaration(command = "continue",
 | 
			
		||||
@@ -55,7 +57,9 @@ public class Continue extends SubCommand {
 | 
			
		||||
        if (!plot.isOwner(player.getUUID()) && !player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_CONTINUE)) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                    Template.of("node", TranslatableCaption.of("permission.no_plot_perms").getComponent(player))
 | 
			
		||||
                    TagResolver.resolver("node", Tag.inserting(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_plot_perms").toComponent(player)
 | 
			
		||||
                    ))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -68,7 +72,7 @@ public class Continue extends SubCommand {
 | 
			
		||||
                < player.getPlotCount() + size)) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.cant_claim_more_plots"),
 | 
			
		||||
                    Template.of("amount", String.valueOf(player.getAllowedPlots()))
 | 
			
		||||
                    TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots())))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -82,7 +86,7 @@ public class Continue extends SubCommand {
 | 
			
		||||
        if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                    Template.of("value", "Done flag removal")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("Done flag removal")))
 | 
			
		||||
            );
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,9 @@ 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 net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.Tag;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
 | 
			
		||||
 | 
			
		||||
@CommandDeclaration(command = "copy",
 | 
			
		||||
        permission = "plots.copy",
 | 
			
		||||
@@ -48,7 +50,7 @@ public class Copy extends SubCommand {
 | 
			
		||||
        if (args.length != 1) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", "/plot copy <X;Z>")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("/plot copy <X;Z>")))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -67,8 +69,12 @@ public class Copy extends SubCommand {
 | 
			
		||||
 | 
			
		||||
        plot1.getPlotModificationManager().copy(plot2, player).thenAccept(result -> {
 | 
			
		||||
            if (result) {
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("move.copy_success"), Template.of("origin", String.valueOf(plot1)),
 | 
			
		||||
                        Template.of("target", String.valueOf(plot2))
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("move.copy_success"),
 | 
			
		||||
                        TagResolver.builder()
 | 
			
		||||
                                .tag("origin", Tag.inserting(Component.text(plot1.toString())))
 | 
			
		||||
                                .tag("target", Tag.inserting(Component.text(plot2.toString())))
 | 
			
		||||
                                .build()
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("move.requires_unowned"));
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,9 @@ import com.plotsquared.core.generator.HybridUtils;
 | 
			
		||||
import com.plotsquared.core.location.Location;
 | 
			
		||||
import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import com.plotsquared.core.plot.Plot;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
@CommandDeclaration(command = "createroadschematic",
 | 
			
		||||
@@ -61,7 +63,7 @@ public class CreateRoadSchematic extends SubCommand {
 | 
			
		||||
        this.hybridUtils.setupRoadSchematic(plot);
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("schematics.schematic_road_created"),
 | 
			
		||||
                Template.of("command", "/plot debugroadregen")
 | 
			
		||||
                TagResolver.resolver("command", Tag.inserting(Component.text("/plot debugroadregen")))
 | 
			
		||||
        );
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -40,7 +40,9 @@ import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import com.plotsquared.core.util.FileUtils;
 | 
			
		||||
import com.plotsquared.core.util.query.PlotQuery;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.io.File;
 | 
			
		||||
@@ -101,7 +103,10 @@ public class DatabaseCommand extends SubCommand {
 | 
			
		||||
        if (args.length < 1) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", "/plot database [area] <sqlite | mysql | import>")
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "value",
 | 
			
		||||
                            Tag.inserting(Component.text("/plot database [area] <sqlite | mysql | import>"))
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -116,7 +121,7 @@ public class DatabaseCommand extends SubCommand {
 | 
			
		||||
        if (args.length < 1) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", "/plot database [area] <sqlite|mysql|import>")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("/plot database [area] <sqlite|mysql|import>")))
 | 
			
		||||
            );
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("database.arg"));
 | 
			
		||||
            return false;
 | 
			
		||||
@@ -129,7 +134,10 @@ public class DatabaseCommand extends SubCommand {
 | 
			
		||||
                    if (args.length < 2) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                                Template.of("value", "/plot database import <sqlite file> [prefix]")
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "value",
 | 
			
		||||
                                        Tag.inserting(Component.text("/plot database import <sqlite file> [prefix]"))
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -140,7 +148,7 @@ public class DatabaseCommand extends SubCommand {
 | 
			
		||||
                    if (!file.exists()) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("database.does_not_exist"),
 | 
			
		||||
                                Template.of("value", String.valueOf(file))
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(file.toString())))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -184,8 +192,10 @@ public class DatabaseCommand extends SubCommand {
 | 
			
		||||
                                    }
 | 
			
		||||
                                    player.sendMessage(
 | 
			
		||||
                                            TranslatableCaption.of("database.skipping_duplicated_plot"),
 | 
			
		||||
                                            Template.of("plot", String.valueOf(plot)),
 | 
			
		||||
                                            Template.of("id", String.valueOf(plot.temp))
 | 
			
		||||
                                            TagResolver.builder()
 | 
			
		||||
                                                    .tag("plot", Tag.inserting(Component.text(plot.toString())))
 | 
			
		||||
                                                    .tag("id", Tag.inserting(Component.text(plot.temp)))
 | 
			
		||||
                                                    .build()
 | 
			
		||||
                                    );
 | 
			
		||||
                                    continue;
 | 
			
		||||
                                }
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,8 @@ import com.plotsquared.core.uuid.UUIDMapping;
 | 
			
		||||
import com.sk89q.worldedit.world.entity.EntityType;
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
import net.kyori.adventure.text.TextComponent;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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;
 | 
			
		||||
@@ -68,7 +69,10 @@ public class Debug extends SubCommand {
 | 
			
		||||
        if (args.length == 0) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", "/plot debug <loadedchunks | player | debug-players | entitytypes | msg>")
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "value",
 | 
			
		||||
                            Tag.inserting(Component.text("/plot debug <loadedchunks | player | debug-players | entitytypes | msg>"))
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        if (args.length > 0) {
 | 
			
		||||
@@ -95,7 +99,7 @@ public class Debug extends SubCommand {
 | 
			
		||||
            final Collection<UUIDMapping> mappings = PlotSquared.get().getImpromptuUUIDPipeline().getAllImmediately();
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("debug.cached_uuids"),
 | 
			
		||||
                    Template.of("value", String.valueOf(mappings.size()))
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text(mappings.size())))
 | 
			
		||||
            );
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
@@ -104,7 +108,7 @@ public class Debug extends SubCommand {
 | 
			
		||||
            for (final PlotPlayer<?> pp : PlotPlayer.getDebugModePlayers()) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("debug.player_in_debugmode_list"),
 | 
			
		||||
                        Template.of("value", pp.getName())
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text(pp.getName())))
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            return true;
 | 
			
		||||
@@ -114,10 +118,11 @@ public class Debug extends SubCommand {
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("debug.entity_categories"));
 | 
			
		||||
            EntityCategory.REGISTRY.forEach(category -> {
 | 
			
		||||
                final StringBuilder builder =
 | 
			
		||||
                        new StringBuilder("§7- §6").append(category.getId()).append("§7: §6");
 | 
			
		||||
                        new StringBuilder("<gray>-</gray> <gold>").append(category.getId()).append("</gold><gray>: <gold>");
 | 
			
		||||
                for (final EntityType entityType : category.getAll()) {
 | 
			
		||||
                    builder.append(entityType.getId()).append(" ");
 | 
			
		||||
                }
 | 
			
		||||
                builder.append("</gold>");
 | 
			
		||||
                player.sendMessage(StaticCaption.of("<prefix>" + builder));
 | 
			
		||||
            });
 | 
			
		||||
            EntityType.REGISTRY.values().stream().sorted(Comparator.comparing(EntityType::getId))
 | 
			
		||||
@@ -137,28 +142,53 @@ public class Debug extends SubCommand {
 | 
			
		||||
                .getCaptionMap(TranslatableCaption.DEFAULT_NAMESPACE)
 | 
			
		||||
                .getCaptions();
 | 
			
		||||
        TextComponent.Builder information = Component.text();
 | 
			
		||||
        Component header = MINI_MESSAGE.parse(TranslatableCaption.of("debug.debug_header").getComponent(player) + "\n");
 | 
			
		||||
        Component header = TranslatableCaption.of("debug.debug_header").toComponent(player)
 | 
			
		||||
                .append(Component.newline());
 | 
			
		||||
        String line = TranslatableCaption.of("debug.debug_line").getComponent(player) + "\n";
 | 
			
		||||
        String section = TranslatableCaption.of("debug.debug_section").getComponent(player) + "\n";
 | 
			
		||||
        information.append(header);
 | 
			
		||||
        information.append(MINI_MESSAGE.parse(section, Template.of("val", "PlotArea")));
 | 
			
		||||
        information.append(MINI_MESSAGE.deserialize(
 | 
			
		||||
                section,
 | 
			
		||||
                TagResolver.resolver("val", Tag.inserting(Component.text("PlotArea")))
 | 
			
		||||
        ));
 | 
			
		||||
        information.append(MINI_MESSAGE
 | 
			
		||||
                .parse(
 | 
			
		||||
                .deserialize(
 | 
			
		||||
                        line,
 | 
			
		||||
                        Template.of("var", "Plot Worlds"),
 | 
			
		||||
                        Template.of("val", StringMan.join(this.plotAreaManager.getAllPlotAreas(), ", "))
 | 
			
		||||
                        TagResolver.builder()
 | 
			
		||||
                                .tag("var", Tag.inserting(Component.text("Plot Worlds")))
 | 
			
		||||
                                .tag(
 | 
			
		||||
                                        "val",
 | 
			
		||||
                                        Tag.inserting(Component.text(StringMan.join(
 | 
			
		||||
                                                this.plotAreaManager.getAllPlotAreas(),
 | 
			
		||||
                                                ", "
 | 
			
		||||
                                        )))
 | 
			
		||||
                                )
 | 
			
		||||
                                .build()
 | 
			
		||||
                ));
 | 
			
		||||
        information.append(
 | 
			
		||||
                MINI_MESSAGE.parse(
 | 
			
		||||
                MINI_MESSAGE.deserialize(
 | 
			
		||||
                        line,
 | 
			
		||||
                        Template.of("var", "Owned Plots"),
 | 
			
		||||
                        Template.of("val", String.valueOf(PlotQuery.newQuery().allPlots().count()))
 | 
			
		||||
                        TagResolver.builder()
 | 
			
		||||
                                .tag("var", Tag.inserting(Component.text("Owned Plots")))
 | 
			
		||||
                                .tag(
 | 
			
		||||
                                        "val",
 | 
			
		||||
                                        Tag.inserting(Component.text(PlotQuery.newQuery().allPlots().count()))
 | 
			
		||||
                                )
 | 
			
		||||
                                .build()
 | 
			
		||||
                ));
 | 
			
		||||
        information.append(MINI_MESSAGE.parse(section, Template.of("val", "Messages")));
 | 
			
		||||
        information.append(MINI_MESSAGE.parse(
 | 
			
		||||
        information.append(MINI_MESSAGE.deserialize(
 | 
			
		||||
                section,
 | 
			
		||||
                TagResolver.resolver("val", Tag.inserting(Component.text("Messages")))
 | 
			
		||||
        ));
 | 
			
		||||
        information.append(MINI_MESSAGE.deserialize(
 | 
			
		||||
                line,
 | 
			
		||||
                Template.of("var", "Total Messages"),
 | 
			
		||||
                Template.of("val", String.valueOf(captions.size()))
 | 
			
		||||
                TagResolver.builder()
 | 
			
		||||
                        .tag("var", Tag.inserting(Component.text("Total Messages")))
 | 
			
		||||
                        .tag(
 | 
			
		||||
                                "val",
 | 
			
		||||
                                Tag.inserting(Component.text(captions.size()))
 | 
			
		||||
                        )
 | 
			
		||||
                        .build()
 | 
			
		||||
        ));
 | 
			
		||||
        player.sendMessage(StaticCaption.of(MINI_MESSAGE.serialize(information.build())));
 | 
			
		||||
        return true;
 | 
			
		||||
 
 | 
			
		||||
@@ -36,7 +36,9 @@ import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import com.plotsquared.core.util.StringMan;
 | 
			
		||||
import com.plotsquared.core.util.query.PlotQuery;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.Arrays;
 | 
			
		||||
@@ -95,7 +97,7 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
                    if (analysis != null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("debugexec.changes_column"),
 | 
			
		||||
                                Template.of("value", String.valueOf(analysis.changes))
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(analysis.changes)))
 | 
			
		||||
                        );
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -105,7 +107,7 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
                        public void run(PlotAnalysis value) {
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("debugexec.analyze_done"),
 | 
			
		||||
                                    Template.of("command", "/plot debugexec analyze")
 | 
			
		||||
                                    TagResolver.resolver("command", Tag.inserting(Component.text("/plot debugexec analyze")))
 | 
			
		||||
                            );
 | 
			
		||||
                        }
 | 
			
		||||
                    });
 | 
			
		||||
@@ -115,7 +117,10 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
                    if (args.length != 2) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                                Template.of("value", "/plot debugexec analyze <threshold>")
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "value",
 | 
			
		||||
                                        Tag.inserting(Component.text("/plot debugexec analyze <threshold>"))
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        player.sendMessage(TranslatableCaption.of("debugexec.threshold_default"));
 | 
			
		||||
                        return false;
 | 
			
		||||
@@ -126,7 +131,7 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
                    } catch (NumberFormatException ignored) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("debugexec.invalid_threshold"),
 | 
			
		||||
                                Template.of("value", args[1])
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(args[1])))
 | 
			
		||||
                        );
 | 
			
		||||
                        player.sendMessage(TranslatableCaption.of("debugexec.threshold_default_double"));
 | 
			
		||||
                        return false;
 | 
			
		||||
@@ -157,7 +162,7 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
                    if (args.length != 2) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                                Template.of("value", "/plot debugexec remove-flag <flag>")
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text("/plot debugexec remove-flag <flag>")))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -175,7 +180,7 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
                    }
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("debugexec.cleared_flag"),
 | 
			
		||||
                            Template.of("value", flag)
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text(flag)))
 | 
			
		||||
                    );
 | 
			
		||||
                    return true;
 | 
			
		||||
                }
 | 
			
		||||
@@ -183,7 +188,10 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
                    if (args.length != 2) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                                Template.of("value", "Invalid syntax: /plot debugexec start-rgar <world>")
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "value",
 | 
			
		||||
                                        Tag.inserting(Component.text("Invalid syntax: /plot debugexec start-rgar <world>"))
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -191,7 +199,7 @@ public class DebugExec extends SubCommand {
 | 
			
		||||
                    if (area == null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("errors.not_valid_plot_world"),
 | 
			
		||||
                                Template.of("value", args[1])
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(args[1])))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,9 @@ import com.plotsquared.core.inject.annotations.WorldFile;
 | 
			
		||||
import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import com.plotsquared.core.util.PremiumVerification;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.io.File;
 | 
			
		||||
@@ -69,9 +71,9 @@ public class DebugPaste extends SubCommand {
 | 
			
		||||
                StringBuilder b = new StringBuilder();
 | 
			
		||||
                b.append(
 | 
			
		||||
                        """
 | 
			
		||||
                         # Welcome to this paste
 | 
			
		||||
                         # It is meant to provide us at IntellectualSites with better information about your problem
 | 
			
		||||
                         """
 | 
			
		||||
                                # Welcome to this paste
 | 
			
		||||
                                # It is meant to provide us at IntellectualSites with better information about your problem
 | 
			
		||||
                                """
 | 
			
		||||
                );
 | 
			
		||||
                b.append("# PlotSquared Information\n");
 | 
			
		||||
                b.append("PlotSquared Version: ").append(PlotSquared.get().getVersion())
 | 
			
		||||
@@ -131,8 +133,10 @@ public class DebugPaste extends SubCommand {
 | 
			
		||||
                } catch (IOException ignored) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("debugpaste.latest_log"),
 | 
			
		||||
                            Template.of("file", "latest.log"),
 | 
			
		||||
                            Template.of("size", "14MB")
 | 
			
		||||
                            TagResolver.builder()
 | 
			
		||||
                                    .tag("file", Tag.inserting(Component.text("latest.log")))
 | 
			
		||||
                                    .tag("size", Tag.inserting(Component.text("14MB")))
 | 
			
		||||
                                    .build()
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -141,7 +145,7 @@ public class DebugPaste extends SubCommand {
 | 
			
		||||
                } catch (final IllegalArgumentException ignored) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("debugpaste.empty_file"),
 | 
			
		||||
                            Template.of("file", "settings.yml")
 | 
			
		||||
                            TagResolver.resolver("file", Tag.inserting(Component.text("settings.yml")))
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                try {
 | 
			
		||||
@@ -149,7 +153,7 @@ public class DebugPaste extends SubCommand {
 | 
			
		||||
                } catch (final IllegalArgumentException ignored) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("debugpaste.empty_file"),
 | 
			
		||||
                            Template.of("file", "worlds.yml")
 | 
			
		||||
                            TagResolver.resolver("file", Tag.inserting(Component.text("worlds.yml")))
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -162,7 +166,7 @@ public class DebugPaste extends SubCommand {
 | 
			
		||||
                } catch (final IOException ignored) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("debugpaste.skip_multiverse"),
 | 
			
		||||
                            Template.of("file", "worlds.yml")
 | 
			
		||||
                            TagResolver.resolver("file", Tag.inserting(Component.text("worlds.yml")))
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
@@ -177,20 +181,20 @@ public class DebugPaste extends SubCommand {
 | 
			
		||||
                                String.format("https://athion.net/ISPaster/paste/view/%s", pasteId);
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("debugpaste.debug_report_created"),
 | 
			
		||||
                                Template.of("url", link)
 | 
			
		||||
                                TagResolver.resolver("url", Tag.preProcessParsed(link))
 | 
			
		||||
                        );
 | 
			
		||||
                    } else {
 | 
			
		||||
                        final String responseMessage = jsonObject.get("response").getAsString();
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("debugpaste.creation_failed"),
 | 
			
		||||
                                Template.of("value", responseMessage)
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(responseMessage)))
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                } catch (final Throwable throwable) {
 | 
			
		||||
                    throwable.printStackTrace();
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("debugpaste.creation_failed"),
 | 
			
		||||
                            Template.of("value", throwable.getMessage())
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text(throwable.getMessage())))
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,9 @@ import com.plotsquared.core.plot.Plot;
 | 
			
		||||
import com.plotsquared.core.plot.PlotArea;
 | 
			
		||||
import com.plotsquared.core.plot.PlotManager;
 | 
			
		||||
import com.plotsquared.core.queue.QueueCoordinator;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.Arrays;
 | 
			
		||||
@@ -60,7 +62,7 @@ public class DebugRoadRegen extends SubCommand {
 | 
			
		||||
        if (args.length < 1) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", DebugRoadRegen.USAGE)
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text(DebugRoadRegen.USAGE)))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -73,16 +75,19 @@ public class DebugRoadRegen extends SubCommand {
 | 
			
		||||
        }
 | 
			
		||||
        String kind = args[0].toLowerCase();
 | 
			
		||||
        switch (kind) {
 | 
			
		||||
            case "plot":
 | 
			
		||||
            case "plot" -> {
 | 
			
		||||
                return regenPlot(player);
 | 
			
		||||
            case "region":
 | 
			
		||||
            }
 | 
			
		||||
            case "region" -> {
 | 
			
		||||
                return regenRegion(player, Arrays.copyOfRange(args, 1, args.length));
 | 
			
		||||
            default:
 | 
			
		||||
            }
 | 
			
		||||
            default -> {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                        Template.of("value", DebugRoadRegen.USAGE)
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text(DebugRoadRegen.USAGE)))
 | 
			
		||||
                );
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -103,11 +108,11 @@ public class DebugRoadRegen extends SubCommand {
 | 
			
		||||
            queue.setCompleteTask(() -> {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("debugroadregen.regen_done"),
 | 
			
		||||
                        Template.of("value", plot.getId().toString())
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text(plot.getId().toString())))
 | 
			
		||||
                );
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("debugroadregen.regen_all"),
 | 
			
		||||
                        Template.of("value", "/plot regenallroads")
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text("/plot regenallroads")))
 | 
			
		||||
                );
 | 
			
		||||
            });
 | 
			
		||||
            manager.createRoadEast(plot, queue);
 | 
			
		||||
@@ -126,18 +131,18 @@ public class DebugRoadRegen extends SubCommand {
 | 
			
		||||
            } catch (NumberFormatException ignored) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("invalid.not_valid_number"),
 | 
			
		||||
                        Template.of("value", "0, 256")
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text("0, 256")))
 | 
			
		||||
                );
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                        Template.of("value", DebugRoadRegen.USAGE)
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text(DebugRoadRegen.USAGE)))
 | 
			
		||||
                );
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
        } else if (args.length != 0) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", DebugRoadRegen.USAGE)
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text(DebugRoadRegen.USAGE)))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -155,11 +160,11 @@ public class DebugRoadRegen extends SubCommand {
 | 
			
		||||
        }
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("debugroadregen.schematic"),
 | 
			
		||||
                Template.of("command", "/plot createroadschematic")
 | 
			
		||||
                TagResolver.resolver("command", Tag.inserting(Component.text("/plot createroadschematic")))
 | 
			
		||||
        );
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("debugroadregen.regenallroads"),
 | 
			
		||||
                Template.of("command", "/plot regenallroads")
 | 
			
		||||
                TagResolver.resolver("command", Tag.inserting(Component.text("/plot regenallroads")))
 | 
			
		||||
        );
 | 
			
		||||
        boolean result = this.hybridUtils.scheduleSingleRegionRoadUpdate(plot, height);
 | 
			
		||||
        if (!result) {
 | 
			
		||||
 
 | 
			
		||||
@@ -32,7 +32,9 @@ import com.plotsquared.core.util.EconHandler;
 | 
			
		||||
import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import com.plotsquared.core.util.PlotExpression;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -77,7 +79,7 @@ public class Delete extends SubCommand {
 | 
			
		||||
        if (eventResult == Result.DENY) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                    Template.of("value", "Delete")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("Delete")))
 | 
			
		||||
            );
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
@@ -112,14 +114,17 @@ public class Delete extends SubCommand {
 | 
			
		||||
                        this.econHandler.depositMoney(player, value);
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("economy.added_balance"),
 | 
			
		||||
                                Template.of("money", this.econHandler.format(value))
 | 
			
		||||
                                TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(value))))
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("working.deleting_done"),
 | 
			
		||||
                        Template.of("amount", String.valueOf(System.currentTimeMillis() - start)),
 | 
			
		||||
                        Template.of("plot", plot.getId().toString())
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "amount",
 | 
			
		||||
                                Tag.inserting(Component.text(String.valueOf(System.currentTimeMillis() - start)))
 | 
			
		||||
                        ),
 | 
			
		||||
                        TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString())))
 | 
			
		||||
                );
 | 
			
		||||
                eventDispatcher.callPostDelete(plot);
 | 
			
		||||
            });
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,9 @@ import com.plotsquared.core.util.PlayerManager;
 | 
			
		||||
import com.plotsquared.core.util.TabCompletions;
 | 
			
		||||
import com.plotsquared.core.util.WorldUtil;
 | 
			
		||||
import com.sk89q.worldedit.world.gamemode.GameModes;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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;
 | 
			
		||||
@@ -88,7 +90,7 @@ public class Deny extends SubCommand {
 | 
			
		||||
        if (size >= maxDenySize) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("members.plot_max_members_denied"),
 | 
			
		||||
                    Template.of("amount", String.valueOf(size))
 | 
			
		||||
                    TagResolver.resolver("amount", Tag.inserting(Component.text(size)))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -99,7 +101,7 @@ public class Deny extends SubCommand {
 | 
			
		||||
            } else if (throwable != null || uuids.isEmpty()) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                        Template.of("value", args[0])
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text(args[0])))
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                for (UUID uuid : uuids) {
 | 
			
		||||
@@ -107,7 +109,7 @@ public class Deny extends SubCommand {
 | 
			
		||||
                            player.hasPermission(Permission.PERMISSION_DENY_EVERYONE) || player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_DENY))) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                                Template.of("value", args[0])
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(args[0])))
 | 
			
		||||
                        );
 | 
			
		||||
                    } else if (plot.isOwner(uuid)) {
 | 
			
		||||
                        player.sendMessage(TranslatableCaption.of("deny.cant_remove_owner"));
 | 
			
		||||
@@ -115,7 +117,10 @@ public class Deny extends SubCommand {
 | 
			
		||||
                    } else if (plot.getDenied().contains(uuid)) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("member.already_added"),
 | 
			
		||||
                                Template.of("player", PlayerManager.resolveName(uuid).getComponent(player))
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "player",
 | 
			
		||||
                                        Tag.inserting(PlayerManager.resolveName(uuid).toComponent(player))
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return;
 | 
			
		||||
                    } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,9 @@ import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import com.plotsquared.core.plot.Plot;
 | 
			
		||||
import com.plotsquared.core.plot.flag.implementations.DescriptionFlag;
 | 
			
		||||
import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
@CommandDeclaration(command = "setdescription",
 | 
			
		||||
@@ -54,7 +56,7 @@ public class Desc extends SetCommand {
 | 
			
		||||
            if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                        Template.of("value", "Description removal")
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text("Description removal")))
 | 
			
		||||
                );
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
@@ -69,7 +71,7 @@ public class Desc extends SetCommand {
 | 
			
		||||
        if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                    Template.of("value", "Description set")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("Description set")))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,9 @@ import com.plotsquared.core.plot.flag.PlotFlag;
 | 
			
		||||
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
 | 
			
		||||
import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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;
 | 
			
		||||
 | 
			
		||||
@CommandDeclaration(command = "done",
 | 
			
		||||
@@ -69,7 +71,7 @@ public class Done extends SubCommand {
 | 
			
		||||
        if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                    Template.of("value", "Done")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("Done")))
 | 
			
		||||
            );
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
@@ -89,7 +91,7 @@ public class Done extends SubCommand {
 | 
			
		||||
        plot.addRunning();
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("web.generating_link"),
 | 
			
		||||
                Template.of("plot", plot.getId().toString())
 | 
			
		||||
                TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString())))
 | 
			
		||||
        );
 | 
			
		||||
        final Settings.Auto_Clear doneRequirements = Settings.AUTO_CLEAR.get("done");
 | 
			
		||||
        if (PlotSquared.platform().expireManager() == null || doneRequirements == null) {
 | 
			
		||||
@@ -101,7 +103,7 @@ public class Done extends SubCommand {
 | 
			
		||||
                public void run(PlotAnalysis value) {
 | 
			
		||||
                    plot.removeRunning();
 | 
			
		||||
                    boolean result =
 | 
			
		||||
                            value.getComplexity(doneRequirements) <= doneRequirements.THRESHOLD;
 | 
			
		||||
                            value.getComplexity(doneRequirements) >= doneRequirements.THRESHOLD;
 | 
			
		||||
                    finish(plot, player, result);
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,9 @@ import com.plotsquared.core.util.StringMan;
 | 
			
		||||
import com.plotsquared.core.util.TabCompletions;
 | 
			
		||||
import com.plotsquared.core.util.WorldUtil;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.net.URL;
 | 
			
		||||
@@ -111,7 +113,10 @@ public class Download extends SubCommand {
 | 
			
		||||
            if (!player.hasPermission(Permission.PERMISSION_DOWNLOAD_WORLD)) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                        Template.of("node", Permission.PERMISSION_DOWNLOAD_WORLD.toString())
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_DOWNLOAD_WORLD)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
@@ -125,18 +130,24 @@ public class Download extends SubCommand {
 | 
			
		||||
                    if (url == null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("web.generating_link_failed"),
 | 
			
		||||
                                Template.of("plot", plot.getId().toString())
 | 
			
		||||
                                TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString())))
 | 
			
		||||
                        );
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    player.sendMessage(TranslatableCaption.of("web.generation_link_success_legacy_world"), Template.of("url", url.toString()));
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("web.generation_link_success_legacy_world"),
 | 
			
		||||
                            TagResolver.resolver("url", Tag.inserting(Component.text(url.toString())))
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            });
 | 
			
		||||
        } else {
 | 
			
		||||
            sendUsage(player);
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
        player.sendMessage(TranslatableCaption.of("web.generating_link"), Template.of("plot", plot.getId().toString()));
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("web.generating_link"),
 | 
			
		||||
                TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString())))
 | 
			
		||||
        );
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -174,20 +185,25 @@ public class Download extends SubCommand {
 | 
			
		||||
        if (Settings.Web.LEGACY_WEBINTERFACE) {
 | 
			
		||||
            schematicHandler
 | 
			
		||||
                    .getCompoundTag(plot)
 | 
			
		||||
                    .whenComplete((compoundTag, throwable) -> {
 | 
			
		||||
                        schematicHandler.upload(compoundTag, null, null, new RunnableVal<>() {
 | 
			
		||||
                            @Override
 | 
			
		||||
                            public void run(URL value) {
 | 
			
		||||
                                plot.removeRunning();
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("web.generation_link_success"),
 | 
			
		||||
                                        Template.of("download", value.toString()),
 | 
			
		||||
                                        Template.of("delete", "Not available")
 | 
			
		||||
                                );
 | 
			
		||||
                                player.sendMessage(StaticCaption.of(value.toString()));
 | 
			
		||||
                    .whenComplete((compoundTag, throwable) -> schematicHandler.upload(
 | 
			
		||||
                            compoundTag,
 | 
			
		||||
                            null,
 | 
			
		||||
                            null,
 | 
			
		||||
                            new RunnableVal<>() {
 | 
			
		||||
                                @Override
 | 
			
		||||
                                public void run(URL value) {
 | 
			
		||||
                                    plot.removeRunning();
 | 
			
		||||
                                    player.sendMessage(
 | 
			
		||||
                                            TranslatableCaption.of("web.generation_link_success"),
 | 
			
		||||
                                            TagResolver.builder()
 | 
			
		||||
                                                    .tag("download", Tag.preProcessParsed(value.toString()))
 | 
			
		||||
                                                    .tag("delete", Tag.preProcessParsed("Not available"))
 | 
			
		||||
                                                    .build()
 | 
			
		||||
                                    );
 | 
			
		||||
                                    player.sendMessage(StaticCaption.of(value.toString()));
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                        });
 | 
			
		||||
                    });
 | 
			
		||||
                    ));
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        // TODO legacy support
 | 
			
		||||
@@ -196,13 +212,15 @@ public class Download extends SubCommand {
 | 
			
		||||
                    if (throwable != null || !result.isSuccess()) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("web.generating_link_failed"),
 | 
			
		||||
                                Template.of("plot", plot.getId().toString())
 | 
			
		||||
                                TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString())))
 | 
			
		||||
                        );
 | 
			
		||||
                    } else {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("web.generation_link_success"),
 | 
			
		||||
                                Template.of("download", result.getDownloadUrl()),
 | 
			
		||||
                                Template.of("delete", result.getDeletionUrl())
 | 
			
		||||
                                TagResolver.builder()
 | 
			
		||||
                                        .tag("download", Tag.preProcessParsed(result.getDownloadUrl()))
 | 
			
		||||
                                        .tag("delete", Tag.preProcessParsed(result.getDeletionUrl()))
 | 
			
		||||
                                        .build()
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                });
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,6 @@ import com.plotsquared.core.PlotSquared;
 | 
			
		||||
import com.plotsquared.core.configuration.Settings;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.CaptionUtility;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.StaticCaption;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.Templates;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
 | 
			
		||||
import com.plotsquared.core.events.PlotFlagAddEvent;
 | 
			
		||||
import com.plotsquared.core.events.PlotFlagRemoveEvent;
 | 
			
		||||
@@ -47,7 +46,9 @@ 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.TextComponent;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import net.kyori.adventure.text.format.Style;
 | 
			
		||||
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 org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
 | 
			
		||||
@@ -84,7 +85,10 @@ public final class FlagCommand extends Command {
 | 
			
		||||
    private static boolean sendMessage(PlotPlayer<?> player) {
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                Template.of("value", "/plot flag <set | remove | add | list | info> <flag> <value>")
 | 
			
		||||
                TagResolver.resolver(
 | 
			
		||||
                        "value",
 | 
			
		||||
                        Tag.inserting(Component.text("/plot flag <set | remove | add | list | info> <flag> <value>"))
 | 
			
		||||
                )
 | 
			
		||||
        );
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
@@ -110,9 +114,9 @@ public final class FlagCommand extends Command {
 | 
			
		||||
                if (!result) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of(
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "node",
 | 
			
		||||
                                    perm + "." + numeric
 | 
			
		||||
                                    Tag.inserting(Component.text(perm + "." + numeric))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
@@ -129,16 +133,21 @@ public final class FlagCommand extends Command {
 | 
			
		||||
                    );
 | 
			
		||||
                    final boolean result = player.hasPermission(permission);
 | 
			
		||||
                    if (!result) {
 | 
			
		||||
                        player.sendMessage(TranslatableCaption.of("permission.no_permission"), Template.of("node", permission));
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                TagResolver.resolver("node", Tag.inserting(Component.text(permission)))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } catch (final FlagParseException e) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("flag.flag_parse_error"),
 | 
			
		||||
                        Template.of("flag_name", flag.getName()),
 | 
			
		||||
                        Template.of("flag_value", e.getValue()),
 | 
			
		||||
                        Template.of("error", e.getErrorMessage().getComponent(player))
 | 
			
		||||
                        TagResolver.builder()
 | 
			
		||||
                                .tag("flag_name", Tag.inserting(Component.text(flag.getName())))
 | 
			
		||||
                                .tag("flag_value", Tag.inserting(Component.text(e.getValue())))
 | 
			
		||||
                                .tag("error", Tag.inserting(e.getErrorMessage().toComponent(player)))
 | 
			
		||||
                                .build()
 | 
			
		||||
                );
 | 
			
		||||
                return false;
 | 
			
		||||
            } catch (final Exception e) {
 | 
			
		||||
@@ -155,7 +164,10 @@ public final class FlagCommand extends Command {
 | 
			
		||||
            perm = basePerm;
 | 
			
		||||
        }
 | 
			
		||||
        if (!result) {
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("permission.no_permission"), Template.of("node", perm));
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                    TagResolver.resolver("node", Tag.inserting(Component.text(perm)))
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
@@ -179,7 +191,7 @@ public final class FlagCommand extends Command {
 | 
			
		||||
        if (!plot.isOwner(player.getUUID()) && !player.hasPermission(Permission.PERMISSION_SET_FLAG_OTHER)) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_SET_FLAG_OTHER))
 | 
			
		||||
                    TagResolver.resolver("node", Tag.inserting(Permission.PERMISSION_SET_FLAG_OTHER))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -214,7 +226,7 @@ public final class FlagCommand extends Command {
 | 
			
		||||
                    if (best != null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("flag.not_valid_flag_suggested"),
 | 
			
		||||
                                Template.of("value", best)
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(best)))
 | 
			
		||||
                        );
 | 
			
		||||
                        suggested = true;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -323,7 +335,7 @@ public final class FlagCommand extends Command {
 | 
			
		||||
        if (args.length < 2) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", "/plot flag set <flag> <value>")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("/plot flag set <flag> <value>")))
 | 
			
		||||
            );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -336,7 +348,7 @@ public final class FlagCommand extends Command {
 | 
			
		||||
        if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                    Template.of("value", "Flag set")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("Flag set")))
 | 
			
		||||
            );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -352,15 +364,21 @@ public final class FlagCommand extends Command {
 | 
			
		||||
        } catch (final FlagParseException e) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("flag.flag_parse_error"),
 | 
			
		||||
                    Template.of("flag_name", plotFlag.getName()),
 | 
			
		||||
                    Template.of("flag_value", e.getValue()),
 | 
			
		||||
                    Template.of("error", e.getErrorMessage().getComponent(player))
 | 
			
		||||
                    TagResolver.builder()
 | 
			
		||||
                            .tag("flag_name", Tag.inserting(Component.text(plotFlag.getName())))
 | 
			
		||||
                            .tag("flag_value", Tag.inserting(Component.text(e.getValue())))
 | 
			
		||||
                            .tag("error", Tag.inserting(e.getErrorMessage().toComponent(player)))
 | 
			
		||||
                            .build()
 | 
			
		||||
            );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        plot.setFlag(parsed);
 | 
			
		||||
        player.sendMessage(TranslatableCaption.of("flag.flag_added"), Template.of("flag", String.valueOf(args[0])),
 | 
			
		||||
                Template.of("value", String.valueOf(parsed))
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("flag.flag_added"),
 | 
			
		||||
                TagResolver.builder()
 | 
			
		||||
                        .tag("flag", Tag.inserting(Component.text(args[0])))
 | 
			
		||||
                        .tag("value", Tag.inserting(Component.text(parsed.toString())))
 | 
			
		||||
                        .build()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -382,7 +400,7 @@ public final class FlagCommand extends Command {
 | 
			
		||||
        if (args.length < 2) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", "/plot flag add <flag> <values>")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("/plot flag add <flag> <values>")))
 | 
			
		||||
            );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -395,7 +413,7 @@ public final class FlagCommand extends Command {
 | 
			
		||||
        if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                    Template.of("value", "Flag add")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("Flag add")))
 | 
			
		||||
            );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -416,9 +434,11 @@ public final class FlagCommand extends Command {
 | 
			
		||||
        } catch (FlagParseException e) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("flag.flag_parse_error"),
 | 
			
		||||
                    Template.of("flag_name", plotFlag.getName()),
 | 
			
		||||
                    Template.of("flag_value", e.getValue()),
 | 
			
		||||
                    Template.of("error", e.getErrorMessage().getComponent(player))
 | 
			
		||||
                    TagResolver.builder()
 | 
			
		||||
                            .tag("flag_name", Tag.inserting(Component.text(plotFlag.getName())))
 | 
			
		||||
                            .tag("flag_value", Tag.inserting(Component.text(e.getValue())))
 | 
			
		||||
                            .tag("error", Tag.inserting(e.getErrorMessage().toComponent(player)))
 | 
			
		||||
                            .build()
 | 
			
		||||
            );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -428,8 +448,12 @@ public final class FlagCommand extends Command {
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("flag.flag_not_added"));
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
        player.sendMessage(TranslatableCaption.of("flag.flag_added"), Template.of("flag", String.valueOf(args[0])),
 | 
			
		||||
                Template.of("value", String.valueOf(parsed))
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("flag.flag_added"),
 | 
			
		||||
                TagResolver.builder()
 | 
			
		||||
                        .tag("flag", Tag.inserting(Component.text(args[0])))
 | 
			
		||||
                        .tag("value", Tag.inserting(Component.text(parsed.toString())))
 | 
			
		||||
                        .build()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -451,7 +475,7 @@ public final class FlagCommand extends Command {
 | 
			
		||||
        if (args.length != 1 && args.length != 2) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", "/plot flag remove <flag> [values]")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("/plot flag remove <flag> [values]")))
 | 
			
		||||
            );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -465,7 +489,7 @@ public final class FlagCommand extends Command {
 | 
			
		||||
        if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                    Template.of("value", "Flag remove")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("Flag remove")))
 | 
			
		||||
            );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -475,7 +499,10 @@ public final class FlagCommand extends Command {
 | 
			
		||||
            if (args.length != 2) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                        Template.of("node", Permission.PERMISSION_SET_FLAG_KEY.format(args[0].toLowerCase()))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Component.text(Permission.PERMISSION_SET_FLAG_KEY.format(args[0].toLowerCase())))
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
@@ -490,9 +517,11 @@ public final class FlagCommand extends Command {
 | 
			
		||||
            } catch (final FlagParseException e) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("flag.flag_parse_error"),
 | 
			
		||||
                        Template.of("flag_name", flag.getName()),
 | 
			
		||||
                        Template.of("flag_value", e.getValue()),
 | 
			
		||||
                        Template.of("error", String.valueOf(e.getErrorMessage()))
 | 
			
		||||
                        TagResolver.builder()
 | 
			
		||||
                                .tag("flag_name", Tag.inserting(Component.text(flag.getName())))
 | 
			
		||||
                                .tag("flag_value", Tag.inserting(Component.text(e.getValue())))
 | 
			
		||||
                                .tag("error", Tag.inserting(e.getErrorMessage().toComponent(player)))
 | 
			
		||||
                                .build()
 | 
			
		||||
                );
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
@@ -503,10 +532,13 @@ public final class FlagCommand extends Command {
 | 
			
		||||
            if (list.removeAll((List) parsedFlag.getValue())) {
 | 
			
		||||
                if (list.isEmpty()) {
 | 
			
		||||
                    if (plot.removeFlag(flag)) {
 | 
			
		||||
                        player.sendMessage(TranslatableCaption.of("flag.flag_removed"), Template.of("flag", args[0]), Template.of(
 | 
			
		||||
                                "value",
 | 
			
		||||
                                String.valueOf(flagWithOldValue)
 | 
			
		||||
                        ));
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("flag.flag_removed"),
 | 
			
		||||
                                TagResolver.builder()
 | 
			
		||||
                                        .tag("flag", Tag.inserting(Component.text(args[0])))
 | 
			
		||||
                                        .tag("value", Tag.inserting(Component.text(flag.toString())))
 | 
			
		||||
                                        .build()
 | 
			
		||||
                        );
 | 
			
		||||
                        return;
 | 
			
		||||
                    } else {
 | 
			
		||||
                        player.sendMessage(TranslatableCaption.of("flag.flag_not_removed"));
 | 
			
		||||
@@ -518,7 +550,10 @@ public final class FlagCommand extends Command {
 | 
			
		||||
                    if (addEvent.getEventResult() == Result.DENY) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                                Template.of("value", "Re-addition of " + plotFlag.getName())
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "value",
 | 
			
		||||
                                        Tag.inserting(Component.text("Re-addition of " + plotFlag.getName()))
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -541,10 +576,13 @@ public final class FlagCommand extends Command {
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        player.sendMessage(TranslatableCaption.of("flag.flag_removed"), Template.of("flag", args[0]), Template.of(
 | 
			
		||||
                "value",
 | 
			
		||||
                String.valueOf(flagWithOldValue)
 | 
			
		||||
        ));
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("flag.flag_removed"),
 | 
			
		||||
                TagResolver.builder()
 | 
			
		||||
                        .tag("flag", Tag.inserting(Component.text(args[0])))
 | 
			
		||||
                        .tag("value", Tag.inserting(Component.text(flag.toString())))
 | 
			
		||||
                        .build()
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @CommandDeclaration(command = "list",
 | 
			
		||||
@@ -562,34 +600,35 @@ public final class FlagCommand extends Command {
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        final Map<String, ArrayList<String>> flags = new HashMap<>();
 | 
			
		||||
        final Map<Component, ArrayList<String>> flags = new HashMap<>();
 | 
			
		||||
        for (PlotFlag<?, ?> plotFlag : GlobalFlagContainer.getInstance().getRecognizedPlotFlags()) {
 | 
			
		||||
            if (plotFlag instanceof InternalFlag) {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
            final String category = MINI_MESSAGE.stripTokens(plotFlag.getFlagCategory().getComponent(player));
 | 
			
		||||
            final Collection<String> flagList =
 | 
			
		||||
                    flags.computeIfAbsent(category, k -> new ArrayList<>());
 | 
			
		||||
            final Component category = plotFlag.getFlagCategory().toComponent(player);
 | 
			
		||||
            final Collection<String> flagList = flags.computeIfAbsent(category, k -> new ArrayList<>());
 | 
			
		||||
            flagList.add(plotFlag.getName());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (final Map.Entry<String, ArrayList<String>> entry : flags.entrySet()) {
 | 
			
		||||
        for (final Map.Entry<Component, ArrayList<String>> entry : flags.entrySet()) {
 | 
			
		||||
            Collections.sort(entry.getValue());
 | 
			
		||||
            Component category =
 | 
			
		||||
                    MINI_MESSAGE.parse(
 | 
			
		||||
                    MINI_MESSAGE.deserialize(
 | 
			
		||||
                            TranslatableCaption.of("flag.flag_list_categories").getComponent(player),
 | 
			
		||||
                            Template.of("category", entry.getKey())
 | 
			
		||||
                            TagResolver.resolver("category", Tag.inserting(entry.getKey().style(Style.empty())))
 | 
			
		||||
                    );
 | 
			
		||||
            TextComponent.Builder builder = Component.text().append(category);
 | 
			
		||||
            final Iterator<String> flagIterator = entry.getValue().iterator();
 | 
			
		||||
            while (flagIterator.hasNext()) {
 | 
			
		||||
                final String flag = flagIterator.next();
 | 
			
		||||
                builder.append(MINI_MESSAGE
 | 
			
		||||
                        .parse(
 | 
			
		||||
                        .deserialize(
 | 
			
		||||
                                TranslatableCaption.of("flag.flag_list_flag").getComponent(player),
 | 
			
		||||
                                Template.of("command", "/plot flag info " + flag),
 | 
			
		||||
                                Template.of("flag", flag),
 | 
			
		||||
                                Template.of("suffix", flagIterator.hasNext() ? ", " : "")
 | 
			
		||||
                                TagResolver.builder()
 | 
			
		||||
                                        .tag("command", Tag.preProcessParsed("/plot flag info " + flag))
 | 
			
		||||
                                        .tag("flag", Tag.inserting(Component.text(flag)))
 | 
			
		||||
                                        .tag("suffix", Tag.inserting(Component.text(flagIterator.hasNext() ? ", " : "")))
 | 
			
		||||
                                        .build()
 | 
			
		||||
                        ));
 | 
			
		||||
            }
 | 
			
		||||
            player.sendMessage(StaticCaption.of(MINI_MESSAGE.serialize(builder.build())));
 | 
			
		||||
@@ -613,7 +652,7 @@ public final class FlagCommand extends Command {
 | 
			
		||||
        if (args.length < 1) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", "/plot flag info <flag>")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("/plot flag info <flag>")))
 | 
			
		||||
            );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -621,11 +660,17 @@ public final class FlagCommand extends Command {
 | 
			
		||||
        if (plotFlag != null) {
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("flag.flag_info_header"));
 | 
			
		||||
            // Flag name
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("flag.flag_info_name"), Template.of("flag", plotFlag.getName()));
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("flag.flag_info_name"),
 | 
			
		||||
                    TagResolver.resolver("flag", Tag.inserting(Component.text(plotFlag.getName())))
 | 
			
		||||
            );
 | 
			
		||||
            // Flag category
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("flag.flag_info_category"),
 | 
			
		||||
                    Templates.of(player, "value", plotFlag.getFlagCategory())
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "value",
 | 
			
		||||
                            Tag.inserting(plotFlag.getFlagCategory().toComponent(player))
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
            // Flag description
 | 
			
		||||
            // TODO maybe merge and \n instead?
 | 
			
		||||
@@ -634,16 +679,18 @@ public final class FlagCommand extends Command {
 | 
			
		||||
            // Flag example
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("flag.flag_info_example"),
 | 
			
		||||
                    Template.of("command", "/plot flag set"),
 | 
			
		||||
                    Template.of("flag", plotFlag.getName()),
 | 
			
		||||
                    Template.of("value", plotFlag.getExample())
 | 
			
		||||
                    TagResolver.builder()
 | 
			
		||||
                            .tag("command", Tag.preProcessParsed("/plot flag set"))
 | 
			
		||||
                            .tag("flag", Tag.preProcessParsed(plotFlag.getName()))
 | 
			
		||||
                            .tag("value", Tag.preProcessParsed(plotFlag.getExample()))
 | 
			
		||||
                            .build()
 | 
			
		||||
            );
 | 
			
		||||
            // Default value
 | 
			
		||||
            final String defaultValue = player.getLocation().getPlotArea().getFlagContainer()
 | 
			
		||||
                    .getFlagErased(plotFlag.getClass()).toString();
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("flag.flag_info_default_value"),
 | 
			
		||||
                    Template.of("value", defaultValue)
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text(defaultValue)))
 | 
			
		||||
            );
 | 
			
		||||
            // Footer. Done this way to prevent the duplicate-message-thingy from catching it
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("flag.flag_info_footer"));
 | 
			
		||||
 
 | 
			
		||||
@@ -31,7 +31,9 @@ import com.plotsquared.core.util.TabCompletions;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal2;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal3;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
@@ -63,7 +65,7 @@ public class Grant extends Command {
 | 
			
		||||
        checkTrue(
 | 
			
		||||
                args.length >= 1 && args.length <= 2,
 | 
			
		||||
                TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                Template.of("value", "/plot grant <check | add> [player]")
 | 
			
		||||
                TagResolver.resolver("value", Tag.inserting(Component.text("/plot grant <check | add> [player]")))
 | 
			
		||||
        );
 | 
			
		||||
        final String arg0 = args[0].toLowerCase();
 | 
			
		||||
        switch (arg0) {
 | 
			
		||||
@@ -71,7 +73,7 @@ public class Grant extends Command {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_GRANT.format(arg0))) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Template.of("node", Permission.PERMISSION_GRANT.format(arg0))
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text(Permission.PERMISSION_GRANT.format(arg0))))
 | 
			
		||||
                    );
 | 
			
		||||
                    return CompletableFuture.completedFuture(false);
 | 
			
		||||
                }
 | 
			
		||||
@@ -84,7 +86,7 @@ public class Grant extends Command {
 | 
			
		||||
                    } else if (throwable != null || uuids.size() != 1) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                                Template.of("value", String.valueOf(uuids))
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(String.valueOf(uuids))))
 | 
			
		||||
                        );
 | 
			
		||||
                    } else {
 | 
			
		||||
                        final UUID uuid = uuids.iterator().next();
 | 
			
		||||
@@ -95,7 +97,7 @@ public class Grant extends Command {
 | 
			
		||||
                                if (args[0].equalsIgnoreCase("check")) {
 | 
			
		||||
                                    player.sendMessage(
 | 
			
		||||
                                            TranslatableCaption.of("grants.granted_plots"),
 | 
			
		||||
                                            Template.of("amount", String.valueOf(access.get().orElse(0)))
 | 
			
		||||
                                            TagResolver.resolver("amount", Tag.inserting(Component.text(access.get().orElse(0))))
 | 
			
		||||
                                    );
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    access.set(access.get().orElse(0) + 1);
 | 
			
		||||
@@ -115,7 +117,7 @@ public class Grant extends Command {
 | 
			
		||||
                                        }
 | 
			
		||||
                                        player.sendMessage(
 | 
			
		||||
                                                TranslatableCaption.of("grants.granted_plots"),
 | 
			
		||||
                                                Template.of("amount", String.valueOf(granted))
 | 
			
		||||
                                                TagResolver.resolver("amount", Tag.inserting(Component.text(granted)))
 | 
			
		||||
                                        );
 | 
			
		||||
                                    } else { // add
 | 
			
		||||
                                        int amount;
 | 
			
		||||
@@ -130,7 +132,7 @@ public class Grant extends Command {
 | 
			
		||||
                                        DBFunc.addPersistentMeta(uuid, key, rawData, replace);
 | 
			
		||||
                                        player.sendMessage(
 | 
			
		||||
                                                TranslatableCaption.of("grants.added"),
 | 
			
		||||
                                                Template.of("grants", String.valueOf(amount))
 | 
			
		||||
                                                TagResolver.resolver("grants", Tag.inserting(Component.text(amount)))
 | 
			
		||||
                                        );
 | 
			
		||||
                                    }
 | 
			
		||||
                                }
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,8 @@ 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.TextComponent;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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;
 | 
			
		||||
@@ -59,9 +60,10 @@ public class Help extends Command {
 | 
			
		||||
            RunnableVal2<Command, CommandResult> whenDone
 | 
			
		||||
    ) {
 | 
			
		||||
        switch (args.length) {
 | 
			
		||||
            case 0:
 | 
			
		||||
            case 0 -> {
 | 
			
		||||
                return displayHelp(player, null, 0);
 | 
			
		||||
            case 1:
 | 
			
		||||
            }
 | 
			
		||||
            case 1 -> {
 | 
			
		||||
                if (MathMan.isInteger(args[0])) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        return displayHelp(player, null, Integer.parseInt(args[0]));
 | 
			
		||||
@@ -71,7 +73,8 @@ public class Help extends Command {
 | 
			
		||||
                } else {
 | 
			
		||||
                    return displayHelp(player, args[0], 1);
 | 
			
		||||
                }
 | 
			
		||||
            case 2:
 | 
			
		||||
            }
 | 
			
		||||
            case 2 -> {
 | 
			
		||||
                if (MathMan.isInteger(args[1])) {
 | 
			
		||||
                    try {
 | 
			
		||||
                        return displayHelp(player, args[0], Integer.parseInt(args[1]));
 | 
			
		||||
@@ -80,8 +83,8 @@ public class Help extends Command {
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                return CompletableFuture.completedFuture(false);
 | 
			
		||||
            default:
 | 
			
		||||
                sendUsage(player);
 | 
			
		||||
            }
 | 
			
		||||
            default -> sendUsage(player);
 | 
			
		||||
        }
 | 
			
		||||
        return CompletableFuture.completedFuture(true);
 | 
			
		||||
    }
 | 
			
		||||
@@ -110,27 +113,36 @@ public class Help extends Command {
 | 
			
		||||
            }
 | 
			
		||||
            if (cat == null && page == 0) {
 | 
			
		||||
                TextComponent.Builder builder = Component.text();
 | 
			
		||||
                builder.append(MINI_MESSAGE.parse(TranslatableCaption.of("help.help_header").getComponent(player)));
 | 
			
		||||
                builder.append(MINI_MESSAGE.deserialize(TranslatableCaption.of("help.help_header").getComponent(player)));
 | 
			
		||||
                for (CommandCategory c : CommandCategory.values()) {
 | 
			
		||||
                    if (!c.canAccess(player)) {
 | 
			
		||||
                        continue;
 | 
			
		||||
                    }
 | 
			
		||||
                    builder.append(Component.newline()).append(MINI_MESSAGE
 | 
			
		||||
                            .parse(
 | 
			
		||||
                            .deserialize(
 | 
			
		||||
                                    TranslatableCaption.of("help.help_info_item").getComponent(player),
 | 
			
		||||
                                    Template.of("command", "/plot help"),
 | 
			
		||||
                                    Template.of("category", c.name().toLowerCase()),
 | 
			
		||||
                                    Template.of("category_desc", c.getComponent(player))
 | 
			
		||||
                                    TagResolver.builder()
 | 
			
		||||
                                            .tag("command", Tag.inserting(Component.text("/plot help")))
 | 
			
		||||
                                            .tag("category", Tag.inserting(Component.text(c.name().toLowerCase())))
 | 
			
		||||
                                            .tag("category_desc", Tag.inserting(c.toComponent(player)))
 | 
			
		||||
                                            .build()
 | 
			
		||||
                            ));
 | 
			
		||||
                }
 | 
			
		||||
                builder.append(Component.newline()).append(MINI_MESSAGE
 | 
			
		||||
                        .parse(
 | 
			
		||||
                        .deserialize(
 | 
			
		||||
                                TranslatableCaption.of("help.help_info_item").getComponent(player),
 | 
			
		||||
                                Template.of("command", "/plot help"),
 | 
			
		||||
                                Template.of("category", "all"),
 | 
			
		||||
                                Template.of("category_desc", "Display all commands")
 | 
			
		||||
                                TagResolver.builder()
 | 
			
		||||
                                        .tag("command", Tag.inserting(Component.text("/plot help")))
 | 
			
		||||
                                        .tag("category", Tag.inserting(Component.text("all")))
 | 
			
		||||
                                        .tag(
 | 
			
		||||
                                                "category_desc",
 | 
			
		||||
                                                Tag.inserting(TranslatableCaption
 | 
			
		||||
                                                        .of("help.help_display_all_commands")
 | 
			
		||||
                                                        .toComponent(player))
 | 
			
		||||
                                        )
 | 
			
		||||
                                        .build()
 | 
			
		||||
                        ));
 | 
			
		||||
                builder.append(Component.newline()).append(MINI_MESSAGE.parse(TranslatableCaption
 | 
			
		||||
                builder.append(Component.newline()).append(MINI_MESSAGE.deserialize(TranslatableCaption
 | 
			
		||||
                        .of("help.help_footer")
 | 
			
		||||
                        .getComponent(player)));
 | 
			
		||||
                player.sendMessage(StaticCaption.of(MINI_MESSAGE.serialize(builder.asComponent())));
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,9 @@ import com.plotsquared.core.util.query.PlotQuery;
 | 
			
		||||
import com.plotsquared.core.util.query.SortingStrategy;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal2;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal3;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.ArrayList;
 | 
			
		||||
@@ -71,8 +73,10 @@ public class HomeCommand extends Command {
 | 
			
		||||
        } else if (plots.size() < page || page < 1) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("invalid.number_not_in_range"),
 | 
			
		||||
                    Template.of("min", "1"),
 | 
			
		||||
                    Template.of("max", String.valueOf(plots.size()))
 | 
			
		||||
                    TagResolver.builder()
 | 
			
		||||
                            .tag("min", Tag.inserting(Component.text(1)))
 | 
			
		||||
                            .tag("max", Tag.inserting(Component.text(plots.size())))
 | 
			
		||||
                            .build()
 | 
			
		||||
            );
 | 
			
		||||
            return;
 | 
			
		||||
        }
 | 
			
		||||
@@ -106,7 +110,7 @@ public class HomeCommand extends Command {
 | 
			
		||||
        if (!player.hasPermission(Permission.PERMISSION_VISIT_OWNED) && !player.hasPermission(Permission.PERMISSION_HOME)) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                    Template.of("node", Permission.PERMISSION_VISIT_OWNED.toString())
 | 
			
		||||
                    TagResolver.resolver("node", Tag.inserting(Component.text(Permission.PERMISSION_VISIT_OWNED.toString())))
 | 
			
		||||
            );
 | 
			
		||||
            return CompletableFuture.completedFuture(false);
 | 
			
		||||
        }
 | 
			
		||||
@@ -128,7 +132,7 @@ public class HomeCommand extends Command {
 | 
			
		||||
                    } catch (NumberFormatException ignored) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("invalid.not_a_number"),
 | 
			
		||||
                                Template.of("value", identifier)
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(identifier)))
 | 
			
		||||
                        );
 | 
			
		||||
                        return CompletableFuture.completedFuture(false);
 | 
			
		||||
                    }
 | 
			
		||||
@@ -169,7 +173,7 @@ public class HomeCommand extends Command {
 | 
			
		||||
                    } catch (NumberFormatException ignored) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("invalid.not_a_number"),
 | 
			
		||||
                                Template.of("value", identifier)
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(identifier)))
 | 
			
		||||
                        );
 | 
			
		||||
                        return CompletableFuture.completedFuture(false);
 | 
			
		||||
                    }
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,6 @@ package com.plotsquared.core.command;
 | 
			
		||||
 | 
			
		||||
import com.google.inject.TypeLiteral;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.StaticCaption;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.Templates;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
 | 
			
		||||
import com.plotsquared.core.permissions.Permission;
 | 
			
		||||
import com.plotsquared.core.player.MetaDataAccess;
 | 
			
		||||
@@ -35,7 +34,8 @@ import com.plotsquared.core.util.TabCompletions;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal;
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
import net.kyori.adventure.text.TextComponent;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.Tag;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
 | 
			
		||||
 | 
			
		||||
import java.util.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
@@ -71,41 +71,44 @@ public class Inbox extends SubCommand {
 | 
			
		||||
            max = comments.length;
 | 
			
		||||
        }
 | 
			
		||||
        TextComponent.Builder builder = Component.text();
 | 
			
		||||
        builder.append(MINI_MESSAGE.parse(TranslatableCaption.of("list.comment_list_header_paged").getComponent(player) + '\n',
 | 
			
		||||
                Template.of("amount", String.valueOf(comments.length)), Template.of("cur", String.valueOf(page + 1)),
 | 
			
		||||
                Template.of("max", String.valueOf(totalPages + 1)), Template.of("word", "all")
 | 
			
		||||
        builder.append(MINI_MESSAGE.deserialize(
 | 
			
		||||
                TranslatableCaption.of("list.comment_list_header_paged").getComponent(player) + '\n',
 | 
			
		||||
                TagResolver.builder()
 | 
			
		||||
                        .tag("amount", Tag.inserting(Component.text(comments.length)))
 | 
			
		||||
                        .tag("cur", Tag.inserting(Component.text(page + 1)))
 | 
			
		||||
                        .tag("max", Tag.inserting(Component.text(totalPages + 1)))
 | 
			
		||||
                        .tag("word", Tag.inserting(Component.text("all")))
 | 
			
		||||
                        .build()
 | 
			
		||||
        ));
 | 
			
		||||
 | 
			
		||||
        // This might work xD
 | 
			
		||||
        for (int x = page * 12; x < max; x++) {
 | 
			
		||||
            PlotComment comment = comments[x];
 | 
			
		||||
            Component commentColored;
 | 
			
		||||
            if (player.getName().equals(comment.senderName)) {
 | 
			
		||||
            if (player.getName().equals(comment.senderName())) {
 | 
			
		||||
                commentColored = MINI_MESSAGE
 | 
			
		||||
                        .parse(
 | 
			
		||||
                        .deserialize(
 | 
			
		||||
                                TranslatableCaption.of("list.comment_list_by_lister").getComponent(player),
 | 
			
		||||
                                Template.of("comment", comment.comment)
 | 
			
		||||
                                TagResolver.resolver("comment", Tag.inserting(Component.text(comment.comment())))
 | 
			
		||||
                        );
 | 
			
		||||
            } else {
 | 
			
		||||
                commentColored = MINI_MESSAGE
 | 
			
		||||
                        .parse(
 | 
			
		||||
                        .deserialize(
 | 
			
		||||
                                TranslatableCaption.of("list.comment_list_by_other").getComponent(player),
 | 
			
		||||
                                Template.of("comment", comment.comment)
 | 
			
		||||
                                TagResolver.resolver("comment", Tag.inserting(Component.text(comment.comment())))
 | 
			
		||||
                        );
 | 
			
		||||
            }
 | 
			
		||||
            Template number = Template.of("number", String.valueOf(x));
 | 
			
		||||
            Template world = Template.of("world", comment.world);
 | 
			
		||||
            Template plot_id = Template.of("plot_id", comment.id.getX() + ";" + comment.id.getY());
 | 
			
		||||
            Template commenter = Template.of("commenter", comment.senderName);
 | 
			
		||||
            Template commentTemplate = Template.of("comment", commentColored);
 | 
			
		||||
            TagResolver resolver = TagResolver.builder()
 | 
			
		||||
                    .tag("number", Tag.inserting(Component.text(x)))
 | 
			
		||||
                    .tag("world", Tag.inserting(Component.text(comment.world())))
 | 
			
		||||
                    .tag("plot_id", Tag.inserting(Component.text(comment.id().getX() + ";" + comment.id().getY())))
 | 
			
		||||
                    .tag("commenter", Tag.inserting(Component.text(comment.senderName())))
 | 
			
		||||
                    .tag("comment", Tag.inserting(commentColored))
 | 
			
		||||
                    .build();
 | 
			
		||||
            builder.append(MINI_MESSAGE
 | 
			
		||||
                    .parse(
 | 
			
		||||
                    .deserialize(
 | 
			
		||||
                            TranslatableCaption.of("list.comment_list_comment").getComponent(player),
 | 
			
		||||
                            number,
 | 
			
		||||
                            world,
 | 
			
		||||
                            plot_id,
 | 
			
		||||
                            commenter,
 | 
			
		||||
                            commentTemplate
 | 
			
		||||
                            resolver
 | 
			
		||||
                    ));
 | 
			
		||||
        }
 | 
			
		||||
        player.sendMessage(StaticCaption.of(MINI_MESSAGE.serialize(builder.build())));
 | 
			
		||||
@@ -134,7 +137,7 @@ public class Inbox extends SubCommand {
 | 
			
		||||
                                int unread = 0;
 | 
			
		||||
                                for (PlotComment comment : value) {
 | 
			
		||||
                                    total++;
 | 
			
		||||
                                    if (comment.timestamp > CommentManager
 | 
			
		||||
                                    if (comment.timestamp() > CommentManager
 | 
			
		||||
                                            .getTimestamp(player, inbox.toString())) {
 | 
			
		||||
                                        unread++;
 | 
			
		||||
                                    }
 | 
			
		||||
@@ -142,20 +145,23 @@ public class Inbox extends SubCommand {
 | 
			
		||||
                                if (total != 0) {
 | 
			
		||||
                                    player.sendMessage(
 | 
			
		||||
                                            TranslatableCaption.of("comment.inbox_item"),
 | 
			
		||||
                                            Template.of("value", inbox + " (" + total + '/' + unread + ')')
 | 
			
		||||
                                            TagResolver.resolver(
 | 
			
		||||
                                                    "value",
 | 
			
		||||
                                                    Tag.inserting(Component.text(inbox + " (" + total + '/' + unread + ')'))
 | 
			
		||||
                                            )
 | 
			
		||||
                                    );
 | 
			
		||||
                                    return;
 | 
			
		||||
                                }
 | 
			
		||||
                            }
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("comment.inbox_item"),
 | 
			
		||||
                                    Template.of("value", inbox.toString())
 | 
			
		||||
                                    TagResolver.resolver("value", Tag.inserting(Component.text(inbox.toString())))
 | 
			
		||||
                            );
 | 
			
		||||
                        }
 | 
			
		||||
                    })) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("comment.inbox_item"),
 | 
			
		||||
                                Template.of("value", inbox.toString())
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(inbox.toString())))
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
@@ -166,7 +172,10 @@ public class Inbox extends SubCommand {
 | 
			
		||||
        if (inbox == null) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("comment.invalid_inbox"),
 | 
			
		||||
                    Template.of("list", StringMan.join(CommentManager.inboxes.keySet(), ", "))
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "list",
 | 
			
		||||
                            Tag.inserting(Component.text(StringMan.join(CommentManager.inboxes.keySet(), ", ")))
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -181,7 +190,7 @@ public class Inbox extends SubCommand {
 | 
			
		||||
        final int page;
 | 
			
		||||
        if (args.length > 1) {
 | 
			
		||||
            switch (args[1].toLowerCase()) {
 | 
			
		||||
                case "delete":
 | 
			
		||||
                case "delete" -> {
 | 
			
		||||
                    if (!inbox.canModify(plot, player)) {
 | 
			
		||||
                        player.sendMessage(TranslatableCaption.of("comment.no_perm_inbox_modify"));
 | 
			
		||||
                        return false;
 | 
			
		||||
@@ -189,7 +198,10 @@ public class Inbox extends SubCommand {
 | 
			
		||||
                    if (args.length != 3) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                                Template.of("value", "/plot inbox " + inbox + " delete <index>")
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "value",
 | 
			
		||||
                                        Tag.inserting(Component.text("/plot inbox " + inbox + " delete <index>"))
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -199,25 +211,27 @@ public class Inbox extends SubCommand {
 | 
			
		||||
                        if (index < 1) {
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("comment.not_valid_inbox_index"),
 | 
			
		||||
                                    Templates.of("number", index)
 | 
			
		||||
                                    TagResolver.resolver("number", Tag.inserting(Component.text(index)))
 | 
			
		||||
                            );
 | 
			
		||||
                            return false;
 | 
			
		||||
                        }
 | 
			
		||||
                    } catch (NumberFormatException ignored) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                                Template.of("value", "/plot inbox " + inbox + " delete <index>")
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "value",
 | 
			
		||||
                                        Tag.inserting(Component.text("/plot inbox " + inbox + " delete <index>"))
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (!inbox.getComments(plot, new RunnableVal<>() {
 | 
			
		||||
                        @Override
 | 
			
		||||
                        public void run(List<PlotComment> value) {
 | 
			
		||||
                            if (index > value.size()) {
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("comment.not_valid_inbox_index"),
 | 
			
		||||
                                        Templates.of("number", index)
 | 
			
		||||
                                        TagResolver.resolver("number", Tag.inserting(Component.text(index)))
 | 
			
		||||
                                );
 | 
			
		||||
                                return;
 | 
			
		||||
                            }
 | 
			
		||||
@@ -227,7 +241,7 @@ public class Inbox extends SubCommand {
 | 
			
		||||
                            if (success) {
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
                                        TranslatableCaption.of("comment.comment_removed_success"),
 | 
			
		||||
                                        Template.of("value", comment.comment)
 | 
			
		||||
                                        TagResolver.resolver("value", Tag.inserting(Component.text(comment.comment())))
 | 
			
		||||
                                );
 | 
			
		||||
                            } else {
 | 
			
		||||
                                player.sendMessage(
 | 
			
		||||
@@ -239,7 +253,8 @@ public class Inbox extends SubCommand {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    return true;
 | 
			
		||||
                case "clear":
 | 
			
		||||
                }
 | 
			
		||||
                case "clear" -> {
 | 
			
		||||
                    if (!inbox.canModify(plot, player)) {
 | 
			
		||||
                        player.sendMessage(TranslatableCaption.of("comment.no_perm_inbox_modify"));
 | 
			
		||||
                    }
 | 
			
		||||
@@ -248,18 +263,20 @@ public class Inbox extends SubCommand {
 | 
			
		||||
                    if (!comments.isEmpty()) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("comment.comment_removed_success"),
 | 
			
		||||
                                Template.of("value", String.valueOf(comments))
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text("*")))
 | 
			
		||||
                        );
 | 
			
		||||
                        plot.getPlotCommentContainer().removeComments(comments);
 | 
			
		||||
                    }
 | 
			
		||||
                    return true;
 | 
			
		||||
                default:
 | 
			
		||||
                }
 | 
			
		||||
                default -> {
 | 
			
		||||
                    try {
 | 
			
		||||
                        page = Integer.parseInt(args[1]);
 | 
			
		||||
                    } catch (NumberFormatException ignored) {
 | 
			
		||||
                        sendUsage(player);
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        } else {
 | 
			
		||||
            page = 1;
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,9 @@ import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import com.plotsquared.core.plot.Plot;
 | 
			
		||||
import com.plotsquared.core.plot.flag.implementations.HideInfoFlag;
 | 
			
		||||
import com.plotsquared.core.util.TabCompletions;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.Collection;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
@@ -50,8 +52,9 @@ public class Info extends SubCommand {
 | 
			
		||||
            arg = args[0];
 | 
			
		||||
            switch (arg) {
 | 
			
		||||
                // 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" -> plot = Plot
 | 
			
		||||
                        .getPlotFromString(player, null, false);
 | 
			
		||||
                case "trusted", "alias", "biome", "denied", "flags", "id", "size", "members", "creationdate", "seen", "owner", "rating", "likes" ->
 | 
			
		||||
                        plot = Plot
 | 
			
		||||
                                .getPlotFromString(player, null, false);
 | 
			
		||||
                default -> {
 | 
			
		||||
                    plot = Plot.getPlotFromString(player, arg, false);
 | 
			
		||||
                    if (args.length == 2) {
 | 
			
		||||
@@ -90,7 +93,10 @@ public class Info extends SubCommand {
 | 
			
		||||
                            .hasPermission(Permission.PERMISSION_AREA_INFO_FORCE.toString())) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                Template.of("node", Permission.PERMISSION_AREA_INFO_FORCE.toString())
 | 
			
		||||
                                TagResolver.resolver(
 | 
			
		||||
                                        "node",
 | 
			
		||||
                                        Tag.inserting(Permission.PERMISSION_AREA_INFO_FORCE)
 | 
			
		||||
                                )
 | 
			
		||||
                        );
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -112,7 +118,10 @@ public class Info extends SubCommand {
 | 
			
		||||
        if (!hasOwner && !containsEveryone && !trustedEveryone) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("info.plot_info_unclaimed"),
 | 
			
		||||
                    Template.of("plot", plot.getId().getX() + ";" + plot.getId().getY())
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "plot",
 | 
			
		||||
                            Tag.inserting(Component.text(plot.getId().getX() + ";" + plot.getId().getY()))
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
 
 | 
			
		||||
@@ -30,7 +30,9 @@ import com.plotsquared.core.plot.world.PlotAreaManager;
 | 
			
		||||
import com.plotsquared.core.util.PlayerManager;
 | 
			
		||||
import com.plotsquared.core.util.TabCompletions;
 | 
			
		||||
import com.plotsquared.core.util.WorldUtil;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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;
 | 
			
		||||
@@ -80,7 +82,7 @@ public class Kick extends SubCommand {
 | 
			
		||||
            } else if (throwable != null || uuids.isEmpty()) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                        Template.of("value", args[0])
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text(args[0])))
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                Set<PlotPlayer<?>> players = new HashSet<>();
 | 
			
		||||
@@ -103,7 +105,7 @@ public class Kick extends SubCommand {
 | 
			
		||||
                if (players.isEmpty()) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                            Template.of("value", args[0])
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text(args[0])))
 | 
			
		||||
                    );
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
@@ -111,14 +113,14 @@ public class Kick extends SubCommand {
 | 
			
		||||
                    if (!plot.equals(player2.getCurrentPlot())) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                                Template.of("value", args[0])
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(args[0])))
 | 
			
		||||
                        );
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (player2.hasPermission(Permission.PERMISSION_ADMIN_ENTRY_DENIED)) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("cluster.cannot_kick_player"),
 | 
			
		||||
                                Template.of("name", player2.getName())
 | 
			
		||||
                                TagResolver.resolver("name", Tag.inserting(Component.text(player2.getName())))
 | 
			
		||||
                        );
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,9 @@ import com.plotsquared.core.plot.Plot;
 | 
			
		||||
import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal2;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal3;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.UUID;
 | 
			
		||||
@@ -67,7 +69,7 @@ public class Leave extends Command {
 | 
			
		||||
                }
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("member.plot_left"),
 | 
			
		||||
                        Template.of("player", player.getName())
 | 
			
		||||
                        TagResolver.resolver("player", Tag.inserting(Component.text(player.getName())))
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,9 @@ import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import com.plotsquared.core.util.TabCompletions;
 | 
			
		||||
import com.plotsquared.core.util.query.PlotQuery;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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;
 | 
			
		||||
@@ -151,7 +153,7 @@ public class Like extends SubCommand {
 | 
			
		||||
            if (oldRating != null) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("ratings.rating_already_exists"),
 | 
			
		||||
                        Template.of("plot", plot.getId().toString())
 | 
			
		||||
                        TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString())))
 | 
			
		||||
                );
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
@@ -169,12 +171,12 @@ public class Like extends SubCommand {
 | 
			
		||||
                if (like) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("ratings.rating_liked"),
 | 
			
		||||
                            Template.of("plot", plot.getId().toString())
 | 
			
		||||
                            TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString())))
 | 
			
		||||
                    );
 | 
			
		||||
                } else {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("ratings.rating_disliked"),
 | 
			
		||||
                            Template.of("plot", plot.getId().toString())
 | 
			
		||||
                            TagResolver.resolver("plot", Tag.inserting(Component.text(plot.getId().toString())))
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,6 @@ import com.plotsquared.core.PlotSquared;
 | 
			
		||||
import com.plotsquared.core.configuration.Settings;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.Caption;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.CaptionHolder;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.Templates;
 | 
			
		||||
import com.plotsquared.core.configuration.caption.TranslatableCaption;
 | 
			
		||||
import com.plotsquared.core.database.DBFunc;
 | 
			
		||||
import com.plotsquared.core.permissions.Permission;
 | 
			
		||||
@@ -46,7 +45,8 @@ import com.plotsquared.core.util.task.RunnableVal3;
 | 
			
		||||
import com.plotsquared.core.uuid.UUIDMapping;
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
import net.kyori.adventure.text.TextComponent;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.ArrayList;
 | 
			
		||||
@@ -123,7 +123,7 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
    public void noArgs(PlotPlayer<?> player) {
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("commandconfig.subcommand_set_options_header"),
 | 
			
		||||
                Templates.of("values", Arrays.toString(getArgumentList(player)))
 | 
			
		||||
                TagResolver.resolver("values", Tag.inserting(Component.text(Arrays.toString(getArgumentList(player)))))
 | 
			
		||||
        );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -159,9 +159,14 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
            if (query == null) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("commandconfig.did_you_mean"),
 | 
			
		||||
                        Template.of(
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "value",
 | 
			
		||||
                                new StringComparison<>(args[0], new String[]{"mine", "shared", "world", "all"}).getBestMatch()
 | 
			
		||||
                                Tag.inserting(Component.text(
 | 
			
		||||
                                        new StringComparison<>(
 | 
			
		||||
                                                args[0],
 | 
			
		||||
                                                new String[]{"mine", "shared", "world", "all"}
 | 
			
		||||
                                        ).getBestMatch()
 | 
			
		||||
                                ))
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                return;
 | 
			
		||||
@@ -189,7 +194,7 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_LIST_MINE)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Templates.of("node", "plots.list.mine")
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.mine")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -204,7 +209,7 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_LIST_SHARED)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Templates.of("node", "plots.list.shared")
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.shared")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -217,14 +222,14 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_LIST_WORLD)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Templates.of("node", "plots.list.world")
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.world")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (!player.hasPermission("plots.list.world." + world)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Templates.of("node", "plots.list.world." + world)
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.world." + world)))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -234,7 +239,7 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_LIST_EXPIRED)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Templates.of("node", "plots.list.expired")
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.expired")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -248,14 +253,14 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_LIST_AREA)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Templates.of("node", "plots.list.area")
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.area")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (!player.hasPermission("plots.list.world." + world)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Templates.of("node", "plots.list.world." + world)
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.world." + world)))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -269,7 +274,7 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_LIST_ALL)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Templates.of("node", "plots.list.all")
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.all")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -279,7 +284,7 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_LIST_DONE)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Templates.of("node", "plots.list.done")
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.done")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -294,7 +299,7 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_LIST_TOP)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Templates.of("node", "plots.list.top")
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.top")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -305,7 +310,7 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_LIST_FOR_SALE)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Templates.of("node", "plots.list.forsale")
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.forsale")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -318,7 +323,7 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_LIST_UNOWNED)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Templates.of("node", "plots.list.unowned")
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.unowned")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -328,14 +333,14 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                if (!player.hasPermission(Permission.PERMISSION_LIST_FUZZY)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                            Templates.of("node", "plots.list.fuzzy")
 | 
			
		||||
                            TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.fuzzy")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
                if (args.length < (page == -1 ? 2 : 3)) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                            Templates.of("value", "/plot list fuzzy <search...> [#]")
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text("/plot list fuzzy <search...> [#]")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
@@ -353,14 +358,14 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                    if (!player.hasPermission(Permission.PERMISSION_LIST_WORLD)) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                Templates.of("node", "plots.list.world")
 | 
			
		||||
                                TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.world")))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    if (!player.hasPermission("plots.list.world." + args[0])) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                Templates.of("node", "plots.list.world." + args[0])
 | 
			
		||||
                                TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.world." + args[0])))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -379,12 +384,15 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                    if (uuid == null) {
 | 
			
		||||
                        player.sendMessage(TranslatableCaption.of("errors.invalid_player"), Templates.of("value", args[0]));
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(args[0])))
 | 
			
		||||
                        );
 | 
			
		||||
                    } else {
 | 
			
		||||
                        if (!player.hasPermission(Permission.PERMISSION_LIST_PLAYER)) {
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                                    Templates.of("node", "plots.list.player")
 | 
			
		||||
                                    TagResolver.resolver("node", Tag.inserting(Component.text("plots.list.player")))
 | 
			
		||||
                            );
 | 
			
		||||
                        } else {
 | 
			
		||||
                            sort[0] = false;
 | 
			
		||||
@@ -420,32 +428,34 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                } else {
 | 
			
		||||
                    color = TranslatableCaption.of("info.plot_list_default");
 | 
			
		||||
                }
 | 
			
		||||
                Component trusted = MINI_MESSAGE.parse(
 | 
			
		||||
                Component trusted = MINI_MESSAGE.deserialize(
 | 
			
		||||
                        TranslatableCaption.of("info.plot_info_trusted").getComponent(player),
 | 
			
		||||
                        Template.of("trusted", PlayerManager.getPlayerList(plot.getTrusted(), player))
 | 
			
		||||
                        TagResolver.resolver("trusted", Tag.inserting(PlayerManager.getPlayerList(plot.getTrusted(), player)))
 | 
			
		||||
                );
 | 
			
		||||
                Component members = MINI_MESSAGE.parse(
 | 
			
		||||
                Component members = MINI_MESSAGE.deserialize(
 | 
			
		||||
                        TranslatableCaption.of("info.plot_info_members").getComponent(player),
 | 
			
		||||
                        Template.of("members", PlayerManager.getPlayerList(plot.getMembers(), player))
 | 
			
		||||
                        TagResolver.resolver("members", Tag.inserting(PlayerManager.getPlayerList(plot.getMembers(), player)))
 | 
			
		||||
                );
 | 
			
		||||
                Template command_tp = Template.of("command_tp", "/plot visit " + plot.getArea() + ";" + plot.getId());
 | 
			
		||||
                Template command_info = Template.of("command_info", "/plot info " + plot.getArea() + ";" + plot.getId());
 | 
			
		||||
                Template hover_info =
 | 
			
		||||
                        Template.of(
 | 
			
		||||
                                "hover_info",
 | 
			
		||||
                                MINI_MESSAGE.serialize(Component
 | 
			
		||||
                                        .text()
 | 
			
		||||
                                        .append(trusted)
 | 
			
		||||
                                        .append(Component.newline())
 | 
			
		||||
                                        .append(members)
 | 
			
		||||
                                        .asComponent())
 | 
			
		||||
                        );
 | 
			
		||||
                Template numberTemplate = Template.of("number", String.valueOf(i));
 | 
			
		||||
                Template plotTemplate = Template.of(
 | 
			
		||||
                        "plot",
 | 
			
		||||
                        MINI_MESSAGE.parse(color.getComponent(player), Template.of("plot", plot.toString()))
 | 
			
		||||
                TagResolver.Builder finalResolver = TagResolver.builder();
 | 
			
		||||
                finalResolver.tag(
 | 
			
		||||
                        "command_tp",
 | 
			
		||||
                        Tag.preProcessParsed("/plot visit " + plot.getArea() + ";" + plot.getId())
 | 
			
		||||
                );
 | 
			
		||||
 | 
			
		||||
                finalResolver.tag(
 | 
			
		||||
                        "command_info",
 | 
			
		||||
                        Tag.preProcessParsed("/plot info " + plot.getArea() + ";" + plot.getId())
 | 
			
		||||
                );
 | 
			
		||||
                finalResolver.tag("hover_info", Tag.inserting(
 | 
			
		||||
                        Component.text()
 | 
			
		||||
                                .append(trusted)
 | 
			
		||||
                                .append(Component.newline())
 | 
			
		||||
                                .append(members)
 | 
			
		||||
                                .asComponent()
 | 
			
		||||
                ));
 | 
			
		||||
                finalResolver.tag("number", Tag.inserting(Component.text(i)));
 | 
			
		||||
                finalResolver.tag("plot", Tag.inserting(MINI_MESSAGE.deserialize(
 | 
			
		||||
                        color.getComponent(player), TagResolver.resolver("plot", Tag.inserting(Component.text(plot.toString())))
 | 
			
		||||
                )));
 | 
			
		||||
                String prefix = "";
 | 
			
		||||
                String online = TranslatableCaption.of("info.plot_list_player_online").getComponent(player);
 | 
			
		||||
                String offline = TranslatableCaption.of("info.plot_list_player_offline").getComponent(player);
 | 
			
		||||
@@ -454,35 +464,37 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                String everyone = TranslatableCaption.of("info.plot_list_player_everyone").getComponent(player);
 | 
			
		||||
                TextComponent.Builder builder = Component.text();
 | 
			
		||||
                if (plot.getFlag(ServerPlotFlag.class)) {
 | 
			
		||||
                    Template serverTemplate = Template.of(
 | 
			
		||||
                    TagResolver serverResolver = TagResolver.resolver(
 | 
			
		||||
                            "info.server",
 | 
			
		||||
                            TranslatableCaption.of("info.server").getComponent(player)
 | 
			
		||||
                            Tag.inserting(TranslatableCaption.of("info.server").toComponent(player))
 | 
			
		||||
                    );
 | 
			
		||||
                    builder.append(MINI_MESSAGE.parse(server, serverTemplate));
 | 
			
		||||
                    builder.append(MINI_MESSAGE.deserialize(server, serverResolver));
 | 
			
		||||
                } else {
 | 
			
		||||
                    try {
 | 
			
		||||
                        final List<UUIDMapping> names = PlotSquared.get().getImpromptuUUIDPipeline().getNames(plot.getOwners())
 | 
			
		||||
                                .get(Settings.UUID.BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS);
 | 
			
		||||
                        for (final UUIDMapping uuidMapping : names) {
 | 
			
		||||
                            PlotPlayer<?> pp = PlotSquared.platform().playerManager().getPlayerIfExists(uuidMapping.getUuid());
 | 
			
		||||
                            Template prefixTemplate = Template.of("prefix", prefix);
 | 
			
		||||
                            Template playerTemplate = Template.of("player", uuidMapping.getUsername());
 | 
			
		||||
                            PlotPlayer<?> pp = PlotSquared.platform().playerManager().getPlayerIfExists(uuidMapping.uuid());
 | 
			
		||||
                            TagResolver resolver = TagResolver.builder()
 | 
			
		||||
                                    .tag("prefix", Tag.inserting(Component.text(prefix)))
 | 
			
		||||
                                    .tag("player", Tag.inserting(Component.text(uuidMapping.username())))
 | 
			
		||||
                                    .build();
 | 
			
		||||
                            if (pp != null) {
 | 
			
		||||
                                builder.append(MINI_MESSAGE.parse(online, prefixTemplate, playerTemplate));
 | 
			
		||||
                            } else if (uuidMapping.getUsername().equalsIgnoreCase("unknown")) {
 | 
			
		||||
                                Template unknownTemplate = Template.of(
 | 
			
		||||
                                builder.append(MINI_MESSAGE.deserialize(online, resolver));
 | 
			
		||||
                            } else if (uuidMapping.username().equalsIgnoreCase("unknown")) {
 | 
			
		||||
                                TagResolver unknownResolver = TagResolver.resolver(
 | 
			
		||||
                                        "info.unknown",
 | 
			
		||||
                                        TranslatableCaption.of("info.unknown").getComponent(player)
 | 
			
		||||
                                        Tag.inserting(TranslatableCaption.of("info.unknown").toComponent(player))
 | 
			
		||||
                                );
 | 
			
		||||
                                builder.append(MINI_MESSAGE.parse(unknown, unknownTemplate));
 | 
			
		||||
                            } else if (uuidMapping.getUuid().equals(DBFunc.EVERYONE)) {
 | 
			
		||||
                                Template everyoneTemplate = Template.of(
 | 
			
		||||
                                builder.append(MINI_MESSAGE.deserialize(unknown, unknownResolver));
 | 
			
		||||
                            } else if (uuidMapping.uuid().equals(DBFunc.EVERYONE)) {
 | 
			
		||||
                                TagResolver everyoneResolver = TagResolver.resolver(
 | 
			
		||||
                                        "info.everyone",
 | 
			
		||||
                                        TranslatableCaption.of("info.everyone").getComponent(player)
 | 
			
		||||
                                        Tag.inserting(TranslatableCaption.of("info.everyone").toComponent(player))
 | 
			
		||||
                                );
 | 
			
		||||
                                builder.append(MINI_MESSAGE.parse(everyone, everyoneTemplate));
 | 
			
		||||
                                builder.append(MINI_MESSAGE.deserialize(everyone, everyoneResolver));
 | 
			
		||||
                            } else {
 | 
			
		||||
                                builder.append(MINI_MESSAGE.parse(offline, prefixTemplate, playerTemplate));
 | 
			
		||||
                                builder.append(MINI_MESSAGE.deserialize(offline, resolver));
 | 
			
		||||
                            }
 | 
			
		||||
                            prefix = ", ";
 | 
			
		||||
                        }
 | 
			
		||||
@@ -498,15 +510,15 @@ public class ListCmd extends SubCommand {
 | 
			
		||||
                        }
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                                Templates.of("value", playerBuilder.toString())
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(playerBuilder.toString())))
 | 
			
		||||
                        );
 | 
			
		||||
                    } catch (TimeoutException e) {
 | 
			
		||||
                        player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout"));
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                Template players = Template.of("players", builder.asComponent());
 | 
			
		||||
                finalResolver.tag("players", Tag.inserting(builder.asComponent()));
 | 
			
		||||
                caption.set(TranslatableCaption.of("info.plot_list_item"));
 | 
			
		||||
                caption.setTemplates(command_tp, command_info, hover_info, numberTemplate, plotTemplate, players);
 | 
			
		||||
                caption.setTagResolvers(finalResolver.build());
 | 
			
		||||
            }
 | 
			
		||||
        }, "/plot list " + args[0], TranslatableCaption.of("list.plot_list_header_paged"));
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,9 @@ import com.plotsquared.core.util.SchematicHandler;
 | 
			
		||||
import com.plotsquared.core.util.TimeUtil;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.net.MalformedURLException;
 | 
			
		||||
@@ -97,7 +99,7 @@ public class Load extends SubCommand {
 | 
			
		||||
                        // No schematics found:
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("web.load_null"),
 | 
			
		||||
                                Template.of("command", "/plot load")
 | 
			
		||||
                                TagResolver.resolver("command", Tag.inserting(Component.text("/plot load")))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -108,7 +110,7 @@ public class Load extends SubCommand {
 | 
			
		||||
                        // use /plot load <index>
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("invalid.not_valid_number"),
 | 
			
		||||
                                Template.of("value", "(1, " + schematics.size() + ')')
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text("(1, " + schematics.size() + ')')))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
@@ -128,7 +130,10 @@ public class Load extends SubCommand {
 | 
			
		||||
                            plot.removeRunning();
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("schematics.schematic_invalid"),
 | 
			
		||||
                                    Template.of("reason", "non-existent or not in gzip format")
 | 
			
		||||
                                    TagResolver.resolver(
 | 
			
		||||
                                            "reason",
 | 
			
		||||
                                            Tag.inserting(Component.text("non-existent or not in gzip format"))
 | 
			
		||||
                                    )
 | 
			
		||||
                            );
 | 
			
		||||
                            return;
 | 
			
		||||
                        }
 | 
			
		||||
@@ -159,7 +164,7 @@ public class Load extends SubCommand {
 | 
			
		||||
                plot.removeRunning();
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                        Template.of("value", "/plot load <index>")
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text("/plot load <index>")))
 | 
			
		||||
                );
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
@@ -210,46 +215,9 @@ public class Load extends SubCommand {
 | 
			
		||||
            }
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("web.load_list"),
 | 
			
		||||
                    Template.of("command", "/plot load #")
 | 
			
		||||
                    TagResolver.resolver("command", Tag.inserting(Component.text("/plot load #")))
 | 
			
		||||
            );
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * @deprecated Use {@link TimeUtil#secToTime(long)}
 | 
			
		||||
     */
 | 
			
		||||
    @Deprecated(forRemoval = true, since = "6.6.2")
 | 
			
		||||
    public String secToTime(long time) {
 | 
			
		||||
        StringBuilder toreturn = new StringBuilder();
 | 
			
		||||
        if (time >= 33868800) {
 | 
			
		||||
            int years = (int) (time / 33868800);
 | 
			
		||||
            time -= years * 33868800;
 | 
			
		||||
            toreturn.append(years).append("y ");
 | 
			
		||||
        }
 | 
			
		||||
        if (time >= 604800) {
 | 
			
		||||
            int weeks = (int) (time / 604800);
 | 
			
		||||
            time -= weeks * 604800;
 | 
			
		||||
            toreturn.append(weeks).append("w ");
 | 
			
		||||
        }
 | 
			
		||||
        if (time >= 86400) {
 | 
			
		||||
            int days = (int) (time / 86400);
 | 
			
		||||
            time -= days * 86400;
 | 
			
		||||
            toreturn.append(days).append("d ");
 | 
			
		||||
        }
 | 
			
		||||
        if (time >= 3600) {
 | 
			
		||||
            int hours = (int) (time / 3600);
 | 
			
		||||
            time -= hours * 3600;
 | 
			
		||||
            toreturn.append(hours).append("h ");
 | 
			
		||||
        }
 | 
			
		||||
        if (time >= 60) {
 | 
			
		||||
            int minutes = (int) (time / 60);
 | 
			
		||||
            time -= minutes * 60;
 | 
			
		||||
            toreturn.append(minutes).append("m ");
 | 
			
		||||
        }
 | 
			
		||||
        if (toreturn.length() == 0 || (time > 0)) {
 | 
			
		||||
            toreturn.append(time).append("s ");
 | 
			
		||||
        }
 | 
			
		||||
        return toreturn.toString().trim();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -35,6 +35,9 @@ import com.plotsquared.core.util.EconHandler;
 | 
			
		||||
import com.plotsquared.core.util.PlotExpression;
 | 
			
		||||
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.apache.logging.log4j.LogManager;
 | 
			
		||||
import org.apache.logging.log4j.Logger;
 | 
			
		||||
 | 
			
		||||
@@ -71,7 +74,6 @@ public class MainCommand extends Command {
 | 
			
		||||
            commands.add(Buy.class);
 | 
			
		||||
            if (Settings.Web.LEGACY_WEBINTERFACE) {
 | 
			
		||||
                LOGGER.warn("Legacy webinterface is used. Please note that it will be removed in future.");
 | 
			
		||||
                commands.add(Save.class);
 | 
			
		||||
            }
 | 
			
		||||
            commands.add(Load.class);
 | 
			
		||||
            commands.add(Confirm.class);
 | 
			
		||||
@@ -120,7 +122,6 @@ public class MainCommand extends Command {
 | 
			
		||||
            commands.add(Move.class);
 | 
			
		||||
            commands.add(Condense.class);
 | 
			
		||||
            commands.add(Copy.class);
 | 
			
		||||
            commands.add(Chat.class);
 | 
			
		||||
            commands.add(Trim.class);
 | 
			
		||||
            commands.add(Done.class);
 | 
			
		||||
            commands.add(Continue.class);
 | 
			
		||||
@@ -310,7 +311,7 @@ public class MainCommand extends Command {
 | 
			
		||||
            if (message != null) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("errors.error"),
 | 
			
		||||
                        net.kyori.adventure.text.minimessage.Template.of("value", message)
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text(message)))
 | 
			
		||||
                );
 | 
			
		||||
            } else {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,9 @@ import com.plotsquared.core.util.EconHandler;
 | 
			
		||||
import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import com.plotsquared.core.util.PlotExpression;
 | 
			
		||||
import com.plotsquared.core.util.StringMan;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.UUID;
 | 
			
		||||
@@ -114,11 +116,13 @@ public class Merge extends SubCommand {
 | 
			
		||||
        if (direction == null) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", "/plot merge <" + StringMan.join(values, " | ") + "> [removeroads]")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text(
 | 
			
		||||
                            "/plot merge <" + StringMan.join(values, " | ") + "> [removeroads]"
 | 
			
		||||
                    )))
 | 
			
		||||
            );
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("help.direction"),
 | 
			
		||||
                    Template.of("dir", direction(location.getYaw()))
 | 
			
		||||
                    TagResolver.resolver("dir", Tag.inserting(Component.text(direction(location.getYaw()))))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -129,7 +133,7 @@ public class Merge extends SubCommand {
 | 
			
		||||
        if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                    Template.of("value", "Merge")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("Merge")))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -140,7 +144,7 @@ public class Merge extends SubCommand {
 | 
			
		||||
        if (!force && size - 1 > maxSize) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                    Template.of("node", Permission.PERMISSION_MERGE + "." + (size + 1))
 | 
			
		||||
                    TagResolver.resolver("node", Tag.inserting(Component.text(Permission.PERMISSION_MERGE + "." + (size + 1))))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -166,7 +170,10 @@ public class Merge extends SubCommand {
 | 
			
		||||
            if (!force && !terrain && !player.hasPermission(Permission.PERMISSION_MERGE_KEEP_ROAD)) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                        Template.of("node", String.valueOf(Permission.PERMISSION_MERGE_KEEP_ROAD))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "node",
 | 
			
		||||
                                Tag.inserting(Permission.PERMISSION_MERGE_KEEP_ROAD)
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                return true;
 | 
			
		||||
            }
 | 
			
		||||
@@ -175,8 +182,11 @@ public class Merge extends SubCommand {
 | 
			
		||||
                    this.econHandler.withdrawMoney(player, price);
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("economy.removed_balance"),
 | 
			
		||||
                            Template.of("money", this.econHandler.format(price)),
 | 
			
		||||
                            Template.of("balance", this.econHandler.format(this.econHandler.getMoney(player)))
 | 
			
		||||
                            TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price)))),
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "balance",
 | 
			
		||||
                                    Tag.inserting(Component.text(this.econHandler.format(this.econHandler.getMoney(player))))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("merge.success_merge"));
 | 
			
		||||
@@ -190,7 +200,7 @@ public class Merge extends SubCommand {
 | 
			
		||||
                && this.econHandler.getMoney(player) < price) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("economy.cannot_afford_merge"),
 | 
			
		||||
                    Template.of("money", this.econHandler.format(price))
 | 
			
		||||
                    TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price))))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -203,7 +213,7 @@ public class Merge extends SubCommand {
 | 
			
		||||
        if (!force && !terrain && !player.hasPermission(Permission.PERMISSION_MERGE_KEEP_ROAD)) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_MERGE_KEEP_ROAD))
 | 
			
		||||
                    TagResolver.resolver("node", Tag.inserting(Permission.PERMISSION_MERGE_KEEP_ROAD))
 | 
			
		||||
            );
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
@@ -212,7 +222,7 @@ public class Merge extends SubCommand {
 | 
			
		||||
                this.econHandler.withdrawMoney(player, price);
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("economy.removed_balance"),
 | 
			
		||||
                        Template.of("money", this.econHandler.format(price))
 | 
			
		||||
                        TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price))))
 | 
			
		||||
                );
 | 
			
		||||
            }
 | 
			
		||||
            player.sendMessage(TranslatableCaption.of("merge.success_merge"));
 | 
			
		||||
@@ -228,7 +238,7 @@ public class Merge extends SubCommand {
 | 
			
		||||
        if (!force && !player.hasPermission(Permission.PERMISSION_MERGE_OTHER)) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_MERGE_OTHER))
 | 
			
		||||
                    TagResolver.resolver("node", Tag.inserting(Permission.PERMISSION_MERGE_OTHER))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -253,14 +263,14 @@ public class Merge extends SubCommand {
 | 
			
		||||
                    if (!force && this.econHandler.getMoney(player) < price) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("economy.cannot_afford_merge"),
 | 
			
		||||
                                Template.of("money", this.econHandler.format(price))
 | 
			
		||||
                                TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price))))
 | 
			
		||||
                        );
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                    this.econHandler.withdrawMoney(player, price);
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("economy.removed_balance"),
 | 
			
		||||
                            Template.of("money", this.econHandler.format(price))
 | 
			
		||||
                            TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price))))
 | 
			
		||||
                    );
 | 
			
		||||
                }
 | 
			
		||||
                player.sendMessage(TranslatableCaption.of("merge.success_merge"));
 | 
			
		||||
@@ -268,10 +278,15 @@ public class Merge extends SubCommand {
 | 
			
		||||
            };
 | 
			
		||||
            if (!force && hasConfirmation(player)) {
 | 
			
		||||
                CmdConfirm.addPending(accepter, MINI_MESSAGE.serialize(MINI_MESSAGE
 | 
			
		||||
                                .parse(
 | 
			
		||||
                                .deserialize(
 | 
			
		||||
                                        TranslatableCaption.of("merge.merge_request_confirm").getComponent(player),
 | 
			
		||||
                                        Template.of("player", player.getName()),
 | 
			
		||||
                                        Template.of("location", plot.getWorldName() + ";" + plot.getId())
 | 
			
		||||
                                        TagResolver.builder()
 | 
			
		||||
                                                .tag("player", Tag.inserting(Component.text(player.getName())))
 | 
			
		||||
                                                .tag(
 | 
			
		||||
                                                        "location",
 | 
			
		||||
                                                        Tag.inserting(Component.text(plot.getWorldName() + " " + plot.getId()))
 | 
			
		||||
                                                )
 | 
			
		||||
                                                .build()
 | 
			
		||||
                                )),
 | 
			
		||||
                        run
 | 
			
		||||
                );
 | 
			
		||||
@@ -292,14 +307,14 @@ public class Merge extends SubCommand {
 | 
			
		||||
                        if (!force && this.econHandler.getMoney(player) < price) {
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("economy.cannot_afford_merge"),
 | 
			
		||||
                                    Template.of("money", this.econHandler.format(price))
 | 
			
		||||
                                    TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price))))
 | 
			
		||||
                            );
 | 
			
		||||
                            return false;
 | 
			
		||||
                        }
 | 
			
		||||
                        this.econHandler.withdrawMoney(player, price);
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("economy.removed_balance"),
 | 
			
		||||
                                Template.of("money", this.econHandler.format(price))
 | 
			
		||||
                                TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price))))
 | 
			
		||||
                        );
 | 
			
		||||
                    }
 | 
			
		||||
                    player.sendMessage(TranslatableCaption.of("merge.success_merge"));
 | 
			
		||||
 
 | 
			
		||||
@@ -28,7 +28,9 @@ import com.plotsquared.core.plot.PlotArea;
 | 
			
		||||
import com.plotsquared.core.plot.world.PlotAreaManager;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal2;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal3;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.CompletableFuture;
 | 
			
		||||
@@ -104,8 +106,10 @@ public class Move extends SubCommand {
 | 
			
		||||
            if (result) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("move.move_success"),
 | 
			
		||||
                        Template.of("origin", p1),
 | 
			
		||||
                        Template.of("target", p2)
 | 
			
		||||
                        TagResolver.builder()
 | 
			
		||||
                                .tag("origin", Tag.inserting(Component.text(p1)))
 | 
			
		||||
                                .tag("target", Tag.inserting(Component.text(p2)))
 | 
			
		||||
                                .build()
 | 
			
		||||
                );
 | 
			
		||||
                return true;
 | 
			
		||||
            } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -35,7 +35,9 @@ import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import com.plotsquared.core.util.InventoryUtil;
 | 
			
		||||
import com.sk89q.worldedit.world.item.ItemType;
 | 
			
		||||
import com.sk89q.worldedit.world.item.ItemTypes;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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 javax.annotation.Nullable;
 | 
			
		||||
@@ -54,7 +56,7 @@ public class Music extends SubCommand {
 | 
			
		||||
            .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_strad", "music_disc_ward", "music_disc_11", "music_disc_wait", "music_disc_otherside",
 | 
			
		||||
                    "music_disc_pigstep", "music_disc_5"
 | 
			
		||||
                    "music_disc_pigstep", "music_disc_5", "music_disc_relic"
 | 
			
		||||
            );
 | 
			
		||||
 | 
			
		||||
    private final InventoryUtil inventoryUtil;
 | 
			
		||||
@@ -81,7 +83,10 @@ public class Music extends SubCommand {
 | 
			
		||||
        if (!plot.isAdded(player.getUUID()) && !player.hasPermission(Permission.PERMISSION_ADMIN_MUSIC_OTHER)) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("permission.no_permission"),
 | 
			
		||||
                    Template.of("node", String.valueOf(Permission.PERMISSION_ADMIN_MUSIC_OTHER))
 | 
			
		||||
                    TagResolver.resolver(
 | 
			
		||||
                            "node",
 | 
			
		||||
                            Tag.inserting(Permission.PERMISSION_ADMIN_MUSIC_OTHER)
 | 
			
		||||
                    )
 | 
			
		||||
            );
 | 
			
		||||
            return true;
 | 
			
		||||
        }
 | 
			
		||||
@@ -104,15 +109,17 @@ public class Music extends SubCommand {
 | 
			
		||||
                    if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
                        getPlayer().sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                                Template.of("value", "Music removal")
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text("Music removal")))
 | 
			
		||||
                        );
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    plot.removeFlag(event.getFlag());
 | 
			
		||||
                    getPlayer().sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("flag.flag_removed"),
 | 
			
		||||
                            Template.of("flag", "music"),
 | 
			
		||||
                            Template.of("value", "music_disc")
 | 
			
		||||
                            TagResolver.builder()
 | 
			
		||||
                                    .tag("flag", Tag.inserting(Component.text("music")))
 | 
			
		||||
                                    .tag("value", Tag.inserting(Component.text("music_disc")))
 | 
			
		||||
                                    .build()
 | 
			
		||||
                    );
 | 
			
		||||
                } else if (item.getName().toLowerCase(Locale.ENGLISH).contains("disc")) {
 | 
			
		||||
                    PlotFlag<?, ?> plotFlag = plot.getFlagContainer().getFlag(MusicFlag.class)
 | 
			
		||||
@@ -121,13 +128,17 @@ public class Music extends SubCommand {
 | 
			
		||||
                    if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
                        getPlayer().sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                                Template.of("value", "Music addition")
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text("Music addition")))
 | 
			
		||||
                        );
 | 
			
		||||
                        return true;
 | 
			
		||||
                    }
 | 
			
		||||
                    plot.setFlag(event.getFlag());
 | 
			
		||||
                    getPlayer().sendMessage(TranslatableCaption.of("flag.flag_added"), Template.of("flag", "music"),
 | 
			
		||||
                            Template.of("value", String.valueOf(event.getFlag().getValue()))
 | 
			
		||||
                    getPlayer().sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("flag.flag_added"),
 | 
			
		||||
                            TagResolver.builder()
 | 
			
		||||
                                    .tag("flag", Tag.inserting(Component.text("music")))
 | 
			
		||||
                                    .tag("value", Tag.inserting(Component.text(event.getFlag().getValue().toString())))
 | 
			
		||||
                                    .build()
 | 
			
		||||
                    );
 | 
			
		||||
                } else {
 | 
			
		||||
                    getPlayer().sendMessage(TranslatableCaption.of("flag.flag_not_added"));
 | 
			
		||||
 
 | 
			
		||||
@@ -24,7 +24,9 @@ import com.plotsquared.core.plot.Plot;
 | 
			
		||||
import com.plotsquared.core.util.StringMan;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal2;
 | 
			
		||||
import com.plotsquared.core.util.task.RunnableVal3;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.List;
 | 
			
		||||
import java.util.concurrent.CompletableFuture;
 | 
			
		||||
@@ -49,7 +51,7 @@ public class Near extends Command {
 | 
			
		||||
        final Plot plot = check(player.getCurrentPlot(), TranslatableCaption.of("errors.not_in_plot"));
 | 
			
		||||
        player.sendMessage(
 | 
			
		||||
                TranslatableCaption.of("near.plot_near"),
 | 
			
		||||
                Template.of("list", StringMan.join(getPlayersInPlotVisible(plot, player), ", "))
 | 
			
		||||
                TagResolver.resolver("list", Tag.inserting(Component.text(StringMan.join(plot.getPlayersInPlot(), ", "))))
 | 
			
		||||
        );
 | 
			
		||||
        return CompletableFuture.completedFuture(true);
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -34,7 +34,9 @@ import com.plotsquared.core.util.EventDispatcher;
 | 
			
		||||
import com.plotsquared.core.util.PlayerManager;
 | 
			
		||||
import com.plotsquared.core.util.TabCompletions;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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 org.checkerframework.checker.nullness.qual.Nullable;
 | 
			
		||||
 | 
			
		||||
@@ -65,7 +67,7 @@ public class Owner extends SetCommand {
 | 
			
		||||
        if (value == null || value.isEmpty()) {
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    TranslatableCaption.of("commandconfig.command_syntax"),
 | 
			
		||||
                    Template.of("value", "/plot setowner <owner>")
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text("/plot setowner <owner>")))
 | 
			
		||||
            );
 | 
			
		||||
            return false;
 | 
			
		||||
        }
 | 
			
		||||
@@ -77,7 +79,7 @@ public class Owner extends SetCommand {
 | 
			
		||||
                    && !value.equalsIgnoreCase("-")) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                        Template.of("value", value)
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text(value)))
 | 
			
		||||
                );
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
@@ -91,7 +93,7 @@ public class Owner extends SetCommand {
 | 
			
		||||
            if (event.getEventResult() == Result.DENY) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                        Template.of("value", "Owner change")
 | 
			
		||||
                        TagResolver.resolver("value", Tag.inserting(Component.text("Owner change")))
 | 
			
		||||
                );
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
@@ -114,7 +116,7 @@ public class Owner extends SetCommand {
 | 
			
		||||
                if (unlinkEvent.getEventResult() == Result.DENY) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("events.event_denied"),
 | 
			
		||||
                            Template.of("value", "Unlink on owner change")
 | 
			
		||||
                            TagResolver.resolver("value", Tag.inserting(Component.text("Unlink on owner change")))
 | 
			
		||||
                    );
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
@@ -134,7 +136,10 @@ public class Owner extends SetCommand {
 | 
			
		||||
            if (plot.isOwner(uuid)) {
 | 
			
		||||
                player.sendMessage(
 | 
			
		||||
                        TranslatableCaption.of("member.already_owner"),
 | 
			
		||||
                        Template.of("player", PlayerManager.resolveName(uuid, false).getComponent(player))
 | 
			
		||||
                        TagResolver.resolver(
 | 
			
		||||
                                "player",
 | 
			
		||||
                                Tag.inserting(PlayerManager.resolveName(uuid, false).toComponent(player))
 | 
			
		||||
                        )
 | 
			
		||||
                );
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
@@ -142,7 +147,10 @@ public class Owner extends SetCommand {
 | 
			
		||||
                if (other == null) {
 | 
			
		||||
                    player.sendMessage(
 | 
			
		||||
                            TranslatableCaption.of("errors.invalid_player_offline"),
 | 
			
		||||
                            Template.of("player", PlayerManager.resolveName(uuid).getComponent(player))
 | 
			
		||||
                            TagResolver.resolver(
 | 
			
		||||
                                    "player",
 | 
			
		||||
                                    Tag.inserting(PlayerManager.resolveName(uuid).toComponent(player))
 | 
			
		||||
                            )
 | 
			
		||||
                    );
 | 
			
		||||
                    return;
 | 
			
		||||
                }
 | 
			
		||||
@@ -178,7 +186,10 @@ public class Owner extends SetCommand {
 | 
			
		||||
                        if (other != null) {
 | 
			
		||||
                            other.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("owner.now_owner"),
 | 
			
		||||
                                    Template.of("plot", plot.getArea() + ";" + plot.getId())
 | 
			
		||||
                                    TagResolver.resolver(
 | 
			
		||||
                                            "plot",
 | 
			
		||||
                                            Tag.inserting(Component.text(plot.getArea() + ";" + plot.getId()))
 | 
			
		||||
                                    )
 | 
			
		||||
                            );
 | 
			
		||||
                        }
 | 
			
		||||
                    } else {
 | 
			
		||||
 
 | 
			
		||||
@@ -23,7 +23,9 @@ import com.plotsquared.core.configuration.caption.StaticCaption;
 | 
			
		||||
import com.plotsquared.core.player.PlotPlayer;
 | 
			
		||||
import com.plotsquared.core.util.PremiumVerification;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
import net.kyori.adventure.text.Component;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.Tag;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
 | 
			
		||||
 | 
			
		||||
@CommandDeclaration(command = "plugin",
 | 
			
		||||
        permission = "plots.use",
 | 
			
		||||
@@ -39,7 +41,7 @@ public class PluginCmd extends SubCommand {
 | 
			
		||||
                    StaticCaption.of("<gray>>> </gray><gold><bold>" + PlotSquared
 | 
			
		||||
                            .platform()
 | 
			
		||||
                            .pluginName() + " <reset><gray>(<gold>Version</gold><gray>: </gray><gold><version></gold><gray>)</gray>"),
 | 
			
		||||
                    Template.of("version", String.valueOf(PlotSquared.get().getVersion()))
 | 
			
		||||
                    TagResolver.resolver("version", Tag.inserting(Component.text(String.valueOf(PlotSquared.get().getVersion()))))
 | 
			
		||||
            );
 | 
			
		||||
            player.sendMessage(StaticCaption.of(
 | 
			
		||||
                    "<gray>>> </gray><gold><bold>Authors<reset><gray>: </gray><gold>Citymonstret </gold><gray>& </gray><gold>Empire92 </gold><gray>& </gray><gold>MattBDev </gold><gray>& </gray><gold>dordsor21 </gold><gray>& </gray><gold>NotMyFault </gold><gray>& </gray><gold>SirYwell</gold>"));
 | 
			
		||||
@@ -49,7 +51,7 @@ public class PluginCmd extends SubCommand {
 | 
			
		||||
                    "<gray>>> </gray><gold><bold>Discord<reset><gray>: </gray><gold><click:open_url:https://discord.gg/intellectualsites>https://discord.gg/intellectualsites</gold>"));
 | 
			
		||||
            player.sendMessage(
 | 
			
		||||
                    StaticCaption.of("<gray>>> </gray><gold><bold>Premium<reset><gray>: <gold><value></gold>"),
 | 
			
		||||
                    Template.of("value", String.valueOf(PremiumVerification.isPremium()))
 | 
			
		||||
                    TagResolver.resolver("value", Tag.inserting(Component.text(PremiumVerification.isPremium())))
 | 
			
		||||
            );
 | 
			
		||||
        });
 | 
			
		||||
        return true;
 | 
			
		||||
 
 | 
			
		||||
@@ -33,7 +33,9 @@ import com.plotsquared.core.util.StringMan;
 | 
			
		||||
import com.plotsquared.core.util.query.PlotQuery;
 | 
			
		||||
import com.plotsquared.core.util.task.TaskManager;
 | 
			
		||||
import com.plotsquared.core.uuid.UUIDMapping;
 | 
			
		||||
import net.kyori.adventure.text.minimessage.Template;
 | 
			
		||||
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.apache.logging.log4j.LogManager;
 | 
			
		||||
import org.apache.logging.log4j.Logger;
 | 
			
		||||
import org.checkerframework.checker.nullness.qual.NonNull;
 | 
			
		||||
@@ -88,72 +90,56 @@ public class Purge extends SubCommand {
 | 
			
		||||
                return false;
 | 
			
		||||
            }
 | 
			
		||||
            switch (split[0].toLowerCase()) {
 | 
			
		||||
                case "world":
 | 
			
		||||
                case "w":
 | 
			
		||||
                    world = split[1];
 | 
			
		||||
                    break;
 | 
			
		||||
                case "area":
 | 
			
		||||
                case "a":
 | 
			
		||||
                case "world", "w" -> world = split[1];
 | 
			
		||||
                case "area", "a" -> {
 | 
			
		||||
                    area = this.plotAreaManager.getPlotAreaByString(split[1]);
 | 
			
		||||
                    if (area == null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("errors.not_valid_plot_world"),
 | 
			
		||||
                                Template.of("value", split[1])
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(split[1])))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                case "plotid":
 | 
			
		||||
                case "id":
 | 
			
		||||
                }
 | 
			
		||||
                case "plotid", "id" -> {
 | 
			
		||||
                    try {
 | 
			
		||||
                        id = PlotId.fromString(split[1]);
 | 
			
		||||
                    } catch (IllegalArgumentException ignored) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("invalid.not_valid_plot_id"),
 | 
			
		||||
                                Template.of("value", split[1])
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(split[1])))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    break;
 | 
			
		||||
                case "owner":
 | 
			
		||||
                case "o":
 | 
			
		||||
                }
 | 
			
		||||
                case "owner", "o" -> {
 | 
			
		||||
                    UUIDMapping ownerMapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(split[1]);
 | 
			
		||||
                    if (ownerMapping == null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                                Template.of("value", split[1])
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(split[1])))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    owner = ownerMapping.getUuid();
 | 
			
		||||
                    break;
 | 
			
		||||
                case "shared":
 | 
			
		||||
                case "s":
 | 
			
		||||
                    owner = ownerMapping.uuid();
 | 
			
		||||
                }
 | 
			
		||||
                case "shared", "s" -> {
 | 
			
		||||
                    UUIDMapping addedMapping = PlotSquared.get().getImpromptuUUIDPipeline().getImmediately(split[1]);
 | 
			
		||||
                    if (addedMapping == null) {
 | 
			
		||||
                        player.sendMessage(
 | 
			
		||||
                                TranslatableCaption.of("errors.invalid_player"),
 | 
			
		||||
                                Template.of("value", split[1])
 | 
			
		||||
                                TagResolver.resolver("value", Tag.inserting(Component.text(split[1])))
 | 
			
		||||
                        );
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                    added = addedMapping.getUuid();
 | 
			
		||||
                    break;
 | 
			
		||||
                case "clear":
 | 
			
		||||
                case "c":
 | 
			
		||||
                case "delete":
 | 
			
		||||
                case "d":
 | 
			
		||||
                case "del":
 | 
			
		||||
                    clear = Boolean.parseBoolean(split[1]);
 | 
			
		||||
                    break;
 | 
			
		||||
                case "unknown":
 | 
			
		||||
                case "?":
 | 
			
		||||
                case "u":
 | 
			
		||||
                    unknown = Boolean.parseBoolean(split[1]);
 | 
			
		||||
                    break;
 | 
			
		||||
                default:
 | 
			
		||||
                    added = addedMapping.uuid();
 | 
			
		||||
                }
 | 
			
		||||
                case "clear", "c", "delete", "d", "del" -> clear = Boolean.parseBoolean(split[1]);
 | 
			
		||||
                case "unknown", "?", "u" -> unknown = Boolean.parseBoolean(split[1]);
 | 
			
		||||
                default -> {
 | 
			
		||||
                    sendUsage(player);
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        final HashSet<Plot> toDelete = new HashSet<>();
 | 
			
		||||
@@ -234,9 +220,9 @@ public class Purge extends SubCommand {
 | 
			
		||||
                            try {
 | 
			
		||||
                                ids.add(plot.temp);
 | 
			
		||||
                                if (finalClear) {
 | 
			
		||||
                                    plot.getPlotModificationManager().clear(false, true, player, () -> {
 | 
			
		||||
                                        LOGGER.info("Plot {} cleared by purge", plot.getId());
 | 
			
		||||
                                    });
 | 
			
		||||
                                    plot.getPlotModificationManager().clear(false, true, player,
 | 
			
		||||
                                            () -> LOGGER.info("Plot {} cleared by purge", plot.getId())
 | 
			
		||||
                                    );
 | 
			
		||||
                                } else {
 | 
			
		||||
                                    plot.getPlotModificationManager().removeSign();
 | 
			
		||||
                                }
 | 
			
		||||
@@ -258,7 +244,10 @@ public class Purge extends SubCommand {
 | 
			
		||||
                            DBFunc.purgeIds(ids);
 | 
			
		||||
                            player.sendMessage(
 | 
			
		||||
                                    TranslatableCaption.of("purge.purge_success"),
 | 
			
		||||
                                    Template.of("amount", ids.size() + "/" + toDelete.size())
 | 
			
		||||
                                    TagResolver.resolver(
 | 
			
		||||
                                            "amount",
 | 
			
		||||
                                            Tag.inserting(Component.text(ids.size() + "/" + toDelete.size()))
 | 
			
		||||
                                    )
 | 
			
		||||
                            );
 | 
			
		||||
                        });
 | 
			
		||||
                    }
 | 
			
		||||
 
 | 
			
		||||
Some files were not shown because too many files have changed in this diff Show More
		Reference in New Issue
	
	Block a user