mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-10-26 07:03:45 +01:00 
			
		
		
		
	Compare commits
	
		
			89 Commits
		
	
	
		
			renovate/c
			...
			feature/v6
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 70baca7145 | ||
|   | 2a90015037 | ||
|   | f17aa377b7 | ||
|   | e159fa054d | ||
|   | 058c65e34c | ||
|   | 8608604306 | ||
|   | 8d0cc68721 | ||
|   | 2a79c0a419 | ||
|   | 90d42b8b9f | ||
|   | a79c474957 | ||
|   | 4bb480a238 | ||
|   | 9ffa935c0c | ||
|   | 0a32268784 | ||
|   | ae3b8c06f6 | ||
|   | 713c4ad0d2 | ||
|   | 48386c0828 | ||
|   | 625b3921e1 | ||
|   | 48aa37d173 | ||
|   | 2c2314e95c | ||
|   | 5eb2fc3ad0 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 82cd9a092c | ||
|   | 62754362c2 | ||
|   | 2e9dfd6f6f | ||
|   | fc9fe1462f | ||
|   | 41f546ca6b | ||
|   | d037da33cb | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | dc2d08c67e | ||
|   | 96dfc27411 | ||
|   | 171d2e5e99 | ||
|   | 4433892431 | ||
|   | 98a07dad1b | ||
|   | 0ffa22b7a6 | ||
|   | 60a0129fe9 | ||
|   | d5f8a0842b | ||
|   | f7d55ce105 | ||
|   | 85911646f3 | ||
|   | 8b75dece69 | ||
|   | 7d6e515ba8 | ||
|   | 13d7357c85 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 16e26b910c | ||
|   | faadebd30e | ||
|   | 2aeacb3dcf | ||
|   | 9db7791835 | ||
|   | f49ddb819d | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | d71c62771e | ||
|   | a6aaa9538f | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 0974fb2834 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 8982b33b6c | ||
|   | a7b3b3b7df | ||
|   | 888bb20e78 | ||
|   | b11bb6fa22 | ||
|   | e5764b958d | ||
|   | bfe3141ff1 | ||
|   | 73c82deeb0 | ||
|   | 38682ecff6 | ||
|   | 6a54dc7eff | ||
|   | 8454c29c91 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | b2c9311a47 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | c4aa497a2b | ||
|   | c13f544390 | ||
|   | c28177d6af | ||
|   | 8a80f252cf | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 93571c72d1 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 6fd7379221 | ||
|   | dc5c80d812 | ||
|   | 96e9a61e7c | ||
|   | b9bd9b81e6 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | ec77812879 | ||
|   | efc2083798 | ||
|   | 3a6f845c01 | ||
|   | 7efd42ae45 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | f43f4cbf5d | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 104cc4b7a4 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 218be43143 | ||
|   | 308dba5601 | ||
|   | 5f233bb5d1 | ||
|   | 5e188d114f | ||
|   | 660e05d27f | ||
|   | 4c0ad148bf | ||
|   | 5c7bfb988c | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | b46f486680 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 05797d0c78 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 36ef2cf9ba | ||
|   | 26ec31a012 | ||
|   | fd4a542062 | ||
|   | dc13f2565f | ||
|   | 9f632af0ae | ||
|   | d698c6a1e5 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 40e1bd9897 | 
							
								
								
									
										1
									
								
								.github/ISSUE_TEMPLATE/bug_report.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/ISSUE_TEMPLATE/bug_report.yml
									
									
									
									
										vendored
									
									
								
							| @@ -27,6 +27,7 @@ body: | |||||||
|       description: Which server version version you using? If your server version is not listed, it is not supported. Update to a supported version first. |       description: Which server version version you using? If your server version is not listed, it is not supported. Update to a supported version first. | ||||||
|       multiple: false |       multiple: false | ||||||
|       options: |       options: | ||||||
|  |         - '1.18.2' | ||||||
|         - '1.18.1' |         - '1.18.1' | ||||||
|         - '1.18' |         - '1.18' | ||||||
|         - '1.17.1' |         - '1.17.1' | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										6
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							| @@ -8,11 +8,11 @@ jobs: | |||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout Repository |       - name: Checkout Repository | ||||||
|         uses: actions/checkout@v2.4.0 |         uses: actions/checkout@v3 | ||||||
|       - name: Validate Gradle Wrapper" |       - name: Validate Gradle Wrapper" | ||||||
|         uses: gradle/wrapper-validation-action@v1.0.4 |         uses: gradle/wrapper-validation-action@v1 | ||||||
|       - name: Setup Java |       - name: Setup Java | ||||||
|         uses: actions/setup-java@v3.0.0 |         uses: actions/setup-java@v3 | ||||||
|         with: |         with: | ||||||
|           distribution: temurin |           distribution: temurin | ||||||
|           java-version: 17 |           java-version: 17 | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							| @@ -23,15 +23,15 @@ jobs: | |||||||
|  |  | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout repository |       - name: Checkout repository | ||||||
|         uses: actions/checkout@v2 |         uses: actions/checkout@v3 | ||||||
|  |  | ||||||
|       - name: Initialize CodeQL |       - name: Initialize CodeQL | ||||||
|         uses: github/codeql-action/init@v1 |         uses: github/codeql-action/init@v2 | ||||||
|         with: |         with: | ||||||
|           languages: ${{ matrix.language }} |           languages: ${{ matrix.language }} | ||||||
|  |  | ||||||
|       - name: Autobuild |       - name: Autobuild | ||||||
|         uses: github/codeql-action/autobuild@v1 |         uses: github/codeql-action/autobuild@v2 | ||||||
|  |  | ||||||
|       - name: Perform CodeQL Analysis |       - name: Perform CodeQL Analysis | ||||||
|         uses: github/codeql-action/analyze@v1 |         uses: github/codeql-action/analyze@v2 | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/workflows/release-drafter.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/release-drafter.yml
									
									
									
									
										vendored
									
									
								
							| @@ -14,6 +14,6 @@ jobs: | |||||||
|     if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }} |     if: ${{ github.event_name != 'pull_request' || github.repository != github.event.pull_request.head.repo.full_name }} | ||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - uses: release-drafter/release-drafter@v5.18.1 |       - uses: release-drafter/release-drafter@v5 | ||||||
|         env: |         env: | ||||||
|           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} |           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | ||||||
|   | |||||||
							
								
								
									
										10
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										10
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -41,7 +41,8 @@ hs_err_pid* | |||||||
| *.iml | *.iml | ||||||
|  |  | ||||||
| ## Directory-based project format: | ## Directory-based project format: | ||||||
| .idea/ | /.idea/* | ||||||
|  | !/.idea/icon.svg | ||||||
| # if you remove the above rule, at least ignore the following: | # if you remove the above rule, at least ignore the following: | ||||||
|  |  | ||||||
| # User-specific stuff: | # User-specific stuff: | ||||||
| @@ -74,9 +75,6 @@ hs_err_pid* | |||||||
| # IntelliJ | # IntelliJ | ||||||
| /out/ | /out/ | ||||||
|  |  | ||||||
| # mpeltonen/sbt-idea plugin |  | ||||||
| .idea_modules/ |  | ||||||
|  |  | ||||||
| # JIRA plugin | # JIRA plugin | ||||||
| atlassian-ide-plugin.xml | atlassian-ide-plugin.xml | ||||||
|  |  | ||||||
| @@ -133,5 +131,9 @@ local.properties | |||||||
| checkstyle.xml | checkstyle.xml | ||||||
| classes/ | classes/ | ||||||
| *.bat | *.bat | ||||||
|  |  | ||||||
|  | # Other | ||||||
| docs/ | docs/ | ||||||
| build/ | build/ | ||||||
|  |  | ||||||
|  | .DS_Store | ||||||
|   | |||||||
							
								
								
									
										50
									
								
								.idea/icon.svg
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										50
									
								
								.idea/icon.svg
									
									
									
										generated
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,50 @@ | |||||||
|  | <?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"> | ||||||
|  | 			<rdf:RDF> | ||||||
|  | 				<cc:Work rdf:about=""> | ||||||
|  | 					<dc:format>image/svg+xml</dc:format> | ||||||
|  |                     <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" /> | ||||||
|  | 			</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" /> | ||||||
|  | 					</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> | ||||||
|  |                     <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> | ||||||
|  |                     <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> | ||||||
|  |                     <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> | ||||||
|  |                     <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> | ||||||
|  | 		</g> | ||||||
|  | </svg> | ||||||
| After Width: | Height: | Size: 11 KiB | 
| @@ -1,4 +0,0 @@ | |||||||
| jdkVersion = "17" |  | ||||||
| build = "gradle clean build -x test" |  | ||||||
| tools = ["findsecbugs", "ErrorProne", "Semgrep", "Detekt", "Infer"] |  | ||||||
| ignoreRules = ["CatchAndPrintStackTrace", "ReferenceEquality", "FallThrough", "FutureReturnValueIgnored", "MixedMutabilityReturnType", "EmptyCatch", "MissingCasesInEnumSwitch", "OperatorPrecedence", "StaticAssignmentInConstructor", "ReferenceEquality", "EqualsHashCode", "EqualsGetClass", "TypeParameterUnusedInFormals", "StringSplitter", "InlineMeSuggester", "NULL_DEREFERENCE"] |  | ||||||
| @@ -8,7 +8,7 @@ repositories { | |||||||
|  |  | ||||||
|     maven { |     maven { | ||||||
|         name = "PaperMC" |         name = "PaperMC" | ||||||
|         url = uri("https://papermc.io/repo/repository/maven-public/") |         url = uri("https://repo.papermc.io/repository/maven-public/") | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     maven { |     maven { | ||||||
| @@ -21,20 +21,20 @@ dependencies { | |||||||
|     api(projects.plotSquaredCore) |     api(projects.plotSquaredCore) | ||||||
|  |  | ||||||
|     // Metrics |     // Metrics | ||||||
|     implementation(libs.bstats) |     implementation("org.bstats:bstats-bukkit") | ||||||
|  |  | ||||||
|     // Paper |     // Paper | ||||||
|     compileOnly(libs.paper) |     compileOnly(libs.paper) | ||||||
|     implementation(libs.paperlib) |     implementation("io.papermc:paperlib") | ||||||
|  |  | ||||||
|     // Plugins |     // Plugins | ||||||
|     compileOnly(libs.worldeditBukkit) { |     compileOnly(libs.worldeditBukkit) { | ||||||
|         exclude(group = "org.bukkit") |         exclude(group = "org.bukkit") | ||||||
|         exclude(group = "org.spigotmc") |         exclude(group = "org.spigotmc") | ||||||
|     } |     } | ||||||
|     compileOnly(libs.fastasyncworldeditBukkit) { isTransitive = false } |     compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit") { isTransitive = false } | ||||||
|     testImplementation(libs.fastasyncworldeditBukkit) { isTransitive = false } |     testImplementation("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit") { isTransitive = false } | ||||||
|     compileOnly(libs.vault) { |     compileOnly("com.github.MilkBowl:VaultAPI") { | ||||||
|         exclude(group = "org.bukkit") |         exclude(group = "org.bukkit") | ||||||
|     } |     } | ||||||
|     compileOnly(libs.placeholderapi) |     compileOnly(libs.placeholderapi) | ||||||
| @@ -44,15 +44,15 @@ dependencies { | |||||||
|  |  | ||||||
|     // Other libraries |     // Other libraries | ||||||
|     implementation(libs.squirrelid) { isTransitive = false } |     implementation(libs.squirrelid) { isTransitive = false } | ||||||
|     implementation(libs.serverlib) |     implementation("dev.notmyfault.serverlib:ServerLib") | ||||||
|  |  | ||||||
|     // Our libraries |     // Our libraries | ||||||
|     implementation(libs.arkitektonika) |     implementation(libs.arkitektonika) | ||||||
|     implementation(libs.http4j) |     implementation(libs.http4j) | ||||||
|     implementation(libs.paster) |     implementation("com.intellectualsites.paster:Paster") | ||||||
|  |  | ||||||
|     // Adventure |     // Adventure | ||||||
|     implementation(libs.adventurePlatformBukkit) |     implementation("net.kyori:adventure-platform-bukkit") | ||||||
| } | } | ||||||
|  |  | ||||||
| tasks.processResources { | tasks.processResources { | ||||||
| @@ -83,8 +83,10 @@ tasks.named<ShadowJar>("shadowJar") { | |||||||
|     relocate("org.jetbrains", "com.plotsquared.core.annotations") |     relocate("org.jetbrains", "com.plotsquared.core.annotations") | ||||||
|     relocate("org.intellij.lang", "com.plotsquared.core.intellij.annotations") |     relocate("org.intellij.lang", "com.plotsquared.core.intellij.annotations") | ||||||
|     relocate("javax.annotation", "com.plotsquared.core.annotation") |     relocate("javax.annotation", "com.plotsquared.core.annotation") | ||||||
|     relocate("com.google.code.findbugs", "com.plotsquared.core.findbugs") |     relocate("com.github.spotbugs", "com.plotsquared.core.spotbugs") | ||||||
|     relocate("javax.inject", "com.plotsquared.core.annotation.inject") |     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") | ||||||
|  |  | ||||||
|     // Get rid of all the libs which are 100% unused. |     // Get rid of all the libs which are 100% unused. | ||||||
|     minimize() |     minimize() | ||||||
| @@ -95,7 +97,7 @@ tasks.named<ShadowJar>("shadowJar") { | |||||||
| tasks { | tasks { | ||||||
|     withType<Javadoc> { |     withType<Javadoc> { | ||||||
|         val opt = options as StandardJavadocDocletOptions |         val opt = options as StandardJavadocDocletOptions | ||||||
|         opt.links("https://papermc.io/javadocs/paper/1.18/") |         opt.links("https://jd.papermc.io/paper/1.18/") | ||||||
|         opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-bukkit/" + libs.worldeditBukkit.get().versionConstraint.toString()) |         opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-bukkit/" + libs.worldeditBukkit.get().versionConstraint.toString()) | ||||||
|         opt.links("https://javadoc.io/doc/com.plotsquared/PlotSquared-Core/latest/") |         opt.links("https://javadoc.io/doc/com.plotsquared/PlotSquared-Core/latest/") | ||||||
|         opt.links("https://jd.adventure.kyori.net/api/" + libs.adventure.get().versionConstraint.toString()) |         opt.links("https://jd.adventure.kyori.net/api/" + libs.adventure.get().versionConstraint.toString()) | ||||||
|   | |||||||
| @@ -238,6 +238,16 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl | |||||||
|         return this.version; |         return this.version; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int versionMinHeight() { | ||||||
|  |         return serverVersion()[1] >= 18 ? -64 : 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int versionMaxHeight() { | ||||||
|  |         return serverVersion()[1] >= 18 ? 319 : 255; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public @NonNull String serverImplementation() { |     public @NonNull String serverImplementation() { | ||||||
|         return Bukkit.getVersion(); |         return Bukkit.getVersion(); | ||||||
| @@ -503,8 +513,10 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl | |||||||
|                 this.backgroundPipeline.registerService(essentialsUUIDService); |                 this.backgroundPipeline.registerService(essentialsUUIDService); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|  |             if (Settings.UUID.IMPROMPTU_SERVICE_MOJANG_API) { | ||||||
|                 final SquirrelIdUUIDService impromptuMojangService = new SquirrelIdUUIDService(Settings.UUID.IMPROMPTU_LIMIT); |                 final SquirrelIdUUIDService impromptuMojangService = new SquirrelIdUUIDService(Settings.UUID.IMPROMPTU_LIMIT); | ||||||
|                 this.impromptuPipeline.registerService(impromptuMojangService); |                 this.impromptuPipeline.registerService(impromptuMojangService); | ||||||
|  |             } | ||||||
|             final SquirrelIdUUIDService backgroundMojangService = new SquirrelIdUUIDService(Settings.UUID.BACKGROUND_LIMIT); |             final SquirrelIdUUIDService backgroundMojangService = new SquirrelIdUUIDService(Settings.UUID.BACKGROUND_LIMIT); | ||||||
|             this.backgroundPipeline.registerService(backgroundMojangService); |             this.backgroundPipeline.registerService(backgroundMojangService); | ||||||
|         } else { |         } else { | ||||||
|   | |||||||
| @@ -25,17 +25,18 @@ | |||||||
|  */ |  */ | ||||||
| package com.plotsquared.bukkit.generator; | package com.plotsquared.bukkit.generator; | ||||||
|  |  | ||||||
| import com.plotsquared.core.PlotSquared; | import com.plotsquared.bukkit.queue.LimitedRegionWrapperQueue; | ||||||
|  | import com.plotsquared.core.generator.HybridPlotWorld; | ||||||
| import com.plotsquared.core.generator.IndependentPlotGenerator; | import com.plotsquared.core.generator.IndependentPlotGenerator; | ||||||
| import com.plotsquared.core.location.ChunkWrapper; | import com.plotsquared.core.location.Location; | ||||||
|  | import com.plotsquared.core.location.UncheckedWorldLocation; | ||||||
| import com.plotsquared.core.plot.PlotArea; | import com.plotsquared.core.plot.PlotArea; | ||||||
| import com.plotsquared.core.plot.world.PlotAreaManager; | import com.plotsquared.core.plot.world.PlotAreaManager; | ||||||
| import com.plotsquared.core.queue.QueueCoordinator; | import com.plotsquared.core.plot.world.SinglePlotArea; | ||||||
| import com.plotsquared.core.queue.ScopedQueueCoordinator; | import com.plotsquared.core.queue.ScopedQueueCoordinator; | ||||||
| import com.sk89q.worldedit.bukkit.BukkitWorld; |  | ||||||
| import org.bukkit.Chunk; |  | ||||||
| import org.bukkit.World; |  | ||||||
| import org.bukkit.generator.BlockPopulator; | import org.bukkit.generator.BlockPopulator; | ||||||
|  | import org.bukkit.generator.LimitedRegion; | ||||||
|  | import org.bukkit.generator.WorldInfo; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
| import java.util.Random; | import java.util.Random; | ||||||
| @@ -43,32 +44,51 @@ import java.util.Random; | |||||||
| final class BlockStatePopulator extends BlockPopulator { | final class BlockStatePopulator extends BlockPopulator { | ||||||
|  |  | ||||||
|     private final IndependentPlotGenerator plotGenerator; |     private final IndependentPlotGenerator plotGenerator; | ||||||
|     private final PlotAreaManager plotAreaManager; |  | ||||||
|  |  | ||||||
|     private QueueCoordinator queue; |     /** | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     public BlockStatePopulator( | ||||||
|  |             final @NonNull IndependentPlotGenerator plotGenerator | ||||||
|  |     ) { | ||||||
|  |         this.plotGenerator = plotGenerator; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @deprecated Use {@link BlockStatePopulator#BlockStatePopulator(IndependentPlotGenerator)} as plotAreManager is unused | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public BlockStatePopulator( |     public BlockStatePopulator( | ||||||
|             final @NonNull IndependentPlotGenerator plotGenerator, |             final @NonNull IndependentPlotGenerator plotGenerator, | ||||||
|             final @NonNull PlotAreaManager plotAreaManager |             final @NonNull PlotAreaManager plotAreaManager | ||||||
|     ) { |     ) { | ||||||
|         this.plotGenerator = plotGenerator; |         this.plotGenerator = plotGenerator; | ||||||
|         this.plotAreaManager = plotAreaManager; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void populate(final @NonNull World world, final @NonNull Random random, final @NonNull Chunk source) { |     public void populate( | ||||||
|         if (this.queue == null) { |             @NonNull final WorldInfo worldInfo, | ||||||
|             this.queue = PlotSquared.platform().globalBlockQueue().getNewQueue(new BukkitWorld(world)); |             @NonNull final Random random, | ||||||
|         } |             final int chunkX, | ||||||
|         final PlotArea area = this.plotAreaManager.getPlotArea(world.getName(), null); |             final int chunkZ, | ||||||
|         if (area == null) { |             @NonNull final LimitedRegion limitedRegion | ||||||
|  |     ) { | ||||||
|  |         PlotArea area = UncheckedWorldLocation.at(worldInfo.getName(), chunkX << 4, 0, chunkZ << 4).getPlotArea(); | ||||||
|  |         if (area == null || (area instanceof HybridPlotWorld hpw && !hpw.populationNeeded()) || area instanceof SinglePlotArea) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         final ChunkWrapper wrap = new ChunkWrapper(area.getWorldName(), source.getX(), source.getZ()); |         LimitedRegionWrapperQueue wrapped = new LimitedRegionWrapperQueue(limitedRegion); | ||||||
|         final ScopedQueueCoordinator chunk = this.queue.getForChunk(wrap.x, wrap.z); |         // It is possible for the region to be larger than the chunk, but there is no reason for P2 to need to populate | ||||||
|         if (this.plotGenerator.populateChunk(chunk, area)) { |         // outside of the actual chunk area. | ||||||
|             this.queue.enqueue(); |         Location min = UncheckedWorldLocation.at(worldInfo.getName(), chunkX << 4, worldInfo.getMinHeight(), chunkZ << 4); | ||||||
|         } |         Location max = UncheckedWorldLocation.at( | ||||||
|  |                 worldInfo.getName(), | ||||||
|  |                 (chunkX << 4) + 15, | ||||||
|  |                 worldInfo.getMaxHeight(), | ||||||
|  |                 (chunkZ << 4) + 15 | ||||||
|  |         ); | ||||||
|  |         ScopedQueueCoordinator offsetChunkQueue = new ScopedQueueCoordinator(wrapped, min, max); | ||||||
|  |         this.plotGenerator.populateChunk(offsetChunkQueue, area); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -25,7 +25,11 @@ | |||||||
|  */ |  */ | ||||||
| package com.plotsquared.bukkit.generator; | package com.plotsquared.bukkit.generator; | ||||||
|  |  | ||||||
|  | import com.plotsquared.core.PlotSquared; | ||||||
| import com.plotsquared.core.generator.AugmentedUtils; | import com.plotsquared.core.generator.AugmentedUtils; | ||||||
|  | import com.plotsquared.core.queue.QueueCoordinator; | ||||||
|  | import com.sk89q.worldedit.bukkit.BukkitAdapter; | ||||||
|  | import com.sk89q.worldedit.util.SideEffectSet; | ||||||
| import org.bukkit.Chunk; | import org.bukkit.Chunk; | ||||||
| import org.bukkit.World; | import org.bukkit.World; | ||||||
| import org.bukkit.generator.BlockPopulator; | import org.bukkit.generator.BlockPopulator; | ||||||
| @@ -52,7 +56,14 @@ public class BukkitAugmentedGenerator extends BlockPopulator { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void populate(@NonNull World world, @NonNull Random random, @NonNull Chunk source) { |     public void populate(@NonNull World world, @NonNull Random random, @NonNull Chunk source) { | ||||||
|         AugmentedUtils.generate(source, world.getName(), source.getX(), source.getZ(), null); |         QueueCoordinator queue = PlotSquared.platform().globalBlockQueue().getNewQueue(BukkitAdapter.adapt(world)); | ||||||
|  |         // The chunk is already loaded and we do not want to load the chunk in "fully" by using any PaperLib methods. | ||||||
|  |         queue.setForceSync(true); | ||||||
|  |         queue.setSideEffectSet(SideEffectSet.none()); | ||||||
|  |         queue.setBiomesEnabled(false); | ||||||
|  |         queue.setChunkObject(source); | ||||||
|  |         AugmentedUtils.generateChunk(world.getName(), source.getX(), source.getZ(), queue); | ||||||
|  |         queue.enqueue(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -27,6 +27,7 @@ package com.plotsquared.bukkit.generator; | |||||||
|  |  | ||||||
| import com.plotsquared.bukkit.queue.GenChunk; | import com.plotsquared.bukkit.queue.GenChunk; | ||||||
| import com.plotsquared.bukkit.util.BukkitUtil; | import com.plotsquared.bukkit.util.BukkitUtil; | ||||||
|  | import com.plotsquared.bukkit.util.BukkitWorld; | ||||||
| import com.plotsquared.core.PlotSquared; | import com.plotsquared.core.PlotSquared; | ||||||
| import com.plotsquared.core.generator.GeneratorWrapper; | import com.plotsquared.core.generator.GeneratorWrapper; | ||||||
| import com.plotsquared.core.generator.IndependentPlotGenerator; | import com.plotsquared.core.generator.IndependentPlotGenerator; | ||||||
| @@ -48,8 +49,7 @@ import java.util.List; | |||||||
| import java.util.Random; | import java.util.Random; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
|  |  | ||||||
| public class BukkitPlotGenerator extends ChunkGenerator | public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrapper<ChunkGenerator> { | ||||||
|         implements GeneratorWrapper<ChunkGenerator> { |  | ||||||
|  |  | ||||||
|     @SuppressWarnings("unused") |     @SuppressWarnings("unused") | ||||||
|     public final boolean PAPER_ASYNC_SAFE = true; |     public final boolean PAPER_ASYNC_SAFE = true; | ||||||
| @@ -72,7 +72,12 @@ public class BukkitPlotGenerator extends ChunkGenerator | |||||||
|         this.plotGenerator = generator; |         this.plotGenerator = generator; | ||||||
|         this.platformGenerator = this; |         this.platformGenerator = this; | ||||||
|         this.populators = new ArrayList<>(); |         this.populators = new ArrayList<>(); | ||||||
|         this.populators.add(new BlockStatePopulator(this.plotGenerator, this.plotAreaManager)); |         int minecraftMinorVersion = PlotSquared.platform().serverVersion()[1]; | ||||||
|  |         if (minecraftMinorVersion >= 17) { | ||||||
|  |             this.populators.add(new BlockStatePopulator(this.plotGenerator)); | ||||||
|  |         } else { | ||||||
|  |             this.populators.add(new LegacyBlockStatePopulator(this.plotGenerator)); | ||||||
|  |         } | ||||||
|         this.full = true; |         this.full = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -158,13 +163,14 @@ public class BukkitPlotGenerator extends ChunkGenerator | |||||||
|             @NonNull World world, @NonNull Random random, int x, int z, |             @NonNull World world, @NonNull Random random, int x, int z, | ||||||
|             @NonNull BiomeGrid biome |             @NonNull BiomeGrid biome | ||||||
|     ) { |     ) { | ||||||
|  |         int minY = BukkitWorld.getMinWorldHeight(world); | ||||||
|         GenChunk result = new GenChunk(); |         int maxY = BukkitWorld.getMaxWorldHeight(world); | ||||||
|  |         GenChunk result = new GenChunk(minY, maxY); | ||||||
|         if (this.getPlotGenerator() instanceof SingleWorldGenerator) { |         if (this.getPlotGenerator() instanceof SingleWorldGenerator) { | ||||||
|             if (result.getChunkData() != null) { |             if (result.getChunkData() != null) { | ||||||
|                 for (int chunkX = 0; chunkX < 16; chunkX++) { |                 for (int chunkX = 0; chunkX < 16; chunkX++) { | ||||||
|                     for (int chunkZ = 0; chunkZ < 16; chunkZ++) { |                     for (int chunkZ = 0; chunkZ < 16; chunkZ++) { | ||||||
|                         for (int y = 0; y < world.getMaxHeight(); y++) { |                         for (int y = minY; y < maxY; y++) { | ||||||
|                             biome.setBiome(chunkX, y, chunkZ, Biome.PLAINS); |                             biome.setBiome(chunkX, y, chunkZ, Biome.PLAINS); | ||||||
|  |  | ||||||
|                         } |                         } | ||||||
|   | |||||||
| @@ -80,7 +80,8 @@ final class DelegatePlotGenerator extends IndependentPlotGenerator { | |||||||
|                     result.setBiome(x, z, BukkitAdapter.adapt(biome)); |                     result.setBiome(x, z, BukkitAdapter.adapt(biome)); | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 //do not annotate with Override until we discontinue support for 1.4.4 |                 //do not annotate with Override until we discontinue support for 1.4.4 (we no longer support 1.4.4) | ||||||
|  |                 @Override | ||||||
|                 public void setBiome(int x, int y, int z, @NonNull Biome biome) { |                 public void setBiome(int x, int y, int z, @NonNull Biome biome) { | ||||||
|                     result.setBiome(x, z, BukkitAdapter.adapt(biome)); |                     result.setBiome(x, z, BukkitAdapter.adapt(biome)); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -0,0 +1,81 @@ | |||||||
|  | /* | ||||||
|  |  *       _____  _       _    _____                                _ | ||||||
|  |  *      |  __ \| |     | |  / ____|                              | | | ||||||
|  |  *      | |__) | | ___ | |_| (___   __ _ _   _  __ _ _ __ ___  __| | | ||||||
|  |  *      |  ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | | ||||||
|  |  *      | |    | | (_) | |_ ____) | (_| | |_| | (_| | | |  __/ (_| | | ||||||
|  |  *      |_|    |_|\___/ \__|_____/ \__, |\__,_|\__,_|_|  \___|\__,_| | ||||||
|  |  *                                    | | | ||||||
|  |  *                                    |_| | ||||||
|  |  *            PlotSquared plot management system for Minecraft | ||||||
|  |  *               Copyright (C) 2014 - 2022 IntellectualSites | ||||||
|  |  * | ||||||
|  |  *     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.generator; | ||||||
|  |  | ||||||
|  | import com.plotsquared.core.PlotSquared; | ||||||
|  | import com.plotsquared.core.generator.HybridPlotWorld; | ||||||
|  | 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.SinglePlotArea; | ||||||
|  | import com.plotsquared.core.queue.QueueCoordinator; | ||||||
|  | import com.plotsquared.core.queue.ScopedQueueCoordinator; | ||||||
|  | import com.sk89q.worldedit.bukkit.BukkitWorld; | ||||||
|  | import com.sk89q.worldedit.util.SideEffectSet; | ||||||
|  | import org.bukkit.Chunk; | ||||||
|  | import org.bukkit.World; | ||||||
|  | import org.bukkit.generator.BlockPopulator; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  | import org.jetbrains.annotations.NotNull; | ||||||
|  |  | ||||||
|  | import java.util.Random; | ||||||
|  |  | ||||||
|  | final class LegacyBlockStatePopulator extends BlockPopulator { | ||||||
|  |  | ||||||
|  |     private final IndependentPlotGenerator plotGenerator; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     public LegacyBlockStatePopulator( | ||||||
|  |             final @NonNull IndependentPlotGenerator plotGenerator | ||||||
|  |     ) { | ||||||
|  |         this.plotGenerator = plotGenerator; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void populate(@NotNull final World world, @NotNull final Random random, @NotNull final Chunk source) { | ||||||
|  |         int chunkMinX = source.getX() << 4; | ||||||
|  |         int chunkMinZ = source.getZ() << 4; | ||||||
|  |         PlotArea area = Location.at(world.getName(), chunkMinX, 0, chunkMinZ).getPlotArea(); | ||||||
|  |         if (area == null || (area instanceof HybridPlotWorld hpw && !hpw.populationNeeded()) || area instanceof SinglePlotArea) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         QueueCoordinator queue = PlotSquared.platform().globalBlockQueue().getNewQueue(new BukkitWorld(world)); | ||||||
|  |         queue.setForceSync(true); | ||||||
|  |         queue.setSideEffectSet(SideEffectSet.none()); | ||||||
|  |         queue.setBiomesEnabled(false); | ||||||
|  |         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); | ||||||
|  |         this.plotGenerator.populateChunk(offsetChunkQueue, area); | ||||||
|  |         queue.enqueue(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -354,7 +354,8 @@ public class BlockEventListener implements Listener { | |||||||
|         Plot plot = area.getPlot(location); |         Plot plot = area.getPlot(location); | ||||||
|         if (plot != null) { |         if (plot != null) { | ||||||
|             BukkitPlayer plotPlayer = BukkitUtil.adapt(player); |             BukkitPlayer plotPlayer = BukkitUtil.adapt(player); | ||||||
|             if (event.getBlock().getY() == 0) { |             // == rather than <= as we only care about the "ground level" not being destroyed | ||||||
|  |             if (event.getBlock().getY() == area.getMinGenHeight()) { | ||||||
|                 if (!Permissions |                 if (!Permissions | ||||||
|                         .hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_DESTROY_GROUNDLEVEL)) { |                         .hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_DESTROY_GROUNDLEVEL)) { | ||||||
|                     plotPlayer.sendMessage( |                     plotPlayer.sendMessage( | ||||||
| @@ -550,6 +551,10 @@ public class BlockEventListener implements Listener { | |||||||
|         if (plot == null) { |         if (plot == null) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |         if (location.getY() >= area.getMaxBuildHeight() || location.getY() < area.getMinBuildHeight()) { | ||||||
|  |             event.setCancelled(true); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|         switch (event.getNewState().getType()) { |         switch (event.getNewState().getType()) { | ||||||
|             case SNOW: |             case SNOW: | ||||||
|             case SNOW_BLOCK: |             case SNOW_BLOCK: | ||||||
| @@ -649,7 +654,8 @@ public class BlockEventListener implements Listener { | |||||||
|                     event.getBlock().breakNaturally(); |                     event.getBlock().breakNaturally(); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             if (location.getY() == 0) { |             // == rather than <= as we only care about the "ground level" not being destroyed | ||||||
|  |             if (location.getY() == area.getMinGenHeight()) { | ||||||
|                 event.setCancelled(true); |                 event.setCancelled(true); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
| @@ -748,62 +754,66 @@ public class BlockEventListener implements Listener { | |||||||
|  |  | ||||||
|     @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) |     @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) | ||||||
|     public void onChange(BlockFromToEvent event) { |     public void onChange(BlockFromToEvent event) { | ||||||
|         Block from = event.getBlock(); |         Block fromBlock = event.getBlock(); | ||||||
|  |  | ||||||
|         // Check liquid flow flag inside of origin plot too |         // Check liquid flow flag inside of origin plot too | ||||||
|         final Location fLocation = BukkitUtil.adapt(from.getLocation()); |         final Location fromLocation = BukkitUtil.adapt(fromBlock.getLocation()); | ||||||
|         final PlotArea fromArea = fLocation.getPlotArea(); |         final PlotArea fromArea = fromLocation.getPlotArea(); | ||||||
|         if (fromArea != null) { |         if (fromArea != null) { | ||||||
|             final Plot plot = fromArea.getOwnedPlot(fLocation); |             final Plot fromPlot = fromArea.getOwnedPlot(fromLocation); | ||||||
|             if (plot != null && plot.getFlag(LiquidFlowFlag.class) == LiquidFlowFlag.FlowStatus.DISABLED && event |             if (fromPlot != null && fromPlot.getFlag(LiquidFlowFlag.class) == LiquidFlowFlag.FlowStatus.DISABLED && event | ||||||
|                     .getBlock() |                     .getBlock() | ||||||
|                     .isLiquid()) { |                     .isLiquid()) { | ||||||
|                 plot.debug("Liquid could not flow because liquid-flow = disabled"); |                 fromPlot.debug("Liquid could not flow because liquid-flow = disabled"); | ||||||
|                 event.setCancelled(true); |                 event.setCancelled(true); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         Block to = event.getToBlock(); |         Block toBlock = event.getToBlock(); | ||||||
|         Location tLocation = BukkitUtil.adapt(to.getLocation()); |         Location toLocation = BukkitUtil.adapt(toBlock.getLocation()); | ||||||
|         PlotArea area = tLocation.getPlotArea(); |         PlotArea toArea = toLocation.getPlotArea(); | ||||||
|         if (area == null) { |         if (toArea == null) { | ||||||
|             if (from.getType() == Material.DRAGON_EGG && fromArea != null) { |             if (fromBlock.getType() == Material.DRAGON_EGG && fromArea != null) { | ||||||
|                 event.setCancelled(true); |                 event.setCancelled(true); | ||||||
|             } |             } | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         Plot plot = area.getOwnedPlot(tLocation); |         if (toLocation.getY() >= toArea.getMaxBuildHeight() || toLocation.getY() < toArea.getMinBuildHeight()) { | ||||||
|  |             event.setCancelled(true); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         Plot toPlot = toArea.getOwnedPlot(toLocation); | ||||||
|  |  | ||||||
|         if (from.getType() == Material.DRAGON_EGG && fromArea != null) { |         if (fromBlock.getType() == Material.DRAGON_EGG && fromArea != null) { | ||||||
|             final Plot fromPlot = fromArea.getOwnedPlot(fLocation); |             final Plot fromPlot = fromArea.getOwnedPlot(fromLocation); | ||||||
|  |  | ||||||
|             if (fromPlot != null || plot != null) { |             if (fromPlot != null || toPlot != null) { | ||||||
|                 if ((fromPlot == null || !fromPlot.equals(plot)) && (plot == null || !plot.equals(fromPlot))) { |                 if ((fromPlot == null || !fromPlot.equals(toPlot)) && (toPlot == null || !toPlot.equals(fromPlot))) { | ||||||
|                     event.setCancelled(true); |                     event.setCancelled(true); | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (plot != null) { |         if (toPlot != null) { | ||||||
|             if (!area.contains(fLocation.getX(), fLocation.getZ()) || !Objects.equals(plot, area.getOwnedPlot(fLocation))) { |             if (!toArea.contains(fromLocation.getX(), fromLocation.getZ()) || !Objects.equals(toPlot, toArea.getOwnedPlot(fromLocation))) { | ||||||
|                 event.setCancelled(true); |                 event.setCancelled(true); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             if (plot.getFlag(LiquidFlowFlag.class) == LiquidFlowFlag.FlowStatus.ENABLED && event.getBlock().isLiquid()) { |             if (toPlot.getFlag(LiquidFlowFlag.class) == LiquidFlowFlag.FlowStatus.ENABLED && event.getBlock().isLiquid()) { | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             if (plot.getFlag(DisablePhysicsFlag.class)) { |             if (toPlot.getFlag(DisablePhysicsFlag.class)) { | ||||||
|                 plot.debug(event.getBlock().getType() + " could not update because disable-physics = true"); |                 toPlot.debug(event.getBlock().getType() + " could not update because disable-physics = true"); | ||||||
|                 event.setCancelled(true); |                 event.setCancelled(true); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             if (plot.getFlag(LiquidFlowFlag.class) == LiquidFlowFlag.FlowStatus.DISABLED && event.getBlock().isLiquid()) { |             if (toPlot.getFlag(LiquidFlowFlag.class) == LiquidFlowFlag.FlowStatus.DISABLED && event.getBlock().isLiquid()) { | ||||||
|                 plot.debug("Liquid could not flow because liquid-flow = disabled"); |                 toPlot.debug("Liquid could not flow because liquid-flow = disabled"); | ||||||
|                 event.setCancelled(true); |                 event.setCancelled(true); | ||||||
|             } |             } | ||||||
|         } else if (!area.contains(fLocation.getX(), fLocation.getZ()) || !Objects.equals(null, area.getOwnedPlot(fLocation))) { |         } else if (!toArea.contains(fromLocation.getX(), fromLocation.getZ()) || !Objects.equals(null, toArea.getOwnedPlot(fromLocation))) { | ||||||
|             event.setCancelled(true); |             event.setCancelled(true); | ||||||
|         } else if (event.getBlock().isLiquid()) { |         } else if (event.getBlock().isLiquid()) { | ||||||
|             final org.bukkit.Location location = event.getBlock().getLocation(); |             final org.bukkit.Location location = event.getBlock().getLocation(); | ||||||
|   | |||||||
| @@ -168,6 +168,7 @@ public class EntityEventListener implements Listener { | |||||||
|             case "RAID": |             case "RAID": | ||||||
|             case "SHEARED": |             case "SHEARED": | ||||||
|             case "SILVERFISH_BLOCK": |             case "SILVERFISH_BLOCK": | ||||||
|  |             case "ENDER_PEARL": | ||||||
|             case "TRAP": |             case "TRAP": | ||||||
|             case "VILLAGE_DEFENSE": |             case "VILLAGE_DEFENSE": | ||||||
|             case "VILLAGE_INVASION": |             case "VILLAGE_INVASION": | ||||||
|   | |||||||
| @@ -44,6 +44,7 @@ import com.plotsquared.core.player.PlotPlayer; | |||||||
| import com.plotsquared.core.plot.Plot; | import com.plotsquared.core.plot.Plot; | ||||||
| import com.plotsquared.core.plot.PlotArea; | import com.plotsquared.core.plot.PlotArea; | ||||||
| import com.plotsquared.core.plot.flag.implementations.DoneFlag; | import com.plotsquared.core.plot.flag.implementations.DoneFlag; | ||||||
|  | import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag; | ||||||
| import com.plotsquared.core.plot.world.PlotAreaManager; | import com.plotsquared.core.plot.world.PlotAreaManager; | ||||||
| import com.plotsquared.core.util.Permissions; | import com.plotsquared.core.util.Permissions; | ||||||
| import net.kyori.adventure.text.minimessage.Template; | import net.kyori.adventure.text.minimessage.Template; | ||||||
| @@ -195,6 +196,7 @@ public class PaperListener implements Listener { | |||||||
|             case "RAID": |             case "RAID": | ||||||
|             case "SHEARED": |             case "SHEARED": | ||||||
|             case "SILVERFISH_BLOCK": |             case "SILVERFISH_BLOCK": | ||||||
|  |             case "ENDER_PEARL": | ||||||
|             case "TRAP": |             case "TRAP": | ||||||
|             case "VILLAGE_DEFENSE": |             case "VILLAGE_DEFENSE": | ||||||
|             case "VILLAGE_INVASION": |             case "VILLAGE_INVASION": | ||||||
| @@ -352,6 +354,7 @@ public class PaperListener implements Listener { | |||||||
|                 event.setCancelled(true); |                 event.setCancelled(true); | ||||||
|             } |             } | ||||||
|         } else if (!plot.isAdded(pp.getUUID())) { |         } else if (!plot.isAdded(pp.getUUID())) { | ||||||
|  |             if (!plot.getFlag(ProjectilesFlag.class)) { | ||||||
|                 if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_PROJECTILE_OTHER)) { |                 if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_PROJECTILE_OTHER)) { | ||||||
|                     pp.sendMessage( |                     pp.sendMessage( | ||||||
|                             TranslatableCaption.of("permission.no_permission_event"), |                             TranslatableCaption.of("permission.no_permission_event"), | ||||||
| @@ -362,6 +365,7 @@ public class PaperListener implements Listener { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @EventHandler |     @EventHandler | ||||||
|     public void onAsyncTabCompletion(final AsyncTabCompleteEvent event) { |     public void onAsyncTabCompletion(final AsyncTabCompleteEvent event) { | ||||||
|   | |||||||
| @@ -76,7 +76,6 @@ import com.plotsquared.core.util.EventDispatcher; | |||||||
| import com.plotsquared.core.util.MathMan; | import com.plotsquared.core.util.MathMan; | ||||||
| import com.plotsquared.core.util.Permissions; | import com.plotsquared.core.util.Permissions; | ||||||
| import com.plotsquared.core.util.PremiumVerification; | import com.plotsquared.core.util.PremiumVerification; | ||||||
| import com.plotsquared.core.util.RegExUtil; |  | ||||||
| import com.plotsquared.core.util.entity.EntityCategories; | import com.plotsquared.core.util.entity.EntityCategories; | ||||||
| import com.plotsquared.core.util.task.TaskManager; | import com.plotsquared.core.util.task.TaskManager; | ||||||
| import com.plotsquared.core.util.task.TaskTime; | import com.plotsquared.core.util.task.TaskTime; | ||||||
| @@ -223,10 +222,9 @@ public class PlayerEventListener extends PlotListener implements Listener { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @SuppressWarnings("StringSplitter") |  | ||||||
|     @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) |     @EventHandler(ignoreCancelled = true, priority = EventPriority.HIGHEST) | ||||||
|     public void playerCommand(PlayerCommandPreprocessEvent event) { |     public void playerCommand(PlayerCommandPreprocessEvent event) { | ||||||
|         String msg = event.getMessage().toLowerCase().replaceAll("/", "").trim(); |         String msg = event.getMessage().replace("/", "").toLowerCase(Locale.ROOT).trim(); | ||||||
|         if (msg.isEmpty()) { |         if (msg.isEmpty()) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
| @@ -240,11 +238,9 @@ public class PlayerEventListener extends PlotListener implements Listener { | |||||||
|         String[] parts = msg.split(" "); |         String[] parts = msg.split(" "); | ||||||
|         Plot plot = plotPlayer.getCurrentPlot(); |         Plot plot = plotPlayer.getCurrentPlot(); | ||||||
|         // Check WorldEdit |         // Check WorldEdit | ||||||
|         switch (parts[0].toLowerCase()) { |         switch (parts[0]) { | ||||||
|             case "up": |             case "up": | ||||||
|             case "/up": |  | ||||||
|             case "worldedit:up": |             case "worldedit:up": | ||||||
|             case "worldedit:/up": |  | ||||||
|                 if (plot == null || (!plot.isAdded(plotPlayer.getUUID()) && !Permissions |                 if (plot == null || (!plot.isAdded(plotPlayer.getUUID()) && !Permissions | ||||||
|                         .hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_BUILD_OTHER, true))) { |                         .hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_BUILD_OTHER, true))) { | ||||||
|                     event.setCancelled(true); |                     event.setCancelled(true); | ||||||
| @@ -258,15 +254,40 @@ public class PlayerEventListener extends PlotListener implements Listener { | |||||||
|         List<String> blockedCommands = plot != null ? |         List<String> blockedCommands = plot != null ? | ||||||
|                 plot.getFlag(BlockedCmdsFlag.class) : |                 plot.getFlag(BlockedCmdsFlag.class) : | ||||||
|                 area.getFlag(BlockedCmdsFlag.class); |                 area.getFlag(BlockedCmdsFlag.class); | ||||||
|         if (!blockedCommands.isEmpty() && !Permissions |         if (blockedCommands.isEmpty()) { | ||||||
|                 .hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_INTERACT_BLOCKED_CMDS)) { |             return; | ||||||
|             String part = parts[0]; |  | ||||||
|             if (parts[0].contains(":")) { |  | ||||||
|                 part = parts[0].split(":")[1]; |  | ||||||
|                 msg = msg.replace(parts[0].split(":")[0] + ':', ""); |  | ||||||
|         } |         } | ||||||
|  |         if (Permissions.hasPermission(plotPlayer, Permission.PERMISSION_ADMIN_INTERACT_BLOCKED_CMDS)) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         // When using namespaced commands, we're not interested in the namespace | ||||||
|  |         String part = parts[0]; | ||||||
|  |         if (part.contains(":")) { | ||||||
|  |             String[] namespaced = part.split(":"); | ||||||
|  |             part = namespaced[1]; | ||||||
|  |             msg = msg.substring(namespaced[0].length() + 1); | ||||||
|  |         } | ||||||
|  |         msg = replaceAliases(msg, part); | ||||||
|  |         for (String blocked : blockedCommands) { | ||||||
|  |             if (blocked.equalsIgnoreCase(msg)) { | ||||||
|  |                 String perm; | ||||||
|  |                 if (plot != null && plot.isAdded(plotPlayer.getUUID())) { | ||||||
|  |                     perm = "plots.admin.command.blocked-cmds.shared"; | ||||||
|  |                 } else { | ||||||
|  |                     perm = "plots.admin.command.blocked-cmds.road"; | ||||||
|  |                 } | ||||||
|  |                 if (!Permissions.hasPermission(plotPlayer, perm)) { | ||||||
|  |                     plotPlayer.sendMessage(TranslatableCaption.of("blockedcmds.command_blocked")); | ||||||
|  |                     event.setCancelled(true); | ||||||
|  |                 } | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private String replaceAliases(String msg, String part) { | ||||||
|         String s1 = part; |         String s1 = part; | ||||||
|             List<String> aliases = new ArrayList<>(); |         Set<String> aliases = new HashSet<>(); | ||||||
|         for (HelpTopic cmdLabel : Bukkit.getServer().getHelpMap().getHelpTopics()) { |         for (HelpTopic cmdLabel : Bukkit.getServer().getHelpMap().getHelpTopics()) { | ||||||
|             if (part.equals(cmdLabel.getName())) { |             if (part.equals(cmdLabel.getName())) { | ||||||
|                 break; |                 break; | ||||||
| @@ -275,8 +296,8 @@ public class PlayerEventListener extends PlotListener implements Listener { | |||||||
|             if (aliases.contains(label)) { |             if (aliases.contains(label)) { | ||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|                 PluginCommand p; |             PluginCommand p = Bukkit.getPluginCommand(label); | ||||||
|                 if ((p = Bukkit.getPluginCommand(label)) != null) { |             if (p != null) { | ||||||
|                 for (String a : p.getAliases()) { |                 for (String a : p.getAliases()) { | ||||||
|                     if (aliases.contains(a)) { |                     if (aliases.contains(a)) { | ||||||
|                         continue; |                         continue; | ||||||
| @@ -293,28 +314,7 @@ public class PlayerEventListener extends PlotListener implements Listener { | |||||||
|         if (!s1.equals(part)) { |         if (!s1.equals(part)) { | ||||||
|             msg = msg.replace(s1, part); |             msg = msg.replace(s1, part); | ||||||
|         } |         } | ||||||
|             for (String s : blockedCommands) { |         return msg; | ||||||
|                 Pattern pattern; |  | ||||||
|                 if (!RegExUtil.compiledPatterns.containsKey(s)) { |  | ||||||
|                     RegExUtil.compiledPatterns.put(s, pattern = Pattern.compile(s)); |  | ||||||
|                 } else { |  | ||||||
|                     pattern = RegExUtil.compiledPatterns.get(s); |  | ||||||
|                 } |  | ||||||
|                 if (pattern.matcher(msg).matches()) { |  | ||||||
|                     String perm; |  | ||||||
|                     if (plot != null && plot.isAdded(plotPlayer.getUUID())) { |  | ||||||
|                         perm = "plots.admin.command.blocked-cmds.shared"; |  | ||||||
|                     } else { |  | ||||||
|                         perm = "plots.admin.command.blocked-cmds.road"; |  | ||||||
|                     } |  | ||||||
|                     if (!Permissions.hasPermission(plotPlayer, perm)) { |  | ||||||
|                         plotPlayer.sendMessage(TranslatableCaption.of("blockedcmds.command_blocked")); |  | ||||||
|                         event.setCancelled(true); |  | ||||||
|                     } |  | ||||||
|                     return; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) |     @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ import com.plotsquared.core.player.PlotPlayer; | |||||||
| import com.plotsquared.core.plot.Plot; | import com.plotsquared.core.plot.Plot; | ||||||
| import com.plotsquared.core.plot.PlotArea; | import com.plotsquared.core.plot.PlotArea; | ||||||
| import com.plotsquared.core.plot.PlotHandler; | 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.plot.world.PlotAreaManager; | ||||||
| import com.plotsquared.core.util.Permissions; | import com.plotsquared.core.util.Permissions; | ||||||
| import net.kyori.adventure.text.minimessage.Template; | import net.kyori.adventure.text.minimessage.Template; | ||||||
| @@ -128,6 +129,7 @@ public class ProjectileEventListener implements Listener { | |||||||
|                 event.setCancelled(true); |                 event.setCancelled(true); | ||||||
|             } |             } | ||||||
|         } else if (!plot.isAdded(pp.getUUID())) { |         } else if (!plot.isAdded(pp.getUUID())) { | ||||||
|  |             if (!plot.getFlag(ProjectilesFlag.class)) { | ||||||
|                 if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_PROJECTILE_OTHER)) { |                 if (!Permissions.hasPermission(pp, Permission.PERMISSION_ADMIN_PROJECTILE_OTHER)) { | ||||||
|                     pp.sendMessage( |                     pp.sendMessage( | ||||||
|                             TranslatableCaption.of("permission.no_permission_event"), |                             TranslatableCaption.of("permission.no_permission_event"), | ||||||
| @@ -138,6 +140,7 @@ public class ProjectileEventListener implements Listener { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @EventHandler |     @EventHandler | ||||||
|     public void onProjectileHit(ProjectileHitEvent event) { |     public void onProjectileHit(ProjectileHitEvent event) { | ||||||
| @@ -162,7 +165,7 @@ public class ProjectileEventListener implements Listener { | |||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             if (plot.isAdded(pp.getUUID()) || Permissions |             if (plot.isAdded(pp.getUUID()) || Permissions | ||||||
|                     .hasPermission(pp, Permission.PERMISSION_ADMIN_PROJECTILE_OTHER)) { |                     .hasPermission(pp, Permission.PERMISSION_ADMIN_PROJECTILE_OTHER) || plot.getFlag(ProjectilesFlag.class)) { | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             entity.remove(); |             entity.remove(); | ||||||
|   | |||||||
| @@ -46,7 +46,7 @@ import static com.plotsquared.core.util.ReflectionUtils.getRefClass; | |||||||
| public class SingleWorldListener implements Listener { | public class SingleWorldListener implements Listener { | ||||||
|  |  | ||||||
|     private final Method methodGetHandleChunk; |     private final Method methodGetHandleChunk; | ||||||
|     private Field shouldSave; |     private Field shouldSave = null; | ||||||
|  |  | ||||||
|     public SingleWorldListener() throws Exception { |     public SingleWorldListener() throws Exception { | ||||||
|         ReflectionUtils.RefClass classCraftChunk = getRefClass("{cb}.CraftChunk"); |         ReflectionUtils.RefClass classCraftChunk = getRefClass("{cb}.CraftChunk"); | ||||||
| @@ -59,9 +59,12 @@ public class SingleWorldListener implements Listener { | |||||||
|                 } else { |                 } else { | ||||||
|                     this.shouldSave = classChunk.getField("s").getRealField(); |                     this.shouldSave = classChunk.getField("s").getRealField(); | ||||||
|                 } |                 } | ||||||
|             } else { |             } else if (PlotSquared.platform().serverVersion()[1] == 17) { | ||||||
|                 ReflectionUtils.RefClass classChunk = getRefClass("net.minecraft.world.level.chunk.Chunk"); |                 ReflectionUtils.RefClass classChunk = getRefClass("net.minecraft.world.level.chunk.Chunk"); | ||||||
|                 this.shouldSave = classChunk.getField("r").getRealField(); |                 this.shouldSave = classChunk.getField("r").getRealField(); | ||||||
|  |             } else if (PlotSquared.platform().serverVersion()[1] == 18) { | ||||||
|  |                 ReflectionUtils.RefClass classChunk = getRefClass("net.minecraft.world.level.chunk.IChunkAccess"); | ||||||
|  |                 this.shouldSave = classChunk.getField("b").getRealField(); | ||||||
|             } |             } | ||||||
|         } catch (NoSuchFieldException e) { |         } catch (NoSuchFieldException e) { | ||||||
|             e.printStackTrace(); |             e.printStackTrace(); | ||||||
|   | |||||||
| @@ -74,11 +74,13 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator { | |||||||
|     private final Consumer<Throwable> throwableConsumer; |     private final Consumer<Throwable> throwableConsumer; | ||||||
|     private final boolean unloadAfter; |     private final boolean unloadAfter; | ||||||
|     private final int totalSize; |     private final int totalSize; | ||||||
|  |  | ||||||
|     private final AtomicInteger expectedSize; |     private final AtomicInteger expectedSize; | ||||||
|  |     private final AtomicInteger loadingChunks = new AtomicInteger(); | ||||||
|  |     private final boolean forceSync; | ||||||
|  |  | ||||||
|     private int batchSize; |     private int batchSize; | ||||||
|     private PlotSquaredTask task; |     private PlotSquaredTask task; | ||||||
|     private boolean shouldCancel; |     private volatile boolean shouldCancel; | ||||||
|     private boolean finished; |     private boolean finished; | ||||||
|  |  | ||||||
|     @Inject |     @Inject | ||||||
| @@ -91,7 +93,8 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator { | |||||||
|             @Assisted final @NonNull Runnable whenDone, |             @Assisted final @NonNull Runnable whenDone, | ||||||
|             @Assisted final @NonNull Consumer<Throwable> throwableConsumer, |             @Assisted final @NonNull Consumer<Throwable> throwableConsumer, | ||||||
|             @Assisted final boolean unloadAfter, |             @Assisted final boolean unloadAfter, | ||||||
|             @Assisted final @NonNull Collection<ProgressSubscriber> progressSubscribers |             @Assisted final @NonNull Collection<ProgressSubscriber> progressSubscribers, | ||||||
|  |             @Assisted final boolean forceSync | ||||||
|     ) { |     ) { | ||||||
|         this.requestedChunks = new LinkedBlockingQueue<>(requestedChunks); |         this.requestedChunks = new LinkedBlockingQueue<>(requestedChunks); | ||||||
|         this.availableChunks = new LinkedBlockingQueue<>(); |         this.availableChunks = new LinkedBlockingQueue<>(); | ||||||
| @@ -106,14 +109,27 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator { | |||||||
|         this.plugin = JavaPlugin.getPlugin(BukkitPlatform.class); |         this.plugin = JavaPlugin.getPlugin(BukkitPlatform.class); | ||||||
|         this.bukkitWorld = Bukkit.getWorld(world.getName()); |         this.bukkitWorld = Bukkit.getWorld(world.getName()); | ||||||
|         this.progressSubscribers.addAll(progressSubscribers); |         this.progressSubscribers.addAll(progressSubscribers); | ||||||
|  |         this.forceSync = forceSync; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void start() { |     public void start() { | ||||||
|  |         if (!forceSync) { | ||||||
|             // Request initial batch |             // Request initial batch | ||||||
|             this.requestBatch(); |             this.requestBatch(); | ||||||
|             // Wait until next tick to give the chunks a chance to be loaded |             // Wait until next tick to give the chunks a chance to be loaded | ||||||
|             TaskManager.runTaskLater(() -> task = TaskManager.runTaskRepeat(this, TaskTime.ticks(1)), TaskTime.ticks(1)); |             TaskManager.runTaskLater(() -> task = TaskManager.runTaskRepeat(this, TaskTime.ticks(1)), TaskTime.ticks(1)); | ||||||
|  |         } else { | ||||||
|  |             try { | ||||||
|  |                 while (!shouldCancel && !requestedChunks.isEmpty()) { | ||||||
|  |                     chunkConsumer.accept(requestedChunks.poll()); | ||||||
|  |                 } | ||||||
|  |             } catch (Throwable t) { | ||||||
|  |                 throwableConsumer.accept(t); | ||||||
|  |             } finally { | ||||||
|  |                 finish(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @@ -130,7 +146,9 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator { | |||||||
|             for (final ProgressSubscriber subscriber : this.progressSubscribers) { |             for (final ProgressSubscriber subscriber : this.progressSubscribers) { | ||||||
|                 subscriber.notifyEnd(); |                 subscriber.notifyEnd(); | ||||||
|             } |             } | ||||||
|  |             if (task != null) { | ||||||
|                 task.cancel(); |                 task.cancel(); | ||||||
|  |             } | ||||||
|             finished = true; |             finished = true; | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -150,6 +168,13 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator { | |||||||
|  |  | ||||||
|         Chunk chunk = this.availableChunks.poll(); |         Chunk chunk = this.availableChunks.poll(); | ||||||
|         if (chunk == null) { |         if (chunk == null) { | ||||||
|  |             if (this.availableChunks.isEmpty()) { | ||||||
|  |                 if (this.requestedChunks.isEmpty() && loadingChunks.get() == 0) { | ||||||
|  |                     finish(); | ||||||
|  |                 } else { | ||||||
|  |                     requestBatch(); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         long[] iterationTime = new long[2]; |         long[] iterationTime = new long[2]; | ||||||
| @@ -197,9 +222,11 @@ public final class BukkitChunkCoordinator extends ChunkCoordinator { | |||||||
|         BlockVector2 chunk; |         BlockVector2 chunk; | ||||||
|         for (int i = 0; i < this.batchSize && (chunk = this.requestedChunks.poll()) != null; i++) { |         for (int i = 0; i < this.batchSize && (chunk = this.requestedChunks.poll()) != null; i++) { | ||||||
|             // This required PaperLib to be bumped to version 1.0.4 to mark the request as urgent |             // This required PaperLib to be bumped to version 1.0.4 to mark the request as urgent | ||||||
|  |             loadingChunks.incrementAndGet(); | ||||||
|             PaperLib |             PaperLib | ||||||
|                     .getChunkAtAsync(this.bukkitWorld, chunk.getX(), chunk.getZ(), true, true) |                     .getChunkAtAsync(this.bukkitWorld, chunk.getX(), chunk.getZ(), true, true) | ||||||
|                     .whenComplete((chunkObject, throwable) -> { |                     .whenComplete((chunkObject, throwable) -> { | ||||||
|  |                         loadingChunks.decrementAndGet(); | ||||||
|                         if (throwable != null) { |                         if (throwable != null) { | ||||||
|                             throwable.printStackTrace(); |                             throwable.printStackTrace(); | ||||||
|                             // We want one less because this couldn't be processed |                             // We want one less because this couldn't be processed | ||||||
|   | |||||||
| @@ -51,6 +51,7 @@ import com.sk89q.worldedit.world.biome.BiomeType; | |||||||
| import com.sk89q.worldedit.world.block.BaseBlock; | import com.sk89q.worldedit.world.block.BaseBlock; | ||||||
| import com.sk89q.worldedit.world.block.BlockState; | import com.sk89q.worldedit.world.block.BlockState; | ||||||
| import org.bukkit.Bukkit; | import org.bukkit.Bukkit; | ||||||
|  | import org.bukkit.Chunk; | ||||||
| import org.bukkit.block.Block; | import org.bukkit.block.Block; | ||||||
| import org.bukkit.block.Container; | import org.bukkit.block.Container; | ||||||
| import org.bukkit.block.data.BlockData; | import org.bukkit.block.data.BlockData; | ||||||
| @@ -62,10 +63,27 @@ import java.util.function.Consumer; | |||||||
|  |  | ||||||
| public class BukkitQueueCoordinator extends BasicQueueCoordinator { | public class BukkitQueueCoordinator extends BasicQueueCoordinator { | ||||||
|  |  | ||||||
|     private final SideEffectSet noSideEffectSet; |     private static final SideEffectSet NO_SIDE_EFFECT_SET; | ||||||
|     private final SideEffectSet lightingSideEffectSet; |     private static final SideEffectSet EDGE_SIDE_EFFECT_SET; | ||||||
|     private final SideEffectSet edgeSideEffectSet; |     private static final SideEffectSet LIGHTING_SIDE_EFFECT_SET; | ||||||
|     private final SideEffectSet edgeLightingSideEffectSet; |     private static final SideEffectSet EDGE_LIGHTING_SIDE_EFFECT_SET; | ||||||
|  |  | ||||||
|  |     static { | ||||||
|  |         NO_SIDE_EFFECT_SET = SideEffectSet.none().with(SideEffect.LIGHTING, SideEffect.State.OFF).with( | ||||||
|  |                 SideEffect.NEIGHBORS, | ||||||
|  |                 SideEffect.State.OFF | ||||||
|  |         ); | ||||||
|  |         EDGE_SIDE_EFFECT_SET = SideEffectSet.none().with(SideEffect.UPDATE, SideEffect.State.ON).with( | ||||||
|  |                 SideEffect.NEIGHBORS, | ||||||
|  |                 SideEffect.State.ON | ||||||
|  |         ); | ||||||
|  |         LIGHTING_SIDE_EFFECT_SET = SideEffectSet.none().with(SideEffect.NEIGHBORS, SideEffect.State.OFF); | ||||||
|  |         EDGE_LIGHTING_SIDE_EFFECT_SET = SideEffectSet.none().with(SideEffect.UPDATE, SideEffect.State.ON).with( | ||||||
|  |                 SideEffect.NEIGHBORS, | ||||||
|  |                 SideEffect.State.ON | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private org.bukkit.World bukkitWorld; |     private org.bukkit.World bukkitWorld; | ||||||
|     @Inject |     @Inject | ||||||
|     private ChunkCoordinatorBuilderFactory chunkCoordinatorBuilderFactory; |     private ChunkCoordinatorBuilderFactory chunkCoordinatorBuilderFactory; | ||||||
| @@ -76,19 +94,6 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { | |||||||
|     @Inject |     @Inject | ||||||
|     public BukkitQueueCoordinator(@NonNull World world) { |     public BukkitQueueCoordinator(@NonNull World world) { | ||||||
|         super(world); |         super(world); | ||||||
|         noSideEffectSet = SideEffectSet.none().with(SideEffect.LIGHTING, SideEffect.State.OFF).with( |  | ||||||
|                 SideEffect.NEIGHBORS, |  | ||||||
|                 SideEffect.State.OFF |  | ||||||
|         ); |  | ||||||
|         lightingSideEffectSet = SideEffectSet.none().with(SideEffect.NEIGHBORS, SideEffect.State.OFF); |  | ||||||
|         edgeSideEffectSet = noSideEffectSet.with(SideEffect.UPDATE, SideEffect.State.ON).with( |  | ||||||
|                 SideEffect.NEIGHBORS, |  | ||||||
|                 SideEffect.State.ON |  | ||||||
|         ); |  | ||||||
|         edgeLightingSideEffectSet = noSideEffectSet.with(SideEffect.UPDATE, SideEffect.State.ON).with( |  | ||||||
|                 SideEffect.NEIGHBORS, |  | ||||||
|                 SideEffect.State.ON |  | ||||||
|         ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @@ -111,8 +116,8 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { | |||||||
|     public boolean enqueue() { |     public boolean enqueue() { | ||||||
|         final Clipboard regenClipboard; |         final Clipboard regenClipboard; | ||||||
|         if (isRegen()) { |         if (isRegen()) { | ||||||
|             BlockVector3 start = BlockVector3.at(getRegenStart()[0] << 4, 0, getRegenStart()[1] << 4); |             BlockVector3 start = BlockVector3.at(getRegenStart()[0] << 4, getMinY(), getRegenStart()[1] << 4); | ||||||
|             BlockVector3 end = BlockVector3.at((getRegenEnd()[0] << 4) + 15, 255, (getRegenEnd()[1] << 4) + 15); |             BlockVector3 end = BlockVector3.at((getRegenEnd()[0] << 4) + 15, getMaxY(), (getRegenEnd()[1] << 4) + 15); | ||||||
|             Region region = new CuboidRegion(start, end); |             Region region = new CuboidRegion(start, end); | ||||||
|             regenClipboard = new BlockArrayClipboard(region); |             regenClipboard = new BlockArrayClipboard(region); | ||||||
|             regenClipboard.setOrigin(start); |             regenClipboard.setOrigin(start); | ||||||
| @@ -134,7 +139,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { | |||||||
|                 int sx = blockVector2.getX() << 4; |                 int sx = blockVector2.getX() << 4; | ||||||
|                 int sz = blockVector2.getZ() << 4; |                 int sz = blockVector2.getZ() << 4; | ||||||
|                 if (isRegenChunk) { |                 if (isRegenChunk) { | ||||||
|                     for (int layer = 0; layer < 16; layer++) { |                     for (int layer = getMinLayer(); layer <= getMaxLayer(); layer++) { | ||||||
|                         for (int y = 0; y < 16; y++) { |                         for (int y = 0; y < 16; y++) { | ||||||
|                             for (int x = 0; x < 16; x++) { |                             for (int x = 0; x < 16; x++) { | ||||||
|                                 for (int z = 0; z < 16; z++) { |                                 for (int z = 0; z < 16; z++) { | ||||||
| @@ -170,7 +175,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { | |||||||
|                             int lx = ChunkUtil.getX(j); |                             int lx = ChunkUtil.getX(j); | ||||||
|                             int lz = ChunkUtil.getZ(j); |                             int lz = ChunkUtil.getZ(j); | ||||||
|                             int x = sx + lx; |                             int x = sx + lx; | ||||||
|                             int y = ChunkUtil.getY(layer, j); |                             int y = ChunkUtil.getY(layer + localChunk.getMinSection(), j); | ||||||
|                             int z = sz + lz; |                             int z = sz + lz; | ||||||
|                             boolean edge = Settings.QUEUE.UPDATE_EDGES && isEdge(y >> 4, lx, y & 15, lz, blockVector2, |                             boolean edge = Settings.QUEUE.UPDATE_EDGES && isEdge(y >> 4, lx, y & 15, lz, blockVector2, | ||||||
|                                     localChunk |                                     localChunk | ||||||
| @@ -179,7 +184,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { | |||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 for (int layer = 0; layer < localChunk.getBaseblocks().length; layer++) { |                 for (int layer = 0; layer < localChunk.getBiomes().length; layer++) { | ||||||
|                     BiomeType[] biomesLayer = localChunk.getBiomes()[layer]; |                     BiomeType[] biomesLayer = localChunk.getBiomes()[layer]; | ||||||
|                     if (biomesLayer == null) { |                     if (biomesLayer == null) { | ||||||
|                         continue; |                         continue; | ||||||
| @@ -201,7 +206,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { | |||||||
|                     localChunk.getTiles().forEach((blockVector3, tag) -> { |                     localChunk.getTiles().forEach((blockVector3, tag) -> { | ||||||
|                         try { |                         try { | ||||||
|                             BaseBlock block = getWorld().getBlock(blockVector3).toBaseBlock(tag); |                             BaseBlock block = getWorld().getBlock(blockVector3).toBaseBlock(tag); | ||||||
|                             getWorld().setBlock(blockVector3, block, noSideEffectSet); |                             getWorld().setBlock(blockVector3, block, getSideEffectSet(SideEffectState.NONE)); | ||||||
|                         } catch (WorldEditException ignored) { |                         } catch (WorldEditException ignored) { | ||||||
|                             StateWrapper sw = new StateWrapper(tag); |                             StateWrapper sw = new StateWrapper(tag); | ||||||
|                             sw.restoreTag(getWorld().getName(), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ()); |                             sw.restoreTag(getWorld().getName(), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ()); | ||||||
| @@ -258,15 +263,21 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { | |||||||
|             } |             } | ||||||
|             SideEffectSet sideEffectSet; |             SideEffectSet sideEffectSet; | ||||||
|             if (lighting) { |             if (lighting) { | ||||||
|                 sideEffectSet = edge ? edgeLightingSideEffectSet : lightingSideEffectSet; |                 sideEffectSet = getSideEffectSet(edge ? SideEffectState.EDGE_LIGHTING : SideEffectState.LIGHTING); | ||||||
|             } else { |             } else { | ||||||
|                 sideEffectSet = edge ? edgeSideEffectSet : noSideEffectSet; |                 sideEffectSet = getSideEffectSet(edge ? SideEffectState.EDGE : SideEffectState.NONE); | ||||||
|             } |             } | ||||||
|             getWorld().setBlock(loc, block, sideEffectSet); |             getWorld().setBlock(loc, block, sideEffectSet); | ||||||
|         } catch (WorldEditException ignored) { |         } catch (WorldEditException ignored) { | ||||||
|             // Fallback to not so nice method |             // Fallback to not so nice method | ||||||
|             BlockData blockData = BukkitAdapter.adapt(block); |             BlockData blockData = BukkitAdapter.adapt(block); | ||||||
|             Block existing = getBukkitWorld().getBlockAt(x, y, z); |             Block existing; | ||||||
|  |             // Assume a chunk object has been given only when it should have been. | ||||||
|  |             if (getChunkObject() instanceof Chunk chunkObject) { | ||||||
|  |                 existing = chunkObject.getBlock(x & 15, y, z & 15); | ||||||
|  |             } else { | ||||||
|  |                  existing = getBukkitWorld().getBlockAt(x, y, z); | ||||||
|  |             } | ||||||
|             final BlockState existingBaseBlock = BukkitAdapter.adapt(existing.getBlockData()); |             final BlockState existingBaseBlock = BukkitAdapter.adapt(existing.getBlockData()); | ||||||
|             if (BukkitBlockUtil.get(existing).equals(existingBaseBlock) && existing.getBlockData().matches(blockData)) { |             if (BukkitBlockUtil.get(existing).equals(existingBaseBlock) && existing.getBlockData().matches(blockData)) { | ||||||
|                 return; |                 return; | ||||||
| @@ -282,7 +293,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { | |||||||
|                 CompoundTag tag = block.getNbtData(); |                 CompoundTag tag = block.getNbtData(); | ||||||
|                 StateWrapper sw = new StateWrapper(tag); |                 StateWrapper sw = new StateWrapper(tag); | ||||||
|  |  | ||||||
|                 sw.restoreTag(getWorld().getName(), existing.getX(), existing.getY(), existing.getZ()); |                 sw.restoreTag(existing); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -295,47 +306,48 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private boolean isEdge(int layer, int x, int y, int z, BlockVector2 blockVector2, LocalChunk localChunk) { |     private boolean isEdge(int layer, int x, int y, int z, BlockVector2 blockVector2, LocalChunk localChunk) { | ||||||
|         if (layer == 0 || layer == localChunk.getBaseblocks().length - 1) { |         int layerIndex = (layer - localChunk.getMinSection()); | ||||||
|  |         if (layer == localChunk.getMinSection() || layerIndex == localChunk.getBaseblocks().length - 1) { | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         if (x == 0) { |         if (x == 0) { | ||||||
|             LocalChunk localChunkX = getBlockChunks().get(blockVector2.withX(blockVector2.getX() - 1)); |             LocalChunk localChunkX = getBlockChunks().get(blockVector2.withX(blockVector2.getX() - 1)); | ||||||
|             if (localChunkX == null || localChunkX.getBaseblocks()[layer] == null || |             if (localChunkX == null || localChunkX.getBaseblocks()[layerIndex] == null || | ||||||
|                     localChunkX.getBaseblocks()[layer][ChunkUtil.getJ(15, y, z)] != null) { |                     localChunkX.getBaseblocks()[layerIndex][ChunkUtil.getJ(15, y, z)] != null) { | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|         } else if (x == 15) { |         } else if (x == 15) { | ||||||
|             LocalChunk localChunkX = getBlockChunks().get(blockVector2.withX(blockVector2.getX() + 1)); |             LocalChunk localChunkX = getBlockChunks().get(blockVector2.withX(blockVector2.getX() + 1)); | ||||||
|             if (localChunkX == null || localChunkX.getBaseblocks()[layer] == null || |             if (localChunkX == null || localChunkX.getBaseblocks()[layerIndex] == null || | ||||||
|                     localChunkX.getBaseblocks()[layer][ChunkUtil.getJ(0, y, z)] != null) { |                     localChunkX.getBaseblocks()[layerIndex][ChunkUtil.getJ(0, y, z)] != null) { | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         if (z == 0) { |         if (z == 0) { | ||||||
|             LocalChunk localChunkZ = getBlockChunks().get(blockVector2.withZ(blockVector2.getZ() - 1)); |             LocalChunk localChunkZ = getBlockChunks().get(blockVector2.withZ(blockVector2.getZ() - 1)); | ||||||
|             if (localChunkZ == null || localChunkZ.getBaseblocks()[layer] == null || |             if (localChunkZ == null || localChunkZ.getBaseblocks()[layerIndex] == null || | ||||||
|                     localChunkZ.getBaseblocks()[layer][ChunkUtil.getJ(x, y, 15)] != null) { |                     localChunkZ.getBaseblocks()[layerIndex][ChunkUtil.getJ(x, y, 15)] != null) { | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|         } else if (z == 15) { |         } else if (z == 15) { | ||||||
|             LocalChunk localChunkZ = getBlockChunks().get(blockVector2.withZ(blockVector2.getZ() + 1)); |             LocalChunk localChunkZ = getBlockChunks().get(blockVector2.withZ(blockVector2.getZ() + 1)); | ||||||
|             if (localChunkZ == null || localChunkZ.getBaseblocks()[layer] == null || |             if (localChunkZ == null || localChunkZ.getBaseblocks()[layerIndex] == null || | ||||||
|                     localChunkZ.getBaseblocks()[layer][ChunkUtil.getJ(x, y, 0)] != null) { |                     localChunkZ.getBaseblocks()[layerIndex][ChunkUtil.getJ(x, y, 0)] != null) { | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         if (y == 0) { |         if (y == 0) { | ||||||
|             if (localChunk.getBaseblocks()[layer - 1] == null || |             if (localChunk.getBaseblocks()[layerIndex - 1] == null || | ||||||
|                     localChunk.getBaseblocks()[layer][ChunkUtil.getJ(x, 15, z)] != null) { |                     localChunk.getBaseblocks()[layerIndex][ChunkUtil.getJ(x, 15, z)] != null) { | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|         } else if (y == 15) { |         } else if (y == 15) { | ||||||
|             if (localChunk.getBaseblocks()[layer + 1] == null || |             if (localChunk.getBaseblocks()[layerIndex + 1] == null || | ||||||
|                     localChunk.getBaseblocks()[layer][ChunkUtil.getJ(x, 0, z)] != null) { |                     localChunk.getBaseblocks()[layerIndex][ChunkUtil.getJ(x, 0, z)] != null) { | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         BaseBlock[] baseBlocks = localChunk.getBaseblocks()[layer]; |         BaseBlock[] baseBlocks = localChunk.getBaseblocks()[layerIndex]; | ||||||
|         if (x > 0 && baseBlocks[ChunkUtil.getJ(x - 1, y, z)] == null) { |         if (x > 0 && baseBlocks[ChunkUtil.getJ(x - 1, y, z)] == null) { | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
| @@ -374,4 +386,23 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private SideEffectSet getSideEffectSet(SideEffectState state) { | ||||||
|  |         if (getSideEffectSet() != null) { | ||||||
|  |             return getSideEffectSet(); | ||||||
|  |         } | ||||||
|  |         return switch (state) { | ||||||
|  |             case NONE -> NO_SIDE_EFFECT_SET; | ||||||
|  |             case EDGE -> EDGE_SIDE_EFFECT_SET; | ||||||
|  |             case LIGHTING -> LIGHTING_SIDE_EFFECT_SET; | ||||||
|  |             case EDGE_LIGHTING -> EDGE_LIGHTING_SIDE_EFFECT_SET; | ||||||
|  |         }; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private enum SideEffectState { | ||||||
|  |         NONE, | ||||||
|  |         EDGE, | ||||||
|  |         LIGHTING, | ||||||
|  |         EDGE_LIGHTING | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ import com.plotsquared.bukkit.util.BukkitUtil; | |||||||
| import com.plotsquared.core.location.ChunkWrapper; | import com.plotsquared.core.location.ChunkWrapper; | ||||||
| import com.plotsquared.core.location.Location; | import com.plotsquared.core.location.Location; | ||||||
| import com.plotsquared.core.queue.ScopedQueueCoordinator; | import com.plotsquared.core.queue.ScopedQueueCoordinator; | ||||||
|  | import com.plotsquared.core.util.AnnotationHelper; | ||||||
| import com.plotsquared.core.util.ChunkUtil; | import com.plotsquared.core.util.ChunkUtil; | ||||||
| import com.plotsquared.core.util.PatternUtil; | import com.plotsquared.core.util.PatternUtil; | ||||||
| import com.sk89q.worldedit.bukkit.BukkitAdapter; | import com.sk89q.worldedit.bukkit.BukkitAdapter; | ||||||
| @@ -50,6 +51,7 @@ import org.checkerframework.checker.nullness.qual.Nullable; | |||||||
|  |  | ||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
|  |  | ||||||
|  | @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||||
| public class GenChunk extends ScopedQueueCoordinator { | public class GenChunk extends ScopedQueueCoordinator { | ||||||
|  |  | ||||||
|     public final Biome[] biomes; |     public final Biome[] biomes; | ||||||
| @@ -61,8 +63,14 @@ public class GenChunk extends ScopedQueueCoordinator { | |||||||
|     public int chunkZ; |     public int chunkZ; | ||||||
|     private ChunkData chunkData = null; |     private ChunkData chunkData = null; | ||||||
|  |  | ||||||
|     public GenChunk() { |     /** | ||||||
|         super(null, Location.at("", 0, 0, 0), Location.at("", 15, 255, 15)); |      * @param minY minimum world Y, inclusive | ||||||
|  |      * @param maxY maximum world Y, inclusive | ||||||
|  |      * | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      */ | ||||||
|  |     public GenChunk(int minY, int maxY) { | ||||||
|  |         super(null, Location.at("", 0, minY, 0), Location.at("", 15, maxY, 15)); | ||||||
|         this.biomes = Biome.values(); |         this.biomes = Biome.values(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -117,7 +125,7 @@ public class GenChunk extends ScopedQueueCoordinator { | |||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         Biome biome = BukkitAdapter.adapt(biomeType); |         Biome biome = BukkitAdapter.adapt(biomeType); | ||||||
|         for (int y = 0; y < 256; y++) { |         for (int y = getMin().getY(); y <= getMax().getY(); y++) { | ||||||
|             for (int x = 0; x < 16; x++) { |             for (int x = 0; x < 16; x++) { | ||||||
|                 for (int z = 0; z < 16; z++) { |                 for (int z = 0; z < 16; z++) { | ||||||
|                     this.biomeGrid.setBiome(x, y, z, biome); |                     this.biomeGrid.setBiome(x, y, z, biome); | ||||||
| @@ -130,7 +138,7 @@ public class GenChunk extends ScopedQueueCoordinator { | |||||||
|     public void setCuboid(@NonNull Location pos1, @NonNull Location pos2, @NonNull BlockState block) { |     public void setCuboid(@NonNull Location pos1, @NonNull Location pos2, @NonNull BlockState block) { | ||||||
|         if (result != null && pos1.getX() == 0 && pos1.getZ() == 0 && pos2.getX() == 15 && pos2.getZ() == 15) { |         if (result != null && pos1.getX() == 0 && pos1.getZ() == 0 && pos2.getX() == 15 && pos2.getZ() == 15) { | ||||||
|             for (int y = pos1.getY(); y <= pos2.getY(); y++) { |             for (int y = pos1.getY(); y <= pos2.getY(); y++) { | ||||||
|                 int layer = y >> 4; |                 int layer = getLayerIndex(y); | ||||||
|                 BlockState[] data = result[layer]; |                 BlockState[] data = result[layer]; | ||||||
|                 if (data == null) { |                 if (data == null) { | ||||||
|                     result[layer] = data = new BlockState[4096]; |                     result[layer] = data = new BlockState[4096]; | ||||||
| @@ -164,7 +172,7 @@ public class GenChunk extends ScopedQueueCoordinator { | |||||||
|      */ |      */ | ||||||
|     public boolean setBiome(int x, int z, @NonNull Biome biome) { |     public boolean setBiome(int x, int z, @NonNull Biome biome) { | ||||||
|         if (this.biomeGrid != null) { |         if (this.biomeGrid != null) { | ||||||
|             for (int y = 0; y < 256; y++) { |             for (int y = getMin().getY(); y <= getMax().getY(); y++) { | ||||||
|                 this.setBiome(x, y, z, biome); |                 this.setBiome(x, y, z, biome); | ||||||
|             } |             } | ||||||
|             return true; |             return true; | ||||||
| @@ -197,7 +205,7 @@ public class GenChunk extends ScopedQueueCoordinator { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void storeCache(final int x, final int y, final int z, final @NonNull BlockState id) { |     private void storeCache(final int x, final int y, final int z, final @NonNull BlockState id) { | ||||||
|         int i = y >> 4; |         int i = getLayerIndex(y); | ||||||
|         BlockState[] v = this.result[i]; |         BlockState[] v = this.result[i]; | ||||||
|         if (v == null) { |         if (v == null) { | ||||||
|             this.result[i] = v = new BlockState[4096]; |             this.result[i] = v = new BlockState[4096]; | ||||||
| @@ -219,7 +227,7 @@ public class GenChunk extends ScopedQueueCoordinator { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public @Nullable BlockState getBlock(int x, int y, int z) { |     public @Nullable BlockState getBlock(int x, int y, int z) { | ||||||
|         int i = y >> 4; |         int i = getLayerIndex(y); | ||||||
|         if (result == null) { |         if (result == null) { | ||||||
|             return BukkitBlockUtil.get(chunkData.getType(x, y, z)); |             return BukkitBlockUtil.get(chunkData.getType(x, y, z)); | ||||||
|         } |         } | ||||||
| @@ -246,16 +254,16 @@ public class GenChunk extends ScopedQueueCoordinator { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public @NonNull Location getMax() { |     public @NonNull Location getMax() { | ||||||
|         return Location.at(getWorld().getName(), 15 + (getX() << 4), 255, 15 + (getZ() << 4)); |         return Location.at(getWorld().getName(), 15 + (getX() << 4), super.getMax().getY(), 15 + (getZ() << 4)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public @NonNull Location getMin() { |     public @NonNull Location getMin() { | ||||||
|         return Location.at(getWorld().getName(), getX() << 4, 0, getZ() << 4); |         return Location.at(getWorld().getName(), getX() << 4, super.getMin().getY(), getZ() << 4); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public @NonNull GenChunk clone() { |     public @NonNull GenChunk clone() { | ||||||
|         GenChunk toReturn = new GenChunk(); |         GenChunk toReturn = new GenChunk(getMin().getY(), getMax().getY()); | ||||||
|         if (this.result != null) { |         if (this.result != null) { | ||||||
|             for (int i = 0; i < this.result.length; i++) { |             for (int i = 0; i < this.result.length; i++) { | ||||||
|                 BlockState[] matrix = this.result[i]; |                 BlockState[] matrix = this.result[i]; | ||||||
| @@ -269,4 +277,8 @@ public class GenChunk extends ScopedQueueCoordinator { | |||||||
|         return toReturn; |         return toReturn; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private int getLayerIndex(int y) { | ||||||
|  |         return (y - getMin().getY()) >> 4; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,128 @@ | |||||||
|  | /* | ||||||
|  |  *       _____  _       _    _____                                _ | ||||||
|  |  *      |  __ \| |     | |  / ____|                              | | | ||||||
|  |  *      | |__) | | ___ | |_| (___   __ _ _   _  __ _ _ __ ___  __| | | ||||||
|  |  *      |  ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | | ||||||
|  |  *      | |    | | (_) | |_ ____) | (_| | |_| | (_| | | |  __/ (_| | | ||||||
|  |  *      |_|    |_|\___/ \__|_____/ \__, |\__,_|\__,_|_|  \___|\__,_| | ||||||
|  |  *                                    | | | ||||||
|  |  *                                    |_| | ||||||
|  |  *            PlotSquared plot management system for Minecraft | ||||||
|  |  *               Copyright (C) 2014 - 2022 IntellectualSites | ||||||
|  |  * | ||||||
|  |  *     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.queue; | ||||||
|  |  | ||||||
|  | import com.plotsquared.bukkit.schematic.StateWrapper; | ||||||
|  | import com.plotsquared.core.queue.DelegateQueueCoordinator; | ||||||
|  | import com.sk89q.jnbt.CompoundTag; | ||||||
|  | import com.sk89q.worldedit.bukkit.BukkitAdapter; | ||||||
|  | import com.sk89q.worldedit.entity.Entity; | ||||||
|  | import com.sk89q.worldedit.function.pattern.Pattern; | ||||||
|  | import com.sk89q.worldedit.math.BlockVector3; | ||||||
|  | import com.sk89q.worldedit.world.block.BaseBlock; | ||||||
|  | import com.sk89q.worldedit.world.block.BlockState; | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  | import org.bukkit.Location; | ||||||
|  | import org.bukkit.entity.EntityType; | ||||||
|  | import org.bukkit.generator.LimitedRegion; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Wraps a {@link LimitedRegion} inside a {@link com.plotsquared.core.queue.QueueCoordinator} so it can be written to. | ||||||
|  |  * | ||||||
|  |  * @since TODO | ||||||
|  |  */ | ||||||
|  | public class LimitedRegionWrapperQueue extends DelegateQueueCoordinator { | ||||||
|  |  | ||||||
|  |     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + LimitedRegionWrapperQueue.class.getSimpleName()); | ||||||
|  |  | ||||||
|  |     private final LimitedRegion limitedRegion; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     public LimitedRegionWrapperQueue(LimitedRegion limitedRegion) { | ||||||
|  |         super(null); | ||||||
|  |         this.limitedRegion = limitedRegion; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setBlock(final int x, final int y, final int z, @NonNull final Pattern pattern) { | ||||||
|  |         return setBlock(x, y, z, pattern.applyBlock(BlockVector3.at(x, y, z))); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setBlock(final int x, final int y, final int z, @NonNull final BaseBlock id) { | ||||||
|  |         boolean result = setBlock(x, y, z, id.toImmutableState()); | ||||||
|  |         if (result && id.hasNbtData()) { | ||||||
|  |             CompoundTag tag = id.getNbtData(); | ||||||
|  |             StateWrapper sw = new StateWrapper(tag); | ||||||
|  |             try { | ||||||
|  |                 sw.restoreTag(limitedRegion.getBlockState(x, y, z).getBlock()); | ||||||
|  |             } catch (IllegalArgumentException e) { | ||||||
|  |                 LOGGER.error("Error attempting to populate tile entity into the world at location {},{},{}", x, y, z, e); | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return result; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setBlock(final int x, final int y, final int z, @NonNull final BlockState id) { | ||||||
|  |         try { | ||||||
|  |             limitedRegion.setType(x, y, z, BukkitAdapter.adapt(id.getBlockType())); | ||||||
|  |             limitedRegion.setBlockData(x, y, z, BukkitAdapter.adapt(id)); | ||||||
|  |         } catch (IllegalArgumentException e) { | ||||||
|  |             LOGGER.error("Error attempting to populate block into the world at location {},{},{}", x, y, z, e); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setEntity(@NonNull final Entity entity) { | ||||||
|  |         EntityType type = BukkitAdapter.adapt(entity.getState().getType()); | ||||||
|  |         double x = entity.getLocation().getX(); | ||||||
|  |         double y = entity.getLocation().getY(); | ||||||
|  |         double z = entity.getLocation().getZ(); | ||||||
|  |         Location location = new Location(limitedRegion.getWorld(), x, y, z); | ||||||
|  |         try { | ||||||
|  |             limitedRegion.spawnEntity(location, type); | ||||||
|  |         } catch (IllegalArgumentException e) { | ||||||
|  |             LOGGER.error("Error attempting to populate entity into the world at location {},{},{}", (int) x, (int) y, (int) z, e); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setTile(final int x, final int y, final int z, @NonNull final CompoundTag tag) { | ||||||
|  |         StateWrapper sw = new StateWrapper(tag); | ||||||
|  |         try { | ||||||
|  |             return sw.restoreTag(limitedRegion.getBlockState(x, y, z).getBlock()); | ||||||
|  |         } catch (IllegalArgumentException e) { | ||||||
|  |             LOGGER.error("Error attempting to populate tile entity into the world at location {},{},{}", x, y, z, e); | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean isSettingTiles() { | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -35,15 +35,18 @@ import com.sk89q.jnbt.Tag; | |||||||
| import com.sk89q.worldedit.blocks.BaseItemStack; | import com.sk89q.worldedit.blocks.BaseItemStack; | ||||||
| import com.sk89q.worldedit.bukkit.BukkitAdapter; | import com.sk89q.worldedit.bukkit.BukkitAdapter; | ||||||
| import com.sk89q.worldedit.world.item.ItemType; | import com.sk89q.worldedit.world.item.ItemType; | ||||||
|  | import org.bukkit.Bukkit; | ||||||
| import org.bukkit.ChatColor; | import org.bukkit.ChatColor; | ||||||
| import org.bukkit.World; | import org.bukkit.World; | ||||||
| import org.bukkit.block.Block; | import org.bukkit.block.Block; | ||||||
| import org.bukkit.block.Container; | import org.bukkit.block.Container; | ||||||
| import org.bukkit.block.Sign; | import org.bukkit.block.Sign; | ||||||
|  | import org.bukkit.block.Skull; | ||||||
| import org.bukkit.enchantments.Enchantment; | import org.bukkit.enchantments.Enchantment; | ||||||
| import org.bukkit.inventory.Inventory; | import org.bukkit.inventory.Inventory; | ||||||
| import org.bukkit.inventory.InventoryHolder; | import org.bukkit.inventory.InventoryHolder; | ||||||
| import org.bukkit.inventory.ItemStack; | import org.bukkit.inventory.ItemStack; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
| @@ -56,6 +59,11 @@ public class StateWrapper { | |||||||
|     public org.bukkit.block.BlockState state = null; |     public org.bukkit.block.BlockState state = null; | ||||||
|     public CompoundTag tag = null; |     public CompoundTag tag = null; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @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 = "TODO") | ||||||
|     public StateWrapper(org.bukkit.block.BlockState state) { |     public StateWrapper(org.bukkit.block.BlockState state) { | ||||||
|         this.state = state; |         this.state = state; | ||||||
|     } |     } | ||||||
| @@ -166,14 +174,32 @@ public class StateWrapper { | |||||||
|         return str; |         return str; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @SuppressWarnings("deprecation") // #setLine is needed for Spigot compatibility |     /** | ||||||
|  |      * Restore the TileEntity data to the given world at the given coordinates. | ||||||
|  |      * | ||||||
|  |      * @param worldName World name | ||||||
|  |      * @param x         x position | ||||||
|  |      * @param y         y position | ||||||
|  |      * @param z         z position | ||||||
|  |      * @return true if successful | ||||||
|  |      */ | ||||||
|     public boolean restoreTag(String worldName, int x, int y, int z) { |     public boolean restoreTag(String worldName, int x, int y, int z) { | ||||||
|         if (this.tag == null) { |         World world = BukkitUtil.getWorld(worldName); | ||||||
|  |         if (world == null) { | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         World world = BukkitUtil.getWorld(worldName); |         return restoreTag(world.getBlockAt(x, y, z)); | ||||||
|         Block block = world.getBlockAt(x, y, z); |     } | ||||||
|         if (block == null) { |  | ||||||
|  |     /** | ||||||
|  |      * Restore the TileEntity data to the given block | ||||||
|  |      * | ||||||
|  |      * @param block Block to restore to | ||||||
|  |      * @return true if successful | ||||||
|  |      */ | ||||||
|  |     @SuppressWarnings("deprecation") // #setLine is needed for Spigot compatibility | ||||||
|  |     public boolean restoreTag(@NonNull Block block) { | ||||||
|  |         if (this.tag == null) { | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         org.bukkit.block.BlockState state = block.getState(); |         org.bukkit.block.BlockState state = block.getState(); | ||||||
| @@ -211,10 +237,37 @@ public class StateWrapper { | |||||||
|                 } |                 } | ||||||
|                 return false; |                 return false; | ||||||
|             } |             } | ||||||
|  |             case "skull" -> { | ||||||
|  |                 if (state instanceof Skull skull) { | ||||||
|  |                     CompoundTag skullOwner = ((CompoundTag) this.tag.getValue().get("SkullOwner")); | ||||||
|  |                     if (skullOwner == null) { | ||||||
|  |                         return true; | ||||||
|  |                     } | ||||||
|  |                     String player = skullOwner.getString("Name"); | ||||||
|  |                     if (player == null || player.isEmpty()) { | ||||||
|  |                         return false; | ||||||
|  |                     } | ||||||
|  |                     try { | ||||||
|  |                         skull.setOwningPlayer(Bukkit.getOfflinePlayer(player)); | ||||||
|  |                         skull.update(true); | ||||||
|  |                     } catch (Exception e) { | ||||||
|  |                         e.printStackTrace(); | ||||||
|  |                     } | ||||||
|  |                     return true; | ||||||
|  |                 } | ||||||
|  |                 return false; | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|         return false; |         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 = "TODO") | ||||||
|     public CompoundTag getTag() { |     public CompoundTag getTag() { | ||||||
|         if (this.tag != null) { |         if (this.tag != null) { | ||||||
|             return this.tag; |             return this.tag; | ||||||
|   | |||||||
| @@ -40,7 +40,6 @@ import com.plotsquared.core.queue.QueueCoordinator; | |||||||
| import com.plotsquared.core.queue.ScopedQueueCoordinator; | import com.plotsquared.core.queue.ScopedQueueCoordinator; | ||||||
| import com.plotsquared.core.util.ChunkManager; | import com.plotsquared.core.util.ChunkManager; | ||||||
| import com.plotsquared.core.util.RegionManager; | import com.plotsquared.core.util.RegionManager; | ||||||
| import com.plotsquared.core.util.RegionUtil; |  | ||||||
| import com.plotsquared.core.util.WorldUtil; | import com.plotsquared.core.util.WorldUtil; | ||||||
| import com.plotsquared.core.util.entity.EntityCategories; | import com.plotsquared.core.util.entity.EntityCategories; | ||||||
| import com.plotsquared.core.util.task.RunnableVal; | import com.plotsquared.core.util.task.RunnableVal; | ||||||
| @@ -261,7 +260,7 @@ public class BukkitRegionManager extends RegionManager { | |||||||
|             if (checkX2 && checkZ2) { |             if (checkX2 && checkZ2) { | ||||||
|                 map.saveRegion(world, xxt2, xxt, zzt2, zzt); // |                 map.saveRegion(world, xxt2, xxt, zzt2, zzt); // | ||||||
|             } |             } | ||||||
|             CuboidRegion currentPlotClear = RegionUtil.createRegion(pos1.getX(), pos2.getX(), pos1.getZ(), pos2.getZ()); |             CuboidRegion currentPlotClear = new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()); | ||||||
|             map.saveEntitiesOut(Bukkit.getWorld(world.getName()).getChunkAt(x, z), currentPlotClear); |             map.saveEntitiesOut(Bukkit.getWorld(world.getName()).getChunkAt(x, z), currentPlotClear); | ||||||
|             AugmentedUtils.bypass( |             AugmentedUtils.bypass( | ||||||
|                     ignoreAugment, |                     ignoreAugment, | ||||||
| @@ -276,20 +275,16 @@ public class BukkitRegionManager extends RegionManager { | |||||||
|                                     PlotLoc plotLoc = new PlotLoc(bx + x1, bz + z1); |                                     PlotLoc plotLoc = new PlotLoc(bx + x1, bz + z1); | ||||||
|                                     BaseBlock[] ids = map.allBlocks.get(plotLoc); |                                     BaseBlock[] ids = map.allBlocks.get(plotLoc); | ||||||
|                                     if (ids != null) { |                                     if (ids != null) { | ||||||
|                                         for (int y = 0; y < Math.min(128, ids.length); y++) { |                                         int minY = value.getMin().getY(); | ||||||
|                                             BaseBlock id = ids[y]; |                                         for (int yIndex = 0; yIndex < ids.length; yIndex++) { | ||||||
|  |                                             int y = yIndex + minY; | ||||||
|  |                                             BaseBlock id = ids[yIndex]; | ||||||
|                                             if (id != null) { |                                             if (id != null) { | ||||||
|                                                 value.setBlock(x1, y, z1, id); |                                                 value.setBlock(x1, y, z1, id); | ||||||
|                                             } else { |                                             } else { | ||||||
|                                                 value.setBlock(x1, y, z1, BlockTypes.AIR.getDefaultState()); |                                                 value.setBlock(x1, y, z1, BlockTypes.AIR.getDefaultState()); | ||||||
|                                             } |                                             } | ||||||
|                                         } |                                         } | ||||||
|                                         for (int y = Math.min(128, ids.length); y < ids.length; y++) { |  | ||||||
|                                             BaseBlock id = ids[y]; |  | ||||||
|                                             if (id != null) { |  | ||||||
|                                                 value.setBlock(x1, y, z1, id); |  | ||||||
|                                             } |  | ||||||
|                                         } |  | ||||||
|                                     } |                                     } | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
| @@ -297,7 +292,7 @@ public class BukkitRegionManager extends RegionManager { | |||||||
|                     }, world.getName(), chunk) |                     }, world.getName(), chunk) | ||||||
|             ); |             ); | ||||||
|             //map.restoreBlocks(worldObj, 0, 0); |             //map.restoreBlocks(worldObj, 0, 0); | ||||||
|             map.restoreEntities(Bukkit.getWorld(world.getName()), 0, 0); |             map.restoreEntities(Bukkit.getWorld(world.getName())); | ||||||
|         }); |         }); | ||||||
|         regenQueue.setCompleteTask(whenDone); |         regenQueue.setCompleteTask(whenDone); | ||||||
|         queue.setCompleteTask(regenQueue::enqueue); |         queue.setCompleteTask(regenQueue::enqueue); | ||||||
|   | |||||||
| @@ -76,7 +76,7 @@ public class BukkitSetupUtils extends SetupUtils { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void updateGenerators(final boolean force) { |     public void updateGenerators(final boolean force) { | ||||||
|         if (!SetupUtils.generators.isEmpty() && !force) { |         if (loaded && !SetupUtils.generators.isEmpty() && !force) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         String testWorld = "CheckingPlotSquaredGenerator"; |         String testWorld = "CheckingPlotSquaredGenerator"; | ||||||
| @@ -100,6 +100,7 @@ public class BukkitSetupUtils extends SetupUtils { | |||||||
|                 e.printStackTrace(); |                 e.printStackTrace(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         loaded = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
| @@ -44,7 +44,6 @@ import com.plotsquared.core.util.task.TaskManager; | |||||||
| import com.sk89q.worldedit.bukkit.BukkitAdapter; | import com.sk89q.worldedit.bukkit.BukkitAdapter; | ||||||
| import com.sk89q.worldedit.bukkit.BukkitWorld; | import com.sk89q.worldedit.bukkit.BukkitWorld; | ||||||
| import com.sk89q.worldedit.math.BlockVector2; | import com.sk89q.worldedit.math.BlockVector2; | ||||||
| import com.sk89q.worldedit.regions.CuboidRegion; |  | ||||||
| import com.sk89q.worldedit.world.biome.BiomeType; | import com.sk89q.worldedit.world.biome.BiomeType; | ||||||
| import com.sk89q.worldedit.world.block.BlockCategories; | import com.sk89q.worldedit.world.block.BlockCategories; | ||||||
| import com.sk89q.worldedit.world.block.BlockState; | import com.sk89q.worldedit.world.block.BlockState; | ||||||
| @@ -61,7 +60,6 @@ import org.bukkit.Bukkit; | |||||||
| import org.bukkit.Chunk; | import org.bukkit.Chunk; | ||||||
| import org.bukkit.Material; | import org.bukkit.Material; | ||||||
| import org.bukkit.World; | import org.bukkit.World; | ||||||
| import org.bukkit.block.Biome; |  | ||||||
| import org.bukkit.block.Block; | import org.bukkit.block.Block; | ||||||
| import org.bukkit.block.BlockFace; | import org.bukkit.block.BlockFace; | ||||||
| import org.bukkit.block.Sign; | import org.bukkit.block.Sign; | ||||||
| @@ -246,7 +244,9 @@ public class BukkitUtil extends WorldUtil { | |||||||
|             final World bukkitWorld = Objects.requireNonNull(getWorld(world)); |             final World bukkitWorld = Objects.requireNonNull(getWorld(world)); | ||||||
|             // Skip top and bottom block |             // Skip top and bottom block | ||||||
|             int air = 1; |             int air = 1; | ||||||
|             for (int y = bukkitWorld.getMaxHeight() - 1; y >= 0; y--) { |             int maxY = com.plotsquared.bukkit.util.BukkitWorld.getMaxWorldHeight(bukkitWorld); | ||||||
|  |             int minY = com.plotsquared.bukkit.util.BukkitWorld.getMinWorldHeight(bukkitWorld); | ||||||
|  |             for (int y = maxY - 1; y >= minY; y--) { | ||||||
|                 Block block = bukkitWorld.getBlockAt(x, y, z); |                 Block block = bukkitWorld.getBlockAt(x, y, z); | ||||||
|                 Material type = block.getType(); |                 Material type = block.getType(); | ||||||
|                 if (type.isSolid()) { |                 if (type.isSolid()) { | ||||||
| @@ -273,7 +273,9 @@ public class BukkitUtil extends WorldUtil { | |||||||
|         final World bukkitWorld = Objects.requireNonNull(getWorld(world)); |         final World bukkitWorld = Objects.requireNonNull(getWorld(world)); | ||||||
|         // Skip top and bottom block |         // Skip top and bottom block | ||||||
|         int air = 1; |         int air = 1; | ||||||
|         for (int y = bukkitWorld.getMaxHeight() - 1; y >= 0; y--) { |         int maxY = com.plotsquared.bukkit.util.BukkitWorld.getMaxWorldHeight(bukkitWorld); | ||||||
|  |         int minY = com.plotsquared.bukkit.util.BukkitWorld.getMinWorldHeight(bukkitWorld); | ||||||
|  |         for (int y = maxY - 1; y >= minY; y--) { | ||||||
|             Block block = bukkitWorld.getBlockAt(x, y, z); |             Block block = bukkitWorld.getBlockAt(x, y, z); | ||||||
|             Material type = block.getType(); |             Material type = block.getType(); | ||||||
|             if (type.isSolid()) { |             if (type.isSolid()) { | ||||||
| @@ -345,14 +347,16 @@ public class BukkitUtil extends WorldUtil { | |||||||
|             final Block block = world.getBlockAt(location.getX(), location.getY(), location.getZ()); |             final Block block = world.getBlockAt(location.getX(), location.getY(), location.getZ()); | ||||||
|             final Material type = block.getType(); |             final Material type = block.getType(); | ||||||
|             if (type != Material.LEGACY_SIGN && type != Material.LEGACY_WALL_SIGN) { |             if (type != Material.LEGACY_SIGN && type != Material.LEGACY_WALL_SIGN) { | ||||||
|                 BlockFace facing = BlockFace.EAST; |                 BlockFace facing = BlockFace.NORTH; | ||||||
|                 if (world.getBlockAt(location.getX(), location.getY(), location.getZ() + 1).getType().isSolid()) { |                 if (!world.getBlockAt(location.getX(), location.getY(), location.getZ() + 1).getType().isSolid()) { | ||||||
|                     facing = BlockFace.NORTH; |                     if (world.getBlockAt(location.getX() - 1, location.getY(), location.getZ()).getType().isSolid()) { | ||||||
|  |                         facing = BlockFace.EAST; | ||||||
|                     } else if (world.getBlockAt(location.getX() + 1, location.getY(), location.getZ()).getType().isSolid()) { |                     } else if (world.getBlockAt(location.getX() + 1, location.getY(), location.getZ()).getType().isSolid()) { | ||||||
|                         facing = BlockFace.WEST; |                         facing = BlockFace.WEST; | ||||||
|                     } else if (world.getBlockAt(location.getX(), location.getY(), location.getZ() - 1).getType().isSolid()) { |                     } else if (world.getBlockAt(location.getX(), location.getY(), location.getZ() - 1).getType().isSolid()) { | ||||||
|                         facing = BlockFace.SOUTH; |                         facing = BlockFace.SOUTH; | ||||||
|                     } |                     } | ||||||
|  |                 } | ||||||
|                 if (PlotSquared.platform().serverVersion()[1] == 13) { |                 if (PlotSquared.platform().serverVersion()[1] == 13) { | ||||||
|                     block.setType(Material.valueOf(area.legacySignMaterial()), false); |                     block.setType(Material.valueOf(area.legacySignMaterial()), false); | ||||||
|                 } else { |                 } else { | ||||||
| @@ -371,7 +375,7 @@ public class BukkitUtil extends WorldUtil { | |||||||
|                     sign.setLine(i, LEGACY_COMPONENT_SERIALIZER |                     sign.setLine(i, LEGACY_COMPONENT_SERIALIZER | ||||||
|                             .serialize(MINI_MESSAGE.parse(lines[i].getComponent(LocaleHolder.console()), replacements))); |                             .serialize(MINI_MESSAGE.parse(lines[i].getComponent(LocaleHolder.console()), replacements))); | ||||||
|                 } |                 } | ||||||
|                 sign.update(true); |                 sign.update(true, false); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| @@ -382,27 +386,6 @@ public class BukkitUtil extends WorldUtil { | |||||||
|         return new StringComparison<BlockState>().new ComparisonResult(1, state); |         return new StringComparison<BlockState>().new ComparisonResult(1, state); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |  | ||||||
|     public void setBiomes( |  | ||||||
|             final @NonNull String worldName, |  | ||||||
|             final @NonNull CuboidRegion region, |  | ||||||
|             final @NonNull BiomeType biomeType |  | ||||||
|     ) { |  | ||||||
|         final World world = getWorld(worldName); |  | ||||||
|         if (world == null) { |  | ||||||
|             LOGGER.warn("An error occurred while setting the biome because the world was null", new RuntimeException()); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         final Biome biome = BukkitAdapter.adapt(biomeType); |  | ||||||
|         for (int x = region.getMinimumPoint().getX(); x <= region.getMaximumPoint().getX(); x++) { |  | ||||||
|             for (int z = region.getMinimumPoint().getZ(); z <= region.getMaximumPoint().getZ(); z++) { |  | ||||||
|                 if (world.getBiome(x, z) != biome) { |  | ||||||
|                     world.setBiome(x, z, biome); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public com.sk89q.worldedit.world.@NonNull World getWeWorld(final @NonNull String world) { |     public com.sk89q.worldedit.world.@NonNull World getWeWorld(final @NonNull String world) { | ||||||
|         return new BukkitWorld(Bukkit.getWorld(world)); |         return new BukkitWorld(Bukkit.getWorld(world)); | ||||||
|   | |||||||
| @@ -36,6 +36,18 @@ import java.util.Objects; | |||||||
| public class BukkitWorld implements World<org.bukkit.World> { | public class BukkitWorld implements World<org.bukkit.World> { | ||||||
|  |  | ||||||
|     private static final Map<String, BukkitWorld> worldMap = Maps.newHashMap(); |     private static final Map<String, BukkitWorld> worldMap = Maps.newHashMap(); | ||||||
|  |     private static final boolean HAS_MIN_Y; | ||||||
|  |  | ||||||
|  |     static { | ||||||
|  |         boolean temp; | ||||||
|  |         try { | ||||||
|  |             org.bukkit.World.class.getMethod("getMinHeight"); | ||||||
|  |             temp = true; | ||||||
|  |         } catch (NoSuchMethodException e) { | ||||||
|  |             temp = false; | ||||||
|  |         } | ||||||
|  |         HAS_MIN_Y = temp; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private final org.bukkit.World world; |     private final org.bukkit.World world; | ||||||
|  |  | ||||||
| @@ -73,6 +85,24 @@ public class BukkitWorld implements World<org.bukkit.World> { | |||||||
|         return bukkitWorld; |         return bukkitWorld; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the min world height from a Bukkit {@link org.bukkit.World}. Inclusive | ||||||
|  |      * | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      */ | ||||||
|  |     public static int getMinWorldHeight(org.bukkit.World world) { | ||||||
|  |         return HAS_MIN_Y ? world.getMinHeight() : 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the max world height from a Bukkit {@link org.bukkit.World}. Exclusive | ||||||
|  |      * | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      */ | ||||||
|  |     public static int getMaxWorldHeight(org.bukkit.World world) { | ||||||
|  |         return HAS_MIN_Y ? world.getMaxHeight() : 256; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public org.bukkit.World getPlatformWorld() { |     public org.bukkit.World getPlatformWorld() { | ||||||
|         return this.world; |         return this.world; | ||||||
| @@ -83,6 +113,16 @@ public class BukkitWorld implements World<org.bukkit.World> { | |||||||
|         return this.world.getName(); |         return this.world.getName(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int getMinHeight() { | ||||||
|  |         return getMinWorldHeight(world); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int getMaxHeight() { | ||||||
|  |         return getMaxWorldHeight(world) - 1; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean equals(final Object o) { |     public boolean equals(final Object o) { | ||||||
|         if (this == o) { |         if (this == o) { | ||||||
| @@ -103,7 +143,7 @@ public class BukkitWorld implements World<org.bukkit.World> { | |||||||
|     /** |     /** | ||||||
|      * @deprecated This method is not meant to be invoked or overridden, with no replacement. |      * @deprecated This method is not meant to be invoked or overridden, with no replacement. | ||||||
|      */ |      */ | ||||||
|     @Deprecated(forRemoval = true, since = "TODO") |     @Deprecated(forRemoval = true, since = "6.6.0") | ||||||
|     protected boolean canEqual(final Object other) { |     protected boolean canEqual(final Object other) { | ||||||
|         return other instanceof BukkitWorld; |         return other instanceof BukkitWorld; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -70,7 +70,7 @@ public class ContentMap { | |||||||
|         } |         } | ||||||
|         for (int x = x1; x <= x2; x++) { |         for (int x = x1; x <= x2; x++) { | ||||||
|             for (int z = z1; z <= z2; z++) { |             for (int z = z1; z <= z2; z++) { | ||||||
|                 saveBlocks(world, 256, x, z, 0, 0); |                 saveBlocks(world, x, z); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| @@ -92,14 +92,7 @@ public class ContentMap { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void saveEntitiesIn(Chunk chunk, CuboidRegion region) { |     void saveEntitiesIn(Chunk chunk, CuboidRegion region, boolean delete) { | ||||||
|         saveEntitiesIn(chunk, region, 0, 0, false); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     void saveEntitiesIn( |  | ||||||
|             Chunk chunk, CuboidRegion region, int offsetX, int offsetZ, |  | ||||||
|             boolean delete |  | ||||||
|     ) { |  | ||||||
|         for (Entity entity : chunk.getEntities()) { |         for (Entity entity : chunk.getEntities()) { | ||||||
|             Location location = BukkitUtil.adapt(entity.getLocation()); |             Location location = BukkitUtil.adapt(entity.getLocation()); | ||||||
|             int x = location.getX(); |             int x = location.getX(); | ||||||
| @@ -111,8 +104,6 @@ public class ContentMap { | |||||||
|                 continue; |                 continue; | ||||||
|             } |             } | ||||||
|             EntityWrapper wrap = new ReplicatingEntityWrapper(entity, (short) 2); |             EntityWrapper wrap = new ReplicatingEntityWrapper(entity, (short) 2); | ||||||
|             wrap.x += offsetX; |  | ||||||
|             wrap.z += offsetZ; |  | ||||||
|             wrap.saveEntity(); |             wrap.saveEntity(); | ||||||
|             this.entities.add(wrap); |             this.entities.add(wrap); | ||||||
|             if (delete) { |             if (delete) { | ||||||
| @@ -123,10 +114,10 @@ public class ContentMap { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     void restoreEntities(World world, int xOffset, int zOffset) { |     void restoreEntities(World world) { | ||||||
|         for (EntityWrapper entity : this.entities) { |         for (EntityWrapper entity : this.entities) { | ||||||
|             try { |             try { | ||||||
|                 entity.spawn(world, xOffset, zOffset); |                 entity.spawn(world, 0, 0); | ||||||
|             } catch (Exception e) { |             } catch (Exception e) { | ||||||
|                 LOGGER.error("Failed to restore entity", e); |                 LOGGER.error("Failed to restore entity", e); | ||||||
|             } |             } | ||||||
| @@ -134,15 +125,13 @@ public class ContentMap { | |||||||
|         this.entities.clear(); |         this.entities.clear(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     //todo optimize maxY |     private void saveBlocks(BukkitWorld world, int x, int z) { | ||||||
|     void saveBlocks(BukkitWorld world, int maxY, int x, int z, int offsetX, int offsetZ) { |         BaseBlock[] ids = new BaseBlock[world.getMaxY() - world.getMinY() + 1]; | ||||||
|         maxY = Math.min(255, maxY); |         for (short yIndex = 0; yIndex <= world.getMaxY() - world.getMinY(); yIndex++) { | ||||||
|         BaseBlock[] ids = new BaseBlock[maxY + 1]; |             BaseBlock block = world.getFullBlock(BlockVector3.at(x, yIndex + world.getMinY(), z)); | ||||||
|         for (short y = 0; y <= maxY; y++) { |             ids[yIndex] = block; | ||||||
|             BaseBlock block = world.getFullBlock(BlockVector3.at(x, y, z)); |  | ||||||
|             ids[y] = block; |  | ||||||
|         } |         } | ||||||
|         PlotLoc loc = new PlotLoc(x + offsetX, z + offsetZ); |         PlotLoc loc = new PlotLoc(x, z); | ||||||
|         this.allBlocks.put(loc, ids); |         this.allBlocks.put(loc, ids); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -110,6 +110,11 @@ public class FaweRegionManager extends BukkitRegionManager { | |||||||
|         delegate.setBiome(region, extendBiome, biome, world, 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); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean copyRegion( |     public boolean copyRegion( | ||||||
|             final @NonNull Location pos1, |             final @NonNull Location pos1, | ||||||
|   | |||||||
| @@ -67,7 +67,7 @@ public class FaweSchematicHandler extends SchematicHandler { | |||||||
|             final PlotPlayer<?> actor, |             final PlotPlayer<?> actor, | ||||||
|             final RunnableVal<Boolean> whenDone |             final RunnableVal<Boolean> whenDone | ||||||
|     ) { |     ) { | ||||||
|         delegate.paste(schematic, plot, xOffset, yOffset, zOffset, autoHeight, whenDone); |         delegate.paste(schematic, plot, xOffset, yOffset, zOffset, autoHeight, actor, whenDone); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
| @@ -55,7 +55,7 @@ further defined and clarified by project maintainers. | |||||||
| ## Enforcement | ## Enforcement | ||||||
|  |  | ||||||
| Instances of abusive, harassing, or otherwise unacceptable behavior may be | Instances of abusive, harassing, or otherwise unacceptable behavior may be | ||||||
| reported by contacting the project team at contact@alexander-soderberg.com. All | reported by contacting the project team at contact@intellectualsites.com. All | ||||||
| complaints will be reviewed and investigated and will result in a response that | complaints will be reviewed and investigated and will result in a response that | ||||||
| is deemed necessary and appropriate to the circumstances. The project team is | is deemed necessary and appropriate to the circumstances. The project team is | ||||||
| obligated to maintain confidentiality with regard to the reporter of an incident. | obligated to maintain confidentiality with regard to the reporter of an incident. | ||||||
|   | |||||||
| @@ -2,18 +2,18 @@ import java.time.format.DateTimeFormatter | |||||||
|  |  | ||||||
| dependencies { | dependencies { | ||||||
|     // Expected everywhere. |     // Expected everywhere. | ||||||
|     compileOnlyApi(libs.checkerqual) |     compileOnlyApi("org.checkerframework:checker-qual") | ||||||
|  |  | ||||||
|     // Minecraft expectations |     // Minecraft expectations | ||||||
|     compileOnlyApi(libs.gson) |     compileOnlyApi("com.google.code.gson:gson") | ||||||
|     compileOnly(libs.guava) |     compileOnly("com.google.guava:guava") | ||||||
|  |  | ||||||
|     // Platform expectations |     // Platform expectations | ||||||
|     compileOnlyApi(libs.snakeyaml) |     compileOnlyApi("org.yaml:snakeyaml") | ||||||
|  |  | ||||||
|     // Adventure |     // Adventure | ||||||
|     api(libs.adventure) |     api("net.kyori:adventure-api") | ||||||
|     api(libs.minimessage) |     api("net.kyori:adventure-text-minimessage") | ||||||
|  |  | ||||||
|     // Guice |     // Guice | ||||||
|     api(libs.guice) { |     api(libs.guice) { | ||||||
| @@ -22,7 +22,7 @@ dependencies { | |||||||
|     api(libs.guiceassistedinject) { |     api(libs.guiceassistedinject) { | ||||||
|         exclude("com.google.inject", "guice") |         exclude("com.google.inject", "guice") | ||||||
|     } |     } | ||||||
|     api(libs.findbugs) |     api(libs.spotbugs) | ||||||
|  |  | ||||||
|     // Plugins |     // Plugins | ||||||
|     compileOnly(libs.worldeditCore) { |     compileOnly(libs.worldeditCore) { | ||||||
| @@ -31,18 +31,18 @@ dependencies { | |||||||
|         exclude(group = "dummypermscompat") |         exclude(group = "dummypermscompat") | ||||||
|     } |     } | ||||||
|     testImplementation(libs.worldeditCore) |     testImplementation(libs.worldeditCore) | ||||||
|     compileOnly(libs.fastasyncworldeditCore) { isTransitive = false } |     compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Core") { isTransitive = false } | ||||||
|     testImplementation(libs.fastasyncworldeditCore) { isTransitive = false } |     testImplementation("com.fastasyncworldedit:FastAsyncWorldEdit-Core") { isTransitive = false } | ||||||
|  |  | ||||||
|     // Logging |     // Logging | ||||||
|     compileOnlyApi(libs.log4j) |     compileOnlyApi("org.apache.logging.log4j:log4j-api") | ||||||
|  |  | ||||||
|     // Other libraries |     // Other libraries | ||||||
|     api(libs.prtree) |     api(libs.prtree) | ||||||
|     api(libs.aopalliance) |     api(libs.aopalliance) | ||||||
|     api(libs.cloudServices) |     api(libs.cloudServices) | ||||||
|     api(libs.arkitektonika) |     api(libs.arkitektonika) | ||||||
|     api(libs.paster) |     api("com.intellectualsites.paster:Paster") | ||||||
| } | } | ||||||
|  |  | ||||||
| tasks.processResources { | tasks.processResources { | ||||||
|   | |||||||
| @@ -98,6 +98,22 @@ public interface PlotPlatform<P> extends LocaleHolder { | |||||||
|      */ |      */ | ||||||
|     int[] serverVersion(); |     int[] serverVersion(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Gets the default minimum world height for the version of Minecraft that the server is running. | ||||||
|  |      * | ||||||
|  |      * @return minimum world height | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      */ | ||||||
|  |     int versionMinHeight(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Gets the default maximum world height for the version of Minecraft that the server is running. | ||||||
|  |      * | ||||||
|  |      * @return maximum world height (inclusive) | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      */ | ||||||
|  |     int versionMaxHeight(); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Gets the server implementation name and version |      * Gets the server implementation name and version | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -889,8 +889,8 @@ public class PlotSquared { | |||||||
|                             e.printStackTrace(); |                             e.printStackTrace(); | ||||||
|                         } |                         } | ||||||
|                         LOGGER.info("| generator: {}>{}", baseGenerator, areaGen); |                         LOGGER.info("| generator: {}>{}", baseGenerator, areaGen); | ||||||
|                         LOGGER.info("| plot world: {}", pa); |                         LOGGER.info("| plot world: {}", pa.getClass().getCanonicalName()); | ||||||
|                         LOGGER.info("| manager: {}", pa); |                         LOGGER.info("| manager: {}", pa.getPlotManager().getClass().getCanonicalName()); | ||||||
|                         LOGGER.info("Note: Area created for cluster '{}' (invalid or old configuration?)", name); |                         LOGGER.info("Note: Area created for cluster '{}' (invalid or old configuration?)", name); | ||||||
|                         areaGen.getPlotGenerator().initialize(pa); |                         areaGen.getPlotGenerator().initialize(pa); | ||||||
|                         areaGen.augment(pa); |                         areaGen.augment(pa); | ||||||
| @@ -906,6 +906,13 @@ public class PlotSquared { | |||||||
|                     throw new IllegalArgumentException("Invalid Generator: " + gen_string); |                     throw new IllegalArgumentException("Invalid Generator: " + gen_string); | ||||||
|                 } |                 } | ||||||
|                 PlotArea pa = areaGen.getPlotGenerator().getNewPlotArea(world, null, null, null); |                 PlotArea pa = areaGen.getPlotGenerator().getNewPlotArea(world, null, null, null); | ||||||
|  |                 LOGGER.info("- generator: {}>{}", baseGenerator, areaGen); | ||||||
|  |                 LOGGER.info("- plot world: {}", pa.getClass().getCanonicalName()); | ||||||
|  |                 LOGGER.info("- plot area manager: {}", pa.getPlotManager().getClass().getCanonicalName()); | ||||||
|  |                 if (!this.worldConfiguration.contains(path)) { | ||||||
|  |                     this.worldConfiguration.createSection(path); | ||||||
|  |                     worldSection = this.worldConfiguration.getConfigurationSection(path); | ||||||
|  |                 } | ||||||
|                 pa.saveConfiguration(worldSection); |                 pa.saveConfiguration(worldSection); | ||||||
|                 pa.loadDefaultConfiguration(worldSection); |                 pa.loadDefaultConfiguration(worldSection); | ||||||
|                 try { |                 try { | ||||||
| @@ -913,9 +920,6 @@ public class PlotSquared { | |||||||
|                 } catch (IOException e) { |                 } catch (IOException e) { | ||||||
|                     e.printStackTrace(); |                     e.printStackTrace(); | ||||||
|                 } |                 } | ||||||
|                 LOGGER.info("- generator: {}>{}", baseGenerator, areaGen); |  | ||||||
|                 LOGGER.info("- plot world: {}", pa); |  | ||||||
|                 LOGGER.info("- plot area manager: {}", pa.getPlotManager()); |  | ||||||
|                 areaGen.getPlotGenerator().initialize(pa); |                 areaGen.getPlotGenerator().initialize(pa); | ||||||
|                 areaGen.augment(pa); |                 areaGen.augment(pa); | ||||||
|                 addPlotArea(pa); |                 addPlotArea(pa); | ||||||
| @@ -1020,8 +1024,8 @@ public class PlotSquared { | |||||||
|             // save configuration |             // save configuration | ||||||
|  |  | ||||||
|             final List<String> validArguments = Arrays |             final List<String> validArguments = Arrays | ||||||
|                     .asList("s=", "size=", "g=", "gap=", "h=", "height=", "f=", "floor=", "m=", "main=", |                     .asList("s=", "size=", "g=", "gap=", "h=", "height=", "minh=", "minheight=", "maxh=", "maxheight=", | ||||||
|                             "w=", "wall=", "b=", "border=" |                             "f=", "floor=", "m=", "main=", "w=", "wall=", "b=", "border=" | ||||||
|                     ); |                     ); | ||||||
|  |  | ||||||
|             // Calculate the number of expected arguments |             // Calculate the number of expected arguments | ||||||
| @@ -1100,6 +1104,14 @@ public class PlotSquared { | |||||||
|                                     ConfigurationUtil.INTEGER.parseString(value).shortValue() |                                     ConfigurationUtil.INTEGER.parseString(value).shortValue() | ||||||
|                             ); |                             ); | ||||||
|                         } |                         } | ||||||
|  |                         case "minh", "minheight" -> this.worldConfiguration.set( | ||||||
|  |                                 base + "world.min_gen_height", | ||||||
|  |                                 ConfigurationUtil.INTEGER.parseString(value).shortValue() | ||||||
|  |                         ); | ||||||
|  |                         case "maxh", "maxheight" -> this.worldConfiguration.set( | ||||||
|  |                                 base + "world.max_gen_height", | ||||||
|  |                                 ConfigurationUtil.INTEGER.parseString(value).shortValue() | ||||||
|  |                         ); | ||||||
|                         case "f", "floor" -> this.worldConfiguration.set( |                         case "f", "floor" -> this.worldConfiguration.set( | ||||||
|                                 base + "plot.floor", |                                 base + "plot.floor", | ||||||
|                                 ConfigurationUtil.BLOCK_BUCKET.parseString(value).toString() |                                 ConfigurationUtil.BLOCK_BUCKET.parseString(value).toString() | ||||||
|   | |||||||
| @@ -75,6 +75,7 @@ import com.sk89q.worldedit.function.operation.Operations; | |||||||
| import com.sk89q.worldedit.math.BlockVector3; | import com.sk89q.worldedit.math.BlockVector3; | ||||||
| import com.sk89q.worldedit.regions.CuboidRegion; | import com.sk89q.worldedit.regions.CuboidRegion; | ||||||
| import com.sk89q.worldedit.regions.Region; | import com.sk89q.worldedit.regions.Region; | ||||||
|  | import com.sk89q.worldedit.world.World; | ||||||
| import net.kyori.adventure.text.minimessage.Template; | import net.kyori.adventure.text.minimessage.Template; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
| @@ -191,11 +192,12 @@ public class Area extends SubCommand { | |||||||
|                 final BlockVector3 playerSelectionMin = playerSelectedRegion.getMinimumPoint(); |                 final BlockVector3 playerSelectionMin = playerSelectedRegion.getMinimumPoint(); | ||||||
|                 final BlockVector3 playerSelectionMax = playerSelectedRegion.getMaximumPoint(); |                 final BlockVector3 playerSelectionMax = playerSelectedRegion.getMaximumPoint(); | ||||||
|                 // Create a new selection that spans the entire vertical range of the world |                 // Create a new selection that spans the entire vertical range of the world | ||||||
|  |                 World world = playerSelectedRegion.getWorld(); | ||||||
|                 final CuboidRegion selectedRegion = |                 final CuboidRegion selectedRegion = | ||||||
|                         new CuboidRegion( |                         new CuboidRegion( | ||||||
|                                 playerSelectedRegion.getWorld(), |                                 playerSelectedRegion.getWorld(), | ||||||
|                                 BlockVector3.at(playerSelectionMin.getX(), 0, playerSelectionMin.getZ()), |                                 BlockVector3.at(playerSelectionMin.getX(), world.getMinY(), playerSelectionMin.getZ()), | ||||||
|                                 BlockVector3.at(playerSelectionMax.getX(), 255, playerSelectionMax.getZ()) |                                 BlockVector3.at(playerSelectionMax.getX(), world.getMaxY(), playerSelectionMax.getZ()) | ||||||
|                         ); |                         ); | ||||||
|                 // There's only one plot in the area... |                 // There's only one plot in the area... | ||||||
|                 final PlotId plotId = PlotId.of(1, 1); |                 final PlotId plotId = PlotId.of(1, 1); | ||||||
| @@ -278,9 +280,9 @@ public class Area extends SubCommand { | |||||||
|                     if (offsetZ != 0) { |                     if (offsetZ != 0) { | ||||||
|                         this.worldConfiguration.set(path + ".road.offset.z", offsetZ); |                         this.worldConfiguration.set(path + ".road.offset.z", offsetZ); | ||||||
|                     } |                     } | ||||||
|                     final String world = this.setupUtils.setupWorld(singleBuilder); |                     final String worldName = this.setupUtils.setupWorld(singleBuilder); | ||||||
|                     if (this.worldUtil.isWorld(world)) { |                     if (this.worldUtil.isWorld(worldName)) { | ||||||
|                         PlotSquared.get().loadWorld(world, null); |                         PlotSquared.get().loadWorld(worldName, null); | ||||||
|                         player.sendMessage(TranslatableCaption.of("single.single_area_created")); |                         player.sendMessage(TranslatableCaption.of("single.single_area_created")); | ||||||
|                     } else { |                     } else { | ||||||
|                         player.sendMessage( |                         player.sendMessage( | ||||||
| @@ -369,7 +371,8 @@ public class Area extends SubCommand { | |||||||
|                                 int lower = (area.ROAD_WIDTH & 1) == 0 ? area.ROAD_WIDTH / 2 - 1 : area.ROAD_WIDTH / 2; |                                 int lower = (area.ROAD_WIDTH & 1) == 0 ? area.ROAD_WIDTH / 2 - 1 : area.ROAD_WIDTH / 2; | ||||||
|                                 final int offsetX = bx - (area.ROAD_WIDTH == 0 ? 0 : lower); |                                 final int offsetX = bx - (area.ROAD_WIDTH == 0 ? 0 : lower); | ||||||
|                                 final int offsetZ = bz - (area.ROAD_WIDTH == 0 ? 0 : lower); |                                 final int offsetZ = bz - (area.ROAD_WIDTH == 0 ? 0 : lower); | ||||||
|                                 final CuboidRegion region = RegionUtil.createRegion(bx, tx, bz, tz); |                                 // Height doesn't matter for this region | ||||||
|  |                                 final CuboidRegion region = RegionUtil.createRegion(bx, tx, 0, 0, bz, tz); | ||||||
|                                 final Set<PlotArea> areas = this.plotAreaManager.getPlotAreasSet(area.getWorldName(), region); |                                 final Set<PlotArea> areas = this.plotAreaManager.getPlotAreasSet(area.getWorldName(), region); | ||||||
|                                 if (!areas.isEmpty()) { |                                 if (!areas.isEmpty()) { | ||||||
|                                     player.sendMessage( |                                     player.sendMessage( | ||||||
|   | |||||||
| @@ -48,7 +48,7 @@ public class Confirm extends SubCommand { | |||||||
|             player.sendMessage(TranslatableCaption.of("confirm.expired_confirm")); |             player.sendMessage(TranslatableCaption.of("confirm.expired_confirm")); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         TaskManager.runTaskAsync(command.command); |         TaskManager.runTask(command.command); | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -49,6 +49,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; | |||||||
| import java.util.Arrays; | import java.util.Arrays; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
|  | import java.util.LinkedHashSet; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Locale; | import java.util.Locale; | ||||||
| import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||||
| @@ -207,7 +208,7 @@ public class DebugExec extends SubCommand { | |||||||
|                     } |                     } | ||||||
|                     boolean result; |                     boolean result; | ||||||
|                     if (HybridUtils.regions != null) { |                     if (HybridUtils.regions != null) { | ||||||
|                         result = this.hybridUtils.scheduleRoadUpdate(area, HybridUtils.regions, 0, new HashSet<>()); |                         result = this.hybridUtils.scheduleRoadUpdate(area, HybridUtils.regions, 0, new LinkedHashSet<>()); | ||||||
|                     } else { |                     } else { | ||||||
|                         result = this.hybridUtils.scheduleRoadUpdate(area, 0); |                         result = this.hybridUtils.scheduleRoadUpdate(area, 0); | ||||||
|                     } |                     } | ||||||
|   | |||||||
| @@ -161,6 +161,7 @@ public class Deny extends SubCommand { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void handleKick(PlotPlayer<?> player, Plot plot) { |     private void handleKick(PlotPlayer<?> player, Plot plot) { | ||||||
|  |         plot = plot.getBasePlot(false); | ||||||
|         if (player == null) { |         if (player == null) { | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -32,6 +32,7 @@ import com.plotsquared.core.configuration.caption.Caption; | |||||||
| import com.plotsquared.core.configuration.caption.CaptionHolder; | import com.plotsquared.core.configuration.caption.CaptionHolder; | ||||||
| import com.plotsquared.core.configuration.caption.Templates; | import com.plotsquared.core.configuration.caption.Templates; | ||||||
| import com.plotsquared.core.configuration.caption.TranslatableCaption; | import com.plotsquared.core.configuration.caption.TranslatableCaption; | ||||||
|  | import com.plotsquared.core.database.DBFunc; | ||||||
| import com.plotsquared.core.permissions.Permission; | import com.plotsquared.core.permissions.Permission; | ||||||
| import com.plotsquared.core.player.PlotPlayer; | import com.plotsquared.core.player.PlotPlayer; | ||||||
| import com.plotsquared.core.plot.Plot; | import com.plotsquared.core.plot.Plot; | ||||||
| @@ -39,6 +40,7 @@ import com.plotsquared.core.plot.PlotArea; | |||||||
| import com.plotsquared.core.plot.expiration.ExpireManager; | import com.plotsquared.core.plot.expiration.ExpireManager; | ||||||
| import com.plotsquared.core.plot.flag.implementations.DoneFlag; | import com.plotsquared.core.plot.flag.implementations.DoneFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.PriceFlag; | import com.plotsquared.core.plot.flag.implementations.PriceFlag; | ||||||
|  | import com.plotsquared.core.plot.flag.implementations.ServerPlotFlag; | ||||||
| import com.plotsquared.core.plot.world.PlotAreaManager; | import com.plotsquared.core.plot.world.PlotAreaManager; | ||||||
| import com.plotsquared.core.util.EconHandler; | import com.plotsquared.core.util.EconHandler; | ||||||
| import com.plotsquared.core.util.MathMan; | import com.plotsquared.core.util.MathMan; | ||||||
| @@ -418,7 +420,7 @@ public class ListCmd extends SubCommand { | |||||||
|                 Caption color; |                 Caption color; | ||||||
|                 if (plot.getOwner() == null) { |                 if (plot.getOwner() == null) { | ||||||
|                     color = TranslatableCaption.of("info.plot_list_no_owner"); |                     color = TranslatableCaption.of("info.plot_list_no_owner"); | ||||||
|                 } else if (plot.isOwner(player.getUUID())) { |                 } else if (plot.isOwner(player.getUUID()) || plot.getOwner().equals(DBFunc.EVERYONE)) { | ||||||
|                     color = TranslatableCaption.of("info.plot_list_owned_by"); |                     color = TranslatableCaption.of("info.plot_list_owned_by"); | ||||||
|                 } else if (plot.isAdded(player.getUUID())) { |                 } else if (plot.isAdded(player.getUUID())) { | ||||||
|                     color = TranslatableCaption.of("info.plot_list_added_to"); |                     color = TranslatableCaption.of("info.plot_list_added_to"); | ||||||
| @@ -456,7 +458,17 @@ public class ListCmd extends SubCommand { | |||||||
|                 String prefix = ""; |                 String prefix = ""; | ||||||
|                 String online = TranslatableCaption.of("info.plot_list_player_online").getComponent(player); |                 String online = TranslatableCaption.of("info.plot_list_player_online").getComponent(player); | ||||||
|                 String offline = TranslatableCaption.of("info.plot_list_player_offline").getComponent(player); |                 String offline = TranslatableCaption.of("info.plot_list_player_offline").getComponent(player); | ||||||
|  |                 String unknown = TranslatableCaption.of("info.plot_list_player_unknown").getComponent(player); | ||||||
|  |                 String server = TranslatableCaption.of("info.plot_list_player_server").getComponent(player); | ||||||
|  |                 String everyone = TranslatableCaption.of("info.plot_list_player_everyone").getComponent(player); | ||||||
|                 TextComponent.Builder builder = Component.text(); |                 TextComponent.Builder builder = Component.text(); | ||||||
|  |                 if (plot.getFlag(ServerPlotFlag.class)) { | ||||||
|  |                     Template serverTemplate = Template.of( | ||||||
|  |                             "info.server", | ||||||
|  |                             TranslatableCaption.of("info.server").getComponent(player) | ||||||
|  |                     ); | ||||||
|  |                     builder.append(MINI_MESSAGE.parse(server, serverTemplate)); | ||||||
|  |                 } else { | ||||||
|                     try { |                     try { | ||||||
|                         final List<UUIDMapping> names = PlotSquared.get().getImpromptuUUIDPipeline().getNames(plot.getOwners()) |                         final List<UUIDMapping> names = PlotSquared.get().getImpromptuUUIDPipeline().getNames(plot.getOwners()) | ||||||
|                                 .get(Settings.UUID.BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS); |                                 .get(Settings.UUID.BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS); | ||||||
| @@ -466,6 +478,18 @@ public class ListCmd extends SubCommand { | |||||||
|                             Template playerTemplate = Template.of("player", uuidMapping.getUsername()); |                             Template playerTemplate = Template.of("player", uuidMapping.getUsername()); | ||||||
|                             if (pp != null) { |                             if (pp != null) { | ||||||
|                                 builder.append(MINI_MESSAGE.parse(online, prefixTemplate, playerTemplate)); |                                 builder.append(MINI_MESSAGE.parse(online, prefixTemplate, playerTemplate)); | ||||||
|  |                             } else if (uuidMapping.getUsername().equalsIgnoreCase("unknown")) { | ||||||
|  |                                 Template unknownTemplate = Template.of( | ||||||
|  |                                         "info.unknown", | ||||||
|  |                                         TranslatableCaption.of("info.unknown").getComponent(player) | ||||||
|  |                                 ); | ||||||
|  |                                 builder.append(MINI_MESSAGE.parse(unknown, unknownTemplate)); | ||||||
|  |                             } else if (uuidMapping.getUuid().equals(DBFunc.EVERYONE)) { | ||||||
|  |                                 Template everyoneTemplate = Template.of( | ||||||
|  |                                         "info.everyone", | ||||||
|  |                                         TranslatableCaption.of("info.everyone").getComponent(player) | ||||||
|  |                                 ); | ||||||
|  |                                 builder.append(MINI_MESSAGE.parse(everyone, everyoneTemplate)); | ||||||
|                             } else { |                             } else { | ||||||
|                                 builder.append(MINI_MESSAGE.parse(offline, prefixTemplate, playerTemplate)); |                                 builder.append(MINI_MESSAGE.parse(offline, prefixTemplate, playerTemplate)); | ||||||
|                             } |                             } | ||||||
| @@ -488,6 +512,7 @@ public class ListCmd extends SubCommand { | |||||||
|                     } catch (TimeoutException e) { |                     } catch (TimeoutException e) { | ||||||
|                         player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout")); |                         player.sendMessage(TranslatableCaption.of("players.fetching_players_timeout")); | ||||||
|                     } |                     } | ||||||
|  |                 } | ||||||
|                 Template players = Template.of("players", builder.asComponent()); |                 Template players = Template.of("players", builder.asComponent()); | ||||||
|                 caption.set(TranslatableCaption.of("info.plot_list_item")); |                 caption.set(TranslatableCaption.of("info.plot_list_item")); | ||||||
|                 caption.setTemplates(command_tp, command_info, hover_info, numberTemplate, plotTemplate, players); |                 caption.setTemplates(command_tp, command_info, hover_info, numberTemplate, plotTemplate, players); | ||||||
|   | |||||||
| @@ -40,6 +40,7 @@ import com.plotsquared.core.plot.schematic.Schematic; | |||||||
| import com.plotsquared.core.plot.world.PlotAreaManager; | import com.plotsquared.core.plot.world.PlotAreaManager; | ||||||
| import com.plotsquared.core.util.Permissions; | import com.plotsquared.core.util.Permissions; | ||||||
| import com.plotsquared.core.util.SchematicHandler; | 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.RunnableVal; | ||||||
| import com.plotsquared.core.util.task.TaskManager; | import com.plotsquared.core.util.task.TaskManager; | ||||||
| import net.kyori.adventure.text.minimessage.Template; | import net.kyori.adventure.text.minimessage.Template; | ||||||
| @@ -205,7 +206,7 @@ public class Load extends SubCommand { | |||||||
|                     if (split.length < 5) { |                     if (split.length < 5) { | ||||||
|                         continue; |                         continue; | ||||||
|                     } |                     } | ||||||
|                     String time = secToTime((System.currentTimeMillis() / 1000) - Long.parseLong(split[0])); |                     String time = TimeUtil.secToTime((System.currentTimeMillis() / 1000) - Long.parseLong(split[0])); | ||||||
|                     String world = split[1]; |                     String world = split[1]; | ||||||
|                     PlotId id = PlotId.fromString(split[2] + ';' + split[3]); |                     PlotId id = PlotId.fromString(split[2] + ';' + split[3]); | ||||||
|                     String size = split[4]; |                     String size = split[4]; | ||||||
| @@ -223,6 +224,10 @@ public class Load extends SubCommand { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @deprecated Use {@link TimeUtil#secToTime(long)} | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "6.6.2") | ||||||
|     public String secToTime(long time) { |     public String secToTime(long time) { | ||||||
|         StringBuilder toreturn = new StringBuilder(); |         StringBuilder toreturn = new StringBuilder(); | ||||||
|         if (time >= 33868800) { |         if (time >= 33868800) { | ||||||
|   | |||||||
| @@ -104,8 +104,8 @@ public class Save extends SubCommand { | |||||||
|                     TaskManager.runTaskAsync(() -> { |                     TaskManager.runTaskAsync(() -> { | ||||||
|                         String time = (System.currentTimeMillis() / 1000) + ""; |                         String time = (System.currentTimeMillis() / 1000) + ""; | ||||||
|                         Location[] corners = plot.getCorners(); |                         Location[] corners = plot.getCorners(); | ||||||
|                         corners[0] = corners[0].withY(0); |                         corners[0] = corners[0].withY(plot.getArea().getMinBuildHeight()); | ||||||
|                         corners[1] = corners[1].withY(255); |                         corners[1] = corners[1].withY(plot.getArea().getMaxBuildHeight()); | ||||||
|                         int size = (corners[1].getX() - corners[0].getX()) + 1; |                         int size = (corners[1].getX() - corners[0].getX()) + 1; | ||||||
|                         PlotId id = plot.getId(); |                         PlotId id = plot.getId(); | ||||||
|                         String world1 = plot.getArea().toString().replaceAll(";", "-") |                         String world1 = plot.getArea().toString().replaceAll(";", "-") | ||||||
|   | |||||||
| @@ -57,8 +57,12 @@ public class SetHome extends SetCommand { | |||||||
|                 Plot base = plot.getBasePlot(false); |                 Plot base = plot.getBasePlot(false); | ||||||
|                 Location bottom = base.getBottomAbs(); |                 Location bottom = base.getBottomAbs(); | ||||||
|                 Location location = player.getLocationFull(); |                 Location location = player.getLocationFull(); | ||||||
|                 BlockLoc rel = new BlockLoc(location.getX() - bottom.getX(), location.getY(), |                 BlockLoc rel = new BlockLoc( | ||||||
|                         location.getZ() - bottom.getZ(), location.getYaw(), location.getPitch() |                         location.getX() - bottom.getX(), | ||||||
|  |                         location.getY(), // y is absolute | ||||||
|  |                         location.getZ() - bottom.getZ(), | ||||||
|  |                         location.getYaw(), | ||||||
|  |                         location.getPitch() | ||||||
|                 ); |                 ); | ||||||
|                 base.setHome(rel); |                 base.setHome(rel); | ||||||
|                 player.sendMessage(TranslatableCaption.of("position.position_set")); |                 player.sendMessage(TranslatableCaption.of("position.position_set")); | ||||||
|   | |||||||
| @@ -180,12 +180,12 @@ public class Trim extends SubCommand { | |||||||
|                             int bx = cbx << 4; |                             int bx = cbx << 4; | ||||||
|                             int bz = cbz << 4; |                             int bz = cbz << 4; | ||||||
|                             CuboidRegion region = |                             CuboidRegion region = | ||||||
|                                     RegionUtil.createRegion(bx, bx + 511, bz, bz + 511); |                                     RegionUtil.createRegion(bx, bx + 511, 0, 0, bz, bz + 511); | ||||||
|                             for (Plot plot : PlotQuery.newQuery().inWorld(world)) { |                             for (Plot plot : PlotQuery.newQuery().inWorld(world)) { | ||||||
|                                 Location bot = plot.getBottomAbs(); |                                 Location bot = plot.getBottomAbs(); | ||||||
|                                 Location top = plot.getExtendedTopAbs(); |                                 Location top = plot.getExtendedTopAbs(); | ||||||
|                                 CuboidRegion plotReg = RegionUtil |                                 CuboidRegion plotReg = RegionUtil | ||||||
|                                         .createRegion(bot.getX(), top.getX(), bot.getZ(), top.getZ()); |                                         .createRegion(bot.getX(), top.getX(), 0, 0, bot.getZ(), top.getZ()); | ||||||
|                                 if (!RegionUtil.intersects(region, plotReg)) { |                                 if (!RegionUtil.intersects(region, plotReg)) { | ||||||
|                                     continue; |                                     continue; | ||||||
|                                 } |                                 } | ||||||
|   | |||||||
| @@ -249,6 +249,9 @@ public class Settings extends Config { | |||||||
|         public static int UUID_CACHE_SIZE = 100000; |         public static int UUID_CACHE_SIZE = 100000; | ||||||
|         @Comment("Rate limit (per 10 minutes) for background UUID fetching from the Mojang API") |         @Comment("Rate limit (per 10 minutes) for background UUID fetching from the Mojang API") | ||||||
|         public static int BACKGROUND_LIMIT = 200; |         public static int BACKGROUND_LIMIT = 200; | ||||||
|  |         @Comment("Whether the Mojang API service is enabled for impromptu api calls. If false only the Background task will use" + | ||||||
|  |                 " http requests to fill the UUID cache (requires restart)") | ||||||
|  |         public static boolean IMPROMPTU_SERVICE_MOJANG_API = true; | ||||||
|         @Comment("Rate limit (per 10 minutes) for random UUID fetching from the Mojang API") |         @Comment("Rate limit (per 10 minutes) for random UUID fetching from the Mojang API") | ||||||
|         public static int IMPROMPTU_LIMIT = 300; |         public static int IMPROMPTU_LIMIT = 300; | ||||||
|         @Comment("Timeout (in milliseconds) for non-blocking UUID requests (mostly commands)") |         @Comment("Timeout (in milliseconds) for non-blocking UUID requests (mostly commands)") | ||||||
| @@ -691,6 +694,7 @@ public class Settings extends Config { | |||||||
|         @Comment({"If blocks at the edges of queued operations should be set causing updates", |         @Comment({"If blocks at the edges of queued operations should be set causing updates", | ||||||
|                 " - Slightly slower, but prevents issues such as fences left connected to nothing"}) |                 " - Slightly slower, but prevents issues such as fences left connected to nothing"}) | ||||||
|         public static boolean UPDATE_EDGES = true; |         public static boolean UPDATE_EDGES = true; | ||||||
|  |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Comment("Settings related to tab completion") |     @Comment("Settings related to tab completion") | ||||||
|   | |||||||
| @@ -54,12 +54,23 @@ public class AugmentedUtils { | |||||||
|         enabled = true; |         enabled = true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static boolean generate( |     /** | ||||||
|             @Nullable Object chunkObject, |      * Generate an augmented world chunk at the given location. If a queue is given, the data will be written to it, else a new | ||||||
|  |      * queue will be created and written to world. Returns true if generation occurred. | ||||||
|  |      * | ||||||
|  |      * @param world  World name to generate data for. Must be a PlotSquared world containing one or more areas else nothing will | ||||||
|  |      *               happen. | ||||||
|  |      * @param chunkX Chunk X position | ||||||
|  |      * @param chunkZ Chunk Z position | ||||||
|  |      * @param queue  Queue to write to, if desired. | ||||||
|  |      * @return true if generation occurred. | ||||||
|  |      * @since 6.8.0 | ||||||
|  |      */ | ||||||
|  |     public static boolean generateChunk( | ||||||
|             final @NonNull String world, |             final @NonNull String world, | ||||||
|             final int chunkX, |             final int chunkX, | ||||||
|             final int chunkZ, |             final int chunkZ, | ||||||
|             QueueCoordinator queue |             @Nullable QueueCoordinator queue | ||||||
|     ) { |     ) { | ||||||
|         if (!enabled) { |         if (!enabled) { | ||||||
|             return false; |             return false; | ||||||
| @@ -70,7 +81,7 @@ public class AugmentedUtils { | |||||||
|         final int blockZ = chunkZ << 4; |         final int blockZ = chunkZ << 4; | ||||||
|         // Create a region that contains the |         // Create a region that contains the | ||||||
|         // entire chunk |         // entire chunk | ||||||
|         CuboidRegion region = RegionUtil.createRegion(blockX, blockX + 15, blockZ, blockZ + 15); |         CuboidRegion region = RegionUtil.createRegion(blockX, blockX + 15, 0, 0, blockZ, blockZ + 15); | ||||||
|         // Query for plot areas in the chunk |         // Query for plot areas in the chunk | ||||||
|         final Set<PlotArea> areas = PlotSquared.get().getPlotAreaManager().getPlotAreasSet(world, region); |         final Set<PlotArea> areas = PlotSquared.get().getPlotAreaManager().getPlotAreasSet(world, region); | ||||||
|         if (areas.isEmpty()) { |         if (areas.isEmpty()) { | ||||||
| @@ -97,9 +108,6 @@ public class AugmentedUtils { | |||||||
|                         .platform() |                         .platform() | ||||||
|                         .worldUtil() |                         .worldUtil() | ||||||
|                         .getWeWorld(world)); |                         .getWeWorld(world)); | ||||||
|                 if (chunkObject != null) { |  | ||||||
|                     queue.setChunkObject(chunkObject); |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|             QueueCoordinator primaryMask; |             QueueCoordinator primaryMask; | ||||||
|             // coordinates |             // coordinates | ||||||
| @@ -122,6 +130,7 @@ public class AugmentedUtils { | |||||||
|             } |             } | ||||||
|             QueueCoordinator secondaryMask; |             QueueCoordinator secondaryMask; | ||||||
|             BlockState air = BlockTypes.AIR.getDefaultState(); |             BlockState air = BlockTypes.AIR.getDefaultState(); | ||||||
|  |             int startYOffset = !(area instanceof ClassicPlotWorld) || ((ClassicPlotWorld) area).PLOT_BEDROCK ? 1 : 0; | ||||||
|             if (area.getTerrain() == PlotAreaTerrainType.ROAD) { |             if (area.getTerrain() == PlotAreaTerrainType.ROAD) { | ||||||
|                 PlotManager manager = area.getPlotManager(); |                 PlotManager manager = area.getPlotManager(); | ||||||
|                 final boolean[][] canPlace = new boolean[16][16]; |                 final boolean[][] canPlace = new boolean[16][16]; | ||||||
| @@ -132,7 +141,7 @@ public class AugmentedUtils { | |||||||
|                         int worldZ = z + blockZ; |                         int worldZ = z + blockZ; | ||||||
|                         boolean can = manager.getPlotId(worldX, 0, worldZ) == null; |                         boolean can = manager.getPlotId(worldX, 0, worldZ) == null; | ||||||
|                         if (can) { |                         if (can) { | ||||||
|                             for (int y = 1; y < 128; y++) { |                             for (int y = area.getMinGenHeight() + startYOffset; y <= area.getMaxGenHeight(); y++) { | ||||||
|                                 queue.setBlock(worldX, y, worldZ, air); |                                 queue.setBlock(worldX, y, worldZ, air); | ||||||
|                             } |                             } | ||||||
|                             canPlace[x][z] = true; |                             canPlace[x][z] = true; | ||||||
| @@ -149,30 +158,24 @@ public class AugmentedUtils { | |||||||
|                 secondaryMask = primaryMask; |                 secondaryMask = primaryMask; | ||||||
|                 for (int x = relativeBottomX; x <= relativeTopX; x++) { |                 for (int x = relativeBottomX; x <= relativeTopX; x++) { | ||||||
|                     for (int z = relativeBottomZ; z <= relativeTopZ; z++) { |                     for (int z = relativeBottomZ; z <= relativeTopZ; z++) { | ||||||
|                         for (int y = 1; y < 128; y++) { |                         for (int y = area.getMinGenHeight() + startYOffset; y <= area.getMaxGenHeight(); y++) { | ||||||
|                             queue.setBlock(blockX + x, y, blockZ + z, air); |                             queue.setBlock(blockX + x, y, blockZ + z, air); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 generationResult = true; |                 generationResult = true; | ||||||
|             } |             } | ||||||
|             if (chunkObject != null) { |  | ||||||
|                 primaryMask.setChunkObject(chunkObject); |  | ||||||
|             } |  | ||||||
|             if (chunkObject != null) { |  | ||||||
|                 secondaryMask.setChunkObject(chunkObject); |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|  |             // This queue should not be enqueued as it is simply used to restrict block setting, and then delegate to the | ||||||
|  |             // actual queue | ||||||
|             ScopedQueueCoordinator scoped = |             ScopedQueueCoordinator scoped = | ||||||
|                     new ScopedQueueCoordinator( |                     new ScopedQueueCoordinator( | ||||||
|                             secondaryMask, |                             secondaryMask, | ||||||
|                             Location.at(world, blockX, 0, blockZ), |                             Location.at(world, blockX, area.getMinGenHeight(), blockZ), | ||||||
|                             Location.at(world, blockX + 15, 255, blockZ + 15) |                             Location.at(world, blockX + 15, area.getMaxGenHeight(), blockZ + 15) | ||||||
|                     ); |                     ); | ||||||
|             generator.generateChunk(scoped, area); |             generator.generateChunk(scoped, area); | ||||||
|             generator.populateChunk(scoped, area); |             generator.populateChunk(scoped, area); | ||||||
|             scoped.setForceSync(true); |  | ||||||
|             scoped.enqueue(); |  | ||||||
|         } |         } | ||||||
|         if (enqueue) { |         if (enqueue) { | ||||||
|             queue.enqueue(); |             queue.enqueue(); | ||||||
| @@ -180,4 +183,19 @@ public class AugmentedUtils { | |||||||
|         return generationResult; |         return generationResult; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @deprecated Use {@link AugmentedUtils#generateChunk(String, int, int, QueueCoordinator)} as chunkObject is not required | ||||||
|  |      * in the above method | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "6.8.0") | ||||||
|  |     public static boolean generate( | ||||||
|  |             @Nullable Object chunkObject, | ||||||
|  |             final @NonNull String world, | ||||||
|  |             final int chunkX, | ||||||
|  |             final int chunkZ, | ||||||
|  |             QueueCoordinator queue | ||||||
|  |     ) { | ||||||
|  |         return generateChunk(world, chunkX, chunkZ, queue); | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -37,7 +37,6 @@ import com.plotsquared.core.plot.Plot; | |||||||
| import com.plotsquared.core.plot.PlotAreaTerrainType; | import com.plotsquared.core.plot.PlotAreaTerrainType; | ||||||
| import com.plotsquared.core.plot.PlotId; | import com.plotsquared.core.plot.PlotId; | ||||||
| import com.plotsquared.core.queue.QueueCoordinator; | import com.plotsquared.core.queue.QueueCoordinator; | ||||||
| import com.plotsquared.core.util.BlockUtil; |  | ||||||
| import com.plotsquared.core.util.MathMan; | import com.plotsquared.core.util.MathMan; | ||||||
| import com.plotsquared.core.util.RegionManager; | import com.plotsquared.core.util.RegionManager; | ||||||
| import com.plotsquared.core.util.task.TaskManager; | import com.plotsquared.core.util.task.TaskManager; | ||||||
| @@ -147,7 +146,15 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|     ) { |     ) { | ||||||
|         Plot plot = classicPlotWorld.getPlotAbs(plotId); |         Plot plot = classicPlotWorld.getPlotAbs(plotId); | ||||||
|         if (plot != null && plot.isBasePlot()) { |         if (plot != null && plot.isBasePlot()) { | ||||||
|             return this.regionManager.setCuboids(classicPlotWorld, plot.getRegions(), blocks, 1, getWorldHeight(), actor, queue); |             return this.regionManager.setCuboids( | ||||||
|  |                     classicPlotWorld, | ||||||
|  |                     plot.getRegions(), | ||||||
|  |                     blocks, | ||||||
|  |                     classicPlotWorld.getMinBuildHeight(), | ||||||
|  |                     classicPlotWorld.getMaxBuildHeight(), | ||||||
|  |                     actor, | ||||||
|  |                     queue | ||||||
|  |             ); | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| @@ -175,7 +182,7 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|                             plot.getRegions(), |                             plot.getRegions(), | ||||||
|                             blocks, |                             blocks, | ||||||
|                             classicPlotWorld.PLOT_HEIGHT + 1, |                             classicPlotWorld.PLOT_HEIGHT + 1, | ||||||
|                             getWorldHeight(), |                             classicPlotWorld.getMaxBuildHeight(), | ||||||
|                             actor, |                             actor, | ||||||
|                             queue |                             queue | ||||||
|                     ); |                     ); | ||||||
| @@ -204,7 +211,7 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|                     classicPlotWorld, |                     classicPlotWorld, | ||||||
|                     plot.getRegions(), |                     plot.getRegions(), | ||||||
|                     blocks, |                     blocks, | ||||||
|                     1, |                     classicPlotWorld.getMinBuildHeight(), | ||||||
|                     classicPlotWorld.PLOT_HEIGHT - 1, |                     classicPlotWorld.PLOT_HEIGHT - 1, | ||||||
|                     actor, |                     actor, | ||||||
|                     queue |                     queue | ||||||
| @@ -281,7 +288,7 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         int maxY = classicPlotWorld.getPlotManager().getWorldHeight(); |         int maxY = classicPlotWorld.getMaxBuildHeight(); | ||||||
|         if (!plot.isMerged(Direction.NORTH)) { |         if (!plot.isMerged(Direction.NORTH)) { | ||||||
|             int z = bottom.getZ(); |             int z = bottom.getZ(); | ||||||
|             for (int x = bottom.getX(); x <= top.getX(); x++) { |             for (int x = bottom.getX(); x <= top.getX(); x++) { | ||||||
| @@ -382,7 +389,7 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|         if (!plot.isMerged(Direction.NORTH)) { |         if (!plot.isMerged(Direction.NORTH)) { | ||||||
|             int z = bot.getZ(); |             int z = bot.getZ(); | ||||||
|             for (int x = bot.getX(); x < top.getX(); x++) { |             for (int x = bot.getX(); x < top.getX(); x++) { | ||||||
|                 for (int y = 1; y <= classicPlotWorld.WALL_HEIGHT; y++) { |                 for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) { | ||||||
|                     queue.setBlock(x, y, z, blocks); |                     queue.setBlock(x, y, z, blocks); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -390,7 +397,7 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|         if (!plot.isMerged(Direction.WEST)) { |         if (!plot.isMerged(Direction.WEST)) { | ||||||
|             int x = bot.getX(); |             int x = bot.getX(); | ||||||
|             for (int z = bot.getZ(); z < top.getZ(); z++) { |             for (int z = bot.getZ(); z < top.getZ(); z++) { | ||||||
|                 for (int y = 1; y <= classicPlotWorld.WALL_HEIGHT; y++) { |                 for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) { | ||||||
|                     queue.setBlock(x, y, z, blocks); |                     queue.setBlock(x, y, z, blocks); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -398,7 +405,7 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|         if (!plot.isMerged(Direction.SOUTH)) { |         if (!plot.isMerged(Direction.SOUTH)) { | ||||||
|             int z = top.getZ(); |             int z = top.getZ(); | ||||||
|             for (int x = bot.getX(); x < top.getX() + (plot.isMerged(Direction.EAST) ? 0 : 1); x++) { |             for (int x = bot.getX(); x < top.getX() + (plot.isMerged(Direction.EAST) ? 0 : 1); x++) { | ||||||
|                 for (int y = 1; y <= classicPlotWorld.WALL_HEIGHT; y++) { |                 for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) { | ||||||
|                     queue.setBlock(x, y, z, blocks); |                     queue.setBlock(x, y, z, blocks); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -406,7 +413,7 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|         if (!plot.isMerged(Direction.EAST)) { |         if (!plot.isMerged(Direction.EAST)) { | ||||||
|             int x = top.getX(); |             int x = top.getX(); | ||||||
|             for (int z = bot.getZ(); z < top.getZ() + (plot.isMerged(Direction.SOUTH) ? 0 : 1); z++) { |             for (int z = bot.getZ(); z < top.getZ() + (plot.isMerged(Direction.SOUTH) ? 0 : 1); z++) { | ||||||
|                 for (int y = 1; y <= classicPlotWorld.WALL_HEIGHT; y++) { |                 for (int y = classicPlotWorld.getMinBuildHeight(); y <= classicPlotWorld.WALL_HEIGHT; y++) { | ||||||
|                     queue.setBlock(x, y, z, blocks); |                     queue.setBlock(x, y, z, blocks); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
| @@ -501,7 +508,7 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|             enqueue = true; |             enqueue = true; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         int maxY = getWorldHeight(); |         int maxY = classicPlotWorld.getMaxGenHeight(); | ||||||
|         queue.setCuboid( |         queue.setCuboid( | ||||||
|                 Location.at( |                 Location.at( | ||||||
|                         classicPlotWorld.getWorldName(), |                         classicPlotWorld.getWorldName(), | ||||||
| @@ -513,27 +520,27 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|         ); |         ); | ||||||
|         if (classicPlotWorld.PLOT_BEDROCK) { |         if (classicPlotWorld.PLOT_BEDROCK) { | ||||||
|             queue.setCuboid( |             queue.setCuboid( | ||||||
|                     Location.at(classicPlotWorld.getWorldName(), sx, 0, sz + 1), |                     Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.getMinGenHeight(), sz + 1), | ||||||
|                     Location.at(classicPlotWorld.getWorldName(), ex, 0, ez - 1), |                     Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getMinGenHeight(), ez - 1), | ||||||
|                     BlockTypes.BEDROCK.getDefaultState() |                     BlockTypes.BEDROCK.getDefaultState() | ||||||
|             ); |             ); | ||||||
|             queue.setCuboid( |  | ||||||
|                     Location.at(classicPlotWorld.getWorldName(), sx, 1, sz + 1), |  | ||||||
|                     Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT, ez - 1), |  | ||||||
|                     classicPlotWorld.WALL_FILLING.toPattern() |  | ||||||
|             ); |  | ||||||
|         } else { |  | ||||||
|             queue.setCuboid( |  | ||||||
|                     Location.at(classicPlotWorld.getWorldName(), sx, 0, sz + 1), |  | ||||||
|                     Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT, ez - 1), |  | ||||||
|                     classicPlotWorld.WALL_FILLING.toPattern() |  | ||||||
|             ); |  | ||||||
|         } |         } | ||||||
|  |         int startYOffset = classicPlotWorld.PLOT_BEDROCK ? 1 : 0; | ||||||
|         queue.setCuboid( |         queue.setCuboid( | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), sx, 1, sz + 1), |                 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getMinGenHeight() + startYOffset, sz + 1), | ||||||
|  |                 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT, ez - 1), | ||||||
|  |                 classicPlotWorld.WALL_FILLING.toPattern() | ||||||
|  |         ); | ||||||
|  |         queue.setCuboid( | ||||||
|  |                 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.getMinGenHeight() + startYOffset, sz + 1), | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT, ez - 1), |                 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT, ez - 1), | ||||||
|                 classicPlotWorld.WALL_FILLING.toPattern() |                 classicPlotWorld.WALL_FILLING.toPattern() | ||||||
|         ); |         ); | ||||||
|  |         queue.setCuboid( | ||||||
|  |                 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight() + startYOffset, sz + 1), | ||||||
|  |                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT, ez - 1), | ||||||
|  |                 classicPlotWorld.ROAD_BLOCK.toPattern() | ||||||
|  |         ); | ||||||
|  |  | ||||||
|         if (classicPlotWorld.PLACE_TOP_BLOCK) { |         if (classicPlotWorld.PLACE_TOP_BLOCK) { | ||||||
|             queue.setCuboid( |             queue.setCuboid( | ||||||
| @@ -541,24 +548,12 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|                     Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT + 1, ez - 1), |                     Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.WALL_HEIGHT + 1, ez - 1), | ||||||
|                     classicPlotWorld.WALL_BLOCK.toPattern() |                     classicPlotWorld.WALL_BLOCK.toPattern() | ||||||
|             ); |             ); | ||||||
|         } |  | ||||||
|         queue.setCuboid( |  | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex, 1, sz + 1), |  | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT, ez - 1), |  | ||||||
|                 classicPlotWorld.WALL_FILLING.toPattern() |  | ||||||
|         ); |  | ||||||
|         if (classicPlotWorld.PLACE_TOP_BLOCK) { |  | ||||||
|             queue.setCuboid( |             queue.setCuboid( | ||||||
|                     Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT + 1, sz + 1), |                     Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT + 1, sz + 1), | ||||||
|                     Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT + 1, ez - 1), |                     Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.WALL_HEIGHT + 1, ez - 1), | ||||||
|                     classicPlotWorld.WALL_BLOCK.toPattern() |                     classicPlotWorld.WALL_BLOCK.toPattern() | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|         queue.setCuboid( |  | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz + 1), |  | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT, ez - 1), |  | ||||||
|                 classicPlotWorld.ROAD_BLOCK.toPattern() |  | ||||||
|         ); |  | ||||||
|         return !enqueue || queue.enqueue(); |         return !enqueue || queue.enqueue(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -584,19 +579,32 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|                         classicPlotWorld.schematicStartHeight() + 1, |                         classicPlotWorld.schematicStartHeight() + 1, | ||||||
|                         sz |                         sz | ||||||
|                 ), |                 ), | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.getPlotManager().getWorldHeight(), ez), |                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.getMaxGenHeight(), ez), | ||||||
|                 BlockTypes.AIR.getDefaultState() |                 BlockTypes.AIR.getDefaultState() | ||||||
|         ); |         ); | ||||||
|  |         if (classicPlotWorld.PLOT_BEDROCK) { | ||||||
|             queue.setCuboid( |             queue.setCuboid( | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), sx + 1, 0, sz), |                     Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight(), sz), | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex - 1, 0, ez), |                     Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.getMinGenHeight(), ez), | ||||||
|                 BlockUtil.get((short) 7, (byte) 0) |                     BlockTypes.BEDROCK.getDefaultState() | ||||||
|             ); |             ); | ||||||
|  |         } | ||||||
|  |         int startYOffset = classicPlotWorld.PLOT_BEDROCK ? 1 : 0; | ||||||
|         queue.setCuboid( |         queue.setCuboid( | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz), |                 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight() + startYOffset, sz), | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT, sz), |                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT, sz), | ||||||
|                 classicPlotWorld.WALL_FILLING.toPattern() |                 classicPlotWorld.WALL_FILLING.toPattern() | ||||||
|         ); |         ); | ||||||
|  |         queue.setCuboid( | ||||||
|  |                 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight() + startYOffset, ez), | ||||||
|  |                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT, ez), | ||||||
|  |                 classicPlotWorld.WALL_FILLING.toPattern() | ||||||
|  |         ); | ||||||
|  |         queue.setCuboid( | ||||||
|  |                 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight() + startYOffset, sz + 1), | ||||||
|  |                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT, ez - 1), | ||||||
|  |                 classicPlotWorld.ROAD_BLOCK.toPattern() | ||||||
|  |         ); | ||||||
|  |  | ||||||
|         if (classicPlotWorld.PLACE_TOP_BLOCK) { |         if (classicPlotWorld.PLACE_TOP_BLOCK) { | ||||||
|             queue.setCuboid( |             queue.setCuboid( | ||||||
| @@ -604,24 +612,12 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|                     Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT + 1, sz), |                     Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT + 1, sz), | ||||||
|                     classicPlotWorld.WALL_BLOCK.toPattern() |                     classicPlotWorld.WALL_BLOCK.toPattern() | ||||||
|             ); |             ); | ||||||
|         } |  | ||||||
|         queue.setCuboid( |  | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, ez), |  | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT, ez), |  | ||||||
|                 classicPlotWorld.WALL_FILLING.toPattern() |  | ||||||
|         ); |  | ||||||
|         if (classicPlotWorld.PLACE_TOP_BLOCK) { |  | ||||||
|             queue.setCuboid( |             queue.setCuboid( | ||||||
|                     Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.WALL_HEIGHT + 1, ez), |                     Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.WALL_HEIGHT + 1, ez), | ||||||
|                     Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT + 1, ez), |                     Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.WALL_HEIGHT + 1, ez), | ||||||
|                     classicPlotWorld.WALL_BLOCK.toPattern() |                     classicPlotWorld.WALL_BLOCK.toPattern() | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|         queue.setCuboid( |  | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz + 1), |  | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT, ez - 1), |  | ||||||
|                 classicPlotWorld.ROAD_BLOCK.toPattern() |  | ||||||
|         ); |  | ||||||
|         return !enqueue || queue.enqueue(); |         return !enqueue || queue.enqueue(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -642,14 +638,19 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|  |  | ||||||
|         queue.setCuboid( |         queue.setCuboid( | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.ROAD_HEIGHT + 1, sz + 1), |                 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.ROAD_HEIGHT + 1, sz + 1), | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.getPlotManager().getWorldHeight(), ez - 1), |                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.getMaxGenHeight(), ez - 1), | ||||||
|                 BlockTypes.AIR.getDefaultState() |                 BlockTypes.AIR.getDefaultState() | ||||||
|         ); |         ); | ||||||
|         queue.setCuboid(Location.at(classicPlotWorld.getWorldName(), sx + 1, 0, sz + 1), |         if (classicPlotWorld.PLOT_BEDROCK) { | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex - 1, 0, ez - 1), BlockUtil.get((short) 7, (byte) 0) |  | ||||||
|         ); |  | ||||||
|             queue.setCuboid( |             queue.setCuboid( | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz + 1), |                     Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight(), sz + 1), | ||||||
|  |                     Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.getMinGenHeight(), ez - 1), | ||||||
|  |                     BlockTypes.BEDROCK.getDefaultState() | ||||||
|  |             ); | ||||||
|  |         } | ||||||
|  |         int startYOffset = classicPlotWorld.PLOT_BEDROCK ? 1 : 0; | ||||||
|  |         queue.setCuboid( | ||||||
|  |                 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight() + startYOffset, sz + 1), | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT, ez - 1), |                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.ROAD_HEIGHT, ez - 1), | ||||||
|                 classicPlotWorld.ROAD_BLOCK.toPattern() |                 classicPlotWorld.ROAD_BLOCK.toPattern() | ||||||
|         ); |         ); | ||||||
| @@ -679,11 +680,12 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|                                 classicPlotWorld.schematicStartHeight() + 1, |                                 classicPlotWorld.schematicStartHeight() + 1, | ||||||
|                                 sz |                                 sz | ||||||
|                         ), |                         ), | ||||||
|                         Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getPlotManager().getWorldHeight(), ez), |                         Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getMaxGenHeight(), ez), | ||||||
|                         BlockTypes.AIR.getDefaultState() |                         BlockTypes.AIR.getDefaultState() | ||||||
|                 ); |                 ); | ||||||
|  |         int startYOffset = classicPlotWorld.PLOT_BEDROCK ? 1 : 0; | ||||||
|         queue.setCuboid( |         queue.setCuboid( | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), sx, 1, sz + 1), |                 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.getMinGenHeight() + startYOffset, sz + 1), | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT - 1, ez - 1), |                 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT - 1, ez - 1), | ||||||
|                 classicPlotWorld.MAIN_BLOCK.toPattern() |                 classicPlotWorld.MAIN_BLOCK.toPattern() | ||||||
|         ); |         ); | ||||||
| @@ -719,11 +721,12 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|                                 classicPlotWorld.schematicStartHeight() + 1, |                                 classicPlotWorld.schematicStartHeight() + 1, | ||||||
|                                 sz |                                 sz | ||||||
|                         ), |                         ), | ||||||
|                         Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getPlotManager().getWorldHeight(), ez), |                         Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getMaxGenHeight(), ez), | ||||||
|                         BlockTypes.AIR.getDefaultState() |                         BlockTypes.AIR.getDefaultState() | ||||||
|                 ); |                 ); | ||||||
|  |         int startYOffset = classicPlotWorld.PLOT_BEDROCK ? 1 : 0; | ||||||
|         queue.setCuboid( |         queue.setCuboid( | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), sx + 1, 1, sz), |                 Location.at(classicPlotWorld.getWorldName(), sx + 1, classicPlotWorld.getMinGenHeight() + startYOffset, sz), | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.PLOT_HEIGHT - 1, ez), |                 Location.at(classicPlotWorld.getWorldName(), ex - 1, classicPlotWorld.PLOT_HEIGHT - 1, ez), | ||||||
|                 classicPlotWorld.MAIN_BLOCK.toPattern() |                 classicPlotWorld.MAIN_BLOCK.toPattern() | ||||||
|         ); |         ); | ||||||
| @@ -758,11 +761,12 @@ public class ClassicPlotManager extends SquarePlotManager { | |||||||
|                                 classicPlotWorld.schematicStartHeight() + 1, |                                 classicPlotWorld.schematicStartHeight() + 1, | ||||||
|                                 sz |                                 sz | ||||||
|                         ), |                         ), | ||||||
|                         Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getPlotManager().getWorldHeight(), ez), |                         Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.getMaxGenHeight(), ez), | ||||||
|                         BlockTypes.AIR.getDefaultState() |                         BlockTypes.AIR.getDefaultState() | ||||||
|                 ); |                 ); | ||||||
|  |         int startYOffset = classicPlotWorld.PLOT_BEDROCK ? 1 : 0; | ||||||
|         queue.setCuboid( |         queue.setCuboid( | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), sx, 1, sz), |                 Location.at(classicPlotWorld.getWorldName(), sx, classicPlotWorld.getMinGenHeight() + startYOffset, sz), | ||||||
|                 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT - 1, ez), |                 Location.at(classicPlotWorld.getWorldName(), ex, classicPlotWorld.PLOT_HEIGHT - 1, ez), | ||||||
|                 classicPlotWorld.MAIN_BLOCK.toPattern() |                 classicPlotWorld.MAIN_BLOCK.toPattern() | ||||||
|         ); |         ); | ||||||
|   | |||||||
| @@ -127,16 +127,16 @@ public abstract class ClassicPlotWorld extends SquarePlotWorld { | |||||||
|     public void loadConfiguration(ConfigurationSection config) { |     public void loadConfiguration(ConfigurationSection config) { | ||||||
|         super.loadConfiguration(config); |         super.loadConfiguration(config); | ||||||
|         this.PLOT_BEDROCK = config.getBoolean("plot.bedrock"); |         this.PLOT_BEDROCK = config.getBoolean("plot.bedrock"); | ||||||
|         this.PLOT_HEIGHT = Math.min(255, config.getInt("plot.height")); |         this.PLOT_HEIGHT = Math.min(getMaxGenHeight(), config.getInt("plot.height")); | ||||||
|         this.MAIN_BLOCK = new BlockBucket(config.getString("plot.filling")); |         this.MAIN_BLOCK = new BlockBucket(config.getString("plot.filling")); | ||||||
|         this.TOP_BLOCK = new BlockBucket(config.getString("plot.floor")); |         this.TOP_BLOCK = new BlockBucket(config.getString("plot.floor")); | ||||||
|         this.WALL_BLOCK = new BlockBucket(config.getString("wall.block")); |         this.WALL_BLOCK = new BlockBucket(config.getString("wall.block")); | ||||||
|         this.ROAD_HEIGHT = Math.min(255, config.getInt("road.height")); |         this.ROAD_HEIGHT = Math.min(getMaxGenHeight(), config.getInt("road.height")); | ||||||
|         this.ROAD_BLOCK = new BlockBucket(config.getString("road.block")); |         this.ROAD_BLOCK = new BlockBucket(config.getString("road.block")); | ||||||
|         this.WALL_FILLING = new BlockBucket(config.getString("wall.filling")); |         this.WALL_FILLING = new BlockBucket(config.getString("wall.filling")); | ||||||
|         this.WALL_HEIGHT = Math.min(254, config.getInt("wall.height")); |  | ||||||
|         this.CLAIMED_WALL_BLOCK = new BlockBucket(config.getString("wall.block_claimed")); |  | ||||||
|         this.PLACE_TOP_BLOCK = config.getBoolean("wall.place_top_block"); |         this.PLACE_TOP_BLOCK = config.getBoolean("wall.place_top_block"); | ||||||
|  |         this.WALL_HEIGHT = Math.min(getMaxGenHeight() - (PLACE_TOP_BLOCK ? 1 : 0), config.getInt("wall.height")); | ||||||
|  |         this.CLAIMED_WALL_BLOCK = new BlockBucket(config.getString("wall.block_claimed")); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     int schematicStartHeight() { |     int schematicStartHeight() { | ||||||
|   | |||||||
| @@ -35,13 +35,23 @@ import com.plotsquared.core.plot.PlotArea; | |||||||
| import com.plotsquared.core.plot.PlotId; | import com.plotsquared.core.plot.PlotId; | ||||||
| import com.plotsquared.core.queue.ScopedQueueCoordinator; | import com.plotsquared.core.queue.ScopedQueueCoordinator; | ||||||
| import com.plotsquared.core.util.MathMan; | import com.plotsquared.core.util.MathMan; | ||||||
|  | import com.sk89q.worldedit.entity.BaseEntity; | ||||||
|  | import com.sk89q.worldedit.entity.Entity; | ||||||
|  | import com.sk89q.worldedit.extent.Extent; | ||||||
|  | import com.sk89q.worldedit.math.BlockVector3; | ||||||
|  | import com.sk89q.worldedit.math.Vector3; | ||||||
|  | import com.sk89q.worldedit.regions.CuboidRegion; | ||||||
|  | import com.sk89q.worldedit.regions.RegionOperationException; | ||||||
|  | import com.sk89q.worldedit.world.NullWorld; | ||||||
| import com.sk89q.worldedit.world.biome.BiomeType; | import com.sk89q.worldedit.world.biome.BiomeType; | ||||||
| import com.sk89q.worldedit.world.block.BaseBlock; | import com.sk89q.worldedit.world.block.BaseBlock; | ||||||
| import com.sk89q.worldedit.world.block.BlockTypes; | import com.sk89q.worldedit.world.block.BlockTypes; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
|  |  | ||||||
| public class HybridGen extends IndependentPlotGenerator { | public class HybridGen extends IndependentPlotGenerator { | ||||||
|  |  | ||||||
|  |     private static final CuboidRegion CHUNK = new CuboidRegion(BlockVector3.ZERO, BlockVector3.at(15, 396, 15)); | ||||||
|     private final HybridPlotWorldFactory hybridPlotWorldFactory; |     private final HybridPlotWorldFactory hybridPlotWorldFactory; | ||||||
|  |  | ||||||
|     @Inject |     @Inject | ||||||
| @@ -55,12 +65,17 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void placeSchem( |     private void placeSchem( | ||||||
|             HybridPlotWorld world, ScopedQueueCoordinator result, short relativeX, |             HybridPlotWorld world, | ||||||
|             short relativeZ, int x, int z, boolean isRoad |             ScopedQueueCoordinator result, | ||||||
|  |             short relativeX, | ||||||
|  |             short relativeZ, | ||||||
|  |             int x, | ||||||
|  |             int z, | ||||||
|  |             boolean isRoad, | ||||||
|  |             boolean isPopulating | ||||||
|     ) { |     ) { | ||||||
|         int minY; // Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT); |         int minY; // Math.min(world.PLOT_HEIGHT, world.ROAD_HEIGHT); | ||||||
|         if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad |         if ((isRoad && Settings.Schematics.PASTE_ROAD_ON_TOP) || (!isRoad && Settings.Schematics.PASTE_ON_TOP)) { | ||||||
|                 && Settings.Schematics.PASTE_ON_TOP)) { |  | ||||||
|             minY = world.SCHEM_Y; |             minY = world.SCHEM_Y; | ||||||
|         } else { |         } else { | ||||||
|             minY = world.getMinBuildHeight(); |             minY = world.getMinBuildHeight(); | ||||||
| @@ -69,10 +84,12 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|         if (blocks != null) { |         if (blocks != null) { | ||||||
|             for (int y = 0; y < blocks.length; y++) { |             for (int y = 0; y < blocks.length; y++) { | ||||||
|                 if (blocks[y] != null) { |                 if (blocks[y] != null) { | ||||||
|  |                     if (!isPopulating || blocks[y].hasNbtData()) { | ||||||
|                         result.setBlock(x, minY + y, z, blocks[y]); |                         result.setBlock(x, minY + y, z, blocks[y]); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |         } | ||||||
|         BiomeType biome = world.G_SCH_B.get(MathMan.pair(relativeX, relativeZ)); |         BiomeType biome = world.G_SCH_B.get(MathMan.pair(relativeX, relativeZ)); | ||||||
|         if (biome != null) { |         if (biome != null) { | ||||||
|             result.setBiome(x, z, biome); |             result.setBiome(x, z, biome); | ||||||
| @@ -91,7 +108,7 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|         if (hybridPlotWorld.PLOT_BEDROCK) { |         if (hybridPlotWorld.PLOT_BEDROCK) { | ||||||
|             for (short x = 0; x < 16; x++) { |             for (short x = 0; x < 16; x++) { | ||||||
|                 for (short z = 0; z < 16; z++) { |                 for (short z = 0; z < 16; z++) { | ||||||
|                     result.setBlock(x, 0, z, BlockTypes.BEDROCK.getDefaultState()); |                     result.setBlock(x, hybridPlotWorld.getMinGenHeight(), z, BlockTypes.BEDROCK.getDefaultState()); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -121,42 +138,38 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|         short[] relativeX = new short[16]; |         short[] relativeX = new short[16]; | ||||||
|         boolean[] insideRoadX = new boolean[16]; |         boolean[] insideRoadX = new boolean[16]; | ||||||
|         boolean[] insideWallX = new boolean[16]; |         boolean[] insideWallX = new boolean[16]; | ||||||
|  |         short offsetX = relativeOffsetX; | ||||||
|         for (short i = 0; i < 16; i++) { |         for (short i = 0; i < 16; i++) { | ||||||
|             short v = (short) (relativeOffsetX + i); |             if (offsetX >= hybridPlotWorld.SIZE) { | ||||||
|             while (v >= hybridPlotWorld.SIZE) { |                 offsetX -= hybridPlotWorld.SIZE; | ||||||
|                 v -= hybridPlotWorld.SIZE; |  | ||||||
|             } |             } | ||||||
|             relativeX[i] = v; |             relativeX[i] = offsetX; | ||||||
|             if (hybridPlotWorld.ROAD_WIDTH != 0) { |             if (hybridPlotWorld.ROAD_WIDTH != 0) { | ||||||
|                 insideRoadX[i] = |                 insideRoadX[i] = offsetX < hybridPlotWorld.PATH_WIDTH_LOWER || offsetX > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|                         v < hybridPlotWorld.PATH_WIDTH_LOWER || v > hybridPlotWorld.PATH_WIDTH_UPPER; |                 insideWallX[i] = offsetX == hybridPlotWorld.PATH_WIDTH_LOWER || offsetX == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|                 insideWallX[i] = |  | ||||||
|                         v == hybridPlotWorld.PATH_WIDTH_LOWER || v == hybridPlotWorld.PATH_WIDTH_UPPER; |  | ||||||
|             } |             } | ||||||
|  |             offsetX++; | ||||||
|         } |         } | ||||||
|         // The Z-coordinate of a given Z coordinate, relative to the |         // The Z-coordinate of a given Z coordinate, relative to the | ||||||
|         // plot (Counting from the corner with the least positive |         // plot (Counting from the corner with the least positive | ||||||
|         // coordinates) |         // coordinates) | ||||||
|         short[] relativeZ = new short[16]; |         short[] relativeZ = new short[16]; | ||||||
|         // Whether or not the given Z coordinate belongs to the road |  | ||||||
|         boolean[] insideRoadZ = new boolean[16]; |         boolean[] insideRoadZ = new boolean[16]; | ||||||
|         // Whether or not the given Z coordinate belongs to the wall |  | ||||||
|         boolean[] insideWallZ = new boolean[16]; |         boolean[] insideWallZ = new boolean[16]; | ||||||
|  |         short offsetZ = relativeOffsetZ; | ||||||
|         for (short i = 0; i < 16; i++) { |         for (short i = 0; i < 16; i++) { | ||||||
|             short v = (short) (relativeOffsetZ + i); |             if (offsetZ >= hybridPlotWorld.SIZE) { | ||||||
|             while (v >= hybridPlotWorld.SIZE) { |                 offsetZ -= hybridPlotWorld.SIZE; | ||||||
|                 v -= hybridPlotWorld.SIZE; |  | ||||||
|             } |             } | ||||||
|             relativeZ[i] = v; |             relativeZ[i] = offsetZ; | ||||||
|             if (hybridPlotWorld.ROAD_WIDTH != 0) { |             if (hybridPlotWorld.ROAD_WIDTH != 0) { | ||||||
|                 insideRoadZ[i] = |                 insideRoadZ[i] = offsetZ < hybridPlotWorld.PATH_WIDTH_LOWER || offsetZ > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|                         v < hybridPlotWorld.PATH_WIDTH_LOWER || v > hybridPlotWorld.PATH_WIDTH_UPPER; |                 insideWallZ[i] = offsetZ == hybridPlotWorld.PATH_WIDTH_LOWER || offsetZ == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|                 insideWallZ[i] = |  | ||||||
|                         v == hybridPlotWorld.PATH_WIDTH_LOWER || v == hybridPlotWorld.PATH_WIDTH_UPPER; |  | ||||||
|             } |             } | ||||||
|  |             offsetZ++; | ||||||
|         } |         } | ||||||
|         // generation |         // generation | ||||||
|         int startY = hybridPlotWorld.PLOT_BEDROCK ? 1 : 0; |         int startY = hybridPlotWorld.getMinGenHeight() + (hybridPlotWorld.PLOT_BEDROCK ? 1 : 0); | ||||||
|         for (short x = 0; x < 16; x++) { |         for (short x = 0; x < 16; x++) { | ||||||
|             if (insideRoadX[x]) { |             if (insideRoadX[x]) { | ||||||
|                 for (short z = 0; z < 16; z++) { |                 for (short z = 0; z < 16; z++) { | ||||||
| @@ -165,7 +178,7 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                         result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); |                         result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); | ||||||
|                     } |                     } | ||||||
|                     if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                     if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true); |                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } else if (insideWallX[x]) { |             } else if (insideWallX[x]) { | ||||||
| @@ -176,9 +189,7 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); |                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); | ||||||
|                         } |                         } | ||||||
|                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||||
|                                     true |  | ||||||
|                             ); |  | ||||||
|                         } |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         // wall |                         // wall | ||||||
| @@ -187,14 +198,10 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                         } |                         } | ||||||
|                         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                             if (hybridPlotWorld.PLACE_TOP_BLOCK) { |                             if (hybridPlotWorld.PLACE_TOP_BLOCK) { | ||||||
|                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, |                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, hybridPlotWorld.WALL_BLOCK.toPattern()); | ||||||
|                                         hybridPlotWorld.WALL_BLOCK.toPattern() |  | ||||||
|                                 ); |  | ||||||
|                             } |                             } | ||||||
|                         } else { |                         } else { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||||
|                                     true |  | ||||||
|                             ); |  | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @@ -206,9 +213,7 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); |                             result.setBlock(x, y, z, hybridPlotWorld.ROAD_BLOCK.toPattern()); | ||||||
|                         } |                         } | ||||||
|                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||||
|                                     true |  | ||||||
|                             ); |  | ||||||
|                         } |                         } | ||||||
|                     } else if (insideWallZ[z]) { |                     } else if (insideWallZ[z]) { | ||||||
|                         // wall |                         // wall | ||||||
| @@ -217,27 +222,19 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|                         } |                         } | ||||||
|                         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |                         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|                             if (hybridPlotWorld.PLACE_TOP_BLOCK) { |                             if (hybridPlotWorld.PLACE_TOP_BLOCK) { | ||||||
|                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, |                                 result.setBlock(x, hybridPlotWorld.WALL_HEIGHT + 1, z, hybridPlotWorld.WALL_BLOCK.toPattern()); | ||||||
|                                         hybridPlotWorld.WALL_BLOCK.toPattern() |  | ||||||
|                                 ); |  | ||||||
|                             } |                             } | ||||||
|                         } else { |                         } else { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, false); | ||||||
|                                     true |  | ||||||
|                             ); |  | ||||||
|                         } |                         } | ||||||
|                     } else { |                     } else { | ||||||
|                         // plot |                         // plot | ||||||
|                         for (int y = startY; y < hybridPlotWorld.PLOT_HEIGHT; y++) { |                         for (int y = startY; y < hybridPlotWorld.PLOT_HEIGHT; y++) { | ||||||
|                             result.setBlock(x, y, z, hybridPlotWorld.MAIN_BLOCK.toPattern()); |                             result.setBlock(x, y, z, hybridPlotWorld.MAIN_BLOCK.toPattern()); | ||||||
|                         } |                         } | ||||||
|                         result.setBlock(x, hybridPlotWorld.PLOT_HEIGHT, z, |                         result.setBlock(x, hybridPlotWorld.PLOT_HEIGHT, z, hybridPlotWorld.TOP_BLOCK.toPattern()); | ||||||
|                                 hybridPlotWorld.TOP_BLOCK.toPattern() |  | ||||||
|                         ); |  | ||||||
|                         if (hybridPlotWorld.PLOT_SCHEMATIC) { |                         if (hybridPlotWorld.PLOT_SCHEMATIC) { | ||||||
|                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, false, false); | ||||||
|                                     false |  | ||||||
|                             ); |  | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @@ -245,6 +242,138 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean populateChunk(final ScopedQueueCoordinator result, final PlotArea settings) { | ||||||
|  |         HybridPlotWorld hybridPlotWorld = (HybridPlotWorld) settings; | ||||||
|  |         if (!hybridPlotWorld.populationNeeded()) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|  |         // Coords | ||||||
|  |         Location min = result.getMin(); | ||||||
|  |         int bx = min.getX() - hybridPlotWorld.ROAD_OFFSET_X; | ||||||
|  |         int bz = min.getZ() - hybridPlotWorld.ROAD_OFFSET_Z; | ||||||
|  |         // The relative X-coordinate (within the plot) of the minimum X coordinate | ||||||
|  |         // contained in the scoped queue | ||||||
|  |         short relativeOffsetX; | ||||||
|  |         if (bx < 0) { | ||||||
|  |             relativeOffsetX = (short) (hybridPlotWorld.SIZE + (bx % hybridPlotWorld.SIZE)); | ||||||
|  |         } else { | ||||||
|  |             relativeOffsetX = (short) (bx % hybridPlotWorld.SIZE); | ||||||
|  |         } | ||||||
|  |         // The relative Z-coordinate (within the plot) of the minimum Z coordinate | ||||||
|  |         // contained in the scoped queue | ||||||
|  |         short relativeOffsetZ; | ||||||
|  |         if (bz < 0) { | ||||||
|  |             relativeOffsetZ = (short) (hybridPlotWorld.SIZE + (bz % hybridPlotWorld.SIZE)); | ||||||
|  |         } else { | ||||||
|  |             relativeOffsetZ = (short) (bz % hybridPlotWorld.SIZE); | ||||||
|  |         } | ||||||
|  |         boolean allRoad = true; | ||||||
|  |         boolean overlap = false; | ||||||
|  |  | ||||||
|  |         // The X-coordinate of a given X coordinate, relative to the | ||||||
|  |         // plot (Counting from the corner with the least positive | ||||||
|  |         // coordinates) | ||||||
|  |         short[] relativeX = new short[16]; | ||||||
|  |         boolean[] insideRoadX = new boolean[16]; | ||||||
|  |         boolean[] insideWallX = new boolean[16]; | ||||||
|  |         short offsetX = relativeOffsetX; | ||||||
|  |         for (short i = 0; i < 16; i++) { | ||||||
|  |             if (offsetX >= hybridPlotWorld.SIZE) { | ||||||
|  |                 offsetX -= hybridPlotWorld.SIZE; | ||||||
|  |                 overlap = true; | ||||||
|  |             } | ||||||
|  |             relativeX[i] = offsetX; | ||||||
|  |             if (hybridPlotWorld.ROAD_WIDTH != 0) { | ||||||
|  |                 boolean insideRoad = offsetX < hybridPlotWorld.PATH_WIDTH_LOWER || offsetX > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|  |                 boolean insideWall = offsetX == hybridPlotWorld.PATH_WIDTH_LOWER || offsetX == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|  |                 insideRoadX[i] = insideRoad; | ||||||
|  |                 insideWallX[i] = insideWall; | ||||||
|  |                 allRoad &= insideRoad && insideWall; | ||||||
|  |             } | ||||||
|  |             offsetX++; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // The Z-coordinate of a given Z coordinate, relative to the | ||||||
|  |         // plot (Counting from the corner with the least positive | ||||||
|  |         // coordinates) | ||||||
|  |         short[] relativeZ = new short[16]; | ||||||
|  |         boolean[] insideRoadZ = new boolean[16]; | ||||||
|  |         boolean[] insideWallZ = new boolean[16]; | ||||||
|  |         short offsetZ = relativeOffsetZ; | ||||||
|  |         for (short i = 0; i < 16; i++) { | ||||||
|  |             if (offsetZ >= hybridPlotWorld.SIZE) { | ||||||
|  |                 offsetZ -= hybridPlotWorld.SIZE; | ||||||
|  |                 overlap = true; | ||||||
|  |             } | ||||||
|  |             relativeZ[i] = offsetZ; | ||||||
|  |             if (hybridPlotWorld.ROAD_WIDTH != 0) { | ||||||
|  |                 boolean insideRoad = offsetZ < hybridPlotWorld.PATH_WIDTH_LOWER || offsetZ > hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|  |                 boolean insideWall = offsetZ == hybridPlotWorld.PATH_WIDTH_LOWER || offsetZ == hybridPlotWorld.PATH_WIDTH_UPPER; | ||||||
|  |                 insideRoadZ[i] = insideRoad; | ||||||
|  |                 insideWallZ[i] = insideWall; | ||||||
|  |                 allRoad &= insideRoad && insideWall; | ||||||
|  |             } | ||||||
|  |             offsetZ++; | ||||||
|  |         } | ||||||
|  |         for (short x = 0; x < 16; x++) { | ||||||
|  |             if (insideRoadX[x] || insideWallX[x]) { | ||||||
|  |                 if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|  |                     for (short z = 0; z < 16; z++) { | ||||||
|  |                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, true); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } else { | ||||||
|  |                 for (short z = 0; z < 16; z++) { | ||||||
|  |                     if (insideRoadZ[z] || insideWallZ[z]) { | ||||||
|  |                         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|  |                             placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, true, true); | ||||||
|  |                         } | ||||||
|  |                     } else if (hybridPlotWorld.PLOT_SCHEMATIC) { | ||||||
|  |                         placeSchem(hybridPlotWorld, result, relativeX[x], relativeZ[z], x, z, false, true); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         if (!allRoad && hybridPlotWorld.getPlotSchematicEntities() != null && !hybridPlotWorld | ||||||
|  |                 .getPlotSchematicEntities() | ||||||
|  |                 .isEmpty()) { | ||||||
|  |             CuboidRegion region = CHUNK.clone(); | ||||||
|  |             try { | ||||||
|  |                 region.shift(hybridPlotWorld | ||||||
|  |                         .getPlotSchematicMinPoint() | ||||||
|  |                         .add(relativeOffsetX, 0, relativeOffsetZ) | ||||||
|  |                         .subtract(hybridPlotWorld.PATH_WIDTH_LOWER + 1, 0, hybridPlotWorld.PATH_WIDTH_LOWER + 1)); | ||||||
|  |                 for (Entity entity : hybridPlotWorld.getPlotSchematicEntities()) { | ||||||
|  |                     if (region.contains(entity.getLocation().toVector().toBlockPoint())) { | ||||||
|  |                         Vector3 pos = (entity.getLocation().toVector() | ||||||
|  |                                 .subtract(region.getMinimumPoint().withY(hybridPlotWorld.getPlotSchematicMinPoint().getY()).toVector3())) | ||||||
|  |                                 .add(min.getBlockVector3().withY(hybridPlotWorld.SCHEM_Y).toVector3()); | ||||||
|  |                         result.setEntity(new PopulatingEntity( | ||||||
|  |                                 entity, | ||||||
|  |                                 new com.sk89q.worldedit.util.Location(NullWorld.getInstance(), pos) | ||||||
|  |                         )); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } catch (RegionOperationException e) { | ||||||
|  |                 throw new RuntimeException(e); | ||||||
|  |             } | ||||||
|  |             if (overlap) { | ||||||
|  |                 try { | ||||||
|  |                     region.shift(BlockVector3.at(-hybridPlotWorld.SIZE, 0, -hybridPlotWorld.SIZE)); | ||||||
|  |                     for (Entity entity : hybridPlotWorld.getPlotSchematicEntities()) { | ||||||
|  |                         if (region.contains(entity.getLocation().toVector().toBlockPoint())) { | ||||||
|  |                             result.setEntity(entity); | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                 } catch (RegionOperationException e) { | ||||||
|  |                     throw new RuntimeException(e); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public PlotArea getNewPlotArea(String world, String id, PlotId min, PlotId max) { |     public PlotArea getNewPlotArea(String world, String id, PlotId min, PlotId max) { | ||||||
|         return this.hybridPlotWorldFactory.create(world, id, this, min, max); |         return this.hybridPlotWorldFactory.create(world, id, this, min, max); | ||||||
| @@ -255,4 +384,58 @@ public class HybridGen extends IndependentPlotGenerator { | |||||||
|         // All initialization is done in the PlotArea class |         // All initialization is done in the PlotArea class | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Wrapper to allow a WorldEdit {@link Entity} to effectively have a mutable location as the location in its NBT should be changed | ||||||
|  |      * when set to the world. | ||||||
|  |      * | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     private static final class PopulatingEntity implements Entity { | ||||||
|  |  | ||||||
|  |         private final Entity parent; | ||||||
|  |         private com.sk89q.worldedit.util.Location location; | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * @since TODO | ||||||
|  |          */ | ||||||
|  |         private PopulatingEntity(Entity parent, com.sk89q.worldedit.util.Location location) { | ||||||
|  |             this.parent = parent; | ||||||
|  |             this.location = location; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Nullable | ||||||
|  |         @Override | ||||||
|  |         public BaseEntity getState() { | ||||||
|  |             return parent.getState(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public boolean remove() { | ||||||
|  |             return parent.remove(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public com.sk89q.worldedit.util.Location getLocation() { | ||||||
|  |             return location; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public boolean setLocation(final com.sk89q.worldedit.util.Location location) { | ||||||
|  |             this.location = location; | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public Extent getExtent() { | ||||||
|  |             return parent.getExtent(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Nullable | ||||||
|  |         @Override | ||||||
|  |         public <T> T getFacet(final Class<? extends T> cls) { | ||||||
|  |             return parent.getFacet(cls); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -46,7 +46,6 @@ import com.sk89q.worldedit.function.pattern.Pattern; | |||||||
| import com.sk89q.worldedit.regions.CuboidRegion; | import com.sk89q.worldedit.regions.CuboidRegion; | ||||||
| import com.sk89q.worldedit.world.biome.BiomeType; | import com.sk89q.worldedit.world.biome.BiomeType; | ||||||
| import com.sk89q.worldedit.world.block.BaseBlock; | import com.sk89q.worldedit.world.block.BaseBlock; | ||||||
| import com.sk89q.worldedit.world.block.BlockState; |  | ||||||
| import com.sk89q.worldedit.world.block.BlockTypes; | import com.sk89q.worldedit.world.block.BlockTypes; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
| import org.checkerframework.checker.nullness.qual.Nullable; | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
| @@ -107,22 +106,32 @@ public class HybridPlotManager extends ClassicPlotManager { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean createRoadEast(final @NonNull Plot plot, @Nullable QueueCoordinator queue) { |     public boolean createRoadEast(final @NonNull Plot plot, @Nullable QueueCoordinator queue) { | ||||||
|  |         boolean enqueue = false; | ||||||
|  |         if (queue == null) { | ||||||
|  |             queue = hybridPlotWorld.getQueue(); | ||||||
|  |             enqueue = true; | ||||||
|  |         } | ||||||
|         super.createRoadEast(plot, queue); |         super.createRoadEast(plot, queue); | ||||||
|         PlotId id = plot.getId(); |         PlotId id = plot.getId(); | ||||||
|         PlotId id2 = PlotId.of(id.getX() + 1, id.getY()); |         PlotId id2 = PlotId.of(id.getX() + 1, id.getY()); | ||||||
|         Location bot = getPlotBottomLocAbs(id2); |         Location bot = getPlotBottomLocAbs(id2); | ||||||
|         Location top = getPlotTopLocAbs(id); |         Location top = getPlotTopLocAbs(id); | ||||||
|         Location pos1 = Location.at(hybridPlotWorld.getWorldName(), top.getX() + 1, 0, bot.getZ() - 1); |         Location pos1 = Location.at( | ||||||
|         Location pos2 = Location.at(hybridPlotWorld.getWorldName(), bot.getX(), Math.min(getWorldHeight(), 255), top.getZ() + 1); |                 hybridPlotWorld.getWorldName(), | ||||||
|  |                 top.getX() + 1, | ||||||
|  |                 hybridPlotWorld.getMinGenHeight(), | ||||||
|  |                 bot.getZ() - 1 | ||||||
|  |         ); | ||||||
|  |         Location pos2 = Location.at( | ||||||
|  |                 hybridPlotWorld.getWorldName(), | ||||||
|  |                 bot.getX(), | ||||||
|  |                 hybridPlotWorld.getMaxGenHeight(), | ||||||
|  |                 top.getZ() + 1 | ||||||
|  |         ); | ||||||
|         this.resetBiome(hybridPlotWorld, pos1, pos2); |         this.resetBiome(hybridPlotWorld, pos1, pos2); | ||||||
|         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|         boolean enqueue = false; |  | ||||||
|         if (queue == null) { |  | ||||||
|             queue = hybridPlotWorld.getQueue(); |  | ||||||
|             enqueue = true; |  | ||||||
|         } |  | ||||||
|         createSchemAbs(queue, pos1, pos2, true); |         createSchemAbs(queue, pos1, pos2, true); | ||||||
|         return !enqueue || queue.enqueue(); |         return !enqueue || queue.enqueue(); | ||||||
|     } |     } | ||||||
| @@ -139,7 +148,7 @@ public class HybridPlotManager extends ClassicPlotManager { | |||||||
|                         (pos1.getX() + pos2.getX()) / 2, |                         (pos1.getX() + pos2.getX()) / 2, | ||||||
|                         (pos1.getZ() + pos2.getZ()) / 2 |                         (pos1.getZ() + pos2.getZ()) / 2 | ||||||
|                 ), biome)) { |                 ), biome)) { | ||||||
|             WorldUtil.setBiome(hybridPlotWorld.getWorldName(), pos1.getX(), pos1.getZ(), pos2.getX(), pos2.getZ(), biome); |             WorldUtil.setBiome(hybridPlotWorld.getWorldName(), new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()), biome); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -190,38 +199,38 @@ public class HybridPlotManager extends ClassicPlotManager { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean createRoadSouth(final @NonNull Plot plot, @Nullable QueueCoordinator queue) { |     public boolean createRoadSouth(final @NonNull Plot plot, @Nullable QueueCoordinator queue) { | ||||||
|  |         boolean enqueue = false; | ||||||
|  |         if (queue == null) { | ||||||
|  |             enqueue = true; | ||||||
|  |             queue = hybridPlotWorld.getQueue(); | ||||||
|  |         } | ||||||
|         super.createRoadSouth(plot, queue); |         super.createRoadSouth(plot, queue); | ||||||
|         PlotId id = plot.getId(); |         PlotId id = plot.getId(); | ||||||
|         PlotId id2 = PlotId.of(id.getX(), id.getY() + 1); |         PlotId id2 = PlotId.of(id.getX(), id.getY() + 1); | ||||||
|         Location bot = getPlotBottomLocAbs(id2); |         Location bot = getPlotBottomLocAbs(id2); | ||||||
|         Location top = getPlotTopLocAbs(id); |         Location top = getPlotTopLocAbs(id); | ||||||
|         Location pos1 = Location.at(hybridPlotWorld.getWorldName(), bot.getX() - 1, 0, top.getZ() + 1); |         Location pos1 = Location.at(hybridPlotWorld.getWorldName(), bot.getX() - 1, hybridPlotWorld.getMinGenHeight(), top.getZ() + 1); | ||||||
|         Location pos2 = Location.at(hybridPlotWorld.getWorldName(), top.getX() + 1, Math.min(getWorldHeight(), 255), bot.getZ()); |         Location pos2 = Location.at(hybridPlotWorld.getWorldName(), top.getX() + 1, hybridPlotWorld.getMaxGenHeight(), bot.getZ()); | ||||||
|         this.resetBiome(hybridPlotWorld, pos1, pos2); |         this.resetBiome(hybridPlotWorld, pos1, pos2); | ||||||
|         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |         if (!hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|         boolean enqueue = false; |  | ||||||
|         if (queue == null) { |  | ||||||
|             enqueue = true; |  | ||||||
|             queue = hybridPlotWorld.getQueue(); |  | ||||||
|         } |  | ||||||
|         createSchemAbs(queue, pos1, pos2, true); |         createSchemAbs(queue, pos1, pos2, true); | ||||||
|         return !enqueue || queue.enqueue(); |         return !enqueue || queue.enqueue(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean createRoadSouthEast(final @NonNull Plot plot, @Nullable QueueCoordinator queue) { |     public boolean createRoadSouthEast(final @NonNull Plot plot, @Nullable QueueCoordinator queue) { | ||||||
|         super.createRoadSouthEast(plot, queue); |  | ||||||
|         PlotId id = plot.getId(); |  | ||||||
|         PlotId id2 = PlotId.of(id.getX() + 1, id.getY() + 1); |  | ||||||
|         Location pos1 = getPlotTopLocAbs(id).add(1, 0, 1).withY(0); |  | ||||||
|         Location pos2 = getPlotBottomLocAbs(id2).withY(Math.min(getWorldHeight(), 255)); |  | ||||||
|         boolean enqueue = false; |         boolean enqueue = false; | ||||||
|         if (queue == null) { |         if (queue == null) { | ||||||
|             enqueue = true; |             enqueue = true; | ||||||
|             queue = hybridPlotWorld.getQueue(); |             queue = hybridPlotWorld.getQueue(); | ||||||
|         } |         } | ||||||
|  |         super.createRoadSouthEast(plot, queue); | ||||||
|  |         PlotId id = plot.getId(); | ||||||
|  |         PlotId id2 = PlotId.of(id.getX() + 1, id.getY() + 1); | ||||||
|  |         Location pos1 = getPlotTopLocAbs(id).add(1, 0, 1); | ||||||
|  |         Location pos2 = getPlotBottomLocAbs(id2); | ||||||
|         createSchemAbs(queue, pos1, pos2, true); |         createSchemAbs(queue, pos1, pos2, true); | ||||||
|         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { |         if (hybridPlotWorld.ROAD_SCHEMATIC_ENABLED) { | ||||||
|             createSchemAbs(queue, pos1, pos2, true); |             createSchemAbs(queue, pos1, pos2, true); | ||||||
| @@ -271,11 +280,23 @@ public class HybridPlotManager extends ClassicPlotManager { | |||||||
|             queue.setCompleteTask(whenDone); |             queue.setCompleteTask(whenDone); | ||||||
|         } |         } | ||||||
|         if (!canRegen) { |         if (!canRegen) { | ||||||
|             queue.setCuboid(pos1.withY(0), pos2.withY(0), bedrock); |             queue.setCuboid( | ||||||
|  |                     pos1.withY(hybridPlotWorld.getMinGenHeight()), | ||||||
|  |                     pos2.withY(hybridPlotWorld.getMinGenHeight()), | ||||||
|  |                     hybridPlotWorld.PLOT_BEDROCK ? bedrock : filling | ||||||
|  |             ); | ||||||
|             // Each component has a different layer |             // Each component has a different layer | ||||||
|             queue.setCuboid(pos1.withY(1), pos2.withY(hybridPlotWorld.PLOT_HEIGHT - 1), filling); |             queue.setCuboid( | ||||||
|  |                     pos1.withY(hybridPlotWorld.getMinGenHeight() + 1), | ||||||
|  |                     pos2.withY(hybridPlotWorld.PLOT_HEIGHT - 1), | ||||||
|  |                     filling | ||||||
|  |             ); | ||||||
|             queue.setCuboid(pos1.withY(hybridPlotWorld.PLOT_HEIGHT), pos2.withY(hybridPlotWorld.PLOT_HEIGHT), plotfloor); |             queue.setCuboid(pos1.withY(hybridPlotWorld.PLOT_HEIGHT), pos2.withY(hybridPlotWorld.PLOT_HEIGHT), plotfloor); | ||||||
|             queue.setCuboid(pos1.withY(hybridPlotWorld.PLOT_HEIGHT + 1), pos2.withY(getWorldHeight()), BlockTypes.AIR.getDefaultState()); |             queue.setCuboid( | ||||||
|  |                     pos1.withY(hybridPlotWorld.PLOT_HEIGHT + 1), | ||||||
|  |                     pos2.withY(hybridPlotWorld.getMaxGenHeight()), | ||||||
|  |                     BlockTypes.AIR.getDefaultState() | ||||||
|  |             ); | ||||||
|             queue.setBiomeCuboid(pos1, pos2, biome); |             queue.setBiomeCuboid(pos1, pos2, biome); | ||||||
|         } else { |         } else { | ||||||
|             queue.setRegenRegion(new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3())); |             queue.setRegenRegion(new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3())); | ||||||
|   | |||||||
| @@ -40,11 +40,13 @@ import com.plotsquared.core.plot.PlotId; | |||||||
| import com.plotsquared.core.plot.PlotManager; | import com.plotsquared.core.plot.PlotManager; | ||||||
| import com.plotsquared.core.plot.schematic.Schematic; | import com.plotsquared.core.plot.schematic.Schematic; | ||||||
| import com.plotsquared.core.queue.GlobalBlockQueue; | import com.plotsquared.core.queue.GlobalBlockQueue; | ||||||
|  | import com.plotsquared.core.util.AnnotationHelper; | ||||||
| import com.plotsquared.core.util.FileUtils; | import com.plotsquared.core.util.FileUtils; | ||||||
| import com.plotsquared.core.util.MathMan; | import com.plotsquared.core.util.MathMan; | ||||||
| import com.plotsquared.core.util.SchematicHandler; | import com.plotsquared.core.util.SchematicHandler; | ||||||
| import com.sk89q.jnbt.CompoundTag; | import com.sk89q.jnbt.CompoundTag; | ||||||
| import com.sk89q.jnbt.CompoundTagBuilder; | import com.sk89q.jnbt.CompoundTagBuilder; | ||||||
|  | import com.sk89q.worldedit.entity.Entity; | ||||||
| import com.sk89q.worldedit.extent.clipboard.Clipboard; | import com.sk89q.worldedit.extent.clipboard.Clipboard; | ||||||
| import com.sk89q.worldedit.extent.transform.BlockTransformExtent; | import com.sk89q.worldedit.extent.transform.BlockTransformExtent; | ||||||
| import com.sk89q.worldedit.internal.helper.MCDirections; | import com.sk89q.worldedit.internal.helper.MCDirections; | ||||||
| @@ -58,11 +60,13 @@ import com.sk89q.worldedit.world.block.BaseBlock; | |||||||
| import org.apache.logging.log4j.LogManager; | import org.apache.logging.log4j.LogManager; | ||||||
| import org.apache.logging.log4j.Logger; | import org.apache.logging.log4j.Logger; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
|  |  | ||||||
| import javax.annotation.Nullable; |  | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.lang.reflect.Field; | import java.lang.reflect.Field; | ||||||
|  | import java.util.ArrayList; | ||||||
| import java.util.HashMap; | import java.util.HashMap; | ||||||
|  | import java.util.List; | ||||||
| import java.util.Locale; | import java.util.Locale; | ||||||
|  |  | ||||||
| public class HybridPlotWorld extends ClassicPlotWorld { | public class HybridPlotWorld extends ClassicPlotWorld { | ||||||
| @@ -71,6 +75,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|     private static final AffineTransform transform = new AffineTransform().rotateY(90); |     private static final AffineTransform transform = new AffineTransform().rotateY(90); | ||||||
|     public boolean ROAD_SCHEMATIC_ENABLED; |     public boolean ROAD_SCHEMATIC_ENABLED; | ||||||
|     public boolean PLOT_SCHEMATIC = false; |     public boolean PLOT_SCHEMATIC = false; | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public int PLOT_SCHEMATIC_HEIGHT = -1; |     public int PLOT_SCHEMATIC_HEIGHT = -1; | ||||||
|     public short PATH_WIDTH_LOWER; |     public short PATH_WIDTH_LOWER; | ||||||
|     public short PATH_WIDTH_UPPER; |     public short PATH_WIDTH_UPPER; | ||||||
| @@ -79,6 +84,12 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|     public int SCHEM_Y; |     public int SCHEM_Y; | ||||||
|     private Location SIGN_LOCATION; |     private Location SIGN_LOCATION; | ||||||
|     private File root = null; |     private File root = null; | ||||||
|  |     private int lastOverlayHeightError = Integer.MIN_VALUE; | ||||||
|  |     private List<Entity> schem3Entities = null; | ||||||
|  |     private BlockVector3 schem3MinPoint = null; | ||||||
|  |     private boolean schem1PopulationNeeded = false; | ||||||
|  |     private boolean schem2PopulationNeeded = false; | ||||||
|  |     private boolean schem3PopulationNeeded = false; | ||||||
|  |  | ||||||
|     @Inject |     @Inject | ||||||
|     private SchematicHandler schematicHandler; |     private SchematicHandler schematicHandler; | ||||||
| @@ -97,6 +108,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|         PlotSquared.platform().injector().injectMembers(this); |         PlotSquared.platform().injector().injectMembers(this); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public static byte wrap(byte data, int start) { |     public static byte wrap(byte data, int start) { | ||||||
|         if ((data >= start) && (data < (start + 4))) { |         if ((data >= start) && (data < (start + 4))) { | ||||||
|             data = (byte) ((((data - start) + 2) & 3) + start); |             data = (byte) ((((data - start) + 2) & 3) + start); | ||||||
| @@ -104,6 +116,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|         return data; |         return data; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public static byte wrap2(byte data, int start) { |     public static byte wrap2(byte data, int start) { | ||||||
|         if ((data >= start) && (data < (start + 2))) { |         if ((data >= start) && (data < (start + 2))) { | ||||||
|             data = (byte) ((((data - start) + 1) & 1) + start); |             data = (byte) ((((data - start) + 1) & 1) + start); | ||||||
| @@ -111,8 +124,6 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|         return data; |         return data; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     // FIXME depends on block ids |  | ||||||
|     // Possibly make abstract? |  | ||||||
|     public static BaseBlock rotate(BaseBlock id) { |     public static BaseBlock rotate(BaseBlock id) { | ||||||
|  |  | ||||||
|         CompoundTag tag = id.getNbtData(); |         CompoundTag tag = id.getNbtData(); | ||||||
| @@ -171,9 +182,9 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|     public void loadConfiguration(ConfigurationSection config) { |     public void loadConfiguration(ConfigurationSection config) { | ||||||
|         super.loadConfiguration(config); |         super.loadConfiguration(config); | ||||||
|         if ((this.ROAD_WIDTH & 1) == 0) { |         if ((this.ROAD_WIDTH & 1) == 0) { | ||||||
|             this.PATH_WIDTH_LOWER = (short) (Math.floor(this.ROAD_WIDTH / 2) - 1); |             this.PATH_WIDTH_LOWER = (short) (Math.floor(this.ROAD_WIDTH / 2f) - 1); | ||||||
|         } else { |         } else { | ||||||
|             this.PATH_WIDTH_LOWER = (short) Math.floor(this.ROAD_WIDTH / 2); |             this.PATH_WIDTH_LOWER = (short) Math.floor(this.ROAD_WIDTH / 2f); | ||||||
|         } |         } | ||||||
|         if (this.ROAD_WIDTH == 0) { |         if (this.ROAD_WIDTH == 0) { | ||||||
|             this.PATH_WIDTH_UPPER = (short) (this.SIZE + 1); |             this.PATH_WIDTH_UPPER = (short) (this.SIZE + 1); | ||||||
| @@ -250,32 +261,43 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|         Schematic schematic1 = this.schematicHandler.getSchematic(schematic1File); |         Schematic schematic1 = this.schematicHandler.getSchematic(schematic1File); | ||||||
|         Schematic schematic2 = this.schematicHandler.getSchematic(schematic2File); |         Schematic schematic2 = this.schematicHandler.getSchematic(schematic2File); | ||||||
|         Schematic schematic3 = this.schematicHandler.getSchematic(schematic3File); |         Schematic schematic3 = this.schematicHandler.getSchematic(schematic3File); | ||||||
|  |  | ||||||
|  |         // If the plot schematic contains entities, then they need to be populated upon generation. | ||||||
|  |         if (schematic3 != null && !schematic3.getClipboard().getEntities().isEmpty()) { | ||||||
|  |             this.schem3Entities = new ArrayList<>(schematic3.getClipboard().getEntities()); | ||||||
|  |             this.schem3MinPoint = schematic3.getClipboard().getMinimumPoint(); | ||||||
|  |             this.schem3PopulationNeeded = true; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         int shift = this.ROAD_WIDTH / 2; |         int shift = this.ROAD_WIDTH / 2; | ||||||
|         int oddshift = (this.ROAD_WIDTH & 1) == 0 ? 0 : 1; |         int oddshift = (this.ROAD_WIDTH & 1); | ||||||
|  |  | ||||||
|         SCHEM_Y = schematicStartHeight(); |         SCHEM_Y = schematicStartHeight(); | ||||||
|         int plotY = PLOT_HEIGHT - SCHEM_Y; |         int plotY = PLOT_HEIGHT - SCHEM_Y; | ||||||
|         int minRoadWall = Settings.Schematics.USE_WALL_IN_ROAD_SCHEM_HEIGHT ? Math.min(ROAD_HEIGHT, WALL_HEIGHT) : ROAD_HEIGHT; |         int minRoadWall = Settings.Schematics.USE_WALL_IN_ROAD_SCHEM_HEIGHT ? Math.min(ROAD_HEIGHT, WALL_HEIGHT) : ROAD_HEIGHT; | ||||||
|         int roadY = minRoadWall - SCHEM_Y; |         int roadY = minRoadWall - SCHEM_Y; | ||||||
|  |  | ||||||
|  |         int worldHeight = getMaxGenHeight() - getMinGenHeight() + 1; | ||||||
|  |  | ||||||
|  |         // SCHEM_Y should be normalised to the plot "start" height | ||||||
|         if (schematic3 != null) { |         if (schematic3 != null) { | ||||||
|             if (schematic3.getClipboard().getDimensions().getY() == 256) { |             if (schematic3.getClipboard().getDimensions().getY() == worldHeight) { | ||||||
|                 SCHEM_Y = plotY = 0; |                 SCHEM_Y = plotY = 0; | ||||||
|             } else if (!Settings.Schematics.PASTE_ON_TOP) { |             } else if (!Settings.Schematics.PASTE_ON_TOP) { | ||||||
|                 SCHEM_Y = plotY = getMinBuildHeight(); |                 SCHEM_Y = plotY = getMinBuildHeight() - getMinGenHeight(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         if (schematic1 != null) { |         if (schematic1 != null) { | ||||||
|             if (schematic1.getClipboard().getDimensions().getY() == 256) { |             if (schematic1.getClipboard().getDimensions().getY() == worldHeight) { | ||||||
|                 SCHEM_Y = roadY = 0; |                 SCHEM_Y = roadY = getMinGenHeight(); | ||||||
|                 if (schematic3 != null && schematic3.getClipboard().getDimensions().getY() != 256 |                 if (schematic3 != null && schematic3.getClipboard().getDimensions().getY() != worldHeight | ||||||
|                         && !Settings.Schematics.PASTE_ON_TOP) { |                         && !Settings.Schematics.PASTE_ON_TOP) { | ||||||
|                     plotY = PLOT_HEIGHT; |                     plotY = PLOT_HEIGHT; | ||||||
|                 } |                 } | ||||||
|             } else if (!Settings.Schematics.PASTE_ROAD_ON_TOP) { |             } else if (!Settings.Schematics.PASTE_ROAD_ON_TOP) { | ||||||
|                 SCHEM_Y = roadY = getMinBuildHeight(); |                 SCHEM_Y = roadY = getMinBuildHeight(); | ||||||
|                 if (schematic3 != null && schematic3.getClipboard().getDimensions().getY() != 256 |                 if (schematic3 != null && schematic3.getClipboard().getDimensions().getY() != worldHeight | ||||||
|                         && !Settings.Schematics.PASTE_ON_TOP) { |                         && !Settings.Schematics.PASTE_ON_TOP) { | ||||||
|                     plotY = PLOT_HEIGHT; |                     plotY = PLOT_HEIGHT; | ||||||
|                 } |                 } | ||||||
| @@ -310,19 +332,28 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|             for (short x = 0; x < w3; x++) { |             for (short x = 0; x < w3; x++) { | ||||||
|                 for (short z = 0; z < l3; z++) { |                 for (short z = 0; z < l3; z++) { | ||||||
|                     for (short y = 0; y < h3; y++) { |                     for (short y = 0; y < h3; y++) { | ||||||
|                         BaseBlock id = |                         BaseBlock id = blockArrayClipboard3.getFullBlock(BlockVector3.at( | ||||||
|                                 blockArrayClipboard3.getFullBlock(BlockVector3.at( |  | ||||||
|                                 x + min.getBlockX(), |                                 x + min.getBlockX(), | ||||||
|                                 y + min.getBlockY(), |                                 y + min.getBlockY(), | ||||||
|                                 z + min.getBlockZ() |                                 z + min.getBlockZ() | ||||||
|                         )); |                         )); | ||||||
|                         if (!id.getBlockType().getMaterial().isAir()) { |                         if (!id.getBlockType().getMaterial().isAir()) { | ||||||
|                             addOverlayBlock((short) (x + shift + oddshift + centerShiftX), (short) (y + plotY), |                             schem3PopulationNeeded |= id.hasNbtData(); | ||||||
|                                     (short) (z + shift + oddshift + centerShiftZ), id, false, h3 |                             addOverlayBlock( | ||||||
|  |                                     (short) (x + shift + oddshift + centerShiftX), | ||||||
|  |                                     (short) (y + plotY), | ||||||
|  |                                     (short) (z + shift + oddshift + centerShiftZ), | ||||||
|  |                                     id, | ||||||
|  |                                     false, | ||||||
|  |                                     h3 | ||||||
|                             ); |                             ); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                     BiomeType biome = blockArrayClipboard3.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); |                     if (blockArrayClipboard3.hasBiomes()) { | ||||||
|  |                         BiomeType biome = blockArrayClipboard3.getBiome(BlockVector2.at( | ||||||
|  |                                 x + min.getBlockX(), | ||||||
|  |                                 z + min.getBlockZ() | ||||||
|  |                         )); | ||||||
|                         addOverlayBiome( |                         addOverlayBiome( | ||||||
|                                 (short) (x + shift + oddshift + centerShiftX), |                                 (short) (x + shift + oddshift + centerShiftX), | ||||||
|                                 (short) (z + shift + oddshift + centerShiftZ), |                                 (short) (z + shift + oddshift + centerShiftZ), | ||||||
| @@ -330,12 +361,13 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|                         ); |                         ); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|             if (Settings.DEBUG) { |             if (Settings.DEBUG) { | ||||||
|                 LOGGER.info("- plot schematic: {}", schematic3File.getPath()); |                 LOGGER.info("- plot schematic: {}", schematic3File.getPath()); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         if ((schematic1 == null&& schematic2 == null) || this.ROAD_WIDTH == 0) { |         if ((schematic1 == null && schematic2 == null) || this.ROAD_WIDTH == 0) { | ||||||
|             if (Settings.DEBUG) { |             if (Settings.DEBUG) { | ||||||
|                 LOGGER.info("- schematic: false"); |                 LOGGER.info("- schematic: false"); | ||||||
|             } |             } | ||||||
| @@ -366,6 +398,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|                             z + min.getBlockZ() |                             z + min.getBlockZ() | ||||||
|                     )); |                     )); | ||||||
|                     if (!id.getBlockType().getMaterial().isAir()) { |                     if (!id.getBlockType().getMaterial().isAir()) { | ||||||
|  |                         schem1PopulationNeeded |= id.hasNbtData(); | ||||||
|                         addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z + shift + oddshift), id, false, h1); |                         addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z + shift + oddshift), id, false, h1); | ||||||
|                         addOverlayBlock( |                         addOverlayBlock( | ||||||
|                                 (short) (z + shift + oddshift), |                                 (short) (z + shift + oddshift), | ||||||
| @@ -377,11 +410,13 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|                         ); |                         ); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |                 if (blockArrayClipboard1.hasBiomes()) { | ||||||
|                     BiomeType biome = blockArrayClipboard1.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); |                     BiomeType biome = blockArrayClipboard1.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); | ||||||
|                     addOverlayBiome((short) (x - shift), (short) (z + shift + oddshift), biome); |                     addOverlayBiome((short) (x - shift), (short) (z + shift + oddshift), biome); | ||||||
|                     addOverlayBiome((short) (z + shift + oddshift), (short) (shift - x + (oddshift - 1)), biome); |                     addOverlayBiome((short) (z + shift + oddshift), (short) (shift - x + (oddshift - 1)), biome); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|         Clipboard blockArrayClipboard2 = schematic2.getClipboard(); |         Clipboard blockArrayClipboard2 = schematic2.getClipboard(); | ||||||
|         BlockVector3 d2 = blockArrayClipboard2.getDimensions(); |         BlockVector3 d2 = blockArrayClipboard2.getDimensions(); | ||||||
| @@ -402,14 +437,17 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|                             z + min.getBlockZ() |                             z + min.getBlockZ() | ||||||
|                     )); |                     )); | ||||||
|                     if (!id.getBlockType().getMaterial().isAir()) { |                     if (!id.getBlockType().getMaterial().isAir()) { | ||||||
|  |                         schem2PopulationNeeded |= id.hasNbtData(); | ||||||
|                         addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z - shift), id, false, h2); |                         addOverlayBlock((short) (x - shift), (short) (y + roadY), (short) (z - shift), id, false, h2); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|  |                 if (blockArrayClipboard2.hasBiomes()) { | ||||||
|                     BiomeType biome = blockArrayClipboard2.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); |                     BiomeType biome = blockArrayClipboard2.getBiome(BlockVector2.at(x + min.getBlockX(), z + min.getBlockZ())); | ||||||
|                     addOverlayBiome((short) (x - shift), (short) (z - shift), biome); |                     addOverlayBiome((short) (x - shift), (short) (z - shift), biome); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public void addOverlayBlock(short x, short y, short z, BaseBlock id, boolean rotate, int height) { |     public void addOverlayBlock(short x, short y, short z, BaseBlock id, boolean rotate, int height) { | ||||||
|         if (z < 0) { |         if (z < 0) { | ||||||
| @@ -428,7 +466,10 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|         int pair = MathMan.pair(x, z); |         int pair = MathMan.pair(x, z); | ||||||
|         BaseBlock[] existing = this.G_SCH.computeIfAbsent(pair, k -> new BaseBlock[height]); |         BaseBlock[] existing = this.G_SCH.computeIfAbsent(pair, k -> new BaseBlock[height]); | ||||||
|         if (y >= height) { |         if (y >= height) { | ||||||
|             LOGGER.error("Error adding overlay block. `y > height`"); |             if (y != lastOverlayHeightError) { | ||||||
|  |                 lastOverlayHeightError = y; | ||||||
|  |                 LOGGER.error(String.format("Error adding overlay block. `y > height`. y=%s, height=%s", y, height)); | ||||||
|  |             } | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|         existing[y] = id; |         existing[y] = id; | ||||||
| @@ -449,8 +490,52 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|         this.G_SCH_B.put(pair, id); |         this.G_SCH_B.put(pair, id); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the entities contained within the plot schematic for generation. Intended for internal use only. | ||||||
|  |      * | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||||
|  |     public @Nullable List<Entity> getPlotSchematicEntities() { | ||||||
|  |         return schem3Entities; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the minimum point of the plot schematic for generation. Intended for internal use only. | ||||||
|  |      * | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||||
|  |     public @Nullable BlockVector3 getPlotSchematicMinPoint() { | ||||||
|  |         return schem3MinPoint; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get if post-generation population of chunks with tiles/entities is needed for this world. Not for public API use. | ||||||
|  |      * | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||||
|  |     public boolean populationNeeded() { | ||||||
|  |         return schem1PopulationNeeded || schem2PopulationNeeded || schem3PopulationNeeded; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @deprecated in favour of {@link HybridPlotWorld#getSchematicRoot()} | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public File getRoot() { |     public File getRoot() { | ||||||
|         return this.root; |         return this.root; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the root folder for this world's generation schematics. May be null if schematics not initialised via | ||||||
|  |      * {@link HybridPlotWorld#setupSchematics()} | ||||||
|  |      * | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     public @Nullable File getSchematicRoot() { | ||||||
|  |         return this.root; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -41,7 +41,7 @@ import com.plotsquared.core.plot.flag.GlobalFlagContainer; | |||||||
| import com.plotsquared.core.plot.flag.PlotFlag; | import com.plotsquared.core.plot.flag.PlotFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.AnalysisFlag; | import com.plotsquared.core.plot.flag.implementations.AnalysisFlag; | ||||||
| import com.plotsquared.core.plot.world.PlotAreaManager; | import com.plotsquared.core.plot.world.PlotAreaManager; | ||||||
| import com.plotsquared.core.queue.ChunkQueueCoordinator; | import com.plotsquared.core.queue.BlockArrayCacheScopedQueueCoordinator; | ||||||
| import com.plotsquared.core.queue.GlobalBlockQueue; | import com.plotsquared.core.queue.GlobalBlockQueue; | ||||||
| import com.plotsquared.core.queue.QueueCoordinator; | import com.plotsquared.core.queue.QueueCoordinator; | ||||||
| import com.plotsquared.core.util.ChunkManager; | import com.plotsquared.core.util.ChunkManager; | ||||||
| @@ -65,6 +65,7 @@ import com.sk89q.worldedit.world.block.BlockTypes; | |||||||
| import org.apache.logging.log4j.LogManager; | import org.apache.logging.log4j.LogManager; | ||||||
| import org.apache.logging.log4j.Logger; | import org.apache.logging.log4j.Logger; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
|  |  | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.util.ArrayDeque; | import java.util.ArrayDeque; | ||||||
| @@ -73,6 +74,7 @@ import java.util.Arrays; | |||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
| import java.util.Iterator; | import java.util.Iterator; | ||||||
|  | import java.util.LinkedHashSet; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| import java.util.concurrent.atomic.AtomicBoolean; | import java.util.concurrent.atomic.AtomicBoolean; | ||||||
| @@ -81,11 +83,14 @@ import java.util.concurrent.atomic.AtomicInteger; | |||||||
| public class HybridUtils { | public class HybridUtils { | ||||||
|  |  | ||||||
|     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + HybridUtils.class.getSimpleName()); |     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + HybridUtils.class.getSimpleName()); | ||||||
|  |     private static final BlockState AIR = BlockTypes.AIR.getDefaultState(); | ||||||
|  |  | ||||||
|     public static HybridUtils manager; |     public static HybridUtils manager; | ||||||
|     public static Set<BlockVector2> regions; |     public static Set<BlockVector2> regions; | ||||||
|     public static int height; |     public static int height; | ||||||
|     public static Set<BlockVector2> chunks = new HashSet<>(); |     // Use ordered for reasonable chunk loading order to reduce paper unloading neighbour chunks and then us attempting to load | ||||||
|  |     // them again, causing errors | ||||||
|  |     public static Set<BlockVector2> chunks = new LinkedHashSet<>(); | ||||||
|     public static PlotArea area; |     public static PlotArea area; | ||||||
|     public static boolean UPDATE = false; |     public static boolean UPDATE = false; | ||||||
|  |  | ||||||
| @@ -132,6 +137,11 @@ public class HybridUtils { | |||||||
|          * |          * | ||||||
|          */ |          */ | ||||||
|         TaskManager.runTaskAsync(() -> { |         TaskManager.runTaskAsync(() -> { | ||||||
|  |             final PlotArea area = this.plotAreaManager.getPlotArea(world, null); | ||||||
|  |             if (!(area instanceof HybridPlotWorld hpw)) { | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |  | ||||||
|             final BlockVector3 bot = region.getMinimumPoint(); |             final BlockVector3 bot = region.getMinimumPoint(); | ||||||
|             final BlockVector3 top = region.getMaximumPoint(); |             final BlockVector3 top = region.getMaximumPoint(); | ||||||
|  |  | ||||||
| @@ -145,38 +155,31 @@ public class HybridUtils { | |||||||
|             final int ctz = tz >> 4; |             final int ctz = tz >> 4; | ||||||
|             final int width = tx - bx + 1; |             final int width = tx - bx + 1; | ||||||
|             final int length = tz - bz + 1; |             final int length = tz - bz + 1; | ||||||
|  |             final int height = area.getMaxGenHeight() - area.getMinGenHeight() + 1; | ||||||
|  |             final int minHeight = area.getMinGenHeight(); | ||||||
|  |  | ||||||
|             final PlotArea area = this.plotAreaManager.getPlotArea(world, null); |             final BlockState[][][] newBlocks = new BlockState[height][width][length]; | ||||||
|  |  | ||||||
|             if (!(area instanceof HybridPlotWorld hpw)) { |             BlockArrayCacheScopedQueueCoordinator oldBlockQueue = new BlockArrayCacheScopedQueueCoordinator( | ||||||
|                 return; |                     Location.at("", region.getMinimumPoint().withY(hpw.getMinGenHeight())), | ||||||
|             } |                     Location.at("", region.getMaximumPoint().withY(hpw.getMaxGenHeight())) | ||||||
|  |             ); | ||||||
|  |  | ||||||
|             ChunkQueueCoordinator chunk = new ChunkQueueCoordinator(worldUtil.getWeWorld(world), bot, top, false); |             region.getChunks().forEach(chunkPos -> { | ||||||
|             hpw.getGenerator().generateChunk(chunk, hpw); |                 int relChunkX = chunkPos.getX() - cbx; | ||||||
|  |                 int relChunkZ = chunkPos.getZ() - cbz; | ||||||
|  |                 oldBlockQueue.setOffsetX(relChunkX << 4); | ||||||
|  |                 oldBlockQueue.setOffsetZ(relChunkZ << 4); | ||||||
|  |                 hpw.getGenerator().generateChunk(oldBlockQueue, hpw); | ||||||
|  |             }); | ||||||
|  |  | ||||||
|             final BlockState airBlock = BlockTypes.AIR.getDefaultState(); |             final BlockState[][][] oldBlocks = oldBlockQueue.getBlockStates(); | ||||||
|             final BlockState[][][] oldBlocks = chunk.getBlocks(); |  | ||||||
|             final BlockState[][][] newBlocks = new BlockState[256][width][length]; |  | ||||||
|             for (final BlockState[][] newBlock : newBlocks) { |  | ||||||
|                 for (final BlockState[] blockStates : newBlock) { |  | ||||||
|                     Arrays.fill(blockStates, airBlock); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             for (final BlockState[][] oldBlock : oldBlocks) { |  | ||||||
|                 for (final BlockState[] blockStates : oldBlock) { |  | ||||||
|                     Arrays.fill(blockStates, airBlock); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             System.gc(); |  | ||||||
|             System.gc(); |  | ||||||
|  |  | ||||||
|             QueueCoordinator queue = area.getQueue(); |             QueueCoordinator queue = area.getQueue(); | ||||||
|             queue.addReadChunks(region.getChunks()); |             queue.addReadChunks(region.getChunks()); | ||||||
|             queue.setChunkConsumer(blockVector2 -> { |             queue.setChunkConsumer(chunkPos -> { | ||||||
|                 int X = blockVector2.getX(); |                 int X = chunkPos.getX(); | ||||||
|                 int Z = blockVector2.getZ(); |                 int Z = chunkPos.getZ(); | ||||||
|                 int minX; |                 int minX; | ||||||
|                 if (X == cbx) { |                 if (X == cbx) { | ||||||
|                     minX = bx & 15; |                     minX = bx & 15; | ||||||
| @@ -211,11 +214,15 @@ public class HybridUtils { | |||||||
|                     int xx = chunkBlockX + x; |                     int xx = chunkBlockX + x; | ||||||
|                     for (int z = minZ; z <= maxZ; z++) { |                     for (int z = minZ; z <= maxZ; z++) { | ||||||
|                         int zz = chunkBlockZ + z; |                         int zz = chunkBlockZ + z; | ||||||
|                         for (int y = 0; y < 256; y++) { |                         for (int yIndex = 0; yIndex < height; yIndex++) { | ||||||
|  |                             int y = yIndex + minHeight; | ||||||
|                             BlockState block = queue.getBlock(xx, y, zz); |                             BlockState block = queue.getBlock(xx, y, zz); | ||||||
|  |                             if (block == null) { | ||||||
|  |                                 block = AIR; | ||||||
|  |                             } | ||||||
|                             int xr = xb + x; |                             int xr = xb + x; | ||||||
|                             int zr = zb + z; |                             int zr = zb + z; | ||||||
|                             newBlocks[y][xr][zr] = block; |                             newBlocks[yIndex][xr][zr] = block; | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
| @@ -232,11 +239,11 @@ public class HybridUtils { | |||||||
|                 for (int x = 0; x < width; x++) { |                 for (int x = 0; x < width; x++) { | ||||||
|                     for (int z = 0; z < length; z++) { |                     for (int z = 0; z < length; z++) { | ||||||
|                         Set<BlockType> types = new HashSet<>(); |                         Set<BlockType> types = new HashSet<>(); | ||||||
|                         for (int y = 0; y < 256; y++) { |                         for (int yIndex = 0; yIndex < height; yIndex++) { | ||||||
|                             BlockState old = oldBlocks[y][x][z]; |                             BlockState old = oldBlocks[yIndex][x][z]; // Nullable | ||||||
|                             try { |                             try { | ||||||
|                                 BlockState now = newBlocks[y][x][z]; |                                 BlockState now = newBlocks[yIndex][x][z]; // Not null | ||||||
|                                 if (!old.equals(now)) { |                                 if (!now.equals(old) && !(old == null && now.getBlockType().equals(BlockTypes.AIR))) { | ||||||
|                                     changes[i]++; |                                     changes[i]++; | ||||||
|                                 } |                                 } | ||||||
|                                 if (now.getBlockType().getMaterial().isAir()) { |                                 if (now.getBlockType().getMaterial().isAir()) { | ||||||
| @@ -244,23 +251,23 @@ public class HybridUtils { | |||||||
|                                 } else { |                                 } else { | ||||||
|                                     // check vertices |                                     // check vertices | ||||||
|                                     // modifications_adjacent |                                     // modifications_adjacent | ||||||
|                                     if (x > 0 && z > 0 && y > 0 && x < width - 1 && z < length - 1 && y < 255) { |                                     if (x > 0 && z > 0 && yIndex > 0 && x < width - 1 && z < length - 1 && yIndex < (height - 1)) { | ||||||
|                                         if (newBlocks[y - 1][x][z].getBlockType().getMaterial().isAir()) { |                                         if (newBlocks[yIndex - 1][x][z].getBlockType().getMaterial().isAir()) { | ||||||
|                                             faces[i]++; |                                             faces[i]++; | ||||||
|                                         } |                                         } | ||||||
|                                         if (newBlocks[y][x - 1][z].getBlockType().getMaterial().isAir()) { |                                         if (newBlocks[yIndex][x - 1][z].getBlockType().getMaterial().isAir()) { | ||||||
|                                             faces[i]++; |                                             faces[i]++; | ||||||
|                                         } |                                         } | ||||||
|                                         if (newBlocks[y][x][z - 1].getBlockType().getMaterial().isAir()) { |                                         if (newBlocks[yIndex][x][z - 1].getBlockType().getMaterial().isAir()) { | ||||||
|                                             faces[i]++; |                                             faces[i]++; | ||||||
|                                         } |                                         } | ||||||
|                                         if (newBlocks[y + 1][x][z].getBlockType().getMaterial().isAir()) { |                                         if (newBlocks[yIndex + 1][x][z].getBlockType().getMaterial().isAir()) { | ||||||
|                                             faces[i]++; |                                             faces[i]++; | ||||||
|                                         } |                                         } | ||||||
|                                         if (newBlocks[y][x + 1][z].getBlockType().getMaterial().isAir()) { |                                         if (newBlocks[yIndex][x + 1][z].getBlockType().getMaterial().isAir()) { | ||||||
|                                             faces[i]++; |                                             faces[i]++; | ||||||
|                                         } |                                         } | ||||||
|                                         if (newBlocks[y][x][z + 1].getBlockType().getMaterial().isAir()) { |                                         if (newBlocks[yIndex][x][z + 1].getBlockType().getMaterial().isAir()) { | ||||||
|                                             faces[i]++; |                                             faces[i]++; | ||||||
|                                         } |                                         } | ||||||
|                                     } |                                     } | ||||||
| @@ -294,8 +301,6 @@ public class HybridUtils { | |||||||
|                 analysis.data_sd = (int) (MathMan.getSD(data, analysis.data) * 100); |                 analysis.data_sd = (int) (MathMan.getSD(data, analysis.data) * 100); | ||||||
|                 analysis.air_sd = (int) (MathMan.getSD(air, analysis.air) * 100); |                 analysis.air_sd = (int) (MathMan.getSD(air, analysis.air) * 100); | ||||||
|                 analysis.variety_sd = (int) (MathMan.getSD(variety, analysis.variety) * 100); |                 analysis.variety_sd = (int) (MathMan.getSD(variety, analysis.variety) * 100); | ||||||
|                 System.gc(); |  | ||||||
|                 System.gc(); |  | ||||||
|                 whenDone.value = analysis; |                 whenDone.value = analysis; | ||||||
|                 whenDone.run(); |                 whenDone.run(); | ||||||
|             }); |             }); | ||||||
| @@ -408,7 +413,7 @@ public class HybridUtils { | |||||||
|         } |         } | ||||||
|         HybridUtils.UPDATE = true; |         HybridUtils.UPDATE = true; | ||||||
|         Set<BlockVector2> regions = this.worldUtil.getChunkChunks(area.getWorldName()); |         Set<BlockVector2> regions = this.worldUtil.getChunkChunks(area.getWorldName()); | ||||||
|         return scheduleRoadUpdate(area, regions, extend, new HashSet<>()); |         return scheduleRoadUpdate(area, regions, extend, new LinkedHashSet<>()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public boolean scheduleSingleRegionRoadUpdate(Plot plot, int extend) { |     public boolean scheduleSingleRegionRoadUpdate(Plot plot, int extend) { | ||||||
| @@ -418,7 +423,7 @@ public class HybridUtils { | |||||||
|         HybridUtils.UPDATE = true; |         HybridUtils.UPDATE = true; | ||||||
|         Set<BlockVector2> regions = new HashSet<>(); |         Set<BlockVector2> regions = new HashSet<>(); | ||||||
|         regions.add(RegionManager.getRegion(plot.getCenterSynchronous())); |         regions.add(RegionManager.getRegion(plot.getCenterSynchronous())); | ||||||
|         return scheduleRoadUpdate(plot.getArea(), regions, extend, new HashSet<>()); |         return scheduleRoadUpdate(plot.getArea(), regions, extend, new LinkedHashSet<>()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public boolean scheduleRoadUpdate( |     public boolean scheduleRoadUpdate( | ||||||
| @@ -431,26 +436,29 @@ public class HybridUtils { | |||||||
|         HybridUtils.area = area; |         HybridUtils.area = area; | ||||||
|         HybridUtils.height = extend; |         HybridUtils.height = extend; | ||||||
|         HybridUtils.chunks = chunks; |         HybridUtils.chunks = chunks; | ||||||
|  |         final int initial = 1024 * regions.size() + chunks.size(); | ||||||
|         final AtomicInteger count = new AtomicInteger(0); |         final AtomicInteger count = new AtomicInteger(0); | ||||||
|         TaskManager.runTask(new Runnable() { |         TaskManager.runTask(new Runnable() { | ||||||
|             @Override |             @Override | ||||||
|             public void run() { |             public void run() { | ||||||
|                 if (!UPDATE) { |                 if (!UPDATE) { | ||||||
|                     Iterator<BlockVector2> iter = chunks.iterator(); |                     Iterator<BlockVector2> iter = chunks.iterator(); | ||||||
|  |                     QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName())); | ||||||
|                     while (iter.hasNext()) { |                     while (iter.hasNext()) { | ||||||
|                         BlockVector2 chunk = iter.next(); |                         BlockVector2 chunk = iter.next(); | ||||||
|                         iter.remove(); |                         iter.remove(); | ||||||
|                         boolean regenedRoad = regenerateRoad(area, chunk, extend); |                         boolean regenedRoad = regenerateRoad(area, chunk, extend, queue); | ||||||
|                         if (!regenedRoad) { |                         if (!regenedRoad) { | ||||||
|                             LOGGER.info("Failed to regenerate roads"); |                             LOGGER.info("Failed to regenerate roads in chunk {}", chunk); | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |                     queue.enqueue(); | ||||||
|                     LOGGER.info("Cancelled road task"); |                     LOGGER.info("Cancelled road task"); | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|                 count.incrementAndGet(); |                 count.incrementAndGet(); | ||||||
|                 if (count.intValue() % 20 == 0) { |                 if (count.intValue() % 10 == 0) { | ||||||
|                     LOGGER.info("Progress: {}%", 100 * (2048 - chunks.size()) / 2048); |                     LOGGER.info("Progress: {}%", 100 * (initial - (chunks.size() + 1024 * regions.size())) / initial); | ||||||
|                 } |                 } | ||||||
|                 if (HybridUtils.regions.isEmpty() && chunks.isEmpty()) { |                 if (HybridUtils.regions.isEmpty() && chunks.isEmpty()) { | ||||||
|                     regeneratePlotWalls(area); |                     regeneratePlotWalls(area); | ||||||
| @@ -462,7 +470,7 @@ public class HybridUtils { | |||||||
|                     final Runnable task = this; |                     final Runnable task = this; | ||||||
|                     TaskManager.runTaskAsync(() -> { |                     TaskManager.runTaskAsync(() -> { | ||||||
|                         try { |                         try { | ||||||
|                             if (chunks.size() < 1024) { |                             if (chunks.size() < 64) { | ||||||
|                                 if (!HybridUtils.regions.isEmpty()) { |                                 if (!HybridUtils.regions.isEmpty()) { | ||||||
|                                     Iterator<BlockVector2> iterator = HybridUtils.regions.iterator(); |                                     Iterator<BlockVector2> iterator = HybridUtils.regions.iterator(); | ||||||
|                                     BlockVector2 loc = iterator.next(); |                                     BlockVector2 loc = iterator.next(); | ||||||
| @@ -475,18 +483,35 @@ public class HybridUtils { | |||||||
|                             } |                             } | ||||||
|                             if (!chunks.isEmpty()) { |                             if (!chunks.isEmpty()) { | ||||||
|                                 TaskManager.getPlatformImplementation().sync(() -> { |                                 TaskManager.getPlatformImplementation().sync(() -> { | ||||||
|                                     long start = System.currentTimeMillis(); |  | ||||||
|                                     Iterator<BlockVector2> iterator = chunks.iterator(); |                                     Iterator<BlockVector2> iterator = chunks.iterator(); | ||||||
|                                     while (System.currentTimeMillis() - start < 20 && !chunks.isEmpty()) { |                                     if (chunks.size() >= 32) { | ||||||
|  |                                         QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName())); | ||||||
|  |                                         for (int i = 0; i < 32; i++) { | ||||||
|                                             final BlockVector2 chunk = iterator.next(); |                                             final BlockVector2 chunk = iterator.next(); | ||||||
|                                             iterator.remove(); |                                             iterator.remove(); | ||||||
|                                         boolean regenedRoads = regenerateRoad(area, chunk, extend); |                                             boolean regenedRoads = regenerateRoad(area, chunk, extend, queue); | ||||||
|                                             if (!regenedRoads) { |                                             if (!regenedRoads) { | ||||||
|                                             LOGGER.info("Failed to regenerate road"); |                                                 LOGGER.info("Failed to regenerate the road in chunk {}", chunk); | ||||||
|                                             } |                                             } | ||||||
|                                         } |                                         } | ||||||
|  |                                         queue.setCompleteTask(task); | ||||||
|  |                                         queue.enqueue(); | ||||||
|  |                                         return null; | ||||||
|  |                                     } | ||||||
|  |                                     QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName())); | ||||||
|  |                                     while (!chunks.isEmpty()) { | ||||||
|  |                                         final BlockVector2 chunk = iterator.next(); | ||||||
|  |                                         iterator.remove(); | ||||||
|  |                                         boolean regenedRoads = regenerateRoad(area, chunk, extend, queue); | ||||||
|  |                                         if (!regenedRoads) { | ||||||
|  |                                             LOGGER.info("Failed to regenerate road in chunk {}", chunk); | ||||||
|  |                                         } | ||||||
|  |                                     } | ||||||
|  |                                     queue.setCompleteTask(task); | ||||||
|  |                                     queue.enqueue(); | ||||||
|                                     return null; |                                     return null; | ||||||
|                                 }); |                                 }); | ||||||
|  |                                 return; | ||||||
|                             } |                             } | ||||||
|                         } catch (Exception e) { |                         } catch (Exception e) { | ||||||
|                             e.printStackTrace(); |                             e.printStackTrace(); | ||||||
| @@ -514,7 +539,6 @@ public class HybridUtils { | |||||||
|         Location bot = plot.getBottomAbs().subtract(1, 0, 1); |         Location bot = plot.getBottomAbs().subtract(1, 0, 1); | ||||||
|         Location top = plot.getTopAbs(); |         Location top = plot.getTopAbs(); | ||||||
|         final HybridPlotWorld plotworld = (HybridPlotWorld) plot.getArea(); |         final HybridPlotWorld plotworld = (HybridPlotWorld) plot.getArea(); | ||||||
|         PlotManager plotManager = plotworld.getPlotManager(); |  | ||||||
|         // Do not use plotworld#schematicStartHeight() here as we want to restore the pre 6.1.4 way of doing it if |         // Do not use plotworld#schematicStartHeight() here as we want to restore the pre 6.1.4 way of doing it if | ||||||
|         //  USE_WALL_IN_ROAD_SCHEM_HEIGHT is false |         //  USE_WALL_IN_ROAD_SCHEM_HEIGHT is false | ||||||
|         int schemY = Settings.Schematics.USE_WALL_IN_ROAD_SCHEM_HEIGHT ? |         int schemY = Settings.Schematics.USE_WALL_IN_ROAD_SCHEM_HEIGHT ? | ||||||
| @@ -524,10 +548,10 @@ public class HybridUtils { | |||||||
|         int sy = Settings.Schematics.PASTE_ROAD_ON_TOP ? schemY : plot.getArea().getMinBuildHeight(); |         int sy = Settings.Schematics.PASTE_ROAD_ON_TOP ? schemY : plot.getArea().getMinBuildHeight(); | ||||||
|         int ex = bot.getX(); |         int ex = bot.getX(); | ||||||
|         int ez = top.getZ(); |         int ez = top.getZ(); | ||||||
|         int ey = get_ey(plotManager, queue, sx, ex, sz, ez, sy); |         int ey = get_ey(plotworld, queue, sx, ex, sz, ez, sy); | ||||||
|         int bz = sz - plotworld.ROAD_WIDTH; |         int bz = sz - plotworld.ROAD_WIDTH; | ||||||
|         int tz = sz - 1; |         int tz = sz - 1; | ||||||
|         int ty = get_ey(plotManager, queue, sx, ex, bz, tz, sy); |         int ty = get_ey(plotworld, queue, sx, ex, bz, tz, sy); | ||||||
|  |  | ||||||
|         final Set<CuboidRegion> sideRoad = Collections.singleton(RegionUtil.createRegion(sx, ex, sy, ey, sz, ez)); |         final Set<CuboidRegion> sideRoad = Collections.singleton(RegionUtil.createRegion(sx, ex, sy, ey, sz, ez)); | ||||||
|         final Set<CuboidRegion> intersection = Collections.singleton(RegionUtil.createRegion(sx, ex, sy, ty, bz, tz)); |         final Set<CuboidRegion> intersection = Collections.singleton(RegionUtil.createRegion(sx, ex, sy, ty, bz, tz)); | ||||||
| @@ -553,11 +577,11 @@ public class HybridUtils { | |||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public int get_ey(final PlotManager pm, QueueCoordinator queue, int sx, int ex, int sz, int ez, int sy) { |     private int get_ey(final HybridPlotWorld hpw, QueueCoordinator queue, int sx, int ex, int sz, int ez, int sy) { | ||||||
|         int ey = sy; |         int ey = sy; | ||||||
|         for (int x = sx; x <= ex; x++) { |         for (int x = sx; x <= ex; x++) { | ||||||
|             for (int z = sz; z <= ez; z++) { |             for (int z = sz; z <= ez; z++) { | ||||||
|                 for (int y = sy; y <= pm.getWorldHeight(); y++) { |                 for (int y = sy; y <= hpw.getMaxGenHeight(); y++) { | ||||||
|                     if (y > ey) { |                     if (y > ey) { | ||||||
|                         BlockState block = queue.getBlock(x, y, z); |                         BlockState block = queue.getBlock(x, y, z); | ||||||
|                         if (!block.getBlockType().getMaterial().isAir()) { |                         if (!block.getBlockType().getMaterial().isAir()) { | ||||||
| @@ -570,7 +594,36 @@ public class HybridUtils { | |||||||
|         return ey; |         return ey; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Regenerate the road in a chunk in a plot area. | ||||||
|  |      * | ||||||
|  |      * @param area   Plot area to regenerate road for | ||||||
|  |      * @param chunk  Chunk location to regenerate | ||||||
|  |      * @param extend How far to extend setting air above the road | ||||||
|  |      * @return if successful | ||||||
|  |      * @deprecated use {@link HybridUtils#regenerateRoad(PlotArea, BlockVector2, int, QueueCoordinator)} | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "6.6.0") | ||||||
|     public boolean regenerateRoad(final PlotArea area, final BlockVector2 chunk, int extend) { |     public boolean regenerateRoad(final PlotArea area, final BlockVector2 chunk, int extend) { | ||||||
|  |         return regenerateRoad(area, chunk, extend, null); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Regenerate the road in a chunk in a plot area. | ||||||
|  |      * | ||||||
|  |      * @param area             Plot area to regenerate road for | ||||||
|  |      * @param chunk            Chunk location to regenerate | ||||||
|  |      * @param extend           How far to extend setting air above the road | ||||||
|  |      * @param queueCoordinator {@link QueueCoordinator} to use to set the blocks. Null if one should be created and enqueued | ||||||
|  |      * @return if successful | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      */ | ||||||
|  |     public boolean regenerateRoad( | ||||||
|  |             final PlotArea area, | ||||||
|  |             final BlockVector2 chunk, | ||||||
|  |             int extend, | ||||||
|  |             @Nullable QueueCoordinator queueCoordinator | ||||||
|  |     ) { | ||||||
|         int x = chunk.getX() << 4; |         int x = chunk.getX() << 4; | ||||||
|         int z = chunk.getZ() << 4; |         int z = chunk.getZ() << 4; | ||||||
|         int ex = x + 15; |         int ex = x + 15; | ||||||
| @@ -596,9 +649,16 @@ public class HybridUtils { | |||||||
|         z -= plotWorld.ROAD_OFFSET_Z; |         z -= plotWorld.ROAD_OFFSET_Z; | ||||||
|         final int finalX = x; |         final int finalX = x; | ||||||
|         final int finalZ = z; |         final int finalZ = z; | ||||||
|         QueueCoordinator queue = this.blockQueue.getNewQueue(worldUtil.getWeWorld(plotWorld.getWorldName())); |         final boolean enqueue; | ||||||
|  |         final QueueCoordinator queue; | ||||||
|  |         if (queueCoordinator == null) { | ||||||
|  |             queue = this.blockQueue.getNewQueue(worldUtil.getWeWorld(plotWorld.getWorldName())); | ||||||
|  |             enqueue = true; | ||||||
|  |         } else { | ||||||
|  |             queue = queueCoordinator; | ||||||
|  |             enqueue = false; | ||||||
|  |         } | ||||||
|         if (id1 == null || id2 == null || id1 != id2) { |         if (id1 == null || id2 == null || id1 != id2) { | ||||||
|             this.chunkManager.loadChunk(area.getWorldName(), chunk, false).thenRun(() -> { |  | ||||||
|             if (id1 != null) { |             if (id1 != null) { | ||||||
|                 Plot p1 = area.getPlotAbs(id1); |                 Plot p1 = area.getPlotAbs(id1); | ||||||
|                 if (p1 != null && p1.hasOwner() && p1.isMerged()) { |                 if (p1 != null && p1.hasOwner() && p1.isMerged()) { | ||||||
| @@ -611,7 +671,7 @@ public class HybridUtils { | |||||||
|                     toCheck.set(true); |                     toCheck.set(true); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|                 int size = plotWorld.SIZE; |             short size = plotWorld.SIZE; | ||||||
|             for (int X = 0; X < 16; X++) { |             for (int X = 0; X < 16; X++) { | ||||||
|                 short absX = (short) ((finalX + X) % size); |                 short absX = (short) ((finalX + X) % size); | ||||||
|                 for (int Z = 0; Z < 16; Z++) { |                 for (int Z = 0; Z < 16; Z++) { | ||||||
| @@ -638,29 +698,29 @@ public class HybridUtils { | |||||||
|                     } |                     } | ||||||
|                     if (condition) { |                     if (condition) { | ||||||
|                         BaseBlock[] blocks = plotWorld.G_SCH.get(MathMan.pair(absX, absZ)); |                         BaseBlock[] blocks = plotWorld.G_SCH.get(MathMan.pair(absX, absZ)); | ||||||
|                             int minY = Settings.Schematics.PASTE_ROAD_ON_TOP ? plotWorld.SCHEM_Y : 1; |                         int minY = Settings.Schematics.PASTE_ROAD_ON_TOP ? plotWorld.SCHEM_Y : area.getMinGenHeight() + 1; | ||||||
|                             int maxY = Math.max(extend, blocks.length); |                         int maxDy = Math.max(extend, blocks.length); | ||||||
|                             for (int y = 0; y < maxY; y++) { |                         for (int dy = 0; dy < maxDy; dy++) { | ||||||
|                                 if (y > blocks.length - 1) { |                             if (dy > blocks.length - 1) { | ||||||
|                                 queue.setBlock( |                                 queue.setBlock( | ||||||
|                                         finalX + X + plotWorld.ROAD_OFFSET_X, |                                         finalX + X + plotWorld.ROAD_OFFSET_X, | ||||||
|                                             minY + y, |                                         minY + dy, | ||||||
|                                         finalZ + Z + plotWorld.ROAD_OFFSET_Z, |                                         finalZ + Z + plotWorld.ROAD_OFFSET_Z, | ||||||
|                                         WEExtent.AIRBASE |                                         WEExtent.AIRBASE | ||||||
|                                 ); |                                 ); | ||||||
|                             } else { |                             } else { | ||||||
|                                     BaseBlock block = blocks[y]; |                                 BaseBlock block = blocks[dy]; | ||||||
|                                 if (block != null) { |                                 if (block != null) { | ||||||
|                                     queue.setBlock( |                                     queue.setBlock( | ||||||
|                                             finalX + X + plotWorld.ROAD_OFFSET_X, |                                             finalX + X + plotWorld.ROAD_OFFSET_X, | ||||||
|                                                 minY + y, |                                             minY + dy, | ||||||
|                                             finalZ + Z + plotWorld.ROAD_OFFSET_Z, |                                             finalZ + Z + plotWorld.ROAD_OFFSET_Z, | ||||||
|                                             block |                                             block | ||||||
|                                     ); |                                     ); | ||||||
|                                 } else { |                                 } else { | ||||||
|                                     queue.setBlock( |                                     queue.setBlock( | ||||||
|                                             finalX + X + plotWorld.ROAD_OFFSET_X, |                                             finalX + X + plotWorld.ROAD_OFFSET_X, | ||||||
|                                                 minY + y, |                                             minY + dy, | ||||||
|                                             finalZ + Z + plotWorld.ROAD_OFFSET_Z, |                                             finalZ + Z + plotWorld.ROAD_OFFSET_Z, | ||||||
|                                             WEExtent.AIRBASE |                                             WEExtent.AIRBASE | ||||||
|                                     ); |                                     ); | ||||||
| @@ -680,8 +740,9 @@ public class HybridUtils { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  |             if (enqueue) { | ||||||
|                 queue.enqueue(); |                 queue.enqueue(); | ||||||
|             }); |             } | ||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|         return false; |         return false; | ||||||
|   | |||||||
| @@ -47,16 +47,25 @@ public abstract class IndependentPlotGenerator { | |||||||
|     public abstract String getName(); |     public abstract String getName(); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Use the setBlock or setBiome method of the PlotChunk result parameter to make changes. |      * Generate chunk block data | ||||||
|      * The PlotArea settings is the same one this was initialized with. |  | ||||||
|      * The PseudoRandom random is a fast random object. |  | ||||||
|      * |      * | ||||||
|      * @param result   queue |      * @param result   queue | ||||||
|      * @param settings PlotArea (settings) |      * @param settings PlotArea (settings) | ||||||
|  |      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. | ||||||
|      */ |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public abstract void generateChunk(ScopedQueueCoordinator result, PlotArea settings); |     public abstract void generateChunk(ScopedQueueCoordinator result, PlotArea settings); | ||||||
|  |  | ||||||
|     public boolean populateChunk(ScopedQueueCoordinator result, PlotArea setting) { |     /** | ||||||
|  |      * Populates the queue representing a chunk area with tile entities and entities | ||||||
|  |      * | ||||||
|  |      * @param result   Queue to write to | ||||||
|  |      * @param settings PlotArea (settings) | ||||||
|  |      * @return True if any population occurred | ||||||
|  |      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|  |     public boolean populateChunk(ScopedQueueCoordinator result, PlotArea settings) { | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -96,7 +96,7 @@ public abstract class SquarePlotManager extends GridPlotManager { | |||||||
|                 .floor(squarePlotWorld.ROAD_WIDTH / 2) - 1; |                 .floor(squarePlotWorld.ROAD_WIDTH / 2) - 1; | ||||||
|         int z = (squarePlotWorld.ROAD_OFFSET_Z + (pz * (squarePlotWorld.ROAD_WIDTH + squarePlotWorld.PLOT_WIDTH))) - (int) Math |         int z = (squarePlotWorld.ROAD_OFFSET_Z + (pz * (squarePlotWorld.ROAD_WIDTH + squarePlotWorld.PLOT_WIDTH))) - (int) Math | ||||||
|                 .floor(squarePlotWorld.ROAD_WIDTH / 2) - 1; |                 .floor(squarePlotWorld.ROAD_WIDTH / 2) - 1; | ||||||
|         return Location.at(squarePlotWorld.getWorldName(), x, Math.min(getWorldHeight(), 255), z); |         return Location.at(squarePlotWorld.getWorldName(), x, squarePlotWorld.getMaxGenHeight(), z); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
| @@ -260,7 +260,7 @@ public abstract class SquarePlotManager extends GridPlotManager { | |||||||
|                 - (int) Math.floor(squarePlotWorld.ROAD_WIDTH / 2); |                 - (int) Math.floor(squarePlotWorld.ROAD_WIDTH / 2); | ||||||
|         int z = (squarePlotWorld.ROAD_OFFSET_Z + (pz * (squarePlotWorld.ROAD_WIDTH + squarePlotWorld.PLOT_WIDTH))) - squarePlotWorld.PLOT_WIDTH |         int z = (squarePlotWorld.ROAD_OFFSET_Z + (pz * (squarePlotWorld.ROAD_WIDTH + squarePlotWorld.PLOT_WIDTH))) - squarePlotWorld.PLOT_WIDTH | ||||||
|                 - (int) Math.floor(squarePlotWorld.ROAD_WIDTH / 2); |                 - (int) Math.floor(squarePlotWorld.ROAD_WIDTH / 2); | ||||||
|         return Location.at(squarePlotWorld.getWorldName(), x, squarePlotWorld.getMinBuildHeight(), z); |         return Location.at(squarePlotWorld.getWorldName(), x, squarePlotWorld.getMinGenHeight(), z); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -309,7 +309,7 @@ public class PlotListener { | |||||||
|                         } |                         } | ||||||
|                         if ((lastPlot != null) && plot.getId().equals(lastPlot.getId()) && plot.hasOwner()) { |                         if ((lastPlot != null) && plot.getId().equals(lastPlot.getId()) && plot.hasOwner()) { | ||||||
|                             final UUID plotOwner = plot.getOwnerAbs(); |                             final UUID plotOwner = plot.getOwnerAbs(); | ||||||
|                             String owner = PlayerManager.resolveName(plotOwner, false).getComponent(player); |                             String owner = PlayerManager.resolveName(plotOwner, true).getComponent(player); | ||||||
|                             Caption header = fromFlag ? StaticCaption.of(title) : TranslatableCaption.of("titles" + |                             Caption header = fromFlag ? StaticCaption.of(title) : TranslatableCaption.of("titles" + | ||||||
|                                     ".title_entered_plot"); |                                     ".title_entered_plot"); | ||||||
|                             Caption subHeader = fromFlag ? StaticCaption.of(subtitle) : TranslatableCaption.of("titles" + |                             Caption subHeader = fromFlag ? StaticCaption.of(subtitle) : TranslatableCaption.of("titles" + | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ import com.plotsquared.core.plot.world.PlotAreaManager; | |||||||
| import com.plotsquared.core.util.Permissions; | import com.plotsquared.core.util.Permissions; | ||||||
| import com.plotsquared.core.util.WEManager; | import com.plotsquared.core.util.WEManager; | ||||||
| import com.plotsquared.core.util.WorldUtil; | import com.plotsquared.core.util.WorldUtil; | ||||||
|  | import com.sk89q.worldedit.EditSession; | ||||||
| import com.sk89q.worldedit.WorldEdit; | import com.sk89q.worldedit.WorldEdit; | ||||||
| import com.sk89q.worldedit.entity.Player; | import com.sk89q.worldedit.entity.Player; | ||||||
| import com.sk89q.worldedit.event.extent.EditSessionEvent; | import com.sk89q.worldedit.event.extent.EditSessionEvent; | ||||||
| @@ -67,6 +68,9 @@ public class WESubscriber { | |||||||
|             WorldEdit.getInstance().getEventBus().unregister(this); |             WorldEdit.getInstance().getEventBus().unregister(this); | ||||||
|             return; |             return; | ||||||
|         } |         } | ||||||
|  |         if (event.getStage() != EditSession.Stage.BEFORE_HISTORY) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|         World worldObj = event.getWorld(); |         World worldObj = event.getWorld(); | ||||||
|         if (worldObj == null) { |         if (worldObj == null) { | ||||||
|             return; |             return; | ||||||
|   | |||||||
| @@ -41,14 +41,17 @@ import org.khelekore.prtree.SimpleMBR; | |||||||
|  * An unmodifiable 6-tuple (world,x,y,z,yaw,pitch) |  * An unmodifiable 6-tuple (world,x,y,z,yaw,pitch) | ||||||
|  */ |  */ | ||||||
| @SuppressWarnings("unused") | @SuppressWarnings("unused") | ||||||
| public final class Location extends BlockLoc implements Comparable<Location> { | public sealed class Location extends BlockLoc implements Comparable<Location> permits UncheckedWorldLocation { | ||||||
|  |  | ||||||
|     private final float yaw; |     private final float yaw; | ||||||
|     private final float pitch; |     private final float pitch; | ||||||
|     private final BlockVector3 blockVector3; |     private final BlockVector3 blockVector3; | ||||||
|     private final World<?> world; |     private final World<?> world; | ||||||
|  |  | ||||||
|     private Location( |     /** | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     protected Location( | ||||||
|             final @NonNull World<?> world, final @NonNull BlockVector3 blockVector3, |             final @NonNull World<?> world, final @NonNull BlockVector3 blockVector3, | ||||||
|             final float yaw, final float pitch |             final float yaw, final float pitch | ||||||
|     ) { |     ) { | ||||||
|   | |||||||
| @@ -0,0 +1,77 @@ | |||||||
|  | /* | ||||||
|  |  *       _____  _       _    _____                                _ | ||||||
|  |  *      |  __ \| |     | |  / ____|                              | | | ||||||
|  |  *      | |__) | | ___ | |_| (___   __ _ _   _  __ _ _ __ ___  __| | | ||||||
|  |  *      |  ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | | ||||||
|  |  *      | |    | | (_) | |_ ____) | (_| | |_| | (_| | | |  __/ (_| | | ||||||
|  |  *      |_|    |_|\___/ \__|_____/ \__, |\__,_|\__,_|_|  \___|\__,_| | ||||||
|  |  *                                    | | | ||||||
|  |  *                                    |_| | ||||||
|  |  *            PlotSquared plot management system for Minecraft | ||||||
|  |  *               Copyright (C) 2014 - 2022 IntellectualSites | ||||||
|  |  * | ||||||
|  |  *     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.location; | ||||||
|  |  | ||||||
|  | import com.plotsquared.core.util.AnnotationHelper; | ||||||
|  | import com.sk89q.worldedit.math.BlockVector3; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * Used internally for generation to reference locations in worlds that "don't exist yet". There is no guarantee that the world | ||||||
|  |  * name provided by {@link UncheckedWorldLocation#getWorldName()} exists on the server. | ||||||
|  |  * | ||||||
|  |  * @since TODO | ||||||
|  |  */ | ||||||
|  | @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||||
|  | public final class UncheckedWorldLocation extends Location { | ||||||
|  |  | ||||||
|  |     private final String worldName; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     private UncheckedWorldLocation( | ||||||
|  |             final @NonNull String worldName, final int x, final int y, final int z | ||||||
|  |     ) { | ||||||
|  |         super(World.nullWorld(), BlockVector3.at(x, y, z), 0f, 0f); | ||||||
|  |         this.worldName = worldName; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Construct a new location with yaw and pitch equal to 0 | ||||||
|  |      * | ||||||
|  |      * @param world World | ||||||
|  |      * @param x     X coordinate | ||||||
|  |      * @param y     Y coordinate | ||||||
|  |      * @param z     Z coordinate | ||||||
|  |      * @return New location | ||||||
|  |      * | ||||||
|  |      * @since TODO | ||||||
|  |      */ | ||||||
|  |     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||||
|  |     public static @NonNull UncheckedWorldLocation at( | ||||||
|  |             final @NonNull String world, final int x, final int y, final int z | ||||||
|  |     ) { | ||||||
|  |         return new UncheckedWorldLocation(world, x, y, z); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to changes at any time.") | ||||||
|  |     public @NonNull String getWorldName() { | ||||||
|  |         return this.worldName; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -58,6 +58,21 @@ public interface World<T> { | |||||||
|      */ |      */ | ||||||
|     @NonNull String getName(); |     @NonNull String getName(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the min world height. Inclusive. | ||||||
|  |      * | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      */ | ||||||
|  |     int getMinHeight(); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the max world height. Inclusive. | ||||||
|  |      * | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      */ | ||||||
|  |     int getMaxHeight(); | ||||||
|  |  | ||||||
|     class NullWorld<T> implements World<T> { |     class NullWorld<T> implements World<T> { | ||||||
|  |  | ||||||
|         private NullWorld() { |         private NullWorld() { | ||||||
| @@ -74,6 +89,16 @@ public interface World<T> { | |||||||
|             return ""; |             return ""; | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public int getMinHeight() { | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         @Override | ||||||
|  |         public int getMaxHeight() { | ||||||
|  |             return 0; | ||||||
|  |         } | ||||||
|  |  | ||||||
|         @Override |         @Override | ||||||
|         public boolean equals(final Object obj) { |         public boolean equals(final Object obj) { | ||||||
|             return obj instanceof NullWorld; |             return obj instanceof NullWorld; | ||||||
|   | |||||||
| @@ -122,7 +122,7 @@ import static com.plotsquared.core.util.entity.EntityCategories.CAP_VEHICLE; | |||||||
|  */ |  */ | ||||||
| public class Plot { | public class Plot { | ||||||
|  |  | ||||||
|  |     @Deprecated(forRemoval = true, since = "6.6.0") | ||||||
|     public static final int MAX_HEIGHT = 256; |     public static final int MAX_HEIGHT = 256; | ||||||
|  |  | ||||||
|     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Plot.class.getSimpleName()); |     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Plot.class.getSimpleName()); | ||||||
| @@ -1371,7 +1371,7 @@ public class Plot { | |||||||
|         int z = largest.getMinimumPoint().getZ() - 1; |         int z = largest.getMinimumPoint().getZ() - 1; | ||||||
|         PlotManager manager = getManager(); |         PlotManager manager = getManager(); | ||||||
|         int y = isLoaded() ? this.worldUtil.getHighestBlockSynchronous(getWorldName(), x, z) : 62; |         int y = isLoaded() ? this.worldUtil.getHighestBlockSynchronous(getWorldName(), x, z) : 62; | ||||||
|         if (area.allowSigns() && (y <= 0 || y >= 255)) { |         if (area.allowSigns() && (y <= area.getMinGenHeight() || y >= area.getMaxGenHeight())) { | ||||||
|             y = Math.max(y, manager.getSignLoc(this).getY() - 1); |             y = Math.max(y, manager.getSignLoc(this).getY() - 1); | ||||||
|         } |         } | ||||||
|         return Location.at(getWorldName(), x, y + 1, z); |         return Location.at(getWorldName(), x, y + 1, z); | ||||||
| @@ -1387,7 +1387,7 @@ public class Plot { | |||||||
|         if (isLoaded()) { |         if (isLoaded()) { | ||||||
|             this.worldUtil.getHighestBlock(getWorldName(), x, z, y -> { |             this.worldUtil.getHighestBlock(getWorldName(), x, z, y -> { | ||||||
|                 int height = y; |                 int height = y; | ||||||
|                 if (area.allowSigns() && (y <= 0 || y >= 255)) { |                 if (area.allowSigns() && (y <= area.getMinGenHeight() || y >= area.getMaxGenHeight())) { | ||||||
|                     height = Math.max(y, manager.getSignLoc(this).getY() - 1); |                     height = Math.max(y, manager.getSignLoc(this).getY() - 1); | ||||||
|                 } |                 } | ||||||
|                 result.accept(Location.at(getWorldName(), x, height + 1, z)); |                 result.accept(Location.at(getWorldName(), x, height + 1, z)); | ||||||
| @@ -1420,15 +1420,7 @@ public class Plot { | |||||||
|                         0 |                         0 | ||||||
|                 ); |                 ); | ||||||
|             } |             } | ||||||
|             Location location = Location |             Location location = toHomeLocation(bottom, home); | ||||||
|                     .at( |  | ||||||
|                             bottom.getWorldName(), |  | ||||||
|                             bottom.getX() + home.getX(), |  | ||||||
|                             bottom.getY() + home.getY(), |  | ||||||
|                             bottom.getZ() + home.getZ(), |  | ||||||
|                             home.getYaw(), |  | ||||||
|                             home.getPitch() |  | ||||||
|                     ); |  | ||||||
|             if (!this.worldUtil.getBlockSynchronous(location).getBlockType().getMaterial().isAir()) { |             if (!this.worldUtil.getBlockSynchronous(location).getBlockType().getMaterial().isAir()) { | ||||||
|                 location = location.withY( |                 location = location.withY( | ||||||
|                         Math.max(1 + this.worldUtil.getHighestBlockSynchronous( |                         Math.max(1 + this.worldUtil.getHighestBlockSynchronous( | ||||||
| @@ -1461,15 +1453,7 @@ public class Plot { | |||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             Location bottom = this.getBottomAbs(); |             Location bottom = this.getBottomAbs(); | ||||||
|             Location location = Location |             Location location = toHomeLocation(bottom, home); | ||||||
|                     .at( |  | ||||||
|                             bottom.getWorldName(), |  | ||||||
|                             bottom.getX() + home.getX(), |  | ||||||
|                             bottom.getY() + home.getY(), |  | ||||||
|                             bottom.getZ() + home.getZ(), |  | ||||||
|                             home.getYaw(), |  | ||||||
|                             home.getPitch() |  | ||||||
|                     ); |  | ||||||
|             this.worldUtil.getBlock(location, block -> { |             this.worldUtil.getBlock(location, block -> { | ||||||
|                 if (!block.getBlockType().getMaterial().isAir()) { |                 if (!block.getBlockType().getMaterial().isAir()) { | ||||||
|                     this.worldUtil.getHighestBlock(this.getWorldName(), location.getX(), location.getZ(), |                     this.worldUtil.getHighestBlock(this.getWorldName(), location.getX(), location.getZ(), | ||||||
| @@ -1482,6 +1466,17 @@ public class Plot { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private Location toHomeLocation(Location bottom, BlockLoc relativeHome) { | ||||||
|  |         return Location.at( | ||||||
|  |                 bottom.getWorldName(), | ||||||
|  |                 bottom.getX() + relativeHome.getX(), | ||||||
|  |                 relativeHome.getY(), // y is absolute | ||||||
|  |                 bottom.getZ() + relativeHome.getZ(), | ||||||
|  |                 relativeHome.getYaw(), | ||||||
|  |                 relativeHome.getPitch() | ||||||
|  |         ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Sets the home location |      * Sets the home location | ||||||
|      * |      * | ||||||
| @@ -1619,8 +1614,8 @@ public class Plot { | |||||||
|     public double getVolume() { |     public double getVolume() { | ||||||
|         double count = 0; |         double count = 0; | ||||||
|         for (CuboidRegion region : getRegions()) { |         for (CuboidRegion region : getRegions()) { | ||||||
|             count += (region.getMaximumPoint().getX() - (double) region.getMinimumPoint().getX() + 1) * ( |             // CuboidRegion#getArea is deprecated and we want to ensure use of correct height | ||||||
|                     region.getMaximumPoint().getZ() - (double) region.getMinimumPoint().getZ() + 1) * MAX_HEIGHT; |             count += region.getLength() * region.getWidth() * (area.getMaxGenHeight() - area.getMinGenHeight() + 1); | ||||||
|         } |         } | ||||||
|         return count; |         return count; | ||||||
|     } |     } | ||||||
| @@ -1738,7 +1733,6 @@ public class Plot { | |||||||
|             area.addPlot(this); |             area.addPlot(this); | ||||||
|             updateWorldBorder(); |             updateWorldBorder(); | ||||||
|         } |         } | ||||||
|         this.getPlotModificationManager().setSign(player.getName()); |  | ||||||
|         player.sendMessage(TranslatableCaption.of("working.claimed"), Template.of("plot", this.getId().toString())); |         player.sendMessage(TranslatableCaption.of("working.claimed"), Template.of("plot", this.getId().toString())); | ||||||
|         if (teleport) { |         if (teleport) { | ||||||
|             if (!auto && Settings.Teleport.ON_CLAIM) { |             if (!auto && Settings.Teleport.ON_CLAIM) { | ||||||
| @@ -1786,6 +1780,7 @@ public class Plot { | |||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
|         plotworld.getPlotManager().claimPlot(this, null); |         plotworld.getPlotManager().claimPlot(this, null); | ||||||
|  |         this.getPlotModificationManager().setSign(player.getName()); | ||||||
|         return true; |         return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -2438,8 +2433,8 @@ public class Plot { | |||||||
|             return regions_cache; |             return regions_cache; | ||||||
|         } |         } | ||||||
|         if (!this.isMerged()) { |         if (!this.isMerged()) { | ||||||
|             Location pos1 = this.getBottomAbs(); |             Location pos1 = this.getBottomAbs().withY(getArea().getMinBuildHeight()); | ||||||
|             Location pos2 = this.getTopAbs(); |             Location pos2 = this.getTopAbs().withY(getArea().getMaxBuildHeight()); | ||||||
|             connected_cache = Sets.newHashSet(this); |             connected_cache = Sets.newHashSet(this); | ||||||
|             CuboidRegion rg = new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()); |             CuboidRegion rg = new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()); | ||||||
|             regions_cache = Collections.singleton(rg); |             regions_cache = Collections.singleton(rg); | ||||||
|   | |||||||
| @@ -34,8 +34,6 @@ import com.plotsquared.core.configuration.ConfigurationNode; | |||||||
| import com.plotsquared.core.configuration.ConfigurationSection; | import com.plotsquared.core.configuration.ConfigurationSection; | ||||||
| import com.plotsquared.core.configuration.ConfigurationUtil; | import com.plotsquared.core.configuration.ConfigurationUtil; | ||||||
| import com.plotsquared.core.configuration.Settings; | import com.plotsquared.core.configuration.Settings; | ||||||
| import com.plotsquared.core.configuration.caption.CaptionUtility; |  | ||||||
| import com.plotsquared.core.configuration.caption.LocaleHolder; |  | ||||||
| import com.plotsquared.core.configuration.caption.TranslatableCaption; | import com.plotsquared.core.configuration.caption.TranslatableCaption; | ||||||
| import com.plotsquared.core.configuration.file.YamlConfiguration; | import com.plotsquared.core.configuration.file.YamlConfiguration; | ||||||
| import com.plotsquared.core.generator.GridPlotWorld; | import com.plotsquared.core.generator.GridPlotWorld; | ||||||
| @@ -54,7 +52,6 @@ import com.plotsquared.core.plot.flag.FlagParseException; | |||||||
| import com.plotsquared.core.plot.flag.GlobalFlagContainer; | import com.plotsquared.core.plot.flag.GlobalFlagContainer; | ||||||
| import com.plotsquared.core.plot.flag.PlotFlag; | import com.plotsquared.core.plot.flag.PlotFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.DoneFlag; | import com.plotsquared.core.plot.flag.implementations.DoneFlag; | ||||||
| import com.plotsquared.core.plot.flag.types.DoubleFlag; |  | ||||||
| import com.plotsquared.core.queue.GlobalBlockQueue; | import com.plotsquared.core.queue.GlobalBlockQueue; | ||||||
| import com.plotsquared.core.queue.QueueCoordinator; | import com.plotsquared.core.queue.QueueCoordinator; | ||||||
| import com.plotsquared.core.util.MathMan; | import com.plotsquared.core.util.MathMan; | ||||||
| @@ -144,8 +141,10 @@ public abstract class PlotArea { | |||||||
|     private boolean homeAllowNonmember = false; |     private boolean homeAllowNonmember = false; | ||||||
|     private BlockLoc nonmemberHome; |     private BlockLoc nonmemberHome; | ||||||
|     private BlockLoc defaultHome; |     private BlockLoc defaultHome; | ||||||
|     private int maxBuildHeight = 256; |     private int maxBuildHeight = PlotSquared.platform().versionMaxHeight() + 1; // Exclusive | ||||||
|     private int minBuildHeight = 1; |     private int minBuildHeight = PlotSquared.platform().versionMinHeight() + 1; // Inclusive | ||||||
|  |     private int maxGenHeight = PlotSquared.platform().versionMaxHeight(); // Inclusive | ||||||
|  |     private int minGenHeight = PlotSquared.platform().versionMinHeight(); // Inclusive | ||||||
|     private GameMode gameMode = GameModes.CREATIVE; |     private GameMode gameMode = GameModes.CREATIVE; | ||||||
|     private Map<String, PlotExpression> prices = new HashMap<>(); |     private Map<String, PlotExpression> prices = new HashMap<>(); | ||||||
|     private List<String> schematics = new ArrayList<>(); |     private List<String> schematics = new ArrayList<>(); | ||||||
| @@ -361,6 +360,8 @@ public abstract class PlotArea { | |||||||
|         this.worldBorder = config.getBoolean("world.border"); |         this.worldBorder = config.getBoolean("world.border"); | ||||||
|         this.maxBuildHeight = config.getInt("world.max_height"); |         this.maxBuildHeight = config.getInt("world.max_height"); | ||||||
|         this.minBuildHeight = config.getInt("world.min_height"); |         this.minBuildHeight = config.getInt("world.min_height"); | ||||||
|  |         this.minGenHeight = config.getInt("world.min_gen_height"); | ||||||
|  |         this.maxGenHeight = config.getInt("world.max_gen_height"); | ||||||
|  |  | ||||||
|         switch (config.getString("world.gamemode").toLowerCase()) { |         switch (config.getString("world.gamemode").toLowerCase()) { | ||||||
|             case "creative", "c", "1" -> this.gameMode = GameModes.CREATIVE; |             case "creative", "c", "1" -> this.gameMode = GameModes.CREATIVE; | ||||||
| @@ -484,6 +485,8 @@ public abstract class PlotArea { | |||||||
|         options.put("home.nonmembers", position); |         options.put("home.nonmembers", position); | ||||||
|         options.put("world.max_height", this.getMaxBuildHeight()); |         options.put("world.max_height", this.getMaxBuildHeight()); | ||||||
|         options.put("world.min_height", this.getMinBuildHeight()); |         options.put("world.min_height", this.getMinBuildHeight()); | ||||||
|  |         options.put("world.min_gen_height", this.getMinGenHeight()); | ||||||
|  |         options.put("world.max_gen_height", this.getMaxGenHeight()); | ||||||
|         options.put("world.gamemode", this.getGameMode().getName().toLowerCase()); |         options.put("world.gamemode", this.getGameMode().getName().toLowerCase()); | ||||||
|         options.put("road.flags.default", null); |         options.put("road.flags.default", null); | ||||||
|  |  | ||||||
| @@ -1078,8 +1081,8 @@ public abstract class PlotArea { | |||||||
|                     BlockVector2 pos1 = BlockVector2.at(value.getP1().getX(), value.getP1().getY()); |                     BlockVector2 pos1 = BlockVector2.at(value.getP1().getX(), value.getP1().getY()); | ||||||
|                     BlockVector2 pos2 = BlockVector2.at(value.getP2().getX(), value.getP2().getY()); |                     BlockVector2 pos2 = BlockVector2.at(value.getP2().getX(), value.getP2().getY()); | ||||||
|                     return new CuboidRegion( |                     return new CuboidRegion( | ||||||
|                             pos1.toBlockVector3(), |                             pos1.toBlockVector3(getMinGenHeight()), | ||||||
|                             pos2.toBlockVector3(Plot.MAX_HEIGHT - 1) |                             pos2.toBlockVector3(getMaxGenHeight()) | ||||||
|                     ); |                     ); | ||||||
|                 } |                 } | ||||||
|             }; |             }; | ||||||
| @@ -1361,14 +1364,38 @@ public abstract class PlotArea { | |||||||
|         this.defaultHome = defaultHome; |         this.defaultHome = defaultHome; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the maximum height players may build in. Exclusive. | ||||||
|  |      */ | ||||||
|     public int getMaxBuildHeight() { |     public int getMaxBuildHeight() { | ||||||
|         return this.maxBuildHeight; |         return this.maxBuildHeight; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the minimum height players may build in. Inclusive. | ||||||
|  |      */ | ||||||
|     public int getMinBuildHeight() { |     public int getMinBuildHeight() { | ||||||
|         return this.minBuildHeight; |         return this.minBuildHeight; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the min height from which P2 will generate blocks. Inclusive. | ||||||
|  |      * | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      */ | ||||||
|  |     public int getMinGenHeight() { | ||||||
|  |         return this.minGenHeight; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the max height to which P2 will generate blocks. Inclusive. | ||||||
|  |      * | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      */ | ||||||
|  |     public int getMaxGenHeight() { | ||||||
|  |         return this.maxGenHeight; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public GameMode getGameMode() { |     public GameMode getGameMode() { | ||||||
|         return this.gameMode; |         return this.gameMode; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -89,11 +89,17 @@ public class PlotCluster { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void setRegion() { |     private void setRegion() { | ||||||
|         this.region = RegionUtil.createRegion(this.pos1.getX(), this.pos2.getX(), |         this.region = RegionUtil.createRegion(this.pos1.getX(), this.pos2.getX(), 0, 0, | ||||||
|                 this.pos1.getY(), this.pos2.getY() |                 this.pos1.getY(), this.pos2.getY() | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns a region of PlotIDs | ||||||
|  |      * | ||||||
|  |      * @deprecated - returns region of IDs, not of actual blocks. | ||||||
|  |      */ | ||||||
|  |     @Deprecated | ||||||
|     public CuboidRegion getRegion() { |     public CuboidRegion getRegion() { | ||||||
|         return this.region; |         return this.region; | ||||||
|     } |     } | ||||||
| @@ -165,7 +171,7 @@ public class PlotCluster { | |||||||
|         Consumer<Location> locationConsumer = toReturn -> |         Consumer<Location> locationConsumer = toReturn -> | ||||||
|                 PlotSquared.platform().worldUtil().getHighestBlock(this.area.getWorldName(), toReturn.getX(), toReturn.getZ(), |                 PlotSquared.platform().worldUtil().getHighestBlock(this.area.getWorldName(), toReturn.getX(), toReturn.getZ(), | ||||||
|                         highest -> { |                         highest -> { | ||||||
|                             if (highest == 0) { |                             if (highest <= area.getMinBuildHeight()) { | ||||||
|                                 highest = 63; |                                 highest = 63; | ||||||
|                             } |                             } | ||||||
|                             if (highest > toReturn.getY()) { |                             if (highest > toReturn.getY()) { | ||||||
| @@ -175,12 +181,12 @@ public class PlotCluster { | |||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|                 ); |                 ); | ||||||
|         if (home.getY() == 0) { |         if (home.getY() == Integer.MIN_VALUE) { | ||||||
|             // default pos |             // default pos | ||||||
|             Plot center = getCenterPlot(); |             Plot center = getCenterPlot(); | ||||||
|             center.getHome(location -> { |             center.getHome(location -> { | ||||||
|                 Location toReturn = location; |                 Location toReturn = location; | ||||||
|                 if (toReturn.getY() == 0) { |                 if (toReturn.getY() <= area.getMinBuildHeight()) { | ||||||
|                     PlotManager manager = this.area.getPlotManager(); |                     PlotManager manager = this.area.getPlotManager(); | ||||||
|                     Location locationSign = manager.getSignLoc(center); |                     Location locationSign = manager.getSignLoc(center); | ||||||
|                     toReturn = toReturn.withY(locationSign.getY()); |                     toReturn = toReturn.withY(locationSign.getY()); | ||||||
|   | |||||||
| @@ -69,8 +69,6 @@ import java.util.concurrent.CompletableFuture; | |||||||
| import java.util.concurrent.atomic.AtomicBoolean; | import java.util.concurrent.atomic.AtomicBoolean; | ||||||
| import java.util.stream.Collectors; | import java.util.stream.Collectors; | ||||||
|  |  | ||||||
| import static com.plotsquared.core.plot.Plot.MAX_HEIGHT; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Manager that handles {@link Plot} modifications |  * Manager that handles {@link Plot} modifications | ||||||
|  */ |  */ | ||||||
| @@ -311,7 +309,7 @@ public final class PlotModificationManager { | |||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|                 CuboidRegion region = regions.poll(); |                 CuboidRegion region = regions.poll(); | ||||||
|                 PlotSquared.platform().regionManager().setBiome(region, extendBiome, biome, plot.getWorldName(), this); |                 PlotSquared.platform().regionManager().setBiome(region, extendBiome, biome, plot.getArea(), this); | ||||||
|             } |             } | ||||||
|         }; |         }; | ||||||
|         run.run(); |         run.run(); | ||||||
| @@ -335,10 +333,9 @@ public final class PlotModificationManager { | |||||||
|             ids.add(current.getId()); |             ids.add(current.getId()); | ||||||
|         } |         } | ||||||
|         this.plot.clearRatings(); |         this.plot.clearRatings(); | ||||||
|         QueueCoordinator queue = null; |         QueueCoordinator queue = this.plot.getArea().getQueue(); | ||||||
|         if (createSign) { |         if (createSign) { | ||||||
|             this.removeSign(); |             this.removeSign(); | ||||||
|             queue = this.plot.getArea().getQueue(); |  | ||||||
|         } |         } | ||||||
|         PlotManager manager = this.plot.getArea().getPlotManager(); |         PlotManager manager = this.plot.getArea().getPlotManager(); | ||||||
|         if (createRoad) { |         if (createRoad) { | ||||||
| @@ -527,28 +524,6 @@ public final class PlotModificationManager { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |  | ||||||
|      * Remove the south road section of a plot<br> |  | ||||||
|      * - Used when a plot is merged<br> |  | ||||||
|      * |  | ||||||
|      * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues, |  | ||||||
|      *              otherwise writes to the queue but does not enqueue. |  | ||||||
|      */ |  | ||||||
|     public void removeRoadSouth(final @Nullable QueueCoordinator queue) { |  | ||||||
|         if (this.plot.getArea().getType() != PlotAreaType.NORMAL && this.plot |  | ||||||
|                 .getArea() |  | ||||||
|                 .getTerrain() == PlotAreaTerrainType.ROAD) { |  | ||||||
|             Plot other = this.plot.getRelative(Direction.SOUTH); |  | ||||||
|             Location bot = other.getBottomAbs(); |  | ||||||
|             Location top = this.plot.getTopAbs(); |  | ||||||
|             Location pos1 = Location.at(this.plot.getWorldName(), bot.getX(), 0, top.getZ()); |  | ||||||
|             Location pos2 = Location.at(this.plot.getWorldName(), top.getX(), MAX_HEIGHT, bot.getZ()); |  | ||||||
|             PlotSquared.platform().regionManager().regenerateRegion(pos1, pos2, true, null); |  | ||||||
|         } else if (this.plot.getArea().getTerrain() != PlotAreaTerrainType.ALL) { // no road generated => no road to remove |  | ||||||
|             this.plot.getManager().removeRoadSouth(this.plot, queue); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Auto merge a plot in a specific direction. |      * Auto merge a plot in a specific direction. | ||||||
|      * |      * | ||||||
| @@ -915,6 +890,28 @@ public final class PlotModificationManager { | |||||||
|         return this.setComponent(component, parsed.toPattern(), actor, queue); |         return this.setComponent(component, parsed.toPattern(), actor, queue); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Remove the south road section of a plot<br> | ||||||
|  |      * - Used when a plot is merged<br> | ||||||
|  |      * | ||||||
|  |      * @param queue Nullable {@link QueueCoordinator}. If null, creates own queue and enqueues, | ||||||
|  |      *              otherwise writes to the queue but does not enqueue. | ||||||
|  |      */ | ||||||
|  |     public void removeRoadSouth(final @Nullable QueueCoordinator queue) { | ||||||
|  |         if (this.plot.getArea().getType() != PlotAreaType.NORMAL && this.plot | ||||||
|  |                 .getArea() | ||||||
|  |                 .getTerrain() == PlotAreaTerrainType.ROAD) { | ||||||
|  |             Plot other = this.plot.getRelative(Direction.SOUTH); | ||||||
|  |             Location bot = other.getBottomAbs(); | ||||||
|  |             Location top = this.plot.getTopAbs(); | ||||||
|  |             Location pos1 = Location.at(this.plot.getWorldName(), bot.getX(), plot.getArea().getMinGenHeight(), top.getZ()); | ||||||
|  |             Location pos2 = Location.at(this.plot.getWorldName(), top.getX(), plot.getArea().getMaxGenHeight(), bot.getZ()); | ||||||
|  |             PlotSquared.platform().regionManager().regenerateRegion(pos1, pos2, true, null); | ||||||
|  |         } else if (this.plot.getArea().getTerrain() != PlotAreaTerrainType.ALL) { // no road generated => no road to remove | ||||||
|  |             this.plot.getManager().removeRoadSouth(this.plot, queue); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Remove the east road section of a plot<br> |      * Remove the east road section of a plot<br> | ||||||
|      * - Used when a plot is merged<br> |      * - Used when a plot is merged<br> | ||||||
| @@ -929,8 +926,8 @@ public final class PlotModificationManager { | |||||||
|             Plot other = this.plot.getRelative(Direction.EAST); |             Plot other = this.plot.getRelative(Direction.EAST); | ||||||
|             Location bot = other.getBottomAbs(); |             Location bot = other.getBottomAbs(); | ||||||
|             Location top = this.plot.getTopAbs(); |             Location top = this.plot.getTopAbs(); | ||||||
|             Location pos1 = Location.at(this.plot.getWorldName(), top.getX(), 0, bot.getZ()); |             Location pos1 = Location.at(this.plot.getWorldName(), top.getX(), plot.getArea().getMinGenHeight(), bot.getZ()); | ||||||
|             Location pos2 = Location.at(this.plot.getWorldName(), bot.getX(), MAX_HEIGHT, top.getZ()); |             Location pos2 = Location.at(this.plot.getWorldName(), bot.getX(), plot.getArea().getMaxGenHeight(), top.getZ()); | ||||||
|             PlotSquared.platform().regionManager().regenerateRegion(pos1, pos2, true, null); |             PlotSquared.platform().regionManager().regenerateRegion(pos1, pos2, true, null); | ||||||
|         } else if (this.plot.getArea().getTerrain() != PlotAreaTerrainType.ALL) { // no road generated => no road to remove |         } else if (this.plot.getArea().getTerrain() != PlotAreaTerrainType.ALL) { // no road generated => no road to remove | ||||||
|             this.plot.getArea().getPlotManager().removeRoadEast(this.plot, queue); |             this.plot.getArea().getPlotManager().removeRoadEast(this.plot, queue); | ||||||
| @@ -948,8 +945,8 @@ public final class PlotModificationManager { | |||||||
|                 .getArea() |                 .getArea() | ||||||
|                 .getTerrain() == PlotAreaTerrainType.ROAD) { |                 .getTerrain() == PlotAreaTerrainType.ROAD) { | ||||||
|             Plot other = this.plot.getRelative(1, 1); |             Plot other = this.plot.getRelative(1, 1); | ||||||
|             Location pos1 = this.plot.getTopAbs().add(1, 0, 1).withY(0); |             Location pos1 = this.plot.getTopAbs().add(1, 0, 1); | ||||||
|             Location pos2 = other.getBottomAbs().subtract(1, 0, 1).withY(MAX_HEIGHT); |             Location pos2 = other.getBottomAbs().subtract(1, 0, 1); | ||||||
|             PlotSquared.platform().regionManager().regenerateRegion(pos1, pos2, true, null); |             PlotSquared.platform().regionManager().regenerateRegion(pos1, pos2, true, null); | ||||||
|         } else if (this.plot.getArea().getTerrain() != PlotAreaTerrainType.ALL) { // no road generated => no road to remove |         } else if (this.plot.getArea().getTerrain() != PlotAreaTerrainType.ALL) { // no road generated => no road to remove | ||||||
|             this.plot.getArea().getPlotManager().removeRoadSouthEast(this.plot, queue); |             this.plot.getArea().getPlotManager().removeRoadSouthEast(this.plot, queue); | ||||||
|   | |||||||
| @@ -125,7 +125,7 @@ public abstract class PlotWorld { | |||||||
|     /** |     /** | ||||||
|      * @deprecated This method is not meant to be invoked or overridden, with no replacement. |      * @deprecated This method is not meant to be invoked or overridden, with no replacement. | ||||||
|      */ |      */ | ||||||
|     @Deprecated(forRemoval = true, since = "TODO") |     @Deprecated(forRemoval = true, since = "6.6.0") | ||||||
|     protected boolean canEqual(final Object other) { |     protected boolean canEqual(final Object other) { | ||||||
|         return other instanceof PlotWorld; |         return other instanceof PlotWorld; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -75,9 +75,9 @@ public class ExpiryTask { | |||||||
|                     plots = plots != null ? plots : getPlotsToCheck(); |                     plots = plots != null ? plots : getPlotsToCheck(); | ||||||
|                     int diff = settings.REQUIRED_PLOTS; |                     int diff = settings.REQUIRED_PLOTS; | ||||||
|                     boolean min = true; |                     boolean min = true; | ||||||
|                     if (settings.REQUIRED_PLOTS - plots.size() < settings.REQUIRED_PLOTS) { |                     if (plots.size() > settings.REQUIRED_PLOTS) { | ||||||
|                         min = false; |                         min = false; | ||||||
|                         diff = settings.REQUIRED_PLOTS - plots.size(); |                         diff = plots.size() - settings.REQUIRED_PLOTS; | ||||||
|                     } |                     } | ||||||
|                     List<Long> entireList = |                     List<Long> entireList = | ||||||
|                             plots.stream().map(plot -> ExpireManager.IMP.getAge(plot, settings.DELETE_IF_OWNER_IS_UNKNOWN)) |                             plots.stream().map(plot -> ExpireManager.IMP.getAge(plot, settings.DELETE_IF_OWNER_IS_UNKNOWN)) | ||||||
|   | |||||||
| @@ -391,7 +391,7 @@ public class FlagContainer { | |||||||
|     /** |     /** | ||||||
|      * @deprecated This method is not meant to be invoked or overridden, with no replacement. |      * @deprecated This method is not meant to be invoked or overridden, with no replacement. | ||||||
|      */ |      */ | ||||||
|     @Deprecated(forRemoval = true, since = "TODO") |     @Deprecated(forRemoval = true, since = "6.6.0") | ||||||
|     protected boolean canEqual(final Object other) { |     protected boolean canEqual(final Object other) { | ||||||
|         return other instanceof FlagContainer; |         return other instanceof FlagContainer; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -93,6 +93,7 @@ import com.plotsquared.core.plot.flag.implementations.PlayerInteractFlag; | |||||||
| import com.plotsquared.core.plot.flag.implementations.PlotTitleFlag; | import com.plotsquared.core.plot.flag.implementations.PlotTitleFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.PreventCreativeCopyFlag; | import com.plotsquared.core.plot.flag.implementations.PreventCreativeCopyFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.PriceFlag; | import com.plotsquared.core.plot.flag.implementations.PriceFlag; | ||||||
|  | import com.plotsquared.core.plot.flag.implementations.ProjectilesFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.PveFlag; | import com.plotsquared.core.plot.flag.implementations.PveFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.PvpFlag; | import com.plotsquared.core.plot.flag.implementations.PvpFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.RedstoneFlag; | import com.plotsquared.core.plot.flag.implementations.RedstoneFlag; | ||||||
| @@ -198,6 +199,7 @@ public final class GlobalFlagContainer extends FlagContainer { | |||||||
|         this.addFlag(VehicleUseFlag.VEHICLE_USE_FALSE); |         this.addFlag(VehicleUseFlag.VEHICLE_USE_FALSE); | ||||||
|         this.addFlag(VillagerInteractFlag.VILLAGER_INTERACT_FALSE); |         this.addFlag(VillagerInteractFlag.VILLAGER_INTERACT_FALSE); | ||||||
|         this.addFlag(VineGrowFlag.VINE_GROW_TRUE); |         this.addFlag(VineGrowFlag.VINE_GROW_TRUE); | ||||||
|  |         this.addFlag(ProjectilesFlag.PROJECTILES_FALSE); | ||||||
|  |  | ||||||
|         // Double flags |         // Double flags | ||||||
|         this.addFlag(PriceFlag.PRICE_NOT_BUYABLE); |         this.addFlag(PriceFlag.PRICE_NOT_BUYABLE); | ||||||
|   | |||||||
| @@ -221,7 +221,7 @@ public abstract class PlotFlag<T, F extends PlotFlag<T, F>> { | |||||||
|     /** |     /** | ||||||
|      * @deprecated This method is not meant to be invoked or overridden, with no replacement. |      * @deprecated This method is not meant to be invoked or overridden, with no replacement. | ||||||
|      */ |      */ | ||||||
|     @Deprecated(forRemoval = true, since = "TODO") |     @Deprecated(forRemoval = true, since = "6.6.0") | ||||||
|     protected boolean canEqual(final Object other) { |     protected boolean canEqual(final Object other) { | ||||||
|         return other instanceof PlotFlag; |         return other instanceof PlotFlag; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -0,0 +1,46 @@ | |||||||
|  | /* | ||||||
|  |  *       _____  _       _    _____                                _ | ||||||
|  |  *      |  __ \| |     | |  / ____|                              | | | ||||||
|  |  *      | |__) | | ___ | |_| (___   __ _ _   _  __ _ _ __ ___  __| | | ||||||
|  |  *      |  ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | | ||||||
|  |  *      | |    | | (_) | |_ ____) | (_| | |_| | (_| | | |  __/ (_| | | ||||||
|  |  *      |_|    |_|\___/ \__|_____/ \__, |\__,_|\__,_|_|  \___|\__,_| | ||||||
|  |  *                                    | | | ||||||
|  |  *                                    |_| | ||||||
|  |  *            PlotSquared plot management system for Minecraft | ||||||
|  |  *               Copyright (C) 2014 - 2022 IntellectualSites | ||||||
|  |  * | ||||||
|  |  *     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.plot.flag.implementations; | ||||||
|  |  | ||||||
|  | import com.plotsquared.core.configuration.caption.TranslatableCaption; | ||||||
|  | import com.plotsquared.core.plot.flag.types.BooleanFlag; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | public class ProjectilesFlag extends BooleanFlag<ProjectilesFlag> { | ||||||
|  |  | ||||||
|  |     public static final ProjectilesFlag PROJECTILES_TRUE = new ProjectilesFlag(true); | ||||||
|  |     public static final ProjectilesFlag PROJECTILES_FALSE = new ProjectilesFlag(false); | ||||||
|  |  | ||||||
|  |     private ProjectilesFlag(boolean value){ | ||||||
|  |         super(value, TranslatableCaption.of("flags.flag_description_projectiles")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     protected ProjectilesFlag flagOf(@NonNull final Boolean value) { | ||||||
|  |         return value ? PROJECTILES_TRUE : PROJECTILES_FALSE; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -34,6 +34,7 @@ import com.sk89q.worldedit.function.pattern.Pattern; | |||||||
| import com.sk89q.worldedit.math.BlockVector2; | import com.sk89q.worldedit.math.BlockVector2; | ||||||
| import com.sk89q.worldedit.regions.CuboidRegion; | import com.sk89q.worldedit.regions.CuboidRegion; | ||||||
| import com.sk89q.worldedit.util.Location; | import com.sk89q.worldedit.util.Location; | ||||||
|  | import com.sk89q.worldedit.util.SideEffectSet; | ||||||
| import com.sk89q.worldedit.world.World; | import com.sk89q.worldedit.world.World; | ||||||
| import com.sk89q.worldedit.world.biome.BiomeType; | import com.sk89q.worldedit.world.biome.BiomeType; | ||||||
| import com.sk89q.worldedit.world.block.BaseBlock; | import com.sk89q.worldedit.world.block.BaseBlock; | ||||||
| @@ -61,6 +62,7 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator { | |||||||
|     private int lastX = Integer.MIN_VALUE; |     private int lastX = Integer.MIN_VALUE; | ||||||
|     private int lastZ = Integer.MIN_VALUE; |     private int lastZ = Integer.MIN_VALUE; | ||||||
|     private boolean settingBiomes = false; |     private boolean settingBiomes = false; | ||||||
|  |     private boolean disableBiomes = false; | ||||||
|     private boolean settingTiles = false; |     private boolean settingTiles = false; | ||||||
|     private boolean regen = false; |     private boolean regen = false; | ||||||
|     private int[] regenStart; |     private int[] regenStart; | ||||||
| @@ -68,7 +70,8 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator { | |||||||
|     private CuboidRegion regenRegion = null; |     private CuboidRegion regenRegion = null; | ||||||
|     private Consumer<BlockVector2> consumer = null; |     private Consumer<BlockVector2> consumer = null; | ||||||
|     private boolean unloadAfter = true; |     private boolean unloadAfter = true; | ||||||
|     private Runnable whenDone; |     private Runnable whenDone = null; | ||||||
|  |     private SideEffectSet sideEffectSet = null; | ||||||
|     @Nullable |     @Nullable | ||||||
|     private LightingMode lightingMode = LightingMode.valueOf(Settings.QUEUE.LIGHTING_MODE); |     private LightingMode lightingMode = LightingMode.valueOf(Settings.QUEUE.LIGHTING_MODE); | ||||||
|  |  | ||||||
| @@ -101,7 +104,7 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean setBlock(int x, int y, int z, @NonNull BaseBlock id) { |     public boolean setBlock(int x, int y, int z, @NonNull BaseBlock id) { | ||||||
|         if ((y > 255) || (y < 0)) { |         if ((y > world.getMaxY()) || (y < world.getMinY())) { | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         LocalChunk chunk = getChunk(x >> 4, z >> 4); |         LocalChunk chunk = getChunk(x >> 4, z >> 4); | ||||||
| @@ -120,8 +123,11 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator { | |||||||
|     @SuppressWarnings("removal") |     @SuppressWarnings("removal") | ||||||
|     @Override |     @Override | ||||||
|     public boolean setBiome(int x, int z, @NonNull BiomeType biomeType) { |     public boolean setBiome(int x, int z, @NonNull BiomeType biomeType) { | ||||||
|  |         if (disableBiomes) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|         LocalChunk chunk = getChunk(x >> 4, z >> 4); |         LocalChunk chunk = getChunk(x >> 4, z >> 4); | ||||||
|         for (int y = 0; y < 256; y++) { |         for (int y = world.getMinY(); y <= world.getMaxY(); y++) { | ||||||
|             chunk.setBiome(x & 15, y, z & 15, biomeType); |             chunk.setBiome(x & 15, y, z & 15, biomeType); | ||||||
|         } |         } | ||||||
|         settingBiomes = true; |         settingBiomes = true; | ||||||
| @@ -130,6 +136,9 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public final boolean setBiome(int x, int y, int z, @NonNull BiomeType biomeType) { |     public final boolean setBiome(int x, int y, int z, @NonNull BiomeType biomeType) { | ||||||
|  |         if (disableBiomes) { | ||||||
|  |             return false; | ||||||
|  |         } | ||||||
|         LocalChunk chunk = getChunk(x >> 4, z >> 4); |         LocalChunk chunk = getChunk(x >> 4, z >> 4); | ||||||
|         chunk.setBiome(x & 15, y, z & 15, biomeType); |         chunk.setBiome(x & 15, y, z & 15, biomeType); | ||||||
|         settingBiomes = true; |         settingBiomes = true; | ||||||
| @@ -141,6 +150,12 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator { | |||||||
|         return this.settingBiomes; |         return this.settingBiomes; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void setBiomesEnabled(boolean settingBiomes) { | ||||||
|  |         this.settingBiomes = settingBiomes; | ||||||
|  |         this.disableBiomes = true; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean setTile(int x, int y, int z, @NonNull CompoundTag tag) { |     public boolean setTile(int x, int y, int z, @NonNull CompoundTag tag) { | ||||||
|         LocalChunk chunk = getChunk(x >> 4, z >> 4); |         LocalChunk chunk = getChunk(x >> 4, z >> 4); | ||||||
| @@ -315,6 +330,29 @@ public abstract class BasicQueueCoordinator extends QueueCoordinator { | |||||||
|         this.whenDone = whenDone; |         this.whenDone = whenDone; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public SideEffectSet getSideEffectSet() { | ||||||
|  |         return sideEffectSet; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void setSideEffectSet(SideEffectSet sideEffectSet) { | ||||||
|  |         this.sideEffectSet = sideEffectSet; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // Don't ask about the @NonNull placement. That's how it needs to be else it errors. | ||||||
|  |     @Override | ||||||
|  |     public void setBiomeCuboid( | ||||||
|  |             final com.plotsquared.core.location.@NonNull Location pos1, | ||||||
|  |             final com.plotsquared.core.location.@NonNull Location pos2, | ||||||
|  |             @NonNull final BiomeType biome | ||||||
|  |     ) { | ||||||
|  |         if (disableBiomes) { | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |         super.setBiomeCuboid(pos1, pos2, biome); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get the {@link LocalChunk} from the queue at the given chunk coordinates. Returns a new instance if one doesn't exist |      * Get the {@link LocalChunk} from the queue at the given chunk coordinates. Returns a new instance if one doesn't exist | ||||||
|      */ |      */ | ||||||
|   | |||||||
| @@ -0,0 +1,175 @@ | |||||||
|  | /* | ||||||
|  |  *       _____  _       _    _____                                _ | ||||||
|  |  *      |  __ \| |     | |  / ____|                              | | | ||||||
|  |  *      | |__) | | ___ | |_| (___   __ _ _   _  __ _ _ __ ___  __| | | ||||||
|  |  *      |  ___/| |/ _ \| __|\___ \ / _` | | | |/ _` | '__/ _ \/ _` | | ||||||
|  |  *      | |    | | (_) | |_ ____) | (_| | |_| | (_| | | |  __/ (_| | | ||||||
|  |  *      |_|    |_|\___/ \__|_____/ \__, |\__,_|\__,_|_|  \___|\__,_| | ||||||
|  |  *                                    | | | ||||||
|  |  *                                    |_| | ||||||
|  |  *            PlotSquared plot management system for Minecraft | ||||||
|  |  *               Copyright (C) 2014 - 2022 IntellectualSites | ||||||
|  |  * | ||||||
|  |  *     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.queue; | ||||||
|  |  | ||||||
|  | import com.plotsquared.core.location.Location; | ||||||
|  | import com.plotsquared.core.util.AnnotationHelper; | ||||||
|  | import com.sk89q.jnbt.CompoundTag; | ||||||
|  | import com.sk89q.worldedit.function.pattern.Pattern; | ||||||
|  | import com.sk89q.worldedit.math.BlockVector3; | ||||||
|  | import com.sk89q.worldedit.world.biome.BiomeType; | ||||||
|  | import com.sk89q.worldedit.world.block.BaseBlock; | ||||||
|  | import com.sk89q.worldedit.world.block.BlockState; | ||||||
|  | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * {@link QueueCoordinator} that caches all blocks set to it in a given array of form BlockState[][][]. An offset can be | ||||||
|  |  * applied to blocks set to it, and the scope limited. This should have blocks set to it one chunk at a time, based on the | ||||||
|  |  * result of {@link BlockArrayCacheScopedQueueCoordinator#getMin()} and {@link BlockArrayCacheScopedQueueCoordinator#getMax()}. | ||||||
|  |  * The min and max points of this queue are offset according to the minimum point given in the constructor, and the offsets set | ||||||
|  |  * in {@link BlockArrayCacheScopedQueueCoordinator#setOffsetX(int)} and | ||||||
|  |  * {@link BlockArrayCacheScopedQueueCoordinator#setOffsetZ(int)} | ||||||
|  |  */ | ||||||
|  | @AnnotationHelper.ApiDescription(info = "Internal use only. Subject to change at any time and created for specific use cases.") | ||||||
|  | public class BlockArrayCacheScopedQueueCoordinator extends ScopedQueueCoordinator { | ||||||
|  |  | ||||||
|  |     private final BlockState[][][] blockStates; | ||||||
|  |     private final int height; | ||||||
|  |     private final int width; | ||||||
|  |     private final int length; | ||||||
|  |     private final int minY; | ||||||
|  |     private final int maxY; | ||||||
|  |     private final int scopeMinX; | ||||||
|  |     private final int scopeMinZ; | ||||||
|  |     private final int scopeMaxX; | ||||||
|  |     private final int scopeMaxZ; | ||||||
|  |     private int offsetX = 0; | ||||||
|  |     private int offsetZ = 0; | ||||||
|  |     /** | ||||||
|  |      * Construct a new instance | ||||||
|  |      * | ||||||
|  |      * @param min Inclusive location of the minimum point to limit the scope to. | ||||||
|  |      * @param max Inclusive location of the maximum point to limit the scope to. | ||||||
|  |      * @since 6.8.0 | ||||||
|  |      */ | ||||||
|  |     public BlockArrayCacheScopedQueueCoordinator(Location min, Location max) { | ||||||
|  |         super(null, min, max); | ||||||
|  |         this.width = max.getX() - min.getX() + 1; | ||||||
|  |         this.length = max.getZ() - min.getZ() + 1; | ||||||
|  |         this.minY = min.getY(); | ||||||
|  |         this.maxY = max.getY(); | ||||||
|  |         this.height = maxY - minY + 1; | ||||||
|  |  | ||||||
|  |         this.scopeMinX = min.getX() & 15; | ||||||
|  |         this.scopeMinZ = min.getZ() & 15; | ||||||
|  |         this.scopeMaxX = scopeMinX + width; | ||||||
|  |         this.scopeMaxZ = scopeMinZ + length; | ||||||
|  |         this.blockStates = new BlockState[height][width][length]; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public BlockState[][][] getBlockStates() { | ||||||
|  |         return blockStates; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setBlock(int x, final int y, int z, final @NonNull BlockState id) { | ||||||
|  |         x += offsetX; | ||||||
|  |         z += offsetZ; | ||||||
|  |         if (x >= scopeMinX && x < scopeMaxX && y >= minY && y <= maxY && z >= scopeMinZ && z < scopeMaxZ) { | ||||||
|  |             blockStates[y - minY][x - scopeMinX][z - scopeMinZ] = id; | ||||||
|  |         } | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setBlock(final int x, final int y, final int z, @NonNull final Pattern pattern) { | ||||||
|  |         int rx = x + offsetX; | ||||||
|  |         int rz = z + offsetZ; | ||||||
|  |         if (rx >= scopeMinX && rx < scopeMaxX && y >= minY && y <= maxY && rz >= scopeMinZ && rz < scopeMaxZ) { | ||||||
|  |             BlockState state = pattern | ||||||
|  |                     .applyBlock(super.getMin().getBlockVector3().add(BlockVector3.at(x, y, z))) | ||||||
|  |                     .toImmutableState(); | ||||||
|  |             blockStates[y - minY][rx - scopeMinX][rz - scopeMinZ] = state; | ||||||
|  |         } | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public @NonNull Location getMin() { | ||||||
|  |         return super.getMin().add(offsetX - scopeMinX, 0, offsetZ - scopeMinZ); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public @NonNull Location getMax() { | ||||||
|  |         return getMin().add(15, 0, 15).withY(maxY); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setBlock(int x, int y, int z, final @NonNull BaseBlock id) { | ||||||
|  |         x += offsetX; | ||||||
|  |         z += offsetZ; | ||||||
|  |         if (x >= scopeMinX && x < scopeMaxX && y >= minY && y <= maxY && z >= scopeMinZ && z < scopeMaxZ) { | ||||||
|  |             blockStates[y - minY][x][z] = id.toImmutableState(); | ||||||
|  |         } | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public @Nullable BlockState getBlock(final int x, final int y, final int z) { | ||||||
|  |         if (x >= 0 && x < width && y >= minY && y <= maxY && z >= 0 && z < length) { | ||||||
|  |             return blockStates[y - minY][x][z]; | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setOffsetX(final int offsetX) { | ||||||
|  |         this.offsetX = offsetX; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public void setOffsetZ(final int offsetZ) { | ||||||
|  |         this.offsetZ = offsetZ; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public int size() { | ||||||
|  |         return height * width * length; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setBiome(final int x, final int z, @NonNull final BiomeType biome) { | ||||||
|  |         //do nothing | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setBiome(final int x, final int y, final int z, @NonNull final BiomeType biome) { | ||||||
|  |         //do nothing | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void fillBiome(final BiomeType biome) { | ||||||
|  |         //do nothing | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public boolean setTile(final int x, final int y, final int z, @NonNull final CompoundTag tag) { | ||||||
|  |         //do nothing | ||||||
|  |         return false; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -36,8 +36,12 @@ import org.checkerframework.checker.nullness.qual.NonNull; | |||||||
| import org.checkerframework.checker.nullness.qual.Nullable; | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Queue that is limited to a single chunk |  * Queue that is limited to a single chunk. It does not allow a delegate queue and should be treated as a cache for changes to | ||||||
|  |  * be set to. Does not support tile entities or entities. | ||||||
|  |  * | ||||||
|  |  * @deprecated This class is poorly designed and will no longer be used in P2 | ||||||
|  */ |  */ | ||||||
|  | @Deprecated(forRemoval = true, since = "6.8.0") | ||||||
| public class ChunkQueueCoordinator extends ScopedQueueCoordinator { | public class ChunkQueueCoordinator extends ScopedQueueCoordinator { | ||||||
|  |  | ||||||
|     public final BiomeType[][][] biomeResult; |     public final BiomeType[][][] biomeResult; | ||||||
| @@ -54,12 +58,12 @@ public class ChunkQueueCoordinator extends ScopedQueueCoordinator { | |||||||
|             @NonNull BlockVector3 top, |             @NonNull BlockVector3 top, | ||||||
|             boolean biomes |             boolean biomes | ||||||
|     ) { |     ) { | ||||||
|         super(null, Location.at("", 0, 0, 0), Location.at("", 15, 255, 15)); |         super(null, Location.at("", 0, weWorld.getMinY(), 0), Location.at("", 15, weWorld.getMaxY(), 15)); | ||||||
|         this.weWorld = weWorld; |         this.weWorld = weWorld; | ||||||
|         this.width = top.getX() - bot.getX() + 1; |         this.width = top.getX() - bot.getX() + 1; | ||||||
|         this.length = top.getZ() - bot.getZ() + 1; |         this.length = top.getZ() - bot.getZ() + 1; | ||||||
|         this.result = new BlockState[256][width][length]; |         this.result = new BlockState[weWorld.getMaxY() - weWorld.getMinY() + 1][width][length]; | ||||||
|         this.biomeResult = biomes ? new BiomeType[256][width][length] : null; |         this.biomeResult = biomes ? new BiomeType[weWorld.getMaxY() - weWorld.getMinY() + 1][width][length] : null; | ||||||
|         this.bot = bot; |         this.bot = bot; | ||||||
|         this.top = top; |         this.top = top; | ||||||
|     } |     } | ||||||
| @@ -71,7 +75,7 @@ public class ChunkQueueCoordinator extends ScopedQueueCoordinator { | |||||||
|     @Override |     @Override | ||||||
|     public boolean setBiome(int x, int z, @NonNull BiomeType biomeType) { |     public boolean setBiome(int x, int z, @NonNull BiomeType biomeType) { | ||||||
|         if (this.biomeResult != null) { |         if (this.biomeResult != null) { | ||||||
|             for (int y = 0; y < 256; y++) { |             for (int y = weWorld.getMinY(); y <= weWorld.getMaxY(); y++) { | ||||||
|                 this.storeCacheBiome(x, y, z, biomeType); |                 this.storeCacheBiome(x, y, z, biomeType); | ||||||
|             } |             } | ||||||
|             return true; |             return true; | ||||||
| @@ -101,9 +105,10 @@ public class ChunkQueueCoordinator extends ScopedQueueCoordinator { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void storeCache(final int x, final int y, final int z, final @NonNull BlockState id) { |     private void storeCache(final int x, final int y, final int z, final @NonNull BlockState id) { | ||||||
|         BlockState[][] resultY = result[y]; |         int yIndex = getYIndex(y); | ||||||
|  |         BlockState[][] resultY = result[yIndex]; | ||||||
|         if (resultY == null) { |         if (resultY == null) { | ||||||
|             result[y] = resultY = new BlockState[length][]; |             result[yIndex] = resultY = new BlockState[length][]; | ||||||
|         } |         } | ||||||
|         BlockState[] resultYZ = resultY[z]; |         BlockState[] resultYZ = resultY[z]; | ||||||
|         if (resultYZ == null) { |         if (resultYZ == null) { | ||||||
| @@ -113,9 +118,10 @@ public class ChunkQueueCoordinator extends ScopedQueueCoordinator { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private void storeCacheBiome(final int x, final int y, final int z, final @NonNull BiomeType id) { |     private void storeCacheBiome(final int x, final int y, final int z, final @NonNull BiomeType id) { | ||||||
|         BiomeType[][] resultY = biomeResult[y]; |         int yIndex = getYIndex(y); | ||||||
|  |         BiomeType[][] resultY = biomeResult[yIndex]; | ||||||
|         if (resultY == null) { |         if (resultY == null) { | ||||||
|             biomeResult[y] = resultY = new BiomeType[length][]; |             biomeResult[yIndex] = resultY = new BiomeType[length][]; | ||||||
|         } |         } | ||||||
|         BiomeType[] resultYZ = resultY[z]; |         BiomeType[] resultYZ = resultY[z]; | ||||||
|         if (resultYZ == null) { |         if (resultYZ == null) { | ||||||
| @@ -132,7 +138,7 @@ public class ChunkQueueCoordinator extends ScopedQueueCoordinator { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public @Nullable BlockState getBlock(int x, int y, int z) { |     public @Nullable BlockState getBlock(int x, int y, int z) { | ||||||
|         BlockState[][] blocksY = result[y]; |         BlockState[][] blocksY = result[getYIndex(y)]; | ||||||
|         if (blocksY != null) { |         if (blocksY != null) { | ||||||
|             BlockState[] blocksYZ = blocksY[z]; |             BlockState[] blocksYZ = blocksY[z]; | ||||||
|             if (blocksYZ != null) { |             if (blocksYZ != null) { | ||||||
| @@ -157,4 +163,8 @@ public class ChunkQueueCoordinator extends ScopedQueueCoordinator { | |||||||
|         return Location.at(getWorld().getName(), bot.getX(), bot.getY(), bot.getZ()); |         return Location.at(getWorld().getName(), bot.getX(), bot.getY(), bot.getZ()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private int getYIndex(int y) { | ||||||
|  |         return y - weWorld.getMinY(); | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -32,6 +32,7 @@ import com.sk89q.worldedit.entity.Entity; | |||||||
| import com.sk89q.worldedit.function.pattern.Pattern; | import com.sk89q.worldedit.function.pattern.Pattern; | ||||||
| import com.sk89q.worldedit.math.BlockVector2; | import com.sk89q.worldedit.math.BlockVector2; | ||||||
| import com.sk89q.worldedit.regions.CuboidRegion; | import com.sk89q.worldedit.regions.CuboidRegion; | ||||||
|  | import com.sk89q.worldedit.util.SideEffectSet; | ||||||
| import com.sk89q.worldedit.world.World; | import com.sk89q.worldedit.world.World; | ||||||
| import com.sk89q.worldedit.world.biome.BiomeType; | import com.sk89q.worldedit.world.biome.BiomeType; | ||||||
| import com.sk89q.worldedit.world.block.BaseBlock; | import com.sk89q.worldedit.world.block.BaseBlock; | ||||||
| @@ -135,6 +136,13 @@ public class DelegateQueueCoordinator extends QueueCoordinator { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void setBiomesEnabled(final boolean enabled) { | ||||||
|  |         if (parent != null) { | ||||||
|  |             parent.setBiomesEnabled(enabled); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean setEntity(@NonNull Entity entity) { |     public boolean setEntity(@NonNull Entity entity) { | ||||||
|         if (parent != null) { |         if (parent != null) { | ||||||
| @@ -248,6 +256,21 @@ public class DelegateQueueCoordinator extends QueueCoordinator { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public SideEffectSet getSideEffectSet() { | ||||||
|  |         if (parent != null) { | ||||||
|  |             return parent.getSideEffectSet(); | ||||||
|  |         } | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void setSideEffectSet(final SideEffectSet sideEffectSet) { | ||||||
|  |         if (parent != null) { | ||||||
|  |             parent.setSideEffectSet(sideEffectSet); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public @NonNull List<BlockVector2> getReadChunks() { |     public @NonNull List<BlockVector2> getReadChunks() { | ||||||
|         if (parent != null) { |         if (parent != null) { | ||||||
|   | |||||||
| @@ -42,6 +42,7 @@ public class LocalChunk { | |||||||
|     private final QueueCoordinator parent; |     private final QueueCoordinator parent; | ||||||
|     private final int x; |     private final int x; | ||||||
|     private final int z; |     private final int z; | ||||||
|  |     private final int minSection; | ||||||
|  |  | ||||||
|     private final BaseBlock[][] baseblocks; |     private final BaseBlock[][] baseblocks; | ||||||
|     private final BiomeType[][] biomes; |     private final BiomeType[][] biomes; | ||||||
| @@ -52,8 +53,10 @@ public class LocalChunk { | |||||||
|         this.parent = parent; |         this.parent = parent; | ||||||
|         this.x = x; |         this.x = x; | ||||||
|         this.z = z; |         this.z = z; | ||||||
|         baseblocks = new BaseBlock[16][]; |         this.minSection = parent.getMinLayer(); | ||||||
|         biomes = new BiomeType[16][]; |         int sections = parent.getMaxLayer() - parent.getMinLayer() + 1; | ||||||
|  |         baseblocks = new BaseBlock[sections][]; | ||||||
|  |         biomes = new BiomeType[sections][]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public @NonNull QueueCoordinator getParent() { |     public @NonNull QueueCoordinator getParent() { | ||||||
| @@ -68,6 +71,15 @@ public class LocalChunk { | |||||||
|         return this.z; |         return this.z; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the minimum layer position stored (usually -4 or 0). | ||||||
|  |      * | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      */ | ||||||
|  |     public int getMinSection() { | ||||||
|  |         return this.minSection; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public @NonNull BaseBlock[][] getBaseblocks() { |     public @NonNull BaseBlock[][] getBaseblocks() { | ||||||
|         return this.baseblocks; |         return this.baseblocks; | ||||||
|     } |     } | ||||||
| @@ -81,7 +93,7 @@ public class LocalChunk { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void setBiome(final int x, final int y, final int z, final @NonNull BiomeType biomeType) { |     public void setBiome(final int x, final int y, final int z, final @NonNull BiomeType biomeType) { | ||||||
|         final int i = y >> 4; |         final int i = getLayerIndex(y); | ||||||
|         final int j = ChunkUtil.getJ(x, y, z); |         final int j = ChunkUtil.getJ(x, y, z); | ||||||
|         BiomeType[] array = this.biomes[i]; |         BiomeType[] array = this.biomes[i]; | ||||||
|         if (array == null) { |         if (array == null) { | ||||||
| @@ -96,7 +108,7 @@ public class LocalChunk { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void setBlock(final int x, final int y, final int z, final @NonNull BaseBlock baseBlock) { |     public void setBlock(final int x, final int y, final int z, final @NonNull BaseBlock baseBlock) { | ||||||
|         final int i = y >> 4; |         final int i = getLayerIndex(y); | ||||||
|         final int j = ChunkUtil.getJ(x, y, z); |         final int j = ChunkUtil.getJ(x, y, z); | ||||||
|         BaseBlock[] array = baseblocks[i]; |         BaseBlock[] array = baseblocks[i]; | ||||||
|         if (array == null) { |         if (array == null) { | ||||||
| @@ -117,4 +129,8 @@ public class LocalChunk { | |||||||
|         return this.entities; |         return this.entities; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private int getLayerIndex(final int y) { | ||||||
|  |         return (y >> 4) - minSection; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -87,11 +87,14 @@ public class LocationOffsetDelegateQueueCoordinator extends DelegateQueueCoordin | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean setBiome(int x, int z, @NonNull BiomeType biome) { |     public boolean setBiome(int x, int z, @NonNull BiomeType biome) { | ||||||
|         boolean result = true; |         try { | ||||||
|         for (int y = 0; y < 256; y++) { |             if (canPlace[x - blockX][z - blockZ]) { | ||||||
|             result &= this.setBiome(x, y, z, biome); |                 return super.setBiome(x, z, biome); | ||||||
|             } |             } | ||||||
|         return result; |         } catch (final Exception e) { | ||||||
|  |             throw e; | ||||||
|  |         } | ||||||
|  |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|   | |||||||
| @@ -35,6 +35,7 @@ import com.sk89q.worldedit.entity.Entity; | |||||||
| import com.sk89q.worldedit.function.pattern.Pattern; | import com.sk89q.worldedit.function.pattern.Pattern; | ||||||
| import com.sk89q.worldedit.math.BlockVector2; | import com.sk89q.worldedit.math.BlockVector2; | ||||||
| import com.sk89q.worldedit.regions.CuboidRegion; | import com.sk89q.worldedit.regions.CuboidRegion; | ||||||
|  | import com.sk89q.worldedit.util.SideEffectSet; | ||||||
| import com.sk89q.worldedit.world.World; | import com.sk89q.worldedit.world.World; | ||||||
| import com.sk89q.worldedit.world.biome.BiomeType; | import com.sk89q.worldedit.world.biome.BiomeType; | ||||||
| import com.sk89q.worldedit.world.block.BaseBlock; | import com.sk89q.worldedit.world.block.BaseBlock; | ||||||
| @@ -75,12 +76,31 @@ public abstract class QueueCoordinator { | |||||||
|      * @param x chunk x coordinate |      * @param x chunk x coordinate | ||||||
|      * @param z chunk z coordinate |      * @param z chunk z coordinate | ||||||
|      * @return a new {@link ScopedQueueCoordinator} |      * @return a new {@link ScopedQueueCoordinator} | ||||||
|  |      * @deprecated Use {@link ScopedQueueCoordinator#getForChunk(int, int, int, int)} | ||||||
|      */ |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "6.6.0") | ||||||
|     public ScopedQueueCoordinator getForChunk(int x, int z) { |     public ScopedQueueCoordinator getForChunk(int x, int z) { | ||||||
|  |         if (getWorld() == null) { | ||||||
|  |             return getForChunk(x, z, PlotSquared.platform().versionMinHeight(), PlotSquared.platform().versionMaxHeight()); | ||||||
|  |         } | ||||||
|  |         return getForChunk(x, z, getWorld().getMinY(), getWorld().getMaxY()); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get a {@link ScopedQueueCoordinator} limited to the chunk at the specific chunk Coordinates | ||||||
|  |      * | ||||||
|  |      * @param x chunk x coordinate | ||||||
|  |      * @param z chunk z coordinate | ||||||
|  |      * @return a new {@link ScopedQueueCoordinator} | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|  |     public ScopedQueueCoordinator getForChunk(int x, int z, int minY, int maxY) { | ||||||
|         int bx = x << 4; |         int bx = x << 4; | ||||||
|         int bz = z << 4; |         int bz = z << 4; | ||||||
|         return new ScopedQueueCoordinator(this, Location.at(getWorld().getName(), bx, 0, bz), |         return new ScopedQueueCoordinator(this, Location.at(getWorld().getName(), bx, minY, bz), | ||||||
|                 Location.at(getWorld().getName(), bx + 15, 255, bz + 255) |                 Location.at(getWorld().getName(), bx + 15, maxY, bz + 15) | ||||||
|         ); |         ); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -126,7 +146,8 @@ public abstract class QueueCoordinator { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Set a chunk object (e.g. the Bukkit Chunk object) to the queue |      * Set a chunk object (e.g. the Bukkit Chunk object) to the queue. This will be used as fallback in case of WNA failure. | ||||||
|  |      * Should ONLY be used in specific cases (i.e. generation, where a chunk is being populated) | ||||||
|      * |      * | ||||||
|      * @param chunkObject chunk object. Usually the implementation-specific chunk (e.g. bukkit Chunk) |      * @param chunkObject chunk object. Usually the implementation-specific chunk (e.g. bukkit Chunk) | ||||||
|      */ |      */ | ||||||
| @@ -230,6 +251,14 @@ public abstract class QueueCoordinator { | |||||||
|      */ |      */ | ||||||
|     public abstract boolean isSettingBiomes(); |     public abstract boolean isSettingBiomes(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * If the queue should accept biome placement | ||||||
|  |      * | ||||||
|  |      * @param enabled If biomes should be enabled | ||||||
|  |      * @since 6.8.0 | ||||||
|  |      */ | ||||||
|  |     public abstract void setBiomesEnabled(boolean enabled); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Add entities to be created |      * Add entities to be created | ||||||
|      * |      * | ||||||
| @@ -395,6 +424,20 @@ public abstract class QueueCoordinator { | |||||||
|      */ |      */ | ||||||
|     public abstract void setLightingMode(@Nullable LightingMode mode); |     public abstract void setLightingMode(@Nullable LightingMode mode); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the overriding {@link SideEffectSet} to be used by the queue if it exists, else null | ||||||
|  |      * | ||||||
|  |      * @return Overriding {@link SideEffectSet} or null | ||||||
|  |      */ | ||||||
|  |     public abstract @Nullable SideEffectSet getSideEffectSet(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Set the overriding {@link SideEffectSet} to be used by the queue. Null to use default side effects. | ||||||
|  |      * | ||||||
|  |      * @param sideEffectSet side effects to override with, or null to use default | ||||||
|  |      */ | ||||||
|  |     public abstract void setSideEffectSet(@Nullable SideEffectSet sideEffectSet); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Fill a cuboid between two positions with a BlockState |      * Fill a cuboid between two positions with a BlockState | ||||||
|      * |      * | ||||||
| @@ -404,7 +447,7 @@ public abstract class QueueCoordinator { | |||||||
|      */ |      */ | ||||||
|     public void setCuboid(@NonNull Location pos1, @NonNull Location pos2, @NonNull BlockState block) { |     public void setCuboid(@NonNull Location pos1, @NonNull Location pos2, @NonNull BlockState block) { | ||||||
|         int yMin = Math.min(pos1.getY(), pos2.getY()); |         int yMin = Math.min(pos1.getY(), pos2.getY()); | ||||||
|         int yMax = Math.min(255, Math.max(pos1.getY(), pos2.getY())); |         int yMax = Math.max(pos1.getY(), pos2.getY()); | ||||||
|         int xMin = Math.min(pos1.getX(), pos2.getX()); |         int xMin = Math.min(pos1.getX(), pos2.getX()); | ||||||
|         int xMax = Math.max(pos1.getX(), pos2.getX()); |         int xMax = Math.max(pos1.getX(), pos2.getX()); | ||||||
|         int zMin = Math.min(pos1.getZ(), pos2.getZ()); |         int zMin = Math.min(pos1.getZ(), pos2.getZ()); | ||||||
| @@ -427,7 +470,7 @@ public abstract class QueueCoordinator { | |||||||
|      */ |      */ | ||||||
|     public void setCuboid(@NonNull Location pos1, @NonNull Location pos2, @NonNull Pattern blocks) { |     public void setCuboid(@NonNull Location pos1, @NonNull Location pos2, @NonNull Pattern blocks) { | ||||||
|         int yMin = Math.min(pos1.getY(), pos2.getY()); |         int yMin = Math.min(pos1.getY(), pos2.getY()); | ||||||
|         int yMax = Math.min(255, Math.max(pos1.getY(), pos2.getY())); |         int yMax = Math.max(pos1.getY(), pos2.getY()); | ||||||
|         int xMin = Math.min(pos1.getX(), pos2.getX()); |         int xMin = Math.min(pos1.getX(), pos2.getX()); | ||||||
|         int xMax = Math.max(pos1.getX(), pos2.getX()); |         int xMax = Math.max(pos1.getX(), pos2.getX()); | ||||||
|         int zMin = Math.min(pos1.getZ(), pos2.getZ()); |         int zMin = Math.min(pos1.getZ(), pos2.getZ()); | ||||||
| @@ -450,7 +493,7 @@ public abstract class QueueCoordinator { | |||||||
|      */ |      */ | ||||||
|     public void setBiomeCuboid(@NonNull Location pos1, @NonNull Location pos2, @NonNull BiomeType biome) { |     public void setBiomeCuboid(@NonNull Location pos1, @NonNull Location pos2, @NonNull BiomeType biome) { | ||||||
|         int yMin = Math.min(pos1.getY(), pos2.getY()); |         int yMin = Math.min(pos1.getY(), pos2.getY()); | ||||||
|         int yMax = Math.min(255, Math.max(pos1.getY(), pos2.getY())); |         int yMax = Math.max(pos1.getY(), pos2.getY()); | ||||||
|         int xMin = Math.min(pos1.getX(), pos2.getX()); |         int xMin = Math.min(pos1.getX(), pos2.getX()); | ||||||
|         int xMax = Math.max(pos1.getX(), pos2.getX()); |         int xMax = Math.max(pos1.getX(), pos2.getX()); | ||||||
|         int zMin = Math.min(pos1.getZ(), pos2.getZ()); |         int zMin = Math.min(pos1.getZ(), pos2.getZ()); | ||||||
| @@ -464,4 +507,32 @@ public abstract class QueueCoordinator { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the min Y limit associated with the queue | ||||||
|  |      */ | ||||||
|  |     protected int getMinY() { | ||||||
|  |         return getWorld() != null ? getWorld().getMinY() : PlotSquared.platform().versionMinHeight(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the max Y limit associated with the queue | ||||||
|  |      */ | ||||||
|  |     protected int getMaxY() { | ||||||
|  |         return getWorld() != null ? getWorld().getMinY() : PlotSquared.platform().versionMaxHeight(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the min chunk layer associated with the queue. Usually 0 or -4; | ||||||
|  |      */ | ||||||
|  |     protected int getMinLayer() { | ||||||
|  |         return (getWorld() != null ? getWorld().getMinY() : PlotSquared.platform().versionMinHeight()) >> 4; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Get the max chunk layer associated with the queue. Usually 15 or 19 | ||||||
|  |      */ | ||||||
|  |     protected int getMaxLayer() { | ||||||
|  |         return (getWorld() != null ? getWorld().getMaxY() : PlotSquared.platform().versionMaxHeight()) >> 4; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -35,34 +35,39 @@ import org.checkerframework.checker.nullness.qual.NonNull; | |||||||
| import org.checkerframework.checker.nullness.qual.Nullable; | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Queue that only sets blocks with a designated area |  * Queue that only sets blocks with a designated X-Z area, will accept any Y values. Requires all blocks be set normalized in | ||||||
|  |  * the x and z directions, i.e. starting from 0,0. An offset of the minimum point of the region will then be applied to x and z. | ||||||
|  |  * | ||||||
|  |  * @deprecated This should be renamed to NormalizedScopedQueueCoordinator or something. | ||||||
|  */ |  */ | ||||||
|  | @Deprecated(forRemoval = true, since = "6.8.0") | ||||||
| public class ScopedQueueCoordinator extends DelegateQueueCoordinator { | public class ScopedQueueCoordinator extends DelegateQueueCoordinator { | ||||||
|  |  | ||||||
|  |     private final Location min; | ||||||
|  |     private final Location max; | ||||||
|     private final int minX; |     private final int minX; | ||||||
|     private final int minY; |  | ||||||
|     private final int minZ; |     private final int minZ; | ||||||
|  |  | ||||||
|     private final int maxX; |     private final int maxX; | ||||||
|     private final int maxY; |  | ||||||
|     private final int maxZ; |     private final int maxZ; | ||||||
|  |  | ||||||
|     private final int dx; |     private final int dx; | ||||||
|     private final int dy; |  | ||||||
|     private final int dz; |     private final int dz; | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Create a new ScopedQueueCoordinator instance that delegates to a given QueueCoordinator. Locations are inclusive. | ||||||
|  |      */ | ||||||
|     public ScopedQueueCoordinator(@Nullable QueueCoordinator parent, @NonNull Location min, @NonNull Location max) { |     public ScopedQueueCoordinator(@Nullable QueueCoordinator parent, @NonNull Location min, @NonNull Location max) { | ||||||
|         super(parent); |         super(parent); | ||||||
|  |         this.min = min; | ||||||
|  |         this.max = max; | ||||||
|         this.minX = min.getX(); |         this.minX = min.getX(); | ||||||
|         this.minY = min.getY(); |  | ||||||
|         this.minZ = min.getZ(); |         this.minZ = min.getZ(); | ||||||
|  |  | ||||||
|         this.maxX = max.getX(); |         this.maxX = max.getX(); | ||||||
|         this.maxY = max.getY(); |  | ||||||
|         this.maxZ = max.getZ(); |         this.maxZ = max.getZ(); | ||||||
|  |  | ||||||
|         this.dx = maxX - minX; |         this.dx = maxX - minX; | ||||||
|         this.dy = maxY - minY; |  | ||||||
|         this.dz = maxZ - minZ; |         this.dz = maxZ - minZ; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -73,11 +78,11 @@ public class ScopedQueueCoordinator extends DelegateQueueCoordinator { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean setBiome(int x, int y, int z, @NonNull BiomeType biome) { |     public boolean setBiome(int x, int y, int z, @NonNull BiomeType biome) { | ||||||
|         return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setBiome(x + minX, y + minY, z + minZ, biome); |         return x >= 0 && x <= dx && z >= 0 && z <= dz && super.setBiome(x + minX, y, z + minZ, biome); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void fillBiome(BiomeType biome) { |     public void fillBiome(BiomeType biome) { | ||||||
|         for (int y = 0; y <= dy; y++) { |         for (int y = min.getY(); y <= max.getY(); y++) { | ||||||
|             for (int x = 0; x <= dx; x++) { |             for (int x = 0; x <= dx; x++) { | ||||||
|                 for (int z = 0; z < dz; z++) { |                 for (int z = 0; z < dz; z++) { | ||||||
|                     setBiome(x, y, z, biome); |                     setBiome(x, y, z, biome); | ||||||
| @@ -88,35 +93,30 @@ public class ScopedQueueCoordinator extends DelegateQueueCoordinator { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean setBlock(int x, int y, int z, @NonNull BaseBlock id) { |     public boolean setBlock(int x, int y, int z, @NonNull BaseBlock id) { | ||||||
|         return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setBlock(x + minX, y + minY, z + minZ, id); |         return x >= 0 && x <= dx && z >= 0 && z <= dz && super.setBlock(x + minX, y, z + minZ, id); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean setBlock(int x, int y, int z, @NonNull BlockState id) { |     public boolean setBlock(int x, int y, int z, @NonNull BlockState id) { | ||||||
|         return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setBlock(x + minX, y + minY, z + minZ, id); |         return x >= 0 && x <= dx && z >= 0 && z <= dz && super.setBlock(x + minX, y, z + minZ, id); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean setBlock(int x, int y, int z, @NonNull Pattern pattern) { |     public boolean setBlock(int x, int y, int z, @NonNull Pattern pattern) { | ||||||
|         return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setBlock( |         return x >= 0 && x <= dx && z >= 0 && z <= dz && super.setBlock(x + minX, y, z + minZ, pattern); | ||||||
|                 x + minX, |  | ||||||
|                 y + minY, |  | ||||||
|                 z + minZ, |  | ||||||
|                 pattern |  | ||||||
|         ); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public boolean setTile(int x, int y, int z, @NonNull CompoundTag tag) { |     public boolean setTile(int x, int y, int z, @NonNull CompoundTag tag) { | ||||||
|         return x >= 0 && x <= dx && y >= 0 && y <= dy && z >= 0 && z <= dz && super.setTile(x + minX, y + minY, z + minZ, tag); |         return x >= 0 && x <= dx && z >= 0 && z <= dz && super.setTile(x + minX, y, z + minZ, tag); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public @NonNull Location getMin() { |     public @NonNull Location getMin() { | ||||||
|         return Location.at(this.getWorld().getName(), this.minX, this.minY, this.minZ); |         return min; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public @NonNull Location getMax() { |     public @NonNull Location getMax() { | ||||||
|         return Location.at(this.getWorld().getName(), this.maxX, this.maxY, this.maxZ); |         return max; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -31,6 +31,7 @@ import com.plotsquared.core.queue.QueueCoordinator; | |||||||
| import com.plotsquared.core.queue.ScopedQueueCoordinator; | import com.plotsquared.core.queue.ScopedQueueCoordinator; | ||||||
| import com.plotsquared.core.util.task.RunnableVal; | import com.plotsquared.core.util.task.RunnableVal; | ||||||
| import com.sk89q.worldedit.math.BlockVector2; | import com.sk89q.worldedit.math.BlockVector2; | ||||||
|  | import com.sk89q.worldedit.world.World; | ||||||
|  |  | ||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.concurrent.CompletableFuture; | import java.util.concurrent.CompletableFuture; | ||||||
| @@ -41,24 +42,26 @@ public abstract class ChunkManager { | |||||||
|     private static final Map<BlockVector2, RunnableVal<ScopedQueueCoordinator>> forceChunks = new ConcurrentHashMap<>(); |     private static final Map<BlockVector2, RunnableVal<ScopedQueueCoordinator>> forceChunks = new ConcurrentHashMap<>(); | ||||||
|     private static final Map<BlockVector2, RunnableVal<ScopedQueueCoordinator>> addChunks = new ConcurrentHashMap<>(); |     private static final Map<BlockVector2, RunnableVal<ScopedQueueCoordinator>> addChunks = new ConcurrentHashMap<>(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public static void setChunkInPlotArea( |     public static void setChunkInPlotArea( | ||||||
|             RunnableVal<ScopedQueueCoordinator> force, |             RunnableVal<ScopedQueueCoordinator> force, | ||||||
|             RunnableVal<ScopedQueueCoordinator> add, |             RunnableVal<ScopedQueueCoordinator> add, | ||||||
|             String world, |             String world, | ||||||
|             BlockVector2 loc |             BlockVector2 loc | ||||||
|     ) { |     ) { | ||||||
|         QueueCoordinator queue = PlotSquared.platform().globalBlockQueue().getNewQueue(PlotSquared |         World weWorld = PlotSquared.platform().worldUtil().getWeWorld(world); | ||||||
|                 .platform() |         QueueCoordinator queue = PlotSquared.platform().globalBlockQueue().getNewQueue(weWorld); | ||||||
|                 .worldUtil() |  | ||||||
|                 .getWeWorld(world)); |  | ||||||
|         if (PlotSquared.get().getPlotAreaManager().isAugmented(world) && PlotSquared.get().isNonStandardGeneration(world, loc)) { |         if (PlotSquared.get().getPlotAreaManager().isAugmented(world) && PlotSquared.get().isNonStandardGeneration(world, loc)) { | ||||||
|             int blockX = loc.getX() << 4; |             int blockX = loc.getX() << 4; | ||||||
|             int blockZ = loc.getZ() << 4; |             int blockZ = loc.getZ() << 4; | ||||||
|             ScopedQueueCoordinator scoped = |             ScopedQueueCoordinator scoped = | ||||||
|                     new ScopedQueueCoordinator( |                     new ScopedQueueCoordinator( | ||||||
|                             queue, |                             queue, | ||||||
|                             Location.at(world, blockX, 0, blockZ), |                             Location.at(world, blockX, weWorld.getMinY(), blockZ), | ||||||
|                             Location.at(world, blockX + 15, 255, blockZ + 15) |                             Location.at(world, blockX + 15, weWorld.getMaxY(), blockZ + 15) | ||||||
|                     ); |                     ); | ||||||
|             if (force != null) { |             if (force != null) { | ||||||
|                 force.run(scoped); |                 force.run(scoped); | ||||||
| @@ -80,6 +83,10 @@ public abstract class ChunkManager { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public static boolean preProcessChunk(BlockVector2 loc, ScopedQueueCoordinator queue) { |     public static boolean preProcessChunk(BlockVector2 loc, ScopedQueueCoordinator queue) { | ||||||
|         final RunnableVal<ScopedQueueCoordinator> forceChunk = forceChunks.get(loc); |         final RunnableVal<ScopedQueueCoordinator> forceChunk = forceChunks.get(loc); | ||||||
|         if (forceChunk != null) { |         if (forceChunk != null) { | ||||||
| @@ -90,6 +97,10 @@ public abstract class ChunkManager { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @deprecated {@link ScopedQueueCoordinator} will be renamed in v7. | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "TODO") | ||||||
|     public static boolean postProcessChunk(BlockVector2 loc, ScopedQueueCoordinator queue) { |     public static boolean postProcessChunk(BlockVector2 loc, ScopedQueueCoordinator queue) { | ||||||
|         final RunnableVal<ScopedQueueCoordinator> addChunk = forceChunks.get(loc); |         final RunnableVal<ScopedQueueCoordinator> addChunk = forceChunks.get(loc); | ||||||
|         if (addChunk != null) { |         if (addChunk != null) { | ||||||
|   | |||||||
| @@ -39,30 +39,27 @@ public class ChunkUtil { | |||||||
|      * - Used for efficient world generation<br> |      * - Used for efficient world generation<br> | ||||||
|      */ |      */ | ||||||
|     private static final short[] x_loc; |     private static final short[] x_loc; | ||||||
|     private static final short[][] y_loc; |     private static final short[] y_loc; | ||||||
|     private static final short[] z_loc; |     private static final short[] z_loc; | ||||||
|     private static final short[][][] CACHE_J; |     private static final short[][][] CACHE_J; | ||||||
|  |  | ||||||
|     static { |     static { | ||||||
|         x_loc = new short[4096]; |         x_loc = new short[4096]; | ||||||
|         y_loc = new short[16][4096]; |         y_loc = new short[4096]; | ||||||
|         z_loc = new short[4096]; |         z_loc = new short[4096]; | ||||||
|         for (int i = 0; i < 16; i++) { |  | ||||||
|             int i4 = i << 4; |  | ||||||
|         for (int j = 0; j < 4096; j++) { |         for (int j = 0; j < 4096; j++) { | ||||||
|                 int y = i4 + (j >> 8); |             int y = j >> 8; | ||||||
|             int a = j - ((y & 0xF) << 8); |             int a = j - ((y & 0xF) << 8); | ||||||
|             int z1 = a >> 4; |             int z1 = a >> 4; | ||||||
|             int x1 = a - (z1 << 4); |             int x1 = a - (z1 << 4); | ||||||
|             x_loc[j] = (short) x1; |             x_loc[j] = (short) x1; | ||||||
|                 y_loc[i][j] = (short) y; |             y_loc[j] = (short) y; | ||||||
|             z_loc[j] = (short) z1; |             z_loc[j] = (short) z1; | ||||||
|         } |         } | ||||||
|         } |         CACHE_J = new short[16][16][16]; | ||||||
|         CACHE_J = new short[256][16][16]; |  | ||||||
|         for (int x = 0; x < 16; x++) { |         for (int x = 0; x < 16; x++) { | ||||||
|             for (int z = 0; z < 16; z++) { |             for (int z = 0; z < 16; z++) { | ||||||
|                 for (int y = 0; y < 256; y++) { |                 for (int y = 0; y < 16; y++) { | ||||||
|                     short j = (short) ((y & 0xF) << 8 | z << 4 | x); |                     short j = (short) ((y & 0xF) << 8 | z << 4 | x); | ||||||
|                     CACHE_J[y][x][z] = j; |                     CACHE_J[y][x][z] = j; | ||||||
|                 } |                 } | ||||||
| @@ -83,7 +80,7 @@ public class ChunkUtil { | |||||||
|      * @return J value for xyz position in Array[4096]. |      * @return J value for xyz position in Array[4096]. | ||||||
|      */ |      */ | ||||||
|     public static int getJ(int x, int y, int z) { |     public static int getJ(int x, int y, int z) { | ||||||
|         return CACHE_J[y][x][z]; |         return CACHE_J[y & 15][x & 15][z & 15]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
| @@ -97,14 +94,14 @@ public class ChunkUtil { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Gets the y coordinate for specific I and J values for a Chunk 16x16x16x16 layerxyz Array[16][4096]. |      * Gets the y coordinate for specific I and J values for a Chunk Nx16x16x16 layerxyz Array[N][4096]. | ||||||
|      * |      * | ||||||
|      * @param i Relative layer of the position in the layerxyz Array[16][4096]. |      * @param i Relative layer of the position in the layerxyz Array[16][4096]. May be negative. | ||||||
|      * @param j Position in the xyz Array[4096]. |      * @param j Position in the xyz Array[4096]. | ||||||
|      * @return x coordinate within the chunk |      * @return x coordinate within the chunk | ||||||
|      */ |      */ | ||||||
|     public static int getY(int i, int j) { |     public static int getY(int i, int j) { | ||||||
|         return y_loc[i][j]; |         return (i << 4) + y_loc[j]; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -37,15 +37,21 @@ public class MainUtil { | |||||||
|      * Cache of mapping x,y,z coordinates to the chunk array<br> |      * Cache of mapping x,y,z coordinates to the chunk array<br> | ||||||
|      * - Used for efficient world generation<br> |      * - Used for efficient world generation<br> | ||||||
|      */ |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "6.0.0") | ||||||
|     public static short[][] x_loc; |     public static short[][] x_loc; | ||||||
|  |     @Deprecated(forRemoval = true, since = "6.0.0") | ||||||
|     public static short[][] y_loc; |     public static short[][] y_loc; | ||||||
|  |     @Deprecated(forRemoval = true, since = "6.0.0") | ||||||
|     public static short[][] z_loc; |     public static short[][] z_loc; | ||||||
|  |     @Deprecated(forRemoval = true, since = "6.0.0") | ||||||
|     public static short[][][] CACHE_I = null; |     public static short[][][] CACHE_I = null; | ||||||
|  |     @Deprecated(forRemoval = true, since = "6.0.0") | ||||||
|     public static short[][][] CACHE_J = null; |     public static short[][][] CACHE_J = null; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * This cache is used for world generation and just saves a bit of calculation time when checking if something is in the plot area. |      * This cache is used for world generation and just saves a bit of calculation time when checking if something is in the plot area. | ||||||
|      */ |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "6.0.0") | ||||||
|     public static void initCache() { |     public static void initCache() { | ||||||
|         if (x_loc == null) { |         if (x_loc == null) { | ||||||
|             x_loc = new short[16][4096]; |             x_loc = new short[16][4096]; | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ import java.util.HashMap; | |||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.regex.Pattern; | import java.util.regex.Pattern; | ||||||
|  |  | ||||||
|  | @Deprecated(since = "6.6.2", forRemoval = true) | ||||||
| public class RegExUtil { | public class RegExUtil { | ||||||
|  |  | ||||||
|     public static Map<String, Pattern> compiledPatterns; |     public static Map<String, Pattern> compiledPatterns; | ||||||
|   | |||||||
| @@ -279,7 +279,10 @@ public abstract class RegionManager { | |||||||
|         fromQueue1.addReadChunks(new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()).getChunks()); |         fromQueue1.addReadChunks(new CuboidRegion(pos1.getBlockVector3(), pos2.getBlockVector3()).getChunks()); | ||||||
|         fromQueue2.addReadChunks(new CuboidRegion( |         fromQueue2.addReadChunks(new CuboidRegion( | ||||||
|                 swapPos.getBlockVector3(), |                 swapPos.getBlockVector3(), | ||||||
|                 BlockVector3.at(swapPos.getX() + pos2.getX() - pos1.getX(), 0, swapPos.getZ() + pos2.getZ() - pos1.getZ()) |                 BlockVector3.at(swapPos.getX() + pos2.getX() - pos1.getX(), | ||||||
|  |                         pos1.getY(), | ||||||
|  |                         swapPos.getZ() + pos2.getZ() - pos1.getZ() | ||||||
|  |                 ) | ||||||
|         ).getChunks()); |         ).getChunks()); | ||||||
|         QueueCoordinator toQueue1 = blockQueue.getNewQueue(world1); |         QueueCoordinator toQueue1 = blockQueue.getNewQueue(world1); | ||||||
|         QueueCoordinator toQueue2 = blockQueue.getNewQueue(world2); |         QueueCoordinator toQueue2 = blockQueue.getNewQueue(world2); | ||||||
| @@ -352,7 +355,7 @@ public abstract class RegionManager { | |||||||
|             int bz = Math.max(pos1.getZ(), cbz) & 15; |             int bz = Math.max(pos1.getZ(), cbz) & 15; | ||||||
|             int tx = Math.min(pos2.getX(), cbx + 15) & 15; |             int tx = Math.min(pos2.getX(), cbx + 15) & 15; | ||||||
|             int tz = Math.min(pos2.getZ(), cbz + 15) & 15; |             int tz = Math.min(pos2.getZ(), cbz + 15) & 15; | ||||||
|             for (int y = 0; y < 256; y++) { |             for (int y = world1.getMinY(); y <= world1.getMaxY(); y++) { | ||||||
|                 for (int x = bx; x <= tx; x++) { |                 for (int x = bx; x <= tx; x++) { | ||||||
|                     for (int z = bz; z <= tz; z++) { |                     for (int z = bz; z <= tz; z++) { | ||||||
|                         int rx = cbx + x; |                         int rx = cbx + x; | ||||||
| @@ -363,7 +366,10 @@ public abstract class RegionManager { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             Region region = new CuboidRegion(BlockVector3.at(cbx + bx, 0, cbz + bz), BlockVector3.at(cbx + tx, 255, cbz + tz)); |             Region region = new CuboidRegion( | ||||||
|  |                     BlockVector3.at(cbx + bx, world1.getMinY(), cbz + bz), | ||||||
|  |                     BlockVector3.at(cbx + tx, world1.getMaxY(), cbz + tz) | ||||||
|  |             ); | ||||||
|             toQueue.addEntities(world1.getEntities(region)); |             toQueue.addEntities(world1.getEntities(region)); | ||||||
|             if (removeEntities) { |             if (removeEntities) { | ||||||
|                 for (Entity entity : world1.getEntities(region)) { |                 for (Entity entity : world1.getEntities(region)) { | ||||||
| @@ -373,6 +379,7 @@ public abstract class RegionManager { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Deprecated(forRemoval = true, since = "6.6.0") | ||||||
|     public void setBiome( |     public void setBiome( | ||||||
|             final CuboidRegion region, |             final CuboidRegion region, | ||||||
|             final int extendBiome, |             final int extendBiome, | ||||||
| @@ -380,39 +387,48 @@ public abstract class RegionManager { | |||||||
|             final String world, |             final String world, | ||||||
|             final Runnable whenDone |             final Runnable whenDone | ||||||
|     ) { |     ) { | ||||||
|         Location pos1 = Location |         setBiome(region, extendBiome, biome, PlotSquared.get().getPlotAreaManager().getPlotAreas(world, region)[0], whenDone); | ||||||
|                 .at( |     } | ||||||
|                         world, |  | ||||||
|                         region.getMinimumPoint().getX() - extendBiome, |  | ||||||
|                         region.getMinimumPoint().getY(), |  | ||||||
|                         region.getMinimumPoint().getZ() - extendBiome |  | ||||||
|                 ); |  | ||||||
|         Location pos2 = Location |  | ||||||
|                 .at( |  | ||||||
|                         world, |  | ||||||
|                         region.getMaximumPoint().getX() + extendBiome, |  | ||||||
|                         region.getMaximumPoint().getY(), |  | ||||||
|                         region.getMaximumPoint().getZ() + extendBiome |  | ||||||
|                 ); |  | ||||||
|         final QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(world)); |  | ||||||
|  |  | ||||||
|         final int minX = pos1.getX(); |     /** | ||||||
|         final int minZ = pos1.getZ(); |      * Set a region to a biome type. | ||||||
|         final int maxX = pos2.getX(); |      * | ||||||
|         final int maxZ = pos2.getZ(); |      * @param region      region to set | ||||||
|  |      * @param extendBiome how far outside the region to extent setting the biome too account for 3D biomes being 4x4 | ||||||
|  |      * @param biome       biome to set | ||||||
|  |      * @param area        {@link PlotArea} in which the biome is being set | ||||||
|  |      * @param whenDone    task to run when complete | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      */ | ||||||
|  |     public void setBiome( | ||||||
|  |             final CuboidRegion region, | ||||||
|  |             final int extendBiome, | ||||||
|  |             final BiomeType biome, | ||||||
|  |             final PlotArea area, | ||||||
|  |             final Runnable whenDone | ||||||
|  |     ) { | ||||||
|  |         final QueueCoordinator queue = blockQueue.getNewQueue(worldUtil.getWeWorld(area.getWorldName())); | ||||||
|         queue.addReadChunks(region.getChunks()); |         queue.addReadChunks(region.getChunks()); | ||||||
|         queue.setChunkConsumer(blockVector2 -> { |         final BlockVector3 regionMin = region.getMinimumPoint(); | ||||||
|             final int cx = blockVector2.getX() << 4; |         final BlockVector3 regionMax = region.getMaximumPoint(); | ||||||
|             final int cz = blockVector2.getZ() << 4; |         queue.setChunkConsumer(chunkPos -> { | ||||||
|  |             BlockVector3 chunkMin = BlockVector3.at( | ||||||
|  |                     Math.max(chunkPos.getX() << 4, regionMin.getBlockX()), | ||||||
|  |                     regionMin.getBlockY(), | ||||||
|  |                     Math.max(chunkPos.getZ() << 4, regionMin.getBlockZ()) | ||||||
|  |             ); | ||||||
|  |             BlockVector3 chunkMax = BlockVector3.at( | ||||||
|  |                     Math.min((chunkPos.getX() << 4) + 15, regionMax.getBlockX()), | ||||||
|  |                     regionMax.getBlockY(), | ||||||
|  |                     Math.min((chunkPos.getZ() << 4) + 15, regionMax.getBlockZ()) | ||||||
|  |             ); | ||||||
|  |             CuboidRegion chunkRegion = new CuboidRegion(region.getWorld(), chunkMin, chunkMax); | ||||||
|             WorldUtil.setBiome( |             WorldUtil.setBiome( | ||||||
|                     world, |                     area.getWorldName(), | ||||||
|                     Math.max(minX, cx), |                     chunkRegion, | ||||||
|                     Math.max(minZ, cz), |  | ||||||
|                     Math.min(maxX, cx + 15), |  | ||||||
|                     Math.min(maxZ, cz + 15), |  | ||||||
|                     biome |                     biome | ||||||
|             ); |             ); | ||||||
|             worldUtil.refreshChunk(blockVector2.getBlockX(), blockVector2.getBlockZ(), world); |             worldUtil.refreshChunk(chunkPos.getBlockX(), chunkPos.getBlockZ(), area.getWorldName()); | ||||||
|         }); |         }); | ||||||
|         queue.setCompleteTask(whenDone); |         queue.setCompleteTask(whenDone); | ||||||
|         queue.enqueue(); |         queue.enqueue(); | ||||||
|   | |||||||
| @@ -76,8 +76,9 @@ public class RegionUtil { | |||||||
|         return new CuboidRegion(min, max); |         return new CuboidRegion(min, max); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Deprecated(forRemoval = true, since = "6.6.0") | ||||||
|     public static CuboidRegion createRegion(int pos1x, int pos2x, int pos1z, int pos2z) { |     public static CuboidRegion createRegion(int pos1x, int pos2x, int pos1z, int pos2z) { | ||||||
|         return createRegion(pos1x, pos2x, 0, Plot.MAX_HEIGHT - 1, pos1z, pos2z); |         return createRegion(pos1x, pos2x, 0, 255, pos1z, pos2z); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public static CuboidRegion createRegion( |     public static CuboidRegion createRegion( | ||||||
|   | |||||||
| @@ -305,12 +305,13 @@ public abstract class SchematicHandler { | |||||||
|             final int WIDTH = dimension.getX(); |             final int WIDTH = dimension.getX(); | ||||||
|             final int LENGTH = dimension.getZ(); |             final int LENGTH = dimension.getZ(); | ||||||
|             final int HEIGHT = dimension.getY(); |             final int HEIGHT = dimension.getY(); | ||||||
|  |             final int worldHeight = plot.getArea().getMaxGenHeight() - plot.getArea().getMinGenHeight() + 1; | ||||||
|             // Validate dimensions |             // Validate dimensions | ||||||
|             CuboidRegion region = plot.getLargestRegion(); |             CuboidRegion region = plot.getLargestRegion(); | ||||||
|             boolean sizeMismatch = |             boolean sizeMismatch = | ||||||
|                     ((region.getMaximumPoint().getX() - region.getMinimumPoint().getX() + xOffset + 1) < WIDTH) || ( |                     ((region.getMaximumPoint().getX() - region.getMinimumPoint().getX() + xOffset + 1) < WIDTH) || ( | ||||||
|                             (region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ() + zOffset + 1) < LENGTH) || (HEIGHT |                             (region.getMaximumPoint().getZ() - region.getMinimumPoint().getZ() + zOffset + 1) < LENGTH) || (HEIGHT | ||||||
|                             > 256); |                             > worldHeight); | ||||||
|             if (!Settings.Schematics.PASTE_MISMATCHES && sizeMismatch) { |             if (!Settings.Schematics.PASTE_MISMATCHES && sizeMismatch) { | ||||||
|                 actor.sendMessage(TranslatableCaption.of("schematics.schematic_size_mismatch")); |                 actor.sendMessage(TranslatableCaption.of("schematics.schematic_size_mismatch")); | ||||||
|                 TaskManager.runTask(whenDone); |                 TaskManager.runTask(whenDone); | ||||||
| @@ -321,14 +322,14 @@ public abstract class SchematicHandler { | |||||||
|             // Calculate the optimal height to paste the schematic at |             // Calculate the optimal height to paste the schematic at | ||||||
|             final int y_offset_actual; |             final int y_offset_actual; | ||||||
|             if (autoHeight) { |             if (autoHeight) { | ||||||
|                 if (HEIGHT >= 256) { |                 if (HEIGHT >= worldHeight) { | ||||||
|                     y_offset_actual = yOffset; |                     y_offset_actual = yOffset; | ||||||
|                 } else { |                 } else { | ||||||
|                     PlotArea pw = plot.getArea(); |                     PlotArea pw = plot.getArea(); | ||||||
|                     if (pw instanceof ClassicPlotWorld) { |                     if (pw instanceof ClassicPlotWorld) { | ||||||
|                         y_offset_actual = yOffset + pw.getMinBuildHeight() + ((ClassicPlotWorld) pw).PLOT_HEIGHT; |                         y_offset_actual = yOffset + pw.getMinBuildHeight() + ((ClassicPlotWorld) pw).PLOT_HEIGHT; | ||||||
|                     } else { |                     } else { | ||||||
|                         y_offset_actual = yOffset + 1 + this.worldUtil |                         y_offset_actual = yOffset + pw.getMinBuildHeight() + this.worldUtil | ||||||
|                                 .getHighestBlockSynchronous(plot.getWorldName(), region.getMinimumPoint().getX() + 1, |                                 .getHighestBlockSynchronous(plot.getWorldName(), region.getMinimumPoint().getX() + 1, | ||||||
|                                         region.getMinimumPoint().getZ() + 1 |                                         region.getMinimumPoint().getZ() + 1 | ||||||
|                                 ); |                                 ); | ||||||
| @@ -360,9 +361,9 @@ public abstract class SchematicHandler { | |||||||
|             // Paste schematic here |             // Paste schematic here | ||||||
|             final QueueCoordinator queue = plot.getArea().getQueue(); |             final QueueCoordinator queue = plot.getArea().getQueue(); | ||||||
|  |  | ||||||
|             for (int ry = 0; ry < Math.min(256, HEIGHT); ry++) { |             for (int ry = 0; ry < Math.min(worldHeight, HEIGHT); ry++) { | ||||||
|                 int yy = y_offset_actual + ry; |                 int yy = y_offset_actual + ry; | ||||||
|                 if (yy > 255 || yy < 0) { |                 if (yy > plot.getArea().getMaxGenHeight() || yy < plot.getArea().getMinGenHeight()) { | ||||||
|                     continue; |                     continue; | ||||||
|                 } |                 } | ||||||
|                 for (int rz = 0; rz < blockArrayClipboard.getDimensions().getZ(); rz++) { |                 for (int rz = 0; rz < blockArrayClipboard.getDimensions().getZ(); rz++) { | ||||||
| @@ -379,18 +380,18 @@ public abstract class SchematicHandler { | |||||||
|                         BlockVector3 loc = BlockVector3.at(rx, ry, rz); |                         BlockVector3 loc = BlockVector3.at(rx, ry, rz); | ||||||
|                         BaseBlock id = blockArrayClipboard.getFullBlock(loc); |                         BaseBlock id = blockArrayClipboard.getFullBlock(loc); | ||||||
|                         queue.setBlock(xx, yy, zz, id); |                         queue.setBlock(xx, yy, zz, id); | ||||||
|                         if (ry == 0) { |  | ||||||
|                         BiomeType biome = blockArrayClipboard.getBiome(loc); |                         BiomeType biome = blockArrayClipboard.getBiome(loc); | ||||||
|                         queue.setBiome(xx, yy, zz, biome); |                         queue.setBiome(xx, yy, zz, biome); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             } |  | ||||||
|             if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) { |             if (actor != null && Settings.QUEUE.NOTIFY_PROGRESS) { | ||||||
|                 queue.addProgressSubscriber(subscriberFactory.createWithActor(actor)); |                 queue.addProgressSubscriber(subscriberFactory.createWithActor(actor)); | ||||||
|             } |             } | ||||||
|  |             if (whenDone != null) { | ||||||
|                 whenDone.value = true; |                 whenDone.value = true; | ||||||
|                 queue.setCompleteTask(whenDone); |                 queue.setCompleteTask(whenDone); | ||||||
|  |             } | ||||||
|             queue.enqueue(); |             queue.enqueue(); | ||||||
|         } catch (Exception e) { |         } catch (Exception e) { | ||||||
|             e.printStackTrace(); |             e.printStackTrace(); | ||||||
|   | |||||||
| @@ -34,6 +34,7 @@ import java.util.HashMap; | |||||||
| public abstract class SetupUtils { | public abstract class SetupUtils { | ||||||
|  |  | ||||||
|     public static HashMap<String, GeneratorWrapper<?>> generators = new HashMap<>(); |     public static HashMap<String, GeneratorWrapper<?>> generators = new HashMap<>(); | ||||||
|  |     protected boolean loaded = false; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * @since 6.1.0 |      * @since 6.1.0 | ||||||
|   | |||||||
| @@ -44,27 +44,27 @@ public final class TimeUtil { | |||||||
|         StringBuilder toReturn = new StringBuilder(); |         StringBuilder toReturn = new StringBuilder(); | ||||||
|         if (time >= 33868800) { |         if (time >= 33868800) { | ||||||
|             int years = (int) (time / 33868800); |             int years = (int) (time / 33868800); | ||||||
|             time -= years * 33868800; |             time -= years * 33868800L; | ||||||
|             toReturn.append(years).append("y "); |             toReturn.append(years).append("y "); | ||||||
|         } |         } | ||||||
|         if (time >= 604800) { |         if (time >= 604800) { | ||||||
|             int weeks = (int) (time / 604800); |             int weeks = (int) (time / 604800); | ||||||
|             time -= weeks * 604800; |             time -= weeks * 604800L; | ||||||
|             toReturn.append(weeks).append("w "); |             toReturn.append(weeks).append("w "); | ||||||
|         } |         } | ||||||
|         if (time >= 86400) { |         if (time >= 86400) { | ||||||
|             int days = (int) (time / 86400); |             int days = (int) (time / 86400); | ||||||
|             time -= days * 86400; |             time -= days * 86400L; | ||||||
|             toReturn.append(days).append("d "); |             toReturn.append(days).append("d "); | ||||||
|         } |         } | ||||||
|         if (time >= 3600) { |         if (time >= 3600) { | ||||||
|             int hours = (int) (time / 3600); |             int hours = (int) (time / 3600); | ||||||
|             time -= hours * 3600; |             time -= hours * 3600L; | ||||||
|             toReturn.append(hours).append("h "); |             toReturn.append(hours).append("h "); | ||||||
|         } |         } | ||||||
|         if (time >= 60) { |         if (time >= 60) { | ||||||
|             int minutes = (int) (time / 60); |             int minutes = (int) (time / 60); | ||||||
|             time -= minutes * 60; |             time -= minutes * 60L; | ||||||
|             toReturn.append(minutes).append("m "); |             toReturn.append(minutes).append("m "); | ||||||
|         } |         } | ||||||
|         if (toReturn.length() == 0 || time > 0) { |         if (toReturn.length() == 0 || time > 0) { | ||||||
|   | |||||||
| @@ -44,6 +44,9 @@ import java.util.UUID; | |||||||
|  |  | ||||||
| public class WEManager { | public class WEManager { | ||||||
|  |  | ||||||
|  |     private static final BlockVector3 MIN = BlockVector3.at(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); | ||||||
|  |     private static final BlockVector3 MAX = BlockVector3.at(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); | ||||||
|  |  | ||||||
|     public static boolean maskContains(Set<CuboidRegion> mask, int x, int y, int z) { |     public static boolean maskContains(Set<CuboidRegion> mask, int x, int y, int z) { | ||||||
|         for (CuboidRegion region : mask) { |         for (CuboidRegion region : mask) { | ||||||
|             if (RegionUtil.contains(region, x, y, z)) { |             if (RegionUtil.contains(region, x, y, z)) { | ||||||
| @@ -91,10 +94,7 @@ public class WEManager { | |||||||
|         Location location = player.getLocation(); |         Location location = player.getLocation(); | ||||||
|         String world = location.getWorldName(); |         String world = location.getWorldName(); | ||||||
|         if (!PlotSquared.get().getPlotAreaManager().hasPlotArea(world)) { |         if (!PlotSquared.get().getPlotAreaManager().hasPlotArea(world)) { | ||||||
|             regions.add(RegionUtil |             regions.add(new CuboidRegion(MIN, MAX)); | ||||||
|                     .createRegion(Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE, |  | ||||||
|                             Integer.MAX_VALUE |  | ||||||
|                     )); |  | ||||||
|             return regions; |             return regions; | ||||||
|         } |         } | ||||||
|         PlotArea area = player.getApplicablePlotArea(); |         PlotArea area = player.getApplicablePlotArea(); | ||||||
|   | |||||||
| @@ -39,6 +39,7 @@ import com.sk89q.jnbt.Tag; | |||||||
| import com.sk89q.worldedit.math.BlockVector2; | import com.sk89q.worldedit.math.BlockVector2; | ||||||
| import com.sk89q.worldedit.math.BlockVector3; | import com.sk89q.worldedit.math.BlockVector3; | ||||||
| import com.sk89q.worldedit.regions.CuboidRegion; | import com.sk89q.worldedit.regions.CuboidRegion; | ||||||
|  | import com.sk89q.worldedit.world.World; | ||||||
| import com.sk89q.worldedit.world.biome.BiomeType; | import com.sk89q.worldedit.world.biome.BiomeType; | ||||||
| import com.sk89q.worldedit.world.block.BlockState; | import com.sk89q.worldedit.world.block.BlockState; | ||||||
| import com.sk89q.worldedit.world.block.BlockType; | import com.sk89q.worldedit.world.block.BlockType; | ||||||
| @@ -78,14 +79,29 @@ public abstract class WorldUtil { | |||||||
|      * @param p2x   Max X |      * @param p2x   Max X | ||||||
|      * @param p2z   Max Z |      * @param p2z   Max Z | ||||||
|      * @param biome Biome |      * @param biome Biome | ||||||
|  |      * @deprecated use {@link WorldUtil#setBiome(String, CuboidRegion, BiomeType)} | ||||||
|      */ |      */ | ||||||
|  |     @Deprecated(forRemoval = true) | ||||||
|     public static void setBiome(String world, int p1x, int p1z, int p2x, int p2z, BiomeType biome) { |     public static void setBiome(String world, int p1x, int p1z, int p2x, int p2z, BiomeType biome) { | ||||||
|         BlockVector3 pos1 = BlockVector2.at(p1x, p1z).toBlockVector3(); |         World weWorld = PlotSquared.platform().worldUtil().getWeWorld(world); | ||||||
|         BlockVector3 pos2 = BlockVector2.at(p2x, p2z).toBlockVector3(Plot.MAX_HEIGHT - 1); |         BlockVector3 pos1 = BlockVector2.at(p1x, p1z).toBlockVector3(weWorld.getMinY()); | ||||||
|  |         BlockVector3 pos2 = BlockVector2.at(p2x, p2z).toBlockVector3(weWorld.getMaxY()); | ||||||
|         CuboidRegion region = new CuboidRegion(pos1, pos2); |         CuboidRegion region = new CuboidRegion(pos1, pos2); | ||||||
|         PlotSquared.platform().worldUtil().setBiomes(world, region, biome); |         PlotSquared.platform().worldUtil().setBiomes(world, region, biome); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Set the biome in a region | ||||||
|  |      * | ||||||
|  |      * @param world  World name | ||||||
|  |      * @param region Region | ||||||
|  |      * @param biome  Biome | ||||||
|  |      * @since 6.6.0 | ||||||
|  |      */ | ||||||
|  |     public static void setBiome(String world, final CuboidRegion region, BiomeType biome) { | ||||||
|  |         PlotSquared.platform().worldUtil().setBiomes(world, region, biome); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Check if a given world name corresponds to a real world |      * Check if a given world name corresponds to a real world | ||||||
|      * |      * | ||||||
| @@ -217,11 +233,14 @@ public abstract class WorldUtil { | |||||||
|     /** |     /** | ||||||
|      * Set the biome in a region |      * Set the biome in a region | ||||||
|      * |      * | ||||||
|      * @param world  World name |      * @param worldName World name | ||||||
|      * @param region    Region |      * @param region    Region | ||||||
|      * @param biome     New biome |      * @param biome     New biome | ||||||
|      */ |      */ | ||||||
|     public abstract void setBiomes(@NonNull String world, @NonNull CuboidRegion region, @NonNull BiomeType biome); |     public void setBiomes(@NonNull String worldName, @NonNull CuboidRegion region, @NonNull BiomeType biome) { | ||||||
|  |         final World world = getWeWorld(worldName); | ||||||
|  |         region.forEach(bv -> world.setBiome(bv, biome)); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get the WorldEdit {@link com.sk89q.worldedit.world.World} corresponding to a world name |      * Get the WorldEdit {@link com.sk89q.worldedit.world.World} corresponding to a world name | ||||||
|   | |||||||
| @@ -38,6 +38,7 @@ import com.plotsquared.core.player.PlotPlayer; | |||||||
| import com.plotsquared.core.plot.Plot; | import com.plotsquared.core.plot.Plot; | ||||||
| import com.plotsquared.core.plot.flag.GlobalFlagContainer; | import com.plotsquared.core.plot.flag.GlobalFlagContainer; | ||||||
| import com.plotsquared.core.plot.flag.PlotFlag; | import com.plotsquared.core.plot.flag.PlotFlag; | ||||||
|  | import com.plotsquared.core.plot.flag.implementations.ServerPlotFlag; | ||||||
| import com.plotsquared.core.util.EventDispatcher; | import com.plotsquared.core.util.EventDispatcher; | ||||||
| import com.plotsquared.core.util.PlayerManager; | import com.plotsquared.core.util.PlayerManager; | ||||||
| import net.kyori.adventure.text.Component; | import net.kyori.adventure.text.Component; | ||||||
| @@ -110,6 +111,9 @@ public final class PlaceholderRegistry { | |||||||
|             return plot.getAlias(); |             return plot.getAlias(); | ||||||
|         }); |         }); | ||||||
|         this.createPlaceholder("currentplot_owner", (player, plot) -> { |         this.createPlaceholder("currentplot_owner", (player, plot) -> { | ||||||
|  |             if (plot.getFlag(ServerPlotFlag.class)){ | ||||||
|  |                 return legacyComponent(TranslatableCaption.of("info.server"), player); | ||||||
|  |             } | ||||||
|             final UUID plotOwner = plot.getOwnerAbs(); |             final UUID plotOwner = plot.getOwnerAbs(); | ||||||
|             if (plotOwner == null) { |             if (plotOwner == null) { | ||||||
|                 return legacyComponent(TranslatableCaption.of("generic.generic_unowned"), player); |                 return legacyComponent(TranslatableCaption.of("generic.generic_unowned"), player); | ||||||
|   | |||||||
| @@ -71,7 +71,7 @@ public class UUIDMapping { | |||||||
|     /** |     /** | ||||||
|      * @deprecated This method is not meant to be invoked or overridden, with no replacement. |      * @deprecated This method is not meant to be invoked or overridden, with no replacement. | ||||||
|      */ |      */ | ||||||
|     @Deprecated(forRemoval = true, since = "TODO") |     @Deprecated(forRemoval = true, since = "6.6.0") | ||||||
|     protected boolean canEqual(final Object other) { |     protected boolean canEqual(final Object other) { | ||||||
|         return other instanceof UUIDMapping; |         return other instanceof UUIDMapping; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -161,8 +161,9 @@ | |||||||
|   "setup.road_width": "<gold>Road width</gold>", |   "setup.road_width": "<gold>Road width</gold>", | ||||||
|   "setup.road_height": "<gold>Road height</gold>", |   "setup.road_height": "<gold>Road height</gold>", | ||||||
|   "setup.road_block": "<gold>Road block</gold>", |   "setup.road_block": "<gold>Road block</gold>", | ||||||
|   "setup.wall_filling_block": "<gold>Wall filling block</gold><gray> (Block(s) been put under the plot border down to Y1)</gray>", |   "setup.wall_filling_block": "<gold>Wall filling block</gold><gray> (Block(s) been put under the plot border down to min gen height + 1)</gray>", | ||||||
|   "setup.wall_height": "<gold>Wall height</gold>", |   "setup.wall_height": "<gold>Wall height</gold>", | ||||||
|  |   "setup.min_gen_height": "<gold>Minimum height from which to generate (for 1.18+ can be negative).</gold>", | ||||||
|   "setup.bedrock_boolean": "<gold>Whether a bedrock layer under the plot should be generated or not</gold>", |   "setup.bedrock_boolean": "<gold>Whether a bedrock layer under the plot should be generated or not</gold>", | ||||||
|   "setup.singleplotarea_void_world": "<gold>Void world</gold>", |   "setup.singleplotarea_void_world": "<gold>Void world</gold>", | ||||||
|   "plotareatype.plot_area_type_normal": "<gray>Standard plot generation</gray>", |   "plotareatype.plot_area_type_normal": "<gray>Standard plot generation</gray>", | ||||||
| @@ -380,6 +381,9 @@ | |||||||
|   "info.plot_list_default": "<gold><plot></gold>", |   "info.plot_list_default": "<gold><plot></gold>", | ||||||
|   "info.plot_list_player_online": "<dark_aqua><prefix></dark_aqua><hover:show_text:\"<dark_aqua>Online</dark_aqua>\"><gold><player></gold></hover>", |   "info.plot_list_player_online": "<dark_aqua><prefix></dark_aqua><hover:show_text:\"<dark_aqua>Online</dark_aqua>\"><gold><player></gold></hover>", | ||||||
|   "info.plot_list_player_offline": "<dark_aqua><prefix></dark_aqua><hover:show_text:\"<dark_gray>Offline</dark_gray>\"><gold><player></gold></hover>", |   "info.plot_list_player_offline": "<dark_aqua><prefix></dark_aqua><hover:show_text:\"<dark_gray>Offline</dark_gray>\"><gold><player></gold></hover>", | ||||||
|  |   "info.plot_list_player_unknown": "<hover:show_text:\"<red>The owner of this plot is unknown</red>\"><white><info.unknown></white></hover>", | ||||||
|  |   "info.plot_list_player_server": "<hover:show_text:\"<red>The plot is owned by the server</red>\"><white><info.server></white></hover>", | ||||||
|  |   "info.plot_list_player_everyone": "<hover:show_text:\"<blue>The plot is owned by everyone</blue>\"><white><info.everyone></white></hover>", | ||||||
|   "info.area_info_format": "<header>\n<reset><gold>Name: </gold><gray><name></gray>\n<gold>Type: </gold><gray><type></gray>\n<gold>Terrain: </gold><gray><terrain></gray>\n<gold>Usage: </gold><gray><usage>%</gray>\n<gold>Claimed: </gold><gray><claimed></gray>\n<gold>Clusters: </gold><gray><clusters></gray>\n<gold>Region: </gold><gray><region></gray>\n<gold>Generator: </gold><gray><generator></gray>\n<footer>", |   "info.area_info_format": "<header>\n<reset><gold>Name: </gold><gray><name></gray>\n<gold>Type: </gold><gray><type></gray>\n<gold>Terrain: </gold><gray><terrain></gray>\n<gold>Usage: </gold><gray><usage>%</gray>\n<gold>Claimed: </gold><gray><claimed></gray>\n<gold>Clusters: </gold><gray><clusters></gray>\n<gold>Region: </gold><gray><region></gray>\n<gold>Generator: </gold><gray><generator></gray>\n<footer>", | ||||||
|   "info.area_list_tooltip": "<gold>Claimed=</gold><gray><claimed></gray>\n<gold>Usage=</gold><gray><usage></gray>\n<gold>Clusters=</gold><gray><clusters></gray>\n<gold>Region=</gold><gray><region></gray>\n<gold>Generator=</gold><gray><generator></gray>", |   "info.area_list_tooltip": "<gold>Claimed=</gold><gray><claimed></gray>\n<gold>Usage=</gold><gray><usage></gray>\n<gold>Clusters=</gold><gray><clusters></gray>\n<gold>Region=</gold><gray><region></gray>\n<gold>Generator=</gold><gray><generator></gray>", | ||||||
|   "info.area_list_item": "<click:run_command:<command_tp>><hover:show_text:\"<command_tp>\"><dark_gray>[</dark_gray><gold><number></gold><dark_gray>]</dark_gray></hover></click> <click:run_command:<command_info>><hover:show_text:\"<hover_info>\"><gold><area_name></gold></hover></click><gray> - </gray><gray><area_type>:<area_terrain></gray>", |   "info.area_list_item": "<click:run_command:<command_tp>><hover:show_text:\"<command_tp>\"><dark_gray>[</dark_gray><gold><number></gold><dark_gray>]</dark_gray></hover></click> <click:run_command:<command_info>><hover:show_text:\"<hover_info>\"><gold><area_name></gold></hover></click><gray> - </gray><gray><area_type>:<area_terrain></gray>", | ||||||
| @@ -612,6 +616,7 @@ | |||||||
|   "flags.flag_description_lectern_read_book": "<gray>Prevent players taking books from lecterns.</gray>", |   "flags.flag_description_lectern_read_book": "<gray>Prevent players taking books from lecterns.</gray>", | ||||||
|   "flags.flag_description_prevent_creative_copy": "<gray>Prevents people from copying item NBT data in the plot unless they're added as members.</gray>", |   "flags.flag_description_prevent_creative_copy": "<gray>Prevents people from copying item NBT data in the plot unless they're added as members.</gray>", | ||||||
|   "flags.flag_description_leaf_decay": "<gray>Set to `false` to prevent leaves from decaying.", |   "flags.flag_description_leaf_decay": "<gray>Set to `false` to prevent leaves from decaying.", | ||||||
|  |   "flags.flag_description_projectiles": "<gray>Prevents guests from shooting projectiles on the plot when set to false.</gray>", | ||||||
|   "flags.flag_error_boolean": "Flag value must be a boolean (true | false).", |   "flags.flag_error_boolean": "Flag value must be a boolean (true | false).", | ||||||
|   "flags.flag_error_enum": "Must be one of: <list>", |   "flags.flag_error_enum": "Must be one of: <list>", | ||||||
|   "flags.flag_error_integer": "Flag value must be a whole positive number.", |   "flags.flag_error_integer": "Flag value must be a whole positive number.", | ||||||
|   | |||||||
| @@ -1,5 +1,5 @@ | |||||||
| <p align="center"> | <p align="center"> | ||||||
|     <img src="https://i.imgur.com/33Y65YL.png" width="150"> |     <img src="https://raw.githubusercontent.com/IntellectualSites/Assets/main/plugins/PlotSquared/PlotSquared.svg" width="300"> | ||||||
| </p> | </p> | ||||||
|  |  | ||||||
| --- | --- | ||||||
|   | |||||||
| @@ -18,7 +18,7 @@ plugins { | |||||||
|     idea |     idea | ||||||
| } | } | ||||||
|  |  | ||||||
| version = "6.5.2-SNAPSHOT" | version = "6.8.2-SNAPSHOT" | ||||||
|  |  | ||||||
| allprojects { | allprojects { | ||||||
|     group = "com.plotsquared" |     group = "com.plotsquared" | ||||||
| @@ -34,12 +34,15 @@ allprojects { | |||||||
|  |  | ||||||
|         maven { |         maven { | ||||||
|             name = "Sonatype OSS (S01)" |             name = "Sonatype OSS (S01)" | ||||||
|             url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots") |             url = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/") | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         maven { |         maven { | ||||||
|             name = "Jitpack" |             name = "Jitpack" | ||||||
|             url = uri("https://jitpack.io") |             url = uri("https://jitpack.io") | ||||||
|  |             content { | ||||||
|  |                 includeModule("com.github.MilkBowl", "VaultAPI") | ||||||
|  |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         maven { |         maven { | ||||||
| @@ -61,9 +64,12 @@ subprojects { | |||||||
|         plugin<EclipsePlugin>() |         plugin<EclipsePlugin>() | ||||||
|         plugin<IdeaPlugin>() |         plugin<IdeaPlugin>() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     dependencies { | ||||||
|  |         implementation(platform("com.intellectualsites.bom:bom-1.18.x:1.2")) | ||||||
|  |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| val javadocDir = rootDir.resolve("docs").resolve("javadoc").resolve(project.name) |  | ||||||
| allprojects { | allprojects { | ||||||
|     dependencies { |     dependencies { | ||||||
|         // Tests |         // Tests | ||||||
| @@ -137,7 +143,7 @@ allprojects { | |||||||
|                         } |                         } | ||||||
|                         developer { |                         developer { | ||||||
|                             id.set("NotMyFault") |                             id.set("NotMyFault") | ||||||
|                             name.set("NotMyFault") |                             name.set("Alexander Brandes") | ||||||
|                             organization.set("IntellectualSites") |                             organization.set("IntellectualSites") | ||||||
|                             email.set("contact@notmyfault.dev") |                             email.set("contact@notmyfault.dev") | ||||||
|                         } |                         } | ||||||
| @@ -169,11 +175,6 @@ allprojects { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     tasks { |     tasks { | ||||||
|         named<Delete>("clean") { |  | ||||||
|             doFirst { |  | ||||||
|                 javadocDir.deleteRecursively() |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         compileJava { |         compileJava { | ||||||
|             options.compilerArgs.addAll(arrayOf("-Xmaxerrs", "1000")) |             options.compilerArgs.addAll(arrayOf("-Xmaxerrs", "1000")) | ||||||
| @@ -184,16 +185,6 @@ allprojects { | |||||||
|             options.encoding = "UTF-8" |             options.encoding = "UTF-8" | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         javadoc { |  | ||||||
|             val opt = options as StandardJavadocDocletOptions |  | ||||||
|             opt.addStringOption("Xdoclint:none", "-quiet") |  | ||||||
|             opt.tags( |  | ||||||
|                     "apiNote:a:API Note:", |  | ||||||
|                     "implSpec:a:Implementation Requirements:", |  | ||||||
|                     "implNote:a:Implementation Note:" |  | ||||||
|             ) |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         shadowJar { |         shadowJar { | ||||||
|             this.archiveClassifier.set(null as String?) |             this.archiveClassifier.set(null as String?) | ||||||
|             this.archiveFileName.set("${project.name}-${project.version}.${this.archiveExtension.getOrElse("jar")}") |             this.archiveFileName.set("${project.name}-${project.version}.${this.archiveExtension.getOrElse("jar")}") | ||||||
| @@ -218,37 +209,3 @@ nexusPublishing { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| tasks { |  | ||||||
|     val aggregatedJavadocs = create<Javadoc>("aggregatedJavadocs") { |  | ||||||
|         title = "${project.name} ${project.version} API" |  | ||||||
|         setDestinationDir(javadocDir) |  | ||||||
|         options.destinationDirectory = javadocDir |  | ||||||
|  |  | ||||||
|         doFirst { |  | ||||||
|             javadocDir.deleteRecursively() |  | ||||||
|         } |  | ||||||
|     }.also { |  | ||||||
|         it.group = "Documentation" |  | ||||||
|         it.description = "Generate javadocs from all child projects as if it was a single project" |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     subprojects.forEach { subProject -> |  | ||||||
|         subProject.afterEvaluate { |  | ||||||
|             subProject.tasks.withType<Javadoc>().forEach { task -> |  | ||||||
|                 aggregatedJavadocs.source += task.source |  | ||||||
|                 aggregatedJavadocs.classpath += task.classpath |  | ||||||
|                 aggregatedJavadocs.excludes += task.excludes |  | ||||||
|                 aggregatedJavadocs.includes += task.includes |  | ||||||
|  |  | ||||||
|                 val rootOptions = aggregatedJavadocs.options as StandardJavadocDocletOptions |  | ||||||
|                 val subOptions = task.options as StandardJavadocDocletOptions |  | ||||||
|                 rootOptions.links(*subOptions.links.orEmpty().minus(rootOptions.links.orEmpty().toSet()).toTypedArray()) |  | ||||||
|             } |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     build { |  | ||||||
|         dependsOn(aggregatedJavadocs) |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|   | |||||||
| @@ -1,15 +1,9 @@ | |||||||
| [versions] | [versions] | ||||||
| # Minecraft expectations |  | ||||||
| gson = "2.8.8" # Version set by Minecraft |  | ||||||
| log4j-api = "2.17.1" # Version set by Minecraft |  | ||||||
| guava = "31.0.1-jre" # Version set by Minecraft |  | ||||||
|  |  | ||||||
| # Platform expectations | # Platform expectations | ||||||
| paper = "1.18.1-R0.1-SNAPSHOT" | paper = "1.18.1-R0.1-SNAPSHOT" | ||||||
| checker-qual = "3.21.2" | checker-qual = "3.22.0" | ||||||
| guice = "5.1.0" | guice = "5.1.0" | ||||||
| findbugs = "3.0.1" | spotbugs = "4.7.0" | ||||||
| snakeyaml = "1.30" # Version set by Bukkit |  | ||||||
|  |  | ||||||
| # Adventure & MiniMessage | # Adventure & MiniMessage | ||||||
| adventure-api = "4.9.3" | adventure-api = "4.9.3" | ||||||
| @@ -17,24 +11,18 @@ adventure-text-minimessage = "4.1.0-SNAPSHOT" | |||||||
| adventure-platform-bukkit = "4.0.1" | adventure-platform-bukkit = "4.0.1" | ||||||
|  |  | ||||||
| # Plugins | # Plugins | ||||||
| worldedit = "7.2.9" | worldedit = "7.2.10" | ||||||
| fawe = "2.0.1" |  | ||||||
| vault = "1.7.1" |  | ||||||
| placeholderapi = "2.11.1" | placeholderapi = "2.11.1" | ||||||
| luckperms = "5.4" | luckperms = "5.4" | ||||||
| essentialsx = "2.19.2" | essentialsx = "2.19.4" | ||||||
| mvdwapi = "3.1.1" | mvdwapi = "3.1.1" | ||||||
|  |  | ||||||
| # Third party | # Third party | ||||||
| prtree = "2.0.0" | prtree = "2.0.0" | ||||||
| aopalliance = "1.0" | aopalliance = "1.0" | ||||||
| cloud-services = "1.6.1" | cloud-services = "1.6.2" | ||||||
| arkitektonika = "2.1.1" | arkitektonika = "2.1.1" | ||||||
| paster = "1.1.4" | squirrelid = "0.3.1" | ||||||
| bstats = "3.0.0" |  | ||||||
| paperlib = "1.0.7" |  | ||||||
| squirrelid = "0.3.0" |  | ||||||
| serverlib = "2.3.1" |  | ||||||
| http4j = "1.3" | http4j = "1.3" | ||||||
|  |  | ||||||
| # Gradle plugins | # Gradle plugins | ||||||
| @@ -48,15 +36,10 @@ nexus = "1.1.0" | |||||||
| paper = { group = "io.papermc.paper", name = "paper-api", version.ref = "paper" } | paper = { group = "io.papermc.paper", name = "paper-api", version.ref = "paper" } | ||||||
| checkerqual = { group = "org.checkerframework", name = "checker-qual", version.ref = "checker-qual" } | checkerqual = { group = "org.checkerframework", name = "checker-qual", version.ref = "checker-qual" } | ||||||
|  |  | ||||||
| # Minecraft expectations |  | ||||||
| gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } |  | ||||||
| log4j = { group = "org.apache.logging.log4j", name = "log4j-api", version.ref = "log4j-api" } |  | ||||||
|  |  | ||||||
| # Platform expectations | # Platform expectations | ||||||
| snakeyaml = { group = "org.yaml", name = "snakeyaml", version.ref = "snakeyaml" } |  | ||||||
| guice = { group = "com.google.inject", name = "guice", version.ref = "guice" } | guice = { group = "com.google.inject", name = "guice", version.ref = "guice" } | ||||||
| guiceassistedinject = { group = "com.google.inject.extensions", name = "guice-assistedinject", version.ref = "guice" } | guiceassistedinject = { group = "com.google.inject.extensions", name = "guice-assistedinject", version.ref = "guice" } | ||||||
| findbugs = { group = "com.google.code.findbugs", name = "annotations", version.ref = "findbugs" } | spotbugs = { group = "com.github.spotbugs", name = "spotbugs-annotations", version.ref = "spotbugs" } | ||||||
|  |  | ||||||
| # Adventure & MiniMessage | # Adventure & MiniMessage | ||||||
| adventure = { group = "net.kyori", name = "adventure-api", version.ref = "adventure-api" } | adventure = { group = "net.kyori", name = "adventure-api", version.ref = "adventure-api" } | ||||||
| @@ -66,9 +49,6 @@ adventurePlatformBukkit = { group = "net.kyori", name = "adventure-platform-bukk | |||||||
| # Plugins | # Plugins | ||||||
| worldeditCore = { group = "com.sk89q.worldedit", name = "worldedit-core", version.ref = "worldedit" } | worldeditCore = { group = "com.sk89q.worldedit", name = "worldedit-core", version.ref = "worldedit" } | ||||||
| worldeditBukkit = { group = "com.sk89q.worldedit", name = "worldedit-bukkit", version.ref = "worldedit" } | worldeditBukkit = { group = "com.sk89q.worldedit", name = "worldedit-bukkit", version.ref = "worldedit" } | ||||||
| fastasyncworldeditBukkit = { group = "com.fastasyncworldedit", name = "FastAsyncWorldEdit-Bukkit", version.ref = "fawe" } |  | ||||||
| fastasyncworldeditCore = { group = "com.fastasyncworldedit", name = "FastAsyncWorldEdit-Core", version.ref = "fawe" } |  | ||||||
| vault = { group = "com.github.MilkBowl", name = "VaultAPI", version.ref = "vault" } |  | ||||||
| placeholderapi = { group = "me.clip", name = "placeholderapi", version.ref = "placeholderapi" } | placeholderapi = { group = "me.clip", name = "placeholderapi", version.ref = "placeholderapi" } | ||||||
| luckperms = { group = "net.luckperms", name = "api", version.ref = "luckperms" } | luckperms = { group = "net.luckperms", name = "api", version.ref = "luckperms" } | ||||||
| essentialsx = { group = "net.essentialsx", name = "EssentialsX", version.ref = "essentialsx" } | essentialsx = { group = "net.essentialsx", name = "EssentialsX", version.ref = "essentialsx" } | ||||||
| @@ -78,14 +58,9 @@ prtree = { group = "com.intellectualsites.prtree", name = "PRTree", version.ref | |||||||
| aopalliance = { group = "aopalliance", name = "aopalliance", version.ref = "aopalliance" } | aopalliance = { group = "aopalliance", name = "aopalliance", version.ref = "aopalliance" } | ||||||
| cloudServices = { group = "cloud.commandframework", name = "cloud-services", version.ref = "cloud-services" } | cloudServices = { group = "cloud.commandframework", name = "cloud-services", version.ref = "cloud-services" } | ||||||
| mvdwapi = { group = "com.intellectualsites.mvdwplaceholderapi", name = "MVdWPlaceholderAPI", version.ref = "mvdwapi" } | mvdwapi = { group = "com.intellectualsites.mvdwplaceholderapi", name = "MVdWPlaceholderAPI", version.ref = "mvdwapi" } | ||||||
| squirrelid = { group = "com.github.EngineHub", name = "SquirrelID", version.ref = "squirrelid" } | squirrelid = { group = "org.enginehub", name = "squirrelid", version.ref = "squirrelid" } | ||||||
| serverlib = { group = "dev.notmyfault.serverlib", name = "ServerLib", version.ref = "serverlib" } |  | ||||||
| bstats = { group = "org.bstats", name = "bstats-bukkit", version.ref = "bstats" } |  | ||||||
| paperlib = { group = "io.papermc", name = "paperlib", version.ref = "paperlib" } |  | ||||||
| arkitektonika = { group = "com.intellectualsites.arkitektonika", name = "Arkitektonika-Client", version.ref = "arkitektonika" } | arkitektonika = { group = "com.intellectualsites.arkitektonika", name = "Arkitektonika-Client", version.ref = "arkitektonika" } | ||||||
| http4j = { group = "com.intellectualsites.http", name = "HTTP4J", version.ref = "http4j" } | http4j = { group = "com.intellectualsites.http", name = "HTTP4J", version.ref = "http4j" } | ||||||
| paster = { group = "com.intellectualsites.paster", name = "Paster", version.ref = "paster" } |  | ||||||
| guava = { group = "com.google.guava", name = "guava", version.ref = "guava" } |  | ||||||
|  |  | ||||||
| [plugins] | [plugins] | ||||||
| shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } | shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							| @@ -1,5 +1,5 @@ | |||||||
| distributionBase=GRADLE_USER_HOME | distributionBase=GRADLE_USER_HOME | ||||||
| distributionPath=wrapper/dists | distributionPath=wrapper/dists | ||||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip | distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip | ||||||
| zipStoreBase=GRADLE_USER_HOME | zipStoreBase=GRADLE_USER_HOME | ||||||
| zipStorePath=wrapper/dists | zipStorePath=wrapper/dists | ||||||
|   | |||||||
										
											Binary file not shown.
										
									
								
							| Before Width: | Height: | Size: 36 KiB | 
| @@ -8,7 +8,8 @@ | |||||||
|     "com.google.guava:guava", |     "com.google.guava:guava", | ||||||
|     "com.google.code.gson:gson", |     "com.google.code.gson:gson", | ||||||
|     "gson", |     "gson", | ||||||
|     "snakeyaml" |     "snakeyaml", | ||||||
|  |     "net.kyori" | ||||||
|   ], |   ], | ||||||
|   "timezone": "Europe/Berlin", |   "timezone": "Europe/Berlin", | ||||||
|   "schedule": [ |   "schedule": [ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user