Compare commits

..

15 Commits

Author SHA1 Message Date
Pierre Maurice Schwang
d1a6c021fc chore: improve readability of method retrieval 2025-10-24 22:35:18 +02:00
Pierre Maurice Schwang
a388629d62 fix: backwards compatibility 2025-10-23 21:48:54 +02:00
Pierre Maurice Schwang
6991bc79d6 chore: invalidate sign cache 2025-10-23 21:24:13 +02:00
Pierre Maurice Schwang
a191000142 chore: drop unneeded type adapter 2025-10-23 20:32:09 +02:00
Pierre Maurice Schwang
2cf57dda47 chore/fix: use minecraft codec to create SignTexts 2025-10-23 20:27:36 +02:00
Pierre Maurice Schwang
e60a016164 chore: only support Lin
latest 1.19.4 FAWE has support for it
2025-10-23 20:05:54 +02:00
Pierre Maurice Schwang
e2f6b0a6fe fix/chore: support signs in spigot
no need to use different implementations for spigot vs paper anymore
2025-10-23 19:56:38 +02:00
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
51 changed files with 566 additions and 1269 deletions

View File

@@ -27,7 +27,7 @@ body:
description: Which server version are you using? If your server version is not listed, it is not supported. Update to a supported version first.
multiple: false
options:
- '1.21.11'
- '1.21.4'
- '1.21.3'
- '1.21.1'
- '1.20.6'

18
.github/stale.yml vendored Normal file
View File

@@ -0,0 +1,18 @@
daysUntilStale: 30
daysUntilClose: 7
only: issues
exemptLabels:
- "Bug"
- "Enhancement"
- "Approved"
- "Priority"
- "Under investigation"
staleLabel: "resolution: stale"
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be closed if no further activity occurs. If the issue is still present and can be reproduced, please let the team know.
Thank you for your contributions.
closeComment: >
This issue has been automatically closed because it has not had activity in
a long time. If the issue still applies to the most recent supported
version, please reply to this issue and the team will reopen it.

View File

@@ -9,7 +9,7 @@ jobs:
os: [ ubuntu-latest, windows-latest, macos-latest ]
steps:
- name: Checkout Repository
uses: actions/checkout@v6
uses: actions/checkout@v5
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v5
- name: Setup Java

View File

@@ -9,7 +9,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v6
uses: actions/checkout@v5
- name: Validate Gradle Wrapper
uses: gradle/actions/wrapper-validation@v5
- name: Setup Java

View File

@@ -20,7 +20,7 @@ jobs:
language: [ 'java' ]
steps:
- name: Checkout repository
uses: actions/checkout@v6
uses: actions/checkout@v5
- name: Setup Java
uses: actions/setup-java@v5
with:

View File

@@ -80,7 +80,7 @@ tasks.named<ShadowJar>("shadowJar") {
relocate("net.kyori.examination", "com.plotsquared.core.configuration.examination")
relocate("io.papermc.lib", "com.plotsquared.bukkit.paperlib")
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("com.google.inject", "com.plotsquared.google")
relocate("org.aopalliance", "com.plotsquared.core.aopalliance")
@@ -110,9 +110,9 @@ tasks {
val isRelease = if (rootProject.version.toString().endsWith("-SNAPSHOT")) "TODO" else rootProject.version.toString()
val opt = options as StandardJavadocDocletOptions
opt.links("https://jd.papermc.io/paper/1.20.4/")
// opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-bukkit/" + libs.worldeditBukkit.get().versionConstraint.toString())
opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-bukkit/" + libs.worldeditBukkit.get().versionConstraint.toString())
opt.links("https://intellectualsites.github.io/plotsquared-javadocs/core/")
// opt.links("https://jd.advntr.dev/api/" + libs.adventureApi.get().versionConstraint.toString())
opt.links("https://jd.advntr.dev/api/" + libs.adventureApi.get().versionConstraint.toString())
opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/")
opt.links("https://checkerframework.org/api/")
opt.isLinkSource = true

View File

@@ -46,6 +46,7 @@ import com.plotsquared.bukkit.listener.WorldEvents;
import com.plotsquared.bukkit.placeholder.PAPIPlaceholders;
import com.plotsquared.bukkit.placeholder.PlaceholderFormatter;
import com.plotsquared.bukkit.player.BukkitPlayerManager;
import com.plotsquared.bukkit.schematic.StateWrapper;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.plotsquared.bukkit.util.BukkitWorld;
import com.plotsquared.bukkit.util.SetGenCB;
@@ -289,6 +290,18 @@ public final class BukkitPlatform extends JavaPlugin implements Listener, PlotPl
}
}
// Validate compatibility of StateWrapper with the current running server version
// Do this always, even if it's not required, to prevent running servers which fail to restore plot backups or
// inserting broken plot / road templates.
try {
var instance = StateWrapper.INSTANCE;
} catch (Exception e) {
LOGGER.error("Failed to initialize required classes for restoring tile entities. " +
"PlotSquared will disable itself to prevent possible damages.", e);
getServer().getPluginManager().disablePlugin(this);
return;
}
// We create the injector after PlotSquared has been initialized, so that we have access
// to generated instances and settings
this.injector = Guice

View File

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

View File

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

View File

@@ -219,7 +219,7 @@ public class BlockEventListener implements Listener {
}
}
@EventHandler(priority = EventPriority.LOWEST, ignoreCancelled = true)
@EventHandler(priority = EventPriority.LOWEST)
public void blockDestroy(BlockBreakEvent event) {
Player player = event.getPlayer();
Location location = BukkitUtil.adapt(event.getBlock().getLocation());

View File

@@ -104,10 +104,6 @@ public class PaperListener implements Listener {
}
Plot plot = area.getPlot(location);
if (plot != null) {
// Prevent dropping blocks which normally would not be dropped.
if (!event.willDrop()) {
return;
}
event.setWillDrop(plot.getFlag(TileDropFlag.class));
}
}

View File

