Compare commits

...

53 Commits

Author SHA1 Message Date
Pierre Maurice Schwang
8002d170f5 chore: split logic per platform 2025-10-21 00:05:45 +02:00
Pierre Maurice Schwang
52e8ba6ddd chore: simplify sign logic 2025-10-21 00:05:45 +02:00
Pierre Maurice Schwang
2f1fe633af fix: missing continue and license header 2025-10-21 00:05:25 +02:00
Pierre Maurice Schwang
dc30408ed0 fix: signs with component lines 2025-10-21 00:05:25 +02:00
Pierre Maurice Schwang
313ea8b266 feat: sign contents 2025-10-21 00:05:25 +02:00
Pierre Maurice Schwang
1ad0e700a5 feat: use NMS to populate tile entities 2025-10-21 00:05:24 +02:00
Pierre Maurice Schwang
590f442a0f fix: block nbt population 2025-10-21 00:05:24 +02:00
Pierre Maurice Schwang
308527e822 chore: 1.17 is not supported anymore 2025-10-21 00:05:24 +02:00
renovate[bot]
1f32909ffd Update fawe to v2.14.0 (#4783)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-20 00:58:28 +00:00
renovate[bot]
1785693fe4 Update dependency com.github.spotbugs:spotbugs-annotations to v4.9.8 (#4782)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-20 00:57:53 +00:00
Hannes Greule
df738b279d fix: missing fallback if current plot is not explicitly overridden (#4779) 2025-10-19 15:00:24 +02:00
renovate[bot]
b7b25252c6 Update dependency com.gradleup.shadow to v9 (#4760)
* Update dependency com.gradleup.shadow to v9

* Fix missing shadow runtimes on Gradle 9

Signed-off-by: Alexander Brandes <mc.cache@web.de>

---------

Signed-off-by: Alexander Brandes <mc.cache@web.de>
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Alexander Brandes <mc.cache@web.de>
2025-10-13 20:58:00 +00:00
renovate[bot]
7123f51bb5 Update gradle/actions action to v5 (#4776)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-13 20:48:31 +00:00
renovate[bot]
897afa894e Update junit-framework monorepo to v6 (major) (#4777)
Update junit-framework monorepo to v6

Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-13 20:48:17 +00:00
renovate[bot]
2238609551 Update github/codeql-action action to v4 (#4775)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-13 20:47:56 +00:00
renovate[bot]
255959232b Update Gradle to v9 (#4768)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
Co-authored-by: Alexander Brandes <mc.cache@web.de>
2025-10-13 22:43:06 +02:00
FlorianMichael
622c9f1d13 fix: don't break cow shearing if mob-spawning flag is set to false (#4752) 2025-10-13 22:25:12 +02:00
renovate[bot]
e7aff3982e Update adventure to v4.25.0 (#4774)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-13 00:38:22 +00:00
renovate[bot]
db7ea780f9 Update dependency xyz.jpenilla.run-paper to v3.0.2 (#4773)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-13 00:37:50 +00:00
renovate[bot]
db188150d7 Update dependency xyz.jpenilla.run-paper to v3.0.1 (#4766)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-06 15:34:41 +00:00
renovate[bot]
cfd8401515 Update dependency org.checkerframework:checker-qual to v3.51.1 (#4765)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-06 15:34:23 +00:00
renovate[bot]
c887cbe28c Update junit-framework monorepo (#4767)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-10-06 17:33:19 +02:00
renovate[bot]
59183c1412 Update dependency com.diffplug.spotless to v8 (#4763)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-29 01:13:36 +00:00
renovate[bot]
439fb3a8ea Update dependency xyz.jpenilla.run-paper to v3 (#4764)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-29 01:11:55 +00:00
renovate[bot]
78d6ca1deb Update dependency com.github.spotbugs:spotbugs-annotations to v4.9.6 (#4759)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-22 00:41:24 +00:00
Alexander Brandes
03aa1be5a3 Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-09-19 21:56:38 +02:00
Alexander Brandes
2e3832f1bd Release 7.5.8
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-09-19 21:55:57 +02:00
Pierre Maurice Schwang
05af41f832 fix: binary incompatibility on 1.21.1 (#4758) 2025-09-19 08:55:39 +02:00
renovate[bot]
b613318a29 Update fawe to v2.13.2 (#4754)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-15 01:06:16 +00:00
renovate[bot]
c2f8356042 Update dependency org.checkerframework:checker-qual to v3.51.0 (#4755)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-15 01:05:57 +00:00
Alexander Brandes
109e6059f8 Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-09-09 21:56:03 +02:00
Alexander Brandes
f01c287f89 Release 7.5.7
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-09-09 21:55:30 +02:00
renovate[bot]
fd8cf3c475 Update dependency org.checkerframework:checker-qual to v3.50.0 (#4749)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-08 01:36:33 +00:00
renovate[bot]
8c9957edeb Update actions/setup-java action to v5 (#4750)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-09-08 01:36:15 +00:00
Jordan
aaba2b5b1a fix: improve error handling in backups (#4740)
* fix: improve error handling in backups
 - fixes #4460

* cleanup

* Update Core/src/main/java/com/plotsquared/core/backup/Backup.java

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Alexander Brandes <mc.cache@web.de>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2025-09-01 20:29:52 +02:00
Jordan
02a65c8855 fix: use PlotPlayer#getCurrentPlot across commands to allow /<command> <id> usage (#4738)
* fix: use PlotPlayer#getCurrentPlot across commands to allow /<command> <id> usage
 - fixes #4526
 - supersedes #4675

* cleanup
2025-08-30 20:33:13 +02:00
Jordan
8a5fa26796 fix: allow extended world height when teleporting player on join (#4739) 2025-08-30 20:32:40 +02:00
renovate[bot]
13cbb7e083 Update actions/checkout action to v5 (#4746)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-25 01:08:14 +00:00
EnZaXD
4d8d5b3a9f fix: special handle thrown eggs for projectile hit checks (#4728)
Cancelling the ProjectileHitEvent will not cover for thrown eggs spawning chickens due to how Bukkit has these events structured. The provided patch calls the same code used for normal projectiles in the specialized egg event to prevent unwanted chickens from spawning on other plots.

Signed-off-by: FlorianMichael <florian.michael07@gmail.com>
2025-08-23 13:08:28 +02:00
renovate[bot]
cd6a32cf44 Update adventure to v4.24.0 (#4733)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-18 02:06:13 +00:00
renovate[bot]
273c0ad989 Update Ilshidur/action-discord action to v0.4.0 (#4734)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-18 02:05:32 +00:00
renovate[bot]
774da7183b Update dependency com.gradleup.shadow to v8.3.9 (#4730)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-11 00:56:21 +00:00
renovate[bot]
e083015ab2 Update dependency com.github.spotbugs:spotbugs-annotations to v4.9.4 (#4729)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-11 00:55:56 +00:00
Jordan
3f577d039b feat: add placeholder for multiple owners (#4711)
- closes #4695
2025-08-08 19:51:53 +02:00
Leviaria
4d2e4a3d1a fix: tab completion for /plot grant add/check <name> commands (#4720)
Fix tab completion for /plot grant add/check <name> commands

Fixed an issue where player name tab completion was not working correctly 
for /plot grant add <name> and /plot grant check <name> commands.

Previously, the tab completion logic would only attempt to complete player 
names after all arguments were processed, making it impossible to get 
player suggestions when typing the second argument.

Now the completion properly handles:
- /plot grant <TAB> → shows "add", "check" subcommands
- /plot grant add <TAB> → shows player list
- /plot grant check <TAB> → shows player list

Fixes #4382
2025-08-06 21:44:10 +02:00
renovate[bot]
e5d36579b1 Update fawe to v2.13.1 (#4724)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-04 01:52:49 +00:00
renovate[bot]
f0cde251bd Update dependency net.essentialsx:EssentialsX to v2.21.2 (#4723)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2025-08-04 01:52:09 +00:00
Jordan
58016bb1c8 fix: allow admin override when setting plot context in command (#4712)
* fix: allow admin override when setting plot context in command
 - when admins (plots.admin or console) attempted to use /plot x;z to set context on a plot they are denied on, it would not work
 - fixes #4696

* Print error to user if denied
2025-08-03 11:13:48 +02:00
Alexander Brandes
e5943ba627 Update adventure-platform-bukkit to 4.4.1
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-07-30 09:01:56 +02:00
Alexander Brandes
07dfdeef2c Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-07-29 21:20:36 +02:00
Alexander Brandes
025b08e716 Release 7.5.6
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-07-29 21:16:56 +02:00
Alexander Brandes
921435689e Update adventure-platform-bukkit to 4.4.1-SNAPSHOT (#4717)
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-07-29 21:09:20 +02:00
Alexander Brandes
aae154b23a Back to snapshot for development
Signed-off-by: Alexander Brandes <mc.cache@web.de>
2025-07-29 18:36:10 +02:00
60 changed files with 999 additions and 662 deletions

View File

@@ -11,7 +11,7 @@ jobs:
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }} DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
DISCORD_USERNAME: PlotSquared Release DISCORD_USERNAME: PlotSquared Release
DISCORD_AVATAR: https://raw.githubusercontent.com/IntellectualSites/Assets/main/plugins/PlotSquared/PlotSquared.png DISCORD_AVATAR: https://raw.githubusercontent.com/IntellectualSites/Assets/main/plugins/PlotSquared/PlotSquared.png
uses: Ilshidur/action-discord@0.3.2 uses: Ilshidur/action-discord@0.4.0
with: with:
args: | args: |
"<@&525015541815967744> <@&679322738552471574> <@&699293353862496266>" "<@&525015541815967744> <@&679322738552471574> <@&699293353862496266>"

View File

@@ -9,11 +9,11 @@ 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@v4 uses: actions/checkout@v5
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v4 uses: gradle/actions/wrapper-validation@v5
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: temurin distribution: temurin
java-version: 21 java-version: 21

View File

@@ -9,11 +9,11 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout Repository - name: Checkout Repository
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Validate Gradle Wrapper - name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v4 uses: gradle/actions/wrapper-validation@v5
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: temurin distribution: temurin
java-version: 21 java-version: 21

View File

@@ -20,17 +20,17 @@ jobs:
language: [ 'java' ] language: [ 'java' ]
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v4 uses: actions/checkout@v5
- name: Setup Java - name: Setup Java
uses: actions/setup-java@v4 uses: actions/setup-java@v5
with: with:
distribution: temurin distribution: temurin
java-version: 21 java-version: 21
- name: Initialize CodeQL - name: Initialize CodeQL
uses: github/codeql-action/init@v3 uses: github/codeql-action/init@v4
with: with:
languages: ${{ matrix.language }} languages: ${{ matrix.language }}
- name: Autobuild - name: Autobuild
uses: github/codeql-action/autobuild@v3 uses: github/codeql-action/autobuild@v4
- name: Perform CodeQL Analysis - name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3 uses: github/codeql-action/analyze@v4

View File

@@ -17,6 +17,19 @@ repositories {
} }
} }
// Make sure we control the exact version of paper being included, while dropping spigot + bukkit
configurations.all {
exclude("org.bukkit")
exclude("org.spigotmc")
resolutionStrategy.eachDependency {
if (requested.group == "io.papermc.paper" && requested.name == "paper-api") {
useVersion(checkNotNull(libs.paper.orNull?.version))
because("specific paper version is required to prevent binary incompatibilities on older versions")
}
}
}
dependencies { dependencies {
api(projects.plotsquaredCore) api(projects.plotsquaredCore)
@@ -28,20 +41,13 @@ dependencies {
implementation(libs.paperlib) implementation(libs.paperlib)
// Plugins // Plugins
compileOnly(libs.worldeditBukkit) { compileOnly(libs.worldeditBukkit)
exclude(group = "org.bukkit")
exclude(group = "org.spigotmc")
}
compileOnly(libs.faweBukkit) { isTransitive = false } compileOnly(libs.faweBukkit) { isTransitive = false }
testImplementation(libs.faweBukkit) { isTransitive = false } testImplementation(libs.faweBukkit) { isTransitive = false }
compileOnly(libs.vault) { compileOnly(libs.vault)
exclude(group = "org.bukkit")
}
compileOnly(libs.placeholderapi) compileOnly(libs.placeholderapi)
compileOnly(libs.luckperms) compileOnly(libs.luckperms)
compileOnly(libs.essentialsx) { compileOnly(libs.essentialsx)
exclude(group = "org.spigotmc")
}
compileOnly(libs.mvdwapi) { isTransitive = false } compileOnly(libs.mvdwapi) { isTransitive = false }
// Other libraries // Other libraries
@@ -74,7 +80,7 @@ tasks.named<ShadowJar>("shadowJar") {
relocate("net.kyori.examination", "com.plotsquared.core.configuration.examination") relocate("net.kyori.examination", "com.plotsquared.core.configuration.examination")
relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib") relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib")
relocate("org.bstats", "com.plotsquared.metrics") relocate("org.bstats", "com.plotsquared.metrics")
relocate("org.enginehub", "com.plotsquared.squirrelid") relocate("org.enginehub.squirrelid", "com.plotsquared.squirrelid")
relocate("org.khelekore.prtree", "com.plotsquared.prtree") relocate("org.khelekore.prtree", "com.plotsquared.prtree")
relocate("com.google.inject", "com.plotsquared.google") relocate("com.google.inject", "com.plotsquared.google")
relocate("org.aopalliance", "com.plotsquared.core.aopalliance") relocate("org.aopalliance", "com.plotsquared.core.aopalliance")

View File

@@ -90,12 +90,7 @@ public class BukkitPlotGenerator extends ChunkGenerator implements GeneratorWrap
this.plotGenerator = generator; this.plotGenerator = generator;
this.platformGenerator = this; this.platformGenerator = this;
this.populators = new ArrayList<>(); this.populators = new ArrayList<>();
int minecraftMinorVersion = PlotSquared.platform().serverVersion()[1];
if (minecraftMinorVersion >= 17) {
this.populators.add(new BlockStatePopulator(this.plotGenerator)); this.populators.add(new BlockStatePopulator(this.plotGenerator));
} else {
this.populators.add(new LegacyBlockStatePopulator(this.plotGenerator));
}
this.full = true; this.full = true;
this.useNewGenerationMethods = PlotSquared.platform().serverVersion()[1] >= 19; this.useNewGenerationMethods = PlotSquared.platform().serverVersion()[1] >= 19;
this.biomeProvider = new BukkitPlotBiomeProvider(); this.biomeProvider = new BukkitPlotBiomeProvider();

View File

@@ -36,6 +36,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Random; import java.util.Random;
@Deprecated(since = "TODO")
final class LegacyBlockStatePopulator extends BlockPopulator { final class LegacyBlockStatePopulator extends BlockPopulator {
private final IndependentPlotGenerator plotGenerator; private final IndependentPlotGenerator plotGenerator;

View File

@@ -160,7 +160,7 @@ public class EntityEventListener implements Listener {
return; return;
} }
} }
case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL", case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SILVERFISH_BLOCK", "ENDER_PEARL",
"TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN", "NETHER_PORTAL", "TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN", "NETHER_PORTAL",
"FROZEN", "SPELL", "DEFAULT" -> { "FROZEN", "SPELL", "DEFAULT" -> {
if (!area.isMobSpawning()) { if (!area.isMobSpawning()) {

View File

@@ -202,7 +202,7 @@ public class PaperListener implements Listener {
return; return;
} }
} }
case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SHEARED", "SILVERFISH_BLOCK", "ENDER_PEARL", "TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN" -> { case "REINFORCEMENTS", "NATURAL", "MOUNT", "PATROL", "RAID", "SILVERFISH_BLOCK", "ENDER_PEARL", "TRAP", "VILLAGE_DEFENSE", "VILLAGE_INVASION", "BEEHIVE", "CHUNK_GEN" -> {
if (!area.isMobSpawning()) { if (!area.isMobSpawning()) {
event.setShouldAbortSpawn(true); event.setShouldAbortSpawn(true);
event.setCancelled(true); event.setCancelled(true);

View File

@@ -47,6 +47,7 @@ import org.bukkit.event.entity.LingeringPotionSplashEvent;
import org.bukkit.event.entity.PotionSplashEvent; import org.bukkit.event.entity.PotionSplashEvent;
import org.bukkit.event.entity.ProjectileHitEvent; import org.bukkit.event.entity.ProjectileHitEvent;
import org.bukkit.event.entity.ProjectileLaunchEvent; import org.bukkit.event.entity.ProjectileLaunchEvent;
import org.bukkit.event.player.PlayerEggThrowEvent;
import org.bukkit.projectiles.BlockProjectileSource; import org.bukkit.projectiles.BlockProjectileSource;
import org.bukkit.projectiles.ProjectileSource; import org.bukkit.projectiles.ProjectileSource;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
@@ -157,14 +158,26 @@ public class ProjectileEventListener implements Listener {
@EventHandler @EventHandler
public void onProjectileHit(ProjectileHitEvent event) { public void onProjectileHit(ProjectileHitEvent event) {
Projectile entity = event.getEntity(); if (cancelProjectileHit(event.getEntity())) {
event.setCancelled(true);
}
}
@EventHandler
public void onPlayerEggThrow(PlayerEggThrowEvent event) {
if (cancelProjectileHit(event.getEgg())) {
event.setHatching(false);
}
}
private boolean cancelProjectileHit(Projectile entity) {
Location location = BukkitUtil.adapt(entity.getLocation()); Location location = BukkitUtil.adapt(entity.getLocation());
if (!this.plotAreaManager.hasPlotArea(location.getWorldName())) { if (!this.plotAreaManager.hasPlotArea(location.getWorldName())) {
return; return false;
} }
PlotArea area = location.getPlotArea(); PlotArea area = location.getPlotArea();
if (area == null) { if (area == null) {
return; return false;
} }
Plot plot = area.getPlot(location); Plot plot = area.getPlot(location);
ProjectileSource shooter = entity.getShooter(); ProjectileSource shooter = entity.getShooter();
@@ -172,15 +185,14 @@ public class ProjectileEventListener implements Listener {
if (!((Player) shooter).isOnline()) { if (!((Player) shooter).isOnline()) {
if (plot != null) { if (plot != null) {
if (plot.isAdded(((Player) shooter).getUniqueId()) || plot.getFlag(ProjectilesFlag.class)) { if (plot.isAdded(((Player) shooter).getUniqueId()) || plot.getFlag(ProjectilesFlag.class)) {
return; return false;
} }
} else if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, ProjectilesFlag.class, true)) { } else if (PlotFlagUtil.isAreaRoadFlagsAndFlagEquals(area, ProjectilesFlag.class, true)) {
return; return false;
} }
entity.remove(); entity.remove();
event.setCancelled(true); return true;
return;
} }
PlotPlayer<?> pp = BukkitUtil.adapt((Player) shooter); PlotPlayer<?> pp = BukkitUtil.adapt((Player) shooter);
@@ -189,38 +201,36 @@ public class ProjectileEventListener implements Listener {
Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED Permission.PERMISSION_ADMIN_PROJECTILE_UNOWNED
)) { )) {
entity.remove(); entity.remove();
event.setCancelled(true); return true;
} }
return; return false;
} }
if (plot.isAdded(pp.getUUID()) || pp.hasPermission(Permission.PERMISSION_ADMIN_PROJECTILE_OTHER) || plot.getFlag( if (plot.isAdded(pp.getUUID()) || pp.hasPermission(Permission.PERMISSION_ADMIN_PROJECTILE_OTHER) || plot.getFlag(
ProjectilesFlag.class) || (entity instanceof FishHook && plot.getFlag( ProjectilesFlag.class) || (entity instanceof FishHook && plot.getFlag(
FishingFlag.class))) { FishingFlag.class))) {
return; return false;
} }
entity.remove(); entity.remove();
event.setCancelled(true); return true;
return;
} }
if (!(shooter instanceof Entity) && shooter != null) { if (!(shooter instanceof Entity) && shooter != null) {
if (plot == null) { if (plot == null) {
entity.remove(); entity.remove();
event.setCancelled(true); return true;
return;
} }
Location sLoc = Location sLoc =
BukkitUtil.adapt(((BlockProjectileSource) shooter).getBlock().getLocation()); BukkitUtil.adapt(((BlockProjectileSource) shooter).getBlock().getLocation());
if (!area.contains(sLoc.getX(), sLoc.getZ())) { if (!area.contains(sLoc.getX(), sLoc.getZ())) {
entity.remove(); entity.remove();
event.setCancelled(true); return true;
return;
} }
Plot sPlot = area.getOwnedPlotAbs(sLoc); Plot sPlot = area.getOwnedPlotAbs(sLoc);
if (sPlot == null || !PlotHandler.sameOwners(plot, sPlot)) { if (sPlot == null || !PlotHandler.sameOwners(plot, sPlot)) {
entity.remove(); entity.remove();
event.setCancelled(true); return true;
} }
} }
return false;
} }
} }

View File

@@ -52,6 +52,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Objects;
import java.util.function.Consumer; import java.util.function.Consumer;
public class BukkitQueueCoordinator extends BasicQueueCoordinator { public class BukkitQueueCoordinator extends BasicQueueCoordinator {
@@ -210,8 +211,13 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
BaseBlock block = getWorld().getBlock(blockVector3).toBaseBlock(tag); BaseBlock block = getWorld().getBlock(blockVector3).toBaseBlock(tag);
getWorld().setBlock(blockVector3, block, getSideEffectSet(SideEffectState.NONE)); getWorld().setBlock(blockVector3, block, getSideEffectSet(SideEffectState.NONE));
} catch (WorldEditException ignored) { } catch (WorldEditException ignored) {
StateWrapper sw = new StateWrapper(tag); StateWrapper.INSTANCE.restore(
sw.restoreTag(getWorld().getName(), blockVector3.getX(), blockVector3.getY(), blockVector3.getZ()); getWorld().getName(),
blockVector3.getX(),
blockVector3.getY(),
blockVector3.getZ(),
tag
);
} }
}); });
} }
@@ -295,9 +301,7 @@ public class BukkitQueueCoordinator extends BasicQueueCoordinator {
existing.setBlockData(blockData, false); existing.setBlockData(blockData, false);
if (block.hasNbtData()) { if (block.hasNbtData()) {
CompoundTag tag = block.getNbtData(); CompoundTag tag = block.getNbtData();
StateWrapper sw = new StateWrapper(tag); StateWrapper.INSTANCE.restore(existing, Objects.requireNonNull(tag));
sw.restoreTag(existing);
} }
} }
} }

View File

@@ -34,6 +34,8 @@ import org.bukkit.entity.EntityType;
import org.bukkit.generator.LimitedRegion; import org.bukkit.generator.LimitedRegion;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Objects;
/** /**
* Wraps a {@link LimitedRegion} inside a {@link com.plotsquared.core.queue.QueueCoordinator} so it can be written to. * Wraps a {@link LimitedRegion} inside a {@link com.plotsquared.core.queue.QueueCoordinator} so it can be written to.
* *
@@ -44,7 +46,6 @@ public class LimitedRegionWrapperQueue extends DelegateQueueCoordinator {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + LimitedRegionWrapperQueue.class.getSimpleName()); private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + LimitedRegionWrapperQueue.class.getSimpleName());
private final LimitedRegion limitedRegion; private final LimitedRegion limitedRegion;
private boolean useOtherRestoreTagMethod = false;
/** /**
* @since 6.9.0 * @since 6.9.0
@@ -64,20 +65,11 @@ public class LimitedRegionWrapperQueue extends DelegateQueueCoordinator {
boolean result = setBlock(x, y, z, id.toImmutableState()); boolean result = setBlock(x, y, z, id.toImmutableState());
if (result && id.hasNbtData()) { if (result && id.hasNbtData()) {
CompoundTag tag = id.getNbtData(); CompoundTag tag = id.getNbtData();
StateWrapper sw = new StateWrapper(tag);
try { try {
if (useOtherRestoreTagMethod && getWorld() != null) { StateWrapper.INSTANCE.restore(limitedRegion.getBlockState(x, y, z).getBlock(), Objects.requireNonNull(tag));
sw.restoreTag(getWorld().getName(), x, y, z);
} else {
sw.restoreTag(limitedRegion.getBlockState(x, y, z).getBlock());
}
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
LOGGER.error("Error attempting to populate tile entity into the world at location {},{},{}", x, y, z, e); LOGGER.error("Error attempting to populate tile entity into the world at location {},{},{}", x, y, z, e);
return false; return false;
} catch (IllegalStateException e) {
useOtherRestoreTagMethod = true;
LOGGER.warn("IllegalStateException attempting to populate tile entity into the world at location {},{},{}. " +
"Possibly on <=1.17.1, switching to secondary method.", x, y, z, e);
} }
} }
return result; return result;
@@ -113,9 +105,8 @@ public class LimitedRegionWrapperQueue extends DelegateQueueCoordinator {
@Override @Override
public boolean setTile(final int x, final int y, final int z, @NonNull final CompoundTag tag) { public boolean setTile(final int x, final int y, final int z, @NonNull final CompoundTag tag) {
StateWrapper sw = new StateWrapper(tag);
try { try {
return sw.restoreTag(limitedRegion.getBlockState(x, y, z).getBlock()); return StateWrapper.INSTANCE.restore(limitedRegion.getBlockState(x, y, z).getBlock(), tag);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
LOGGER.error("Error attempting to populate tile entity into the world at location {},{},{}", x, y, z, e); LOGGER.error("Error attempting to populate tile entity into the world at location {},{},{}", x, y, z, e);
return false; return false;

View File

@@ -27,6 +27,8 @@ import com.plotsquared.core.util.WorldUtil;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.util.Objects;
/** /**
* Schematic Handler. * Schematic Handler.
*/ */
@@ -39,8 +41,8 @@ public class BukkitSchematicHandler extends SchematicHandler {
} }
@Override @Override
public boolean restoreTile(QueueCoordinator queue, CompoundTag ct, int x, int y, int z) { public boolean restoreTile(QueueCoordinator queue, CompoundTag tag, int x, int y, int z) {
return new StateWrapper(ct).restoreTag(queue.getWorld().getName(), x, y, z); return StateWrapper.INSTANCE.restore(Objects.requireNonNull(queue.getWorld()).getName(), x, y, z, tag);
} }
} }

View File

@@ -0,0 +1,80 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.schematic;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonSerializationContext;
import com.google.gson.JsonSerializer;
import com.sk89q.jnbt.ByteArrayTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.IntArrayTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.LongArrayTag;
import com.sk89q.jnbt.Tag;
import java.lang.reflect.Type;
final class NbtGsonSerializer implements JsonSerializer<Tag> {
@Override
public JsonElement serialize(final Tag src, final Type typeOfSrc, final JsonSerializationContext context) {
if (src instanceof CompoundTag compoundTag) {
JsonObject object = new JsonObject();
compoundTag.getValue().forEach((s, tag) -> object.add(s, context.serialize(tag)));
return object;
}
if (src instanceof ListTag listTag) {
JsonArray array = new JsonArray();
listTag.getValue().forEach(tag -> array.add(context.serialize(tag)));
return array;
}
if (src instanceof ByteArrayTag byteArrayTag) {
JsonArray array = new JsonArray();
for (final byte b : byteArrayTag.getValue()) {
array.add(b);
}
return array;
}
if (src instanceof IntArrayTag intArrayTag) {
JsonArray array = new JsonArray();
for (final int i : intArrayTag.getValue()) {
array.add(i);
}
return array;
}
if (src instanceof LongArrayTag longArrayTag) {
JsonArray array = new JsonArray();
for (final long l : longArrayTag.getValue()) {
array.add(l);
}
return array;
}
if (src.getValue() instanceof Number number) {
return new JsonPrimitive(number);
}
if (src.getValue() instanceof String string) {
return new JsonPrimitive(string);
}
throw new IllegalArgumentException("Don't know how to serialize " + src);
}
}

View File

@@ -18,332 +18,71 @@
*/ */
package com.plotsquared.bukkit.schematic; package com.plotsquared.bukkit.schematic;
import com.destroystokyo.paper.profile.PlayerProfile;
import com.destroystokyo.paper.profile.ProfileProperty;
import com.plotsquared.bukkit.util.BukkitUtil; import com.plotsquared.bukkit.util.BukkitUtil;
import com.sk89q.jnbt.ByteTag; import com.plotsquared.core.PlotSquared;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.item.ItemType;
import io.papermc.lib.PaperLib; import io.papermc.lib.PaperLib;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.World; import org.bukkit.World;
import org.bukkit.block.Banner;
import org.bukkit.block.Block; import org.bukkit.block.Block;
import org.bukkit.block.Container;
import org.bukkit.block.Sign;
import org.bukkit.block.Skull;
import org.bukkit.block.banner.Pattern;
import org.bukkit.block.banner.PatternType;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import org.jetbrains.annotations.ApiStatus;
import java.util.ArrayList; @ApiStatus.Internal
import java.util.HashMap; public sealed interface StateWrapper permits StateWrapperSpigot, StateWrapper.Factory.NoopStateWrapper {
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.UUID;
public class StateWrapper { StateWrapper INSTANCE = Factory.createStateWrapper();
public CompoundTag tag; boolean restore(final @NonNull Block block, final @NonNull CompoundTag data);
private boolean paperErrorTextureSent = false; default boolean restore(final String worldName, final int x, final int y, final int z, final CompoundTag data) {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + StateWrapper.class.getSimpleName()); final World world = BukkitUtil.getWorld(worldName);
public StateWrapper(CompoundTag tag) {
this.tag = tag;
}
public static String jsonToColourCode(String str) {
str = str.replace("{\"extra\":", "").replace("],\"text\":\"\"}", "]")
.replace("[{\"color\":\"black\",\"text\":\"", "&0")
.replace("[{\"color\":\"dark_blue\",\"text\":\"", "&1")
.replace("[{\"color\":\"dark_green\",\"text\":\"", "&2")
.replace("[{\"color\":\"dark_aqua\",\"text\":\"", "&3")
.replace("[{\"color\":\"dark_red\",\"text\":\"", "&4")
.replace("[{\"color\":\"dark_purple\",\"text\":\"", "&5")
.replace("[{\"color\":\"gold\",\"text\":\"", "&6")
.replace("[{\"color\":\"gray\",\"text\":\"", "&7")
.replace("[{\"color\":\"dark_gray\",\"text\":\"", "&8")
.replace("[{\"color\":\"blue\",\"text\":\"", "&9")
.replace("[{\"color\":\"green\",\"text\":\"", "&a")
.replace("[{\"color\":\"aqua\",\"text\":\"", "&b")
.replace("[{\"color\":\"red\",\"text\":\"", "&c")
.replace("[{\"color\":\"light_purple\",\"text\":\"", "&d")
.replace("[{\"color\":\"yellow\",\"text\":\"", "&e")
.replace("[{\"color\":\"white\",\"text\":\"", "&f")
.replace("[{\"obfuscated\":true,\"text\":\"", "&k")
.replace("[{\"bold\":true,\"text\":\"", "&l")
.replace("[{\"strikethrough\":true,\"text\":\"", "&m")
.replace("[{\"underlined\":true,\"text\":\"", "&n")
.replace("[{\"italic\":true,\"text\":\"", "&o").replace("[{\"color\":\"black\",", "&0")
.replace("[{\"color\":\"dark_blue\",", "&1")
.replace("[{\"color\":\"dark_green\",", "&2")
.replace("[{\"color\":\"dark_aqua\",", "&3").replace("[{\"color\":\"dark_red\",", "&4")
.replace("[{\"color\":\"dark_purple\",", "&5").replace("[{\"color\":\"gold\",", "&6")
.replace("[{\"color\":\"gray\",", "&7").replace("[{\"color\":\"dark_gray\",", "&8")
.replace("[{\"color\":\"blue\",", "&9").replace("[{\"color\":\"green\",", "&a")
.replace("[{\"color\":\"aqua\",", "&b").replace("[{\"color\":\"red\",", "&c")
.replace("[{\"color\":\"light_purple\",", "&d").replace("[{\"color\":\"yellow\",", "&e")
.replace("[{\"color\":\"white\",", "&f").replace("[{\"obfuscated\":true,", "&k")
.replace("[{\"bold\":true,", "&l").replace("[{\"strikethrough\":true,", "&m")
.replace("[{\"underlined\":true,", "&n").replace("[{\"italic\":true,", "&o")
.replace("{\"color\":\"black\",\"text\":\"", "&0")
.replace("{\"color\":\"dark_blue\",\"text\":\"", "&1")
.replace("{\"color\":\"dark_green\",\"text\":\"", "&2")
.replace("{\"color\":\"dark_aqua\",\"text\":\"", "&3")
.replace("{\"color\":\"dark_red\",\"text\":\"", "&4")
.replace("{\"color\":\"dark_purple\",\"text\":\"", "&5")
.replace("{\"color\":\"gold\",\"text\":\"", "&6")
.replace("{\"color\":\"gray\",\"text\":\"", "&7")
.replace("{\"color\":\"dark_gray\",\"text\":\"", "&8")
.replace("{\"color\":\"blue\",\"text\":\"", "&9")
.replace("{\"color\":\"green\",\"text\":\"", "&a")
.replace("{\"color\":\"aqua\",\"text\":\"", "&b")
.replace("{\"color\":\"red\",\"text\":\"", "&c")
.replace("{\"color\":\"light_purple\",\"text\":\"", "&d")
.replace("{\"color\":\"yellow\",\"text\":\"", "&e")
.replace("{\"color\":\"white\",\"text\":\"", "&f")
.replace("{\"obfuscated\":true,\"text\":\"", "&k")
.replace("{\"bold\":true,\"text\":\"", "&l")
.replace("{\"strikethrough\":true,\"text\":\"", "&m")
.replace("{\"underlined\":true,\"text\":\"", "&n")
.replace("{\"italic\":true,\"text\":\"", "&o").replace("{\"color\":\"black\",", "&0")
.replace("{\"color\":\"dark_blue\",", "&1").replace("{\"color\":\"dark_green\",", "&2")
.replace("{\"color\":\"dark_aqua\",", "&3").replace("{\"color\":\"dark_red\",", "&4")
.replace("{\"color\":\"dark_purple\",", "&5").replace("{\"color\":\"gold\",", "&6")
.replace("{\"color\":\"gray\",", "&7").replace("{\"color\":\"dark_gray\",", "&8")
.replace("{\"color\":\"blue\",", "&9").replace("{\"color\":\"green\",", "&a")
.replace("{\"color\":\"aqua\",", "&b").replace("{\"color\":\"red\",", "&c")
.replace("{\"color\":\"light_purple\",", "&d").replace("{\"color\":\"yellow\",", "&e")
.replace("{\"color\":\"white\",", "&f").replace("{\"obfuscated\":true,", "&k")
.replace("{\"bold\":true,", "&l").replace("{\"strikethrough\":true,", "&m")
.replace("{\"underlined\":true,", "&n").replace("{\"italic\":true,", "&o")
.replace("\"color\":\"black\",\"text\":\"", "&0")
.replace("\"color\":\"dark_blue\",\"text\":\"", "&1")
.replace("\"color\":\"dark_green\",\"text\":\"", "&2")
.replace("\"color\":\"dark_aqua\",\"text\":\"", "&3")
.replace("\"color\":\"dark_red\",\"text\":\"", "&4")
.replace("\"color\":\"dark_purple\",\"text\":\"", "&5")
.replace("\"color\":\"gold\",\"text\":\"", "&6")
.replace("\"color\":\"gray\",\"text\":\"", "&7")
.replace("\"color\":\"dark_gray\",\"text\":\"", "&8")
.replace("\"color\":\"blue\",\"text\":\"", "&9")
.replace("\"color\":\"green\",\"text\":\"", "&a")
.replace("\"color\":\"aqua\",\"text\":\"", "&b")
.replace("\"color\":\"red\",\"text\":\"", "&c")
.replace("\"color\":\"light_purple\",\"text\":\"", "&d")
.replace("\"color\":\"yellow\",\"text\":\"", "&e")
.replace("\"color\":\"white\",\"text\":\"", "&f")
.replace("\"obfuscated\":true,\"text\":\"", "&k")
.replace("\"bold\":true,\"text\":\"", "&l")
.replace("\"strikethrough\":true,\"text\":\"", "&m")
.replace("\"underlined\":true,\"text\":\"", "&n")
.replace("\"italic\":true,\"text\":\"", "&o").replace("\"color\":\"black\",", "&0")
.replace("\"color\":\"dark_blue\",", "&1").replace("\"color\":\"dark_green\",", "&2")
.replace("\"color\":\"dark_aqua\",", "&3").replace("\"color\":\"dark_red\",", "&4")
.replace("\"color\":\"dark_purple\",", "&5").replace("\"color\":\"gold\",", "&6")
.replace("\"color\":\"gray\",", "&7").replace("\"color\":\"dark_gray\",", "&8")
.replace("\"color\":\"blue\",", "&9").replace("\"color\":\"green\",", "&a")
.replace("\"color\":\"aqua\",", "&b").replace("\"color\":\"red\",", "&c")
.replace("\"color\":\"light_purple\",", "&d").replace("\"color\":\"yellow\",", "&e")
.replace("\"color\":\"white\",", "&f").replace("\"obfuscated\":true,", "&k")
.replace("\"bold\":true,", "&l").replace("\"strikethrough\":true,", "&m")
.replace("\"underlined\":true,", "&n").replace("\"italic\":true,", "&o")
.replace("[{\"text\":\"", "&0").replace("{\"text\":\"", "&0").replace("\"},", "")
.replace("\"}]", "").replace("\"}", "");
str = ChatColor.translateAlternateColorCodes('&', str);
return str;
}
/**
* Restore the TileEntity data to the given world at the given coordinates.
*
* @param worldName World name
* @param x x position
* @param y y position
* @param z z position
* @return true if successful
*/
public boolean restoreTag(String worldName, int x, int y, int z) {
World world = BukkitUtil.getWorld(worldName);
if (world == null) { if (world == null) {
return false; return false;
} }
return restoreTag(world.getBlockAt(x, y, z)); return this.restore(world.getBlockAt(x, y, z), data);
} }
/** @ApiStatus.Internal
* Restore the TileEntity data to the given block final class Factory {
*
* @param block Block to restore to
* @return true if successful
*/
@SuppressWarnings("deprecation") // #setLine is needed for Spigot compatibility
public boolean restoreTag(@NonNull Block block) {
if (this.tag == null) {
return false;
}
org.bukkit.block.BlockState state = block.getState();
switch (getId()) {
case "chest", "beacon", "brewingstand", "dispenser", "dropper", "furnace", "hopper", "shulkerbox" -> {
if (!(state instanceof Container container)) {
return false;
}
List<Tag> itemsTag = this.tag.getListTag("Items").getValue();
Inventory inv = container.getSnapshotInventory();
for (Tag itemTag : itemsTag) {
CompoundTag itemComp = (CompoundTag) itemTag;
ItemType type = ItemType.REGISTRY.get(itemComp.getString("id").toLowerCase());
if (type == null) {
continue;
}
int count = itemComp.getByte("Count");
int slot = itemComp.getByte("Slot");
CompoundTag tag = (CompoundTag) itemComp.getValue().get("tag");
BaseItemStack baseItemStack = new BaseItemStack(type, tag, count);
ItemStack itemStack = BukkitAdapter.adapt(baseItemStack);
inv.setItem(slot, itemStack);
}
container.update(true, false);
return true;
}
case "sign" -> {
if (state instanceof Sign sign) {
sign.setLine(0, jsonToColourCode(tag.getString("Text1")));
sign.setLine(1, jsonToColourCode(tag.getString("Text2")));
sign.setLine(2, jsonToColourCode(tag.getString("Text3")));
sign.setLine(3, jsonToColourCode(tag.getString("Text4")));
state.update(true);
return true;
}
return false;
}
case "skull" -> {
if (state instanceof Skull skull) {
CompoundTag skullOwner = ((CompoundTag) this.tag.getValue().get("SkullOwner"));
if (skullOwner == null) {
return true;
}
String player = skullOwner.getString("Name");
if (player != null && !player.isEmpty()) { private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + StateWrapper.class.getSimpleName());
private static final String INITIALIZATION_ERROR_TEMPLATE = """
Failed to initialize StateWrapper: {}
Block-/Tile-Entities, pasted by schematics for example, won't be updated with their respective block data. This affects things like sign text, banner patterns, skulls, etc.
Try updating your Server Software, PlotSquared and WorldEdit / FastAsyncWorldEdit first. If the issue persists, report it on the issue tracker.
""";
private static StateWrapper createStateWrapper() {
int[] serverVersion = PlotSquared.platform().serverVersion();
if (PaperLib.isPaper() && (serverVersion[1] == 21 && serverVersion[2] >= 5) || serverVersion[1] > 21) {
try { try {
skull.setOwningPlayer(Bukkit.getOfflinePlayer(player)); return new StateWrapperPaper1_21_5();
skull.update(true);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); LOGGER.error("Failed to initialize Paper-specific state wrapper, falling back to Spigot", e);
} }
return true; }
try {
return new StateWrapperSpigot();
} catch (Exception e) {
LOGGER.error(INITIALIZATION_ERROR_TEMPLATE, StateWrapperSpigot.class.getSimpleName(), e);
}
return new NoopStateWrapper();
} }
final CompoundTag properties = (CompoundTag) skullOwner.getValue().get("Properties");
if (properties == null) {
return false;
}
final ListTag textures = properties.getListTag("textures");
if (textures.getValue().isEmpty()) {
return false;
}
final CompoundTag textureCompound = (CompoundTag) textures.getValue().get(0);
if (textureCompound == null) {
return false;
}
String textureValue = textureCompound.getString("Value");
if (textureValue == null) {
return false;
}
if (!PaperLib.isPaper()) {
if (!paperErrorTextureSent) {
paperErrorTextureSent = true;
LOGGER.error("Failed to populate skull data in your road schematic - This is a Spigot limitation.");
}
return false;
}
final PlayerProfile profile = Bukkit.createProfile(UUID.randomUUID());
profile.setProperty(new ProfileProperty("textures", textureValue));
skull.setPlayerProfile(profile);
skull.update(true);
return true;
} @ApiStatus.Internal
return false; static final class NoopStateWrapper implements StateWrapper {
}
case "banner" -> { @Override
if (state instanceof Banner banner) { public boolean restore(final @NonNull Block block, final @NonNull CompoundTag data) {
List<Tag> patterns = this.tag.getListTag("Patterns").getValue();
if (patterns == null || patterns.isEmpty()) {
return false;
}
banner.setPatterns(patterns.stream().map(t -> (CompoundTag) t).map(compoundTag -> {
DyeColor color = DyeColor.getByWoolData((byte) compoundTag.getInt("Color"));
PatternType patternType = PatternType.getByIdentifier(compoundTag.getString("Pattern"));
if (color == null || patternType == null) {
return null;
}
return new Pattern(color, patternType);
}).filter(Objects::nonNull).toList());
banner.update(true);
return true;
}
return false;
}
}
return false; return false;
} }
public String getId() {
String tileid = this.tag.getString("id").toLowerCase();
if (tileid.startsWith("minecraft:")) {
tileid = tileid.replace("minecraft:", "");
}
return tileid;
} }
public List<CompoundTag> serializeInventory(ItemStack[] items) {
List<CompoundTag> tags = new ArrayList<>();
for (int i = 0; i < items.length; ++i) {
if (items[i] != null) {
Map<String, Tag> tagData = serializeItem(items[i]);
tagData.put("Slot", new ByteTag((byte) i));
tags.add(new CompoundTag(tagData));
}
}
return tags;
}
public Map<String, Tag> serializeItem(ItemStack item) {
Map<String, Tag> data = new HashMap<>();
data.put("id", new StringTag(item.getType().name()));
data.put("Damage", new ShortTag(item.getDurability()));
data.put("Count", new ByteTag((byte) item.getAmount()));
if (!item.getEnchantments().isEmpty()) {
List<CompoundTag> enchantmentList = new ArrayList<>();
for (Entry<Enchantment, Integer> entry : item.getEnchantments().entrySet()) {
Map<String, Tag> enchantment = new HashMap<>();
enchantment.put("id", new StringTag(entry.getKey().toString()));
enchantment.put("lvl", new ShortTag(entry.getValue().shortValue()));
enchantmentList.add(new CompoundTag(enchantment));
}
Map<String, Tag> auxData = new HashMap<>();
auxData.put("ench", new ListTag(CompoundTag.class, enchantmentList));
data.put("tag", new CompoundTag(auxData));
}
return data;
} }
} }

View File

@@ -0,0 +1,155 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.schematic;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.JsonSyntaxException;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.Tag;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bukkit.DyeColor;
import org.bukkit.block.BlockState;
import org.bukkit.block.Sign;
import org.bukkit.block.sign.Side;
import org.bukkit.block.sign.SignSide;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.invoke.MethodHandle;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
final class StateWrapperPaper1_21_5 extends StateWrapperSpigot {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + StateWrapperPaper1_21_5.class.getSimpleName());
private static final Gson GSON = new GsonBuilder().registerTypeHierarchyAdapter(Tag.class, new NbtGsonSerializer()).create();
private static Object KYORI_GSON_SERIALIZER = null;
private static MethodHandle GSON_SERIALIZER_DESERIALIZE_TREE = null;
private static MethodHandle BUKKIT_SIGN_SIDE_LINE_SET = null;
public StateWrapperPaper1_21_5() {
super();
try {
initializeSignHack();
LOGGER.info("Using {} for block data population", StateWrapperPaper1_21_5.class.getSimpleName());
} catch (Throwable e) {
throw new RuntimeException("Failed to initialize sign hack", e);
}
}
@Override
public void postEntityStateLoad(final @NonNull BlockState blockState, final @NonNull CompoundTag data) throws Throwable {
// signs need special handling during generation
if (blockState instanceof Sign sign) {
if (data.getValue().get("front_text") instanceof CompoundTag textTag) {
setSignTextHack(sign.getSide(Side.FRONT), textTag);
}
if (data.getValue().get("back_text") instanceof CompoundTag textTag) {
setSignTextHack(sign.getSide(Side.BACK), textTag);
}
}
}
@Override
public Logger logger() {
return StateWrapperPaper1_21_5.LOGGER;
}
/**
* Set sign content on the bukkit tile entity. The server does not load sign content applied via the main logic
* (CraftBlockEntity#load), as the SignEntity needs to have a valid ServerLevel assigned to it.
* That's not possible on worldgen; therefore, this hack has to be used additionally.
* <br />
* Modern sign content (non-plain-text sign lines) require Paper.
*
* @param side The sign side to apply data onto.
* @param text The compound tag containing the data for the sign side ({@code front_text} / {@code back_text})
* @throws Throwable if something went wrong when reflectively updating the sign.
*/
private static void setSignTextHack(SignSide side, CompoundTag text) throws Throwable {
if (text.containsKey("color")) {
//noinspection UnstableApiUsage
side.setColor(DyeColor.legacyValueOf(text.getString("color").toUpperCase(Locale.ROOT)));
}
if (text.containsKey("has_glowing_text")) {
side.setGlowingText(text.getByte("has_glowing_text") == 1);
}
List<Tag> lines = text.getList("messages");
if (lines != null) {
for (int i = 0; i < Math.min(lines.size(), 3); i++) {
Tag line = lines.get(i);
Object content = line.getValue();
// Minecraft uses mixed lists / arrays in their sign texts. One line can be a complex component, whereas
// the following line could simply be a string. Those simpler lines are represented as `{"": ""}` (only in
// SNBT those will be shown as a standard string).
if (line instanceof CompoundTag compoundTag && compoundTag.getValue().containsKey("")) {
content = compoundTag.getValue().get("");
}
// absolute garbage way to try to handle stringified components (pre 1.21.5)
else if (content instanceof String contentAsString && (contentAsString.startsWith("{") || contentAsString.startsWith("["))) {
try {
content = JsonParser.parseString(contentAsString);
} catch (JsonSyntaxException e) {
// well, it wasn't JSON after all
}
}
// serializes the line content from JNBT to Gson JSON objects, passes that to adventure and deserializes
// into an adventure component.
// pass all possible types of content into the deserializer (Strings, Compounds, Arrays), even though Strings
// could be set directly via Sign#setLine(int, String). The overhead is minimal, the serializer can handle
// strings - and we don't have to use the deprecated method.
BUKKIT_SIGN_SIDE_LINE_SET.invoke(
side, i, GSON_SERIALIZER_DESERIALIZE_TREE.invoke(
KYORI_GSON_SERIALIZER,
content instanceof JsonElement ? content : GSON.toJsonTree(content)
)
);
}
}
}
private static void initializeSignHack() throws Throwable {
char[] dontObfuscate = new char[]{
'n', 'e', 't', '.', 'k', 'y', 'o', 'r', 'i', '.', 'a', 'd', 'v', 'e', 'n', 't', 'u', 'r', 'e', '.',
't', 'e', 'x', 't', '.', 's', 'e', 'r', 'i', 'a', 'l', 'i', 'z', 'e', 'r', '.', 'g', 's', 'o', 'n', '.',
'G', 's', 'o', 'n', 'C', 'o', 'm', 'p', 'o', 'n', 'e', 'n', 't', 'S', 'e', 'r', 'i', 'a', 'l', 'i', 'z', 'e', 'r'
};
Class<?> gsonComponentSerializerClass = Class.forName(new String(dontObfuscate));
KYORI_GSON_SERIALIZER = Arrays.stream(gsonComponentSerializerClass.getMethods())
.filter(method -> method.getName().equals("gson"))
.findFirst()
.orElseThrow().invoke(null);
GSON_SERIALIZER_DESERIALIZE_TREE = LOOKUP.unreflect(Arrays
.stream(gsonComponentSerializerClass.getMethods())
.filter(method -> method.getName().equals("deserializeFromTree") && method.getParameterCount() == 1)
.findFirst()
.orElseThrow());
BUKKIT_SIGN_SIDE_LINE_SET = LOOKUP.unreflect(Arrays.stream(SignSide.class.getMethods())
.filter(method -> method.getName().equals("line") && method.getParameterCount() == 2)
.findFirst()
.orElseThrow());
}
}

View File

@@ -0,0 +1,210 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.bukkit.schematic;
import com.plotsquared.core.util.ReflectionUtils;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.extension.platform.NoCapablePlatformException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
import org.bukkit.block.Block;
import org.bukkit.block.BlockState;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.util.function.Consumer;
sealed class StateWrapperSpigot implements StateWrapper permits StateWrapperPaper1_21_5 {
private static final boolean FORCE_UPDATE_STATE = true;
private static final boolean UPDATE_TRIGGER_PHYSICS = false;
private static final String CRAFTBUKKIT_PACKAGE = Bukkit.getServer().getClass().getPackageName();
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + StateWrapperSpigot.class.getSimpleName());
static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
private static BukkitImplAdapter ADAPTER = null;
private static Class<?> LIN_TAG_CLASS = null;
private static Class<?> JNBT_TAG_CLASS = null;
private static Class<?> CRAFT_BLOCK_ENTITY_STATE_CLASS = null;
private static MethodHandle PAPERWEIGHT_ADAPTER_FROM_NATIVE = null;
private static MethodHandle CRAFT_BLOCK_ENTITY_STATE_LOAD_DATA = null;
private static MethodHandle CRAFT_BLOCK_ENTITY_STATE_UPDATE = null;
private static MethodHandle TO_LIN_TAG = null;
public StateWrapperSpigot() {
try {
findNbtCompoundClassType(clazz -> LIN_TAG_CLASS = clazz, clazz -> JNBT_TAG_CLASS = clazz);
ReflectionUtils.RefClass worldEditPluginRefClass = ReflectionUtils.getRefClass(WorldEditPlugin.class);
WorldEditPlugin worldEditPlugin = (WorldEditPlugin) worldEditPluginRefClass
.getMethod("getInstance")
.of(null)
.call();
ADAPTER = (BukkitImplAdapter) worldEditPluginRefClass
.getMethod("getBukkitImplAdapter")
.of(worldEditPlugin)
.call();
PAPERWEIGHT_ADAPTER_FROM_NATIVE = findPaperweightAdapterFromNativeMethodHandle(
ADAPTER.getClass(), LIN_TAG_CLASS, JNBT_TAG_CLASS
);
TO_LIN_TAG = findToLinTagMethodHandle(LIN_TAG_CLASS);
} catch (NoSuchMethodException | ClassNotFoundException | IllegalAccessException | NoCapablePlatformException e) {
throw new RuntimeException("Failed to access required WorldEdit methods", e);
}
try {
CRAFT_BLOCK_ENTITY_STATE_CLASS = Class.forName(CRAFTBUKKIT_PACKAGE + ".block.CraftBlockEntityState");
CRAFT_BLOCK_ENTITY_STATE_LOAD_DATA = findCraftBlockEntityStateLoadDataMethodHandle(CRAFT_BLOCK_ENTITY_STATE_CLASS);
CRAFT_BLOCK_ENTITY_STATE_UPDATE = findCraftBlockEntityStateUpdateMethodHandle(CRAFT_BLOCK_ENTITY_STATE_CLASS);
} catch (ClassNotFoundException | NoSuchMethodException | IllegalAccessException e) {
throw new RuntimeException("Failed to initialize required native method accessors", e);
}
}
@Override
public boolean restore(final @NonNull Block block, final @NonNull CompoundTag data) {
try {
final BlockState blockState = block.getState();
if (!CRAFT_BLOCK_ENTITY_STATE_CLASS.isAssignableFrom(blockState.getClass())) {
return false;
}
// get native tag
Object nativeTag = PAPERWEIGHT_ADAPTER_FROM_NATIVE.invoke(
ADAPTER,
LIN_TAG_CLASS == null ? data : TO_LIN_TAG.invoke(data)
);
// load block entity data
CRAFT_BLOCK_ENTITY_STATE_LOAD_DATA.invoke(blockState, nativeTag);
postEntityStateLoad(blockState, data);
CRAFT_BLOCK_ENTITY_STATE_UPDATE.invoke(blockState, FORCE_UPDATE_STATE, UPDATE_TRIGGER_PHYSICS);
} catch (Throwable e) {
logger().error("Failed to update tile entity", e);
}
return false;
}
public void postEntityStateLoad(final @NonNull BlockState blockState, final @NonNull CompoundTag data) throws Throwable {
}
public Logger logger() {
return StateWrapperSpigot.LOGGER;
}
/**
* Initialize the used NBT tag class. For modern FAWE and WE that'll be Lin - for older ones JNBT.
*
* @throws ClassNotFoundException if neither can be found.
*/
private static void findNbtCompoundClassType(Consumer<Class<?>> linClass, Consumer<Class<?>> jnbtClass) throws
ClassNotFoundException {
try {
linClass.accept(Class.forName("org.enginehub.linbus.tree.LinTag"));
} catch (ClassNotFoundException e) {
jnbtClass.accept(Class.forName("com.sk89q.jnbt.Tag"));
}
}
/**
* Finds the {@code toLinTag} method on the {@code ToLinTag} interface, if lin-bus is available in the classpath.
* <br />
* Required to access the underlying lin tag of the used JNBT tag by PlotSquared, so it can be converted into the platforms
* native tag later.
*
* @param linTagClass {@code Tag} class of lin-bus, or {@code null} if not available.
* @return the MethodHandle for {@code toLinTag}, or {@code null} if lin-bus is not available in the classpath.
* @throws ClassNotFoundException if the {@code ToLinTag} class could not be found.
* @throws NoSuchMethodException if no {@code toLinTag} method exists.
* @throws IllegalAccessException shouldn't happen.
*/
private static MethodHandle findToLinTagMethodHandle(Class<?> linTagClass) throws ClassNotFoundException,
NoSuchMethodException, IllegalAccessException {
if (linTagClass == null) {
return null;
}
return LOOKUP.findVirtual(
Class.forName("org.enginehub.linbus.tree.ToLinTag"),
"toLinTag",
MethodType.methodType(linTagClass)
);
}
/**
* Find the method (handle) to convert from native (= WE/FAWE) NBT tags to minecraft NBT tags.
* <br />
* Depending on the used version of WE/FAWE, this differs:
* <ul>
* <li>On WE/FAWE version pre LinBus introduction: {@code fromNative(org.sk89q.jnbt.Tag)}</li>
* <li>On WE versions post LinBus introduction: {@code fromNative(org.enginehub.linbus.tree.LinTag)}</li>
* <li>On FAWE versions post LinBus introduction: {@code fromNativeLin(org.enginehub.linbus.tree.LinTag)}</li>
* </ul>
*
* @param adapterClass The bukkit adapter implementation class
* @param linTagClass The lin-bus {@code Tag} class, if existing - otherwise {@code null}
* @param jnbtTagClass The jnbt {@code Tag} class, if lin-bus was not found in classpath - otherwise {@code null}
* @return the method.
* @throws IllegalAccessException shouldn't happen as private lookup is used.
* @throws NoSuchMethodException if the method couldn't be found.
*/
private static MethodHandle findPaperweightAdapterFromNativeMethodHandle(
Class<?> adapterClass, Class<?> linTagClass, Class<?> jnbtTagClass
) throws IllegalAccessException, NoSuchMethodException {
final MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(adapterClass, LOOKUP);
if (jnbtTagClass != null) {
// usage of JNBT = identical method signatures for WE and FAWE
return lookup.findVirtual(adapterClass, "fromNative", MethodType.methodType(Object.class, jnbtTagClass));
}
try {
// FAWE
return lookup.findVirtual(adapterClass, "fromNativeLin", MethodType.methodType(Object.class, linTagClass));
} catch (NoSuchMethodException e) {
// WE
return lookup.findVirtual(adapterClass, "fromNative", MethodType.methodType(Object.class, linTagClass));
}
}
private static MethodHandle findCraftBlockEntityStateLoadDataMethodHandle(Class<?> craftBlockEntityStateClass) throws
NoSuchMethodException, IllegalAccessException, ClassNotFoundException {
for (final Method method : craftBlockEntityStateClass.getMethods()) {
if (method.getName().equals("loadData") && method.getParameterCount() == 1) {
return LOOKUP.unreflect(method);
}
}
throw new NoSuchMethodException("Couldn't find #loadData(CompoundTag) in " + craftBlockEntityStateClass.getName());
}
private static MethodHandle findCraftBlockEntityStateUpdateMethodHandle(Class<?> craftBlockEntityStateClass) throws
NoSuchMethodException, IllegalAccessException, ClassNotFoundException {
for (final Method method : craftBlockEntityStateClass.getMethods()) {
if (method.getReturnType().equals(Boolean.TYPE) && method.getParameterCount() == 2 &&
method.getParameterTypes()[0] == Boolean.TYPE && method.getParameterTypes()[1] == Boolean.TYPE) {
return LOOKUP.unreflect(method);
}
}
throw new NoSuchMethodException("Couldn't find method for #update(boolean, boolean) in " + craftBlockEntityStateClass.getName());
}
}

View File

@@ -18,6 +18,8 @@
*/ */
package com.plotsquared.core.backup; package com.plotsquared.core.backup;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.Nullable; import org.checkerframework.checker.nullness.qual.Nullable;
import java.io.IOException; import java.io.IOException;
@@ -30,12 +32,14 @@ import java.nio.file.Path;
*/ */
public class Backup { public class Backup {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Backup.class.getSimpleName());
private final BackupProfile owner; private final BackupProfile owner;
private final long creationTime; private final long creationTime;
@Nullable @Nullable
private final Path file; private final Path file;
Backup(final BackupProfile owner, final long creationTime, final Path file) { Backup(final BackupProfile owner, final long creationTime, @Nullable final Path file) {
this.owner = owner; this.owner = owner;
this.creationTime = creationTime; this.creationTime = creationTime;
this.file = file; this.file = file;
@@ -49,7 +53,7 @@ public class Backup {
try { try {
Files.deleteIfExists(file); Files.deleteIfExists(file);
} catch (final IOException e) { } catch (final IOException e) {
e.printStackTrace(); LOGGER.error("Error deleting backup at {}", file, e);
} }
} }
} }

View File

@@ -21,14 +21,15 @@ package com.plotsquared.core.backup;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted; import com.google.inject.assistedinject.Assisted;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.player.ConsolePlayer; import com.plotsquared.core.exception.PlotSquaredException;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.schematic.Schematic; import com.plotsquared.core.plot.schematic.Schematic;
import com.plotsquared.core.util.SchematicHandler; import com.plotsquared.core.util.SchematicHandler;
import com.plotsquared.core.util.task.RunnableVal; import com.plotsquared.core.util.task.RunnableVal;
import com.plotsquared.core.util.task.TaskManager; import com.plotsquared.core.util.task.TaskManager;
import net.kyori.adventure.text.minimessage.MiniMessage; import org.apache.logging.log4j.LogManager;
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 org.checkerframework.checker.nullness.qual.Nullable;
@@ -51,7 +52,7 @@ import java.util.concurrent.CompletableFuture;
*/ */
public class PlayerBackupProfile implements BackupProfile { public class PlayerBackupProfile implements BackupProfile {
static final MiniMessage MINI_MESSAGE = MiniMessage.builder().build(); private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + PlayerBackupProfile.class.getSimpleName());
private final UUID owner; private final UUID owner;
private final Plot plot; private final Plot plot;
@@ -87,7 +88,7 @@ public class PlayerBackupProfile implements BackupProfile {
Files.createDirectory(path); Files.createDirectory(path);
} }
} catch (final Exception e) { } catch (final Exception e) {
e.printStackTrace(); LOGGER.error("Error resolving {} from {}", child, parent, e);
} }
return path; return path;
} }
@@ -104,7 +105,7 @@ public class PlayerBackupProfile implements BackupProfile {
try { try {
Files.createDirectories(path); Files.createDirectories(path);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LOGGER.error("Error creating directory {}", path, e);
return Collections.emptyList(); return Collections.emptyList();
} }
} }
@@ -117,11 +118,11 @@ public class PlayerBackupProfile implements BackupProfile {
backups.add( backups.add(
new Backup(this, basicFileAttributes.creationTime().toMillis(), file)); new Backup(this, basicFileAttributes.creationTime().toMillis(), file));
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LOGGER.error("Error getting attributes for file {} to create backup", file, e);
} }
}); });
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LOGGER.error("Error walking files from {}", path, e);
} }
backups.sort(Comparator.comparingLong(Backup::getCreationTime).reversed()); backups.sort(Comparator.comparingLong(Backup::getCreationTime).reversed());
return (this.backupCache = backups); return (this.backupCache = backups);
@@ -133,7 +134,7 @@ public class PlayerBackupProfile implements BackupProfile {
public void destroy() { public void destroy() {
this.listBackups().whenCompleteAsync((backups, error) -> { this.listBackups().whenCompleteAsync((backups, error) -> {
if (error != null) { if (error != null) {
error.printStackTrace(); LOGGER.error("Error while listing backups", error);
} }
backups.forEach(Backup::delete); backups.forEach(Backup::delete);
this.backupCache = null; this.backupCache = null;
@@ -141,10 +142,12 @@ public class PlayerBackupProfile implements BackupProfile {
} }
public @NonNull Path getBackupDirectory() { public @NonNull Path getBackupDirectory() {
return resolve(resolve( return resolve(
resolve(
resolve(backupManager.getBackupPath(), Objects.requireNonNull(plot.getArea().toString(), "plot area id")), resolve(backupManager.getBackupPath(), Objects.requireNonNull(plot.getArea().toString(), "plot area id")),
Objects.requireNonNull(plot.getId().toDashSeparatedString(), "plot id") Objects.requireNonNull(plot.getId().toDashSeparatedString(), "plot id")
), Objects.requireNonNull(owner.toString(), "owner")); ), Objects.requireNonNull(owner.toString(), "owner")
);
} }
@Override @Override
@@ -156,7 +159,8 @@ public class PlayerBackupProfile implements BackupProfile {
backups.get(backups.size() - 1).delete(); backups.get(backups.size() - 1).delete();
} }
final List<Plot> plots = Collections.singletonList(plot); final List<Plot> plots = Collections.singletonList(plot);
final boolean result = this.schematicHandler.exportAll(plots, getBackupDirectory().toFile(), final boolean result = this.schematicHandler.exportAll(
plots, getBackupDirectory().toFile(),
"%world%-%id%-" + System.currentTimeMillis(), () -> "%world%-%id%-" + System.currentTimeMillis(), () ->
future.complete(new Backup(this, System.currentTimeMillis(), null)) future.complete(new Backup(this, System.currentTimeMillis(), null))
); );
@@ -180,7 +184,7 @@ public class PlayerBackupProfile implements BackupProfile {
try { try {
schematic = this.schematicHandler.getSchematic(backup.getFile().toFile()); schematic = this.schematicHandler.getSchematic(backup.getFile().toFile());
} catch (SchematicHandler.UnsupportedFormatException e) { } catch (SchematicHandler.UnsupportedFormatException e) {
e.printStackTrace(); LOGGER.error("Unsupported format for backup {}", backup.getFile(), e);
} }
if (schematic == null) { if (schematic == null) {
future.completeExceptionally(new IllegalArgumentException( future.completeExceptionally(new IllegalArgumentException(
@@ -200,10 +204,9 @@ public class PlayerBackupProfile implements BackupProfile {
if (value) { if (value) {
future.complete(null); future.complete(null);
} else { } else {
future.completeExceptionally(new RuntimeException(MINI_MESSAGE.escapeTags( future.completeExceptionally(new PlotSquaredException(
TranslatableCaption TranslatableCaption
.of("schematics.schematic_paste_failed") .of("schematics.schematic_paste_failed")));
.getComponent(ConsolePlayer.getConsole()))));
} }
} }
} }

View File

@@ -32,6 +32,8 @@ import com.plotsquared.core.util.task.TaskManager;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.apache.logging.log4j.LogManager;
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 org.checkerframework.checker.nullness.qual.Nullable;
@@ -47,6 +49,7 @@ import java.util.concurrent.TimeUnit;
@Singleton @Singleton
public class SimpleBackupManager implements BackupManager { public class SimpleBackupManager implements BackupManager {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + SimpleBackupManager.class.getSimpleName());
private final Path backupPath; private final Path backupPath;
private final boolean automaticBackup; private final boolean automaticBackup;
private final int backupLimit; private final int backupLimit;
@@ -112,7 +115,12 @@ public class SimpleBackupManager implements BackupManager {
TagResolver.resolver("reason", Tag.inserting(Component.text(throwable.getMessage()))) TagResolver.resolver("reason", Tag.inserting(Component.text(throwable.getMessage())))
); );
} }
throwable.printStackTrace(); LOGGER.error(
"Error creating backup for plot {};{} and player {}",
plot.getArea(),
plot.getId(),
player == null ? "null" : player.getName(), throwable
);
} else { } else {
if (player != null) { if (player != null) {
player.sendMessage(TranslatableCaption.of("backups.backup_automatic_finished")); player.sendMessage(TranslatableCaption.of("backups.backup_automatic_finished"));
@@ -128,6 +136,7 @@ public class SimpleBackupManager implements BackupManager {
return this.automaticBackup; return this.automaticBackup;
} }
@NonNull
public Path getBackupPath() { public Path getBackupPath() {
return this.backupPath; return this.backupPath;
} }

View File

@@ -21,7 +21,6 @@ package com.plotsquared.core.command;
import com.plotsquared.core.PlotSquared; 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.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@@ -58,8 +57,7 @@ public class Alias extends SubCommand {
return false; return false;
} }
Location location = player.getLocation(); Plot plot = player.getCurrentPlot();
Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;

View File

@@ -24,6 +24,7 @@ import com.plotsquared.core.backup.BackupProfile;
import com.plotsquared.core.backup.NullBackupProfile; import com.plotsquared.core.backup.NullBackupProfile;
import com.plotsquared.core.backup.PlayerBackupProfile; import com.plotsquared.core.backup.PlayerBackupProfile;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.exception.PlotSquaredException;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@@ -32,6 +33,8 @@ import com.plotsquared.core.util.task.RunnableVal3;
import net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag; import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver; import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.checkerframework.checker.nullness.qual.NonNull; import org.checkerframework.checker.nullness.qual.NonNull;
import java.nio.file.Files; import java.nio.file.Files;
@@ -57,6 +60,8 @@ import java.util.stream.Stream;
permission = "plots.backup") permission = "plots.backup")
public final class Backup extends Command { public final class Backup extends Command {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + Backup.class.getSimpleName());
private final BackupManager backupManager; private final BackupManager backupManager;
@Inject @Inject
@@ -326,19 +331,28 @@ public final class Backup extends Command {
if (backupProfile instanceof NullBackupProfile) { if (backupProfile instanceof NullBackupProfile) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"), TranslatableCaption.of("backups.backup_impossible"),
TagResolver.resolver("plot", Tag.inserting( TagResolver.resolver(
"plot", Tag.inserting(
TranslatableCaption.of("generic.generic_other").toComponent(player) TranslatableCaption.of("generic.generic_other").toComponent(player)
)) )
)
); );
} else { } else {
backupProfile.listBackups().whenComplete((backups, throwable) -> { backupProfile.listBackups().whenComplete((backups, throwable) -> {
if (throwable != null) { if (throwable != null) {
Component reason;
if (throwable instanceof PlotSquaredException pe) {
reason = pe.getCaption().toComponent(player);
} else {
reason = Component.text(throwable.getMessage());
}
player.sendMessage( player.sendMessage(
TranslatableCaption.of("backups.backup_load_failure"), TranslatableCaption.of("backups.backup_load_failure"),
TagResolver.resolver("reason", Tag.inserting(Component.text(throwable.getMessage()))) TagResolver.resolver("reason", Tag.inserting(reason))
); );
throwable.printStackTrace(); LOGGER.error("Error loading player ({}) backup", player.getName(), throwable);
} else { return;
}
if (number < 1 || number > backups.size()) { if (number < 1 || number > backups.size()) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("backups.backup_impossible"), TranslatableCaption.of("backups.backup_impossible"),
@@ -364,7 +378,8 @@ public final class Backup extends Command {
) )
); );
} else { } else {
CmdConfirm.addPending(player, "/plot backup load " + number, CmdConfirm.addPending(
player, "/plot backup load " + number,
() -> backupProfile.restoreBackup(backup, player) () -> backupProfile.restoreBackup(backup, player)
.whenComplete((n, error) -> { .whenComplete((n, error) -> {
if (error != null) { if (error != null) {
@@ -382,7 +397,6 @@ public final class Backup extends Command {
); );
} }
} }
}
}); });
} }
} }

View File

@@ -20,6 +20,7 @@ package com.plotsquared.core.command;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared; import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.PlayerBuyPlotEvent; import com.plotsquared.core.events.PlayerBuyPlotEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
@@ -84,8 +85,9 @@ public class Buy extends Command {
checkTrue(plot.hasOwner(), TranslatableCaption.of("info.plot_unowned")); checkTrue(plot.hasOwner(), TranslatableCaption.of("info.plot_unowned"));
checkTrue(!plot.isOwner(player.getUUID()), TranslatableCaption.of("economy.cannot_buy_own")); checkTrue(!plot.isOwner(player.getUUID()), TranslatableCaption.of("economy.cannot_buy_own"));
Set<Plot> plots = plot.getConnectedPlots(); Set<Plot> plots = plot.getConnectedPlots();
int plotCount = Settings.Limit.GLOBAL ? player.getPlotCount() : player.getPlotCount(plot.getWorldName());
checkTrue( checkTrue(
player.getPlotCount() + plots.size() <= player.getAllowedPlots(), plotCount + plots.size() <= player.getAllowedPlots(),
TranslatableCaption.of("permission.cant_claim_more_plots"), TranslatableCaption.of("permission.cant_claim_more_plots"),
TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots()))) TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots())))
); );

