Merge remote-tracking branch 'upstream/main'

This commit is contained in:
2023-08-19 12:43:25 +02:00
224 changed files with 4739 additions and 10834 deletions

View File

@@ -108,6 +108,14 @@ public class FaweBukkit implements IFawe, Listener {
if (version.isEqualOrHigherThan(MinecraftVersion.CAVES_18) && Settings.settings().HISTORY.SMALL_EDITS) {
LOGGER.warn("Small-edits enabled (maximum y range of 0 -> 256) with 1.18 world heights. Are you sure?");
}
if (version.isEqualOrLowerThan(MinecraftVersion.ONE_DOT_SIXTEEN_EOL)) {
LOGGER.warn("You are running Minecraft 1.16.5. This version has been released over two years ago (January 2021).");
LOGGER.warn("FastAsyncWorldEdit will stop operating on this version in the near future.");
LOGGER.warn("Neither Mojang, nor Spigot or other software vendors support this version anymore." +
"Please update your server to a newer version of Minecraft (1.20+) to continue receiving updates and " +
"support.");
}
}
@Override
@@ -225,7 +233,7 @@ public class FaweBukkit implements IFawe, Listener {
final Plugin residencePlugin = Bukkit.getServer().getPluginManager().getPlugin("Residence");
if (residencePlugin != null && residencePlugin.isEnabled()) {
try {
managers.add(new ResidenceFeature(residencePlugin, this));
managers.add(new ResidenceFeature(residencePlugin));
LOGGER.info("Attempting to use plugin 'Residence'");
} catch (Throwable ignored) {
}
@@ -317,11 +325,11 @@ public class FaweBukkit implements IFawe, Listener {
if (plotSquared == null) {
return;
}
if (PlotSquared.get().getVersion().version[0] == 6) {
if (PlotSquared.get().getVersion().version[0] == 7) {
WEManager.weManager().addManager(new com.fastasyncworldedit.bukkit.regions.plotsquared.PlotSquaredFeature());
LOGGER.info("Plugin 'PlotSquared' v6 found. Using it now.");
LOGGER.info("Plugin 'PlotSquared' v7 found. Using it now.");
} else {
LOGGER.error("Incompatible version of PlotSquared found. Please use PlotSquared v6.");
LOGGER.error("Incompatible version of PlotSquared found. Please use PlotSquared v7.");
LOGGER.info("https://www.spigotmc.org/resources/77506/");
}
}

View File

@@ -3,8 +3,6 @@ package com.fastasyncworldedit.bukkit.adapter;
import co.aikar.timings.Timings;
import com.fastasyncworldedit.bukkit.listener.ChunkListener;
import com.fastasyncworldedit.core.queue.implementation.QueueHandler;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import org.apache.logging.log4j.Logger;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -31,7 +29,7 @@ public class BukkitQueueHandler extends QueueHandler {
}
@Override
public void startSet(boolean parallel) {
public void startUnsafe(boolean parallel) {
ChunkListener.physicsFreeze = true;
if (parallel) {
try {
@@ -51,7 +49,7 @@ public class BukkitQueueHandler extends QueueHandler {
}
@Override
public void endSet(boolean parallel) {
public void endUnsafe(boolean parallel) {
ChunkListener.physicsFreeze = false;
if (parallel) {
try {

View File

@@ -84,7 +84,7 @@ public class NMSAdapter implements FAWEPlatformAdapterImpl {
getArr = get.apply(layer);
}
// write to set array as this should be a copied array, and will be important when the changes are written
// to the GET chunk cached by FAWE
// to the GET chunk cached by FAWE. Future dords, actually read this comment please.
set[i] = switch (ordinal = getArr[i]) {
case BlockTypesCache.ReservedIDs.__RESERVED__ -> {
nonAir--;

View File

@@ -165,7 +165,11 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
.setNameFormat("fawe-regen-%d")
.build()
);
} // else using sequential chunk generation, concurrent not supported
} else { // else using sequential chunk generation, concurrent not supported
executor = Executors.newSingleThreadExecutor(new ThreadFactoryBuilder()
.setNameFormat("fawe-regen-%d")
.build());
}
//TODO: can we get that required radius down without affecting chunk generation (e.g. strucures, features, ...)?
//for now it is working well and fast, if we are bored in the future we could do the research (a lot of it) to reduce the border radius
@@ -253,10 +257,13 @@ public abstract class Regenerator<IChunkAccess, ProtoChunk extends IChunkAccess,
e.printStackTrace();
}
} else { // Concurrency.NONE or generateConcurrent == false
// run sequential
for (long xz : coords) {
chunkStatus.processChunkSave(xz, worldlimits.get(radius).get(xz));
}
// run sequential but submit to different thread
// running regen on the main thread otherwise triggers async-only events on the main thread
executor.submit(() -> {
for (long xz : coords) {
chunkStatus.processChunkSave(xz, worldlimits.get(radius).get(xz));
}
}).get(); // wait until finished this step
}
}

View File

@@ -371,48 +371,6 @@ public abstract class ChunkListener implements Listener {
}
}
/**
* Prevent firework from loading chunks.
*/
@EventHandler(priority = EventPriority.LOWEST)
public void onChunkLoad(ChunkLoadEvent event) {
if (!Settings.settings().TICK_LIMITER.FIREWORKS_LOAD_CHUNKS) {
Chunk chunk = event.getChunk();
Entity[] entities = chunk.getEntities();
World world = chunk.getWorld();
Exception e = new Exception();
int start = 14;
int end = 22;
int depth = Math.min(end, getDepth(e));
for (int frame = start; frame < depth; frame++) {
StackTraceElement elem = getElement(e, frame);
if (elem == null) {
return;
}
String className = elem.getClassName();
int len = className.length();
if (len > 15 && className.charAt(len - 15) == 'E' && className
.endsWith("EntityFireworks")) {
for (Entity ent : world.getEntities()) {
if (ent.getType() == EntityType.FIREWORK) {
Vector velocity = ent.getVelocity();
double vertical = Math.abs(velocity.getY());
if (Math.abs(velocity.getX()) > vertical
|| Math.abs(velocity.getZ()) > vertical) {
LOGGER.warn(
"[FAWE `tick-limiter`] Detected and cancelled rogue FireWork at {}",
ent.getLocation());
ent.remove();
}
}
}
}
}
}
}
@EventHandler(priority = EventPriority.LOWEST)
public void onItemSpawn(ItemSpawnEvent event) {
if (physicsFreeze) {

View File

@@ -2,10 +2,7 @@ package com.fastasyncworldedit.bukkit.regions;
import com.fastasyncworldedit.core.regions.FaweMask;
import com.fastasyncworldedit.core.util.TaskManager;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;

View File

@@ -3,7 +3,6 @@ package com.fastasyncworldedit.bukkit.regions;
import com.bekvon.bukkit.residence.Residence;
import com.bekvon.bukkit.residence.protection.ClaimedResidence;
import com.bekvon.bukkit.residence.protection.CuboidArea;
import com.fastasyncworldedit.bukkit.FaweBukkit;
import com.fastasyncworldedit.core.regions.FaweMask;
import com.fastasyncworldedit.core.util.TaskManager;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
@@ -19,13 +18,8 @@ public class ResidenceFeature extends BukkitMaskManager implements Listener {
private static final Logger LOGGER = LogManagerCompat.getLogger();
private final FaweBukkit plugin;
private final Plugin residence;
public ResidenceFeature(final Plugin residencePlugin, final FaweBukkit p3) {
public ResidenceFeature(final Plugin residencePlugin) {
super(residencePlugin.getName());
this.residence = residencePlugin;
this.plugin = p3;
LOGGER.info("Plugin 'Residence' found. Using it now.");
}

View File

@@ -1,10 +1,7 @@
package com.fastasyncworldedit.bukkit.regions;
import com.fastasyncworldedit.core.regions.FaweMask;
import com.palmergames.bukkit.towny.Towny;
import com.palmergames.bukkit.towny.TownyUniverse;
import com.palmergames.bukkit.towny.exceptions.NotRegisteredException;
import com.palmergames.bukkit.towny.object.PlayerCache;
import com.palmergames.bukkit.towny.TownyAPI;
import com.palmergames.bukkit.towny.object.Resident;
import com.palmergames.bukkit.towny.object.Town;
import com.palmergames.bukkit.towny.object.TownBlock;
@@ -14,7 +11,6 @@ import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import org.apache.logging.log4j.Logger;
import org.bukkit.Chunk;
import org.bukkit.Location;
import org.bukkit.entity.Player;
import org.bukkit.event.Listener;
@@ -24,11 +20,8 @@ public class TownyFeature extends BukkitMaskManager implements Listener {
private static final Logger LOGGER = LogManagerCompat.getLogger();
private final Plugin towny;
public TownyFeature(Plugin townyPlugin) {
super(townyPlugin.getName());
this.towny = townyPlugin;
LOGGER.info("Plugin 'Towny' found. Using it now.");
}
@@ -36,31 +29,27 @@ public class TownyFeature extends BukkitMaskManager implements Listener {
if (block == null) {
return false;
}
Resident resident;
try {
resident = TownyUniverse.getInstance().getResident(player.getName());
try {
if (block.getResident().equals(resident)) {
return true;
}
} catch (NotRegisteredException ignored) {
}
Town town = block.getTown();
if (town.isMayor(resident)) {
Resident resident = TownyAPI.getInstance().getResident(player);
if (resident == null) {
return false;
}
if (block.hasResident(resident) || block.hasTrustedResident(resident)) {
return true;
}
Town town = block.getTownOrNull(); // Will not be null, because block is not null.
if (town.isMayor(resident) || town.hasTrustedResident(resident)) {
return true;
}
if (!town.hasResident(resident)) {
return false;
}
if (player.hasPermission("fawe.towny.*")) {
return true;
}
for (String rank : resident.getTownRanks()) {
if (player.hasPermission("fawe.towny." + rank)) {
return true;
}
if (!town.hasResident(resident)) {
return false;
}
if (player.hasPermission("fawe.towny.*")) {
return true;
}
for (String rank : resident.getTownRanks()) {
if (player.hasPermission("fawe.towny." + rank)) {
return true;
}
}
} catch (NotRegisteredException ignored) {
}
return false;
}
@@ -69,32 +58,23 @@ public class TownyFeature extends BukkitMaskManager implements Listener {
public FaweMask getMask(final com.sk89q.worldedit.entity.Player wePlayer, MaskType type, boolean isWhitelist) {
final Player player = BukkitAdapter.adapt(wePlayer);
final Location location = player.getLocation();
try {
final PlayerCache cache = ((Towny) this.towny).getCache(player);
final WorldCoord mycoord = cache.getLastTownBlock();
if (mycoord == null) {
return null;
}
final TownBlock myplot = mycoord.getTownBlock();
if (myplot == null) {
return null;
}
boolean isMember = isAllowed(player, myplot);
if (isMember) {
final Chunk chunk = location.getChunk();
final BlockVector3 pos1 = BlockVector3
.at(chunk.getX() * 16, 0, chunk.getZ() * 16);
final BlockVector3 pos2 = BlockVector3.at(
chunk.getX() * 16 + 15, 156, chunk.getZ() * 16
+ 15);
return new FaweMask(new CuboidRegion(pos1, pos2)) {
@Override
public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) {
return isAllowed(BukkitAdapter.adapt(player), myplot);
}
};
}
} catch (Exception ignored) {
final WorldCoord mycoord = WorldCoord.parseWorldCoord(location);
if (mycoord.isWilderness()) {
return null;
}
final TownBlock myplot = mycoord.getTownBlockOrNull(); // Will not be null, because of the isWilderness() test above.
boolean isMember = isAllowed(player, myplot);
if (isMember) {
final Location loc1 = mycoord.getLowerMostCornerLocation();
final Location loc2 = mycoord.getUpperMostCornerLocation();
final BlockVector3 pos1 = BlockVector3.at(loc1.getX(), loc1.getY(), loc1.getZ());
final BlockVector3 pos2 = BlockVector3.at(loc2.getX() - 1, loc2.getY(), loc2.getZ() - 1);
return new FaweMask(new CuboidRegion(pos1, pos2)) {
@Override
public boolean isValid(com.sk89q.worldedit.entity.Player player, MaskType type) {
return isAllowed(BukkitAdapter.adapt(player), myplot);
}
};
}
return null;
}

View File

@@ -171,18 +171,17 @@ public class FaweDelegateRegionManager {
.limitUnlimited()
.changeSetNull()
.build();
File schematicFile = new File(hybridPlotWorld.getRoot(), "plot.schem");
File schematicFile = new File(hybridPlotWorld.getSchematicRoot(), "plot.schem");
if (!schematicFile.exists()) {
schematicFile = new File(hybridPlotWorld.getRoot(), "plot.schematic");
schematicFile = new File(hybridPlotWorld.getSchematicRoot(), "plot.schematic");
}
BlockVector3 to = plot.getBottomAbs().getBlockVector3().withY(Settings.Schematics.PASTE_ON_TOP
? hybridPlotWorld.SCHEM_Y
: hybridPlotWorld.getMinBuildHeight());
BlockVector3 to = plot.getBottomAbs().getBlockVector3().withY(hybridPlotWorld.getPlotYStart());
try {
Clipboard clip = ClipboardFormats
.findByFile(schematicFile)
.getReader(new FileInputStream(schematicFile))
.read();
clip.setOrigin(clip.getRegion().getMinimumPoint());
clip.paste(scheditsession, to, true, true, true);
} catch (IOException e) {
e.printStackTrace();
@@ -214,7 +213,7 @@ public class FaweDelegateRegionManager {
) {
TaskManager.taskManager().async(() -> {
synchronized (FaweDelegateRegionManager.class) {
//todo because of the following code this should proably be in the Bukkit module
//todo because of the following code this should probably be in the Bukkit module
World pos1World = BukkitAdapter.adapt(getWorld(pos1.getWorldName()));
World pos3World = BukkitAdapter.adapt(getWorld(swapPos.getWorldName()));
EditSession sessionA = WorldEdit.getInstance().newEditSessionBuilder().world(pos1World)

View File

@@ -152,6 +152,7 @@ public class FaweDelegateSchematicHandler {
final BlockVector3 to = BlockVector3
.at(region.getMinimumPoint().getX() + xOffset, y_offset_actual, region.getMinimumPoint().getZ() + zOffset);
final Clipboard clipboard = schematic.getClipboard();
clipboard.setOrigin(clipboard.getRegion().getMinimumPoint());
clipboard.paste(editSession, to, true, false, true);
if (whenDone != null) {
whenDone.value = true;

View File

@@ -1,13 +1,15 @@
package com.fastasyncworldedit.bukkit.regions.plotsquared;
import com.fastasyncworldedit.core.util.TaskManager;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import com.plotsquared.core.PlotSquared;
import com.plotsquared.core.command.CommandCategory;
import com.plotsquared.core.command.CommandDeclaration;
import com.plotsquared.core.command.RequiredType;
import com.plotsquared.core.command.SubCommand;
import com.plotsquared.core.configuration.caption.StaticCaption;
import com.plotsquared.core.configuration.caption.Templates;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.player.PlotPlayer;
@@ -33,7 +35,7 @@ public class FaweTrim extends SubCommand {
return false;
}
if (!PlotSquared.platform().worldUtil().isWorld(strings[0])) {
plotPlayer.sendMessage(TranslatableCaption.of("errors.not_valid_plot_world"), Templates.of("value", strings[0]));
plotPlayer.sendMessage(TranslatableCaption.of("errors.not_valid_plot_world"), TagResolver.resolver("value", Tag.inserting(Component.text(strings[0]))));
return false;
}
ran = true;

View File

@@ -6,11 +6,9 @@ import com.plotsquared.core.command.CommandCategory;
import com.plotsquared.core.command.CommandDeclaration;
import com.plotsquared.core.command.MainCommand;
import com.plotsquared.core.command.RequiredType;
import com.plotsquared.core.configuration.caption.Templates;
import com.plotsquared.core.configuration.caption.TranslatableCaption;
import com.plotsquared.core.player.PlotPlayer;
import com.plotsquared.core.plot.Plot;
import com.plotsquared.core.util.Permissions;
import com.plotsquared.core.util.StringMan;
import com.plotsquared.core.util.task.RunnableVal2;
import com.plotsquared.core.util.task.RunnableVal3;
@@ -24,6 +22,9 @@ import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.biome.Biomes;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.minimessage.tag.Tag;
import net.kyori.adventure.text.minimessage.tag.resolver.TagResolver;
import org.bukkit.Bukkit;
import java.util.Collection;
@@ -56,7 +57,7 @@ public class PlotSetBiome extends Command {
) throws CommandException {
final Plot plot = check(player.getCurrentPlot(), TranslatableCaption.of("errors.not_in_plot"));
checkTrue(
plot.isOwner(player.getUUID()) || Permissions.hasPermission(player, "plots.admin.command.generatebiome"),
plot.isOwner(player.getUUID()) || player.hasPermission("plots.admin.command.generatebiome"),
TranslatableCaption.of("permission.no_plot_perms")
);
if (plot.getRunning() != 0) {
@@ -64,7 +65,7 @@ public class PlotSetBiome extends Command {
return null;
}
checkTrue(args.length == 1, TranslatableCaption.of("commandconfig.command_syntax"),
Templates.of("value", getUsage())
TagResolver.resolver("value", Tag.inserting(Component.text(getUsage())))
);
final Set<CuboidRegion> regions = plot.getRegions();
BiomeRegistry biomeRegistry =
@@ -80,7 +81,7 @@ public class PlotSetBiome extends Command {
player.sendMessage(TranslatableCaption.of("biome.need_biome"));
player.sendMessage(
TranslatableCaption.of("commandconfig.subcommand_set_options_header"),
Templates.of("values", biomes)
TagResolver.resolver("value", Tag.inserting(Component.text(biomes)))
);
return CompletableFuture.completedFuture(false);
}

View File

@@ -23,8 +23,11 @@ import com.sk89q.worldedit.world.World;
import org.apache.logging.log4j.Logger;
import org.bukkit.Bukkit;
import javax.annotation.Nonnull;
import java.lang.ref.WeakReference;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
@@ -39,7 +42,7 @@ public class PlotSquaredFeature extends FaweMaskManager {
if (Settings.FAWE_Components.FAWE_HOOK) {
Settings.Enabled_Components.WORLDEDIT_RESTRICTIONS = false;
if (Settings.PLATFORM.toLowerCase(Locale.ROOT).startsWith("bukkit")) {
new FaweTrim();
// new FaweTrim();
}
// TODO: revisit this later on
/*
@@ -66,28 +69,32 @@ public class PlotSquaredFeature extends FaweMaskManager {
* @param plot the {@link Plot}
* @param type the {@link MaskType}
* @return {@code true} if the player is the plot owner, trusted, has the permission fawe.plotsquared.member
* or fawe.plotsquared.admin and the NoWorldeditFlag is not set; otherwise {@code false}
* or fawe.plotsquared.admin and the NoWorldeditFlag is not set; otherwise {@code false}
*/
public boolean isAllowed(Player player, Plot plot, MaskType type) {
public boolean isAllowed(Player player, Plot plot, MaskType type, boolean notify) {
if (plot == null) {
return false;
}
UUID uid = player.getUniqueId();
if (plot.getFlag(NoWorldeditFlag.class)) {
player.print(Caption.of(
"fawe.cancel.reason.no.region.reason",
Caption.of("fawe.cancel.reason.no.region.plot.noworldeditflag")
));
if (notify) {
player.print(Caption.of(
"fawe.cancel.reason.no.region.reason",
Caption.of("fawe.cancel.reason.no.region.plot.noworldeditflag")
));
}
return false;
}
if (plot.isOwner(uid) || player.hasPermission("fawe.plotsquared.admin")) {
return true;
}
if (type != MaskType.MEMBER) {
player.print(Caption.of(
"fawe.cancel.reason.no.region.reason",
Caption.of("fawe.cancel.reason.no.region.plot.owner.only")
));
if (notify) {
player.print(Caption.of(
"fawe.cancel.reason.no.region.reason",
Caption.of("fawe.cancel.reason.no.region.plot.owner.only")
));
}
return false;
}
if (plot.getTrusted().contains(uid) || plot.getTrusted().contains(DBFunc.EVERYONE)) {
@@ -95,26 +102,32 @@ public class PlotSquaredFeature extends FaweMaskManager {
}
if (plot.getMembers().contains(uid) || plot.getMembers().contains(DBFunc.EVERYONE)) {
if (!player.hasPermission("fawe.plotsquared.member")) {
player.print(Caption.of(
"fawe.cancel.reason.no.region.reason",
Caption.of("fawe.error.no-perm", "fawe.plotsquared.member")
));
if (notify) {
player.print(Caption.of(
"fawe.cancel.reason.no.region.reason",
Caption.of("fawe.error.no-perm", "fawe.plotsquared.member")
));
}
return false;
}
if (!plot.getOwners().isEmpty() && plot.getOwners().stream().anyMatch(this::playerOnline)) {
return true;
} else {
player.print(Caption.of(
"fawe.cancel.reason.no.region.reason",
Caption.of("fawe.cancel.reason.no.region.plot.owner.offline")
));
if (notify) {
player.print(Caption.of(
"fawe.cancel.reason.no.region.reason",
Caption.of("fawe.cancel.reason.no.region.plot.owner.offline")
));
}
return false;
}
}
player.print(Caption.of(
"fawe.cancel.reason.no.region.reason",
Caption.of("fawe.cancel.reason.no.region.not.added")
));
if (notify) {
player.print(Caption.of(
"fawe.cancel.reason.no.region.reason",
Caption.of("fawe.cancel.reason.no.region.not.added")
));
}
return false;
}
@@ -127,14 +140,19 @@ public class PlotSquaredFeature extends FaweMaskManager {
}
@Override
public FaweMask getMask(Player player, MaskType type, boolean isWhitelist) {
public FaweMask getMask(final Player player, final MaskType type, final boolean isWhitelist) {
return getMask(player, type, isWhitelist, true);
}
@Override
public FaweMask getMask(Player player, MaskType type, boolean isWhitelist, boolean notify) {
final PlotPlayer<org.bukkit.entity.Player> pp = PlotPlayer.from(BukkitAdapter.adapt(player));
if (pp == null) {
return null;
}
final Set<CuboidRegion> regions;
Plot plot = pp.getCurrentPlot();
if (isAllowed(player, plot, type)) {
if (isAllowed(player, plot, type, notify)) {
regions = plot.getRegions();
} else {
plot = null;
@@ -176,15 +194,37 @@ public class PlotSquaredFeature extends FaweMaskManager {
maskedRegion = new RegionIntersection(world, weRegions);
}
return new FaweMask(maskedRegion) {
@Override
public boolean isValid(Player player, MaskType type) {
if (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(finalPlot)) {
return false;
}
return isAllowed(player, finalPlot, type);
if (plot == null) {
return new FaweMask(maskedRegion);
}
return new PlotSquaredMask(maskedRegion, finalPlot);
}
private final class PlotSquaredMask extends FaweMask {
private final Plot plot;
private final WeakReference<Set<Plot>> connectedPlots;
private final boolean singlePlot;
private PlotSquaredMask(@Nonnull Region region, @Nonnull Plot plot) {
super(region);
this.plot = Objects.requireNonNull(plot);
Set<Plot> connected = plot.getConnectedPlots();
connectedPlots = new WeakReference<>(connected);
singlePlot = connected.size() == 1;
}
@Override
public boolean isValid(Player player, MaskType type, boolean notify) {
if ((!connectedPlots.refersTo(plot.getConnectedPlots()) && (!singlePlot || plot
.getConnectedPlots()
.size() > 1)) || (Settings.Done.RESTRICT_BUILDING && DoneFlag.isDone(plot))) {
return false;
}
};
return isAllowed(player, plot, type, notify);
}
}
}

View File

@@ -13,6 +13,7 @@ import java.util.regex.Pattern;
public class MinecraftVersion implements Comparable<MinecraftVersion> {
public static final MinecraftVersion NETHER = new MinecraftVersion(1, 16);
public static final MinecraftVersion ONE_DOT_SIXTEEN_EOL = new MinecraftVersion(1, 16, 5);
public static final MinecraftVersion CAVES_17 = new MinecraftVersion(1, 17);
public static final MinecraftVersion CAVES_18 = new MinecraftVersion(1, 18);
private static MinecraftVersion current = null;

View File

@@ -21,11 +21,8 @@ package com.sk89q.worldedit.bukkit;
import com.fastasyncworldedit.core.util.TaskManager;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.extension.platform.AbstractNonPlayerActor;
import com.sk89q.worldedit.extension.platform.Locatable;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.extension.platform.AbstractCommandBlockActor;
import com.sk89q.worldedit.session.SessionKey;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.auth.AuthorizationException;
import com.sk89q.worldedit.util.formatting.WorldEditText;
import com.sk89q.worldedit.util.formatting.text.Component;
@@ -43,22 +40,20 @@ import java.util.UUID;
import static com.google.common.base.Preconditions.checkNotNull;
public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements Locatable {
public class BukkitBlockCommandSender extends AbstractCommandBlockActor {
private static final String UUID_PREFIX = "CMD";
private final BlockCommandSender sender;
private final WorldEditPlugin plugin;
private final Location location;
private final UUID uuid;
public BukkitBlockCommandSender(WorldEditPlugin plugin, BlockCommandSender sender) {
super(BukkitAdapter.adapt(checkNotNull(sender).getBlock().getLocation()));
checkNotNull(plugin);
checkNotNull(sender);
this.plugin = plugin;
this.sender = sender;
this.location = BukkitAdapter.adapt(sender.getBlock().getLocation());
this.uuid = UUID.nameUUIDFromBytes((UUID_PREFIX + sender.getName()).getBytes(StandardCharsets.UTF_8));
}
@@ -134,21 +129,6 @@ public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements
return WorldEdit.getInstance().getConfiguration().defaultLocale;
}
@Override
public Location getLocation() {
return this.location;
}
@Override
public boolean setLocation(Location location) {
return false;
}
@Override
public Extent getExtent() {
return this.location.getExtent();
}
@Override
public UUID getUniqueId() {
return uuid;

View File

@@ -25,7 +25,6 @@ import com.sk89q.worldedit.util.YAMLConfiguration;
import com.sk89q.worldedit.util.report.Unreported;
import org.apache.logging.log4j.LogManager;
import java.io.File;
import java.nio.file.Path;
/**
@@ -36,7 +35,6 @@ public class BukkitConfiguration extends YAMLConfiguration {
@Unreported
private final WorldEditPlugin plugin;
public boolean noOpPermissions = false;
public boolean commandBlockSupport = false;
public boolean unsupportedVersionEditing = false;
public BukkitConfiguration(YAMLProcessor config, WorldEditPlugin plugin) {
@@ -48,33 +46,12 @@ public class BukkitConfiguration extends YAMLConfiguration {
public void load() {
super.load();
noOpPermissions = config.getBoolean("no-op-permissions", false);
commandBlockSupport = config.getBoolean("command-block-support", false);
unsupportedVersionEditing = "I accept that I will receive no support with this flag enabled.".equals(
config.getString("allow-editing-on-unsupported-versions", "false"));
if (unsupportedVersionEditing) {
WorldEdit.logger.warn("Editing without a Bukkit adapter has been enabled. You will not receive support "
+ "for any issues that arise as a result.");
}
migrateLegacyFolders();
}
private void migrateLegacyFolders() {
migrate(scriptsDir, "craftscripts");
migrate(saveDir, "schematics");
migrate("drawings", "draw.js images");
}
private void migrate(String file, String name) {
File fromDir = new File(".", file);
File toDir = new File(getWorkingDirectoryPath().toFile(), file);
if (fromDir.exists() & !toDir.exists()) {
if (fromDir.renameTo(toDir)) {
plugin.getLogger().info("Migrated " + name + " folder '" + file
+ "' from server root to plugin data folder.");
} else {
plugin.getLogger().warning("Error while migrating " + name + " folder!");
}
}
}
@Override

View File

@@ -21,6 +21,8 @@ package com.sk89q.worldedit.bukkit;
import com.fastasyncworldedit.bukkit.util.WorldUnloadedException;
import com.fastasyncworldedit.core.Fawe;
import com.fastasyncworldedit.core.FaweCache;
import com.fastasyncworldedit.core.configuration.Settings;
import com.fastasyncworldedit.core.internal.exception.FaweException;
import com.fastasyncworldedit.core.queue.IChunkGet;
import com.fastasyncworldedit.core.queue.implementation.packet.ChunkPacket;
@@ -242,6 +244,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public int getBlockLightLevel(BlockVector3 pt) {
//FAWE start - safe edit region
testCoords(pt);
//FAWE end
return getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).getLightLevel();
}
@@ -265,6 +270,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public boolean clearContainerBlockContents(BlockVector3 pt) {
checkNotNull(pt);
//FAWE start - safe edit region
testCoords(pt);
//FAWE end
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
try {
@@ -337,6 +345,7 @@ public class BukkitWorld extends AbstractWorld {
@Override
public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, BlockVector3 pt) {
//FAWE start - allow tree commands to be undone and obey region restrictions
testCoords(pt);
return WorldEditPlugin.getInstance().getBukkitImplAdapter().generateTree(type, editSession, pt, getWorld());
//FAWE end
}
@@ -349,6 +358,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public void checkLoadedChunk(BlockVector3 pt) {
//FAWE start - safe edit region
testCoords(pt);
//FAWE end
World world = getWorld();
//FAWE start
int X = pt.getBlockX() >> 4;
@@ -480,6 +492,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public void simulateBlockMine(BlockVector3 pt) {
//FAWE start - safe edit region
testCoords(pt);
//FAWE end
getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).breakNaturally();
}
@@ -493,6 +508,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public boolean canPlaceAt(BlockVector3 position, com.sk89q.worldedit.world.block.BlockState blockState) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
return adapter.canPlaceAt(getWorld(), position, blockState);
@@ -505,6 +523,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public com.sk89q.worldedit.world.block.BlockState getBlock(BlockVector3 position) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
try {
@@ -526,6 +547,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, SideEffectSet sideEffects) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
if (worldNativeAccess != null) {
try {
return worldNativeAccess.setBlock(position, block, sideEffects);
@@ -545,6 +569,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
return adapter.getFullBlock(BukkitAdapter.adapt(getWorld(), position));
@@ -553,11 +580,25 @@ public class BukkitWorld extends AbstractWorld {
}
}
private void testCoords(BlockVector3 position) throws FaweException {
if (!Settings.settings().REGION_RESTRICTIONS_OPTIONS.RESTRICT_TO_SAFE_RANGE) {
return;
}
int x = position.getX();
int z = position.getZ();
if (x > 30000000 || z > 30000000 || x < -30000000 || z < -30000000) {
throw FaweCache.OUTSIDE_SAFE_REGION;
}
}
@Override
public Set<SideEffect> applySideEffects(
BlockVector3 position, com.sk89q.worldedit.world.block.BlockState previousType,
SideEffectSet sideEffectSet
) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
if (worldNativeAccess != null) {
worldNativeAccess.applySideEffects(position, previousType, sideEffectSet);
return Sets.intersection(
@@ -571,6 +612,9 @@ public class BukkitWorld extends AbstractWorld {
@Override
public boolean useItem(BlockVector3 position, BaseItem item, Direction face) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
return adapter.simulateItemUse(getWorld(), position, item, face);
@@ -588,6 +632,9 @@ public class BukkitWorld extends AbstractWorld {
@SuppressWarnings("deprecation")
@Override
public BiomeType getBiome(BlockVector3 position) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
if (HAS_3D_BIOMES) {
return BukkitAdapter.adapt(getWorld().getBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ()));
} else {
@@ -598,6 +645,9 @@ public class BukkitWorld extends AbstractWorld {
@SuppressWarnings("deprecation")
@Override
public boolean setBiome(BlockVector3 position, BiomeType biome) {
//FAWE start - safe edit region
testCoords(position);
//FAWE end
if (HAS_3D_BIOMES) {
getWorld().setBiome(position.getBlockX(), position.getBlockY(), position.getBlockZ(), BukkitAdapter.adapt(biome));
} else {
@@ -626,11 +676,13 @@ public class BukkitWorld extends AbstractWorld {
@Override
public void refreshChunk(int chunkX, int chunkZ) {
testCoords(BlockVector3.at(chunkX << 4, 0, chunkZ << 4));
getWorld().refreshChunk(chunkX, chunkZ);
}
@Override
public IChunkGet get(int chunkX, int chunkZ) {
testCoords(BlockVector3.at(chunkX << 4, 0, chunkZ << 4));
return WorldEditPlugin.getInstance().getBukkitImplAdapter().get(getWorldChecked(), chunkX, chunkZ);
}

View File

@@ -112,11 +112,15 @@ public class WorldEditPlugin extends JavaPlugin {
private BukkitServerInterface platform;
private BukkitConfiguration config;
private BukkitPermissionAttachmentManager permissionAttachmentManager;
// Fawe start
private BukkitCommandSender bukkitConsoleCommandSender;
// Fawe end
@Override
public void onLoad() {
//FAWE start
this.bukkitConsoleCommandSender = new BukkitCommandSender(this, Bukkit.getConsoleSender());
// This is already covered by Spigot, however, a more pesky warning with a proper explanation over "Ambiguous plugin name..." can't hurt.
Plugin[] plugins = Bukkit.getServer().getPluginManager().getPlugins();
for (Plugin p : plugins) {
@@ -594,7 +598,7 @@ public class WorldEditPlugin extends JavaPlugin {
return new BukkitBlockCommandSender(this, (BlockCommandSender) sender);
}
return new BukkitCommandSender(this, sender);
return bukkitConsoleCommandSender;
}
public BukkitServerInterface getInternalPlatform() {
@@ -668,6 +672,13 @@ public class WorldEditPlugin extends JavaPlugin {
String label = buffer.substring(0, firstSpace);
// Strip leading slash, if present.
label = label.startsWith("/") ? label.substring(1) : label;
// If command not owned by FAWE, do not tab complete
Plugin owner = platform.getDynamicCommands().getCommandOwner(label);
if (owner != WorldEditPlugin.this) {
return;
}
final Optional<org.enginehub.piston.Command> command
= WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().getCommandManager().getCommand(
label);

View File

@@ -19,6 +19,8 @@
package com.sk89q.wepif;
import com.destroystokyo.paper.profile.PlayerProfile;
import org.bukkit.BanEntry;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.OfflinePlayer;
@@ -30,10 +32,13 @@ import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.Plugin;
import org.bukkit.profile.PlayerProfile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.annotation.Nonnull;
import java.time.Duration;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Locale;
@@ -158,6 +163,33 @@ public class TestOfflinePermissible implements OfflinePlayer, Permissible {
throw new UnsupportedOperationException("Not supported yet.");
}
@Override
public <E extends BanEntry<? super PlayerProfile>> @Nullable E ban(
@Nullable final String reason,
@Nullable final Instant expires,
@Nullable final String source
) {
return null;
}
@Override
public <E extends BanEntry<? super PlayerProfile>> @Nullable E ban(
@Nullable final String reason,
@Nullable final Duration duration,
@Nullable final String source
) {
return null;
}
@Override
public @Nullable BanEntry<org.bukkit.profile.PlayerProfile> ban(
@Nullable final String reason,
@Nullable final Date expires,
@Nullable final String source
) {
return null;
}
@Override
public boolean isWhitelisted() {
throw new UnsupportedOperationException("Not supported yet.");
@@ -323,4 +355,9 @@ public class TestOfflinePermissible implements OfflinePlayer, Permissible {
}
@Override
public @Nullable Location getLastDeathLocation() {
return null;
}
}

View File

@@ -26,7 +26,6 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
public class BukkitWorldTest {
@Test
public void testTreeTypeMapping() {
for (TreeGenerator.TreeType type : TreeGenerator.TreeType.values()) {
assertNotNull(BukkitWorld.toBukkitTreeType(type), "No mapping for: " + type);