@@ -600,7 +600,7 @@ public class PlayerEventListener implements Listener {
PlotArea area = location.getPlotArea();
if (area == null) {
if (lastPlot != null) {
plotListener.plotExit(pp, lastPlot, null, null);
plotListener.plotExit(pp, lastPlot);
lastPlotAccess.remove();
}
try (final MetaDataAccess<Location> lastLocationAccess =
@@ -753,7 +753,7 @@ public class PlayerEventListener implements Listener {
if (now == null) {
try (final MetaDataAccess<Boolean> kickAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
if (lastPlot != null && !plotListener.plotExit(pp, lastPlot, now, area) && this.tmpTeleport && !kickAccess.get().orElse(
if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(
false)) {
pp.sendMessage(
TranslatableCaption.of("permission.no_permission_event"),
@@ -847,7 +847,7 @@ public class PlayerEventListener implements Listener {
if (plot == null) {
try (final MetaDataAccess<Boolean> kickAccess =
pp.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
if (lastPlot != null && !plotListener.plotExit(pp, lastPlot, null, area) && this.tmpTeleport && !kickAccess.get().orElse(
if (lastPlot != null && !plotListener.plotExit(pp, lastPlot) && this.tmpTeleport && !kickAccess.get().orElse(
false)) {
pp.sendMessage(
TranslatableCaption.of("permission.no_permission_event"),

View File

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

View File

@@ -34,6 +34,8 @@ import org.bukkit.entity.EntityType;
import org.bukkit.generator.LimitedRegion;
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.
*
@@ -44,7 +46,6 @@ public class LimitedRegionWrapperQueue extends DelegateQueueCoordinator {
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + LimitedRegionWrapperQueue.class.getSimpleName());
private final LimitedRegion limitedRegion;
private boolean useOtherRestoreTagMethod = false;
/**
* @since 6.9.0
@@ -64,20 +65,11 @@ public class LimitedRegionWrapperQueue extends DelegateQueueCoordinator {
boolean result = setBlock(x, y, z, id.toImmutableState());
if (result && id.hasNbtData()) {
CompoundTag tag = id.getNbtData();
StateWrapper sw = new StateWrapper(tag);
try {
if (useOtherRestoreTagMethod && getWorld() != null) {
sw.restoreTag(getWorld().getName(), x, y, z);
} else {
sw.restoreTag(limitedRegion.getBlockState(x, y, z).getBlock());
}
StateWrapper.INSTANCE.restore(limitedRegion.getBlockState(x, y, z).getBlock(), Objects.requireNonNull(tag));
} catch (IllegalArgumentException e) {
LOGGER.error("Error attempting to populate tile entity into the world at location {},{},{}", x, y, z, e);
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;
@@ -113,9 +105,8 @@ public class LimitedRegionWrapperQueue extends DelegateQueueCoordinator {
@Override
public boolean setTile(final int x, final int y, final int z, @NonNull final CompoundTag tag) {
StateWrapper sw = new StateWrapper(tag);
try {
return sw.restoreTag(limitedRegion.getBlockState(x, y, z).getBlock());
return StateWrapper.INSTANCE.restore(limitedRegion.getBlockState(x, y, z).getBlock(), tag);
} catch (IllegalArgumentException e) {
LOGGER.error("Error attempting to populate tile entity into the world at location {},{},{}", x, y, z, e);
return false;

View File

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

View File

@@ -18,332 +18,35 @@
*/
package com.plotsquared.bukkit.schematic;
import com.destroystokyo.paper.profile.PlayerProfile;
import com.destroystokyo.paper.profile.ProfileProperty;
import com.plotsquared.bukkit.util.BukkitUtil;
import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag;
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 org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.DyeColor;
import org.bukkit.World;
import org.bukkit.block.Banner;
import org.bukkit.block.Block;
import org.bukkit.block.Container;
import org.bukkit.block.Sign;
import org.bukkit.block.Skull;
import org.bukkit.block.banner.Pattern;
import org.bukkit.block.banner.PatternType;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import org.checkerframework.checker.nullness.qual.NonNull;
import org.jetbrains.annotations.ApiStatus;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.UUID;
@ApiStatus.Internal
public sealed interface StateWrapper permits StateWrapperSpigot {
public class StateWrapper {
StateWrapper INSTANCE = Factory.createStateWrapper();
public CompoundTag tag;
boolean restore(final @NonNull Block block, final @NonNull CompoundTag data);
private boolean paperErrorTextureSent = false;
private static final Logger LOGGER = LogManager.getLogger("PlotSquared/" + StateWrapper.class.getSimpleName());
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);
default boolean restore(final String worldName, final int x, final int y, final int z, final CompoundTag data) {
final World world = BukkitUtil.getWorld(worldName);
if (world == null) {
return false;
}
return restoreTag(world.getBlockAt(x, y, z));
return this.restore(world.getBlockAt(x, y, z), data);
}
/**
* Restore the TileEntity data to the given block
*
* @param block Block to restore to
* @return true if successful
*/
@SuppressWarnings("deprecation") // #setLine is needed for Spigot compatibility
public boolean restoreTag(@NonNull Block block) {
if (this.tag == null) {
return false;
@ApiStatus.Internal
final class Factory {
private static StateWrapper createStateWrapper() {
return new StateWrapperSpigot();
}
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()) {
try {
skull.setOwningPlayer(Bukkit.getOfflinePlayer(player));
skull.update(true);
} catch (Exception e) {
e.printStackTrace();
}
return true;
}
final CompoundTag properties = (CompoundTag) skullOwner.getValue().get("Properties");
if (properties == null) {
return false;
}
final ListTag textures = properties.getListTag("textures");
if (textures.getValue().isEmpty()) {
return false;
}
final CompoundTag textureCompound = (CompoundTag) textures.getValue().get(0);
if (textureCompound == null) {
return false;
}
String textureValue = textureCompound.getString("Value");
if (textureValue == null) {
return false;
}
if (!PaperLib.isPaper()) {
if (!paperErrorTextureSent) {
paperErrorTextureSent = true;
LOGGER.error("Failed to populate skull data in your road schematic - This is a Spigot limitation.");
}
return false;
}
final PlayerProfile profile = Bukkit.createProfile(UUID.randomUUID());
profile.setProperty(new ProfileProperty("textures", textureValue));
skull.setPlayerProfile(profile);
skull.update(true);
return true;
}
return false;
}
case "banner" -> {
if (state instanceof Banner banner) {
List<Tag> patterns = this.tag.getListTag("Patterns").getValue();
if (patterns == null || patterns.isEmpty()) {
return false;
}
banner.setPatterns(patterns.stream().map(t -> (CompoundTag) t).map(compoundTag -> {
DyeColor color = DyeColor.getByWoolData((byte) compoundTag.getInt("Color"));
PatternType patternType = PatternType.getByIdentifier(compoundTag.getString("Pattern"));
if (color == null || patternType == null) {
return null;
}
return new Pattern(color, patternType);
}).filter(Objects::nonNull).toList());
banner.update(true);
return true;
}
return false;
}
}
return false;
}
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,263 @@
/*
* 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.ReflectionHelper;
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.bukkit.adapter.Refraction;
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.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.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
import java.util.Optional;
final class StateWrapperSpigot implements StateWrapper {
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());
private static final MethodHandles.Lookup LOOKUP = MethodHandles.lookup();
private static BukkitImplAdapter ADAPTER = null;
private static Class<?> LIN_TAG_CLASS = null;
private static Class<?> CRAFT_BLOCK_ENTITY_STATE_CLASS = null;
private static Field CRAFT_SIGN_SIDE_SIGN_TEXT = null;
private static Field CRAFT_SIGN_SIDE_LINES = 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 CRAFT_BLOCK_ENTITY_STATE_GET_SNAPSHOT = null;
private static MethodHandle SIGN_BLOCK_ENTITY_SET_TEXT = null;
private static MethodHandle DECODER_PARSE = null;
private static MethodHandle DATA_RESULT_RESULT = null;
private static MethodHandle TO_LIN_TAG = null;
private static Object SIGN_TEXT_DIRECT_CODEC = null;
private static Object NBT_OPS_INSTANCE = null;
public StateWrapperSpigot() {
try {
ReflectionUtils.RefClass worldEditPluginRefClass = ReflectionUtils.getRefClass(WorldEditPlugin.class);
WorldEditPlugin worldEditPlugin = (WorldEditPlugin) worldEditPluginRefClass
.getMethod("getInstance")
.of(null)
.call();
ADAPTER = (BukkitImplAdapter) worldEditPluginRefClass
.getMethod("getBukkitImplAdapter")
.of(worldEditPlugin)
.call();
LIN_TAG_CLASS = Class.forName("org.enginehub.linbus.tree.LinTag"); // provided WE / FAWE version is too old
PAPERWEIGHT_ADAPTER_FROM_NATIVE = findPaperweightAdapterFromNativeMethodHandle(ADAPTER.getClass());
TO_LIN_TAG = findToLinTagMethodHandle();
} catch (NoSuchMethodException | ClassNotFoundException | IllegalAccessException | NoCapablePlatformException e) {
throw new RuntimeException("Failed to access required WorldEdit classes or methods", e);
}
try {
final Class<?> SIGN_TEXT_CLASS = Class.forName("net.minecraft.world.level.block.entity.SignText");
final Class<?> CRAFT_SIGN_SIDE_CLASS = Class.forName(CRAFTBUKKIT_PACKAGE + ".block.sign.CraftSignSide");
CRAFT_SIGN_SIDE_SIGN_TEXT = CRAFT_SIGN_SIDE_CLASS.getDeclaredField("signText");
CRAFT_SIGN_SIDE_SIGN_TEXT.setAccessible(true);
CRAFT_SIGN_SIDE_LINES = CRAFT_SIGN_SIDE_CLASS.getDeclaredField("lines");
CRAFT_SIGN_SIDE_LINES.setAccessible(true);
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);
CRAFT_BLOCK_ENTITY_STATE_GET_SNAPSHOT = findCraftBlockEntityStateSnapshotMethodHandle(CRAFT_BLOCK_ENTITY_STATE_CLASS);
SIGN_BLOCK_ENTITY_SET_TEXT = findSignBlockEntitySetTextMethodHandle(
Class.forName(Refraction.pickName(
"net.minecraft.world.level.block.entity.SignBlockEntity",
"net.minecraft.world.level.block.entity.TileEntitySign"
)),
SIGN_TEXT_CLASS
);
final Class<?> CODEC_CLASS = Class.forName("com.mojang.serialization.Codec");
final Class<?> DECODER_CLASS = Class.forName("com.mojang.serialization.Decoder");
final Class<?> DATA_RESULT_CLASS = Class.forName("com.mojang.serialization.DataResult");
final Class<?> DYNAMIC_OPS_CLASS = Class.forName("com.mojang.serialization.DynamicOps");
final Class<?> NBT_OPS_CLASS = Class.forName(Refraction.pickName(
"net.minecraft.nbt.NbtOps",
"net.minecraft.nbt.DynamicOpsNBT"
));
SIGN_TEXT_DIRECT_CODEC = Arrays.stream(SIGN_TEXT_CLASS.getFields())
.filter(field -> Modifier.isStatic(field.getModifiers()) && Modifier.isPublic(field.getModifiers()))
.filter(field -> field.getType() == CODEC_CLASS)
.findFirst().orElseThrow().get(null);
DECODER_PARSE = LOOKUP.findVirtual(
DECODER_CLASS, "parse", MethodType.methodType(
DATA_RESULT_CLASS, DYNAMIC_OPS_CLASS, Object.class
)
);
NBT_OPS_INSTANCE = Arrays.stream(NBT_OPS_CLASS.getFields())
.filter(field -> Modifier.isStatic(field.getModifiers()) && Modifier.isPublic(field.getModifiers()))
.filter(field -> field.getType() == NBT_OPS_CLASS)
.findFirst().orElseThrow().get(null);
DATA_RESULT_RESULT = LOOKUP.findVirtual(
DATA_RESULT_CLASS, "result",
MethodType.methodType(Optional.class)
);
} catch (Throwable 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, TO_LIN_TAG.invoke(data));
// load block entity data
CRAFT_BLOCK_ENTITY_STATE_LOAD_DATA.invoke(blockState, nativeTag);
// signs need to be handled explicitly (at least during worldgen)
if (blockState instanceof Sign sign) {
if (data.getValue().get("front_text") instanceof CompoundTag textTag) {
setSignContents(true, sign.getSide(Side.FRONT), blockState, textTag);
}
if (data.getValue().get("back_text") instanceof CompoundTag textTag) {
setSignContents(false, sign.getSide(Side.BACK), blockState, textTag);
}
}
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;
}
private static void setSignContents(boolean front, SignSide side, BlockState blockState, CompoundTag data) throws Throwable {
Object nativeTag = PAPERWEIGHT_ADAPTER_FROM_NATIVE.invoke(ADAPTER, TO_LIN_TAG.invoke(data));
Object dataResult = DECODER_PARSE.invoke(SIGN_TEXT_DIRECT_CODEC, NBT_OPS_INSTANCE, nativeTag);
//noinspection rawtypes
Object signText = ((Optional) DATA_RESULT_RESULT.invoke(dataResult)).orElseThrow();
// set the SignText on the underlying tile entity snapshot (SignBlockEntity)
SIGN_BLOCK_ENTITY_SET_TEXT.invoke(CRAFT_BLOCK_ENTITY_STATE_GET_SNAPSHOT.invoke(blockState), signText, front);
// and update the SignText field on the CraftSignSide - changes are otherwise not reflected
CRAFT_SIGN_SIDE_SIGN_TEXT.set(side, signText);
// reset cached lines to null, so it can be re-retrieved from SignText (for API access etc.)
CRAFT_SIGN_SIDE_LINES.set(side, null);
}
/**
* 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.
*
* @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() throws ClassNotFoundException,
NoSuchMethodException, IllegalAccessException {
return LOOKUP.findVirtual(
Class.forName("org.enginehub.linbus.tree.ToLinTag"),
"toLinTag",
MethodType.methodType(LIN_TAG_CLASS)
);
}
/**
* 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 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
* @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) throws
IllegalAccessException, NoSuchMethodException {
final MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(adapterClass, LOOKUP);
try {
// FAWE
return lookup.findVirtual(adapterClass, "fromNativeLin", MethodType.methodType(Object.class, LIN_TAG_CLASS));
} catch (NoSuchMethodException e) {
// WE
return lookup.findVirtual(adapterClass, "fromNative", MethodType.methodType(Object.class, LIN_TAG_CLASS));
}
}
private static MethodHandle findCraftBlockEntityStateLoadDataMethodHandle(Class<?> craftBlockEntityStateClass) throws
NoSuchMethodException, IllegalAccessException {
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 {
return LOOKUP.unreflect(ReflectionHelper.findMethod(
craftBlockEntityStateClass,
MethodType.methodType(Boolean.TYPE, Boolean.TYPE, Boolean.TYPE),
Modifier.PUBLIC
).orElseThrow(() -> new NoSuchMethodException("Couldn't lookup CraftBlockEntityState#update(boolean, boolean) boolean")));
}
private static MethodHandle findCraftBlockEntityStateSnapshotMethodHandle(Class<?> craftBlockEntityStateClass) throws
IllegalAccessException, NoSuchMethodException {
// doesn't seem to be obfuscated, but protected
final MethodHandles.Lookup lookup = MethodHandles.privateLookupIn(craftBlockEntityStateClass, LOOKUP);
return lookup.unreflect(craftBlockEntityStateClass.getDeclaredMethod("getSnapshot"));
}
private static MethodHandle findSignBlockEntitySetTextMethodHandle(Class<?> signBlockEntity, Class<?> signText) throws
NoSuchMethodException, IllegalAccessException {
return LOOKUP.unreflect(ReflectionHelper.findMethod(
signBlockEntity,
MethodType.methodType(Boolean.TYPE, signText, Boolean.TYPE),
Modifier.PUBLIC
).orElseThrow(() -> new NoSuchMethodException("Couldn't lookup SignBlockEntity#setText(SignText, boolean) boolean")));
}
}

View File

@@ -67,8 +67,8 @@ tasks {
withType<Javadoc> {
val isRelease = if (rootProject.version.toString().endsWith("-SNAPSHOT")) "TODO" else rootProject.version.toString()
val opt = options as StandardJavadocDocletOptions
// opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-core/" + libs.worldeditCore.get().versionConstraint.toString())
// opt.links("https://jd.advntr.dev/api/" + libs.adventureApi.get().versionConstraint.toString())
opt.links("https://docs.enginehub.org/javadoc/com.sk89q.worldedit/worldedit-core/" + libs.worldeditCore.get().versionConstraint.toString())
opt.links("https://jd.advntr.dev/api/" + libs.adventureApi.get().versionConstraint.toString())
opt.links("https://jd.advntr.dev/text-minimessage/" + libs.adventureApi.get().versionConstraint.toString())
opt.links("https://google.github.io/guice/api-docs/" + libs.guice.get().versionConstraint.toString() + "/javadoc/")
opt.links("https://checkerframework.org/api/")

View File

@@ -23,8 +23,6 @@ import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.events.PlayerPlotAddRemoveEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -153,41 +151,20 @@ public class Add extends Command {
return;
}
// Success
confirm.run(
this, () -> {
for (UUID uuid : uuids) {
if (this.eventDispatcher.callPlayerAdd(
player,
plot,
uuid,
PlayerPlotAddRemoveEvent.Reason.COMMAND
).getEventResult() == Result.DENY) {
player.sendMessage(
TranslatableCaption.of("events.event_denied"),
TagResolver.resolver("value", Tag.inserting(Component.text("Add")))
);
continue;
confirm.run(this, () -> {
for (UUID uuid : uuids) {
if (uuid != DBFunc.EVERYONE) {
if (!plot.removeTrusted(uuid)) {
if (plot.getDenied().contains(uuid)) {
plot.removeDenied(uuid);
}
if (uuid != DBFunc.EVERYONE) {
if (!plot.removeTrusted(uuid)) {
if (plot.getDenied().contains(uuid)) {
plot.removeDenied(uuid);
}
}
}
plot.addMember(uuid);
this.eventDispatcher.callMember(player, plot, uuid, true);
this.eventDispatcher.callPostAdded(
player,
plot,
uuid,
false,
PlayerPlotAddRemoveEvent.Reason.COMMAND
);
player.sendMessage(TranslatableCaption.of("member.member_added"));
}
}, null
);
}
plot.addMember(uuid);
this.eventDispatcher.callMember(player, plot, uuid, true);
player.sendMessage(TranslatableCaption.of("member.member_added"));
}
}, null);
} catch (final Throwable exception) {
future.completeExceptionally(exception);
return;

View File

@@ -23,8 +23,6 @@ import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.events.PlayerPlotAddRemoveEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.location.Location;
import com.plotsquared.core.permissions.Permission;
@@ -126,29 +124,21 @@ public class Deny extends SubCommand {
);
return;
} else {
if (this.eventDispatcher
.callPlayerDeny(player, plot, uuid, PlayerPlotAddRemoveEvent.Reason.COMMAND)
.getEventResult() == Result.DENY) {
player.sendMessage(
TranslatableCaption.of("events.event_denied"),
TagResolver.resolver("value", Tag.inserting(Component.text("Deny")))
);
continue;
}
if (uuid != DBFunc.EVERYONE) {
plot.removeMember(uuid);
plot.removeTrusted(uuid);
}
plot.addDenied(uuid);
this.eventDispatcher.callDenied(player, plot, uuid, true);
this.eventDispatcher.callPostDenied(player, plot, uuid, true, PlayerPlotAddRemoveEvent.Reason.COMMAND);
if (!uuid.equals(DBFunc.EVERYONE)) {
handleKick(PlotSquared.platform().playerManager().getPlayerIfExists(uuid), plot);
} else {
for (PlotPlayer<?> plotPlayer : plot.getPlayersInPlot()) {
if (plot.isDenied(plotPlayer.getUUID())) {
handleKick(plotPlayer, plot);
// Ignore plot-owners
if (plot.isAdded(plotPlayer.getUUID())) {
continue;
}
handleKick(plotPlayer, plot);
}
}
}

View File

@@ -20,8 +20,6 @@ package com.plotsquared.core.command;
import com.google.inject.Inject;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.events.PlayerPlotAddRemoveEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.EventDispatcher;
@@ -63,22 +61,11 @@ public class Leave extends Command {
} else {
UUID uuid = player.getUUID();
if (plot.isAdded(uuid)) {
if (this.eventDispatcher
.callPlayerRemove(player, plot, uuid, PlayerPlotAddRemoveEvent.Reason.COMMAND)
.getEventResult() == Result.DENY) {
player.sendMessage(
TranslatableCaption.of("events.event_denied"),
TagResolver.resolver("value", Tag.inserting(Component.text("Leave")))
);
return CompletableFuture.completedFuture(true);
}
if (plot.removeTrusted(uuid)) {
this.eventDispatcher.callTrusted(player, plot, uuid, false);
this.eventDispatcher.callPostTrusted(player, plot, uuid, false, PlayerPlotAddRemoveEvent.Reason.COMMAND);
}
if (plot.removeMember(uuid)) {
this.eventDispatcher.callMember(player, plot, uuid, false);
this.eventDispatcher.callPostAdded(player, plot, uuid, false, PlayerPlotAddRemoveEvent.Reason.COMMAND);
}
player.sendMessage(
TranslatableCaption.of("member.plot_left"),

View File

@@ -21,8 +21,6 @@ package com.plotsquared.core.command;
import com.google.inject.Inject;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.events.PlayerPlotAddRemoveEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -84,48 +82,33 @@ public class Remove extends SubCommand {
return;
} else if (!uuids.isEmpty()) {
for (UUID uuid : uuids) {
if (this.eventDispatcher
.callPlayerRemove(player, plot, uuid, PlayerPlotAddRemoveEvent.Reason.COMMAND)
.getEventResult() == Result.DENY) {
player.sendMessage(
TranslatableCaption.of("events.event_denied"),
TagResolver.resolver("value", Tag.inserting(Component.text("Remove")))
);
continue;
}
if (plot.getTrusted().contains(uuid)) {
if (plot.removeTrusted(uuid)) {
this.eventDispatcher.callTrusted(player, plot, uuid, false);
this.eventDispatcher.callPostTrusted(player, plot, uuid, false, PlayerPlotAddRemoveEvent.Reason.COMMAND);
count++;
}
} else if (plot.getMembers().contains(uuid)) {
if (plot.removeMember(uuid)) {
this.eventDispatcher.callMember(player, plot, uuid, false);
this.eventDispatcher.callPostAdded(player, plot, uuid, false, PlayerPlotAddRemoveEvent.Reason.COMMAND);
count++;
}
} else if (plot.getDenied().contains(uuid)) {
if (plot.removeDenied(uuid)) {
this.eventDispatcher.callDenied(player, plot, uuid, false);
this.eventDispatcher.callPostDenied(player, plot, uuid, true, PlayerPlotAddRemoveEvent.Reason.COMMAND);
count++;
}
} else if (uuid == DBFunc.EVERYONE) {
count += plot.getTrusted().size();
if (plot.removeTrusted(uuid)) {
this.eventDispatcher.callTrusted(player, plot, uuid, false);
this.eventDispatcher.callPostTrusted(player, plot, uuid, false, PlayerPlotAddRemoveEvent.Reason.COMMAND);
}
count += plot.getMembers().size();
if (plot.removeMember(uuid)) {
this.eventDispatcher.callMember(player, plot, uuid, false);
this.eventDispatcher.callPostAdded(player, plot, uuid, false, PlayerPlotAddRemoveEvent.Reason.COMMAND);
}
count += plot.getDenied().size();
if (plot.removeDenied(uuid)) {
this.eventDispatcher.callDenied(player, plot, uuid, false);
this.eventDispatcher.callPostDenied(player, plot, uuid, true, PlayerPlotAddRemoveEvent.Reason.COMMAND);
}
}
}

View File

@@ -23,8 +23,6 @@ import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.events.PlayerPlotAddRemoveEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.permissions.Permission;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
@@ -152,43 +150,23 @@ public class Trust extends Command {
return;
}
// Success
confirm.run(
this, () -> {
for (UUID uuid : uuids) {
if (this.eventDispatcher
.callPlayerTrust(player, currentPlot, uuid, PlayerPlotAddRemoveEvent.Reason.COMMAND)
.getEventResult() == Result.DENY) {
player.sendMessage(
TranslatableCaption.of("events.event_denied"),
TagResolver.resolver("value", Tag.inserting(Component.text("Trust")))
);
return;
confirm.run(this, () -> {
for (UUID uuid : uuids) {
if (uuid != DBFunc.EVERYONE) {
if (!currentPlot.removeMember(uuid)) {
if (currentPlot.getDenied().contains(uuid)) {
currentPlot.removeDenied(uuid);
}
if (uuid != DBFunc.EVERYONE) {
if (!currentPlot.removeMember(uuid)) {
if (currentPlot.getDenied().contains(uuid)) {
currentPlot.removeDenied(uuid);
}
}
}
currentPlot.addTrusted(uuid);
this.eventDispatcher.callTrusted(player, currentPlot, uuid, true);
this.eventDispatcher.callPostTrusted(
player,
currentPlot,
uuid,
false,
PlayerPlotAddRemoveEvent.Reason.COMMAND
);
player.sendMessage(TranslatableCaption.of("trusted.trusted_added"));
}
}, null
);
}
currentPlot.addTrusted(uuid);
this.eventDispatcher.callTrusted(player, currentPlot, uuid, true);
player.sendMessage(TranslatableCaption.of("trusted.trusted_added"));
}
}, null);
}
future.complete(true);
}
);
future.complete(true);
});
return CompletableFuture.completedFuture(true);
}

View File

@@ -435,11 +435,6 @@ public class Settings extends Config {
public static String SCHEMATICS = "schematics";
public static String TEMPLATES = "templates";
@Comment({"If schematics used for generation should be searched for in the path.schematics location",
" - This setting exists and is `false` by default for backwards compatibility.",
" - If false then generation schematics must be located in `schematics`",
" - Schematics must still always be under GEN_ROAD_SCHEMATIC/<world> etc."})
public static boolean USE_SCHEMATICS_PATH_FOR_GEN_SCHEMATICS = false;
}

View File

@@ -1,45 +0,0 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import java.util.UUID;
/**
* Called when a player is going to be added to a plot
*
* @since TODO
*/
public class PlayerPlotAddEvent extends PlayerPlotAddRemoveCancellableEvent {
/**
* Called when a player will be added to a plot
*
* @param initiator Player that initiated the event
* @param plot Plot in which the event occurred
* @param player Player that will be added
* @param reason The reason for the add
*/
public PlayerPlotAddEvent(PlotPlayer<?> initiator, Plot plot, UUID player, Reason reason) {
super(initiator, plot, player, reason);
}
}

View File

@@ -1,55 +0,0 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.UUID;
/**
* Parent class for the varies events regarding a player being added/removed/denied/trusted
*
* @since TODO
*/
public class PlayerPlotAddRemoveCancellableEvent extends PlayerPlotAddRemoveEvent implements CancellablePlotEvent {
private Result eventResult;
protected PlayerPlotAddRemoveCancellableEvent(
final PlotPlayer<?> initiator,
Plot plot,
final UUID player,
final Reason reason
) {
super(initiator, plot, player, reason);
}
@Override
public @Nullable Result getEventResult() {
return eventResult;
}
@Override
public void setEventResult(@Nullable final Result eventResult) {
this.eventResult = eventResult;
}
}

View File

@@ -1,88 +0,0 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import org.checkerframework.checker.nullness.qual.Nullable;
import java.util.UUID;
/**
* Parent class for the varies events regarding a player being added/removed/denied/trusted
*
* @since TODO
*/
public class PlayerPlotAddRemoveEvent extends PlotEvent {
private final Reason reason;
private final PlotPlayer<?> initiator;
private final UUID player;
protected PlayerPlotAddRemoveEvent(final PlotPlayer<?> initiator, Plot plot, final UUID player, final Reason reason) {
super(plot);
this.initiator = initiator;
this.player = player;
this.reason = reason;
}
/**
* The player to be added/denied/removed/trusted.
*
* @return UUID
*/
public UUID getPlayer() {
return this.player;
}
/**
* The player initiating the action. May be null (if a player, or a {@link com.plotsquared.core.player.ConsolePlayer}.
*
* @return PlotPlayer
*/
@Nullable
public PlotPlayer<?> getInitiator() {
return this.initiator;
}
/**
* Get the reason the player is being added/removed/denied/trusted
*
* @return Reason
*/
public Reason getReason() {
return this.reason;
}
public enum Reason {
/**
* If a plot merge caused the player to be added/removed/denied/trusted
*/
MERGE,
/**
* If a command caused the player to be added/removed/denied/trusted
*/
COMMAND,
/**
* If something unknown caused the player to be added/removed/denied/trusted
*/
UNKNOWN
}
}

View File

@@ -23,10 +23,6 @@ import com.plotsquared.core.plot.Plot;
import java.util.UUID;
/**
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotDeniedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public class PlayerPlotDeniedEvent extends PlotEvent {
private final PlotPlayer<?> initiator;
@@ -40,9 +36,7 @@ public class PlayerPlotDeniedEvent extends PlotEvent {
* @param plot Plot in which the event occurred
* @param player Player that was denied/un-denied
* @param added {@code true} of add to deny list, {@code false} if removed
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotDeniedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public PlayerPlotDeniedEvent(PlotPlayer<?> initiator, Plot plot, UUID player, boolean added) {
super(plot);
this.initiator = initiator;
@@ -54,9 +48,7 @@ public class PlayerPlotDeniedEvent extends PlotEvent {
* If a user was added.
*
* @return boolean
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotDeniedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public boolean wasAdded() {
return this.added;
}
@@ -65,9 +57,7 @@ public class PlayerPlotDeniedEvent extends PlotEvent {
* The player added/removed.
*
* @return UUID
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotDeniedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public UUID getPlayer() {
return this.player;
}
@@ -76,9 +66,7 @@ public class PlayerPlotDeniedEvent extends PlotEvent {
* The player initiating the action.
*
* @return PlotPlayer
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotDeniedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public PlotPlayer<?> getInitiator() {
return this.initiator;
}

View File

@@ -1,45 +0,0 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import java.util.UUID;
/**
* Called when a player is going to be denied from a plot
*
* @since TODO
*/
public class PlayerPlotDenyEvent extends PlayerPlotAddRemoveCancellableEvent {
/**
* Called when a player will be denied from a plot
*
* @param initiator Player that initiated the event
* @param plot Plot in which the event occurred
* @param player Player that will be denied
* @param reason The reason for the deny
*/
public PlayerPlotDenyEvent(PlotPlayer<?> initiator, Plot plot, UUID player, Reason reason) {
super(initiator, plot, player, reason);
}
}

View File

@@ -24,9 +24,8 @@ import com.plotsquared.core.plot.Plot;
import java.util.UUID;
/**
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotAddedEvent}
*
*/
@Deprecated(forRemoval = true, since = "TODO")
public class PlayerPlotHelperEvent extends PlotEvent {
private final PlotPlayer<?> initiator;
@@ -40,9 +39,7 @@ public class PlayerPlotHelperEvent extends PlotEvent {
* @param plot Plot in which the event occurred
* @param player Player that was added/removed from the helper list
* @param added {@code true} if the player was added, {@code false} if the player was removed
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotAddedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public PlayerPlotHelperEvent(PlotPlayer<?> initiator, Plot plot, UUID player, boolean added) {
super(plot);
this.initiator = initiator;
@@ -54,9 +51,7 @@ public class PlayerPlotHelperEvent extends PlotEvent {
* If a player was added
*
* @return boolean
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotAddedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public boolean wasAdded() {
return this.added;
}
@@ -65,9 +60,7 @@ public class PlayerPlotHelperEvent extends PlotEvent {
* The UUID added/removed
*
* @return UUID
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotAddedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public UUID getPlayer() {
return this.player;
}
@@ -76,9 +69,7 @@ public class PlayerPlotHelperEvent extends PlotEvent {
* The player initiating the action
*
* @return PlotPlayer
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotAddedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public PlotPlayer<?> getInitiator() {
return this.initiator;
}

View File

@@ -1,45 +0,0 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import java.util.UUID;
/**
* Called when a player is going to be removed from a plot (could be removed from added, trusted, or denied)
*
* @since TODO
*/
public class PlayerPlotRemoveEvent extends PlayerPlotAddRemoveCancellableEvent {
/**
* Called when a player is going to be removed from a plot (could be removed from added, trusted, or denied)
*
* @param initiator Player that initiated the event
* @param plot Plot in which the event occurred
* @param player Player that will be removed
* @param reason The reason for the remove
*/
public PlayerPlotRemoveEvent(PlotPlayer<?> initiator, Plot plot, UUID player, Reason reason) {
super(initiator, plot, player, reason);
}
}

View File

@@ -1,45 +0,0 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import java.util.UUID;
/**
* Called when a player is going to be trusted to a plot
*
* @since TODO
*/
public class PlayerPlotTrustEvent extends PlayerPlotAddRemoveCancellableEvent {
/**
* Called when a player will be trusted to a plot
*
* @param initiator Player that initiated the event
* @param plot Plot in which the event occurred
* @param player Player that will be trusted
* @param reason The reason for the trust
*/
public PlayerPlotTrustEvent(PlotPlayer<?> initiator, Plot plot, UUID player, Reason reason) {
super(initiator, plot, player, reason);
}
}

View File

@@ -23,10 +23,6 @@ import com.plotsquared.core.plot.Plot;
import java.util.UUID;
/**
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotTrustedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public class PlayerPlotTrustedEvent extends PlotEvent {
private final PlotPlayer<?> initiator;
@@ -40,9 +36,7 @@ public class PlayerPlotTrustedEvent extends PlotEvent {
* @param plot Plot in which the event occurred
* @param player Player that was added/removed from the trusted list
* @param added {@code true} if the player was added, {@code false} if the player was removed
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotTrustedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public PlayerPlotTrustedEvent(PlotPlayer<?> initiator, Plot plot, UUID player, boolean added) {
super(plot);
this.initiator = initiator;
@@ -54,9 +48,7 @@ public class PlayerPlotTrustedEvent extends PlotEvent {
* If a player was added
*
* @return boolean
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotTrustedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public boolean wasAdded() {
return this.added;
}
@@ -65,9 +57,7 @@ public class PlayerPlotTrustedEvent extends PlotEvent {
* The UUID added/removed
*
* @return UUID
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotTrustedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public UUID getPlayer() {
return this.player;
}
@@ -76,9 +66,7 @@ public class PlayerPlotTrustedEvent extends PlotEvent {
* The player initiating the action
*
* @return PlotPlayer
* @deprecated Use {@link com.plotsquared.core.events.post.PostPlayerPlotTrustedEvent}
*/
@Deprecated(forRemoval = true, since = "TODO")
public PlotPlayer<?> getInitiator() {
return this.initiator;
}

View File

@@ -1,56 +0,0 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events.post;
import com.plotsquared.core.events.PlayerPlotAddRemoveEvent;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import java.util.UUID;
/**
* Parent class for events covering players being added/removed to added/trusted/denied lists.
*
* @since TODO
*/
public sealed class PostPlayerPlotAddRemoveEvent extends PlayerPlotAddRemoveEvent permits PostPlayerPlotAddedEvent,
PostPlayerPlotDeniedEvent, PostPlayerPlotTrustedEvent {
private final boolean added;
protected PostPlayerPlotAddRemoveEvent(
final PlotPlayer<?> initiator,
final Plot plot,
final UUID player,
final Reason reason,
boolean added
) {
super(initiator, plot, player, reason);
this.added = added;
}
/**
* Get if the player was added to a list, or removed.
*/
public boolean added() {
return added;
}
}

View File

@@ -1,46 +0,0 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events.post;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import java.util.UUID;
/**
* Called when a player is added to a plot
*
* @since TODO
*/
public final class PostPlayerPlotAddedEvent extends PostPlayerPlotAddRemoveEvent {
/**
* PlayerPlotHelperEvent: Called when a player is added to a plot
*
* @param initiator Player that initiated the event
* @param plot Plot in which the event occurred
* @param player Player that was added/removed from the helper list
* @param added {@code true} if the player was added, {@code false} if the player was removed
* @param reason The reason for the add/remove
*/
public PostPlayerPlotAddedEvent(PlotPlayer<?> initiator, Plot plot, UUID player, boolean added, Reason reason) {
super(initiator, plot, player, reason, added);
}
}

View File

@@ -1,46 +0,0 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events.post;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import java.util.UUID;
/**
* Called when a player is denied from a plot
*
* @since TODO
*/
public final class PostPlayerPlotDeniedEvent extends PostPlayerPlotAddRemoveEvent {
/**
* PlayerPlotDeniedEvent: Called when the denied UUID list is modified for a plot.
*
* @param initiator Player that initiated the event
* @param plot Plot in which the event occurred
* @param player Player that was denied/un-denied
* @param added {@code true} of add to deny list, {@code false} if removed
* @param reason The reason for the deny/remove
*/
public PostPlayerPlotDeniedEvent(PlotPlayer<?> initiator, Plot plot, UUID player, boolean added, Reason reason) {
super(initiator, plot, player, reason, added);
}
}

View File

@@ -1,46 +0,0 @@
/*
* PlotSquared, a land and world management plugin for Minecraft.
* Copyright (C) IntellectualSites <https://intellectualsites.com>
* Copyright (C) IntellectualSites team and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.plotsquared.core.events.post;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import java.util.UUID;
/**
* Called when a plot trusted user is added/removed
*
* @since TODO
*/
public final class PostPlayerPlotTrustedEvent extends PostPlayerPlotAddRemoveEvent {
/**
* PlayerPlotTrustedEvent: Called when a plot trusted user is added/removed
*
* @param initiator Player that initiated the event
* @param plot Plot in which the event occurred
* @param player Player that was added/removed from the trusted list
* @param added {@code true} if the player was added, {@code false} if the player was removed
* @param reason The reason for the trust/remove
*/
public PostPlayerPlotTrustedEvent(PlotPlayer<?> initiator, Plot plot, UUID player, boolean added, Reason reason) {
super(initiator, plot, player, reason, added);
}
}

View File

@@ -140,8 +140,7 @@ public class HybridPlotWorld extends ClassicPlotWorld {
@NonNull
@Override
protected PlotManager createManager() {
return new HybridPlotManager(
this, PlotSquared.platform().regionManager(),
return new HybridPlotManager(this, PlotSquared.platform().regionManager(),
PlotSquared.platform().injector().getInstance(ProgressSubscriberFactory.class)
);
}
@@ -216,16 +215,15 @@ public class HybridPlotWorld extends ClassicPlotWorld {
// Try to determine root. This means that plot areas can have separate schematic
// directories
String schematicFolder = Settings.Paths.USE_SCHEMATICS_PATH_FOR_GEN_SCHEMATICS ? Settings.Paths.SCHEMATICS : "schematics";
if (!(root =
FileUtils.getFile(
PlotSquared.platform().getDirectory(),
schematicFolder + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + this.getWorldName() + File.separator + this.getId()
"schematics/GEN_ROAD_SCHEMATIC/" + this.getWorldName() + "/" + this.getId()
))
.exists()) {
root = FileUtils.getFile(
PlotSquared.platform().getDirectory(),
schematicFolder + File.separator + "GEN_ROAD_SCHEMATIC" + File.separator + this.getWorldName()
"schematics/GEN_ROAD_SCHEMATIC/" + this.getWorldName()
);
}

View File

@@ -164,7 +164,7 @@ public class PlotListener {
try (final MetaDataAccess<Plot> lastPlot = player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
Plot last = lastPlot.get().orElse(null);
if ((last != null) && !last.getId().equals(plot.getId())) {
plotExit(player, last, plot, plot.getArea());
plotExit(player, last);
}
if (PlotSquared.platform().expireManager() != null) {
PlotSquared.platform().expireManager().handleEntry(player, plot);
@@ -365,12 +365,7 @@ public class PlotListener {
return true;
}
public boolean plotExit(
final PlotPlayer<?> player,
@NonNull Plot plot,
@Nullable Plot nextPlot,
@Nullable PlotArea nextArea
) {
public boolean plotExit(final PlotPlayer<?> player, Plot plot) {
try (final MetaDataAccess<Plot> lastPlot = player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_LAST_PLOT)) {
final Plot previous = lastPlot.remove();
@@ -387,9 +382,7 @@ public class PlotListener {
if (plot.hasOwner()) {
PlotArea pw = plot.getArea();
if (pw == null) {
if (nextPlot == null || nextPlot.getArea() == null) {
return true;
}
return true;
}
try (final MetaDataAccess<Boolean> kickAccess =
player.accessTemporaryMetaData(PlayerMetaDataKeys.TEMPORARY_KICK)) {
@@ -447,23 +440,11 @@ public class PlotListener {
player.setFlight(value.get());
metaDataAccess.remove();
} else {
FlyFlag.FlyStatus flight = FlyFlag.FlyStatus.DEFAULT;
if (nextPlot != null) {
flight = nextPlot.getFlag(FlyFlag.class);
} else if (nextArea != null) {
if (nextArea.isRoadFlags()) {
flight = nextArea.getRoadFlag(FlyFlag.class);
} else {
flight = nextArea.getFlag(FlyFlag.class);
}
}
if (flight != FlyFlag.FlyStatus.ENABLED) {
GameMode gameMode = player.getGameMode();
if (gameMode == GameModes.SURVIVAL || gameMode == GameModes.ADVENTURE) {
player.setFlight(false);
} else if (!player.getFlight()) {
player.setFlight(true);
}
GameMode gameMode = player.getGameMode();
if (gameMode == GameModes.SURVIVAL || gameMode == GameModes.ADVENTURE) {
player.setFlight(false);
} else if (!player.getFlight()) {
player.setFlight(true);
}
}
}

View File

@@ -355,7 +355,7 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
/**
* {@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., {@code /plot <id> info}.
* an explicit plot override, e.g., `/plot &ltid&gt info`.
*/
private @NonNull String getContextualWorldName() {
Plot current = getCurrentPlot();
@@ -368,9 +368,9 @@ public abstract class PlotPlayer<P> implements CommandCaller, OfflinePlotPlayer,
/**
* {@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., {@code /plot <id> info}.
* an explicit plot override, e.g., `/plot &ltid&gt info`.
*
* @since 7.5.9
* @since TODO
*/
public @Nullable PlotArea getContextualPlotArea() {
Plot current = getCurrentPlot();

View File

@@ -29,7 +29,6 @@ import com.plotsquared.core.configuration.caption.CaptionUtility;
import com.plotsquared.core.configuration.caption.StaticCaption;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.database.DBFunc;
import com.plotsquared.core.events.PlayerPlotAddRemoveEvent;
import com.plotsquared.core.events.PlayerTeleportToPlotEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.events.TeleportCause;
@@ -975,10 +974,7 @@ public class Plot {
* Sets the denied users for this plot.
*
* @param uuids uuids to deny
* @deprecated Use {@link Plot#addDenied(UUID)} (UUID)} calling
* {@link EventDispatcher#callPlayerDeny(PlotPlayer, Plot, UUID, PlayerPlotAddRemoveEvent.Reason)} for each.
*/
@Deprecated
public void setDenied(final @NonNull Set<UUID> uuids) {
boolean larger = uuids.size() > getDenied().size();
HashSet<UUID> intersection;
@@ -1019,10 +1015,7 @@ public class Plot {
* Sets the trusted users for this plot.
*
* @param uuids uuids to trust
* @deprecated Use {@link Plot#addTrusted(UUID)} calling
* {@link EventDispatcher#callPlayerTrust(PlotPlayer, Plot, UUID, PlayerPlotAddRemoveEvent.Reason)} for each.
*/
@Deprecated
public void setTrusted(final @NonNull Set<UUID> uuids) {
boolean larger = uuids.size() > getTrusted().size();
HashSet<UUID> intersection = new HashSet<>(larger ? getTrusted() : uuids);
@@ -1054,10 +1047,7 @@ public class Plot {
* Sets the members for this plot.
*
* @param uuids uuids to set member status for
* @deprecated Use {@link Plot#addMember(UUID)} (UUID)} (UUID)} calling
* {@link EventDispatcher#callPlayerAdd(PlotPlayer, Plot, UUID, PlayerPlotAddRemoveEvent.Reason)} for each.
*/
@Deprecated
public void setMembers(final @NonNull Set<UUID> uuids) {
boolean larger = uuids.size() > getMembers().size();
HashSet<UUID> intersection = new HashSet<>(larger ? getMembers() : uuids);
@@ -1350,7 +1340,7 @@ public class Plot {
for (Plot current : getConnectedPlots()) {
List<PlotPlayer<?>> players = current.getPlayersInPlot();
for (PlotPlayer<?> pp : players) {
this.plotListener.plotExit(pp, current, null, area);
this.plotListener.plotExit(pp, current);
}
if (Settings.Backup.DELETE_ON_UNCLAIM) {
@@ -2312,53 +2302,23 @@ public class Plot {
this.setAlias(plot.getAlias());
}
for (UUID uuid : this.getTrusted()) {
if (eventDispatcher
.callPlayerTrust(null, plot, uuid, PlayerPlotAddRemoveEvent.Reason.MERGE)
.getEventResult() != Result.DENY) {
plot.addTrusted(uuid);
eventDispatcher.callPostTrusted(null, plot, uuid, true, PlayerPlotAddRemoveEvent.Reason.MERGE);
}
plot.addTrusted(uuid);
}
for (UUID uuid : plot.getTrusted()) {
if (eventDispatcher
.callPlayerTrust(null, this, uuid, PlayerPlotAddRemoveEvent.Reason.MERGE)
.getEventResult() != Result.DENY) {
this.addTrusted(uuid);
eventDispatcher.callPostTrusted(null, this, uuid, true, PlayerPlotAddRemoveEvent.Reason.MERGE);
}
this.addTrusted(uuid);
}
for (UUID uuid : this.getMembers()) {
if (eventDispatcher
.callPlayerAdd(null, plot, uuid, PlayerPlotAddRemoveEvent.Reason.MERGE)
.getEventResult() != Result.DENY) {
plot.addMember(uuid);
eventDispatcher.callPostAdded(null, plot, uuid, true, PlayerPlotAddRemoveEvent.Reason.MERGE);
}
plot.addMember(uuid);
}
for (UUID uuid : plot.getMembers()) {
if (eventDispatcher
.callPlayerAdd(null, this, uuid, PlayerPlotAddRemoveEvent.Reason.MERGE)
.getEventResult() != Result.DENY) {
this.addMember(uuid);
eventDispatcher.callPostAdded(null, this, uuid, true, PlayerPlotAddRemoveEvent.Reason.MERGE);
}
this.addMember(uuid);
}
for (UUID uuid : this.getDenied()) {
if (eventDispatcher
.callPlayerDeny(null, plot, uuid, PlayerPlotAddRemoveEvent.Reason.MERGE)
.getEventResult() != Result.DENY) {
plot.addDenied(uuid);
eventDispatcher.callPostDenied(null, plot, uuid, true, PlayerPlotAddRemoveEvent.Reason.MERGE);
}
plot.addDenied(uuid);
}
for (UUID uuid : plot.getDenied()) {
if (eventDispatcher
.callPlayerDeny(null, this, uuid, PlayerPlotAddRemoveEvent.Reason.MERGE)
.getEventResult() != Result.DENY) {
this.addDenied(uuid);
eventDispatcher.callPostDenied(null, this, uuid, true, PlayerPlotAddRemoveEvent.Reason.MERGE);
}
this.addDenied(uuid);
}
}
@@ -2634,7 +2594,7 @@ public class Plot {
public void reEnter() {
TaskManager.runTaskLater(() -> {
for (PlotPlayer<?> pp : Plot.this.getPlayersInPlot()) {
this.plotListener.plotExit(pp, Plot.this, Plot.this, area);
this.plotListener.plotExit(pp, Plot.this);
this.plotListener.plotEntry(pp, Plot.this);
}
}, TaskTime.ticks(1L));

View File

@@ -21,7 +21,6 @@ package com.plotsquared.core.plot;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Lists;
import com.google.inject.Inject;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.collection.QuadMap;
import com.plotsquared.core.configuration.ConfigurationNode;
@@ -30,8 +29,6 @@ import com.plotsquared.core.configuration.ConfigurationUtil;
import com.plotsquared.core.configuration.Settings;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.configuration.file.YamlConfiguration;
import com.plotsquared.core.events.PlayerPlotAddRemoveEvent;
import com.plotsquared.core.events.Result;
import com.plotsquared.core.generator.GridPlotWorld;
import com.plotsquared.core.generator.IndependentPlotGenerator;
import com.plotsquared.core.inject.annotations.WorldConfig;
@@ -50,7 +47,6 @@ import com.plotsquared.core.plot.flag.PlotFlag;
import com.plotsquared.core.plot.flag.implementations.DoneFlag;
import com.plotsquared.core.queue.GlobalBlockQueue;
import com.plotsquared.core.queue.QueueCoordinator;
import com.plotsquared.core.util.EventDispatcher;
import com.plotsquared.core.util.MathMan;
import com.plotsquared.core.util.PlotExpression;
import com.plotsquared.core.util.RegionUtil;
@@ -159,9 +155,6 @@ public abstract class PlotArea implements ComponentLike {
private QuadMap<PlotCluster> clusters;
private String signMaterial = "OAK_WALL_SIGN";
private String legacySignMaterial = "WALL_SIGN";
// These will be injected
@Inject
private EventDispatcher eventDispatcher;
public PlotArea(
final @NonNull String worldName, final @Nullable String id,
@@ -1111,44 +1104,9 @@ public abstract class PlotArea implements ComponentLike {
final PlotId id = PlotId.of(x, y);
final Plot plot = getPlotAbs(id);
Set<UUID> currentlyTrusted = plot.getTrusted();
trusted.forEach(uuid -> {
if (!currentlyTrusted.contains(uuid) && eventDispatcher.callPlayerTrust(
null,
plot,
uuid,
PlayerPlotAddRemoveEvent.Reason.MERGE
).getEventResult() != Result.DENY) {
plot.addTrusted(uuid);
eventDispatcher.callPostTrusted(null, plot, uuid, true, PlayerPlotAddRemoveEvent.Reason.MERGE);
}
});
Set<UUID> currentlyAdded = plot.getMembers();
members.forEach(uuid -> {
if (!currentlyAdded.contains(uuid) && eventDispatcher.callPlayerAdd(
null,
plot,
uuid,
PlayerPlotAddRemoveEvent.Reason.MERGE
).getEventResult() != Result.DENY) {
plot.addMember(uuid);
eventDispatcher.callPostAdded(null, plot, uuid, true, PlayerPlotAddRemoveEvent.Reason.MERGE);
}
});
Set<UUID> currentlyDenied = plot.getDenied();
denied.forEach(uuid -> {
if (!currentlyDenied.contains(uuid) && eventDispatcher.callPlayerDeny(
null,
plot,
uuid,
PlayerPlotAddRemoveEvent.Reason.MERGE
).getEventResult() != Result.DENY) {
plot.addDenied(uuid);
eventDispatcher.callPostDenied(null, plot, uuid, true, PlayerPlotAddRemoveEvent.Reason.MERGE);
}
});
plot.setTrusted(trusted);
plot.setMembers(members);
plot.setDenied(denied);
Plot plot2;
if (lx) {

View File

@@ -29,14 +29,9 @@ import com.plotsquared.core.events.PlayerBuyPlotEvent;
import com.plotsquared.core.events.PlayerClaimPlotEvent;
import com.plotsquared.core.events.PlayerEnterPlotEvent;
import com.plotsquared.core.events.PlayerLeavePlotEvent;
import com.plotsquared.core.events.PlayerPlotAddEvent;
import com.plotsquared.core.events.PlayerPlotAddRemoveEvent;
import com.plotsquared.core.events.PlayerPlotDeniedEvent;
import com.plotsquared.core.events.PlayerPlotDenyEvent;
import com.plotsquared.core.events.PlayerPlotHelperEvent;
import com.plotsquared.core.events.PlayerPlotLimitEvent;
import com.plotsquared.core.events.PlayerPlotRemoveEvent;
import com.plotsquared.core.events.PlayerPlotTrustEvent;
import com.plotsquared.core.events.PlayerPlotTrustedEvent;
import com.plotsquared.core.events.PlayerTeleportToPlotEvent;
import com.plotsquared.core.events.PlotAutoMergeEvent;
@@ -56,9 +51,6 @@ import com.plotsquared.core.events.RemoveRoadEntityEvent;
import com.plotsquared.core.events.TeleportCause;
import com.plotsquared.core.events.post.PostPlayerAutoPlotEvent;
import com.plotsquared.core.events.post.PostPlayerBuyPlotEvent;
import com.plotsquared.core.events.post.PostPlayerPlotAddedEvent;
import com.plotsquared.core.events.post.PostPlayerPlotDeniedEvent;
import com.plotsquared.core.events.post.PostPlayerPlotTrustedEvent;
import com.plotsquared.core.events.post.PostPlotChangeOwnerEvent;
import com.plotsquared.core.events.post.PostPlotClearEvent;
import com.plotsquared.core.events.post.PostPlotDeleteEvent;
@@ -266,7 +258,6 @@ public class EventDispatcher {
return event;
}
@Deprecated(forRemoval = true, since = "TODO")
public PlayerPlotDeniedEvent callDenied(
PlotPlayer<?> initiator, Plot plot, UUID player,
boolean added
@@ -276,7 +267,6 @@ public class EventDispatcher {
return event;
}
@Deprecated(forRemoval = true, since = "TODO")
public PlayerPlotTrustedEvent callTrusted(
PlotPlayer<?> initiator, Plot plot, UUID player,
boolean added
@@ -286,7 +276,6 @@ public class EventDispatcher {
return event;
}
@Deprecated(forRemoval = true, since = "TODO")
public PlayerPlotHelperEvent callMember(
PlotPlayer<?> initiator, Plot plot, UUID player,
boolean added
@@ -296,62 +285,6 @@ public class EventDispatcher {
return event;
}
public PostPlayerPlotDeniedEvent callPostDenied(
PlotPlayer<?> initiator, Plot plot, UUID player, boolean added, PlayerPlotAddRemoveEvent.Reason reason
) {
PostPlayerPlotDeniedEvent event = new PostPlayerPlotDeniedEvent(initiator, plot, player, added, reason);
callEvent(event);
return event;
}
public PostPlayerPlotTrustedEvent callPostTrusted(
PlotPlayer<?> initiator, Plot plot, UUID player, boolean added, PlayerPlotAddRemoveEvent.Reason reason
) {
PostPlayerPlotTrustedEvent event = new PostPlayerPlotTrustedEvent(initiator, plot, player, added, reason);
callEvent(event);
return event;
}
public PostPlayerPlotAddedEvent callPostAdded(
PlotPlayer<?> initiator, Plot plot, UUID player, boolean added, PlayerPlotAddRemoveEvent.Reason reason
) {
PostPlayerPlotAddedEvent event = new PostPlayerPlotAddedEvent(initiator, plot, player, added, reason);
callEvent(event);
return event;
}
public PlayerPlotDenyEvent callPlayerDeny(
PlotPlayer<?> initiator, Plot plot, UUID player, PlayerPlotAddRemoveEvent.Reason reason
) {
PlayerPlotDenyEvent event = new PlayerPlotDenyEvent(initiator, plot, player, reason);
callEvent(event);
return event;
}
public PlayerPlotTrustEvent callPlayerTrust(
PlotPlayer<?> initiator, Plot plot, UUID player, PlayerPlotAddRemoveEvent.Reason reason
) {
PlayerPlotTrustEvent event = new PlayerPlotTrustEvent(initiator, plot, player, reason);
callEvent(event);
return event;
}
public PlayerPlotAddEvent callPlayerAdd(
PlotPlayer<?> initiator, Plot plot, UUID player, PlayerPlotAddRemoveEvent.Reason reason
) {
PlayerPlotAddEvent event = new PlayerPlotAddEvent(initiator, plot, player, reason);
callEvent(event);
return event;
}
public PlayerPlotRemoveEvent callPlayerRemove(
PlotPlayer<?> initiator, Plot plot, UUID player, PlayerPlotAddRemoveEvent.Reason reason
) {
PlayerPlotRemoveEvent event = new PlayerPlotRemoveEvent(initiator, plot, player, reason);
callEvent(event);
return event;
}
public PlotChangeOwnerEvent callOwnerChange(
PlotPlayer<?> initiator, Plot plot, UUID oldOwner,
UUID newOwner, boolean hasOldOwner

View File

@@ -0,0 +1,76 @@
/*
* 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.util;
import org.jetbrains.annotations.ApiStatus;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Method;
import java.util.Optional;
@ApiStatus.Internal
public final class ReflectionHelper {
/**
* Find a (declared) method with an unknown or potentially obfuscated name by its signature and optional modifiers.
* <br>
* The method - if private - is not made accessible. Either call {@link Method#setAccessible(boolean)} or
* use a {@link java.lang.invoke.MethodHandles.Lookup#privateLookupIn(Class, MethodHandles.Lookup) private lookup}.
*
* @param holder The class providing the method.
* @param signature The signature of the method, identified by parameter types and the return type.
* @param modifiers All possible modifiers of the method that should be validated.
* @return The method, if one has been found. Otherwise, an empty Optional.
* @throws RuntimeException if multiple matching methods have been found.
* @see java.lang.reflect.Modifier
*/
public static Optional<Method> findMethod(Class<?> holder, MethodType signature, int... modifiers) {
Method found = null;
outer:
for (final Method method : holder.getDeclaredMethods()) {
if (method.getParameterCount() != signature.parameterCount()) {
continue;
}
if (!signature.returnType().isAssignableFrom(method.getReturnType())) {
continue;
}
for (final int modifier : modifiers) {
if ((method.getModifiers() & modifier) == 0) {
continue outer;
}
}
Class<?>[] parameterTypes = signature.parameterArray();
for (int i = 0; i < parameterTypes.length; i++) {
// validate expected parameter is either the same type or subtype of actual parameter
if (!parameterTypes[i].isAssignableFrom(method.getParameterTypes()[i])) {
continue outer;
}
}
if (found != null) {
throw new RuntimeException("Found ambiguous method by selector: " + method + " vs " + found);
}
found = method;
}
return Optional.ofNullable(found);
}
}

View File

@@ -204,9 +204,6 @@ public final class PlaceholderRegistry {
this.createPlaceholder("currentplot_x", (player, plot) -> Integer.toString(plot.getId().getX()));
this.createPlaceholder("currentplot_y", (player, plot) -> Integer.toString(plot.getId().getY()));
this.createPlaceholder("currentplot_xy", (player, plot) -> plot.getId().toString());
this.createPlaceholder("currentplot_abs_x", (player, plot) -> Integer.toString(plot.getId().getX()), true);
this.createPlaceholder("currentplot_abs_y", (player, plot) -> Integer.toString(plot.getId().getY()), true);
this.createPlaceholder("currentplot_abs_xy", (player, plot) -> plot.getId().toString(), true);
this.createPlaceholder("currentplot_rating", (player, plot) -> {
if (Double.isNaN(plot.getAverageRating())) {
return legacyComponent(TranslatableCaption.of("placeholder.nan"), player);
@@ -256,23 +253,7 @@ public final class PlaceholderRegistry {
final @NonNull String key,
final @NonNull BiFunction<PlotPlayer<?>, Plot, String> placeholderFunction
) {
this.createPlaceholder(key, placeholderFunction, false);
}
/**
* Create a functional placeholder
*
* @param key Placeholder key
* @param placeholderFunction Placeholder generator. Cannot return null
* @param requireAbsolute If the plot given to the placeholder should be the absolute (not base) plot
* @since 7.5.9
*/
public void createPlaceholder(
final @NonNull String key,
final @NonNull BiFunction<PlotPlayer<?>, Plot, String> placeholderFunction,
final boolean requireAbsolute
) {
this.registerPlaceholder(new PlotSpecificPlaceholder(key, requireAbsolute) {
this.registerPlaceholder(new PlotSpecificPlaceholder(key) {
@Override
public @NonNull String getValue(final @NonNull PlotPlayer<?> player, final @NonNull Plot plot) {
return placeholderFunction.apply(player, plot);

View File

@@ -27,28 +27,14 @@ import org.checkerframework.checker.nullness.qual.NonNull;
*/
public abstract class PlotSpecificPlaceholder extends Placeholder {
private final boolean requireAbsolute;
public PlotSpecificPlaceholder(final @NonNull String key) {
this(key, false);
}
/**
* Create a functional placeholder
*
* @param key Placeholder key
* @param requireAbsolute If the plot given to the placeholder should be the absolute (not base) plot
* @since 7.5.9
*/
public PlotSpecificPlaceholder(final @NonNull String key, final boolean requireAbsolute) {
super(key);
this.requireAbsolute = requireAbsolute;
}
@Override
public @NonNull
final String getValue(final @NonNull PlotPlayer<?> player) {
final Plot plot = requireAbsolute ? player.getLocation().getPlotAbs() : player.getCurrentPlot();
final Plot plot = player.getCurrentPlot();
if (plot == null) {
return "";
}

View File

@@ -0,0 +1,79 @@
/*
* 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.util;
import org.junit.jupiter.api.Test;
import java.lang.invoke.MethodType;
import java.lang.reflect.Modifier;
import java.util.Collection;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
class ReflectionHelperTest {
@Test
void findMethod() throws NoSuchMethodException {
assertThrows(
RuntimeException.class, () ->
ReflectionHelper.findMethod(MethodTesterClass.class, MethodType.methodType(String.class))
);
assertEquals(
MethodTesterClass.class.getMethod("methodThree"),
ReflectionHelper.findMethod(MethodTesterClass.class, MethodType.methodType(String.class), Modifier.PUBLIC)
.orElse(null)
);
assertEquals(
MethodTesterClass.class.getDeclaredMethod("methodFour", String.class, Collection.class),
ReflectionHelper.findMethod(MethodTesterClass.class, MethodType.methodType(
String.class, String.class, Collection.class
)).orElse(null)
);
// check that helper allows super classes of parameters when searching
assertEquals(
MethodTesterClass.class.getDeclaredMethod("methodFour", String.class, Collection.class),
ReflectionHelper.findMethod(MethodTesterClass.class, MethodType.methodType(
String.class, String.class, Object.class
)).orElse(null)
);
}
@SuppressWarnings("unused")
private static class MethodTesterClass {
private static String methodOne() {
return "";
}
private static String methodTwo() {
return "";
}
public static String methodThree() {
return "";
}
protected static String methodFour(String param, Collection<String> paramList) {
return "";
}
}
}

View File

@@ -20,7 +20,7 @@ plugins {
}
group = "com.intellectualsites.plotsquared"
version = "7.5.12-SNAPSHOT"
version = "7.5.9-SNAPSHOT"
if (!File("$rootDir/.git").exists()) {
logger.lifecycle("""
@@ -73,8 +73,8 @@ subprojects {
dependencies {
// Tests
testImplementation("org.junit.jupiter:junit-jupiter:6.0.1")
testRuntimeOnly("org.junit.platform:junit-platform-launcher:6.0.1")
testImplementation("org.junit.jupiter:junit-jupiter:6.0.0")
testRuntimeOnly("org.junit.platform:junit-platform-launcher:6.0.0")
}
plugins.withId("java") {
@@ -231,10 +231,9 @@ tasks {
register<RunServer>("runServer-$it") {
dependsOn(getByName("cacheLatestFaweArtifact"))
minecraftVersion(it)
pluginJars(project.files(
project(":plotsquared-bukkit").tasks.named<Jar>("shadowJar")
.map { it.archiveFile }
))
pluginJars(*project(":plotsquared-bukkit").getTasksByName("shadowJar", false)
.map { task -> (task as Jar).archiveFile }
.toTypedArray())
jvmArgs("-DPaper.IgnoreJavaVersion=true", "-Dcom.mojang.eula.agree=true")
downloadPlugins {
url("https://ci.athion.net/job/FastAsyncWorldEdit/lastSuccessfulBuild/artifact/artifacts/${project.ext["faweArtifact"]}")

View File

@@ -3,18 +3,18 @@
paper = "1.20.4-R0.1-SNAPSHOT"
guice = "7.0.0"
spotbugs = "4.9.8"
checkerqual = "3.52.1"
checkerqual = "3.51.1"
gson = "2.10"
guava = "31.1-jre"
snakeyaml = "2.0"
adventure = "4.26.1"
adventure = "4.25.0"
adventure-bukkit = "4.4.1"
log4j = "2.19.0"
# Plugins
worldedit = "7.2.20"
fawe = "2.14.3"
placeholderapi = "2.11.7"
fawe = "2.14.0"
placeholderapi = "2.11.6"
luckperms = "5.5"
essentialsx = "2.21.2"
mvdwapi = "3.1.1"
@@ -33,10 +33,10 @@ vault = "1.7.1"
serverlib = "2.3.7"
# Gradle plugins
shadow = "9.3.0"
shadow = "9.2.2"
grgit = "4.1.1"
spotless = "8.1.0"
publish = "0.35.0"
spotless = "8.0.0"
publish = "0.34.0"
runPaper = "3.0.2"
[libraries]

Binary file not shown.

View File

@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1.0-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME