mirror of
				https://github.com/IntellectualSites/PlotSquared.git
				synced 2025-10-30 17:13:43 +01:00 
			
		
		
		
	Compare commits
	
		
			65 Commits
		
	
	
		
			fix/road-s
			...
			feature/co
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | a5c1f1a74b | ||
|   | 16a4ee835c | ||
|   | c013b92e62 | ||
|   | b00a46b286 | ||
|   | 44b1127181 | ||
|   | c7bfd48a21 | ||
|   | dc13783db8 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 0a390ab342 | ||
|   | d111740f64 | ||
|   | 28e97e8441 | ||
|   | a30cdb37d6 | ||
|   | f848162066 | ||
|   | 40c70aa98d | ||
|   | 0d2b36bac8 | ||
|   | d7e5bcdaa5 | ||
|   | fc783574a3 | ||
|   | 5f7bb784f0 | ||
|   | 26c55a318f | ||
|   | ee68bc3d9e | ||
|   | a3bc3968a5 | ||
|   | 79454da1a6 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 12a4c92ad9 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 167692d464 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | ae26e8155c | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 286ea62a21 | ||
|   | d95c74d8c9 | ||
|   | c1555ddbc7 | ||
|   | 4fe0c586d9 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | aae6ea4fee | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 385d018504 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | f4def082c1 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 69c9f1df83 | ||
|   | e138dc0267 | ||
|   | ca50b53f94 | ||
|   | f705487055 | ||
|   | b7c9453a1a | ||
|   | 1aa370d562 | ||
|   | d3dab0d736 | ||
|   | 764156b267 | ||
|   | 665f5251bf | ||
|   | 7c328095d7 | ||
|   | 7884c91d52 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | e9a19e0821 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 022847fc4b | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 1ee673be58 | ||
|   | 3c2aa99e86 | ||
|   | 11fac3f060 | ||
|   | 3e57e524b9 | ||
|   | f582ec03c5 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 893be136f0 | ||
|   | b74ba30281 | ||
|   | ba9dab1f73 | ||
|   | 8e60fdb477 | ||
|   | 443fe8dd47 | ||
|   | e56e52ba4f | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | cd008bed9b | ||
|   | d4c90283d6 | ||
|   | dc04ec955a | ||
|   | 72f511ce99 | ||
|   | 0d63c2bdb6 | ||
|   | 49e13384cf | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | 1ddc19ff69 | ||
| ![renovate[bot]](/assets/img/avatar_default.png)  | a6d436e841 | ||
|   | 9b0b39ac2e | ||
|   | 638f0bd078 | 
							
								
								
									
										2
									
								
								.github/ISSUE_TEMPLATE/bug_report.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/ISSUE_TEMPLATE/bug_report.yml
									
									
									
									
										vendored
									
									
								
							| @@ -27,7 +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.20.1' |         - '1.20.2' | ||||||
|         - '1.20' |         - '1.20' | ||||||
|         - '1.19.4' |         - '1.19.4' | ||||||
|         - '1.19.3' |         - '1.19.3' | ||||||
|   | |||||||
							
								
								
									
										8
									
								
								.github/renovate.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										8
									
								
								.github/renovate.json
									
									
									
									
										vendored
									
									
								
							| @@ -9,5 +9,11 @@ | |||||||
|     "dependencies" |     "dependencies" | ||||||
|   ], |   ], | ||||||
|   "rebaseWhen": "conflicted", |   "rebaseWhen": "conflicted", | ||||||
|   "schedule": ["on the first day of the month"] |   "schedule": ["on the first day of the month"], | ||||||
|  |   "ignoreDeps": [ | ||||||
|  |     "com.google.code.gson:gson", | ||||||
|  |     "com.google.guava:guava", | ||||||
|  |     "org.yaml:snakeyaml", | ||||||
|  |     "org.apache.logging.log4j:log4j-api", | ||||||
|  |   ] | ||||||
| } | } | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/workflows/build-pr.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build-pr.yml
									
									
									
									
										vendored
									
									
								
							| @@ -9,7 +9,7 @@ jobs: | |||||||
|         os: [ ubuntu-latest, windows-latest, macos-latest ] |         os: [ ubuntu-latest, windows-latest, macos-latest ] | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout Repository |       - name: Checkout Repository | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v4 | ||||||
|       - name: Validate Gradle Wrapper |       - name: Validate Gradle Wrapper | ||||||
|         uses: gradle/wrapper-validation-action@v1 |         uses: gradle/wrapper-validation-action@v1 | ||||||
|       - name: Setup Java |       - name: Setup Java | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/build.yml
									
									
									
									
										vendored
									
									
								
							| @@ -9,7 +9,7 @@ jobs: | |||||||
|     runs-on: ubuntu-latest |     runs-on: ubuntu-latest | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout Repository |       - name: Checkout Repository | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v4 | ||||||
|       - name: Validate Gradle Wrapper |       - name: Validate Gradle Wrapper | ||||||
|         uses: gradle/wrapper-validation-action@v1 |         uses: gradle/wrapper-validation-action@v1 | ||||||
|       - name: Setup Java |       - name: Setup Java | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.github/workflows/codeql.yml
									
									
									
									
										vendored
									
									
								
							| @@ -20,7 +20,7 @@ jobs: | |||||||
|         language: [ 'java' ] |         language: [ 'java' ] | ||||||
|     steps: |     steps: | ||||||
|       - name: Checkout repository |       - name: Checkout repository | ||||||
|         uses: actions/checkout@v3 |         uses: actions/checkout@v4 | ||||||
|       - name: Setup Java |       - name: Setup Java | ||||||
|         uses: actions/setup-java@v3 |         uses: actions/setup-java@v3 | ||||||
|         with: |         with: | ||||||
|   | |||||||
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -138,6 +138,5 @@ build/ | |||||||
|  |  | ||||||
| .DS_Store | .DS_Store | ||||||
| # Ignore run folders | # Ignore run folders | ||||||
| run-[0-0].[0-9]/ | run-[0-9].[0-9][0-9]/ | ||||||
| run-[0-0].[0-9].[0-9]/ | run-[0-9].[0-9][0-9].[0-9]/ | ||||||
|  |  | ||||||
|   | |||||||
| @@ -21,20 +21,20 @@ dependencies { | |||||||
|     api(projects.plotsquaredCore) |     api(projects.plotsquaredCore) | ||||||
|  |  | ||||||
|     // Metrics |     // Metrics | ||||||
|     implementation("org.bstats:bstats-bukkit") |     implementation(libs.bstatsBukkit) | ||||||
|  |  | ||||||
|     // Paper |     // Paper | ||||||
|     compileOnly("io.papermc.paper:paper-api") |     compileOnly(libs.paper) | ||||||
|     implementation("io.papermc:paperlib") |     implementation(libs.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("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit") { isTransitive = false } |     compileOnly(libs.faweBukkit) { isTransitive = false } | ||||||
|     testImplementation("com.fastasyncworldedit:FastAsyncWorldEdit-Bukkit") { isTransitive = false } |     testImplementation(libs.faweBukkit) { isTransitive = false } | ||||||
|     compileOnly("com.github.MilkBowl:VaultAPI") { |     compileOnly(libs.vault) { | ||||||
|         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("dev.notmyfault.serverlib:ServerLib") |     implementation(libs.serverlib) | ||||||
|  |  | ||||||
|     // Our libraries |     // Our libraries | ||||||
|     implementation(libs.arkitektonika) |     implementation(libs.arkitektonika) | ||||||
|     implementation("com.intellectualsites.paster:Paster") |     implementation(libs.paster) | ||||||
|     implementation("com.intellectualsites.informative-annotations:informative-annotations") |     implementation(libs.informativeAnnotations) | ||||||
|  |  | ||||||
|     // Adventure |     // Adventure | ||||||
|     implementation("net.kyori:adventure-platform-bukkit") |     implementation(libs.adventureBukkit) | ||||||
| } | } | ||||||
|  |  | ||||||
| tasks.processResources { | tasks.processResources { | ||||||
| @@ -89,6 +89,8 @@ tasks.named<ShadowJar>("shadowJar") { | |||||||
|     relocate("net.jcip", "com.plotsquared.core.annotations.jcip") |     relocate("net.jcip", "com.plotsquared.core.annotations.jcip") | ||||||
|     relocate("edu.umd.cs.findbugs", "com.plotsquared.core.annotations.findbugs") |     relocate("edu.umd.cs.findbugs", "com.plotsquared.core.annotations.findbugs") | ||||||
|     relocate("com.intellectualsites.annotations", "com.plotsquared.core.annotations.informative") |     relocate("com.intellectualsites.annotations", "com.plotsquared.core.annotations.informative") | ||||||
|  |     relocate("org.jdbi.v3", "com.plotsquared.core.jdbi") | ||||||
|  |     relocate("com.zaxxer.hikari", "com.plotsquared.core.hikari") | ||||||
|  |  | ||||||
|     // Get rid of all the libs which are 100% unused. |     // Get rid of all the libs which are 100% unused. | ||||||
|     minimize() |     minimize() | ||||||
| @@ -100,7 +102,7 @@ tasks { | |||||||
|     withType<Javadoc> { |     withType<Javadoc> { | ||||||
|         val isRelease = if (rootProject.version.toString().endsWith("-SNAPSHOT")) "TODO" else rootProject.version.toString() |         val isRelease = if (rootProject.version.toString().endsWith("-SNAPSHOT")) "TODO" else rootProject.version.toString() | ||||||
|         val opt = options as StandardJavadocDocletOptions |         val opt = options as StandardJavadocDocletOptions | ||||||
|         opt.links("https://jd.papermc.io/paper/1.19/") |         opt.links("https://jd.papermc.io/paper/1.20/") | ||||||
|         opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-bukkit/" + libs.worldeditBukkit.get().versionConstraint.toString()) |         opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-bukkit/" + libs.worldeditBukkit.get().versionConstraint.toString()) | ||||||
|         opt.links("https://intellectualsites.github.io/plotsquared-javadocs/core/") |         opt.links("https://intellectualsites.github.io/plotsquared-javadocs/core/") | ||||||
|         opt.links("https://jd.advntr.dev/api/4.14.0/") |         opt.links("https://jd.advntr.dev/api/4.14.0/") | ||||||
|   | |||||||
| @@ -50,6 +50,7 @@ import com.plotsquared.bukkit.util.BukkitUtil; | |||||||
| import com.plotsquared.bukkit.util.BukkitWorld; | import com.plotsquared.bukkit.util.BukkitWorld; | ||||||
| import com.plotsquared.bukkit.util.SetGenCB; | import com.plotsquared.bukkit.util.SetGenCB; | ||||||
| import com.plotsquared.bukkit.util.TranslationUpdateManager; | import com.plotsquared.bukkit.util.TranslationUpdateManager; | ||||||
|  | import com.plotsquared.bukkit.util.UpdateUtility; | ||||||
| import com.plotsquared.bukkit.util.task.BukkitTaskManager; | import com.plotsquared.bukkit.util.task.BukkitTaskManager; | ||||||
| import com.plotsquared.bukkit.util.task.PaperTimeConverter; | import com.plotsquared.bukkit.util.task.PaperTimeConverter; | ||||||
| import com.plotsquared.bukkit.util.task.SpigotTimeConverter; | import com.plotsquared.bukkit.util.task.SpigotTimeConverter; | ||||||
| @@ -81,6 +82,8 @@ import com.plotsquared.core.inject.annotations.DefaultGenerator; | |||||||
| import com.plotsquared.core.inject.annotations.ImpromptuPipeline; | import com.plotsquared.core.inject.annotations.ImpromptuPipeline; | ||||||
| import com.plotsquared.core.inject.annotations.WorldConfig; | import com.plotsquared.core.inject.annotations.WorldConfig; | ||||||
| import com.plotsquared.core.inject.annotations.WorldFile; | import com.plotsquared.core.inject.annotations.WorldFile; | ||||||
|  | import com.plotsquared.core.inject.modules.DatabaseModule; | ||||||
|  | import com.plotsquared.core.inject.modules.JdbiModule; | ||||||
| import com.plotsquared.core.inject.modules.PlotSquaredModule; | import com.plotsquared.core.inject.modules.PlotSquaredModule; | ||||||
| import com.plotsquared.core.listener.PlotListener; | import com.plotsquared.core.listener.PlotListener; | ||||||
| import com.plotsquared.core.listener.WESubscriber; | import com.plotsquared.core.listener.WESubscriber; | ||||||
| @@ -139,6 +142,7 @@ import org.checkerframework.checker.nullness.qual.NonNull; | |||||||
| import org.checkerframework.checker.nullness.qual.Nullable; | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
| import org.incendo.serverlib.ServerLib; | import org.incendo.serverlib.ServerLib; | ||||||
|  |  | ||||||
|  | import javax.xml.crypto.Data; | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.lang.reflect.Method; | import java.lang.reflect.Method; | ||||||
| @@ -251,6 +255,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|  |     @SuppressWarnings("deprecation") // Paper deprecation | ||||||
|     public void onEnable() { |     public void onEnable() { | ||||||
|         this.pluginName = getDescription().getName(); |         this.pluginName = getDescription().getName(); | ||||||
|  |  | ||||||
| @@ -290,7 +295,9 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl | |||||||
|                         new WorldManagerModule(), |                         new WorldManagerModule(), | ||||||
|                         new PlotSquaredModule(), |                         new PlotSquaredModule(), | ||||||
|                         new BukkitModule(this), |                         new BukkitModule(this), | ||||||
|                         new BackupModule() |                         new BackupModule(), | ||||||
|  |                         new JdbiModule(), | ||||||
|  |                         new DatabaseModule() | ||||||
|                 ); |                 ); | ||||||
|         this.injector.injectMembers(this); |         this.injector.injectMembers(this); | ||||||
|  |  | ||||||
| @@ -302,11 +309,9 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl | |||||||
|  |  | ||||||
|         this.serverLocale = Locale.forLanguageTag(Settings.Enabled_Components.DEFAULT_LOCALE); |         this.serverLocale = Locale.forLanguageTag(Settings.Enabled_Components.DEFAULT_LOCALE); | ||||||
|  |  | ||||||
|         /* TODO Enable update checker before v7 is released to GA |  | ||||||
|         if (PremiumVerification.isPremium() && Settings.Enabled_Components.UPDATE_NOTIFICATIONS) { |         if (PremiumVerification.isPremium() && Settings.Enabled_Components.UPDATE_NOTIFICATIONS) { | ||||||
|             injector.getInstance(UpdateUtility.class).updateChecker(); |             injector.getInstance(UpdateUtility.class).updateChecker(); | ||||||
|         } |         } | ||||||
|          */ |  | ||||||
|  |  | ||||||
|         if (PremiumVerification.isPremium()) { |         if (PremiumVerification.isPremium()) { | ||||||
|             LOGGER.info("PlotSquared version licensed to Spigot user {}", getUserID()); |             LOGGER.info("PlotSquared version licensed to Spigot user {}", getUserID()); | ||||||
| @@ -551,7 +556,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl | |||||||
|         this.startMetrics(); |         this.startMetrics(); | ||||||
|  |  | ||||||
|         if (Settings.Enabled_Components.WORLDS) { |         if (Settings.Enabled_Components.WORLDS) { | ||||||
|             TaskManager.getPlatformImplementation().taskRepeat(this::unload, TaskTime.seconds(1L)); |             TaskManager.getPlatformImplementation().taskRepeat(this::unload, TaskTime.seconds(10L)); | ||||||
|             try { |             try { | ||||||
|                 singleWorldListener = injector().getInstance(SingleWorldListener.class); |                 singleWorldListener = injector().getInstance(SingleWorldListener.class); | ||||||
|                 Bukkit.getPluginManager().registerEvents(singleWorldListener, this); |                 Bukkit.getPluginManager().registerEvents(singleWorldListener, this); | ||||||
| @@ -1161,6 +1166,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl | |||||||
|         return new BukkitPlotGenerator(world, generator, this.plotAreaManager); |         return new BukkitPlotGenerator(world, generator, this.plotAreaManager); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @SuppressWarnings("deprecation") // Paper deprecation | ||||||
|     @Override |     @Override | ||||||
|     public @NonNull String pluginsFormatted() { |     public @NonNull String pluginsFormatted() { | ||||||
|         StringBuilder msg = new StringBuilder(); |         StringBuilder msg = new StringBuilder(); | ||||||
| @@ -1182,7 +1188,7 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     @SuppressWarnings("ConstantConditions") |     @SuppressWarnings({"ConstantConditions", "deprecation"}) // Paper deprecation | ||||||
|     public @NonNull String worldEditImplementations() { |     public @NonNull String worldEditImplementations() { | ||||||
|         StringBuilder msg = new StringBuilder(); |         StringBuilder msg = new StringBuilder(); | ||||||
|         if (Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null) { |         if (Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit") != null) { | ||||||
|   | |||||||
| @@ -33,6 +33,7 @@ import org.bukkit.entity.Ageable; | |||||||
| import org.bukkit.entity.ArmorStand; | import org.bukkit.entity.ArmorStand; | ||||||
| import org.bukkit.entity.Bat; | import org.bukkit.entity.Bat; | ||||||
| import org.bukkit.entity.Boat; | import org.bukkit.entity.Boat; | ||||||
|  | import org.bukkit.entity.Breedable; | ||||||
| import org.bukkit.entity.ChestedHorse; | import org.bukkit.entity.ChestedHorse; | ||||||
| import org.bukkit.entity.EnderDragon; | import org.bukkit.entity.EnderDragon; | ||||||
| import org.bukkit.entity.Entity; | import org.bukkit.entity.Entity; | ||||||
| @@ -74,6 +75,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper { | |||||||
|     private HorseStats horse; |     private HorseStats horse; | ||||||
|     private boolean noGravity; |     private boolean noGravity; | ||||||
|  |  | ||||||
|  |     @SuppressWarnings("deprecation") // Deprecation exists since 1.20, while we support 1.16 onwards | ||||||
|     public ReplicatingEntityWrapper(Entity entity, short depth) { |     public ReplicatingEntityWrapper(Entity entity, short depth) { | ||||||
|         super(entity); |         super(entity); | ||||||
|  |  | ||||||
| @@ -164,7 +166,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper { | |||||||
|                 //this.horse.style = horse.getStyle(); |                 //this.horse.style = horse.getStyle(); | ||||||
|                 //this.horse.color = horse.getColor(); |                 //this.horse.color = horse.getColor(); | ||||||
|                 storeTameable(horse); |                 storeTameable(horse); | ||||||
|                 storeAgeable(horse); |                 storeBreedable(horse); | ||||||
|                 storeLiving(horse); |                 storeLiving(horse); | ||||||
|                 storeInventory(horse); |                 storeInventory(horse); | ||||||
|                 return; |                 return; | ||||||
| @@ -172,7 +174,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper { | |||||||
|             // END INVENTORY HOLDER // |             // END INVENTORY HOLDER // | ||||||
|             case "WOLF", "OCELOT" -> { |             case "WOLF", "OCELOT" -> { | ||||||
|                 storeTameable((Tameable) entity); |                 storeTameable((Tameable) entity); | ||||||
|                 storeAgeable((Ageable) entity); |                 storeBreedable((Breedable) entity); | ||||||
|                 storeLiving((LivingEntity) entity); |                 storeLiving((LivingEntity) entity); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
| @@ -186,18 +188,18 @@ public final class ReplicatingEntityWrapper extends EntityWrapper { | |||||||
|                     this.dataByte = (byte) 0; |                     this.dataByte = (byte) 0; | ||||||
|                 } |                 } | ||||||
|                 this.dataByte2 = sheep.getColor().getDyeData(); |                 this.dataByte2 = sheep.getColor().getDyeData(); | ||||||
|                 storeAgeable(sheep); |                 storeBreedable(sheep); | ||||||
|                 storeLiving(sheep); |                 storeLiving(sheep); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             case "VILLAGER", "CHICKEN", "COW", "MUSHROOM_COW", "PIG", "TURTLE", "POLAR_BEAR" -> { |             case "VILLAGER", "CHICKEN", "COW", "MUSHROOM_COW", "PIG", "TURTLE", "POLAR_BEAR" -> { | ||||||
|                 storeAgeable((Ageable) entity); |                 storeBreedable((Breedable) entity); | ||||||
|                 storeLiving((LivingEntity) entity); |                 storeLiving((LivingEntity) entity); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             case "RABBIT" -> { |             case "RABBIT" -> { | ||||||
|                 this.dataByte = getOrdinal(Rabbit.Type.values(), ((Rabbit) entity).getRabbitType()); |                 this.dataByte = getOrdinal(Rabbit.Type.values(), ((Rabbit) entity).getRabbitType()); | ||||||
|                 storeAgeable((Ageable) entity); |                 storeBreedable((Breedable) entity); | ||||||
|                 storeLiving((LivingEntity) entity); |                 storeLiving((LivingEntity) entity); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
| @@ -381,6 +383,11 @@ public final class ReplicatingEntityWrapper extends EntityWrapper { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @deprecated Use {@link #restoreBreedable(Breedable)} instead | ||||||
|  |      * @since 7.1.0 | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "7.1.0") | ||||||
|     private void restoreAgeable(Ageable entity) { |     private void restoreAgeable(Ageable entity) { | ||||||
|         if (!this.aged.adult) { |         if (!this.aged.adult) { | ||||||
|             entity.setBaby(); |             entity.setBaby(); | ||||||
| @@ -391,6 +398,11 @@ public final class ReplicatingEntityWrapper extends EntityWrapper { | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @deprecated Use {@link #storeBreedable(Breedable)} instead | ||||||
|  |      * @since 7.1.0 | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "7.1.0") | ||||||
|     public void storeAgeable(Ageable aged) { |     public void storeAgeable(Ageable aged) { | ||||||
|         this.aged = new AgeableStats(); |         this.aged = new AgeableStats(); | ||||||
|         this.aged.age = aged.getAge(); |         this.aged.age = aged.getAge(); | ||||||
| @@ -398,6 +410,29 @@ public final class ReplicatingEntityWrapper extends EntityWrapper { | |||||||
|         this.aged.adult = aged.isAdult(); |         this.aged.adult = aged.isAdult(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @since 7.1.0 | ||||||
|  |      */ | ||||||
|  |     private void restoreBreedable(Breedable entity) { | ||||||
|  |         if (!this.aged.adult) { | ||||||
|  |             entity.setBaby(); | ||||||
|  |         } | ||||||
|  |         entity.setAgeLock(this.aged.locked); | ||||||
|  |         if (this.aged.age > 0) { | ||||||
|  |             entity.setAge(this.aged.age); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @since 7.1.0 | ||||||
|  |      */ | ||||||
|  |     private void storeBreedable(Breedable breedable) { | ||||||
|  |         this.aged = new AgeableStats(); | ||||||
|  |         this.aged.age = breedable.getAge(); | ||||||
|  |         this.aged.locked = breedable.getAgeLock(); | ||||||
|  |         this.aged.adult = breedable.isAdult(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public void storeTameable(Tameable tamed) { |     public void storeTameable(Tameable tamed) { | ||||||
|         this.tamed = new TameableStats(); |         this.tamed = new TameableStats(); | ||||||
|         this.tamed.owner = tamed.getOwner(); |         this.tamed.owner = tamed.getOwner(); | ||||||
| @@ -501,7 +536,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper { | |||||||
|                 //horse.setStyle(this.horse.style); |                 //horse.setStyle(this.horse.style); | ||||||
|                 //horse.setColor(this.horse.color); |                 //horse.setColor(this.horse.color); | ||||||
|                 restoreTameable(horse); |                 restoreTameable(horse); | ||||||
|                 restoreAgeable(horse); |                 restoreBreedable(horse); | ||||||
|                 restoreLiving(horse); |                 restoreLiving(horse); | ||||||
|                 restoreInventory(horse); |                 restoreInventory(horse); | ||||||
|                 return entity; |                 return entity; | ||||||
| @@ -509,7 +544,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper { | |||||||
|             // END INVENTORY HOLDER // |             // END INVENTORY HOLDER // | ||||||
|             case "WOLF", "OCELOT" -> { |             case "WOLF", "OCELOT" -> { | ||||||
|                 restoreTameable((Tameable) entity); |                 restoreTameable((Tameable) entity); | ||||||
|                 restoreAgeable((Ageable) entity); |                 restoreBreedable((Breedable) entity); | ||||||
|                 restoreLiving((LivingEntity) entity); |                 restoreLiving((LivingEntity) entity); | ||||||
|                 return entity; |                 return entity; | ||||||
|             } |             } | ||||||
| @@ -522,12 +557,12 @@ public final class ReplicatingEntityWrapper extends EntityWrapper { | |||||||
|                 if (this.dataByte2 != 0) { |                 if (this.dataByte2 != 0) { | ||||||
|                     sheep.setColor(DyeColor.getByDyeData(this.dataByte2)); |                     sheep.setColor(DyeColor.getByDyeData(this.dataByte2)); | ||||||
|                 } |                 } | ||||||
|                 restoreAgeable(sheep); |                 restoreBreedable(sheep); | ||||||
|                 restoreLiving(sheep); |                 restoreLiving(sheep); | ||||||
|                 return sheep; |                 return sheep; | ||||||
|             } |             } | ||||||
|             case "VILLAGER", "CHICKEN", "COW", "TURTLE", "POLAR_BEAR", "MUSHROOM_COW", "PIG" -> { |             case "VILLAGER", "CHICKEN", "COW", "TURTLE", "POLAR_BEAR", "MUSHROOM_COW", "PIG" -> { | ||||||
|                 restoreAgeable((Ageable) entity); |                 restoreBreedable((Breedable) entity); | ||||||
|                 restoreLiving((LivingEntity) entity); |                 restoreLiving((LivingEntity) entity); | ||||||
|                 return entity; |                 return entity; | ||||||
|             } |             } | ||||||
| @@ -536,7 +571,7 @@ public final class ReplicatingEntityWrapper extends EntityWrapper { | |||||||
|                 if (this.dataByte != 0) { |                 if (this.dataByte != 0) { | ||||||
|                     ((Rabbit) entity).setRabbitType(Rabbit.Type.values()[this.dataByte]); |                     ((Rabbit) entity).setRabbitType(Rabbit.Type.values()[this.dataByte]); | ||||||
|                 } |                 } | ||||||
|                 restoreAgeable((Ageable) entity); |                 restoreBreedable((Breedable) entity); | ||||||
|                 restoreLiving((LivingEntity) entity); |                 restoreLiving((LivingEntity) entity); | ||||||
|                 return entity; |                 return entity; | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -33,6 +33,7 @@ import com.plotsquared.core.plot.PlotArea; | |||||||
| import com.plotsquared.core.plot.flag.implementations.BlockBurnFlag; | import com.plotsquared.core.plot.flag.implementations.BlockBurnFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.BlockIgnitionFlag; | import com.plotsquared.core.plot.flag.implementations.BlockIgnitionFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.BreakFlag; | import com.plotsquared.core.plot.flag.implementations.BreakFlag; | ||||||
|  | import com.plotsquared.core.plot.flag.implementations.ConcreteHardenFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.CoralDryFlag; | import com.plotsquared.core.plot.flag.implementations.CoralDryFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.CropGrowFlag; | import com.plotsquared.core.plot.flag.implementations.CropGrowFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.DisablePhysicsFlag; | import com.plotsquared.core.plot.flag.implementations.DisablePhysicsFlag; | ||||||
| @@ -586,6 +587,12 @@ public class BlockEventListener implements Listener { | |||||||
|                 event.setCancelled(true); |                 event.setCancelled(true); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         if (event.getNewState().getType().toString().endsWith("CONCRETE")) { | ||||||
|  |             if (!plot.getFlag(ConcreteHardenFlag.class)) { | ||||||
|  |                 plot.debug("Concrete powder could not harden because concrete-harden = false"); | ||||||
|  |                 event.setCancelled(true); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) |     @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) | ||||||
|   | |||||||
| @@ -152,7 +152,7 @@ public class EntityEventListener implements Listener { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL", |             case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL", | ||||||
|                     "TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN", "NETHER_PORTAL", "DEFAULT", |                     "TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN", "NETHER_PORTAL", | ||||||
|                     "DUPLICATION", "FROZEN", "SPELL" -> { |                     "DUPLICATION", "FROZEN", "SPELL" -> { | ||||||
|                 if (!area.isMobSpawning()) { |                 if (!area.isMobSpawning()) { | ||||||
|                     event.setCancelled(true); |                     event.setCancelled(true); | ||||||
|   | |||||||
| @@ -369,6 +369,7 @@ public class PlayerEventListener implements Listener { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) |     @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) | ||||||
|  |     @SuppressWarnings("deprecation") // Paper deprecation | ||||||
|     public void onConnect(PlayerJoinEvent event) { |     public void onConnect(PlayerJoinEvent event) { | ||||||
|         final Player player = event.getPlayer(); |         final Player player = event.getPlayer(); | ||||||
|         PlotSquared.platform().playerManager().removePlayer(player.getUniqueId()); |         PlotSquared.platform().playerManager().removePlayer(player.getUniqueId()); | ||||||
| @@ -733,6 +734,7 @@ public class PlayerEventListener implements Listener { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @EventHandler(priority = EventPriority.LOW) |     @EventHandler(priority = EventPriority.LOW) | ||||||
|  |     @SuppressWarnings("deprecation") // Paper deprecation | ||||||
|     public void onChat(AsyncPlayerChatEvent event) { |     public void onChat(AsyncPlayerChatEvent event) { | ||||||
|         if (event.isCancelled()) { |         if (event.isCancelled()) { | ||||||
|             return; |             return; | ||||||
| @@ -1063,6 +1065,7 @@ public class PlayerEventListener implements Listener { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     @EventHandler(priority = EventPriority.LOW) |     @EventHandler(priority = EventPriority.LOW) | ||||||
|  |     @SuppressWarnings("deprecation") // Paper deprecation | ||||||
|     public void onCancelledInteract(PlayerInteractEvent event) { |     public void onCancelledInteract(PlayerInteractEvent event) { | ||||||
|         if (event.isCancelled() && event.getAction() == Action.RIGHT_CLICK_AIR) { |         if (event.isCancelled() && event.getAction() == Action.RIGHT_CLICK_AIR) { | ||||||
|             Player player = event.getPlayer(); |             Player player = event.getPlayer(); | ||||||
|   | |||||||
| @@ -44,6 +44,7 @@ import java.util.stream.IntStream; | |||||||
| @Singleton | @Singleton | ||||||
| public class BukkitInventoryUtil extends InventoryUtil { | public class BukkitInventoryUtil extends InventoryUtil { | ||||||
|  |  | ||||||
|  |     @SuppressWarnings("deprecation") // Paper deprecation | ||||||
|     private static @Nullable ItemStack getItem(PlotItemStack item) { |     private static @Nullable ItemStack getItem(PlotItemStack item) { | ||||||
|         if (item == null) { |         if (item == null) { | ||||||
|             return null; |             return null; | ||||||
|   | |||||||
| @@ -67,6 +67,7 @@ public class BukkitSetupUtils extends SetupUtils { | |||||||
|         this.worldFile = worldFile; |         this.worldFile = worldFile; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @SuppressWarnings("deprecation") // Paper deprecation | ||||||
|     @Override |     @Override | ||||||
|     public void updateGenerators(final boolean force) { |     public void updateGenerators(final boolean force) { | ||||||
|         if (loaded && !SetupUtils.generators.isEmpty() && !force) { |         if (loaded && !SetupUtils.generators.isEmpty() && !force) { | ||||||
|   | |||||||
| @@ -44,6 +44,10 @@ public class TranslationUpdateManager { | |||||||
|         String minheightReplacement = "minheight"; |         String minheightReplacement = "minheight"; | ||||||
|         String maxHeight = "maxHeight"; |         String maxHeight = "maxHeight"; | ||||||
|         String maxheightReplacement = "maxheight"; |         String maxheightReplacement = "maxheight"; | ||||||
|  |         String usedGrants = "usedGrants"; | ||||||
|  |         String usedGrantsReplacement = "used_grants"; | ||||||
|  |         String remainingGrants = "remainingGrants"; | ||||||
|  |         String rremainingGrantsReplacement = "remaining_grants"; | ||||||
|  |  | ||||||
|         try (Stream<Path> paths = Files.walk(Paths.get(PlotSquared.platform().getDirectory().toPath().resolve("lang").toUri()))) { |         try (Stream<Path> paths = Files.walk(Paths.get(PlotSquared.platform().getDirectory().toPath().resolve("lang").toUri()))) { | ||||||
|             paths |             paths | ||||||
| @@ -53,6 +57,8 @@ public class TranslationUpdateManager { | |||||||
|                         replaceInFile(p, suggestCommand, suggestCommandReplacement); |                         replaceInFile(p, suggestCommand, suggestCommandReplacement); | ||||||
|                         replaceInFile(p, minHeight, minheightReplacement); |                         replaceInFile(p, minHeight, minheightReplacement); | ||||||
|                         replaceInFile(p, maxHeight, maxheightReplacement); |                         replaceInFile(p, maxHeight, maxheightReplacement); | ||||||
|  |                         replaceInFile(p, usedGrants, usedGrantsReplacement); | ||||||
|  |                         replaceInFile(p, remainingGrants, rremainingGrantsReplacement); | ||||||
|                     }); |                     }); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -35,7 +35,7 @@ import org.bukkit.scheduler.BukkitTask; | |||||||
| import javax.net.ssl.HttpsURLConnection; | import javax.net.ssl.HttpsURLConnection; | ||||||
| import java.io.IOException; | import java.io.IOException; | ||||||
| import java.io.InputStreamReader; | import java.io.InputStreamReader; | ||||||
| import java.net.URL; | import java.net.URI; | ||||||
|  |  | ||||||
| public class UpdateUtility implements Listener { | public class UpdateUtility implements Listener { | ||||||
|  |  | ||||||
| @@ -59,8 +59,9 @@ public class UpdateUtility implements Listener { | |||||||
|     public void updateChecker() { |     public void updateChecker() { | ||||||
|         task = Bukkit.getScheduler().runTaskTimerAsynchronously(this.javaPlugin, () -> { |         task = Bukkit.getScheduler().runTaskTimerAsynchronously(this.javaPlugin, () -> { | ||||||
|             try { |             try { | ||||||
|                 HttpsURLConnection connection = (HttpsURLConnection) new URL( |                 HttpsURLConnection connection = (HttpsURLConnection) URI.create( | ||||||
|                         "https://api.spigotmc.org/simple/0.1/index.php?action=getResource&id=77506") |                         "https://api.spigotmc.org/simple/0.2/index.php?action=getResource&id=77506") | ||||||
|  |                         .toURL() | ||||||
|                         .openConnection(); |                         .openConnection(); | ||||||
|                 connection.setRequestMethod("GET"); |                 connection.setRequestMethod("GET"); | ||||||
|                 JsonObject result = new JsonParser() |                 JsonObject result = new JsonParser() | ||||||
|   | |||||||
| @@ -1,76 +0,0 @@ | |||||||
| # Contributor Covenant Code of Conduct |  | ||||||
|  |  | ||||||
| ## Our Pledge |  | ||||||
|  |  | ||||||
| In the interest of fostering an open and welcoming environment, we as |  | ||||||
| contributors and maintainers pledge to making participation in our project and |  | ||||||
| our community a harassment-free experience for everyone, regardless of age, body |  | ||||||
| size, disability, ethnicity, sex characteristics, gender identity and expression, |  | ||||||
| level of experience, education, socio-economic status, nationality, personal |  | ||||||
| appearance, race, religion, or sexual identity and orientation. |  | ||||||
|  |  | ||||||
| ## Our Standards |  | ||||||
|  |  | ||||||
| Examples of behavior that contributes to creating a positive environment |  | ||||||
| include: |  | ||||||
|  |  | ||||||
| * Using welcoming and inclusive language |  | ||||||
| * Being respectful of differing viewpoints and experiences |  | ||||||
| * Gracefully accepting constructive criticism |  | ||||||
| * Focusing on what is best for the community |  | ||||||
| * Showing empathy towards other community members |  | ||||||
|  |  | ||||||
| Examples of unacceptable behavior by participants include: |  | ||||||
|  |  | ||||||
| * The use of sexualized language or imagery and unwelcome sexual attention or |  | ||||||
|   advances |  | ||||||
| * Trolling, insulting/derogatory comments, and personal or political attacks |  | ||||||
| * Public or private harassment |  | ||||||
| * Publishing others' private information, such as a physical or electronic |  | ||||||
|   address, without explicit permission |  | ||||||
| * Other conduct which could reasonably be considered inappropriate in a |  | ||||||
|   professional setting |  | ||||||
|  |  | ||||||
| ## Our Responsibilities |  | ||||||
|  |  | ||||||
| Project maintainers are responsible for clarifying the standards of acceptable |  | ||||||
| behavior and are expected to take appropriate and fair corrective action in |  | ||||||
| response to any instances of unacceptable behavior. |  | ||||||
|  |  | ||||||
| Project maintainers have the right and responsibility to remove, edit, or |  | ||||||
| reject comments, commits, code, wiki edits, issues, and other contributions |  | ||||||
| that are not aligned to this Code of Conduct, or to ban temporarily or |  | ||||||
| permanently any contributor for other behaviors that they deem inappropriate, |  | ||||||
| threatening, offensive, or harmful. |  | ||||||
|  |  | ||||||
| ## Scope |  | ||||||
|  |  | ||||||
| This Code of Conduct applies both within project spaces and in public spaces |  | ||||||
| when an individual is representing the project or its community. Examples of |  | ||||||
| representing a project or community include using an official project e-mail |  | ||||||
| address, posting via an official social media account, or acting as an appointed |  | ||||||
| representative at an online or offline event. Representation of a project may be |  | ||||||
| further defined and clarified by project maintainers. |  | ||||||
|  |  | ||||||
| ## Enforcement |  | ||||||
|  |  | ||||||
| Instances of abusive, harassing, or otherwise unacceptable behavior may be |  | ||||||
| reported by contacting the project team at contact<at>intellectualsites.com. All |  | ||||||
| complaints will be reviewed and investigated and will result in a response that |  | ||||||
| is deemed necessary and appropriate to the circumstances. The project team is |  | ||||||
| obligated to maintain confidentiality with regard to the reporter of an incident. |  | ||||||
| Further details of specific enforcement policies may be posted separately. |  | ||||||
|  |  | ||||||
| Project maintainers who do not follow or enforce the Code of Conduct in good |  | ||||||
| faith may face temporary or permanent repercussions as determined by other |  | ||||||
| members of the project's leadership. |  | ||||||
|  |  | ||||||
| ## Attribution |  | ||||||
|  |  | ||||||
| This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, |  | ||||||
| available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html |  | ||||||
|  |  | ||||||
| [homepage]: https://www.contributor-covenant.org |  | ||||||
|  |  | ||||||
| For answers to common questions about this code of conduct, see |  | ||||||
| https://www.contributor-covenant.org/faq |  | ||||||
| @@ -2,18 +2,18 @@ import java.time.format.DateTimeFormatter | |||||||
|  |  | ||||||
| dependencies { | dependencies { | ||||||
|     // Expected everywhere. |     // Expected everywhere. | ||||||
|     compileOnlyApi("org.checkerframework:checker-qual") |     compileOnlyApi(libs.checkerqual) | ||||||
|  |  | ||||||
|     // Minecraft expectations |     // Minecraft expectations | ||||||
|     compileOnlyApi("com.google.code.gson:gson") |     compileOnlyApi(libs.gson) | ||||||
|     compileOnly("com.google.guava:guava") |     compileOnly(libs.guava) | ||||||
|  |  | ||||||
|     // Platform expectations |     // Platform expectations | ||||||
|     compileOnlyApi("org.yaml:snakeyaml") |     compileOnlyApi(libs.snakeyaml) | ||||||
|  |  | ||||||
|     // Adventure |     // Adventure | ||||||
|     api("net.kyori:adventure-api") |     api(libs.adventureApi) | ||||||
|     api("net.kyori:adventure-text-minimessage") |     api(libs.adventureMiniMessage) | ||||||
|  |  | ||||||
|     // Guice |     // Guice | ||||||
|     api(libs.guice) { |     api(libs.guice) { | ||||||
| @@ -31,19 +31,24 @@ dependencies { | |||||||
|         exclude(group = "dummypermscompat") |         exclude(group = "dummypermscompat") | ||||||
|     } |     } | ||||||
|     testImplementation(libs.worldeditCore) |     testImplementation(libs.worldeditCore) | ||||||
|     compileOnly("com.fastasyncworldedit:FastAsyncWorldEdit-Core") { isTransitive = false } |     compileOnly(libs.faweBukkit) { isTransitive = false } | ||||||
|     testImplementation("com.fastasyncworldedit:FastAsyncWorldEdit-Core") { isTransitive = false } |     testImplementation(libs.faweCore) { isTransitive = false } | ||||||
|  |  | ||||||
|     // Logging |     // Logging | ||||||
|     compileOnlyApi("org.apache.logging.log4j:log4j-api") |     compileOnlyApi(libs.log4j) | ||||||
|  |  | ||||||
|  |     // Database | ||||||
|  |     api(libs.hikaricp) | ||||||
|  |     api(libs.jdbiCore) | ||||||
|  |     api(libs.jdbiGuice) | ||||||
|  |  | ||||||
|     // 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("com.intellectualsites.paster:Paster") |     api(libs.paster) | ||||||
|     api("com.intellectualsites.informative-annotations:informative-annotations") |     api(libs.informativeAnnotations) | ||||||
| } | } | ||||||
|  |  | ||||||
| tasks.processResources { | tasks.processResources { | ||||||
| @@ -57,8 +62,8 @@ tasks.processResources { | |||||||
|  |  | ||||||
|     doLast { |     doLast { | ||||||
|         copy { |         copy { | ||||||
|             from(File("$rootDir/LICENSE")) |             from(layout.buildDirectory.file("$rootDir/LICENSE")) | ||||||
|             into("$buildDir/resources/main/") |             into(layout.buildDirectory.dir("resources/main")) | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -72,7 +77,6 @@ tasks { | |||||||
|         opt.links("https://jd.advntr.dev/text-minimessage/4.14.0/") |         opt.links("https://jd.advntr.dev/text-minimessage/4.14.0/") | ||||||
|         opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/") |         opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/") | ||||||
|         opt.links("https://checkerframework.org/api/") |         opt.links("https://checkerframework.org/api/") | ||||||
|         opt.links("https://javadoc.io/doc/com.intellectualsites.informative-annotations/informative-annotations/latest/") |  | ||||||
|         opt.isLinkSource = true |         opt.isLinkSource = true | ||||||
|         opt.bottom(File("$rootDir/javadocfooter.html").readText()) |         opt.bottom(File("$rootDir/javadocfooter.html").readText()) | ||||||
|         opt.isUse = true |         opt.isUse = true | ||||||
|   | |||||||
| @@ -18,6 +18,7 @@ | |||||||
|  */ |  */ | ||||||
| package com.plotsquared.core; | package com.plotsquared.core; | ||||||
|  |  | ||||||
|  | import com.google.inject.Key; | ||||||
| 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.MemorySection; | import com.plotsquared.core.configuration.MemorySection; | ||||||
| @@ -31,14 +32,12 @@ import com.plotsquared.core.configuration.caption.load.DefaultCaptionProvider; | |||||||
| import com.plotsquared.core.configuration.file.YamlConfiguration; | import com.plotsquared.core.configuration.file.YamlConfiguration; | ||||||
| import com.plotsquared.core.configuration.serialization.ConfigurationSerialization; | import com.plotsquared.core.configuration.serialization.ConfigurationSerialization; | ||||||
| import com.plotsquared.core.database.DBFunc; | import com.plotsquared.core.database.DBFunc; | ||||||
| import com.plotsquared.core.database.Database; |  | ||||||
| import com.plotsquared.core.database.MySQL; |  | ||||||
| import com.plotsquared.core.database.SQLManager; | import com.plotsquared.core.database.SQLManager; | ||||||
| import com.plotsquared.core.database.SQLite; |  | ||||||
| import com.plotsquared.core.generator.GeneratorWrapper; | import com.plotsquared.core.generator.GeneratorWrapper; | ||||||
| import com.plotsquared.core.generator.HybridPlotWorld; | import com.plotsquared.core.generator.HybridPlotWorld; | ||||||
| import com.plotsquared.core.generator.HybridUtils; | import com.plotsquared.core.generator.HybridUtils; | ||||||
| import com.plotsquared.core.generator.IndependentPlotGenerator; | import com.plotsquared.core.generator.IndependentPlotGenerator; | ||||||
|  | import com.plotsquared.core.inject.annotations.PlotDatabase; | ||||||
| import com.plotsquared.core.inject.factory.HybridPlotWorldFactory; | import com.plotsquared.core.inject.factory.HybridPlotWorldFactory; | ||||||
| import com.plotsquared.core.listener.PlotListener; | import com.plotsquared.core.listener.PlotListener; | ||||||
| import com.plotsquared.core.location.Location; | import com.plotsquared.core.location.Location; | ||||||
| @@ -75,7 +74,9 @@ import org.checkerframework.checker.nullness.qual.MonotonicNonNull; | |||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
| import org.checkerframework.checker.nullness.qual.Nullable; | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
|  |  | ||||||
|  | import javax.sql.DataSource; | ||||||
| import java.io.BufferedReader; | import java.io.BufferedReader; | ||||||
|  | import java.io.Closeable; | ||||||
| import java.io.File; | import java.io.File; | ||||||
| import java.io.FileInputStream; | import java.io.FileInputStream; | ||||||
| import java.io.FileOutputStream; | import java.io.FileOutputStream; | ||||||
| @@ -84,7 +85,7 @@ import java.io.InputStream; | |||||||
| import java.io.InputStreamReader; | import java.io.InputStreamReader; | ||||||
| import java.io.ObjectInputStream; | import java.io.ObjectInputStream; | ||||||
| import java.io.ObjectOutputStream; | import java.io.ObjectOutputStream; | ||||||
| import java.net.MalformedURLException; | import java.net.URI; | ||||||
| import java.net.URISyntaxException; | import java.net.URISyntaxException; | ||||||
| import java.net.URL; | import java.net.URL; | ||||||
| import java.nio.file.Files; | import java.nio.file.Files; | ||||||
| @@ -210,9 +211,10 @@ public class PlotSquared { | |||||||
|             try { |             try { | ||||||
|                 URL logurl = PlotSquared.class.getProtectionDomain().getCodeSource().getLocation(); |                 URL logurl = PlotSquared.class.getProtectionDomain().getCodeSource().getLocation(); | ||||||
|                 this.jarFile = new File( |                 this.jarFile = new File( | ||||||
|                         new URL(logurl.toURI().toString().split("\\!")[0].replaceAll("jar:file", "file")) |                         URI.create( | ||||||
|                                 .toURI().getPath()); |                                 logurl.toURI().toString().split("\\!")[0].replaceAll("jar:file", "file")) | ||||||
|             } catch (MalformedURLException | URISyntaxException | SecurityException e) { |                                 .getPath()); | ||||||
|  |             } catch (URISyntaxException | SecurityException e) { | ||||||
|                 e.printStackTrace(); |                 e.printStackTrace(); | ||||||
|                 this.jarFile = new File(this.platform.getDirectory().getParentFile(), "PlotSquared.jar"); |                 this.jarFile = new File(this.platform.getDirectory().getParentFile(), "PlotSquared.jar"); | ||||||
|                 if (!this.jarFile.exists()) { |                 if (!this.jarFile.exists()) { | ||||||
| @@ -1235,8 +1237,11 @@ public class PlotSquared { | |||||||
|             DBFunc.validatePlots(plots); |             DBFunc.validatePlots(plots); | ||||||
|  |  | ||||||
|             // Close the connection |             // Close the connection | ||||||
|             DBFunc.close(); |             final DataSource dataSource = platform().injector().getInstance(Key.get(DataSource.class, PlotDatabase.class)); | ||||||
|         } catch (NullPointerException throwable) { |             if (dataSource instanceof Closeable closeable) { | ||||||
|  |                 closeable.close(); | ||||||
|  |             } | ||||||
|  |         } catch (IOException | NullPointerException throwable) { | ||||||
|             LOGGER.error("Could not close database connection", throwable); |             LOGGER.error("Could not close database connection", throwable); | ||||||
|             throwable.printStackTrace(); |             throwable.printStackTrace(); | ||||||
|         } |         } | ||||||
| @@ -1281,33 +1286,14 @@ public class PlotSquared { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Setup the database connection. |      * Set up the database connection. | ||||||
|      */ |      */ | ||||||
|     public void setupDatabase() { |     public void setupDatabase() { | ||||||
|         try { |         try { | ||||||
|             if (DBFunc.dbManager != null) { |             if (DBFunc.dbManager != null) { | ||||||
|                 DBFunc.dbManager.close(); |                 DBFunc.dbManager.close(); | ||||||
|             } |             } | ||||||
|             Database database; |             DBFunc.dbManager = platform().injector().getInstance(SQLManager.class); | ||||||
|             if (Storage.MySQL.USE) { |  | ||||||
|                 database = new MySQL(Storage.MySQL.HOST, Storage.MySQL.PORT, Storage.MySQL.DATABASE, |  | ||||||
|                         Storage.MySQL.USER, Storage.MySQL.PASSWORD |  | ||||||
|                 ); |  | ||||||
|             } else if (Storage.SQLite.USE) { |  | ||||||
|                 File file = FileUtils.getFile(platform.getDirectory(), Storage.SQLite.DB + ".db"); |  | ||||||
|                 database = new SQLite(file); |  | ||||||
|             } else { |  | ||||||
|                 LOGGER.error("No storage type is set. Disabling PlotSquared"); |  | ||||||
|                 this.platform.shutdown(); //shutdown used instead of disable because no database is set |  | ||||||
|                 return; |  | ||||||
|             } |  | ||||||
|             DBFunc.dbManager = new SQLManager( |  | ||||||
|                     database, |  | ||||||
|                     Storage.PREFIX, |  | ||||||
|                     this.eventDispatcher, |  | ||||||
|                     this.plotListener, |  | ||||||
|                     this.worldConfiguration |  | ||||||
|             ); |  | ||||||
|             this.plots_tmp = DBFunc.getPlots(); |             this.plots_tmp = DBFunc.getPlots(); | ||||||
|             if (getPlotAreaManager() instanceof SinglePlotAreaManager) { |             if (getPlotAreaManager() instanceof SinglePlotAreaManager) { | ||||||
|                 SinglePlotArea area = ((SinglePlotAreaManager) getPlotAreaManager()).getArea(); |                 SinglePlotArea area = ((SinglePlotAreaManager) getPlotAreaManager()).getArea(); | ||||||
| @@ -1321,13 +1307,13 @@ public class PlotSquared { | |||||||
|             } |             } | ||||||
|             this.clustersTmp = DBFunc.getClusters(); |             this.clustersTmp = DBFunc.getClusters(); | ||||||
|             LOGGER.info("Connection to database established. Type: {}", Storage.MySQL.USE ? "MySQL" : "SQLite"); |             LOGGER.info("Connection to database established. Type: {}", Storage.MySQL.USE ? "MySQL" : "SQLite"); | ||||||
|         } catch (ClassNotFoundException | SQLException e) { |         } catch (Exception e) { | ||||||
|             LOGGER.error( |             LOGGER.error( | ||||||
|                     "Failed to open database connection ({}). Disabling PlotSquared", |                     "Failed to open database connection ({}). Disabling PlotSquared", | ||||||
|                     Storage.MySQL.USE ? "MySQL" : "SQLite" |                     Storage.MySQL.USE ? "MySQL" : "SQLite" | ||||||
|             ); |             ); | ||||||
|             LOGGER.error("==== Here is an ugly stacktrace, if you are interested in those things ==="); |             LOGGER.error("==== Here is an ugly stacktrace, if you are interested in those things ==="); | ||||||
|             e.printStackTrace(); |             LOGGER.error("", e); | ||||||
|             LOGGER.error("==== End of stacktrace ===="); |             LOGGER.error("==== End of stacktrace ===="); | ||||||
|             LOGGER.error( |             LOGGER.error( | ||||||
|                     "Please go to the {} 'storage.yml' and configure the database correctly", |                     "Please go to the {} 'storage.yml' and configure the database correctly", | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
| package com.plotsquared.core.command; | package com.plotsquared.core.command; | ||||||
|  |  | ||||||
| import com.google.inject.Inject; | import com.google.inject.Inject; | ||||||
|  | import com.plotsquared.core.PlotSquared; | ||||||
| import com.plotsquared.core.configuration.Settings; | import com.plotsquared.core.configuration.Settings; | ||||||
| import com.plotsquared.core.configuration.caption.TranslatableCaption; | import com.plotsquared.core.configuration.caption.TranslatableCaption; | ||||||
| import com.plotsquared.core.database.DBFunc; | import com.plotsquared.core.database.DBFunc; | ||||||
| @@ -101,8 +102,13 @@ public class Add extends Command { | |||||||
|                                 Permission.PERMISSION_ADMIN_COMMAND_TRUST))) { |                                 Permission.PERMISSION_ADMIN_COMMAND_TRUST))) { | ||||||
|                             player.sendMessage( |                             player.sendMessage( | ||||||
|                                     TranslatableCaption.of("errors.invalid_player"), |                                     TranslatableCaption.of("errors.invalid_player"), | ||||||
|                                     TagResolver.resolver("value", Tag.inserting( |                                     PlotSquared | ||||||
|                                             PlayerManager.resolveName(uuid).toComponent(player) |                                             .platform() | ||||||
|  |                                             .playerManager() | ||||||
|  |                                             .getUsernameCaption(uuid) | ||||||
|  |                                             .thenApply(caption -> TagResolver.resolver( | ||||||
|  |                                                     "value", | ||||||
|  |                                                     Tag.inserting(caption.toComponent(player)) | ||||||
|                                             )) |                                             )) | ||||||
|                             ); |                             ); | ||||||
|                             iterator.remove(); |                             iterator.remove(); | ||||||
| @@ -111,8 +117,10 @@ public class Add extends Command { | |||||||
|                         if (plot.isOwner(uuid)) { |                         if (plot.isOwner(uuid)) { | ||||||
|                             player.sendMessage( |                             player.sendMessage( | ||||||
|                                     TranslatableCaption.of("member.already_added"), |                                     TranslatableCaption.of("member.already_added"), | ||||||
|                                     TagResolver.resolver("player", Tag.inserting( |                                     PlotSquared.platform().playerManager().getUsernameCaption(uuid) | ||||||
|                                             PlayerManager.resolveName(uuid).toComponent(player) |                                             .thenApply(caption -> TagResolver.resolver( | ||||||
|  |                                                     "player", | ||||||
|  |                                                     Tag.inserting(caption.toComponent(player)) | ||||||
|                                             )) |                                             )) | ||||||
|                             ); |                             ); | ||||||
|                             iterator.remove(); |                             iterator.remove(); | ||||||
| @@ -121,8 +129,10 @@ public class Add extends Command { | |||||||
|                         if (plot.getMembers().contains(uuid)) { |                         if (plot.getMembers().contains(uuid)) { | ||||||
|                             player.sendMessage( |                             player.sendMessage( | ||||||
|                                     TranslatableCaption.of("member.already_added"), |                                     TranslatableCaption.of("member.already_added"), | ||||||
|                                     TagResolver.resolver("player", Tag.inserting( |                                     PlotSquared.platform().playerManager().getUsernameCaption(uuid) | ||||||
|                                             PlayerManager.resolveName(uuid).toComponent(player) |                                             .thenApply(caption -> TagResolver.resolver( | ||||||
|  |                                                     "player", | ||||||
|  |                                                     Tag.inserting(caption.toComponent(player)) | ||||||
|                                             )) |                                             )) | ||||||
|                             ); |                             ); | ||||||
|                             iterator.remove(); |                             iterator.remove(); | ||||||
|   | |||||||
| @@ -131,8 +131,8 @@ public class Auto extends SubCommand { | |||||||
|                         player.sendMessage( |                         player.sendMessage( | ||||||
|                                 TranslatableCaption.of("economy.removed_granted_plot"), |                                 TranslatableCaption.of("economy.removed_granted_plot"), | ||||||
|                                 TagResolver.builder() |                                 TagResolver.builder() | ||||||
|                                         .tag("usedGrants", Tag.inserting(Component.text(grantedPlots - left))) |                                         .tag("used_grants", Tag.inserting(Component.text(grantedPlots - left))) | ||||||
|                                         .tag("remainingGrants", Tag.inserting(Component.text(left))) |                                         .tag("remaining_grants", Tag.inserting(Component.text(left))) | ||||||
|                                         .build() |                                         .build() | ||||||
|                         ); |                         ); | ||||||
|                     } |                     } | ||||||
| @@ -294,7 +294,7 @@ public class Auto extends SubCommand { | |||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         if (this.econHandler != null && plotarea.useEconomy()) { |         if (this.econHandler != null && plotarea.useEconomy() && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON)) { | ||||||
|             PlotExpression costExp = plotarea.getPrices().get("claim"); |             PlotExpression costExp = plotarea.getPrices().get("claim"); | ||||||
|             PlotExpression mergeCostExp = plotarea.getPrices().get("merge"); |             PlotExpression mergeCostExp = plotarea.getPrices().get("merge"); | ||||||
|             int size = sizeX * sizeZ; |             int size = sizeX * sizeZ; | ||||||
|   | |||||||
| @@ -141,7 +141,7 @@ public class Claim extends SubCommand { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             if (this.econHandler.isEnabled(area) && !force) { |             if (this.econHandler.isEnabled(area) && !force && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON)) { | ||||||
|                 PlotExpression costExr = area.getPrices().get("claim"); |                 PlotExpression costExr = area.getPrices().get("claim"); | ||||||
|                 double cost = costExr.evaluate(currentPlots); |                 double cost = costExr.evaluate(currentPlots); | ||||||
|                 if (cost > 0d) { |                 if (cost > 0d) { | ||||||
| @@ -186,8 +186,8 @@ public class Claim extends SubCommand { | |||||||
|                 player.sendMessage( |                 player.sendMessage( | ||||||
|                         TranslatableCaption.of("economy.removed_granted_plot"), |                         TranslatableCaption.of("economy.removed_granted_plot"), | ||||||
|                         TagResolver.builder() |                         TagResolver.builder() | ||||||
|                                 .tag("usedGrants", Tag.inserting(Component.text(grants - 1))) |                                 .tag("used_grants", Tag.inserting(Component.text(grants - 1))) | ||||||
|                                 .tag("remainingGrants", Tag.inserting(Component.text(grants))) |                                 .tag("remaining_grants", Tag.inserting(Component.text(grants))) | ||||||
|                                 .build() |                                 .build() | ||||||
|                 ); |                 ); | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ import com.plotsquared.core.player.PlotPlayer; | |||||||
| import net.kyori.adventure.text.Component; | import net.kyori.adventure.text.Component; | ||||||
| import net.kyori.adventure.text.minimessage.MiniMessage; | import net.kyori.adventure.text.minimessage.MiniMessage; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  | import org.jetbrains.annotations.NotNull; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * CommandCategory. |  * CommandCategory. | ||||||
| @@ -82,7 +83,7 @@ public enum CommandCategory implements Caption { | |||||||
|     // TODO this method shouldn't be invoked |     // TODO this method shouldn't be invoked | ||||||
|     @Deprecated |     @Deprecated | ||||||
|     @Override |     @Override | ||||||
|     public String toString() { |     public @NotNull String toString() { | ||||||
|         return this.caption.getComponent(LocaleHolder.console()); |         return this.caption.getComponent(LocaleHolder.console()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -108,4 +109,5 @@ public enum CommandCategory implements Caption { | |||||||
|         return !MainCommand.getInstance().getCommands(this, player).isEmpty(); |         return !MainCommand.getInstance().getCommands(this, player).isEmpty(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -29,7 +29,6 @@ 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.entity.EntityCategory; | import com.plotsquared.core.util.entity.EntityCategory; | ||||||
| import com.plotsquared.core.util.query.PlotQuery; | import com.plotsquared.core.util.query.PlotQuery; | ||||||
| import com.plotsquared.core.util.task.TaskManager; |  | ||||||
| import com.plotsquared.core.uuid.UUIDMapping; | import com.plotsquared.core.uuid.UUIDMapping; | ||||||
| import com.sk89q.worldedit.world.entity.EntityType; | import com.sk89q.worldedit.world.entity.EntityType; | ||||||
| import net.kyori.adventure.text.Component; | import net.kyori.adventure.text.Component; | ||||||
| @@ -71,7 +70,7 @@ public class Debug extends SubCommand { | |||||||
|                     TranslatableCaption.of("commandconfig.command_syntax"), |                     TranslatableCaption.of("commandconfig.command_syntax"), | ||||||
|                     TagResolver.resolver( |                     TagResolver.resolver( | ||||||
|                             "value", |                             "value", | ||||||
|                             Tag.inserting(Component.text("/plot debug <loadedchunks | player | debug-players | entitytypes | msg>")) |                             Tag.inserting(Component.text("/plot debug <player | debug-players | entitytypes | msg>")) | ||||||
|                     ) |                     ) | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
| @@ -85,16 +84,6 @@ public class Debug extends SubCommand { | |||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         if (args.length > 0 && "loadedchunks".equalsIgnoreCase(args[0])) { |  | ||||||
|             final long start = System.currentTimeMillis(); |  | ||||||
|             player.sendMessage(TranslatableCaption.of("debug.fetching_loaded_chunks")); |  | ||||||
|             TaskManager.runTaskAsync(() -> player.sendMessage(StaticCaption |  | ||||||
|                     .of("Loaded chunks: " + this.worldUtil |  | ||||||
|                             .getChunkChunks(player.getLocation().getWorldName()) |  | ||||||
|                             .size() + " (" + (System.currentTimeMillis() |  | ||||||
|                             - start) + "ms) using thread: " + Thread.currentThread().getName()))); |  | ||||||
|             return true; |  | ||||||
|         } |  | ||||||
|         if (args.length > 0 && "uuids".equalsIgnoreCase(args[0])) { |         if (args.length > 0 && "uuids".equalsIgnoreCase(args[0])) { | ||||||
|             final Collection<UUIDMapping> mappings = PlotSquared.get().getImpromptuUUIDPipeline().getAllImmediately(); |             final Collection<UUIDMapping> mappings = PlotSquared.get().getImpromptuUUIDPipeline().getAllImmediately(); | ||||||
|             player.sendMessage( |             player.sendMessage( | ||||||
| @@ -196,7 +185,7 @@ public class Debug extends SubCommand { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Collection<Command> tab(final PlotPlayer<?> player, String[] args, boolean space) { |     public Collection<Command> tab(final PlotPlayer<?> player, String[] args, boolean space) { | ||||||
|         return Stream.of("loadedchunks", "debug-players", "entitytypes") |         return Stream.of("debug-players", "entitytypes") | ||||||
|                 .filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH))) |                 .filter(value -> value.startsWith(args[0].toLowerCase(Locale.ENGLISH))) | ||||||
|                 .map(value -> new Command(null, false, value, "plots.admin", RequiredType.NONE, null) { |                 .map(value -> new Command(null, false, value, "plots.admin", RequiredType.NONE, null) { | ||||||
|                 }).collect(Collectors.toList()); |                 }).collect(Collectors.toList()); | ||||||
|   | |||||||
| @@ -96,6 +96,7 @@ public class DebugRoadRegen extends SubCommand { | |||||||
|         PlotArea area = location.getPlotArea(); |         PlotArea area = location.getPlotArea(); | ||||||
|         if (area == null) { |         if (area == null) { | ||||||
|             player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world")); |             player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world")); | ||||||
|  |             return false; | ||||||
|         } |         } | ||||||
|         Plot plot = player.getCurrentPlot(); |         Plot plot = player.getCurrentPlot(); | ||||||
|         if (plot == null) { |         if (plot == null) { | ||||||
|   | |||||||
| @@ -117,10 +117,11 @@ public class Deny extends SubCommand { | |||||||
|                     } else if (plot.getDenied().contains(uuid)) { |                     } else if (plot.getDenied().contains(uuid)) { | ||||||
|                         player.sendMessage( |                         player.sendMessage( | ||||||
|                                 TranslatableCaption.of("member.already_added"), |                                 TranslatableCaption.of("member.already_added"), | ||||||
|                                 TagResolver.resolver( |                                 PlotSquared.platform().playerManager().getUsernameCaption(uuid) | ||||||
|  |                                         .thenApply(caption -> TagResolver.resolver( | ||||||
|                                         "player", |                                         "player", | ||||||
|                                         Tag.inserting(PlayerManager.resolveName(uuid).toComponent(player)) |                                         Tag.inserting(caption.toComponent(player)) | ||||||
|                                 ) |                                 )) | ||||||
|                         ); |                         ); | ||||||
|                         return; |                         return; | ||||||
|                     } else { |                     } else { | ||||||
|   | |||||||
| @@ -517,6 +517,7 @@ public class ListCmd extends SubCommand { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 finalResolver.tag("players", Tag.inserting(builder.asComponent())); |                 finalResolver.tag("players", Tag.inserting(builder.asComponent())); | ||||||
|  |                 finalResolver.tag("size", Tag.inserting(Component.text(plot.getConnectedPlots().size()))); | ||||||
|                 caption.set(TranslatableCaption.of("info.plot_list_item")); |                 caption.set(TranslatableCaption.of("info.plot_list_item")); | ||||||
|                 caption.setTagResolvers(finalResolver.build()); |                 caption.setTagResolvers(finalResolver.build()); | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -41,6 +41,7 @@ import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; | |||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
| import java.net.MalformedURLException; | import java.net.MalformedURLException; | ||||||
|  | import java.net.URI; | ||||||
| import java.net.URL; | import java.net.URL; | ||||||
| import java.util.Collections; | import java.util.Collections; | ||||||
| import java.util.List; | import java.util.List; | ||||||
| @@ -116,7 +117,7 @@ public class Load extends SubCommand { | |||||||
|                     } |                     } | ||||||
|                     final URL url; |                     final URL url; | ||||||
|                     try { |                     try { | ||||||
|                         url = new URL(Settings.Web.URL + "saves/" + player.getUUID() + '/' + schematic); |                         url = URI.create(Settings.Web.URL + "saves/" + player.getUUID() + '/' + schematic).toURL(); | ||||||
|                     } catch (MalformedURLException e) { |                     } catch (MalformedURLException e) { | ||||||
|                         e.printStackTrace(); |                         e.printStackTrace(); | ||||||
|                         player.sendMessage(TranslatableCaption.of("web.load_failed")); |                         player.sendMessage(TranslatableCaption.of("web.load_failed")); | ||||||
|   | |||||||
| @@ -183,7 +183,7 @@ public class MainCommand extends Command { | |||||||
|                     if (cmd.hasConfirmation(player)) { |                     if (cmd.hasConfirmation(player)) { | ||||||
|                         CmdConfirm.addPending(player, cmd.getUsage(), () -> { |                         CmdConfirm.addPending(player, cmd.getUsage(), () -> { | ||||||
|                             PlotArea area = player.getApplicablePlotArea(); |                             PlotArea area = player.getApplicablePlotArea(); | ||||||
|                             if (area != null && econHandler.isEnabled(area)) { |                             if (area != null && econHandler.isEnabled(area) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON)) { | ||||||
|                                 PlotExpression priceEval = |                                 PlotExpression priceEval = | ||||||
|                                         area.getPrices().get(cmd.getFullId()); |                                         area.getPrices().get(cmd.getFullId()); | ||||||
|                                 double price = priceEval != null ? priceEval.evaluate(0d) : 0d; |                                 double price = priceEval != null ? priceEval.evaluate(0d) : 0d; | ||||||
| @@ -201,7 +201,7 @@ public class MainCommand extends Command { | |||||||
|                         return; |                         return; | ||||||
|                     } |                     } | ||||||
|                     PlotArea area = player.getApplicablePlotArea(); |                     PlotArea area = player.getApplicablePlotArea(); | ||||||
|                     if (area != null && econHandler.isEnabled(area)) { |                     if (area != null && econHandler.isEnabled(area) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON)) { | ||||||
|                         PlotExpression priceEval = area.getPrices().get(cmd.getFullId()); |                         PlotExpression priceEval = area.getPrices().get(cmd.getFullId()); | ||||||
|                         double price = priceEval != null ? priceEval.evaluate(0d) : 0d; |                         double price = priceEval != null ? priceEval.evaluate(0d) : 0d; | ||||||
|                         if (price != 0d && econHandler.getMoney(player) < price) { |                         if (price != 0d && econHandler.getMoney(player) < price) { | ||||||
|   | |||||||
| @@ -109,7 +109,7 @@ public class Merge extends SubCommand { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             if (direction == null && (args[0].equalsIgnoreCase("all") || args[0] |             if (direction == null && (args[0].equalsIgnoreCase("all") || args[0] | ||||||
|                     .equalsIgnoreCase("auto"))) { |                     .equalsIgnoreCase("auto")) && player.hasPermission(Permission.PERMISSION_MERGE_ALL)) { | ||||||
|                 direction = Direction.ALL; |                 direction = Direction.ALL; | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
| @@ -178,7 +178,7 @@ public class Merge extends SubCommand { | |||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|             if (plot.getPlotModificationManager().autoMerge(Direction.ALL, maxSize, uuid, player, terrain)) { |             if (plot.getPlotModificationManager().autoMerge(Direction.ALL, maxSize, uuid, player, terrain)) { | ||||||
|                 if (this.econHandler.isEnabled(plotArea) && price > 0d) { |                 if (this.econHandler.isEnabled(plotArea) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON) && price > 0d) { | ||||||
|                     this.econHandler.withdrawMoney(player, price); |                     this.econHandler.withdrawMoney(player, price); | ||||||
|                     player.sendMessage( |                     player.sendMessage( | ||||||
|                             TranslatableCaption.of("economy.removed_balance"), |                             TranslatableCaption.of("economy.removed_balance"), | ||||||
| @@ -196,8 +196,8 @@ public class Merge extends SubCommand { | |||||||
|             player.sendMessage(TranslatableCaption.of("merge.no_available_automerge")); |             player.sendMessage(TranslatableCaption.of("merge.no_available_automerge")); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         if (!force && this.econHandler.isEnabled(plotArea) && price > 0d |         if (!force && this.econHandler.isEnabled(plotArea) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON) && price > 0d && this.econHandler.getMoney( | ||||||
|                 && this.econHandler.getMoney(player) < price) { |                 player) < price) { | ||||||
|             player.sendMessage( |             player.sendMessage( | ||||||
|                     TranslatableCaption.of("economy.cannot_afford_merge"), |                     TranslatableCaption.of("economy.cannot_afford_merge"), | ||||||
|                     TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price)))) |                     TagResolver.resolver("money", Tag.inserting(Component.text(this.econHandler.format(price)))) | ||||||
| @@ -218,7 +218,7 @@ public class Merge extends SubCommand { | |||||||
|             return true; |             return true; | ||||||
|         } |         } | ||||||
|         if (plot.getPlotModificationManager().autoMerge(direction, maxSize - size, uuid, player, terrain)) { |         if (plot.getPlotModificationManager().autoMerge(direction, maxSize - size, uuid, player, terrain)) { | ||||||
|             if (this.econHandler.isEnabled(plotArea) && price > 0d) { |             if (this.econHandler.isEnabled(plotArea) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON) && price > 0d) { | ||||||
|                 this.econHandler.withdrawMoney(player, price); |                 this.econHandler.withdrawMoney(player, price); | ||||||
|                 player.sendMessage( |                 player.sendMessage( | ||||||
|                         TranslatableCaption.of("economy.removed_balance"), |                         TranslatableCaption.of("economy.removed_balance"), | ||||||
| @@ -259,7 +259,7 @@ public class Merge extends SubCommand { | |||||||
|                     accepter.sendMessage(TranslatableCaption.of("merge.merge_not_valid")); |                     accepter.sendMessage(TranslatableCaption.of("merge.merge_not_valid")); | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|                 if (this.econHandler.isEnabled(plotArea) && price > 0d) { |                 if (this.econHandler.isEnabled(plotArea) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON) && price > 0d) { | ||||||
|                     if (!force && this.econHandler.getMoney(player) < price) { |                     if (!force && this.econHandler.getMoney(player) < price) { | ||||||
|                         player.sendMessage( |                         player.sendMessage( | ||||||
|                                 TranslatableCaption.of("economy.cannot_afford_merge"), |                                 TranslatableCaption.of("economy.cannot_afford_merge"), | ||||||
| @@ -303,7 +303,7 @@ public class Merge extends SubCommand { | |||||||
|                         player, |                         player, | ||||||
|                         terrain |                         terrain | ||||||
|                 )) { |                 )) { | ||||||
|                     if (this.econHandler.isEnabled(plotArea) && price > 0d) { |                     if (this.econHandler.isEnabled(plotArea) && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON) && price > 0d) { | ||||||
|                         if (!force && this.econHandler.getMoney(player) < price) { |                         if (!force && this.econHandler.getMoney(player) < price) { | ||||||
|                             player.sendMessage( |                             player.sendMessage( | ||||||
|                                     TranslatableCaption.of("economy.cannot_afford_merge"), |                                     TranslatableCaption.of("economy.cannot_afford_merge"), | ||||||
|   | |||||||
| @@ -31,7 +31,6 @@ import com.plotsquared.core.player.PlayerMetaDataKeys; | |||||||
| import com.plotsquared.core.player.PlotPlayer; | import com.plotsquared.core.player.PlotPlayer; | ||||||
| import com.plotsquared.core.plot.Plot; | import com.plotsquared.core.plot.Plot; | ||||||
| import com.plotsquared.core.util.EventDispatcher; | import com.plotsquared.core.util.EventDispatcher; | ||||||
| import com.plotsquared.core.util.PlayerManager; |  | ||||||
| import com.plotsquared.core.util.TabCompletions; | import com.plotsquared.core.util.TabCompletions; | ||||||
| import com.plotsquared.core.util.task.TaskManager; | import com.plotsquared.core.util.task.TaskManager; | ||||||
| import net.kyori.adventure.text.Component; | import net.kyori.adventure.text.Component; | ||||||
| @@ -136,10 +135,11 @@ public class Owner extends SetCommand { | |||||||
|             if (plot.isOwner(uuid)) { |             if (plot.isOwner(uuid)) { | ||||||
|                 player.sendMessage( |                 player.sendMessage( | ||||||
|                         TranslatableCaption.of("member.already_owner"), |                         TranslatableCaption.of("member.already_owner"), | ||||||
|                         TagResolver.resolver( |                         PlotSquared.platform().playerManager().getUsernameCaption(uuid) | ||||||
|  |                                 .thenApply(caption -> TagResolver.resolver( | ||||||
|                                 "player", |                                 "player", | ||||||
|                                 Tag.inserting(PlayerManager.resolveName(uuid, false).toComponent(player)) |                                 Tag.inserting(caption.toComponent(player)) | ||||||
|                         ) |                         )) | ||||||
|                 ); |                 ); | ||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
| @@ -147,10 +147,11 @@ public class Owner extends SetCommand { | |||||||
|                 if (other == null) { |                 if (other == null) { | ||||||
|                     player.sendMessage( |                     player.sendMessage( | ||||||
|                             TranslatableCaption.of("errors.invalid_player_offline"), |                             TranslatableCaption.of("errors.invalid_player_offline"), | ||||||
|                             TagResolver.resolver( |                             PlotSquared.platform().playerManager().getUsernameCaption(uuid) | ||||||
|  |                                     .thenApply(caption -> TagResolver.resolver( | ||||||
|                                     "player", |                                     "player", | ||||||
|                                     Tag.inserting(PlayerManager.resolveName(uuid).toComponent(player)) |                                     Tag.inserting(caption.toComponent(player)) | ||||||
|                             ) |                             )) | ||||||
|                     ); |                     ); | ||||||
|                     return; |                     return; | ||||||
|                 } |                 } | ||||||
|   | |||||||
| @@ -40,6 +40,7 @@ import net.kyori.adventure.text.minimessage.tag.Tag; | |||||||
| import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; | import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  |  | ||||||
|  | import java.net.URI; | ||||||
| import java.net.URL; | import java.net.URL; | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| @@ -130,8 +131,7 @@ public class SchematicCmd extends SubCommand { | |||||||
|                     if (location.startsWith("url:")) { |                     if (location.startsWith("url:")) { | ||||||
|                         try { |                         try { | ||||||
|                             UUID uuid = UUID.fromString(location.substring(4)); |                             UUID uuid = UUID.fromString(location.substring(4)); | ||||||
|                             URL base = new URL(Settings.Web.URL); |                             URL url = URI.create(Settings.Web.URL + "uploads/" + uuid + ".schematic").toURL(); | ||||||
|                             URL url = new URL(base, "uploads/" + uuid + ".schematic"); |  | ||||||
|                             schematic = this.schematicHandler.getSchematic(url); |                             schematic = this.schematicHandler.getSchematic(url); | ||||||
|                         } catch (Exception e) { |                         } catch (Exception e) { | ||||||
|                             e.printStackTrace(); |                             e.printStackTrace(); | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
| package com.plotsquared.core.command; | package com.plotsquared.core.command; | ||||||
|  |  | ||||||
| import com.google.inject.Inject; | import com.google.inject.Inject; | ||||||
|  | import com.plotsquared.core.PlotSquared; | ||||||
| import com.plotsquared.core.configuration.Settings; | import com.plotsquared.core.configuration.Settings; | ||||||
| import com.plotsquared.core.configuration.caption.TranslatableCaption; | import com.plotsquared.core.configuration.caption.TranslatableCaption; | ||||||
| import com.plotsquared.core.database.DBFunc; | import com.plotsquared.core.database.DBFunc; | ||||||
| @@ -103,10 +104,11 @@ public class Trust extends Command { | |||||||
|                             player.hasPermission(Permission.PERMISSION_TRUST_EVERYONE) || player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_TRUST))) { |                             player.hasPermission(Permission.PERMISSION_TRUST_EVERYONE) || player.hasPermission(Permission.PERMISSION_ADMIN_COMMAND_TRUST))) { | ||||||
|                         player.sendMessage( |                         player.sendMessage( | ||||||
|                                 TranslatableCaption.of("errors.invalid_player"), |                                 TranslatableCaption.of("errors.invalid_player"), | ||||||
|                                 TagResolver.resolver( |                                 PlotSquared.platform().playerManager().getUsernameCaption(uuid) | ||||||
|  |                                         .thenApply(caption -> TagResolver.resolver( | ||||||
|                                         "value", |                                         "value", | ||||||
|                                         Tag.inserting(PlayerManager.resolveName(uuid).toComponent(player)) |                                         Tag.inserting(caption.toComponent(player)) | ||||||
|                                 ) |                                 )) | ||||||
|                         ); |                         ); | ||||||
|                         iterator.remove(); |                         iterator.remove(); | ||||||
|                         continue; |                         continue; | ||||||
| @@ -114,10 +116,11 @@ public class Trust extends Command { | |||||||
|                     if (currentPlot.isOwner(uuid)) { |                     if (currentPlot.isOwner(uuid)) { | ||||||
|                         player.sendMessage( |                         player.sendMessage( | ||||||
|                                 TranslatableCaption.of("member.already_added"), |                                 TranslatableCaption.of("member.already_added"), | ||||||
|                                 TagResolver.resolver( |                                 PlotSquared.platform().playerManager().getUsernameCaption(uuid) | ||||||
|                                         "value", |                                         .thenApply(caption -> TagResolver.resolver( | ||||||
|                                         Tag.inserting(PlayerManager.resolveName(uuid).toComponent(player)) |                                         "player", | ||||||
|                                 ) |                                         Tag.inserting(caption.toComponent(player)) | ||||||
|  |                                 )) | ||||||
|                         ); |                         ); | ||||||
|                         iterator.remove(); |                         iterator.remove(); | ||||||
|                         continue; |                         continue; | ||||||
| @@ -125,10 +128,11 @@ public class Trust extends Command { | |||||||
|                     if (currentPlot.getTrusted().contains(uuid)) { |                     if (currentPlot.getTrusted().contains(uuid)) { | ||||||
|                         player.sendMessage( |                         player.sendMessage( | ||||||
|                                 TranslatableCaption.of("member.already_added"), |                                 TranslatableCaption.of("member.already_added"), | ||||||
|                                 TagResolver.resolver( |                                 PlotSquared.platform().playerManager().getUsernameCaption(uuid) | ||||||
|                                         "value", |                                         .thenApply(caption -> TagResolver.resolver( | ||||||
|                                         Tag.inserting(PlayerManager.resolveName(uuid).toComponent(player)) |                                         "player", | ||||||
|                                 ) |                                         Tag.inserting(caption.toComponent(player)) | ||||||
|  |                                 )) | ||||||
|                         ); |                         ); | ||||||
|                         iterator.remove(); |                         iterator.remove(); | ||||||
|                         continue; |                         continue; | ||||||
|   | |||||||
| @@ -206,7 +206,7 @@ public class ComponentPresetManager { | |||||||
|                     return false; |                     return false; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 if (componentPreset.cost() > 0.0D) { |                 if (componentPreset.cost() > 0.0D && !player.hasPermission(Permission.PERMISSION_ADMIN_BYPASS_ECON)) { | ||||||
|                     if (!econHandler.isEnabled(plot.getArea())) { |                     if (!econHandler.isEnabled(plot.getArea())) { | ||||||
|                         getPlayer().sendMessage( |                         getPlayer().sendMessage( | ||||||
|                                 TranslatableCaption.of("preset.economy_disabled"), |                                 TranslatableCaption.of("preset.economy_disabled"), | ||||||
|   | |||||||
| @@ -44,4 +44,6 @@ public interface Caption { | |||||||
|      */ |      */ | ||||||
|     @NonNull Component toComponent(@NonNull LocaleHolder localeHolder); |     @NonNull Component toComponent(@NonNull LocaleHolder localeHolder); | ||||||
|  |  | ||||||
|  |     @NonNull String toString(); | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -51,4 +51,9 @@ public final class StaticCaption implements Caption { | |||||||
|         return MiniMessage.miniMessage().deserialize(this.value); |         return MiniMessage.miniMessage().deserialize(this.value); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public @NonNull String toString() { | ||||||
|  |         return "StaticCaption(" + value + ")"; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ import net.kyori.adventure.text.minimessage.MiniMessage; | |||||||
| import net.kyori.adventure.text.minimessage.tag.Tag; | import net.kyori.adventure.text.minimessage.tag.Tag; | ||||||
| import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; | import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
|  | import org.jetbrains.annotations.NotNull; | ||||||
|  |  | ||||||
| import java.util.Locale; | import java.util.Locale; | ||||||
| import java.util.regex.Pattern; | import java.util.regex.Pattern; | ||||||
| @@ -132,4 +133,9 @@ public final class TranslatableCaption implements NamespacedCaption { | |||||||
|         return Objects.hashCode(this.getNamespace(), this.getKey()); |         return Objects.hashCode(this.getNamespace(), this.getKey()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public @NotNull String toString() { | ||||||
|  |         return "TranslatableCaption(" + getNamespace() + ":" + getKey() + ")"; | ||||||
|  |     } | ||||||
|  |  | ||||||
| } | } | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ import java.sql.Statement; | |||||||
|  * @author -_Husky_- |  * @author -_Husky_- | ||||||
|  * @author tips48 |  * @author tips48 | ||||||
|  */ |  */ | ||||||
|  | @Deprecated(forRemoval = true) | ||||||
| public abstract class Database { | public abstract class Database { | ||||||
|  |  | ||||||
|     public abstract Connection forceConnection() throws SQLException, ClassNotFoundException; |     public abstract Connection forceConnection() throws SQLException, ClassNotFoundException; | ||||||
|   | |||||||
| @@ -33,6 +33,7 @@ import java.sql.Statement; | |||||||
|  * @author -_Husky_- |  * @author -_Husky_- | ||||||
|  * @author tips48 |  * @author tips48 | ||||||
|  */ |  */ | ||||||
|  | @Deprecated(forRemoval = true) | ||||||
| public class MySQL extends Database { | public class MySQL extends Database { | ||||||
|  |  | ||||||
|     private final String user; |     private final String user; | ||||||
|   | |||||||
| @@ -25,6 +25,7 @@ import com.plotsquared.core.configuration.Settings; | |||||||
| import com.plotsquared.core.configuration.Storage; | import com.plotsquared.core.configuration.Storage; | ||||||
| import com.plotsquared.core.configuration.caption.CaptionUtility; | import com.plotsquared.core.configuration.caption.CaptionUtility; | ||||||
| import com.plotsquared.core.configuration.file.YamlConfiguration; | import com.plotsquared.core.configuration.file.YamlConfiguration; | ||||||
|  | import com.plotsquared.core.inject.annotations.PlotDatabase; | ||||||
| import com.plotsquared.core.inject.annotations.WorldConfig; | import com.plotsquared.core.inject.annotations.WorldConfig; | ||||||
| import com.plotsquared.core.listener.PlotListener; | import com.plotsquared.core.listener.PlotListener; | ||||||
| import com.plotsquared.core.location.BlockLoc; | import com.plotsquared.core.location.BlockLoc; | ||||||
| @@ -44,10 +45,14 @@ import com.plotsquared.core.util.HashUtil; | |||||||
| import com.plotsquared.core.util.StringMan; | import com.plotsquared.core.util.StringMan; | ||||||
| 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 jakarta.inject.Inject; | ||||||
| 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.sql.DataSource; | ||||||
|  | import java.io.Closeable; | ||||||
| import java.sql.Connection; | import java.sql.Connection; | ||||||
| import java.sql.DatabaseMetaData; | import java.sql.DatabaseMetaData; | ||||||
| import java.sql.PreparedStatement; | import java.sql.PreparedStatement; | ||||||
| @@ -92,12 +97,12 @@ public class SQLManager implements AbstractDB { | |||||||
|  |  | ||||||
|     // Private Final |     // Private Final | ||||||
|     private final String prefix; |     private final String prefix; | ||||||
|     private final Database database; |  | ||||||
|     private final boolean mySQL; |     private final boolean mySQL; | ||||||
|     @SuppressWarnings({"unused", "FieldCanBeLocal"}) |     @SuppressWarnings({"unused", "FieldCanBeLocal"}) | ||||||
|     private final EventDispatcher eventDispatcher; |     private final EventDispatcher eventDispatcher; | ||||||
|     @SuppressWarnings({"unused", "FieldCanBeLocal"}) |     @SuppressWarnings({"unused", "FieldCanBeLocal"}) | ||||||
|     private final PlotListener plotListener; |     private final PlotListener plotListener; | ||||||
|  |     private final DataSource dataSource; | ||||||
|     private final YamlConfiguration worldConfiguration; |     private final YamlConfiguration worldConfiguration; | ||||||
|     /** |     /** | ||||||
|      * important tasks |      * important tasks | ||||||
| @@ -129,20 +134,12 @@ public class SQLManager implements AbstractDB { | |||||||
|      */ |      */ | ||||||
|     public volatile ConcurrentHashMap<PlotCluster, Queue<UniqueStatement>> clusterTasks; |     public volatile ConcurrentHashMap<PlotCluster, Queue<UniqueStatement>> clusterTasks; | ||||||
|     // Private |     // Private | ||||||
|     private Connection connection; |     private boolean supportsGetGeneratedKeys; | ||||||
|     private boolean closed = false; |     private boolean closed = false; | ||||||
|  |  | ||||||
|     /** |     @Inject | ||||||
|      * Constructor |  | ||||||
|      * |  | ||||||
|      * @param database |  | ||||||
|      * @param prefix   prefix |  | ||||||
|      * @throws SQLException |  | ||||||
|      * @throws ClassNotFoundException |  | ||||||
|      */ |  | ||||||
|     public SQLManager( |     public SQLManager( | ||||||
|             final @NonNull Database database, |             final @NonNull @PlotDatabase DataSource dataSource, | ||||||
|             final @NonNull String prefix, |  | ||||||
|             final @NonNull EventDispatcher eventDispatcher, |             final @NonNull EventDispatcher eventDispatcher, | ||||||
|             final @NonNull PlotListener plotListener, |             final @NonNull PlotListener plotListener, | ||||||
|             @WorldConfig final @NonNull YamlConfiguration worldConfiguration |             @WorldConfig final @NonNull YamlConfiguration worldConfiguration | ||||||
| @@ -152,15 +149,27 @@ public class SQLManager implements AbstractDB { | |||||||
|         this.eventDispatcher = eventDispatcher; |         this.eventDispatcher = eventDispatcher; | ||||||
|         this.plotListener = plotListener; |         this.plotListener = plotListener; | ||||||
|         this.worldConfiguration = worldConfiguration; |         this.worldConfiguration = worldConfiguration; | ||||||
|         this.database = database; |         this.dataSource = dataSource; | ||||||
|         this.connection = database.openConnection(); |         this.mySQL = Storage.MySQL.USE; | ||||||
|         this.mySQL = database instanceof MySQL; |  | ||||||
|         this.globalTasks = new ConcurrentLinkedQueue<>(); |         this.globalTasks = new ConcurrentLinkedQueue<>(); | ||||||
|         this.notifyTasks = new ConcurrentLinkedQueue<>(); |         this.notifyTasks = new ConcurrentLinkedQueue<>(); | ||||||
|         this.plotTasks = new ConcurrentHashMap<>(); |         this.plotTasks = new ConcurrentHashMap<>(); | ||||||
|         this.playerTasks = new ConcurrentHashMap<>(); |         this.playerTasks = new ConcurrentHashMap<>(); | ||||||
|         this.clusterTasks = new ConcurrentHashMap<>(); |         this.clusterTasks = new ConcurrentHashMap<>(); | ||||||
|         this.prefix = prefix; |         this.prefix = Storage.PREFIX; | ||||||
|  |  | ||||||
|  |         try (final Connection connection = dataSource.getConnection()) { | ||||||
|  |             final DatabaseMetaData metaData = connection.getMetaData(); | ||||||
|  |             this.supportsGetGeneratedKeys = metaData.supportsGetGeneratedKeys(); | ||||||
|  |  | ||||||
|  |             if (this.mySQL && !this.supportsGetGeneratedKeys) { | ||||||
|  |                 final String driver = metaData.getDriverName(); | ||||||
|  |                 final String driverVersion = metaData.getDriverVersion(); | ||||||
|  |                 throw new SQLException("Database Driver for MySQL does not support Statement#getGeneratedKeys - which breaks " + | ||||||
|  |                         "PlotSquared functionality (Using " + driver + ":" + driverVersion + ")"); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|         this.SET_OWNER = "UPDATE `" + this.prefix |         this.SET_OWNER = "UPDATE `" + this.prefix | ||||||
|                 + "plot` SET `owner` = ? WHERE `plot_id_x` = ? AND `plot_id_z` = ? AND `world` = ?"; |                 + "plot` SET `owner` = ? WHERE `plot_id_x` = ? AND `plot_id_z` = ? AND `world` = ?"; | ||||||
|         this.GET_ALL_PLOTS = |         this.GET_ALL_PLOTS = | ||||||
| @@ -171,20 +180,32 @@ public class SQLManager implements AbstractDB { | |||||||
|                 "INSERT INTO `" + this.prefix + "plot_settings` (`plot_plot_id`) values "; |                 "INSERT INTO `" + this.prefix + "plot_settings` (`plot_plot_id`) values "; | ||||||
|         this.CREATE_TIERS = |         this.CREATE_TIERS = | ||||||
|                 "INSERT INTO `" + this.prefix + "plot_%tier%` (`plot_plot_id`, `user_uuid`) values "; |                 "INSERT INTO `" + this.prefix + "plot_%tier%` (`plot_plot_id`, `user_uuid`) values "; | ||||||
|         this.CREATE_PLOT = "INSERT INTO `" + this.prefix |         String tempCreatePlot = "INSERT INTO `" + this.prefix | ||||||
|                 + "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) VALUES(?, ?, ?, ?, ?)"; |                 + "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) VALUES(?, ?, ?, ?, ?)"; | ||||||
|  |         if (!supportsGetGeneratedKeys) { | ||||||
|  |             tempCreatePlot += " RETURNING `id`"; | ||||||
|  |         } | ||||||
|  |         this.CREATE_PLOT = tempCreatePlot; | ||||||
|         if (mySQL) { |         if (mySQL) { | ||||||
|             this.CREATE_PLOT_SAFE = "INSERT IGNORE INTO `" + this.prefix |             this.CREATE_PLOT_SAFE = "INSERT IGNORE INTO `" + this.prefix | ||||||
|                     + "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) SELECT ?, ?, ?, ?, ? FROM DUAL WHERE NOT EXISTS (SELECT null FROM `" |                     + "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) SELECT ?, ?, ?, ?, ? FROM DUAL WHERE NOT EXISTS (SELECT null FROM `" | ||||||
|                     + this.prefix + "plot` WHERE `world` = ? AND `plot_id_x` = ? AND `plot_id_z` = ?)"; |                     + this.prefix + "plot` WHERE `world` = ? AND `plot_id_x` = ? AND `plot_id_z` = ?)"; | ||||||
|         } else { |         } else { | ||||||
|             this.CREATE_PLOT_SAFE = "INSERT INTO `" + this.prefix |             String tempCreatePlotSafe = "INSERT INTO `" + this.prefix | ||||||
|                     + "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) SELECT ?, ?, ?, ?, ? WHERE NOT EXISTS (SELECT null FROM `" |                     + "plot`(`plot_id_x`, `plot_id_z`, `owner`, `world`, `timestamp`) SELECT ?, ?, ?, ?, ? WHERE NOT EXISTS (SELECT null FROM `" | ||||||
|                     + this.prefix + "plot` WHERE `world` = ? AND `plot_id_x` = ? AND `plot_id_z` = ?)"; |                     + this.prefix + "plot` WHERE `world` = ? AND `plot_id_x` = ? AND `plot_id_z` = ?)"; | ||||||
|  |             if (!supportsGetGeneratedKeys) { | ||||||
|  |                 tempCreatePlotSafe += " RETURNING `id`"; | ||||||
|             } |             } | ||||||
|         this.CREATE_CLUSTER = "INSERT INTO `" + this.prefix |             this.CREATE_PLOT_SAFE = tempCreatePlotSafe; | ||||||
|  |         } | ||||||
|  |         String tempCreateCluster = "INSERT INTO `" + this.prefix | ||||||
|                 + "cluster`(`pos1_x`, `pos1_z`, `pos2_x`, `pos2_z`, `owner`, `world`) VALUES(?, ?, ?, ?, ?, ?)"; |                 + "cluster`(`pos1_x`, `pos1_z`, `pos2_x`, `pos2_z`, `owner`, `world`) VALUES(?, ?, ?, ?, ?, ?)"; | ||||||
|  |         if (!supportsGetGeneratedKeys) { | ||||||
|  |             tempCreateCluster += " RETURNING `id`"; | ||||||
|  |         } | ||||||
|  |         this.CREATE_CLUSTER = tempCreateCluster; | ||||||
|  |  | ||||||
|         try { |         try { | ||||||
|             createTables(); |             createTables(); | ||||||
|         } catch (SQLException e) { |         } catch (SQLException e) { | ||||||
| @@ -197,11 +218,6 @@ public class SQLManager implements AbstractDB { | |||||||
|                         !globalTasks.isEmpty() || !playerTasks.isEmpty() || !plotTasks.isEmpty() |                         !globalTasks.isEmpty() || !playerTasks.isEmpty() || !plotTasks.isEmpty() | ||||||
|                                 || !clusterTasks.isEmpty(); |                                 || !clusterTasks.isEmpty(); | ||||||
|                 if (hasTask) { |                 if (hasTask) { | ||||||
|                     if (SQLManager.this.mySQL && System.currentTimeMillis() - last > 550000 |  | ||||||
|                             || !isValid()) { |  | ||||||
|                         last = System.currentTimeMillis(); |  | ||||||
|                         reconnect(); |  | ||||||
|                     } |  | ||||||
|                     if (!sendBatch()) { |                     if (!sendBatch()) { | ||||||
|                         try { |                         try { | ||||||
|                             if (!getNotifyTasks().isEmpty()) { |                             if (!getNotifyTasks().isEmpty()) { | ||||||
| @@ -226,32 +242,6 @@ public class SQLManager implements AbstractDB { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public boolean isValid() { |  | ||||||
|         try { |  | ||||||
|             if (connection.isClosed()) { |  | ||||||
|                 return false; |  | ||||||
|             } |  | ||||||
|         } catch (SQLException e) { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|         try (PreparedStatement stmt = this.connection.prepareStatement("SELECT 1")) { |  | ||||||
|             stmt.execute(); |  | ||||||
|             return true; |  | ||||||
|         } catch (Throwable e) { |  | ||||||
|             return false; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public void reconnect() { |  | ||||||
|         try { |  | ||||||
|             close(); |  | ||||||
|             SQLManager.this.closed = false; |  | ||||||
|             SQLManager.this.connection = database.forceConnection(); |  | ||||||
|         } catch (SQLException | ClassNotFoundException e) { |  | ||||||
|             e.printStackTrace(); |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public synchronized Queue<Runnable> getGlobalTasks() { |     public synchronized Queue<Runnable> getGlobalTasks() { | ||||||
|         return this.globalTasks; |         return this.globalTasks; | ||||||
|     } |     } | ||||||
| @@ -270,7 +260,7 @@ public class SQLManager implements AbstractDB { | |||||||
|             task = new UniqueStatement(String.valueOf(plot.hashCode())) { |             task = new UniqueStatement(String.valueOf(plot.hashCode())) { | ||||||
|  |  | ||||||
|                 @Override |                 @Override | ||||||
|                 public PreparedStatement get() { |                 public @Nullable PreparedStatement get(final @NonNull Connection connection) { | ||||||
|                     return null; |                     return null; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| @@ -304,7 +294,7 @@ public class SQLManager implements AbstractDB { | |||||||
|             task = new UniqueStatement(String.valueOf(uuid.hashCode())) { |             task = new UniqueStatement(String.valueOf(uuid.hashCode())) { | ||||||
|  |  | ||||||
|                 @Override |                 @Override | ||||||
|                 public PreparedStatement get() { |                 public PreparedStatement get(final @NonNull Connection connection) { | ||||||
|                     return null; |                     return null; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| @@ -335,7 +325,7 @@ public class SQLManager implements AbstractDB { | |||||||
|             task = new UniqueStatement(String.valueOf(cluster.hashCode())) { |             task = new UniqueStatement(String.valueOf(cluster.hashCode())) { | ||||||
|  |  | ||||||
|                 @Override |                 @Override | ||||||
|                 public PreparedStatement get() { |                 public @Nullable PreparedStatement get(final @NonNull Connection connection) { | ||||||
|                     return null; |                     return null; | ||||||
|                 } |                 } | ||||||
|  |  | ||||||
| @@ -367,10 +357,10 @@ public class SQLManager implements AbstractDB { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     public boolean sendBatch() { |     public boolean sendBatch() { | ||||||
|         try { |         try (Connection connection = this.dataSource().getConnection()) { | ||||||
|             if (!getGlobalTasks().isEmpty()) { |             if (!getGlobalTasks().isEmpty()) { | ||||||
|                 if (this.connection.getAutoCommit()) { |                 if (connection.getAutoCommit()) { | ||||||
|                     this.connection.setAutoCommit(false); |                     connection.setAutoCommit(false); | ||||||
|                 } |                 } | ||||||
|                 Runnable task = getGlobalTasks().remove(); |                 Runnable task = getGlobalTasks().remove(); | ||||||
|                 if (task != null) { |                 if (task != null) { | ||||||
| @@ -381,18 +371,19 @@ public class SQLManager implements AbstractDB { | |||||||
|                         LOGGER.error("============ DATABASE ERROR ============"); |                         LOGGER.error("============ DATABASE ERROR ============"); | ||||||
|                         LOGGER.error("There was an error updating the database."); |                         LOGGER.error("There was an error updating the database."); | ||||||
|                         LOGGER.error(" - It will be corrected on shutdown"); |                         LOGGER.error(" - It will be corrected on shutdown"); | ||||||
|                         e.printStackTrace(); |                         LOGGER.error("", e); | ||||||
|                         LOGGER.error("========================================"); |                         LOGGER.error("========================================"); | ||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|                 commit(); |                 commit(connection); | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             int count = -1; |             int count = -1; | ||||||
|             if (!this.plotTasks.isEmpty()) { |             if (!this.plotTasks.isEmpty()) { | ||||||
|                 count = Math.max(count, 0); |                 count = Math.max(count, 0); | ||||||
|                 if (this.connection.getAutoCommit()) { |                 if (connection.getAutoCommit()) { | ||||||
|                     this.connection.setAutoCommit(false); |                     connection.setAutoCommit(false); | ||||||
|                 } |                 } | ||||||
|                 String method = null; |                 String method = null; | ||||||
|                 PreparedStatement statement = null; |                 PreparedStatement statement = null; | ||||||
| @@ -446,8 +437,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|             if (!this.playerTasks.isEmpty()) { |             if (!this.playerTasks.isEmpty()) { | ||||||
|                 count = Math.max(count, 0); |                 count = Math.max(count, 0); | ||||||
|                 if (this.connection.getAutoCommit()) { |                 if (connection.getAutoCommit()) { | ||||||
|                     this.connection.setAutoCommit(false); |                     connection.setAutoCommit(false); | ||||||
|                 } |                 } | ||||||
|                 String method = null; |                 String method = null; | ||||||
|                 PreparedStatement statement = null; |                 PreparedStatement statement = null; | ||||||
| @@ -491,8 +482,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|             if (!this.clusterTasks.isEmpty()) { |             if (!this.clusterTasks.isEmpty()) { | ||||||
|                 count = Math.max(count, 0); |                 count = Math.max(count, 0); | ||||||
|                 if (this.connection.getAutoCommit()) { |                 if (connection.getAutoCommit()) { | ||||||
|                     this.connection.setAutoCommit(false); |                     connection.setAutoCommit(false); | ||||||
|                 } |                 } | ||||||
|                 String method = null; |                 String method = null; | ||||||
|                 PreparedStatement statement = null; |                 PreparedStatement statement = null; | ||||||
| @@ -536,12 +527,12 @@ public class SQLManager implements AbstractDB { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             if (count > 0) { |             if (count > 0) { | ||||||
|                 commit(); |                 commit(connection); | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|             if (count != -1) { |             if (count != -1) { | ||||||
|                 if (!this.connection.getAutoCommit()) { |                 if (!connection.getAutoCommit()) { | ||||||
|                     this.connection.setAutoCommit(true); |                     connection.setAutoCommit(true); | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             if (!this.clusterTasks.isEmpty()) { |             if (!this.clusterTasks.isEmpty()) { | ||||||
| @@ -561,10 +552,6 @@ public class SQLManager implements AbstractDB { | |||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public Connection getConnection() { |  | ||||||
|         return this.connection; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Set Plot owner |      * Set Plot owner | ||||||
|      * |      * | ||||||
| @@ -583,8 +570,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                 return SQLManager.this.connection.prepareStatement(SQLManager.this.SET_OWNER); |                 return connection.prepareStatement(SQLManager.this.SET_OWNER); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| @@ -592,7 +579,7 @@ public class SQLManager implements AbstractDB { | |||||||
|     @Override |     @Override | ||||||
|     public void createPlotsAndData(final List<Plot> myList, final Runnable whenDone) { |     public void createPlotsAndData(final List<Plot> myList, final Runnable whenDone) { | ||||||
|         addGlobalTask(() -> { |         addGlobalTask(() -> { | ||||||
|             try { |             try (Connection connection = this.dataSource().getConnection()) { | ||||||
|                 // Create the plots |                 // Create the plots | ||||||
|                 createPlots(myList, () -> { |                 createPlots(myList, () -> { | ||||||
|                     final Map<PlotId, Integer> idMap = new HashMap<>(); |                     final Map<PlotId, Integer> idMap = new HashMap<>(); | ||||||
| @@ -609,7 +596,7 @@ public class SQLManager implements AbstractDB { | |||||||
|                         final ArrayList<UUIDPair> denied = new ArrayList<>(); |                         final ArrayList<UUIDPair> denied = new ArrayList<>(); | ||||||
|  |  | ||||||
|                         // Populating structures |                         // Populating structures | ||||||
|                         try (PreparedStatement stmt = SQLManager.this.connection |                         try (PreparedStatement stmt = connection | ||||||
|                                 .prepareStatement(SQLManager.this.GET_ALL_PLOTS); |                                 .prepareStatement(SQLManager.this.GET_ALL_PLOTS); | ||||||
|                              ResultSet result = stmt.executeQuery()) { |                              ResultSet result = stmt.executeQuery()) { | ||||||
|                             while (result.next()) { |                             while (result.next()) { | ||||||
| @@ -634,13 +621,14 @@ public class SQLManager implements AbstractDB { | |||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
|  |  | ||||||
|                         createFlags(idMap, myList, () -> createSettings( |                         createFlags(connection, idMap, myList, () -> createSettings( | ||||||
|  |                                 connection, | ||||||
|                                 settings, |                                 settings, | ||||||
|                                 () -> createTiers(helpers, "helpers", |                                 () -> createTiers(helpers, "helpers", | ||||||
|                                         () -> createTiers(trusted, "trusted", |                                         () -> createTiers(trusted, "trusted", | ||||||
|                                                 () -> createTiers(denied, "denied", () -> { |                                                 () -> createTiers(denied, "denied", () -> { | ||||||
|                                                     try { |                                                     try { | ||||||
|                                                         SQLManager.this.connection.commit(); |                                                         connection.commit(); | ||||||
|                                                     } catch (SQLException e) { |                                                     } catch (SQLException e) { | ||||||
|                                                         e.printStackTrace(); |                                                         e.printStackTrace(); | ||||||
|                                                     } |                                                     } | ||||||
| @@ -654,7 +642,7 @@ public class SQLManager implements AbstractDB { | |||||||
|                     } catch (SQLException e) { |                     } catch (SQLException e) { | ||||||
|                         LOGGER.warn("Failed to set all flags and member tiers for plots", e); |                         LOGGER.warn("Failed to set all flags and member tiers for plots", e); | ||||||
|                         try { |                         try { | ||||||
|                             SQLManager.this.connection.commit(); |                             connection.commit(); | ||||||
|                         } catch (SQLException e1) { |                         } catch (SQLException e1) { | ||||||
|                             e1.printStackTrace(); |                             e1.printStackTrace(); | ||||||
|                         } |                         } | ||||||
| @@ -662,11 +650,6 @@ public class SQLManager implements AbstractDB { | |||||||
|                 }); |                 }); | ||||||
|             } catch (Exception e) { |             } catch (Exception e) { | ||||||
|                 LOGGER.warn("Warning! Failed to set all helper for plots", e); |                 LOGGER.warn("Warning! Failed to set all helper for plots", e); | ||||||
|                 try { |  | ||||||
|                     SQLManager.this.connection.commit(); |  | ||||||
|                 } catch (SQLException e1) { |  | ||||||
|                     e1.printStackTrace(); |  | ||||||
|                 } |  | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| @@ -723,8 +706,13 @@ public class SQLManager implements AbstractDB { | |||||||
|         setBulk(myList, mod, whenDone); |         setBulk(myList, mod, whenDone); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void createFlags(Map<PlotId, Integer> ids, List<Plot> plots, Runnable whenDone) { |     private void createFlags( | ||||||
|         try (final PreparedStatement preparedStatement = this.connection.prepareStatement( |             final @NonNull Connection connection, | ||||||
|  |             final @NonNull Map<@NonNull PlotId, @NonNull Integer> ids, | ||||||
|  |             final @NonNull List<@NonNull Plot> plots, | ||||||
|  |             final @NonNull Runnable whenDone | ||||||
|  |     ) { | ||||||
|  |         try (final PreparedStatement preparedStatement = connection.prepareStatement( | ||||||
|                 "INSERT INTO `" + SQLManager.this.prefix |                 "INSERT INTO `" + SQLManager.this.prefix | ||||||
|                         + "plot_flags`(`plot_id`, `flag`, `value`) VALUES(?, ?, ?)")) { |                         + "plot_flags`(`plot_id`, `flag`, `value`) VALUES(?, ?, ?)")) { | ||||||
|             for (final Plot plot : plots) { |             for (final Plot plot : plots) { | ||||||
| @@ -822,6 +810,7 @@ public class SQLManager implements AbstractDB { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     public <T> void setBulk(List<T> objList, StmtMod<T> mod, Runnable whenDone) { |     public <T> void setBulk(List<T> objList, StmtMod<T> mod, Runnable whenDone) { | ||||||
|  |         try (Connection connection = this.dataSource().getConnection()) { | ||||||
|             int size = objList.size(); |             int size = objList.size(); | ||||||
|             if (size == 0) { |             if (size == 0) { | ||||||
|                 if (whenDone != null) { |                 if (whenDone != null) { | ||||||
| @@ -849,13 +838,13 @@ public class SQLManager implements AbstractDB { | |||||||
|                     if (last == -1) { |                     if (last == -1) { | ||||||
|                         last = subList.size(); |                         last = subList.size(); | ||||||
|                         statement = mod.getCreateMySQL(subList.size()); |                         statement = mod.getCreateMySQL(subList.size()); | ||||||
|                     preparedStmt = this.connection.prepareStatement(statement); |                         preparedStmt = connection.prepareStatement(statement); | ||||||
|                     } |                     } | ||||||
|                     if (subList.size() != last || count % 5000 == 0 && count > 0) { |                     if (subList.size() != last || count % 5000 == 0 && count > 0) { | ||||||
|                         preparedStmt.executeBatch(); |                         preparedStmt.executeBatch(); | ||||||
|                         preparedStmt.close(); |                         preparedStmt.close(); | ||||||
|                         statement = mod.getCreateMySQL(subList.size()); |                         statement = mod.getCreateMySQL(subList.size()); | ||||||
|                     preparedStmt = this.connection.prepareStatement(statement); |                         preparedStmt = connection.prepareStatement(statement); | ||||||
|                     } |                     } | ||||||
|                     for (int i = 0; i < subList.size(); i++) { |                     for (int i = 0; i < subList.size(); i++) { | ||||||
|                         count++; |                         count++; | ||||||
| @@ -891,13 +880,13 @@ public class SQLManager implements AbstractDB { | |||||||
|                     if (last == -1) { |                     if (last == -1) { | ||||||
|                         last = subList.size(); |                         last = subList.size(); | ||||||
|                         statement = mod.getCreateSQLite(subList.size()); |                         statement = mod.getCreateSQLite(subList.size()); | ||||||
|                     preparedStmt = this.connection.prepareStatement(statement); |                         preparedStmt = connection.prepareStatement(statement); | ||||||
|                     } |                     } | ||||||
|                     if (subList.size() != last || count % 5000 == 0 && count > 0) { |                     if (subList.size() != last || count % 5000 == 0 && count > 0) { | ||||||
|                         preparedStmt.executeBatch(); |                         preparedStmt.executeBatch(); | ||||||
|                         preparedStmt.clearParameters(); |                         preparedStmt.clearParameters(); | ||||||
|                         statement = mod.getCreateSQLite(subList.size()); |                         statement = mod.getCreateSQLite(subList.size()); | ||||||
|                     preparedStmt = this.connection.prepareStatement(statement); |                         preparedStmt = connection.prepareStatement(statement); | ||||||
|                     } |                     } | ||||||
|                     for (int i = 0; i < subList.size(); i++) { |                     for (int i = 0; i < subList.size(); i++) { | ||||||
|                         count++; |                         count++; | ||||||
| @@ -914,7 +903,7 @@ public class SQLManager implements AbstractDB { | |||||||
|                 e.printStackTrace(); |                 e.printStackTrace(); | ||||||
|                 LOGGER.error("2: | {}", objList.get(0).getClass().getCanonicalName()); |                 LOGGER.error("2: | {}", objList.get(0).getClass().getCanonicalName()); | ||||||
|                 LOGGER.error("Could not bulk save!"); |                 LOGGER.error("Could not bulk save!"); | ||||||
|             try (PreparedStatement preparedStmt = this.connection |                 try (PreparedStatement preparedStmt = connection | ||||||
|                         .prepareStatement(mod.getCreateSQL())) { |                         .prepareStatement(mod.getCreateSQL())) { | ||||||
|                     for (T obj : objList) { |                     for (T obj : objList) { | ||||||
|                         mod.setSQL(preparedStmt, obj); |                         mod.setSQL(preparedStmt, obj); | ||||||
| @@ -929,10 +918,16 @@ public class SQLManager implements AbstractDB { | |||||||
|             if (whenDone != null) { |             if (whenDone != null) { | ||||||
|                 whenDone.run(); |                 whenDone.run(); | ||||||
|             } |             } | ||||||
|  |         } catch (Exception e) { | ||||||
|  |             LOGGER.error("Failed to create SQL connection", e); | ||||||
|  |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void createSettings(final ArrayList<LegacySettings> myList, final Runnable whenDone) { |     private void createSettings( | ||||||
|         try (final PreparedStatement preparedStatement = this.connection.prepareStatement( |             final @NonNull Connection connection, | ||||||
|  |             final @NonNull List<@NonNull LegacySettings> myList, | ||||||
|  |             final @NonNull Runnable whenDone) { | ||||||
|  |         try (PreparedStatement preparedStatement = connection.prepareStatement( | ||||||
|                 "INSERT INTO `" + SQLManager.this.prefix + "plot_settings`" |                 "INSERT INTO `" + SQLManager.this.prefix + "plot_settings`" | ||||||
|                         + "(`plot_plot_id`,`biome`,`rain`,`custom_time`,`time`,`deny_entry`,`alias`,`merged`,`position`) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)")) { |                         + "(`plot_plot_id`,`biome`,`rain`,`custom_time`,`time`,`deny_entry`,`alias`,`merged`,`position`) VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?)")) { | ||||||
|  |  | ||||||
| @@ -1059,8 +1054,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                 return SQLManager.this.connection.prepareStatement( |                 return connection.prepareStatement( | ||||||
|                         SQLManager.this.CREATE_PLOT_SAFE, |                         SQLManager.this.CREATE_PLOT_SAFE, | ||||||
|                         Statement.RETURN_GENERATED_KEYS |                         Statement.RETURN_GENERATED_KEYS | ||||||
|                 ); |                 ); | ||||||
| @@ -1073,9 +1068,8 @@ public class SQLManager implements AbstractDB { | |||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public void addBatch(PreparedStatement statement) throws SQLException { |             public void addBatch(PreparedStatement statement) throws SQLException { | ||||||
|                 int inserted = statement.executeUpdate(); |                 if (statement.execute() || statement.getUpdateCount() > 0) { | ||||||
|                 if (inserted > 0) { |                     try (ResultSet keys = supportsGetGeneratedKeys ? statement.getGeneratedKeys() : statement.getResultSet()) { | ||||||
|                     try (ResultSet keys = statement.getGeneratedKeys()) { |  | ||||||
|                         if (keys.next()) { |                         if (keys.next()) { | ||||||
|                             plot.temp = keys.getInt(1); |                             plot.temp = keys.getInt(1); | ||||||
|                             addPlotTask(plot, new UniqueStatement( |                             addPlotTask(plot, new UniqueStatement( | ||||||
| @@ -1087,8 +1081,8 @@ public class SQLManager implements AbstractDB { | |||||||
|                                 } |                                 } | ||||||
|  |  | ||||||
|                                 @Override |                                 @Override | ||||||
|                                 public PreparedStatement get() throws SQLException { |                                 public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                                     return SQLManager.this.connection.prepareStatement( |                                     return connection.prepareStatement( | ||||||
|                                             "INSERT INTO `" + SQLManager.this.prefix |                                             "INSERT INTO `" + SQLManager.this.prefix | ||||||
|                                                     + "plot_settings`(`plot_plot_id`) VALUES(?)"); |                                                     + "plot_settings`(`plot_plot_id`) VALUES(?)"); | ||||||
|                                 } |                                 } | ||||||
| @@ -1107,17 +1101,14 @@ public class SQLManager implements AbstractDB { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public void commit() { |     private void commit(final @NonNull Connection connection) { | ||||||
|         if (this.closed) { |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         try { |         try { | ||||||
|             if (!this.connection.getAutoCommit()) { |             if (!connection.getAutoCommit()) { | ||||||
|                 this.connection.commit(); |                 connection.commit(); | ||||||
|                 this.connection.setAutoCommit(true); |                 connection.setAutoCommit(true); | ||||||
|             } |             } | ||||||
|         } catch (SQLException e) { |         } catch (SQLException e) { | ||||||
|             e.printStackTrace(); |             LOGGER.error("Failed to commit database transaction", e); | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -1134,8 +1125,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                 return SQLManager.this.connection |                 return connection | ||||||
|                         .prepareStatement(SQLManager.this.CREATE_PLOT, Statement.RETURN_GENERATED_KEYS); |                         .prepareStatement(SQLManager.this.CREATE_PLOT, Statement.RETURN_GENERATED_KEYS); | ||||||
|             } |             } | ||||||
|  |  | ||||||
| @@ -1145,8 +1136,8 @@ public class SQLManager implements AbstractDB { | |||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public void addBatch(PreparedStatement statement) throws SQLException { |             public void addBatch(PreparedStatement statement) throws SQLException { | ||||||
|                 statement.executeUpdate(); |                 statement.execute(); | ||||||
|                 try (ResultSet keys = statement.getGeneratedKeys()) { |                 try (ResultSet keys = supportsGetGeneratedKeys ? statement.getGeneratedKeys() : statement.getResultSet()) { | ||||||
|                     if (keys.next()) { |                     if (keys.next()) { | ||||||
|                         plot.temp = keys.getInt(1); |                         plot.temp = keys.getInt(1); | ||||||
|                     } |                     } | ||||||
| @@ -1160,8 +1151,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                 return SQLManager.this.connection.prepareStatement( |                 return connection.prepareStatement( | ||||||
|                         "INSERT INTO `" + SQLManager.this.prefix |                         "INSERT INTO `" + SQLManager.this.prefix | ||||||
|                                 + "plot_settings`(`plot_plot_id`) VALUES(?)"); |                                 + "plot_settings`(`plot_plot_id`) VALUES(?)"); | ||||||
|             } |             } | ||||||
| @@ -1176,6 +1167,7 @@ public class SQLManager implements AbstractDB { | |||||||
|      */ |      */ | ||||||
|     @Override |     @Override | ||||||
|     public void createTables() throws SQLException { |     public void createTables() throws SQLException { | ||||||
|  |         try (Connection connection = this.dataSource().getConnection()) { | ||||||
|             String[] tables = |             String[] tables = | ||||||
|                     new String[]{"plot", "plot_denied", "plot_helpers", "plot_comments", "plot_trusted", |                     new String[]{"plot", "plot_denied", "plot_helpers", "plot_comments", "plot_trusted", | ||||||
|                             "plot_rating", "plot_settings", "cluster", "player_meta", "plot_flags"}; |                             "plot_rating", "plot_settings", "cluster", "player_meta", "plot_flags"}; | ||||||
| @@ -1193,7 +1185,7 @@ public class SQLManager implements AbstractDB { | |||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             boolean addConstraint = create == tables.length; |             boolean addConstraint = create == tables.length; | ||||||
|         try (Statement stmt = this.connection.createStatement()) { |             try (Statement stmt = connection.createStatement()) { | ||||||
|                 if (this.mySQL) { |                 if (this.mySQL) { | ||||||
|                     stmt.addBatch("CREATE TABLE IF NOT EXISTS `" + this.prefix + "plot` (" |                     stmt.addBatch("CREATE TABLE IF NOT EXISTS `" + this.prefix + "plot` (" | ||||||
|                             + "`id` INT(11) NOT NULL AUTO_INCREMENT," + "`plot_id_x` INT(11) NOT NULL," |                             + "`id` INT(11) NOT NULL AUTO_INCREMENT," + "`plot_id_x` INT(11) NOT NULL," | ||||||
| @@ -1328,6 +1320,7 @@ public class SQLManager implements AbstractDB { | |||||||
|                 stmt.clearBatch(); |                 stmt.clearBatch(); | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void deleteSettings(final Plot plot) { |     public void deleteSettings(final Plot plot) { | ||||||
| @@ -1338,8 +1331,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                 return SQLManager.this.connection.prepareStatement( |                 return connection.prepareStatement( | ||||||
|                         "DELETE FROM `" + SQLManager.this.prefix |                         "DELETE FROM `" + SQLManager.this.prefix | ||||||
|                                 + "plot_settings` WHERE `plot_plot_id` = ?"); |                                 + "plot_settings` WHERE `plot_plot_id` = ?"); | ||||||
|             } |             } | ||||||
| @@ -1358,8 +1351,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                 return SQLManager.this.connection.prepareStatement( |                 return connection.prepareStatement( | ||||||
|                         "DELETE FROM `" + SQLManager.this.prefix |                         "DELETE FROM `" + SQLManager.this.prefix | ||||||
|                                 + "plot_helpers` WHERE `plot_plot_id` = ?"); |                                 + "plot_helpers` WHERE `plot_plot_id` = ?"); | ||||||
|             } |             } | ||||||
| @@ -1378,8 +1371,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                 return SQLManager.this.connection.prepareStatement( |                 return connection.prepareStatement( | ||||||
|                         "DELETE FROM `" + SQLManager.this.prefix |                         "DELETE FROM `" + SQLManager.this.prefix | ||||||
|                                 + "plot_trusted` WHERE `plot_plot_id` = ?"); |                                 + "plot_trusted` WHERE `plot_plot_id` = ?"); | ||||||
|             } |             } | ||||||
| @@ -1398,8 +1391,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                 return SQLManager.this.connection.prepareStatement( |                 return connection.prepareStatement( | ||||||
|                         "DELETE FROM `" + SQLManager.this.prefix |                         "DELETE FROM `" + SQLManager.this.prefix | ||||||
|                                 + "plot_denied` WHERE `plot_plot_id` = ?"); |                                 + "plot_denied` WHERE `plot_plot_id` = ?"); | ||||||
|             } |             } | ||||||
| @@ -1416,8 +1409,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                 return SQLManager.this.connection.prepareStatement( |                 return connection.prepareStatement( | ||||||
|                         "DELETE FROM `" + SQLManager.this.prefix |                         "DELETE FROM `" + SQLManager.this.prefix | ||||||
|                                 + "plot_comments` WHERE `world` = ? AND `hashcode` = ?"); |                                 + "plot_comments` WHERE `world` = ? AND `hashcode` = ?"); | ||||||
|             } |             } | ||||||
| @@ -1436,8 +1429,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                 return SQLManager.this.connection.prepareStatement( |                 return connection.prepareStatement( | ||||||
|                         "DELETE FROM `" + SQLManager.this.prefix |                         "DELETE FROM `" + SQLManager.this.prefix | ||||||
|                                 + "plot_rating` WHERE `plot_plot_id` = ?"); |                                 + "plot_rating` WHERE `plot_plot_id` = ?"); | ||||||
|             } |             } | ||||||
| @@ -1464,8 +1457,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                 return SQLManager.this.connection.prepareStatement( |                 return connection.prepareStatement( | ||||||
|                         "DELETE FROM `" + SQLManager.this.prefix + "plot` WHERE `id` = ?"); |                         "DELETE FROM `" + SQLManager.this.prefix + "plot` WHERE `id` = ?"); | ||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
| @@ -1486,8 +1479,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                 return SQLManager.this.connection.prepareStatement( |                 return connection.prepareStatement( | ||||||
|                         "INSERT INTO `" + SQLManager.this.prefix |                         "INSERT INTO `" + SQLManager.this.prefix | ||||||
|                                 + "plot_settings`(`plot_plot_id`) VALUES(?)"); |                                 + "plot_settings`(`plot_plot_id`) VALUES(?)"); | ||||||
|             } |             } | ||||||
| @@ -1496,16 +1489,12 @@ public class SQLManager implements AbstractDB { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public int getClusterId(PlotCluster cluster) { |     public int getClusterId(PlotCluster cluster) { | ||||||
|         if (cluster.temp > 0) { |         try (Connection connection = this.dataSource.getConnection()) { | ||||||
|             return cluster.temp; |  | ||||||
|         } |  | ||||||
|         try { |  | ||||||
|             commit(); |  | ||||||
|             if (cluster.temp > 0) { |             if (cluster.temp > 0) { | ||||||
|                 return cluster.temp; |                 return cluster.temp; | ||||||
|             } |             } | ||||||
|             int c_id; |             int c_id; | ||||||
|             try (PreparedStatement stmt = this.connection.prepareStatement( |             try (PreparedStatement stmt = connection.prepareStatement( | ||||||
|                     "SELECT `id` FROM `" + this.prefix |                     "SELECT `id` FROM `" + this.prefix | ||||||
|                             + "cluster` WHERE `pos1_x` = ? AND `pos1_z` = ? AND `pos2_x` = ? AND `pos2_z` = ? AND `world` = ? ORDER BY `timestamp` ASC")) { |                             + "cluster` WHERE `pos1_x` = ? AND `pos1_z` = ? AND `pos2_x` = ? AND `pos2_z` = ? AND `world` = ? ORDER BY `timestamp` ASC")) { | ||||||
|                 stmt.setInt(1, cluster.getP1().getX()); |                 stmt.setInt(1, cluster.getP1().getX()); | ||||||
| @@ -1539,13 +1528,12 @@ public class SQLManager implements AbstractDB { | |||||||
|         if (plot.temp > 0) { |         if (plot.temp > 0) { | ||||||
|             return plot.temp; |             return plot.temp; | ||||||
|         } |         } | ||||||
|         try { |         try (Connection connection = this.dataSource().getConnection()) { | ||||||
|             commit(); |  | ||||||
|             if (plot.temp > 0) { |             if (plot.temp > 0) { | ||||||
|                 return plot.temp; |                 return plot.temp; | ||||||
|             } |             } | ||||||
|             int id; |             int id; | ||||||
|             try (PreparedStatement statement = this.connection.prepareStatement( |             try (PreparedStatement statement = connection.prepareStatement( | ||||||
|                     "SELECT `id` FROM `" + this.prefix |                     "SELECT `id` FROM `" + this.prefix | ||||||
|                             + "plot` WHERE `plot_id_x` = ? AND `plot_id_z` = ? AND world = ? ORDER BY `timestamp` ASC")) { |                             + "plot` WHERE `plot_id_x` = ? AND `plot_id_z` = ? AND world = ? ORDER BY `timestamp` ASC")) { | ||||||
|                 statement.setInt(1, plot.getId().getX()); |                 statement.setInt(1, plot.getId().getX()); | ||||||
| @@ -1574,15 +1562,15 @@ public class SQLManager implements AbstractDB { | |||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public void updateTables(int[] oldVersion) { |     public void updateTables(int[] oldVersion) { | ||||||
|         try { |         try (Connection connection = this.dataSource().getConnection()) { | ||||||
|             if (this.mySQL && !PlotSquared.get().checkVersion(oldVersion, 3, 3, 2)) { |             if (this.mySQL && !PlotSquared.get().checkVersion(oldVersion, 3, 3, 2)) { | ||||||
|                 try (Statement stmt = this.connection.createStatement()) { |                 try (Statement stmt = connection.createStatement()) { | ||||||
|                     stmt.executeUpdate( |                     stmt.executeUpdate( | ||||||
|                             "ALTER TABLE `" + this.prefix + "plots` DROP INDEX `unique_alias`"); |                             "ALTER TABLE `" + this.prefix + "plots` DROP INDEX `unique_alias`"); | ||||||
|                 } catch (SQLException ignored) { |                 } catch (SQLException ignored) { | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             DatabaseMetaData data = this.connection.getMetaData(); |             DatabaseMetaData data = connection.getMetaData(); | ||||||
|             ResultSet rs = |             ResultSet rs = | ||||||
|                     data.getColumns(null, null, this.prefix + "plot_comments", "plot_plot_id"); |                     data.getColumns(null, null, this.prefix + "plot_comments", "plot_plot_id"); | ||||||
|             if (rs.next()) { |             if (rs.next()) { | ||||||
| @@ -1590,7 +1578,7 @@ public class SQLManager implements AbstractDB { | |||||||
|                 rs = data.getColumns(null, null, this.prefix + "plot_comments", "hashcode"); |                 rs = data.getColumns(null, null, this.prefix + "plot_comments", "hashcode"); | ||||||
|                 if (!rs.next()) { |                 if (!rs.next()) { | ||||||
|                     rs.close(); |                     rs.close(); | ||||||
|                     try (Statement statement = this.connection.createStatement()) { |                     try (Statement statement = connection.createStatement()) { | ||||||
|                         statement.addBatch("DROP TABLE `" + this.prefix + "plot_comments`"); |                         statement.addBatch("DROP TABLE `" + this.prefix + "plot_comments`"); | ||||||
|                         if (Storage.MySQL.USE) { |                         if (Storage.MySQL.USE) { | ||||||
|                             statement.addBatch( |                             statement.addBatch( | ||||||
| @@ -1625,7 +1613,7 @@ public class SQLManager implements AbstractDB { | |||||||
|             rs.close(); |             rs.close(); | ||||||
|             rs = data.getColumns(null, null, this.prefix + "plot_denied", "plot_plot_id"); |             rs = data.getColumns(null, null, this.prefix + "plot_denied", "plot_plot_id"); | ||||||
|             if (rs.next()) { |             if (rs.next()) { | ||||||
|                 try (Statement statement = this.connection.createStatement()) { |                 try (Statement statement = connection.createStatement()) { | ||||||
|                     statement.executeUpdate("DELETE FROM `" + this.prefix |                     statement.executeUpdate("DELETE FROM `" + this.prefix | ||||||
|                             + "plot_denied` WHERE `plot_plot_id` NOT IN (SELECT `id` FROM `" |                             + "plot_denied` WHERE `plot_plot_id` NOT IN (SELECT `id` FROM `" | ||||||
|                             + this.prefix + "plot`)"); |                             + this.prefix + "plot`)"); | ||||||
| @@ -1634,7 +1622,7 @@ public class SQLManager implements AbstractDB { | |||||||
|                 } |                 } | ||||||
|  |  | ||||||
|                 rs.close(); |                 rs.close(); | ||||||
|                 try (Statement statement = this.connection.createStatement()) { |                 try (Statement statement = connection.createStatement()) { | ||||||
|                     for (String table : new String[]{"plot_denied", "plot_helpers", |                     for (String table : new String[]{"plot_denied", "plot_helpers", | ||||||
|                             "plot_trusted"}) { |                             "plot_trusted"}) { | ||||||
|                         ResultSet result = statement.executeQuery( |                         ResultSet result = statement.executeQuery( | ||||||
| @@ -1706,9 +1694,12 @@ public class SQLManager implements AbstractDB { | |||||||
|     @Override |     @Override | ||||||
|     public boolean convertFlags() { |     public boolean convertFlags() { | ||||||
|         final Map<Integer, Map<String, String>> flagMap = new HashMap<>(); |         final Map<Integer, Map<String, String>> flagMap = new HashMap<>(); | ||||||
|         try (Statement statement = this.connection.createStatement()) { |         try ( | ||||||
|             try (ResultSet resultSet = statement |                 Connection connection = this.dataSource().getConnection(); | ||||||
|                     .executeQuery("SELECT * FROM `" + this.prefix + "plot_settings`")) { |                 Statement statement = connection.createStatement(); | ||||||
|  |                 ResultSet resultSet = statement | ||||||
|  |                         .executeQuery("SELECT * FROM `" + this.prefix + "plot_settings`") | ||||||
|  |         ) { | ||||||
|             while (resultSet.next()) { |             while (resultSet.next()) { | ||||||
|                 final int id = resultSet.getInt("plot_plot_id"); |                 final int id = resultSet.getInt("plot_plot_id"); | ||||||
|                 final String plotFlags = resultSet.getString("flags"); |                 final String plotFlags = resultSet.getString("flags"); | ||||||
| @@ -1729,14 +1720,14 @@ public class SQLManager implements AbstractDB { | |||||||
|                     } |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|             } |  | ||||||
|         } catch (final Exception e) { |         } catch (final Exception e) { | ||||||
|             LOGGER.error("Failed to load old flag values", e); |             LOGGER.error("Failed to load old flag values", e); | ||||||
|             return false; |             return false; | ||||||
|         } |         } | ||||||
|         LOGGER.info("Loaded {} plot flag collections...", flagMap.size()); |         LOGGER.info("Loaded {} plot flag collections...", flagMap.size()); | ||||||
|         LOGGER.info("Attempting to store these flags in the new table..."); |         LOGGER.info("Attempting to store these flags in the new table..."); | ||||||
|         try (final PreparedStatement preparedStatement = this.connection.prepareStatement( |         try (Connection connection = this.dataSource().getConnection(); PreparedStatement preparedStatement = | ||||||
|  |                 connection.prepareStatement( | ||||||
|                 "INSERT INTO `" + SQLManager.this.prefix |                 "INSERT INTO `" + SQLManager.this.prefix | ||||||
|                         + "plot_flags`(`plot_id`, `flag`, `value`) VALUES(?, ?, ?)")) { |                         + "plot_flags`(`plot_id`, `flag`, `value`) VALUES(?, ?, ?)")) { | ||||||
|  |  | ||||||
| @@ -1821,7 +1812,7 @@ public class SQLManager implements AbstractDB { | |||||||
|             /* |             /* | ||||||
|              * Getting plots |              * Getting plots | ||||||
|              */ |              */ | ||||||
|             try (Statement statement = this.connection.createStatement()) { |             try (Connection connection = this.dataSource().getConnection(); Statement statement = connection.createStatement()) { | ||||||
|                 int id; |                 int id; | ||||||
|                 String o; |                 String o; | ||||||
|                 UUID user; |                 UUID user; | ||||||
| @@ -2154,8 +2145,8 @@ public class SQLManager implements AbstractDB { | |||||||
|             } |             } | ||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException { | ||||||
|                 return SQLManager.this.connection.prepareStatement( |                 return connection.prepareStatement( | ||||||
|                         "UPDATE `" + SQLManager.this.prefix |                         "UPDATE `" + SQLManager.this.prefix | ||||||
|                                 + "plot_settings` SET `merged` = ? WHERE `plot_plot_id` = ?"); |                                 + "plot_settings` SET `merged` = ? WHERE `plot_plot_id` = ?"); | ||||||
|             } |             } | ||||||
| @@ -3058,8 +3049,8 @@ public class SQLManager implements AbstractDB { | |||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public void addBatch(PreparedStatement statement) throws SQLException { |             public void addBatch(PreparedStatement statement) throws SQLException { | ||||||
|                 statement.executeUpdate(); |                 statement.execute(); | ||||||
|                 try (ResultSet keys = statement.getGeneratedKeys()) { |                 try (ResultSet keys = supportsGetGeneratedKeys ? statement.getGeneratedKeys() : statement.getResultSet()) { | ||||||
|                     if (keys.next()) { |                     if (keys.next()) { | ||||||
|                         cluster.temp = keys.getInt(1); |                         cluster.temp = keys.getInt(1); | ||||||
|                     } |                     } | ||||||
| @@ -3140,6 +3131,8 @@ public class SQLManager implements AbstractDB { | |||||||
|  |  | ||||||
|             @Override |             @Override | ||||||
|             public PreparedStatement get() throws SQLException { |             public PreparedStatement get() throws SQLException { | ||||||
|  |                 try (final Connection connection = ) | ||||||
|  |  | ||||||
|                 return SQLManager.this.connection.prepareStatement( |                 return SQLManager.this.connection.prepareStatement( | ||||||
|                         "DELETE FROM `" + SQLManager.this.prefix |                         "DELETE FROM `" + SQLManager.this.prefix | ||||||
|                                 + "cluster_invited` WHERE `cluster_id` = ? AND `user_uuid` = ?"); |                                 + "cluster_invited` WHERE `cluster_id` = ? AND `user_uuid` = ?"); | ||||||
| @@ -3407,13 +3400,16 @@ public class SQLManager implements AbstractDB { | |||||||
|     @Override |     @Override | ||||||
|     public void close() { |     public void close() { | ||||||
|         try { |         try { | ||||||
|             this.closed = true; |             ((Closeable) this.dataSource()).close(); | ||||||
|             this.connection.close(); |         } catch (Exception e) { | ||||||
|         } catch (SQLException e) { |             LOGGER.error("Failed to close data source", e); | ||||||
|             e.printStackTrace(); |  | ||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private @NonNull DataSource dataSource() { | ||||||
|  |         return this.dataSource; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private record LegacySettings( |     private record LegacySettings( | ||||||
|             int id, |             int id, | ||||||
|             PlotSettings settings |             PlotSettings settings | ||||||
| @@ -3437,7 +3433,7 @@ public class SQLManager implements AbstractDB { | |||||||
|             statement.executeBatch(); |             statement.executeBatch(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public abstract PreparedStatement get() throws SQLException; |         public abstract @Nullable PreparedStatement get(final @NonNull Connection connection) throws SQLException; | ||||||
|  |  | ||||||
|         public abstract void set(PreparedStatement statement) throws SQLException; |         public abstract void set(PreparedStatement statement) throws SQLException; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -33,6 +33,7 @@ import java.sql.Statement; | |||||||
| /** | /** | ||||||
|  * Connects to and uses a SQLite database. |  * Connects to and uses a SQLite database. | ||||||
|  */ |  */ | ||||||
|  | @Deprecated(forRemoval = true) | ||||||
| public class SQLite extends Database { | public class SQLite extends Database { | ||||||
|  |  | ||||||
|     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + SQLite.class.getSimpleName()); |     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + SQLite.class.getSimpleName()); | ||||||
|   | |||||||
| @@ -189,7 +189,7 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|                 } |                 } | ||||||
|                 Object value; |                 Object value; | ||||||
|                 try { |                 try { | ||||||
|                     final boolean accessible = field.isAccessible(); |                     final boolean accessible = field.canAccess(this); | ||||||
|                     field.setAccessible(true); |                     field.setAccessible(true); | ||||||
|                     value = field.get(this); |                     value = field.get(this); | ||||||
|                     field.setAccessible(accessible); |                     field.setAccessible(accessible); | ||||||
| @@ -265,7 +265,6 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|  |  | ||||||
|         int worldGenHeight = getMaxGenHeight() - getMinGenHeight() + 1; |         int worldGenHeight = getMaxGenHeight() - getMinGenHeight() + 1; | ||||||
|  |  | ||||||
|         int maxSchematicHeight = 0; |  | ||||||
|         int plotSchemHeight = 0; |         int plotSchemHeight = 0; | ||||||
|  |  | ||||||
|         // SCHEM_Y should be normalised to the plot "start" height |         // SCHEM_Y should be normalised to the plot "start" height | ||||||
| @@ -278,18 +277,16 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|                 SCHEM_Y = getMinGenHeight(); |                 SCHEM_Y = getMinGenHeight(); | ||||||
|                 plotY = 0; |                 plotY = 0; | ||||||
|             } |             } | ||||||
|             maxSchematicHeight = plotY + plotSchemHeight; |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         int roadSchemHeight; |         int roadSchemHeight = 0; | ||||||
|  |  | ||||||
|         if (schematic1 != null) { |         if (schematic1 != null) { | ||||||
|             roadSchemHeight = Math.max( |             roadSchemHeight = Math.max( | ||||||
|                     schematic1.getClipboard().getDimensions().getY(), |                     schematic1.getClipboard().getDimensions().getY(), | ||||||
|                     schematic2.getClipboard().getDimensions().getY() |                     schematic2.getClipboard().getDimensions().getY() | ||||||
|             ); |             ); | ||||||
|             maxSchematicHeight = Math.max(roadSchemHeight, maxSchematicHeight); |             if (roadSchemHeight == worldGenHeight) { | ||||||
|             if (maxSchematicHeight == worldGenHeight) { |  | ||||||
|                 SCHEM_Y = getMinGenHeight(); |                 SCHEM_Y = getMinGenHeight(); | ||||||
|                 roadY = 0; // Road is the lowest schematic |                 roadY = 0; // Road is the lowest schematic | ||||||
|                 if (schematic3 != null && schematic3.getClipboard().getDimensions().getY() != worldGenHeight) { |                 if (schematic3 != null && schematic3.getClipboard().getDimensions().getY() != worldGenHeight) { | ||||||
| @@ -306,13 +303,12 @@ public class HybridPlotWorld extends ClassicPlotWorld { | |||||||
|                         // Road is the lowest schematic. Normalize plotY to it. |                         // Road is the lowest schematic. Normalize plotY to it. | ||||||
|                         plotY = PLOT_HEIGHT - SCHEM_Y; |                         plotY = PLOT_HEIGHT - SCHEM_Y; | ||||||
|                     } |                     } | ||||||
|                     maxSchematicHeight = Math.max(maxSchematicHeight, plotY + plotSchemHeight); |  | ||||||
|                 } |                 } | ||||||
|             } else { |             } else { | ||||||
|                 roadY = minRoadWall - SCHEM_Y; |                 roadY = minRoadWall - SCHEM_Y; | ||||||
|                 maxSchematicHeight = Math.max(maxSchematicHeight, roadY + roadSchemHeight); |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |         int maxSchematicHeight = Math.max(plotY + plotSchemHeight, roadY + roadSchemHeight); | ||||||
|  |  | ||||||
|         if (schematic3 != null) { |         if (schematic3 != null) { | ||||||
|             this.PLOT_SCHEMATIC = true; |             this.PLOT_SCHEMATIC = true; | ||||||
|   | |||||||
| @@ -77,6 +77,10 @@ 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(); |     private static final BlockState AIR = BlockTypes.AIR.getDefaultState(); | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Deprecated and likely to be removed in a future release. | ||||||
|  |      */ | ||||||
|  |     @Deprecated(forRemoval = true, since = "7.0.0") | ||||||
|     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; | ||||||
|   | |||||||
| @@ -0,0 +1,12 @@ | |||||||
|  | package com.plotsquared.core.inject.annotations; | ||||||
|  |  | ||||||
|  | import java.lang.annotation.ElementType; | ||||||
|  | import java.lang.annotation.Retention; | ||||||
|  | import java.lang.annotation.RetentionPolicy; | ||||||
|  | import java.lang.annotation.Target; | ||||||
|  |  | ||||||
|  | @Target({ElementType.FIELD, ElementType.TYPE, ElementType.PARAMETER}) | ||||||
|  | @Retention(RetentionPolicy.RUNTIME) | ||||||
|  | public @interface PlotDatabase { | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -0,0 +1,72 @@ | |||||||
|  | package com.plotsquared.core.inject.modules; | ||||||
|  |  | ||||||
|  | import com.google.inject.AbstractModule; | ||||||
|  | import com.plotsquared.core.PlotSquared; | ||||||
|  | import com.plotsquared.core.configuration.Storage; | ||||||
|  | import com.plotsquared.core.inject.annotations.PlotDatabase; | ||||||
|  | import com.plotsquared.core.util.FileUtils; | ||||||
|  | import com.plotsquared.core.util.StringMan; | ||||||
|  | import com.zaxxer.hikari.HikariConfig; | ||||||
|  | import com.zaxxer.hikari.HikariDataSource; | ||||||
|  | import org.apache.logging.log4j.LogManager; | ||||||
|  | import org.apache.logging.log4j.Logger; | ||||||
|  |  | ||||||
|  | import javax.sql.DataSource; | ||||||
|  | import java.io.File; | ||||||
|  |  | ||||||
|  | public class DatabaseModule extends AbstractModule { | ||||||
|  |  | ||||||
|  |     private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + PlotSquared.class.getSimpleName()); | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     protected void configure() { | ||||||
|  |         try { | ||||||
|  |             if (Storage.MySQL.USE) { | ||||||
|  |                 this.configureMySQL(); | ||||||
|  |             } else if (Storage.SQLite.USE) { | ||||||
|  |                 this.configureSQLite(); | ||||||
|  |             } else { | ||||||
|  |                 LOGGER.error("No storage type is set. Disabling PlotSquared"); | ||||||
|  |                 PlotSquared.platform().shutdown(); | ||||||
|  |             } | ||||||
|  |         } catch (final Exception e) { | ||||||
|  |             LOGGER.error("Unable to initialize database", e); | ||||||
|  |             PlotSquared.platform().shutdown(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void configureSQLite() throws Exception { | ||||||
|  |         final File file = FileUtils.getFile(PlotSquared.platform().getDirectory(), Storage.SQLite.DB + ".db"); | ||||||
|  |         if (!file.exists()) { | ||||||
|  |             file.createNewFile(); | ||||||
|  |         } | ||||||
|  |         Class.forName("org.sqlite.JDBC"); | ||||||
|  |  | ||||||
|  |         final HikariConfig config = new HikariConfig(); | ||||||
|  |         config.setJdbcUrl("jdbc:sqlite:" + file); | ||||||
|  |         config.setDriverClassName("org.sqlite.JDBC"); | ||||||
|  |         final DataSource dataSource = new HikariDataSource(); | ||||||
|  |  | ||||||
|  |         binder().bind(DataSource.class).annotatedWith(PlotDatabase.class).toInstance(dataSource); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void configureMySQL() { | ||||||
|  |         final HikariConfig hikariConfig = new HikariConfig(); | ||||||
|  |         hikariConfig.setJdbcUrl( | ||||||
|  |                 String.format( | ||||||
|  |                         "jdbc:mysql://%s:%s/%s?%s", | ||||||
|  |                         Storage.MySQL.HOST, | ||||||
|  |                         Storage.MySQL.PORT, | ||||||
|  |                         Storage.MySQL.DATABASE, | ||||||
|  |                         StringMan.join(Storage.MySQL.PROPERTIES, "&") | ||||||
|  |                 )); | ||||||
|  |         hikariConfig.setUsername(Storage.MySQL.USER); | ||||||
|  |         hikariConfig.setPassword(Storage.MySQL.PASSWORD); | ||||||
|  |         hikariConfig.addDataSourceProperty("cachePrepStmts", "true"); | ||||||
|  |         hikariConfig.addDataSourceProperty("prepStmtCacheSize", "512"); | ||||||
|  |         hikariConfig.addDataSourceProperty("prepStmtCacheSqlLimit", "2048"); | ||||||
|  |         final DataSource dataSource = new HikariDataSource(hikariConfig); | ||||||
|  |  | ||||||
|  |         binder().bind(DataSource.class).annotatedWith(PlotDatabase.class).toInstance(dataSource); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,15 @@ | |||||||
|  | package com.plotsquared.core.inject.modules; | ||||||
|  |  | ||||||
|  | import com.plotsquared.core.inject.annotations.PlotDatabase; | ||||||
|  | import org.jdbi.v3.guice.AbstractJdbiDefinitionModule; | ||||||
|  |  | ||||||
|  | public class JdbiModule extends AbstractJdbiDefinitionModule { | ||||||
|  |  | ||||||
|  |     public JdbiModule() { | ||||||
|  |         super(PlotDatabase.class); | ||||||
|  |     } | ||||||
|  |     @Override | ||||||
|  |     public void configureJdbi() { | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -55,7 +55,6 @@ import com.plotsquared.core.plot.flag.implementations.TitlesFlag; | |||||||
| import com.plotsquared.core.plot.flag.implementations.WeatherFlag; | import com.plotsquared.core.plot.flag.implementations.WeatherFlag; | ||||||
| import com.plotsquared.core.plot.flag.types.TimedFlag; | import com.plotsquared.core.plot.flag.types.TimedFlag; | ||||||
| import com.plotsquared.core.util.EventDispatcher; | import com.plotsquared.core.util.EventDispatcher; | ||||||
| import com.plotsquared.core.util.PlayerManager; |  | ||||||
| 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; | ||||||
| import com.sk89q.worldedit.world.gamemode.GameMode; | import com.sk89q.worldedit.world.gamemode.GameMode; | ||||||
| @@ -63,7 +62,6 @@ import com.sk89q.worldedit.world.gamemode.GameModes; | |||||||
| import com.sk89q.worldedit.world.item.ItemType; | import com.sk89q.worldedit.world.item.ItemType; | ||||||
| import com.sk89q.worldedit.world.item.ItemTypes; | import com.sk89q.worldedit.world.item.ItemTypes; | ||||||
| import net.kyori.adventure.text.Component; | import net.kyori.adventure.text.Component; | ||||||
| import net.kyori.adventure.text.ComponentLike; |  | ||||||
| import net.kyori.adventure.text.minimessage.MiniMessage; | import net.kyori.adventure.text.minimessage.MiniMessage; | ||||||
| import net.kyori.adventure.text.minimessage.tag.Tag; | import net.kyori.adventure.text.minimessage.tag.Tag; | ||||||
| import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; | import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; | ||||||
| @@ -77,6 +75,7 @@ import java.util.List; | |||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.Optional; | import java.util.Optional; | ||||||
| import java.util.UUID; | import java.util.UUID; | ||||||
|  | import java.util.concurrent.CompletableFuture; | ||||||
|  |  | ||||||
| public class PlotListener { | public class PlotListener { | ||||||
|  |  | ||||||
| @@ -321,22 +320,27 @@ 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(); | ||||||
|                             ComponentLike owner = PlayerManager.resolveName(plotOwner, true).toComponent(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" + | ||||||
|                                     ".title_entered_plot_sub"); |                                     ".title_entered_plot_sub"); | ||||||
|                             TagResolver resolver = TagResolver.builder() |  | ||||||
|  |                             CompletableFuture<TagResolver> future = PlotSquared.platform().playerManager() | ||||||
|  |                                     .getUsernameCaption(plotOwner).thenApply(caption -> TagResolver.builder() | ||||||
|  |                                             .tag("owner", Tag.inserting(caption.toComponent(player))) | ||||||
|                                             .tag("plot", Tag.inserting(Component.text(lastPlot.getId().toString()))) |                                             .tag("plot", Tag.inserting(Component.text(lastPlot.getId().toString()))) | ||||||
|                                             .tag("world", Tag.inserting(Component.text(player.getLocation().getWorldName()))) |                                             .tag("world", Tag.inserting(Component.text(player.getLocation().getWorldName()))) | ||||||
|                                     .tag("owner", Tag.inserting(owner)) |  | ||||||
|                                             .tag("alias", Tag.inserting(Component.text(plot.getAlias()))) |                                             .tag("alias", Tag.inserting(Component.text(plot.getAlias()))) | ||||||
|                                     .build(); |                                             .build() | ||||||
|  |                                     ); | ||||||
|  |  | ||||||
|  |                             future.whenComplete((tagResolver, throwable) -> { | ||||||
|                                 if (Settings.Titles.TITLES_AS_ACTIONBAR) { |                                 if (Settings.Titles.TITLES_AS_ACTIONBAR) { | ||||||
|                                 player.sendActionBar(header, resolver); |                                     player.sendActionBar(header, tagResolver); | ||||||
|                                 } else { |                                 } else { | ||||||
|                                 player.sendTitle(header, subHeader, resolver); |                                     player.sendTitle(header, subHeader, tagResolver); | ||||||
|                                 } |                                 } | ||||||
|  |                             }); | ||||||
|                         } |                         } | ||||||
|                     }, TaskTime.seconds(1L)); |                     }, TaskTime.seconds(1L)); | ||||||
|                 } |                 } | ||||||
|   | |||||||
| @@ -66,7 +66,7 @@ public final class UncheckedWorldLocation extends Location { | |||||||
|      * @param world World |      * @param world World | ||||||
|      * @param loc   Coordinates |      * @param loc   Coordinates | ||||||
|      * @return New location |      * @return New location | ||||||
|      * @since TODO |      * @since 7.0.0 | ||||||
|      */ |      */ | ||||||
|     @DoNotUse |     @DoNotUse | ||||||
|     public static @NonNull UncheckedWorldLocation at(final @NonNull String world, BlockVector3 loc) { |     public static @NonNull UncheckedWorldLocation at(final @NonNull String world, BlockVector3 loc) { | ||||||
|   | |||||||
| @@ -45,6 +45,7 @@ public enum Permission implements ComponentLike { | |||||||
|     PERMISSION_ADMIN_ENTRY_FORCEFIELD("plots.admin.entry.forcefield"), |     PERMISSION_ADMIN_ENTRY_FORCEFIELD("plots.admin.entry.forcefield"), | ||||||
|     PERMISSION_ADMIN_COMMANDS_CHATSPY("plots.admin.command.chatspy"), |     PERMISSION_ADMIN_COMMANDS_CHATSPY("plots.admin.command.chatspy"), | ||||||
|     PERMISSION_MERGE("plots.merge"), |     PERMISSION_MERGE("plots.merge"), | ||||||
|  |     PERMISSION_MERGE_ALL("plots.merge.all"), | ||||||
|     PERMISSION_MERGE_OTHER("plots.merge.other"), |     PERMISSION_MERGE_OTHER("plots.merge.other"), | ||||||
|     PERMISSION_MERGE_KEEP_ROAD("plots.merge.keeproad"), |     PERMISSION_MERGE_KEEP_ROAD("plots.merge.keeproad"), | ||||||
|     PERMISSION_ADMIN_CAPS_OTHER("plots.admin.caps.other"), |     PERMISSION_ADMIN_CAPS_OTHER("plots.admin.caps.other"), | ||||||
| @@ -200,7 +201,8 @@ public enum Permission implements ComponentLike { | |||||||
|     PERMISSION_RATE("plots.rate"), |     PERMISSION_RATE("plots.rate"), | ||||||
|     PERMISSION_ADMIN_FLIGHT("plots.admin.flight"), |     PERMISSION_ADMIN_FLIGHT("plots.admin.flight"), | ||||||
|     PERMISSION_ADMIN_COMPONENTS_OTHER("plots.admin.component.other"), |     PERMISSION_ADMIN_COMPONENTS_OTHER("plots.admin.component.other"), | ||||||
|     PERMISSION_ADMIN_BYPASS_BORDER("plots.admin.border.bypass"); |     PERMISSION_ADMIN_BYPASS_BORDER("plots.admin.border.bypass"), | ||||||
|  |     PERMISSION_ADMIN_BYPASS_ECON("plots.admin.econ.bypass"); | ||||||
|     //</editor-fold> |     //</editor-fold> | ||||||
|  |  | ||||||
|     private final String text; |     private final String text; | ||||||
|   | |||||||
| @@ -25,9 +25,9 @@ import java.util.UUID; | |||||||
| public interface OfflinePlotPlayer extends PermissionHolder { | public interface OfflinePlotPlayer extends PermissionHolder { | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Gets the {@code UUID} of this player |      * Returns the UUID of the player. | ||||||
|      * |      * | ||||||
|      * @return the player {@link UUID} |      * @return the UUID of the player | ||||||
|      */ |      */ | ||||||
|     UUID getUUID(); |     UUID getUUID(); | ||||||
|  |  | ||||||
| @@ -39,9 +39,9 @@ public interface OfflinePlotPlayer extends PermissionHolder { | |||||||
|     long getLastPlayed(); |     long getLastPlayed(); | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Gets the name of this player. |      * Returns the name of the player. | ||||||
|      * |      * | ||||||
|      * @return the player name |      * @return the name of the player | ||||||
|      */ |      */ | ||||||
|     String getName(); |     String getName(); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -80,6 +80,7 @@ import java.util.Map; | |||||||
| import java.util.Queue; | import java.util.Queue; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| import java.util.UUID; | import java.util.UUID; | ||||||
|  | import java.util.concurrent.CompletableFuture; | ||||||
| import java.util.concurrent.ConcurrentHashMap; | import java.util.concurrent.ConcurrentHashMap; | ||||||
| import java.util.concurrent.atomic.AtomicInteger; | import java.util.concurrent.atomic.AtomicInteger; | ||||||
|  |  | ||||||
| @@ -273,8 +274,9 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer, | |||||||
|         return this.meta == null ? null : this.meta.remove(key); |         return this.meta == null ? null : this.meta.remove(key); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * This player's name. |      * Returns the name of the player. | ||||||
|      * |      * | ||||||
|      * @return the name of the player |      * @return the name of the player | ||||||
|      */ |      */ | ||||||
| @@ -880,7 +882,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer, | |||||||
|         final Component titleComponent = MiniMessage.miniMessage().deserialize(title.getComponent(this), replacements); |         final Component titleComponent = MiniMessage.miniMessage().deserialize(title.getComponent(this), replacements); | ||||||
|         final Component subtitleComponent = |         final Component subtitleComponent = | ||||||
|                 MiniMessage.miniMessage().deserialize(subtitle.getComponent(this), replacements); |                 MiniMessage.miniMessage().deserialize(subtitle.getComponent(this), replacements); | ||||||
|         final Title.Times times = Title.Times.of( |         final Title.Times times = Title.Times.times( | ||||||
|                 Duration.of(Settings.Titles.TITLES_FADE_IN * 50L, ChronoUnit.MILLIS), |                 Duration.of(Settings.Titles.TITLES_FADE_IN * 50L, ChronoUnit.MILLIS), | ||||||
|                 Duration.of(Settings.Titles.TITLES_STAY * 50L, ChronoUnit.MILLIS), |                 Duration.of(Settings.Titles.TITLES_STAY * 50L, ChronoUnit.MILLIS), | ||||||
|                 Duration.of(Settings.Titles.TITLES_FADE_OUT * 50L, ChronoUnit.MILLIS) |                 Duration.of(Settings.Titles.TITLES_FADE_OUT * 50L, ChronoUnit.MILLIS) | ||||||
| @@ -952,6 +954,54 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer, | |||||||
|         } |         } | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Sends a message to the command caller, when the future is resolved | ||||||
|  |      * | ||||||
|  |      * @param caption          Caption to send | ||||||
|  |      * @param asyncReplacement Async variable replacement | ||||||
|  |      * @return A Future to be resolved, after the message was sent | ||||||
|  |      * @since 7.1.0 | ||||||
|  |      */ | ||||||
|  |     public final CompletableFuture<Void> sendMessage( | ||||||
|  |             @NonNull Caption caption, | ||||||
|  |             CompletableFuture<@NonNull TagResolver> asyncReplacement | ||||||
|  |     ) { | ||||||
|  |         return sendMessage(caption, new CompletableFuture[]{asyncReplacement}); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Sends a message to the command caller, when all futures are resolved | ||||||
|  |      * | ||||||
|  |      * @param caption           Caption to send | ||||||
|  |      * @param asyncReplacements Async variable replacements | ||||||
|  |      * @param replacements      Sync variable replacements | ||||||
|  |      * @return A Future to be resolved, after the message was sent | ||||||
|  |      * @since 7.1.0 | ||||||
|  |      */ | ||||||
|  |     public final CompletableFuture<Void> sendMessage( | ||||||
|  |             @NonNull Caption caption, | ||||||
|  |             CompletableFuture<@NonNull TagResolver>[] asyncReplacements, | ||||||
|  |             @NonNull TagResolver... replacements | ||||||
|  |     ) { | ||||||
|  |         return CompletableFuture.allOf(asyncReplacements).whenComplete((unused, throwable) -> { | ||||||
|  |             Set<TagResolver> resolvers = new HashSet<>(Arrays.asList(replacements)); | ||||||
|  |             if (throwable != null) { | ||||||
|  |                 sendMessage( | ||||||
|  |                         TranslatableCaption.of("errors.error"), | ||||||
|  |                         TagResolver.resolver("value", Tag.inserting( | ||||||
|  |                                 Component.text("Failed to resolve asynchronous caption replacements") | ||||||
|  |                         )) | ||||||
|  |                 ); | ||||||
|  |                 LOGGER.error("Failed to resolve asynchronous tagresolver(s) for " + caption, throwable); | ||||||
|  |             } else { | ||||||
|  |                 for (final CompletableFuture<TagResolver> asyncReplacement : asyncReplacements) { | ||||||
|  |                     resolvers.add(asyncReplacement.join()); | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             sendMessage(caption, resolvers.toArray(TagResolver[]::new)); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Redefine from PermissionHolder as it's required from CommandCaller |     // Redefine from PermissionHolder as it's required from CommandCaller | ||||||
|     @Override |     @Override | ||||||
|     public boolean hasPermission(@NonNull String permission) { |     public boolean hasPermission(@NonNull String permission) { | ||||||
|   | |||||||
| @@ -51,6 +51,8 @@ import com.plotsquared.core.util.MathMan; | |||||||
| import com.plotsquared.core.util.PlotExpression; | import com.plotsquared.core.util.PlotExpression; | ||||||
| import com.plotsquared.core.util.RegionUtil; | import com.plotsquared.core.util.RegionUtil; | ||||||
| import com.plotsquared.core.util.StringMan; | import com.plotsquared.core.util.StringMan; | ||||||
|  | import com.plotsquared.core.util.task.TaskManager; | ||||||
|  | import com.plotsquared.core.util.task.TaskTime; | ||||||
| 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; | ||||||
| @@ -391,6 +393,28 @@ public abstract class PlotArea implements ComponentLike { | |||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         this.spawnEggs = config.getBoolean("event.spawn.egg"); | ||||||
|  |         this.spawnCustom = config.getBoolean("event.spawn.custom"); | ||||||
|  |         this.spawnBreeding = config.getBoolean("event.spawn.breeding"); | ||||||
|  |  | ||||||
|  |         if (PlotSquared.get().isWeInitialised()) { | ||||||
|  |             loadFlags(config); | ||||||
|  |         } else { | ||||||
|  |             ConsolePlayer.getConsole().sendMessage( | ||||||
|  |                     TranslatableCaption.of("flags.delaying_loading_area_flags"), | ||||||
|  |                     TagResolver.resolver("area", Tag.inserting(Component.text(this.id == null ? this.worldName : this.id))) | ||||||
|  |             ); | ||||||
|  |             TaskManager.runTaskLater(() -> loadFlags(config), TaskTime.ticks(1)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         loadConfiguration(config); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     private void loadFlags(ConfigurationSection config) { | ||||||
|  |         ConsolePlayer.getConsole().sendMessage( | ||||||
|  |                 TranslatableCaption.of("flags.loading_area_flags"), | ||||||
|  |                 TagResolver.resolver("area", Tag.inserting(Component.text(this.id == null ? this.worldName : this.id))) | ||||||
|  |         ); | ||||||
|         List<String> flags = config.getStringList("flags.default"); |         List<String> flags = config.getStringList("flags.default"); | ||||||
|         if (flags.isEmpty()) { |         if (flags.isEmpty()) { | ||||||
|             flags = config.getStringList("flags"); |             flags = config.getStringList("flags"); | ||||||
| @@ -411,10 +435,6 @@ public abstract class PlotArea implements ComponentLike { | |||||||
|                 TagResolver.resolver("flags", Tag.inserting(Component.text(flags.toString()))) |                 TagResolver.resolver("flags", Tag.inserting(Component.text(flags.toString()))) | ||||||
|         ); |         ); | ||||||
|  |  | ||||||
|         this.spawnEggs = config.getBoolean("event.spawn.egg"); |  | ||||||
|         this.spawnCustom = config.getBoolean("event.spawn.custom"); |  | ||||||
|         this.spawnBreeding = config.getBoolean("event.spawn.breeding"); |  | ||||||
|  |  | ||||||
|         List<String> roadflags = config.getStringList("road.flags"); |         List<String> roadflags = config.getStringList("road.flags"); | ||||||
|         if (roadflags.isEmpty()) { |         if (roadflags.isEmpty()) { | ||||||
|             roadflags = new ArrayList<>(); |             roadflags = new ArrayList<>(); | ||||||
| @@ -426,14 +446,12 @@ public abstract class PlotArea implements ComponentLike { | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|         this.roadFlags = roadflags.size() > 0; |         this.roadFlags = !roadflags.isEmpty(); | ||||||
|         parseFlags(this.getRoadFlagContainer(), roadflags); |         parseFlags(this.getRoadFlagContainer(), roadflags); | ||||||
|         ConsolePlayer.getConsole().sendMessage( |         ConsolePlayer.getConsole().sendMessage( | ||||||
|                 TranslatableCaption.of("flags.road_flags"), |                 TranslatableCaption.of("flags.road_flags"), | ||||||
|                 TagResolver.resolver("flags", Tag.inserting(Component.text(roadflags.toString()))) |                 TagResolver.resolver("flags", Tag.inserting(Component.text(roadflags.toString()))) | ||||||
|         ); |         ); | ||||||
|  |  | ||||||
|         loadConfiguration(config); |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public abstract void loadConfiguration(ConfigurationSection config); |     public abstract void loadConfiguration(ConfigurationSection config); | ||||||
|   | |||||||
| @@ -26,8 +26,8 @@ import java.util.Iterator; | |||||||
| import java.util.NoSuchElementException; | import java.util.NoSuchElementException; | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * Plot (X,Y) tuples for plot locations |  * The PlotId class represents a Plot's x and y coordinates within a {@link PlotArea}. PlotId x,y values do not correspond to Block locations. | ||||||
|  * within a plot area |  * A PlotId instance can be created using the {@link #of(int, int)} method or parsed from a string using the {@link #fromString(String)} method. | ||||||
|  */ |  */ | ||||||
| public final class PlotId { | public final class PlotId { | ||||||
|  |  | ||||||
| @@ -36,10 +36,10 @@ public final class PlotId { | |||||||
|     private final int hash; |     private final int hash; | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * PlotId class (PlotId x,y values do not correspond to Block locations) |      * Constructs a new PlotId with the given x and y coordinates. | ||||||
|      * |      * | ||||||
|      * @param x The plot x coordinate |      * @param x the x-coordinate of the plot | ||||||
|      * @param y The plot y coordinate |      * @param y the y-coordinate of the plot | ||||||
|      */ |      */ | ||||||
|     private PlotId(final int x, final int y) { |     private PlotId(final int x, final int y) { | ||||||
|         this.x = x; |         this.x = x; | ||||||
| @@ -48,11 +48,11 @@ public final class PlotId { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Create a new plot ID instance |      * Returns a new PlotId instance with the specified x and y coordinates. | ||||||
|      * |      * | ||||||
|      * @param x The plot x coordinate |      * @param x the x-coordinate of the plot | ||||||
|      * @param y The plot y coordinate |      * @param y the y-coordinate of the plot | ||||||
|      * @return a new PlotId at x,y |      * @return a new PlotId instance with the specified x and y coordinates | ||||||
|      */ |      */ | ||||||
|     public static @NonNull PlotId of(final int x, final int y) { |     public static @NonNull PlotId of(final int x, final int y) { | ||||||
|         return new PlotId(x, y); |         return new PlotId(x, y); | ||||||
| @@ -74,10 +74,13 @@ public final class PlotId { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Attempt to parse a plot ID from a string |      * Returns a PlotId object from the given string, or null if the string is invalid. | ||||||
|  |      * The string should be in the format "x;y" where x and y are integers. | ||||||
|  |      * The string can also contain any combination of the characters ";_,." | ||||||
|  |      * as delimiters. | ||||||
|      * |      * | ||||||
|      * @param string ID string |      * @param string the string to parse | ||||||
|      * @return Plot ID, or {@code null} if none could be parsed |      * @return a PlotId object parsed from the given string, or null if the string is invalid | ||||||
|      */ |      */ | ||||||
|     public static @Nullable PlotId fromStringOrNull(final @NonNull String string) { |     public static @Nullable PlotId fromStringOrNull(final @NonNull String string) { | ||||||
|         final String[] parts = string.split("[;_,.]"); |         final String[] parts = string.split("[;_,.]"); | ||||||
| @@ -95,39 +98,39 @@ public final class PlotId { | |||||||
|         return of(x, y); |         return of(x, y); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Gets the PlotId from the HashCode<br> |      * Returns a new PlotId instance from the given hash. | ||||||
|      * Note: Only accurate for small x,z values (short) |  | ||||||
|      * |      * | ||||||
|      * @param hash ID hash |      * @param hash the hash to unpair | ||||||
|      * @return Plot ID |      * @return a new PlotId instance | ||||||
|      */ |      */ | ||||||
|     public static @NonNull PlotId unpair(final int hash) { |     public static @NonNull PlotId unpair(final int hash) { | ||||||
|         return PlotId.of(hash >> 16, hash & 0xFFFF); |         return PlotId.of(hash >> 16, hash & 0xFFFF); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get the ID X component |      * Returns the x-coordinate of this Plot ID. | ||||||
|      * |      * | ||||||
|      * @return X component |      * @return the x-coordinate of this Plot ID | ||||||
|      */ |      */ | ||||||
|     public int getX() { |     public int getX() { | ||||||
|         return this.x; |         return this.x; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get the ID Y component |      * Returns the y-coordinate of this Plot ID. | ||||||
|      * |      * | ||||||
|      * @return Y component |      * @return the y-coordinate of this Plot ID | ||||||
|      */ |      */ | ||||||
|     public int getY() { |     public int getY() { | ||||||
|         return this.y; |         return this.y; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get the next plot ID for claiming purposes |      * Returns the next Plot ID for claiming purposes based on the current Plot ID. | ||||||
|      * |      * | ||||||
|      * @return Next plot ID |      * @return the next Plot ID | ||||||
|      */ |      */ | ||||||
|     public @NonNull PlotId getNextId() { |     public @NonNull PlotId getNextId() { | ||||||
|         final int absX = Math.abs(x); |         final int absX = Math.abs(x); | ||||||
| @@ -159,10 +162,11 @@ public final class PlotId { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get the PlotId in a relative direction |      * Returns a new Plot ID in the specified relative direction based on the | ||||||
|  |      * current Plot ID. | ||||||
|      * |      * | ||||||
|      * @param direction Direction |      * @param direction the direction in which to get the relative Plot ID | ||||||
|      * @return Relative plot ID |      * @return the relative Plot ID | ||||||
|      */ |      */ | ||||||
|     public @NonNull PlotId getRelative(final @NonNull Direction direction) { |     public @NonNull PlotId getRelative(final @NonNull Direction direction) { | ||||||
|         return switch (direction) { |         return switch (direction) { | ||||||
| @@ -193,10 +197,11 @@ public final class PlotId { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get a String representation of the plot ID where the |      * Returns a string representation of this Plot ID in the format "x;y". | ||||||
|      * components are separated by ";" |  | ||||||
|      * |      * | ||||||
|      * @return {@code x + ";" + y} |      * <p> The format is {@code x + ";" + y} | ||||||
|  |      * | ||||||
|  |      * @return a string representation of this Plot ID | ||||||
|      */ |      */ | ||||||
|     @Override |     @Override | ||||||
|     public @NonNull String toString() { |     public @NonNull String toString() { | ||||||
| @@ -204,41 +209,40 @@ public final class PlotId { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get a String representation of the plot ID where the |      * Returns a string representation of this Plot ID with the specified separator. | ||||||
|      * components are separated by a specified string |      * <p> | ||||||
|  |      * The format is {@code x + separator + y} | ||||||
|      * |      * | ||||||
|      * @param separator Separator |      * @param separator the separator to use between the X and Y coordinates | ||||||
|      * @return {@code x + separator + y} |      * @return a string representation of this Plot ID with the specified separator | ||||||
|      */ |      */ | ||||||
|     public @NonNull String toSeparatedString(String separator) { |     public @NonNull String toSeparatedString(String separator) { | ||||||
|         return this.getX() + separator + this.getY(); |         return this.getX() + separator + this.getY(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get a String representation of the plot ID where the |      * Returns a string representation of this Plot ID in the format "x,y". | ||||||
|      * components are separated by "," |  | ||||||
|      * |      * | ||||||
|      * @return {@code x + "," + y} |      * @return a string representation of this Plot ID | ||||||
|      */ |      */ | ||||||
|     public @NonNull String toCommaSeparatedString() { |     public @NonNull String toCommaSeparatedString() { | ||||||
|         return this.getX() + "," + this.getY(); |         return this.getX() + "," + this.getY(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get a String representation of the plot ID where the |      * Returns a string representation of this Plot ID in the format "x_y". | ||||||
|      * components are separated by "_" |  | ||||||
|      * |      * | ||||||
|      * @return {@code x + "_" + y} |      * @return a string representation of this Plot ID | ||||||
|      */ |      */ | ||||||
|  |  | ||||||
|     public @NonNull String toUnderscoreSeparatedString() { |     public @NonNull String toUnderscoreSeparatedString() { | ||||||
|         return this.getX() + "_" + this.getY(); |         return this.getX() + "_" + this.getY(); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Get a String representation of the plot ID where the |      * Returns a string representation of this Plot ID in the format "x-y". | ||||||
|      * components are separated by "-" |  | ||||||
|      * |      * | ||||||
|      * @return {@code x + "-" + y} |      * @return a string representation of this Plot ID | ||||||
|      */ |      */ | ||||||
|     public @NonNull String toDashSeparatedString() { |     public @NonNull String toDashSeparatedString() { | ||||||
|         return this.getX() + "-" + this.getY(); |         return this.getX() + "-" + this.getY(); | ||||||
| @@ -250,6 +254,10 @@ public final class PlotId { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * An iterator that iterates over a range of {@link PlotId}s. | ||||||
|  |      * The range is defined by a start and end {@link PlotId}. | ||||||
|  |      */ | ||||||
|     public static final class PlotRangeIterator implements Iterator<PlotId>, Iterable<PlotId> { |     public static final class PlotRangeIterator implements Iterator<PlotId>, Iterable<PlotId> { | ||||||
|  |  | ||||||
|         private final PlotId start; |         private final PlotId start; | ||||||
| @@ -265,6 +273,13 @@ public final class PlotId { | |||||||
|             this.y = this.start.getY(); |             this.y = this.start.getY(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|  |         /** | ||||||
|  |          * Returns a new {@link PlotRangeIterator} that iterates over the range of Plots between the specified start and end Plots (inclusive). | ||||||
|  |          * | ||||||
|  |          * @param start the starting Plot of the range | ||||||
|  |          * @param end the ending Plot of the range | ||||||
|  |          * @return a new {@link PlotRangeIterator} that iterates over the range of Plots between the specified start and end Plots (inclusive) | ||||||
|  |          */ | ||||||
|         public static PlotRangeIterator range(final @NonNull PlotId start, final @NonNull PlotId end) { |         public static PlotRangeIterator range(final @NonNull PlotId start, final @NonNull PlotId end) { | ||||||
|             return new PlotRangeIterator(start, end); |             return new PlotRangeIterator(start, end); | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -67,14 +67,25 @@ public class PlotItemStack { | |||||||
|         return this.type; |         return this.type; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the number of items in this stack. | ||||||
|  |      * Valid values range from 1-255. | ||||||
|  |      * | ||||||
|  |      * @return the amount of items in this stack | ||||||
|  |      */ | ||||||
|     public int getAmount() { |     public int getAmount() { | ||||||
|         return amount; |         return amount; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Returns the given name of this stack of items. The name is displayed when | ||||||
|  |      * hovering over the item. | ||||||
|  |      * | ||||||
|  |      * @return the given name of this stack of items | ||||||
|  |      */ | ||||||
|     public String getName() { |     public String getName() { | ||||||
|         return name; |         return name; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     public String[] getLore() { |     public String[] getLore() { | ||||||
|         return lore; |         return lore; | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -38,7 +38,6 @@ import com.plotsquared.core.location.Location; | |||||||
| import com.plotsquared.core.player.PlotPlayer; | import com.plotsquared.core.player.PlotPlayer; | ||||||
| import com.plotsquared.core.plot.flag.PlotFlag; | import com.plotsquared.core.plot.flag.PlotFlag; | ||||||
| import com.plotsquared.core.queue.QueueCoordinator; | import com.plotsquared.core.queue.QueueCoordinator; | ||||||
| import com.plotsquared.core.util.PlayerManager; |  | ||||||
| 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; | ||||||
| import com.sk89q.worldedit.function.pattern.Pattern; | import com.sk89q.worldedit.function.pattern.Pattern; | ||||||
| @@ -59,6 +58,7 @@ import java.util.ArrayList; | |||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| import java.util.HashSet; | import java.util.HashSet; | ||||||
| import java.util.Iterator; | import java.util.Iterator; | ||||||
|  | import java.util.List; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| import java.util.UUID; | import java.util.UUID; | ||||||
| import java.util.concurrent.CompletableFuture; | import java.util.concurrent.CompletableFuture; | ||||||
| @@ -383,13 +383,17 @@ public final class PlotModificationManager { | |||||||
|         } |         } | ||||||
|         if (createSign) { |         if (createSign) { | ||||||
|             queue.setCompleteTask(() -> TaskManager.runTaskAsync(() -> { |             queue.setCompleteTask(() -> TaskManager.runTaskAsync(() -> { | ||||||
|                 for (Plot current : plots) { |                 List<CompletableFuture<Void>> tasks = plots.stream().map(current -> PlotSquared.platform().playerManager() | ||||||
|                     current.getPlotModificationManager().setSign(PlayerManager.resolveName(current.getOwnerAbs()).getComponent( |                                 .getUsernameCaption(current.getOwnerAbs()) | ||||||
|                             LocaleHolder.console())); |                                 .thenAccept(caption -> current | ||||||
|                 } |                                         .getPlotModificationManager() | ||||||
|  |                                         .setSign(caption.getComponent(LocaleHolder.console())))) | ||||||
|  |                         .toList(); | ||||||
|  |                 CompletableFuture.allOf(tasks.toArray(CompletableFuture[]::new)).whenComplete((unused, throwable) -> { | ||||||
|                     if (whenDone != null) { |                     if (whenDone != null) { | ||||||
|                         TaskManager.runTask(whenDone); |                         TaskManager.runTask(whenDone); | ||||||
|                     } |                     } | ||||||
|  |                 }); | ||||||
|             })); |             })); | ||||||
|         } else if (whenDone != null) { |         } else if (whenDone != null) { | ||||||
|             queue.setCompleteTask(whenDone); |             queue.setCompleteTask(whenDone); | ||||||
| @@ -891,7 +895,6 @@ public final class PlotModificationManager { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * /** |  | ||||||
|      * Sets components such as border, wall, floor. |      * Sets components such as border, wall, floor. | ||||||
|      * (components are generator specific) |      * (components are generator specific) | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -18,9 +18,25 @@ | |||||||
|  */ |  */ | ||||||
| package com.plotsquared.core.plot; | package com.plotsquared.core.plot; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * The different types of weather that can be set for a Plot. | ||||||
|  |  */ | ||||||
| public enum PlotWeather { | public enum PlotWeather { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Rainy weather conditions | ||||||
|  |      */ | ||||||
|     RAIN, |     RAIN, | ||||||
|  |     /** | ||||||
|  |      * Clear weather conditions | ||||||
|  |      */ | ||||||
|     CLEAR, |     CLEAR, | ||||||
|  |     /** | ||||||
|  |      * Use the weather of the world the plot is in | ||||||
|  |      */ | ||||||
|     WORLD, |     WORLD, | ||||||
|  |     /** | ||||||
|  |      * Turn off weather for the plot | ||||||
|  |      */ | ||||||
|     OFF |     OFF | ||||||
| } | } | ||||||
|   | |||||||
| @@ -29,6 +29,7 @@ import com.plotsquared.core.plot.flag.implementations.BlockIgnitionFlag; | |||||||
| import com.plotsquared.core.plot.flag.implementations.BlockedCmdsFlag; | import com.plotsquared.core.plot.flag.implementations.BlockedCmdsFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.BreakFlag; | import com.plotsquared.core.plot.flag.implementations.BreakFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.ChatFlag; | import com.plotsquared.core.plot.flag.implementations.ChatFlag; | ||||||
|  | import com.plotsquared.core.plot.flag.implementations.ConcreteHardenFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.CopperOxideFlag; | import com.plotsquared.core.plot.flag.implementations.CopperOxideFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.CoralDryFlag; | import com.plotsquared.core.plot.flag.implementations.CoralDryFlag; | ||||||
| import com.plotsquared.core.plot.flag.implementations.CropGrowFlag; | import com.plotsquared.core.plot.flag.implementations.CropGrowFlag; | ||||||
| @@ -142,6 +143,7 @@ public final class GlobalFlagContainer extends FlagContainer { | |||||||
|         this.addFlag(BeaconEffectsFlag.BEACON_EFFECT_TRUE); |         this.addFlag(BeaconEffectsFlag.BEACON_EFFECT_TRUE); | ||||||
|         this.addFlag(BlockIgnitionFlag.BLOCK_IGNITION_TRUE); |         this.addFlag(BlockIgnitionFlag.BLOCK_IGNITION_TRUE); | ||||||
|         this.addFlag(ChatFlag.CHAT_FLAG_TRUE); |         this.addFlag(ChatFlag.CHAT_FLAG_TRUE); | ||||||
|  |         this.addFlag(ConcreteHardenFlag.CONCRETE_HARDEN_TRUE); | ||||||
|         this.addFlag(CopperOxideFlag.COPPER_OXIDE_FALSE); |         this.addFlag(CopperOxideFlag.COPPER_OXIDE_FALSE); | ||||||
|         this.addFlag(CoralDryFlag.CORAL_DRY_FALSE); |         this.addFlag(CoralDryFlag.CORAL_DRY_FALSE); | ||||||
|         this.addFlag(CropGrowFlag.CROP_GROW_TRUE); |         this.addFlag(CropGrowFlag.CROP_GROW_TRUE); | ||||||
|   | |||||||
| @@ -0,0 +1,39 @@ | |||||||
|  | /* | ||||||
|  |  * PlotSquared, a land and world management plugin for Minecraft. | ||||||
|  |  * Copyright (C) IntellectualSites <https://intellectualsites.com> | ||||||
|  |  * Copyright (C) IntellectualSites team and contributors | ||||||
|  |  * | ||||||
|  |  * This program is free software: you can redistribute it and/or modify | ||||||
|  |  * it under the terms of the GNU General Public License as published by | ||||||
|  |  * the Free Software Foundation, either version 3 of the License, or | ||||||
|  |  * (at your option) any later version. | ||||||
|  |  * | ||||||
|  |  * This program is distributed in the hope that it will be useful, | ||||||
|  |  * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  |  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  |  * GNU General Public License for more details. | ||||||
|  |  * | ||||||
|  |  * You should have received a copy of the GNU General Public License | ||||||
|  |  * along with this program.  If not, see <https://www.gnu.org/licenses/>. | ||||||
|  |  */ | ||||||
|  | package com.plotsquared.core.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 ConcreteHardenFlag extends BooleanFlag<ConcreteHardenFlag> { | ||||||
|  |  | ||||||
|  |     public static final ConcreteHardenFlag CONCRETE_HARDEN_TRUE = new ConcreteHardenFlag(true); | ||||||
|  |     public static final ConcreteHardenFlag CONCRETE_HARDEN_FALSE = new ConcreteHardenFlag(false); | ||||||
|  |  | ||||||
|  |     private ConcreteHardenFlag(boolean value) { | ||||||
|  |         super(value, TranslatableCaption.of("flags.flag_description_concrete_harden")); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     protected ConcreteHardenFlag flagOf(@NonNull Boolean value) { | ||||||
|  |         return value ? CONCRETE_HARDEN_TRUE : CONCRETE_HARDEN_FALSE; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -183,7 +183,7 @@ public class ChunkCoordinatorBuilder { | |||||||
|      * Set whether the chunks should be allow to unload after being accessed. This should only be used where the chunks are read from |      * Set whether the chunks should be allow to unload after being accessed. This should only be used where the chunks are read from | ||||||
|      * and then written to from a separate queue where they're consequently unloaded. |      * and then written to from a separate queue where they're consequently unloaded. | ||||||
|      * |      * | ||||||
|      * @param unloadAfter if to unload chuns afterwards |      * @param unloadAfter if to unload chunks afterwards | ||||||
|      * @return this ChunkCoordinatorBuilder instance |      * @return this ChunkCoordinatorBuilder instance | ||||||
|      */ |      */ | ||||||
|     public @NonNull ChunkCoordinatorBuilder unloadAfter(final boolean unloadAfter) { |     public @NonNull ChunkCoordinatorBuilder unloadAfter(final boolean unloadAfter) { | ||||||
|   | |||||||
| @@ -42,28 +42,14 @@ public class EntityUtil { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     private static int capNumeral(final @NonNull String flagName) { |     private static int capNumeral(final @NonNull String flagName) { | ||||||
|         int i; |         return switch (flagName) { | ||||||
|         switch (flagName) { |             case "mob-cap" -> CAP_MOB; | ||||||
|             case "mob-cap": |             case "hostile-cap" -> CAP_MONSTER; | ||||||
|                 i = CAP_MOB; |             case "animal-cap" -> CAP_ANIMAL; | ||||||
|                 break; |             case "vehicle-cap" -> CAP_VEHICLE; | ||||||
|             case "hostile-cap": |             case "misc-cap" -> CAP_MISC; | ||||||
|                 i = CAP_MONSTER; |             default -> CAP_ENTITY; | ||||||
|                 break; |         }; | ||||||
|             case "animal-cap": |  | ||||||
|                 i = CAP_ANIMAL; |  | ||||||
|                 break; |  | ||||||
|             case "vehicle-cap": |  | ||||||
|                 i = CAP_VEHICLE; |  | ||||||
|                 break; |  | ||||||
|             case "misc-cap": |  | ||||||
|                 i = CAP_MISC; |  | ||||||
|                 break; |  | ||||||
|             case "entity-cap": |  | ||||||
|             default: |  | ||||||
|                 i = CAP_ENTITY; |  | ||||||
|         } |  | ||||||
|         return i; |  | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @SuppressWarnings("unchecked") |     @SuppressWarnings("unchecked") | ||||||
|   | |||||||
| @@ -28,6 +28,7 @@ import com.plotsquared.core.database.DBFunc; | |||||||
| import com.plotsquared.core.player.ConsolePlayer; | import com.plotsquared.core.player.ConsolePlayer; | ||||||
| import com.plotsquared.core.player.OfflinePlotPlayer; | import com.plotsquared.core.player.OfflinePlotPlayer; | ||||||
| import com.plotsquared.core.player.PlotPlayer; | import com.plotsquared.core.player.PlotPlayer; | ||||||
|  | import com.plotsquared.core.plot.Plot; | ||||||
| import com.plotsquared.core.uuid.UUIDMapping; | import com.plotsquared.core.uuid.UUIDMapping; | ||||||
| import net.kyori.adventure.text.Component; | import net.kyori.adventure.text.Component; | ||||||
| import net.kyori.adventure.text.ComponentLike; | import net.kyori.adventure.text.ComponentLike; | ||||||
| @@ -37,6 +38,7 @@ import net.kyori.adventure.text.minimessage.tag.Tag; | |||||||
| import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; | import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; | ||||||
| import org.checkerframework.checker.nullness.qual.NonNull; | import org.checkerframework.checker.nullness.qual.NonNull; | ||||||
| import org.checkerframework.checker.nullness.qual.Nullable; | import org.checkerframework.checker.nullness.qual.Nullable; | ||||||
|  | import org.jetbrains.annotations.Contract; | ||||||
|  |  | ||||||
| import java.util.ArrayList; | import java.util.ArrayList; | ||||||
| import java.util.Collection; | import java.util.Collection; | ||||||
| @@ -48,6 +50,7 @@ import java.util.List; | |||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.Set; | import java.util.Set; | ||||||
| import java.util.UUID; | import java.util.UUID; | ||||||
|  | import java.util.concurrent.CompletableFuture; | ||||||
| import java.util.concurrent.TimeUnit; | import java.util.concurrent.TimeUnit; | ||||||
| import java.util.function.BiConsumer; | import java.util.function.BiConsumer; | ||||||
|  |  | ||||||
| @@ -169,7 +172,9 @@ public abstract class PlayerManager<P extends PlotPlayer<? extends T>, T> { | |||||||
|      * @return A caption containing either the name, {@code None}, {@code Everyone} or {@code Unknown} |      * @return A caption containing either the name, {@code None}, {@code Everyone} or {@code Unknown} | ||||||
|      * @see #resolveName(UUID, boolean) |      * @see #resolveName(UUID, boolean) | ||||||
|      * @since 6.4.0 |      * @since 6.4.0 | ||||||
|  |      * @deprecated Don't unnecessarily block threads and utilize playerMap - see {@link #getUsernameCaption(UUID)} | ||||||
|      */ |      */ | ||||||
|  |     @Deprecated(since = "7.1.0") | ||||||
|     public static @NonNull Caption resolveName(final @Nullable UUID owner) { |     public static @NonNull Caption resolveName(final @Nullable UUID owner) { | ||||||
|         return resolveName(owner, true); |         return resolveName(owner, true); | ||||||
|     } |     } | ||||||
| @@ -181,7 +186,9 @@ public abstract class PlayerManager<P extends PlotPlayer<? extends T>, T> { | |||||||
|      * @param blocking If the operation should block the current thread for {@link Settings.UUID#BLOCKING_TIMEOUT} milliseconds |      * @param blocking If the operation should block the current thread for {@link Settings.UUID#BLOCKING_TIMEOUT} milliseconds | ||||||
|      * @return A caption containing either the name, {@code None}, {@code Everyone} or {@code Unknown} |      * @return A caption containing either the name, {@code None}, {@code Everyone} or {@code Unknown} | ||||||
|      * @since 6.4.0 |      * @since 6.4.0 | ||||||
|  |      * @deprecated Don't unnecessarily block threads and utilize playerMap - see {@link #getUsernameCaption(UUID)} | ||||||
|      */ |      */ | ||||||
|  |     @Deprecated(since = "7.1.0") | ||||||
|     public static @NonNull Caption resolveName(final @Nullable UUID owner, final boolean blocking) { |     public static @NonNull Caption resolveName(final @Nullable UUID owner, final boolean blocking) { | ||||||
|         if (owner == null) { |         if (owner == null) { | ||||||
|             return TranslatableCaption.of("info.none"); |             return TranslatableCaption.of("info.none"); | ||||||
| @@ -211,6 +218,50 @@ public abstract class PlayerManager<P extends PlotPlayer<? extends T>, T> { | |||||||
|         return StaticCaption.of(name); |         return StaticCaption.of(name); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * Resolves a UUID to a formatted {@link Caption} representing the player behind the UUID. | ||||||
|  |      * Returns a {@link CompletableFuture} instead of a plain {@link UUID} as this method may query the | ||||||
|  |      * {@link com.plotsquared.core.uuid.UUIDPipeline ImpromptuUUIDPipeline}. | ||||||
|  |      * <br> | ||||||
|  |      * Special Cases: | ||||||
|  |      * <ul> | ||||||
|  |      *     <li>{@code null}: Resolves to a {@link TranslatableCaption} with the key {@code info.none}</li> | ||||||
|  |      *     <li>{@link DBFunc#EVERYONE}: Resolves to a {@link TranslatableCaption} with the key {@code info.everyone}</li> | ||||||
|  |      *     <li>{@link DBFunc#SERVER}: Resolves to a {@link TranslatableCaption} with the key {@code info.server}</li> | ||||||
|  |      * </ul> | ||||||
|  |      * <br> | ||||||
|  |      * Otherwise, if the UUID is a valid UUID and not reserved by PlotSquared itself, this method first attempts to query the | ||||||
|  |      * online players ({@link #getPlayerIfExists(UUID)}) for the specific UUID. | ||||||
|  |      * If no online player was found for that UUID, the {@link com.plotsquared.core.uuid.UUIDPipeline ImpromptuUUIDPipeline} is | ||||||
|  |      * queried to retrieve the known username | ||||||
|  |      * | ||||||
|  |      * @param uuid The UUID of the player (for example provided by {@link Plot#getOwner()} | ||||||
|  |      * @return A CompletableFuture resolving to a Caption representing the players name of the uuid | ||||||
|  |      * @since 7.1.0 | ||||||
|  |      */ | ||||||
|  |     @Contract("_->!null") | ||||||
|  |     public @NonNull CompletableFuture<Caption> getUsernameCaption(@Nullable UUID uuid) { | ||||||
|  |         if (uuid == null) { | ||||||
|  |             return CompletableFuture.completedFuture(TranslatableCaption.of("info.none")); | ||||||
|  |         } | ||||||
|  |         if (uuid.equals(DBFunc.EVERYONE)) { | ||||||
|  |             return CompletableFuture.completedFuture(TranslatableCaption.of("info.everyone")); | ||||||
|  |         } | ||||||
|  |         if (uuid.equals(DBFunc.SERVER)) { | ||||||
|  |             return CompletableFuture.completedFuture(TranslatableCaption.of("info.server")); | ||||||
|  |         } | ||||||
|  |         P player = getPlayerIfExists(uuid); | ||||||
|  |         if (player != null) { | ||||||
|  |             return CompletableFuture.completedFuture(StaticCaption.of(player.getName())); | ||||||
|  |         } | ||||||
|  |         return PlotSquared.get().getImpromptuUUIDPipeline().getNames(Collections.singleton(uuid)).thenApply(mapping -> { | ||||||
|  |             if (mapping.isEmpty()) { | ||||||
|  |                 return TranslatableCaption.of("info.unknown"); | ||||||
|  |             } | ||||||
|  |             return StaticCaption.of(mapping.get(0).username()); | ||||||
|  |         }); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|      * Remove a player from the player map |      * Remove a player from the player map | ||||||
|      * |      * | ||||||
|   | |||||||
| @@ -83,6 +83,7 @@ import java.io.OutputStreamWriter; | |||||||
| import java.io.PrintWriter; | import java.io.PrintWriter; | ||||||
| import java.net.HttpURLConnection; | import java.net.HttpURLConnection; | ||||||
| import java.net.MalformedURLException; | import java.net.MalformedURLException; | ||||||
|  | import java.net.URI; | ||||||
| import java.net.URL; | import java.net.URL; | ||||||
| import java.net.URLConnection; | import java.net.URLConnection; | ||||||
| import java.nio.channels.Channels; | import java.nio.channels.Channels; | ||||||
| @@ -144,7 +145,7 @@ public abstract class SchematicHandler { | |||||||
|         } |         } | ||||||
|         final URL url; |         final URL url; | ||||||
|         try { |         try { | ||||||
|             url = new URL(Settings.Web.URL + "?key=" + uuid + "&type=" + extension); |             url = URI.create(Settings.Web.URL + "?key=" + uuid + "&type=" + extension).toURL(); | ||||||
|         } catch (MalformedURLException e) { |         } catch (MalformedURLException e) { | ||||||
|             e.printStackTrace(); |             e.printStackTrace(); | ||||||
|             whenDone.run(); |             whenDone.run(); | ||||||
| @@ -153,7 +154,7 @@ public abstract class SchematicHandler { | |||||||
|         TaskManager.runTaskAsync(() -> { |         TaskManager.runTaskAsync(() -> { | ||||||
|             try { |             try { | ||||||
|                 String boundary = Long.toHexString(System.currentTimeMillis()); |                 String boundary = Long.toHexString(System.currentTimeMillis()); | ||||||
|                 URLConnection con = new URL(website).openConnection(); |                 URLConnection con = URI.create(website).toURL().openConnection(); | ||||||
|                 con.setDoOutput(true); |                 con.setDoOutput(true); | ||||||
|                 con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); |                 con.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); | ||||||
|                 try (OutputStream output = con.getOutputStream(); |                 try (OutputStream output = con.getOutputStream(); | ||||||
| @@ -498,9 +499,10 @@ public abstract class SchematicHandler { | |||||||
|     public List<String> getSaves(UUID uuid) { |     public List<String> getSaves(UUID uuid) { | ||||||
|         String rawJSON; |         String rawJSON; | ||||||
|         try { |         try { | ||||||
|             String website = Settings.Web.URL + "list.php?" + uuid.toString(); |             URLConnection connection = URI.create( | ||||||
|             URL url = new URL(website); |                     Settings.Web.URL + "list.php?" + uuid.toString()) | ||||||
|             URLConnection connection = new URL(url.toString()).openConnection(); |                     .toURL() | ||||||
|  |                     .openConnection(); | ||||||
|             connection.setRequestProperty("User-Agent", "Mozilla/5.0"); |             connection.setRequestProperty("User-Agent", "Mozilla/5.0"); | ||||||
|             try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { |             try (BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()))) { | ||||||
|                 rawJSON = reader.lines().collect(Collectors.joining()); |                 rawJSON = reader.lines().collect(Collectors.joining()); | ||||||
|   | |||||||
| @@ -47,6 +47,7 @@ import java.util.Locale; | |||||||
| import java.util.Map; | import java.util.Map; | ||||||
| import java.util.TimeZone; | import java.util.TimeZone; | ||||||
| import java.util.UUID; | import java.util.UUID; | ||||||
|  | import java.util.concurrent.TimeUnit; | ||||||
| import java.util.function.BiFunction; | import java.util.function.BiFunction; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -109,9 +110,9 @@ public final class PlaceholderRegistry { | |||||||
|             if (plotOwner == null) { |             if (plotOwner == null) { | ||||||
|                 return legacyComponent(TranslatableCaption.of("generic.generic_unowned"), player); |                 return legacyComponent(TranslatableCaption.of("generic.generic_unowned"), player); | ||||||
|             } |             } | ||||||
|  |  | ||||||
|             try { |             try { | ||||||
|                 return PlayerManager.resolveName(plotOwner, false).getComponent(player); |                 return PlotSquared.platform().playerManager().getUsernameCaption(plotOwner) | ||||||
|  |                         .get(Settings.UUID.BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS).getComponent(player); | ||||||
|             } catch (final Exception ignored) { |             } catch (final Exception ignored) { | ||||||
|             } |             } | ||||||
|             return legacyComponent(TranslatableCaption.of("info.unknown"), player); |             return legacyComponent(TranslatableCaption.of("info.unknown"), player); | ||||||
| @@ -187,6 +188,7 @@ public final class PlaceholderRegistry { | |||||||
|             } |             } | ||||||
|         }); |         }); | ||||||
|         this.createPlaceholder("currentplot_biome", (player, plot) -> plot.getBiomeSynchronous().toString()); |         this.createPlaceholder("currentplot_biome", (player, plot) -> plot.getBiomeSynchronous().toString()); | ||||||
|  |         this.createPlaceholder("currentplot_size", (player, plot) -> String.valueOf(plot.getConnectedPlots().size())); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     /** |     /** | ||||||
|   | |||||||
| @@ -124,7 +124,7 @@ | |||||||
|   "economy.cannot_afford_merge": "<prefix><red>You cannot afford to merge the plots. It costs <gold><money></gold>.</red>", |   "economy.cannot_afford_merge": "<prefix><red>You cannot afford to merge the plots. It costs <gold><money></gold>.</red>", | ||||||
|   "economy.added_balance": "<prefix><gold><money> </gold><gray>has been added to your balance.</gray>", |   "economy.added_balance": "<prefix><gold><money> </gold><gray>has been added to your balance.</gray>", | ||||||
|   "economy.removed_balance": "<prefix><gold><money> </gold><gray>has been taken from your balance.</gray>", |   "economy.removed_balance": "<prefix><gold><money> </gold><gray>has been taken from your balance.</gray>", | ||||||
|   "economy.removed_granted_plot": "<prefix><gray>You used <usedGrants> plot grant(s), you've got </gray><gold><remainingGrants></gold> <gray>left.</gray>", |   "economy.removed_granted_plot": "<prefix><gray>You used <used_grants> plot grant(s), you've got </gray><gold><remaining_grants></gold> <gray>left.</gray>", | ||||||
|   "setup.choose_generator": "<gold>What generator do you want?</gold>", |   "setup.choose_generator": "<gold>What generator do you want?</gold>", | ||||||
|   "setup.setup_not_started": "<prefix><gold>No setup started.</gold>", |   "setup.setup_not_started": "<prefix><gold>No setup started.</gold>", | ||||||
|   "setup.setup_init": "<prefix><gold>Usage: </gold><gray>/plot setup <value></gray>", |   "setup.setup_init": "<prefix><gold>Usage: </gold><gray>/plot setup <value></gray>", | ||||||
| @@ -551,6 +551,7 @@ | |||||||
|   "flags.flag_description_block_burn": "<gray>Set to `true` to allow blocks to burn within the plot.</gray>", |   "flags.flag_description_block_burn": "<gray>Set to `true` to allow blocks to burn within the plot.</gray>", | ||||||
|   "flags.flag_description_block_ignition": "<gray>Set to `false` to prevent blocks from igniting within the plot.</gray>", |   "flags.flag_description_block_ignition": "<gray>Set to `false` to prevent blocks from igniting within the plot.</gray>", | ||||||
|   "flags.flag_description_break": "<gray>Define a list of materials players should be able to break even when they aren't added to the plot.</gray>", |   "flags.flag_description_break": "<gray>Define a list of materials players should be able to break even when they aren't added to the plot.</gray>", | ||||||
|  |   "flags.flag_description_concrete_harden": "<gray>Set to `false` to disable concrete powder forming to concrete with water.</gray>", | ||||||
|   "flags.flag_description_device_interact": "<gray>Set to `true` to allow devices to be interacted with in the plot.</gray>", |   "flags.flag_description_device_interact": "<gray>Set to `true` to allow devices to be interacted with in the plot.</gray>", | ||||||
|   "flags.flag_description_disable_physics": "<gray>Set to `true` to disable block physics in the plot.</gray>", |   "flags.flag_description_disable_physics": "<gray>Set to `true` to disable block physics in the plot.</gray>", | ||||||
|   "flags.flag_description_drop_protection": "<gray>Set to `true` to prevent dropped items from being picked up by non-members of the plot.</gray>", |   "flags.flag_description_drop_protection": "<gray>Set to `true` to prevent dropped items from being picked up by non-members of the plot.</gray>", | ||||||
| @@ -631,6 +632,8 @@ | |||||||
|   "flags.flag_error_double": "Flag value must be a decimal number.", |   "flags.flag_error_double": "Flag value must be a decimal number.", | ||||||
|   "flags.flag_error_music": "Flag value must be a valid music disc ID.", |   "flags.flag_error_music": "Flag value must be a valid music disc ID.", | ||||||
|   "flags.flag_error_title": "Flag value must be in the format </red><grey>\"A title\" \"The subtitle\"</grey><red>.", |   "flags.flag_error_title": "Flag value must be in the format </red><grey>\"A title\" \"The subtitle\"</grey><red>.", | ||||||
|  |   "flags.delaying_loading_area_flags": "<prefix><gray>Delaying loading flags for area `</gray><dark_aqua><area></dark_aqua><gray>` as WorldEdit is not initialised yet.</gray>", | ||||||
|  |   "flags.loading_area_flags": "<prefix><gray>Loading flags for area: </gray><dark_aqua><area></dark_aqua>", | ||||||
|   "flags.area_flags": "<prefix><gray>Area flags: </gray><dark_aqua><flags></dark_aqua>", |   "flags.area_flags": "<prefix><gray>Area flags: </gray><dark_aqua><flags></dark_aqua>", | ||||||
|   "flags.road_flags": "<prefix><gray>Road flags: </gray><dark_aqua><flags></dark_aqua>", |   "flags.road_flags": "<prefix><gray>Road flags: </gray><dark_aqua><flags></dark_aqua>", | ||||||
|   "commands.description.add": "<gray>Allow a user to build in a plot while the plot owner is online.</gray>", |   "commands.description.add": "<gray>Allow a user to build in a plot while the plot owner is online.</gray>", | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| import com.diffplug.gradle.spotless.SpotlessPlugin | import com.diffplug.gradle.spotless.SpotlessPlugin | ||||||
| import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin | import com.github.jengelman.gradle.plugins.shadow.ShadowPlugin | ||||||
|  | import groovy.json.JsonSlurper | ||||||
| import java.net.URI | import java.net.URI | ||||||
| import xyz.jpenilla.runpaper.task.RunServer | import xyz.jpenilla.runpaper.task.RunServer | ||||||
|  |  | ||||||
| @@ -17,11 +18,11 @@ plugins { | |||||||
|     eclipse |     eclipse | ||||||
|     idea |     idea | ||||||
|  |  | ||||||
|     id("xyz.jpenilla.run-paper") version "2.1.0" |     alias(libs.plugins.runPaper) | ||||||
| } | } | ||||||
|  |  | ||||||
| group = "com.intellectualsites.plotsquared" | group = "com.intellectualsites.plotsquared" | ||||||
| version = "7.0.0-SNAPSHOT" | version = "7.1.1-SNAPSHOT" | ||||||
|  |  | ||||||
| if (!File("$rootDir/.git").exists()) { | if (!File("$rootDir/.git").exists()) { | ||||||
|     logger.lifecycle(""" |     logger.lifecycle(""" | ||||||
| @@ -76,13 +77,9 @@ subprojects { | |||||||
|         plugin<IdeaPlugin>() |         plugin<IdeaPlugin>() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     dependencies { |  | ||||||
|         implementation(platform("com.intellectualsites.bom:bom-newest:1.31")) |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     dependencies { |     dependencies { | ||||||
|         // Tests |         // Tests | ||||||
|         testImplementation("org.junit.jupiter:junit-jupiter:5.9.3") |         testImplementation("org.junit.jupiter:junit-jupiter:5.10.0") | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     plugins.withId("java") { |     plugins.withId("java") { | ||||||
| @@ -153,29 +150,34 @@ subprojects { | |||||||
|                             id.set("Sauilitired") |                             id.set("Sauilitired") | ||||||
|                             name.set("Alexander Söderberg") |                             name.set("Alexander Söderberg") | ||||||
|                             organization.set("IntellectualSites") |                             organization.set("IntellectualSites") | ||||||
|  |                             organizationUrl.set("https://github.com/IntellectualSites") | ||||||
|                         } |                         } | ||||||
|                         developer { |                         developer { | ||||||
|                             id.set("NotMyFault") |                             id.set("NotMyFault") | ||||||
|                             name.set("Alexander Brandes") |                             name.set("Alexander Brandes") | ||||||
|                             organization.set("IntellectualSites") |                             organization.set("IntellectualSites") | ||||||
|  |                             organizationUrl.set("https://github.com/IntellectualSites") | ||||||
|                             email.set("contact(at)notmyfault.dev") |                             email.set("contact(at)notmyfault.dev") | ||||||
|                         } |                         } | ||||||
|                         developer { |                         developer { | ||||||
|                             id.set("SirYwell") |                             id.set("SirYwell") | ||||||
|                             name.set("Hannes Greule") |                             name.set("Hannes Greule") | ||||||
|                             organization.set("IntellectualSites") |                             organization.set("IntellectualSites") | ||||||
|  |                             organizationUrl.set("https://github.com/IntellectualSites") | ||||||
|                         } |                         } | ||||||
|                         developer { |                         developer { | ||||||
|                             id.set("dordsor21") |                             id.set("dordsor21") | ||||||
|                             name.set("dordsor21") |                             name.set("dordsor21") | ||||||
|                             organization.set("IntellectualSites") |                             organization.set("IntellectualSites") | ||||||
|  |                             organizationUrl.set("https://github.com/IntellectualSites") | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     scm { |                     scm { | ||||||
|                         url.set("https://github.com/IntellectualSites/PlotSquared") |                         url.set("https://github.com/IntellectualSites/PlotSquared") | ||||||
|                         connection.set("scm:https://IntellectualSites@github.com/IntellectualSites/PlotSquared.git") |                         connection.set("scm:git:https://github.com/IntellectualSites/PlotSquared.git") | ||||||
|                         developerConnection.set("scm:git://github.com/IntellectualSites/PlotSquared.git") |                         developerConnection.set("scm:git:git@github.com:IntellectualSites/PlotSquared.git") | ||||||
|  |                         tag.set("${project.version}") | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     issueManagement { |                     issueManagement { | ||||||
| @@ -222,14 +224,28 @@ tasks.getByName<Jar>("jar") { | |||||||
|     enabled = false |     enabled = false | ||||||
| } | } | ||||||
|  |  | ||||||
| val supportedVersions = listOf("1.16.5", "1.17", "1.17.1", "1.18.2", "1.19", "1.19.1", "1.19.2", "1.19.3", "1.19.4", "1.20") | val supportedVersions = listOf("1.16.5", "1.17.1", "1.18.2", "1.19.4", "1.20.1", "1.20.2") | ||||||
| tasks { | tasks { | ||||||
|  |     register("cacheLatestFaweArtifact") { | ||||||
|  |         val lastSuccessfulBuildUrl = uri("https://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/api/json").toURL() | ||||||
|  |         val artifact = ((JsonSlurper().parse(lastSuccessfulBuildUrl) as Map<*, *>)["artifacts"] as List<*>) | ||||||
|  |                 .map { it as Map<*, *> } | ||||||
|  |                 .map { it["fileName"] as String } | ||||||
|  |                 .first { it -> it.contains("Bukkit") } | ||||||
|  |         project.ext["faweArtifact"] = artifact | ||||||
|  |     } | ||||||
|  |  | ||||||
|     supportedVersions.forEach { |     supportedVersions.forEach { | ||||||
|         register<RunServer>("runServer-$it") { |         register<RunServer>("runServer-$it") { | ||||||
|  |             dependsOn(getByName("cacheLatestFaweArtifact")) | ||||||
|             minecraftVersion(it) |             minecraftVersion(it) | ||||||
|             pluginJars(*project(":plotsquared-bukkit").getTasksByName("shadowJar", false).map { (it as Jar).archiveFile } |             pluginJars(*project(":plotsquared-bukkit").getTasksByName("shadowJar", false) | ||||||
|  |                     .map { task -> (task as Jar).archiveFile } | ||||||
|                     .toTypedArray()) |                     .toTypedArray()) | ||||||
|             jvmArgs("-DPaper.IgnoreJavaVersion=true", "-Dcom.mojang.eula.agree=true") |             jvmArgs("-DPaper.IgnoreJavaVersion=true", "-Dcom.mojang.eula.agree=true") | ||||||
|  |             downloadPlugins { | ||||||
|  |                 url("https://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/artifact/artifacts/${project.ext["faweArtifact"]}") | ||||||
|  |             } | ||||||
|             group = "run paper" |             group = "run paper" | ||||||
|             runDirectory.set(file("run-$it")) |             runDirectory.set(file("run-$it")) | ||||||
|         } |         } | ||||||
|   | |||||||
| @@ -1,33 +1,62 @@ | |||||||
| [versions] | [versions] | ||||||
| # Platform expectations | # Platform expectations | ||||||
|  | paper = "1.20.2-R0.1-SNAPSHOT" | ||||||
| guice = "7.0.0" | guice = "7.0.0" | ||||||
| spotbugs = "4.7.3" | spotbugs = "4.7.3" | ||||||
|  | checkerqual = "3.39.0" | ||||||
|  | gson = "2.10" | ||||||
|  | guava = "31.1-jre" | ||||||
|  | snakeyaml = "2.0" | ||||||
|  | adventure = "4.14.0" | ||||||
|  | adventure-bukkit = "4.3.1" | ||||||
|  | log4j = "2.19.0" | ||||||
|  |  | ||||||
| # Plugins | # Plugins | ||||||
| worldedit = "7.2.15" | worldedit = "7.2.16" | ||||||
| placeholderapi = "2.11.3" | fawe = "2.8.0" | ||||||
|  | placeholderapi = "2.11.4" | ||||||
| luckperms = "5.4" | luckperms = "5.4" | ||||||
| essentialsx = "2.20.0" | essentialsx = "2.20.1" | ||||||
| mvdwapi = "3.1.1" | mvdwapi = "3.1.1" | ||||||
|  |  | ||||||
|  | # Datebase | ||||||
|  | hikaricp = "5.0.1" | ||||||
|  | jdbi = "3.41.3" | ||||||
|  |  | ||||||
| # Third party | # Third party | ||||||
| prtree = "2.0.1" | prtree = "2.0.1" | ||||||
| aopalliance = "1.0" | aopalliance = "1.0" | ||||||
| cloud-services = "1.8.3" | cloud-services = "1.8.4" | ||||||
| arkitektonika = "2.1.2" | arkitektonika = "2.1.2" | ||||||
| squirrelid = "0.3.2" | squirrelid = "0.3.2" | ||||||
|  | paster = "1.1.5" | ||||||
|  | bstats = "3.0.2" | ||||||
|  | paperlib = "1.0.8" | ||||||
|  | informative-annotations = "1.4" | ||||||
|  | vault = "1.7.1" | ||||||
|  | serverlib = "2.3.4" | ||||||
|  |  | ||||||
| # Gradle plugins | # Gradle plugins | ||||||
| shadow = "8.1.1" | shadow = "8.1.1" | ||||||
| grgit = "4.1.1" | grgit = "4.1.1" | ||||||
| spotless = "6.20.0" | spotless = "6.22.0" | ||||||
| nexus = "1.3.0" | nexus = "1.3.0" | ||||||
|  | runPaper = "2.2.0" | ||||||
|  |  | ||||||
| [libraries] | [libraries] | ||||||
| # Platform expectations | # Platform expectations | ||||||
|  | paper = { group = "io.papermc.paper", name = "paper-api", version.ref = "paper" } | ||||||
| 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" } | ||||||
| spotbugs = { group = "com.github.spotbugs", name = "spotbugs-annotations", version.ref = "spotbugs" } | spotbugs = { group = "com.github.spotbugs", name = "spotbugs-annotations", version.ref = "spotbugs" } | ||||||
|  | checkerqual = { group = "org.checkerframework", name = "checker-qual", version.ref = "checkerqual" } | ||||||
|  | gson = { group = "com.google.code.gson", name = "gson", version.ref = "gson" } | ||||||
|  | guava = { group = "com.google.guava", name = "guava", version.ref = "guava" } | ||||||
|  | snakeyaml = { group = "org.yaml", name = "snakeyaml", version.ref = "snakeyaml" } | ||||||
|  | adventureApi = { group = "net.kyori", name = "adventure-api", version.ref = "adventure" } | ||||||
|  | adventureMiniMessage = { group = "net.kyori", name = "adventure-text-minimessage", version.ref = "adventure" } | ||||||
|  | adventureBukkit = { group = "net.kyori", name = "adventure-platform-bukkit", version.ref = "adventure-bukkit" } | ||||||
|  | log4j = { group = "org.apache.logging.log4j", name = "log4j-api", version.ref = "log4j" } | ||||||
|  |  | ||||||
| # Plugins | # Plugins | ||||||
| worldeditCore = { group = "com.sk89q.worldedit", name = "worldedit-core", version.ref = "worldedit" } | worldeditCore = { group = "com.sk89q.worldedit", name = "worldedit-core", version.ref = "worldedit" } | ||||||
| @@ -35,6 +64,13 @@ worldeditBukkit = { group = "com.sk89q.worldedit", name = "worldedit-bukkit", ve | |||||||
| 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" } | ||||||
|  | faweCore = { group = "com.fastasyncworldedit", name = "FastAsyncWorldEdit-Core", version.ref = "fawe" } | ||||||
|  | faweBukkit = { group = "com.fastasyncworldedit", name = "FastAsyncWorldEdit-Bukkit", version.ref = "fawe" } | ||||||
|  |  | ||||||
|  | # Database | ||||||
|  | hikaricp = { group = "com.zaxxer", name = "HikariCP", version.ref = "hikaricp" } | ||||||
|  | jdbiCore = { group = "org.jdbi", name = "jdbi3-core", version.ref = "jdbi" } | ||||||
|  | jdbiGuice = { group = "org.jdbi", name = "jdbi3-guice", version.ref = "jdbi" } | ||||||
|  |  | ||||||
| # Third party | # Third party | ||||||
| prtree = { group = "com.intellectualsites.prtree", name = "PRTree", version.ref = "prtree" } | prtree = { group = "com.intellectualsites.prtree", name = "PRTree", version.ref = "prtree" } | ||||||
| @@ -43,9 +79,17 @@ cloudServices = { group = "cloud.commandframework", name = "cloud-services", ver | |||||||
| mvdwapi = { group = "com.intellectualsites.mvdwplaceholderapi", name = "MVdWPlaceholderAPI", version.ref = "mvdwapi" } | mvdwapi = { group = "com.intellectualsites.mvdwplaceholderapi", name = "MVdWPlaceholderAPI", version.ref = "mvdwapi" } | ||||||
| squirrelid = { group = "org.enginehub", name = "squirrelid", version.ref = "squirrelid" } | squirrelid = { group = "org.enginehub", name = "squirrelid", version.ref = "squirrelid" } | ||||||
| arkitektonika = { group = "com.intellectualsites.arkitektonika", name = "Arkitektonika-Client", version.ref = "arkitektonika" } | arkitektonika = { group = "com.intellectualsites.arkitektonika", name = "Arkitektonika-Client", version.ref = "arkitektonika" } | ||||||
|  | paster = { group = "com.intellectualsites.paster", name = "Paster", version.ref = "paster" } | ||||||
|  | bstatsBase = { group = "org.bstats", name = "bstats-base", version.ref = "bstats" } | ||||||
|  | bstatsBukkit = { group = "org.bstats", name = "bstats-bukkit", version.ref = "bstats" } | ||||||
|  | informativeAnnotations = { group = "com.intellectualsites.informative-annotations", name = "informative-annotations", version.ref = "informative-annotations" } | ||||||
|  | paperlib = { group = "io.papermc", name = "paperlib", version.ref = "paperlib" } | ||||||
|  | vault = { group = "com.github.MilkBowl", name = "VaultAPI", version.ref = "vault" } | ||||||
|  | serverlib = { group = "dev.notmyfault.serverlib", name = "ServerLib", version.ref = "serverlib" } | ||||||
|  |  | ||||||
| [plugins] | [plugins] | ||||||
| shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } | shadow = { id = "com.github.johnrengelman.shadow", version.ref = "shadow" } | ||||||
| grgit = { id = "org.ajoberstar.grgit", version.ref = "grgit" } | grgit = { id = "org.ajoberstar.grgit", version.ref = "grgit" } | ||||||
| spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } | spotless = { id = "com.diffplug.spotless", version.ref = "spotless" } | ||||||
| nexus = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexus" } | nexus = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexus" } | ||||||
|  | runPaper = { id = "xyz.jpenilla.run-paper", version.ref = "runPaper" } | ||||||
|   | |||||||
							
								
								
									
										
											BIN
										
									
								
								gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								gradle/wrapper/gradle-wrapper.jar
									
									
									
									
										vendored
									
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										2
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								gradle/wrapper/gradle-wrapper.properties
									
									
									
									
										vendored
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| distributionBase=GRADLE_USER_HOME | distributionBase=GRADLE_USER_HOME | ||||||
| distributionPath=wrapper/dists | distributionPath=wrapper/dists | ||||||
| distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-bin.zip | distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip | ||||||
| networkTimeout=10000 | networkTimeout=10000 | ||||||
| validateDistributionUrl=true | validateDistributionUrl=true | ||||||
| zipStoreBase=GRADLE_USER_HOME | zipStoreBase=GRADLE_USER_HOME | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								gradlew
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										17
									
								
								gradlew
									
									
									
									
										vendored
									
									
								
							| @@ -83,7 +83,8 @@ done | |||||||
| # This is normally unused | # This is normally unused | ||||||
| # shellcheck disable=SC2034 | # shellcheck disable=SC2034 | ||||||
| APP_BASE_NAME=${0##*/} | APP_BASE_NAME=${0##*/} | ||||||
| APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit | # Discard cd standard output in case $CDPATH is set (https://github.com/gradle/gradle/issues/25036) | ||||||
|  | APP_HOME=$( cd "${APP_HOME:-./}" > /dev/null && pwd -P ) || exit | ||||||
|  |  | ||||||
| # Use the maximum available, or set MAX_FD != -1 to use that value. | # Use the maximum available, or set MAX_FD != -1 to use that value. | ||||||
| MAX_FD=maximum | MAX_FD=maximum | ||||||
| @@ -144,7 +145,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | |||||||
|     case $MAX_FD in #( |     case $MAX_FD in #( | ||||||
|       max*) |       max*) | ||||||
|         # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. |         # In POSIX sh, ulimit -H is undefined. That's why the result is checked to see if it worked. | ||||||
|         # shellcheck disable=SC3045 |         # shellcheck disable=SC2039,SC3045 | ||||||
|         MAX_FD=$( ulimit -H -n ) || |         MAX_FD=$( ulimit -H -n ) || | ||||||
|             warn "Could not query maximum file descriptor limit" |             warn "Could not query maximum file descriptor limit" | ||||||
|     esac |     esac | ||||||
| @@ -152,7 +153,7 @@ if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then | |||||||
|       '' | soft) :;; #( |       '' | soft) :;; #( | ||||||
|       *) |       *) | ||||||
|         # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. |         # In POSIX sh, ulimit -n is undefined. That's why the result is checked to see if it worked. | ||||||
|         # shellcheck disable=SC3045 |         # shellcheck disable=SC2039,SC3045 | ||||||
|         ulimit -n "$MAX_FD" || |         ulimit -n "$MAX_FD" || | ||||||
|             warn "Could not set maximum file descriptor limit to $MAX_FD" |             warn "Could not set maximum file descriptor limit to $MAX_FD" | ||||||
|     esac |     esac | ||||||
| @@ -201,11 +202,11 @@ fi | |||||||
| # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. | ||||||
| DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' | ||||||
|  |  | ||||||
| # Collect all arguments for the java command; | # Collect all arguments for the java command: | ||||||
| #   * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of | #   * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments, | ||||||
| #     shell script including quotes and variable substitutions, so put them in | #     and any embedded shellness will be escaped. | ||||||
| #     double quotes to make sure that they get re-expanded; and | #   * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be | ||||||
| #   * put everything else in single quotes, so that it's not re-expanded. | #     treated as '${Hostname}' itself on the command line. | ||||||
|  |  | ||||||
| set -- \ | set -- \ | ||||||
|         "-Dorg.gradle.appname=$APP_BASE_NAME" \ |         "-Dorg.gradle.appname=$APP_BASE_NAME" \ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user