View File

@@ -26,7 +26,6 @@ import com.plotsquared.core.events.PlayerClaimPlotEvent;
import com.plotsquared.core.events.PlotMergeEvent; import com.plotsquared.core.events.PlotMergeEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.location.Direction; import com.plotsquared.core.location.Direction;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.MetaDataAccess; import com.plotsquared.core.player.MetaDataAccess;
import com.plotsquared.core.player.PlayerMetaDataKeys; import com.plotsquared.core.player.PlayerMetaDataKeys;
@@ -72,8 +71,7 @@ public class Claim extends SubCommand {
if (args.length >= 1) { if (args.length >= 1) {
schematic = args[0]; schematic = args[0];
} }
Location location = player.getLocation(); Plot plot = player.getCurrentPlot();
Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;
@@ -90,7 +88,7 @@ public class Claim extends SubCommand {
boolean force = event.getEventResult() == Result.FORCE; boolean force = event.getEventResult() == Result.FORCE;
int currentPlots = Settings.Limit.GLOBAL ? int currentPlots = Settings.Limit.GLOBAL ?
player.getPlotCount() : player.getPlotCount() :
player.getPlotCount(location.getWorldName()); player.getPlotCount(plot.getWorldName());
final PlotArea area = plot.getArea(); final PlotArea area = plot.getArea();

View File

@@ -68,8 +68,8 @@ public class Continue extends SubCommand {
return false; return false;
} }
int size = plot.getConnectedPlots().size(); int size = plot.getConnectedPlots().size();
if (!Settings.Done.COUNTS_TOWARDS_LIMIT && (player.getAllowedPlots() int plotCount = Settings.Limit.GLOBAL ? player.getPlotCount() : player.getPlotCount(plot.getWorldName());
< player.getPlotCount() + size)) { if (!Settings.Done.COUNTS_TOWARDS_LIMIT && (player.getAllowedPlots() < plotCount + size)) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("permission.cant_claim_more_plots"), TranslatableCaption.of("permission.cant_claim_more_plots"),
TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots()))) TagResolver.resolver("amount", Tag.inserting(Component.text(player.getAllowedPlots())))

View File

@@ -19,7 +19,6 @@
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@@ -37,8 +36,7 @@ public class Copy extends SubCommand {
@Override @Override
public boolean onCommand(final PlotPlayer<?> player, String[] args) { public boolean onCommand(final PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); Plot plot1 = player.getCurrentPlot();
Plot plot1 = location.getPlotAbs();
if (plot1 == null) { if (plot1 == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;

View File

@@ -22,7 +22,6 @@ import com.google.inject.Inject;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
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.location.Location;
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 net.kyori.adventure.text.Component; import net.kyori.adventure.text.Component;
@@ -47,8 +46,7 @@ public class CreateRoadSchematic extends SubCommand {
@Override @Override
public boolean onCommand(PlotPlayer<?> player, String[] args) { public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); Plot plot = player.getCurrentPlot();
Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;
@@ -57,7 +55,7 @@ public class CreateRoadSchematic extends SubCommand {
player.sendMessage(TranslatableCaption.of("schematics.schematic_too_large")); player.sendMessage(TranslatableCaption.of("schematics.schematic_too_large"));
return false; return false;
} }
if (!(location.getPlotArea() instanceof HybridPlotWorld)) { if (!(plot.getArea() instanceof HybridPlotWorld)) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world"));
} }
this.hybridUtils.setupRoadSchematic(plot); this.hybridUtils.setupRoadSchematic(plot);

View File

@@ -22,7 +22,6 @@ import com.google.inject.Inject;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.generator.HybridPlotManager; import com.plotsquared.core.generator.HybridPlotManager;
import com.plotsquared.core.generator.HybridUtils; import com.plotsquared.core.generator.HybridUtils;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.plot.PlotArea; import com.plotsquared.core.plot.PlotArea;
@@ -57,8 +56,7 @@ public class DebugRoadRegen extends SubCommand {
@Override @Override
public boolean onCommand(PlotPlayer<?> player, String[] args) { public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); Plot plot = player.getCurrentPlot();
Plot plot = location.getPlotAbs();
if (args.length < 1) { if (args.length < 1) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("commandconfig.command_syntax"), TranslatableCaption.of("commandconfig.command_syntax"),
@@ -92,8 +90,7 @@ public class DebugRoadRegen extends SubCommand {
} }
public boolean regenPlot(PlotPlayer<?> player) { public boolean regenPlot(PlotPlayer<?> player) {
Location location = player.getLocation(); PlotArea area = player.getContextualPlotArea();
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; return false;
@@ -148,10 +145,10 @@ public class DebugRoadRegen extends SubCommand {
return false; return false;
} }
Location location = player.getLocation(); PlotArea area = player.getContextualPlotArea();
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();
PlotManager manager = area.getPlotManager(); PlotManager manager = area.getPlotManager();

View File

@@ -23,7 +23,6 @@ import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.events.TeleportCause; import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@@ -61,8 +60,7 @@ public class Delete extends SubCommand {
@Override @Override
public boolean onCommand(final PlotPlayer<?> player, String[] args) { public boolean onCommand(final PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); final Plot plot = player.getCurrentPlot();
final Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;
@@ -92,7 +90,7 @@ public class Delete extends SubCommand {
final java.util.Set<Plot> plots = plot.getConnectedPlots(); final java.util.Set<Plot> plots = plot.getConnectedPlots();
final int currentPlots = Settings.Limit.GLOBAL ? final int currentPlots = Settings.Limit.GLOBAL ?
player.getPlotCount() : player.getPlotCount() :
player.getPlotCount(location.getWorldName()); player.getPlotCount(plot.getWorldName());
Runnable run = () -> { Runnable run = () -> {
if (plot.getRunning() > 0) { if (plot.getRunning() > 0) {
player.sendMessage(TranslatableCaption.of("errors.wait_for_timer")); player.sendMessage(TranslatableCaption.of("errors.wait_for_timer"));

View File

@@ -70,8 +70,7 @@ public class Deny extends SubCommand {
@Override @Override
public boolean onCommand(PlotPlayer<?> player, String[] args) { public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); final Plot plot = player.getCurrentPlot();
final Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;

View File

@@ -26,7 +26,6 @@ import com.plotsquared.core.events.PlotDoneEvent;
import com.plotsquared.core.events.PlotFlagAddEvent; import com.plotsquared.core.events.PlotFlagAddEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.generator.HybridUtils; import com.plotsquared.core.generator.HybridUtils;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@@ -61,8 +60,7 @@ public class Done extends SubCommand {
@Override @Override
public boolean onCommand(final PlotPlayer<?> player, String[] args) { public boolean onCommand(final PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); final Plot plot = player.getCurrentPlot();
final Plot plot = location.getPlotAbs();
if ((plot == null) || !plot.hasOwner()) { if ((plot == null) || !plot.hasOwner()) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;

View File

@@ -73,7 +73,7 @@ public class Download extends SubCommand {
@Override @Override
public boolean onCommand(final PlotPlayer<?> player, String[] args) { public boolean onCommand(final PlotPlayer<?> player, String[] args) {
String world = player.getLocation().getWorldName(); String world = player.getCurrentPlot().getWorldName();
if (!this.plotAreaManager.hasPlotArea(world)) { if (!this.plotAreaManager.hasPlotArea(world)) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world"));
return false; return false;

View File

@@ -27,7 +27,6 @@ import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.PlotFlagAddEvent; import com.plotsquared.core.events.PlotFlagAddEvent;
import com.plotsquared.core.events.PlotFlagRemoveEvent; import com.plotsquared.core.events.PlotFlagRemoveEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@@ -179,8 +178,7 @@ public final class FlagCommand extends Command {
* @return {@code true} if the player is allowed to modify the flags at their current location * @return {@code true} if the player is allowed to modify the flags at their current location
*/ */
private static boolean checkRequirements(final @NonNull PlotPlayer<?> player) { private static boolean checkRequirements(final @NonNull PlotPlayer<?> player) {
final Location location = player.getLocation(); final Plot plot = player.getCurrentPlot();
final Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;
@@ -344,7 +342,7 @@ public final class FlagCommand extends Command {
if (plotFlag == null) { if (plotFlag == null) {
return; return;
} }
Plot plot = player.getLocation().getPlotAbs(); Plot plot = player.getCurrentPlot();
PlotFlagAddEvent event = eventDispatcher.callFlagAdd(plotFlag, plot); PlotFlagAddEvent event = eventDispatcher.callFlagAdd(plotFlag, plot);
if (event.getEventResult() == Result.DENY) { if (event.getEventResult() == Result.DENY) {
player.sendMessage( player.sendMessage(
@@ -409,7 +407,7 @@ public final class FlagCommand extends Command {
if (plotFlag == null) { if (plotFlag == null) {
return; return;
} }
Plot plot = player.getLocation().getPlotAbs(); Plot plot = player.getCurrentPlot();
PlotFlagAddEvent event = eventDispatcher.callFlagAdd(plotFlag, plot); PlotFlagAddEvent event = eventDispatcher.callFlagAdd(plotFlag, plot);
if (event.getEventResult() == Result.DENY) { if (event.getEventResult() == Result.DENY) {
player.sendMessage( player.sendMessage(
@@ -419,7 +417,7 @@ public final class FlagCommand extends Command {
return; return;
} }
boolean force = event.getEventResult() == Result.FORCE; boolean force = event.getEventResult() == Result.FORCE;
final PlotFlag localFlag = player.getLocation().getPlotAbs().getFlagContainer() final PlotFlag localFlag = player.getCurrentPlot().getFlagContainer()
.getFlag(event.getFlag().getClass()); .getFlag(event.getFlag().getClass());
if (!force) { if (!force) {
for (String entry : args[1].split(",")) { for (String entry : args[1].split(",")) {
@@ -444,7 +442,7 @@ public final class FlagCommand extends Command {
return; return;
} }
boolean result = boolean result =
player.getLocation().getPlotAbs().setFlag(localFlag.merge(parsed.getValue())); player.getCurrentPlot().setFlag(localFlag.merge(parsed.getValue()));
if (!result) { if (!result) {
player.sendMessage(TranslatableCaption.of("flag.flag_not_added")); player.sendMessage(TranslatableCaption.of("flag.flag_not_added"));
return; return;
@@ -484,7 +482,7 @@ public final class FlagCommand extends Command {
if (flag == null) { if (flag == null) {
return; return;
} }
final Plot plot = player.getLocation().getPlotAbs(); final Plot plot = player.getCurrentPlot();
final PlotFlag<?, ?> flagWithOldValue = plot.getFlagContainer().getFlag(flag.getClass()); final PlotFlag<?, ?> flagWithOldValue = plot.getFlagContainer().getFlag(flag.getClass());
PlotFlagRemoveEvent event = eventDispatcher.callFlagRemove(flag, plot); PlotFlagRemoveEvent event = eventDispatcher.callFlagRemove(flag, plot);
if (event.getEventResult() == Result.DENY) { if (event.getEventResult() == Result.DENY) {
@@ -687,7 +685,7 @@ public final class FlagCommand extends Command {
.build() .build()
); );
// Default value // Default value
final String defaultValue = player.getLocation().getPlotArea().getFlagContainer() final String defaultValue = player.getCurrentPlot().getArea().getFlagContainer()
.getFlagErased(plotFlag.getClass()).toString(); .getFlagErased(plotFlag.getClass()).toString();
player.sendMessage( player.sendMessage(
TranslatableCaption.of("flag.flag_info_default_value"), TranslatableCaption.of("flag.flag_info_default_value"),

View File

@@ -177,8 +177,14 @@ public class Grant extends Command {
commands.addAll(TabCompletions.completePlayers(player, args[0], Collections.emptyList())); commands.addAll(TabCompletions.completePlayers(player, args[0], Collections.emptyList()));
} }
return commands; return commands;
} else if (args.length == 2) {
final String subcommand = args[0].toLowerCase();
if ((subcommand.equals("add") && player.hasPermission(Permission.PERMISSION_GRANT_ADD)) ||
(subcommand.equals("check") && player.hasPermission(Permission.PERMISSION_GRANT_CHECK))) {
return TabCompletions.completePlayers(player, args[1], Collections.emptyList());
} }
return TabCompletions.completePlayers(player, String.join(",", args).trim(), Collections.emptyList()); }
return Collections.emptyList();
} }
} }

View File

@@ -65,8 +65,7 @@ public class Kick extends SubCommand {
@Override @Override
public boolean onCommand(PlotPlayer<?> player, String[] args) { public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); Plot plot = player.getCurrentPlot();
Plot plot = location.getPlot();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;
@@ -124,7 +123,7 @@ public class Kick extends SubCommand {
); );
return; return;
} }
Location spawn = this.worldUtil.getSpawn(location.getWorldName()); Location spawn = this.worldUtil.getSpawn(plot.getWorldName());
player2.sendMessage(TranslatableCaption.of("kick.you_got_kicked")); player2.sendMessage(TranslatableCaption.of("kick.you_got_kicked"));
if (plot.equals(spawn.getPlot())) { if (plot.equals(spawn.getPlot())) {
Location newSpawn = this.worldUtil.getSpawn(this.plotAreaManager.getAllWorlds()[0]); Location newSpawn = this.worldUtil.getSpawn(this.plotAreaManager.getAllWorlds()[0]);
@@ -148,8 +147,7 @@ public class Kick extends SubCommand {
@Override @Override
public Collection<Command> tab(final PlotPlayer<?> player, final String[] args, final boolean space) { public Collection<Command> tab(final PlotPlayer<?> player, final String[] args, final boolean space) {
Location location = player.getLocation(); Plot plot = player.getCurrentPlot();
Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@@ -150,8 +150,8 @@ public class ListCmd extends SubCommand {
page = 0; page = 0;
} }
String world = player.getLocation().getWorldName(); PlotArea area = player.getContextualPlotArea();
PlotArea area = player.getApplicablePlotArea(); String world = area != null ? area.getWorldName() : "";
String arg = args[0].toLowerCase(); String arg = args[0].toLowerCase();
final boolean[] sort = new boolean[]{true}; final boolean[] sort = new boolean[]{true};

View File

@@ -68,11 +68,6 @@ public class Load extends SubCommand {
@Override @Override
public boolean onCommand(final PlotPlayer<?> player, final String[] args) { public boolean onCommand(final PlotPlayer<?> player, final String[] args) {
final String world = player.getLocation().getWorldName();
if (!this.plotAreaManager.hasPlotArea(world)) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot_world"));
return false;
}
final Plot plot = player.getCurrentPlot(); final Plot plot = player.getCurrentPlot();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));

View File

@@ -283,24 +283,35 @@ public class MainCommand extends Command {
} }
} }
private CompletableFuture<Optional<CommandExecutionData>> preparePlotArgument(@Nullable Plot newPlot, private CompletableFuture<Optional<CommandExecutionData>> preparePlotArgument(
@Nullable Plot newPlot,
@Nonnull CommandExecutionData data, @Nonnull CommandExecutionData data,
@Nullable PlotArea area) { @Nullable PlotArea area
if (newPlot != null && (data.player() instanceof ConsolePlayer ) {
|| (area != null && area.equals(newPlot.getArea())) if (newPlot == null) {
|| data.player().hasPermission(Permission.PERMISSION_ADMIN) return CompletableFuture.completedFuture(Optional.of(data));
|| data.player().hasPermission(Permission.PERMISSION_ADMIN_AREA_SUDO)) }
&& !newPlot.isDenied(data.player().getUUID())) { final PlotPlayer<?> player = data.player();
final boolean isAdmin = player instanceof ConsolePlayer || player.hasPermission(Permission.PERMISSION_ADMIN);
final boolean isDenied = newPlot.isDenied(player.getUUID());
if (!isAdmin) {
if (isDenied) {
throw new CommandException(TranslatableCaption.of("deny.cannot_interact"));
}
if (area != null && area.equals(newPlot.getArea()) && !player.hasPermission(Permission.PERMISSION_ADMIN_AREA_SUDO)) {
return CompletableFuture.completedFuture(Optional.of(data));
}
}
return fetchPlotCenterLocation(newPlot) return fetchPlotCenterLocation(newPlot)
.thenApply(newLoc -> { .thenApply(newLoc -> {
if (!data.player().canTeleport(newLoc)) { if (!player.canTeleport(newLoc)) {
data.player().sendMessage(TranslatableCaption.of("border.denied")); player.sendMessage(TranslatableCaption.of("border.denied"));
return Optional.empty(); return Optional.empty();
} }
// Save meta // Save meta
var originalCommandMeta = setCommandScope(data.player(), new TemporaryCommandMeta(newLoc, newPlot)); var originalCommandMeta = setCommandScope(player, new TemporaryCommandMeta(newLoc, newPlot));
return Optional.of(new CommandExecutionData( return Optional.of(new CommandExecutionData(
data.player(), player,
Arrays.copyOfRange(data.args(), 1, data.args().length), // Trimmed command Arrays.copyOfRange(data.args(), 1, data.args().length), // Trimmed command
data.confirm(), data.confirm(),
data.whenDone(), data.whenDone(),
@@ -308,8 +319,6 @@ public class MainCommand extends Command {
)); ));
}); });
} }
return CompletableFuture.completedFuture(Optional.of(data));
}
private Optional<CommandExecutionData> prepareFlagArgument(@Nonnull CommandExecutionData data, @Nonnull PlotArea area) { private Optional<CommandExecutionData> prepareFlagArgument(@Nonnull CommandExecutionData data, @Nonnull PlotArea area) {
if (data.args().length >= 2 && !data.args()[0].isEmpty() && data.args()[0].charAt(0) == '-') { if (data.args().length >= 2 && !data.args()[0].isEmpty() && data.args()[0].charAt(0) == '-') {

View File

@@ -20,7 +20,6 @@ package com.plotsquared.core.command;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.TeleportCause; import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@@ -36,8 +35,7 @@ public class Middle extends SubCommand {
@Override @Override
public boolean onCommand(PlotPlayer<?> player, String[] arguments) { public boolean onCommand(PlotPlayer<?> player, String[] arguments) {
Location location = player.getLocation(); Plot plot = player.getCurrentPlot();
Plot plot = location.getPlot();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;

View File

@@ -20,7 +20,6 @@ package com.plotsquared.core.command;
import com.google.inject.Inject; import com.google.inject.Inject;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@@ -55,8 +54,7 @@ public class Move extends SubCommand {
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone RunnableVal2<Command, CommandResult> whenDone
) { ) {
Location location = player.getLocation(); Plot plot1 = player.getCurrentPlot();
Plot plot1 = location.getPlotAbs();
if (plot1 == null) { if (plot1 == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return CompletableFuture.completedFuture(false); return CompletableFuture.completedFuture(false);

View File

@@ -23,7 +23,6 @@ import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.PlotFlagAddEvent; import com.plotsquared.core.events.PlotFlagAddEvent;
import com.plotsquared.core.events.PlotFlagRemoveEvent; import com.plotsquared.core.events.PlotFlagRemoveEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@@ -74,8 +73,7 @@ public class Music extends SubCommand {
@Override @Override
public boolean onCommand(PlotPlayer<?> player, String[] args) { public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); final Plot plot = player.getCurrentPlot();
final Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;

View File

@@ -21,7 +21,6 @@ package com.plotsquared.core.command;
import com.google.inject.Inject; import com.google.inject.Inject;
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;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@@ -56,8 +55,7 @@ public class Remove extends SubCommand {
@Override @Override
public boolean onCommand(PlotPlayer<?> player, String[] args) { public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); Plot plot = player.getCurrentPlot();
Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;
@@ -132,8 +130,7 @@ public class Remove extends SubCommand {
@Override @Override
public Collection<Command> tab(final PlotPlayer<?> player, final String[] args, final boolean space) { public Collection<Command> tab(final PlotPlayer<?> player, final String[] args, final boolean space) {
Location location = player.getLocation(); Plot plot = player.getCurrentPlot();
Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
return Collections.emptyList(); return Collections.emptyList();
} }

View File

@@ -22,7 +22,6 @@ import com.google.common.collect.Lists;
import com.google.inject.Inject; import com.google.inject.Inject;
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.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.ConsolePlayer; import com.plotsquared.core.player.ConsolePlayer;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
@@ -102,8 +101,7 @@ public class SchematicCmd extends SubCommand {
); );
break; break;
} }
Location loc = player.getLocation(); final Plot plot = player.getCurrentPlot();
final Plot plot = loc.getPlotAbs();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;
@@ -247,8 +245,7 @@ public class SchematicCmd extends SubCommand {
player.sendMessage(TranslatableCaption.of("error.task_in_process")); player.sendMessage(TranslatableCaption.of("error.task_in_process"));
return false; return false;
} }
Location location = player.getLocation(); Plot plot = player.getCurrentPlot();
Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;

View File

@@ -78,7 +78,7 @@ public class Set extends SubCommand {
@Override @Override
public boolean set(PlotPlayer<?> player, final Plot plot, String value) { public boolean set(PlotPlayer<?> player, final Plot plot, String value) {
final PlotArea plotArea = player.getLocation().getPlotArea(); final PlotArea plotArea = player.getContextualPlotArea();
if (plotArea == null) { if (plotArea == null) {
return false; return false;
} }

View File

@@ -19,7 +19,6 @@
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@@ -32,8 +31,7 @@ public abstract class SetCommand extends SubCommand {
@Override @Override
public boolean onCommand(PlotPlayer<?> player, String[] args) { public boolean onCommand(PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); Plot plot = player.getCurrentPlot();
Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;

View File

@@ -19,7 +19,6 @@
package com.plotsquared.core.command; package com.plotsquared.core.command;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@@ -44,8 +43,7 @@ public class Swap extends SubCommand {
RunnableVal3<Command, Runnable, Runnable> confirm, RunnableVal3<Command, Runnable, Runnable> confirm,
RunnableVal2<Command, CommandResult> whenDone RunnableVal2<Command, CommandResult> whenDone
) { ) {
Location location = player.getLocation(); Plot plot1 = player.getCurrentPlot();
Plot plot1 = location.getPlotAbs();
if (plot1 == null) { if (plot1 == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return CompletableFuture.completedFuture(false); return CompletableFuture.completedFuture(false);
@@ -79,8 +77,10 @@ public class Swap extends SubCommand {
String p1 = plot1.toString(); String p1 = plot1.toString();
String p2 = plot2.toString(); String p2 = plot2.toString();
return plot1.getPlotModificationManager().move(plot2, player, () -> { return plot1.getPlotModificationManager().move(
}, true).thenApply(result -> { plot2, player, () -> {
}, true
).thenApply(result -> {
if (result) { if (result) {
player.sendMessage( player.sendMessage(
TranslatableCaption.of("swap.swap_success"), TranslatableCaption.of("swap.swap_success"),

View File

@@ -22,7 +22,6 @@ import com.google.inject.Inject;
import com.plotsquared.core.configuration.caption.TranslatableCaption; import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.PlotUnlinkEvent; import com.plotsquared.core.events.PlotUnlinkEvent;
import com.plotsquared.core.events.Result; import com.plotsquared.core.events.Result;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission; import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer; import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot; import com.plotsquared.core.plot.Plot;
@@ -51,8 +50,7 @@ public class Unlink extends SubCommand {
@Override @Override
public boolean onCommand(final PlotPlayer<?> player, String[] args) { public boolean onCommand(final PlotPlayer<?> player, String[] args) {
Location location = player.getLocation(); final Plot plot = player.getCurrentPlot();
final Plot plot = location.getPlotAbs();
if (plot == null) { if (plot == null) {
player.sendMessage(TranslatableCaption.of("errors.not_in_plot")); player.sendMessage(TranslatableCaption.of("errors.not_in_plot"));
return false; return false;

View File

@@ -0,0 +1,62 @@
/*
* 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.exception;
import com.plotsquared.core.configuration.caption.Caption;
import com.plotsquared.core.configuration.caption.LocaleHolder;
/**
* Internal use only. Used to allow adventure captions to be used in an exception
*
* @since 7.5.7
*/
public final class PlotSquaredException extends RuntimeException {
private final Caption caption;
/**
* Create a new instance with the given caption
*
* @param caption caption
*/
public PlotSquaredException(Caption caption) {
this.caption = caption;
}
/**
* Create a new instance with the given caption and cause
*
* @param caption caption
* @param cause cause
*/
public PlotSquaredException(Caption caption, Exception cause) {
super(cause);
this.caption = caption;
}
@Override
public String getMessage() {
return caption.getComponent(LocaleHolder.console());
}
public Caption getCaption() {
return caption;
}
}

View File

@@ -290,7 +290,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
* *
* @return the plot the player is standing on or null if standing on a road or not in a {@link PlotArea} * @return the plot the player is standing on or null if standing on a road or not in a {@link PlotArea}
*/ */
public Plot getCurrentPlot() { public @Nullable Plot getCurrentPlot() {
try (final MetaDataAccess<Plot> lastPlotAccess = try (final MetaDataAccess<Plot> lastPlotAccess =
this.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) { this.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
if (lastPlotAccess.get().orElse(null) == null && !Settings.Enabled_Components.EVENTS) { if (lastPlotAccess.get().orElse(null) == null && !Settings.Enabled_Components.EVENTS) {
@@ -319,7 +319,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
*/ */
public int getPlotCount() { public int getPlotCount() {
if (!Settings.Limit.GLOBAL) { if (!Settings.Limit.GLOBAL) {
return getPlotCount(getLocation().getWorldName()); return getPlotCount(getContextualWorldName());
} }
final AtomicInteger count = new AtomicInteger(0); final AtomicInteger count = new AtomicInteger(0);
final UUID uuid = getUUID(); final UUID uuid = getUUID();
@@ -339,7 +339,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
public int getClusterCount() { public int getClusterCount() {
if (!Settings.Limit.GLOBAL) { if (!Settings.Limit.GLOBAL) {
return getClusterCount(getLocation().getWorldName()); return getClusterCount(getContextualWorldName());
} }
final AtomicInteger count = new AtomicInteger(0); final AtomicInteger count = new AtomicInteger(0);
this.plotAreaManager.forEachPlotArea(value -> { this.plotAreaManager.forEachPlotArea(value -> {
@@ -352,6 +352,34 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
return count.get(); return count.get();
} }
/**
* {@return the world name at the player's contextual position}
* The contextual position can be affected when using a command with
* an explicit plot override, e.g., `/plot &ltid&gt info`.
*/
private @NonNull String getContextualWorldName() {
Plot current = getCurrentPlot();
if (current != null) {
return current.getWorldName();
}
return getLocation().getWorldName();
}
/**
* {@return the plot area at the player's contextual position}
* The contextual position can be affected when using a command with
* an explicit plot override, e.g., `/plot &ltid&gt info`.
*
* @since TODO
*/
public @Nullable PlotArea getContextualPlotArea() {
Plot current = getCurrentPlot();
if (current != null) {
return current.getArea();
}
return getLocation().getPlotArea();
}
/** /**
* Get the number of plots this player owns in the world. * Get the number of plots this player owns in the world.
* *
@@ -408,8 +436,12 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
} }
public PlotArea getApplicablePlotArea() { public PlotArea getApplicablePlotArea() {
Plot plot = getCurrentPlot();
if (plot == null) {
return this.plotAreaManager.getApplicablePlotArea(getLocation()); return this.plotAreaManager.getApplicablePlotArea(getLocation());
} }
return plot.getArea();
}
@Override @Override
public @NonNull RequiredType getSuperCaller() { public @NonNull RequiredType getSuperCaller() {
@@ -614,16 +646,16 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
PlotId id = plot.getId(); PlotId id = plot.getId();
int x = id.getX(); int x = id.getX();
int z = id.getY(); int z = id.getY();
ByteBuffer buffer = ByteBuffer.allocate(13); ByteBuffer buffer = ByteBuffer.allocate(14);
buffer.putShort((short) x); buffer.putShort((short) x);
buffer.putShort((short) z); buffer.putShort((short) z);
Location location = getLocation(); Location location = getLocation();
buffer.putInt(location.getX()); buffer.putInt(location.getX());
buffer.put((byte) location.getY()); buffer.putShort((short) location.getY());
buffer.putInt(location.getZ()); buffer.putInt(location.getZ());
setPersistentMeta("quitLoc", buffer.array()); setPersistentMeta("quitLocV2", buffer.array());
} else if (hasPersistentMeta("quitLoc")) { } else if (hasPersistentMeta("quitLocV2")) {
removePersistentMeta("quitLoc"); removePersistentMeta("quitLocV2");
} }
if (plot != null) { if (plot != null) {
this.eventDispatcher.callLeave(this, plot); this.eventDispatcher.callLeave(this, plot);
@@ -678,7 +710,8 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
public void populatePersistentMetaMap() { public void populatePersistentMetaMap() {
if (Settings.Enabled_Components.PERSISTENT_META) { if (Settings.Enabled_Components.PERSISTENT_META) {
DBFunc.getPersistentMeta(getUUID(), new RunnableVal<>() { DBFunc.getPersistentMeta(
getUUID(), new RunnableVal<>() {
@Override @Override
public void run(Map<String, byte[]> value) { public void run(Map<String, byte[]> value) {
try { try {
@@ -700,11 +733,18 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
return; return;
} }
PlotArea area = ((SinglePlotAreaManager) manager).getArea(); PlotArea area = ((SinglePlotAreaManager) manager).getArea();
boolean V2 = false;
byte[] arr = PlotPlayer.this.getPersistentMeta("quitLoc"); byte[] arr = PlotPlayer.this.getPersistentMeta("quitLoc");
if (arr == null) {
arr = PlotPlayer.this.getPersistentMeta("quitLocV2");
if (arr == null) { if (arr == null) {
return; return;
} }
V2 = true;
removePersistentMeta("quitLocV2");
} else {
removePersistentMeta("quitLoc"); removePersistentMeta("quitLoc");
}
if (!getMeta("teleportOnLogin", true)) { if (!getMeta("teleportOnLogin", true)) {
return; return;
@@ -714,7 +754,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
final int plotZ = quitWorld.getShort(); final int plotZ = quitWorld.getShort();
PlotId id = PlotId.of(plotX, plotZ); PlotId id = PlotId.of(plotX, plotZ);
int x = quitWorld.getInt(); int x = quitWorld.getInt();
int y = quitWorld.get() & 0xFF; int y = V2 ? quitWorld.getShort() : (quitWorld.get() & 0xFF);
int z = quitWorld.getInt(); int z = quitWorld.getInt();
Plot plot = area.getOwnedPlot(id); Plot plot = area.getOwnedPlot(id);
@@ -748,10 +788,11 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
} }
} }
} catch (Throwable e) { } catch (Throwable e) {
e.printStackTrace(); LOGGER.error("Error populating persistent meta for player {}", PlotPlayer.this.getName(), e);
} }
} }
}); }
);
} }
} }
@@ -819,7 +860,8 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@Nullable <T> T getPersistentMeta(final @NonNull MetaDataKey<T> key) { @Nullable
<T> T getPersistentMeta(final @NonNull MetaDataKey<T> key) {
final byte[] value = this.getPersistentMeta(key.toString()); final byte[] value = this.getPersistentMeta(key.toString());
if (value == null) { if (value == null) {
return null; return null;
@@ -989,9 +1031,11 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
if (throwable != null) { if (throwable != null) {
sendMessage( sendMessage(
TranslatableCaption.of("errors.error"), TranslatableCaption.of("errors.error"),
TagResolver.resolver("value", Tag.inserting( TagResolver.resolver(
"value", Tag.inserting(
Component.text("Failed to resolve asynchronous caption replacements") Component.text("Failed to resolve asynchronous caption replacements")
)) )
)
); );
LOGGER.error("Failed to resolve asynchronous tagresolver(s) for " + caption, throwable); LOGGER.error("Failed to resolve asynchronous tagresolver(s) for " + caption, throwable);
} else { } else {

View File

@@ -541,7 +541,7 @@ public class Plot {
* *
* @return World name * @return World name
*/ */
public @Nullable String getWorldName() { public @NonNull String getWorldName() {
return area.getWorldName(); return area.getWorldName();
} }

View File

@@ -58,7 +58,7 @@ public class SinglePlot extends Plot {
} }
@Override @Override
public String getWorldName() { public @NonNull String getWorldName() {
return getId().toUnderscoreSeparatedString(); return getId().toUnderscoreSeparatedString();
} }

View File

@@ -135,6 +135,7 @@ public abstract class SchematicHandler {
} }
final String filename; final String filename;
final String website; final String website;
final @Nullable UUID finalUuid = uuid;
if (uuid == null) { if (uuid == null) {
uuid = UUID.randomUUID(); uuid = UUID.randomUUID();
website = Settings.Web.URL + "upload.php?" + uuid; website = Settings.Web.URL + "upload.php?" + uuid;
@@ -144,10 +145,11 @@ public abstract class SchematicHandler {
filename = file + '.' + extension; filename = file + '.' + extension;
} }
final URL url; final URL url;
String uri = Settings.Web.URL + "?key=" + uuid + "&type=" + extension;
try { try {
url = URI.create(Settings.Web.URL + "?key=" + uuid + "&type=" + extension).toURL(); url = URI.create(uri).toURL();
} catch (MalformedURLException e) { } catch (MalformedURLException e) {
e.printStackTrace(); LOGGER.error("Malformed URI `{}`", uri, e);
whenDone.run(); whenDone.run();
return; return;
} }
@@ -193,7 +195,7 @@ public abstract class SchematicHandler {
} }
TaskManager.runTask(whenDone); TaskManager.runTask(whenDone);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LOGGER.error("Error while uploading schematic for UUID {}", finalUuid, e);
TaskManager.runTask(whenDone); TaskManager.runTask(whenDone);
} }
}); });
@@ -388,8 +390,14 @@ public abstract class SchematicHandler {
} }
queue.enqueue(); queue.enqueue();
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace();
TaskManager.runTask(whenDone); TaskManager.runTask(whenDone);
LOGGER.error(
"Error pasting schematic to plot {};{} for player {}",
plot.getArea(),
plot.getId(),
actor == null ? "null" : actor.getName(),
e
);
} }
} }
@@ -456,7 +464,7 @@ public abstract class SchematicHandler {
Clipboard clip = reader.read(); Clipboard clip = reader.read();
return new Schematic(clip); return new Schematic(clip);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LOGGER.error("Error reading schematic from file {}", file.getAbsolutePath(), e);
} }
} else { } else {
throw new UnsupportedFormatException("This schematic format is not recognised or supported."); throw new UnsupportedFormatException("This schematic format is not recognised or supported.");
@@ -470,7 +478,7 @@ public abstract class SchematicHandler {
InputStream inputStream = Channels.newInputStream(readableByteChannel); InputStream inputStream = Channels.newInputStream(readableByteChannel);
return getSchematic(inputStream); return getSchematic(inputStream);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LOGGER.error("Error reading schematic from {}", url, e);
} }
return null; return null;
} }
@@ -486,7 +494,7 @@ public abstract class SchematicHandler {
Clipboard clip = schematicReader.read(); Clipboard clip = schematicReader.read();
return new Schematic(clip); return new Schematic(clip);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LOGGER.error("Error reading schematic", e);
} }
} }
return null; return null;
@@ -515,7 +523,7 @@ public abstract class SchematicHandler {
} }
return schematics; return schematics;
} catch (JsonParseException | IOException e) { } catch (JsonParseException | IOException e) {
e.printStackTrace(); LOGGER.error("Error retrieving saves for UUID {}", uuid, e);
} }
return null; return null;
} }
@@ -532,7 +540,7 @@ public abstract class SchematicHandler {
try (NBTOutputStream nos = new NBTOutputStream(new GZIPOutputStream(output, true))) { try (NBTOutputStream nos = new NBTOutputStream(new GZIPOutputStream(output, true))) {
nos.writeNamedTag("Schematic", tag); nos.writeNamedTag("Schematic", tag);
} catch (IOException e1) { } catch (IOException e1) {
e1.printStackTrace(); LOGGER.error("Error uploading schematic for UUID {}", uuid, e1);
} }
} }
}, whenDone); }, whenDone);
@@ -556,9 +564,9 @@ public abstract class SchematicHandler {
nbtStream.writeNamedTag("Schematic", tag); nbtStream.writeNamedTag("Schematic", tag);
} }
} catch (FileNotFoundException e) { } catch (FileNotFoundException e) {
e.printStackTrace(); LOGGER.error("Error saving schematic at {}", path, e);
} catch (IOException e) { } catch (IOException e) {
e.printStackTrace(); LOGGER.error("Error saving schematic at {}", path, e);
return false; return false;
} }
return true; return true;
@@ -581,7 +589,7 @@ public abstract class SchematicHandler {
schematic.put("BlockData", new ByteArrayTag(buffer.toByteArray())); schematic.put("BlockData", new ByteArrayTag(buffer.toByteArray()));
schematic.put("BlockEntities", new ListTag(CompoundTag.class, tileEntities)); schematic.put("BlockEntities", new ListTag(CompoundTag.class, tileEntities));
if (biomeBuffer.size() == 0 || biomePalette.size() == 0) { if (biomeBuffer.size() == 0 || biomePalette.isEmpty()) {
return; return;
} }
@@ -733,10 +741,7 @@ public abstract class SchematicHandler {
} }
BaseBlock block = aabb.getWorld().getFullBlock(point); BaseBlock block = aabb.getWorld().getFullBlock(point);
if (block.getNbtData() != null) { if (block.getNbtData() != null) {
Map<String, Tag> values = new HashMap<>(); Map<String, Tag> values = new HashMap<>(block.getNbtData().getValue());
for (Map.Entry<String, Tag> entry : block.getNbtData().getValue().entrySet()) {
values.put(entry.getKey(), entry.getValue());
}
// Positions are kept in NBT, we don't want that. // Positions are kept in NBT, we don't want that.
values.remove("x"); values.remove("x");

View File

@@ -49,10 +49,12 @@ import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Locale; import java.util.Locale;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.TimeZone; import java.util.TimeZone;
import java.util.UUID; import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.stream.Collectors;
/** /**
* Registry that contains {@link Placeholder placeholders} * Registry that contains {@link Placeholder placeholders}
@@ -127,6 +129,22 @@ public final class PlaceholderRegistry {
} }
return legacyComponent(TranslatableCaption.of("info.unknown"), player); return legacyComponent(TranslatableCaption.of("info.unknown"), player);
}); });
this.createPlaceholder("currentplot_owners", (player, plot) -> {
if (plot.getFlag(ServerPlotFlag.class)) {
return legacyComponent(TranslatableCaption.of("info.server"), player);
}
final Set<UUID> plotOwners = plot.getOwners();
if (plotOwners.isEmpty()) {
return legacyComponent(TranslatableCaption.of("generic.generic_unowned"), player);
}
return plotOwners.stream().map(PlotSquared.platform().playerManager()::getUsernameCaption).map(f -> {
try {
return f.get(Settings.UUID.BLOCKING_TIMEOUT, TimeUnit.MILLISECONDS).getComponent(player);
} catch (final Exception ignored) {
return legacyComponent(TranslatableCaption.of("info.unknown"), player);
}
}).collect(Collectors.joining(", "));
});
this.createPlaceholder("currentplot_members", (player, plot) -> { this.createPlaceholder("currentplot_members", (player, plot) -> {
if (plot.getMembers().isEmpty() && plot.getTrusted().isEmpty()) { if (plot.getMembers().isEmpty() && plot.getTrusted().isEmpty()) {
return legacyComponent(TranslatableCaption.of("info.none"), player); return legacyComponent(TranslatableCaption.of("info.none"), player);

View File

@@ -415,6 +415,7 @@
"deny.denied_added": "<prefix><dark_aqua>You successfully denied the player from this plot.</dark_aqua>", "deny.denied_added": "<prefix><dark_aqua>You successfully denied the player from this plot.</dark_aqua>",
"deny.no_enter": "<prefix><red>You are denied from the plot <red><gold><plot></gold><red> and therefore not allowed to enter.</red>", "deny.no_enter": "<prefix><red>You are denied from the plot <red><gold><plot></gold><red> and therefore not allowed to enter.</red>",
"deny.you_got_denied": "<prefix><red>You are denied from the plot you were previously on, and got teleported to spawn.</red>", "deny.you_got_denied": "<prefix><red>You are denied from the plot you were previously on, and got teleported to spawn.</red>",
"deny.cannot_interact": "<prefix><red>You are denied from the plot <red><gold><plot></gold><red> and therefore cannot interact with it.</red>",
"deny.cant_remove_owner": "<prefix><red>You can't remove the plot owner.</red>", "deny.cant_remove_owner": "<prefix><red>You can't remove the plot owner.</red>",
"kick.player_not_in_plot": "<prefix><red>The player <gray><player></gray> is not on this plot.</red>", "kick.player_not_in_plot": "<prefix><red>The player <gray><player></gray> is not on this plot.</red>",
"kick.cannot_kick_player": "<prefix><red>You cannot kick the player <gray><player></gray>.</red>", "kick.cannot_kick_player": "<prefix><red>You cannot kick the player <gray><player></gray>.</red>",

View File

@@ -20,7 +20,7 @@ plugins {
} }
group = "com.intellectualsites.plotsquared" group = "com.intellectualsites.plotsquared"
version = "7.5.5" version = "7.5.9-SNAPSHOT"
if (!File("$rootDir/.git").exists()) { if (!File("$rootDir/.git").exists()) {
logger.lifecycle(""" logger.lifecycle("""
@@ -65,10 +65,16 @@ subprojects {
plugin<IdeaPlugin>() plugin<IdeaPlugin>()
} }
configurations.matching { it.name == "signatures" }.configureEach {
attributes {
attribute(Attribute.of("signatures-unique", String::class.java), "true")
}
}
dependencies { dependencies {
// Tests // Tests
testImplementation("org.junit.jupiter:junit-jupiter:5.13.4") testImplementation("org.junit.jupiter:junit-jupiter:6.0.0")
testRuntimeOnly("org.junit.platform:junit-platform-launcher:1.13.4") testRuntimeOnly("org.junit.platform:junit-platform-launcher:6.0.0")
} }
plugins.withId("java") { plugins.withId("java") {
@@ -95,10 +101,16 @@ subprojects {
} }
} }
afterEvaluate {
val javaComponent = components["java"] as AdhocComponentWithVariants val javaComponent = components["java"] as AdhocComponentWithVariants
javaComponent.withVariantsFromConfiguration(configurations["shadowRuntimeElements"]) { configurations.findByName("shadowRuntimeElements")?.let { shadowRuntimeElements ->
javaComponent.withVariantsFromConfiguration(shadowRuntimeElements) {
skip() skip()
} }
} ?: run {
logger.warn("Configuration 'shadowRuntimeElements' does not exist.")
}
}
signing { signing {
if (!project.hasProperty("skip.signing") && !version.toString().endsWith("-SNAPSHOT")) { if (!project.hasProperty("skip.signing") && !version.toString().endsWith("-SNAPSHOT")) {

View File

@@ -2,21 +2,21 @@
# Platform expectations # Platform expectations
paper = "1.20.4-R0.1-SNAPSHOT" paper = "1.20.4-R0.1-SNAPSHOT"
guice = "7.0.0" guice = "7.0.0"
spotbugs = "4.9.3" spotbugs = "4.9.8"
checkerqual = "3.49.5" checkerqual = "3.51.1"
gson = "2.10" gson = "2.10"
guava = "31.1-jre" guava = "31.1-jre"
snakeyaml = "2.0" snakeyaml = "2.0"
adventure = "4.23.0" adventure = "4.25.0"
adventure-bukkit = "4.4.0" adventure-bukkit = "4.4.1"
log4j = "2.19.0" log4j = "2.19.0"
# Plugins # Plugins
worldedit = "7.2.20" worldedit = "7.2.20"
fawe = "2.13.0" fawe = "2.14.0"
placeholderapi = "2.11.6" placeholderapi = "2.11.6"
luckperms = "5.5" luckperms = "5.5"
essentialsx = "2.21.1" essentialsx = "2.21.2"
mvdwapi = "3.1.1" mvdwapi = "3.1.1"
# Third party # Third party
@@ -33,11 +33,11 @@ vault = "1.7.1"
serverlib = "2.3.7" serverlib = "2.3.7"
# Gradle plugins # Gradle plugins
shadow = "8.3.8" shadow = "9.2.2"
grgit = "4.1.1" grgit = "4.1.1"
spotless = "7.2.1" spotless = "8.0.0"
publish = "0.34.0" publish = "0.34.0"
runPaper = "2.3.1" runPaper = "3.0.2"
[libraries] [libraries]
# Platform expectations # Platform expectations

Binary file not shown.

View File

@@ -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.14.3-bin.zip distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
networkTimeout=10000 networkTimeout=10000
validateDistributionUrl=true validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME

5
gradlew vendored
View File

@@ -1,7 +1,7 @@
#!/bin/sh #!/bin/sh
# #
# Copyright © 2015-2021 the original authors. # Copyright © 2015 the original authors.
# #
# Licensed under the Apache License, Version 2.0 (the "License"); # Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License. # you may not use this file except in compliance with the License.
@@ -114,7 +114,6 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;; NONSTOP* ) nonstop=true ;;
esac esac
CLASSPATH="\\\"\\\""
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
@@ -172,7 +171,6 @@ fi
# For Cygwin or MSYS, switch paths to Windows format before running java # For Cygwin or MSYS, switch paths to Windows format before running java
if "$cygwin" || "$msys" ; then if "$cygwin" || "$msys" ; then
APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) APP_HOME=$( cygpath --path --mixed "$APP_HOME" )
CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" )
JAVACMD=$( cygpath --unix "$JAVACMD" ) JAVACMD=$( cygpath --unix "$JAVACMD" )
@@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
set -- \ set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \ "-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@" "$@"

3
gradlew.bat vendored
View File

@@ -70,11 +70,10 @@ goto fail
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell