Propagate FAWE diff annotations down the bukkit module

- Minor upstream merge
This commit is contained in:
NotMyFault 2021-07-14 14:40:20 +02:00
parent d7763c8542
commit bcceadee6b
No known key found for this signature in database
GPG Key ID: 158F5701A6AAD00C
34 changed files with 450 additions and 159 deletions

View File

@ -16,7 +16,7 @@ import com.fastasyncworldedit.bukkit.regions.GriefPreventionFeature;
import com.fastasyncworldedit.bukkit.regions.GriefDefenderFeature;
import com.fastasyncworldedit.bukkit.regions.ResidenceFeature;
import com.fastasyncworldedit.bukkit.regions.TownyFeature;
import com.fastasyncworldedit.bukkit.regions.Worldguard;
import com.fastasyncworldedit.bukkit.regions.WorldGuardFeature;
import com.fastasyncworldedit.bukkit.util.BukkitTaskManager;
import com.fastasyncworldedit.bukkit.util.ItemUtil;
import com.fastasyncworldedit.bukkit.util.MinecraftVersion;
@ -190,7 +190,7 @@ public class FaweBukkit implements IFawe, Listener {
final ArrayList<FaweMaskManager> managers = new ArrayList<>();
if (worldguardPlugin != null && worldguardPlugin.isEnabled()) {
try {
managers.add(new Worldguard(worldguardPlugin));
managers.add(new WorldGuardFeature(worldguardPlugin));
LOGGER.info("Attempting to use plugin 'WorldGuard'");
} catch (Throwable ignored) {
}

View File

@ -1,7 +1,5 @@
package com.fastasyncworldedit.bukkit.adapter;
import com.destroystokyo.paper.util.ReentrantLockWithGetOwner;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;

View File

@ -5,7 +5,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.NotABlockException;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.BukkitEntity;
import com.sk89q.worldedit.bukkit.BukkitItemStack;
import com.fastasyncworldedit.bukkit.util.BukkitItemStack;
import com.sk89q.worldedit.bukkit.BukkitPlayer;
import com.sk89q.worldedit.bukkit.BukkitWorld;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;

View File

@ -1,4 +1,4 @@
package com.destroystokyo.paper.util;
package com.fastasyncworldedit.bukkit.adapter;
import java.util.concurrent.locks.ReentrantLock;

View File

@ -37,7 +37,7 @@ public class WorldGuardFilter extends CuboidRegionFilter {
BlockVector3 min = region.getMinimumPoint();
BlockVector3 max = region.getMaximumPoint();
if (max.getBlockX() - min.getBlockX() > 1024 || max.getBlockZ() - min.getBlockZ() > 1024) {
LOGGER.debug("Large or complex region shapes cannot be optimized. Filtering will be slower");
LOGGER.info("Large or complex region shapes cannot be optimized. Filtering will be slower");
large = true;
break;
}

View File

@ -25,7 +25,7 @@ public class ResidenceFeature extends BukkitMaskManager implements Listener {
super(residencePlugin.getName());
this.residence = residencePlugin;
this.plugin = p3;
LOGGER.debug("Plugin 'Residence' found. Using it now.");
LOGGER.info("Plugin 'Residence' found. Using it now.");
}
public boolean isAllowed(Player player, ClaimedResidence residence, MaskType type) {

View File

@ -29,7 +29,7 @@ public class TownyFeature extends BukkitMaskManager implements Listener {
public TownyFeature(Plugin townyPlugin) {
super(townyPlugin.getName());
this.towny = townyPlugin;
LOGGER.debug("Plugin 'Towny' found. Using it now.");
LOGGER.info("Plugin 'Towny' found. Using it now.");
}
public boolean isAllowed(Player player, TownBlock block) {

View File

@ -30,7 +30,7 @@ import org.bukkit.event.Listener;
import org.bukkit.plugin.Plugin;
import java.util.Locale;
public class Worldguard extends BukkitMaskManager implements Listener {
public class WorldGuardFeature extends BukkitMaskManager implements Listener {
private final WorldGuardPlugin worldguard;
private static final Logger LOGGER = LogManagerCompat.getLogger();
@ -45,10 +45,10 @@ public class Worldguard extends BukkitMaskManager implements Listener {
return (WorldGuardPlugin) plugin;
}
public Worldguard(Plugin p2) {
public WorldGuardFeature(Plugin p2) {
super(p2.getName());
this.worldguard = this.getWorldGuard();
LOGGER.debug("Plugin 'WorldGuard' found. Using it now.");
LOGGER.info("Plugin 'WorldGuard' found. Using it now.");
}

View File

@ -1,10 +1,11 @@
package com.sk89q.worldedit.bukkit;
package com.fastasyncworldedit.bukkit.util;
import com.fastasyncworldedit.core.Fawe;
import com.fastasyncworldedit.bukkit.FaweBukkit;
import com.fastasyncworldedit.bukkit.util.ItemUtil;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.bukkit.BukkitAdapter;
import com.sk89q.worldedit.world.item.ItemType;
import org.bukkit.inventory.ItemStack;

View File

@ -17,7 +17,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.bukkit;
package com.fastasyncworldedit.bukkit.util;
import com.fastasyncworldedit.core.configuration.Caption;
import com.sk89q.worldedit.WorldEditException;
@ -25,12 +25,12 @@ import com.sk89q.worldedit.WorldEditException;
/**
* Thrown if the world has been unloaded.
*/
class WorldUnloadedException extends WorldEditException {
public class WorldUnloadedException extends WorldEditException {
/**
* Create a new instance.
*/
WorldUnloadedException() {
public WorldUnloadedException() {
super(Caption.of("worldedit.error.world-unloaded"));
}
}

View File

@ -0,0 +1,131 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit 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.sk89q.bukkit.util;
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import org.apache.logging.log4j.Logger;
import org.bukkit.plugin.Plugin;
import java.security.CodeSource;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Validates that certain specified classes came from the same source as
* a plugin.
*/
public class ClassSourceValidator {
private static final Logger LOGGER = LogManagerCompat.getLogger();
private static final String SEPARATOR_LINE = Strings.repeat("*", 46);
private final Plugin plugin;
@Nullable
private final CodeSource expectedCodeSource;
/**
* Create a new instance.
*
* @param plugin The plugin
*/
public ClassSourceValidator(Plugin plugin) {
checkNotNull(plugin, "plugin");
this.plugin = plugin;
this.expectedCodeSource = plugin.getClass().getProtectionDomain().getCodeSource();
}
/**
* Return a map of classes that been loaded from a different source.
*
* @param classes A list of classes to check
* @return The results
*/
public Map<Class<?>, CodeSource> findMismatches(List<Class<?>> classes) {
checkNotNull(classes, "classes");
if (expectedCodeSource == null) {
return ImmutableMap.of();
}
Map<Class<?>, CodeSource> mismatches = new HashMap<>();
for (Class<?> testClass : classes) {
CodeSource testSource = testClass.getProtectionDomain().getCodeSource();
if (!expectedCodeSource.equals(testSource)) {
mismatches.put(testClass, testSource);
}
}
return mismatches;
}
/**
* Reports classes that have come from a different source.
*
* <p>The warning is emitted to the log.</p>
*
* @param classes The list of classes to check
*/
public void reportMismatches(List<Class<?>> classes) {
if (Boolean.getBoolean("enginehub.disable.class.source.validation")) {
return;
}
Map<Class<?>, CodeSource> mismatches = findMismatches(classes);
if (mismatches.isEmpty()) {
return;
}
StringBuilder builder = new StringBuilder("\n");
builder.append(SEPARATOR_LINE).append("\n");
builder.append("** /!\\ SEVERE WARNING /!\\\n");
builder.append("** \n");
builder.append("** A plugin developer has included a portion of \n");
builder.append("** ").append(plugin.getName()).append(" into their own plugin, so rather than using\n");
builder.append("** the version of ").append(plugin.getName()).append(" that you downloaded, you\n");
builder.append("** will be using a broken mix of old ").append(plugin.getName()).append(" (that came\n");
builder.append("** with the plugin) and your downloaded version. THIS MAY\n");
builder.append("** SEVERELY BREAK ").append(plugin.getName().toUpperCase(Locale.ROOT)).append(" AND ALL OF ITS FEATURES.\n");
builder.append("**\n");
builder.append("** This may have happened because the developer is using\n");
builder.append("** the ").append(plugin.getName()).append(" API and thinks that including\n");
builder.append("** ").append(plugin.getName()).append(" is necessary. However, it is not!\n");
builder.append("**\n");
builder.append("** Here are some files that have been overridden:\n");
builder.append("** \n");
for (Map.Entry<Class<?>, CodeSource> entry : mismatches.entrySet()) {
CodeSource codeSource = entry.getValue();
String url = codeSource != null ? codeSource.getLocation().toExternalForm() : "(unknown)";
builder.append("** '").append(entry.getKey().getSimpleName()).append("' came from '").append(url).append("'\n");
}
builder.append("**\n");
builder.append("** Please report this to the plugins' developers.\n");
builder.append(SEPARATOR_LINE).append("\n");
LOGGER.error(builder.toString());
}
}

View File

@ -48,21 +48,25 @@ public class DinnerPermsResolver implements PermissionsResolver {
}
@Override
@SuppressWarnings("deprecation")
public boolean hasPermission(String name, String permission) {
return hasPermission(server.getOfflinePlayer(name), permission);
}
@Override
@SuppressWarnings("deprecation")
public boolean hasPermission(String worldName, String name, String permission) {
return hasPermission(worldName, server.getOfflinePlayer(name), permission);
}
@Override
@SuppressWarnings("deprecation")
public boolean inGroup(String name, String group) {
return inGroup(server.getOfflinePlayer(name), group);
}
@Override
@SuppressWarnings("deprecation")
public String[] getGroups(String name) {
return getGroups(server.getOfflinePlayer(name));
}

View File

@ -72,7 +72,6 @@ public class NijiPermissionsResolver implements PermissionsResolver {
}
@Override
@SuppressWarnings("static-access")
public boolean hasPermission(String name, String permission) {
try {
Player player = server.getPlayerExact(name);
@ -82,7 +81,7 @@ public class NijiPermissionsResolver implements PermissionsResolver {
try {
return api.getHandler().has(player, permission);
} catch (Throwable t) {
return api.Security.permission(player, permission);
return Permissions.Security.permission(player, permission);
}
} catch (Throwable t) {
LOGGER.warn("Failed to check permissions", t);
@ -105,7 +104,6 @@ public class NijiPermissionsResolver implements PermissionsResolver {
}
@Override
@SuppressWarnings("static-access")
public boolean inGroup(String name, String group) {
try {
Player player = server.getPlayerExact(name);
@ -115,7 +113,7 @@ public class NijiPermissionsResolver implements PermissionsResolver {
try {
return api.getHandler().inGroup(player.getWorld().getName(), name, group);
} catch (Throwable t) {
return api.Security.inGroup(name, group);
return Permissions.Security.inGroup(name, group);
}
} catch (Throwable t) {
LOGGER.warn("Failed to check groups", t);
@ -124,7 +122,6 @@ public class NijiPermissionsResolver implements PermissionsResolver {
}
@Override
@SuppressWarnings("static-access")
public String[] getGroups(String name) {
try {
Player player = server.getPlayerExact(name);
@ -135,9 +132,9 @@ public class NijiPermissionsResolver implements PermissionsResolver {
try {
groups = api.getHandler().getGroups(player.getWorld().getName(), player.getName());
} catch (Throwable t) {
String group = api.Security.getGroup(player.getWorld().getName(), player.getName());
String group = Permissions.Security.getGroup(player.getWorld().getName(), player.getName());
if (group != null) {
groups = new String[]{group};
groups = new String[] { group };
}
}
if (groups == null) {

View File

@ -28,7 +28,9 @@ import org.bukkit.plugin.RegisteredServiceProvider;
public class VaultResolver implements PermissionsResolver {
//FAWE start - made public
public static Permission perms = null;
//FAWE end
public static PermissionsResolver factory(Server server, YAMLProcessor config) {
if (server.getPluginManager().getPlugin("Vault") == null) {
@ -62,21 +64,25 @@ public class VaultResolver implements PermissionsResolver {
}
@Override
@SuppressWarnings("deprecation")
public boolean hasPermission(String name, String permission) {
return hasPermission(server.getOfflinePlayer(name), permission);
}
@Override
@SuppressWarnings("deprecation")
public boolean hasPermission(String worldName, String name, String permission) {
return hasPermission(worldName, server.getOfflinePlayer(name), permission);
}
@Override
@SuppressWarnings("deprecation")
public boolean inGroup(String player, String group) {
return inGroup(server.getOfflinePlayer(player), group);
}
@Override
@SuppressWarnings("deprecation")
public String[] getGroups(String player) {
return getGroups(server.getOfflinePlayer(player));
}

View File

@ -54,6 +54,7 @@ public class bPermissionsResolver implements PermissionsResolver {
}
@Override
@SuppressWarnings("deprecation")
public boolean hasPermission(String name, String permission) {
return hasPermission(server.getOfflinePlayer(name), permission);
}
@ -64,11 +65,13 @@ public class bPermissionsResolver implements PermissionsResolver {
}
@Override
@SuppressWarnings("deprecation")
public boolean inGroup(String player, String group) {
return inGroup(server.getOfflinePlayer(player), group);
}
@Override
@SuppressWarnings("deprecation")
public String[] getGroups(String player) {
return getGroups(server.getOfflinePlayer(player));
}

View File

@ -30,6 +30,7 @@ import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.PlayerProxy;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
@ -43,6 +44,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import org.bukkit.Material;
import org.bukkit.block.Biome;
import org.bukkit.block.BlockFace;
import org.bukkit.block.data.BlockData;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
@ -53,12 +55,14 @@ import org.jetbrains.annotations.Nullable;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* Adapts between Bukkit and WorldEdit equivalent objects.
*/
// FAWE start - enum-ized
public enum BukkitAdapter {
INSTANCE;
@ -66,17 +70,15 @@ public enum BukkitAdapter {
BukkitAdapter() {
BukkitImplAdapter tmp = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (tmp != null) {
this.adapter = tmp;
} else {
this.adapter = new SimpleBukkitAdapter();
}
this.adapter = Objects.requireNonNullElseGet(tmp, SimpleBukkitAdapter::new);
}
private static final IBukkitAdapter getAdapter() {
private static IBukkitAdapter getAdapter() {
return INSTANCE.adapter;
}
// FAWE end
private static final ParserContext TO_BLOCK_CONTEXT = new ParserContext();
static {
@ -91,7 +93,9 @@ public enum BukkitAdapter {
* @return If they are equal
*/
public static boolean equals(BlockType blockType, Material type) {
// FAWE start - swapped reference to getAdapter
return getAdapter().equals(blockType, type);
// FAWE end
}
/**
@ -104,7 +108,9 @@ public enum BukkitAdapter {
* @return a wrapped Bukkit world
*/
public static BukkitWorld asBukkitWorld(World world) {
// FAWE start - logic moved to IBukkitAdapter
return getAdapter().asBukkitWorld(world);
// FAWE end
}
/**
@ -114,7 +120,9 @@ public enum BukkitAdapter {
* @return a WorldEdit world
*/
public static World adapt(org.bukkit.World world) {
// FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(world);
// FAWE end
}
/**
@ -159,8 +167,32 @@ public enum BukkitAdapter {
* @return The Bukkit player
*/
public static Player adapt(com.sk89q.worldedit.entity.Player player) {
//FAWE start - Get player from PlayerProxy instead of BukkitPlayer if null
player = PlayerProxy.unwrap(player);
return player == null ? null : ((BukkitPlayer) player).getPlayer();
//FAWE end
}
/**
* Create a WorldEdit Direction from a Bukkit BlockFace.
*
* @param face the Bukkit BlockFace
* @return a WorldEdit direction
*/
public static Direction adapt(@Nullable BlockFace face) {
if (face == null) {
return null;
}
switch (face) {
case NORTH: return Direction.NORTH;
case SOUTH: return Direction.SOUTH;
case WEST: return Direction.WEST;
case EAST: return Direction.EAST;
case DOWN: return Direction.DOWN;
case UP:
default:
return Direction.UP;
}
}
/**
@ -170,7 +202,9 @@ public enum BukkitAdapter {
* @return a Bukkit world
*/
public static org.bukkit.World adapt(World world) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(world);
//FAWE end
}
/**
@ -281,7 +315,9 @@ public enum BukkitAdapter {
* @return a WorldEdit entity
*/
public static Entity adapt(org.bukkit.entity.Entity entity) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(entity);
//FAWE end
}
/**
@ -291,7 +327,9 @@ public enum BukkitAdapter {
* @return The Bukkit Material
*/
public static Material adapt(ItemType itemType) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(itemType);
//FAWE end
}
/**
@ -301,7 +339,9 @@ public enum BukkitAdapter {
* @return The Bukkit Material
*/
public static Material adapt(BlockType blockType) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(blockType);
//FAWE end
}
/**
@ -311,7 +351,9 @@ public enum BukkitAdapter {
* @return WorldEdit GameMode
*/
public static GameMode adapt(org.bukkit.GameMode gameMode) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(gameMode);
//FAWE end
}
/**
@ -321,11 +363,15 @@ public enum BukkitAdapter {
* @return WorldEdit BiomeType
*/
public static BiomeType adapt(Biome biome) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(biome);
//FAWE end
}
public static Biome adapt(BiomeType biomeType) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(biomeType);
//FAWE end
}
/**
@ -335,11 +381,15 @@ public enum BukkitAdapter {
* @return WorldEdit EntityType
*/
public static EntityType adapt(org.bukkit.entity.EntityType entityType) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(entityType);
//FAWE end
}
public static org.bukkit.entity.EntityType adapt(EntityType entityType) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(entityType);
//FAWE end
}
private static EnumMap<Material, BlockType> materialBlockTypeCache = new EnumMap<>(Material.class);
@ -353,7 +403,9 @@ public enum BukkitAdapter {
*/
@Nullable
public static BlockType asBlockType(Material material) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().asBlockType(material);
//FAWE end
}
/**
@ -364,7 +416,9 @@ public enum BukkitAdapter {
*/
@Nullable
public static ItemType asItemType(Material material) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().asItemType(material);
//FAWE end
}
private static Int2ObjectMap<BlockState> blockStateCache = new Int2ObjectOpenHashMap<>();
@ -377,7 +431,9 @@ public enum BukkitAdapter {
* @return The WorldEdit BlockState
*/
public static BlockState adapt(@NotNull BlockData blockData) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(blockData);
//FAWE end
}
private static Int2ObjectMap<BlockData> blockDataCache = new Int2ObjectOpenHashMap<>();
@ -389,7 +445,9 @@ public enum BukkitAdapter {
* @return The Bukkit BlockData
*/
public static BlockData adapt(@NotNull BlockStateHolder block) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(block);
//FAWE end
}
/**
@ -399,7 +457,9 @@ public enum BukkitAdapter {
* @return The WorldEdit BlockState
*/
public static BlockState asBlockState(ItemStack itemStack) throws WorldEditException {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().asBlockState(itemStack);
//FAWE end
}
/**
@ -409,7 +469,9 @@ public enum BukkitAdapter {
* @return The WorldEdit BaseItemStack
*/
public static BaseItemStack adapt(ItemStack itemStack) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(itemStack);
//FAWE end
}
/**
@ -419,6 +481,8 @@ public enum BukkitAdapter {
* @return The Bukkit ItemStack
*/
public static ItemStack adapt(BaseItemStack item) {
//FAWE start - logic moved to IBukkitAdapter
return getAdapter().adapt(item);
//FAWE end
}
}

View File

@ -31,6 +31,7 @@ import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.util.formatting.text.TextComponent;
import com.sk89q.worldedit.util.formatting.text.adapter.bukkit.TextAdapter;
import com.sk89q.worldedit.util.formatting.text.format.TextColor;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.World;
import org.bukkit.block.Block;
@ -68,6 +69,7 @@ public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements
}
@Override
@Deprecated
public void printRaw(String msg) {
for (String part : msg.split("\n")) {
sender.sendMessage(part);
@ -75,6 +77,7 @@ public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements
}
@Override
@Deprecated
public void print(String msg) {
for (String part : msg.split("\n")) {
print(TextComponent.of(part, TextColor.LIGHT_PURPLE));
@ -82,6 +85,7 @@ public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements
}
@Override
@Deprecated
public void printDebug(String msg) {
for (String part : msg.split("\n")) {
print(TextComponent.of(part, TextColor.GRAY));
@ -89,6 +93,7 @@ public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements
}
@Override
@Deprecated
public void printError(String msg) {
for (String part : msg.split("\n")) {
print(TextComponent.of(part, TextColor.RED));
@ -142,10 +147,12 @@ public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements
return sender.hasPermission(permission);
}
//FAWE start
@Override
public boolean togglePermission(String permission) {
return true;
}
//FAWE end
@Override
public void setPermission(String permission, boolean value) {
@ -158,6 +165,21 @@ public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements
@Override
public SessionKey getSessionKey() {
return new SessionKey() {
private volatile boolean active = true;
private void updateActive() {
Block block = sender.getBlock();
if (!block.getWorld().isChunkLoaded(block.getX() >> 4, block.getZ() >> 4)) {
active = false;
return;
}
Material type = block.getType();
active = type == Material.COMMAND_BLOCK
|| type == Material.CHAIN_COMMAND_BLOCK
|| type == Material.REPEATING_COMMAND_BLOCK;
}
@Override
public String getName() {
return sender.getName();
@ -165,14 +187,18 @@ public class BukkitBlockCommandSender extends AbstractNonPlayerActor implements
@Override
public boolean isActive() {
@NotNull Block block = sender.getBlock();
@NotNull World world = block.getWorld();
if (world.isChunkLoaded(block.getX() >> 4, block.getZ() >> 4)) {
return sender.getBlock().getType() == Material.COMMAND_BLOCK
|| sender.getBlock().getType() == Material.CHAIN_COMMAND_BLOCK
|| sender.getBlock().getType() == Material.REPEATING_COMMAND_BLOCK;
if (Bukkit.isPrimaryThread()) {
// we can update eagerly
updateActive();
} else {
// we should update it eventually
Bukkit.getScheduler().callSyncMethod(plugin,
() -> {
updateActive();
return null;
});
}
return false;
return active;
}
@Override

View File

@ -51,6 +51,7 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
@Nullable
@Override
public BlockMaterial getMaterial(BlockType blockType) {
//FAWE start - delegate to our internal values
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
BlockMaterial result = adapter.getMaterial(blockType);
@ -71,8 +72,10 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
materialMap[mat.ordinal()] = result;
}
return result;
//FAWE end
}
//FAWE start
@Nullable
@Override
public BlockMaterial getMaterial(BlockState state) {
@ -85,14 +88,7 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
}
return super.getMaterial(state);
}
@Override
public OptionalInt getInternalBlockStateId(BlockState state) {
if (WorldEditPlugin.getInstance().getBukkitImplAdapter() != null) {
return WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBlockStateId(state);
}
return OptionalInt.empty();
}
//FAWE end
@Nullable
@Override
@ -104,6 +100,14 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
return super.getProperties(blockType);
}
@Override
public OptionalInt getInternalBlockStateId(BlockState state) {
if (WorldEditPlugin.getInstance().getBukkitImplAdapter() != null) {
return WorldEditPlugin.getInstance().getBukkitImplAdapter().getInternalBlockStateId(state);
}
return OptionalInt.empty();
}
public static class BukkitBlockMaterial extends PassthroughBlockMaterial {
private final Material material;
@ -113,10 +117,6 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
this.material = bukkitMaterial;
}
public int getId() {
return material.getId();
}
@Override
public boolean isAir() {
switch (material) {
@ -139,12 +139,14 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
return material.isBurnable();
}
@SuppressWarnings("deprecation")
@Override
public boolean isTranslucent() {
return material.isTransparent();
}
}
// FAWE start
@Override
public Collection<String> values() {
ArrayList<String> blocks = new ArrayList<>();
@ -156,4 +158,5 @@ public class BukkitBlockRegistry extends BundledBlockRegistry {
}
return blocks;
}
//FAWE end
}

View File

@ -113,8 +113,10 @@ public class BukkitCommandSender extends AbstractNonPlayerActor {
return true;
}
//FAWE start
@Override public void setPermission(String permission, boolean value) {
}
//FAWE end
@Override
public void checkPermission(String permission) throws AuthorizationException {
@ -140,10 +142,12 @@ public class BukkitCommandSender extends AbstractNonPlayerActor {
@Override
public boolean isActive() {
//FAWE start - check if sender instanceof Entity, before returning true
if (sender instanceof Entity) {
Entity entity = (Entity) sender;
return entity.isValid() && !entity.isDead();
}
//FAWE end
return true;
}

View File

@ -20,11 +20,9 @@
package com.sk89q.worldedit.bukkit;
import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.util.YAMLConfiguration;
import com.sk89q.worldedit.util.report.Unreported;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.nio.file.Path;
@ -34,8 +32,6 @@ import java.nio.file.Path;
*/
public class BukkitConfiguration extends YAMLConfiguration {
private static final Logger LOGGER = LogManagerCompat.getLogger();
public boolean noOpPermissions = false;
public boolean commandBlockSupport = false;
@Unreported private final WorldEditPlugin plugin;
@ -61,13 +57,13 @@ public class BukkitConfiguration extends YAMLConfiguration {
private void migrate(String file, String name) {
File fromDir = new File(".", file);
File toDir = new File(getWorkingDirectory(), file);
File toDir = new File(getWorkingDirectoryPath().toFile(), file);
if (fromDir.exists() & !toDir.exists()) {
if (fromDir.renameTo(toDir)) {
LOGGER.info("Migrated " + name + " folder '" + file
plugin.getLogger().info("Migrated " + name + " folder '" + file
+ "' from server root to plugin data folder.");
} else {
LOGGER.warn("Error while migrating " + name + " folder!");
plugin.getLogger().warning("Error while migrating " + name + " folder!");
}
}
}

View File

@ -39,10 +39,14 @@ import static com.google.common.base.Preconditions.checkNotNull;
/**
* An adapter to adapt a Bukkit entity into a WorldEdit one.
*/
//FAWE start - made class public
public class BukkitEntity implements Entity {
//FAWE end
private final WeakReference<org.bukkit.entity.Entity> entityRef;
//FAWE start
private final EntityType type;
//FAWE end
/**
* Create a new instance.
@ -51,7 +55,9 @@ public class BukkitEntity implements Entity {
*/
public BukkitEntity(org.bukkit.entity.Entity entity) {
checkNotNull(entity);
//FAWE start
this.type = entity.getType();
//FAWE end
this.entityRef = new WeakReference<>(entity);
}
@ -85,11 +91,6 @@ public class BukkitEntity implements Entity {
}
}
@Override
public com.sk89q.worldedit.world.entity.EntityType getType() {
return EntityTypes.get(type.getName().toLowerCase(Locale.ROOT));
}
@Override
public BaseEntity getState() {
org.bukkit.entity.Entity entity = entityRef.get();

View File

@ -1,25 +0,0 @@
package com.sk89q.worldedit.bukkit;
import com.sk89q.worldedit.world.registry.EntityRegistry;
import org.bukkit.entity.EntityType;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
public class BukkitEntityRegistry implements EntityRegistry {
@Override
public Collection<String> registerEntities() {
List<String> types = new ArrayList<>();
for (EntityType type : EntityType.values()) {
String name = type.getName();
if (name != null) {
if (name.indexOf(':') == -1) {
name = "minecraft:" + name;
}
types.add(name);
}
}
return types;
}
}

View File

@ -45,6 +45,7 @@ class BukkitItemRegistry extends BundledItemRegistry {
return super.getRichName(itemStack);
}
//FAWE start
@Override
public Collection<String> values() {
ArrayList<String> values = new ArrayList<>();
@ -56,4 +57,5 @@ class BukkitItemRegistry extends BundledItemRegistry {
}
return values;
}
//FAWE end
}

View File

@ -76,7 +76,9 @@ public class BukkitPlayer extends AbstractPlayerActor {
private final Player player;
private final WorldEditPlugin plugin;
//FAWE start
private final PermissionAttachment permAttachment;
/**
* This constructs a new {@link BukkitPlayer} for the given {@link Player}.
*
@ -88,6 +90,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
this.player = player;
this.permAttachment = plugin.getPermissionAttachmentManager().getOrAddAttachment(player);
}
//FAWE end
/**
* This constructs a new {@link BukkitPlayer} for the given {@link Player}.
@ -98,12 +101,15 @@ public class BukkitPlayer extends AbstractPlayerActor {
public BukkitPlayer(@Nonnull WorldEditPlugin plugin, @Nullable Player player) {
this.plugin = plugin;
this.player = player;
//FAWE start
this.permAttachment = plugin.getPermissionAttachmentManager().getOrAddAttachment(player);
if (player != null && Settings.IMP.CLIPBOARD.USE_DISK) {
loadClipboardFromDisk();
}
//FAWE end
}
//FAWE start
private static Map<String, Object> getExistingMap(WorldEditPlugin plugin, Player player) {
BukkitPlayer cached = plugin.getCachedPlayer(player);
if (cached != null) {
@ -111,6 +117,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
}
return new ConcurrentHashMap<>();
}
//FAWE end
@Override
public UUID getUniqueId() {
@ -143,6 +150,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
return player.getDisplayName();
}
//FAWE start
@Override
public void giveItem(BaseItemStack itemStack) {
final PlayerInventory inv = player.getInventory();
@ -154,14 +162,13 @@ public class BukkitPlayer extends AbstractPlayerActor {
player.getInventory().setItemInMainHand(newItem);
HashMap<Integer, ItemStack> overflow = inv.addItem(item);
if (!overflow.isEmpty()) {
TaskManager.IMP.sync(new RunnableVal<Object>() {
TaskManager.IMP.sync(new RunnableVal<>() {
@Override
public void run(Object value) {
for (Map.Entry<Integer, ItemStack> entry : overflow.entrySet()) {
ItemStack stack = entry.getValue();
if (stack.getType() != Material.AIR && stack.getAmount() > 0) {
Item
dropped = player.getWorld().dropItem(player.getLocation(), stack);
Item dropped = player.getWorld().dropItem(player.getLocation(), stack);
PlayerDropItemEvent event = new PlayerDropItemEvent(player, dropped);
Bukkit.getPluginManager().callEvent(event);
if (event.isCancelled()) {
@ -174,7 +181,9 @@ public class BukkitPlayer extends AbstractPlayerActor {
}
player.updateInventory();
}
//FAWE end
@Deprecated
@Override
public void printRaw(String msg) {
for (String part : msg.split("\n")) {
@ -182,6 +191,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
}
}
@Deprecated
@Override
public void print(String msg) {
for (String part : msg.split("\n")) {
@ -189,6 +199,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
}
}
@Deprecated
@Override
public void printDebug(String msg) {
for (String part : msg.split("\n")) {
@ -196,6 +207,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
}
}
@Deprecated
@Override
public void printError(String msg) {
for (String part : msg.split("\n")) {
@ -205,12 +217,15 @@ public class BukkitPlayer extends AbstractPlayerActor {
@Override
public void print(Component component) {
//FAWE start - Add FAWE prefix to all messages
component = Caption.color(TranslatableComponent.of("prefix", component), getLocale());
//FAWE end
TextAdapter.sendMessage(player, WorldEditText.format(component, getLocale()));
}
@Override
public boolean trySetPosition(Vector3 pos, float pitch, float yaw) {
//FAWE start
org.bukkit.World world = player.getWorld();
if (pos instanceof com.sk89q.worldedit.util.Location) {
com.sk89q.worldedit.util.Location loc = (com.sk89q.worldedit.util.Location) pos;
@ -220,6 +235,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
}
}
org.bukkit.World finalWorld = world;
//FAWE end
return TaskManager.IMP.sync(() -> player.teleport(new Location(finalWorld, pos.getX(), pos.getY(), pos.getZ(), yaw, pitch)));
}
@ -250,6 +266,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
player.getWorld().getName(), player, perm);
}
//FAWE start
@Override
public void setPermission(String permission, boolean value) {
/*
@ -272,6 +289,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
permAttachment.setPermission(permission, value);
}
}
//FAWE end
@Override
public World getWorld() {
@ -331,9 +349,11 @@ public class BukkitPlayer extends AbstractPlayerActor {
@Override
public void sendAnnouncements() {
if (WorldEditPlugin.getInstance().getLifecycledBukkitImplAdapter() == null) {
//FAWE start - swap out EH download url with ours
print(Caption.of("worldedit.version.bukkit.unsupported-adapter",
TextComponent.of("https://intellectualsites.github.io/download/fawe.html", TextColor.AQUA)
.clickEvent(ClickEvent.openUrl("https://intellectualsites.github.io/download/fawe.html"))));
//FAWE end
}
}
@ -406,6 +426,7 @@ public class BukkitPlayer extends AbstractPlayerActor {
}
}
//FAWE start
@Override
public void sendTitle(Component title, Component sub) {
String titleStr = WorldEditText.reduceToText(title, getLocale());
@ -419,4 +440,5 @@ public class BukkitPlayer extends AbstractPlayerActor {
plugin.getPermissionAttachmentManager().removeAttachment(player);
super.unregister();
}
//FAWE end
}

View File

@ -31,7 +31,9 @@ import com.sk89q.worldedit.world.block.BlockState;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;
//FAWE start - implements SlottableBlockBag
public class BukkitPlayerBlockBag extends BlockBag implements SlottableBlockBag {
//FAWE end
private Player player;
private ItemStack[] items;
@ -182,6 +184,7 @@ public class BukkitPlayerBlockBag extends BlockBag implements SlottableBlockBag
public void addSingleSourcePosition(Location pos) {
}
//FAWE start
@Override
public BaseItem getItem(int slot) {
loadInventory();
@ -194,5 +197,6 @@ public class BukkitPlayerBlockBag extends BlockBag implements SlottableBlockBag
BaseItemStack stack = block instanceof BaseItemStack ? (BaseItemStack) block : new BaseItemStack(block.getType(), block.getNbtData(), 1);
items[slot] = BukkitAdapter.adapt(stack);
}
//FAWE end
}

View File

@ -36,7 +36,6 @@ class BukkitRegistries extends BundledRegistries {
private final BlockRegistry blockRegistry = new BukkitBlockRegistry();
private final BiomeRegistry biomeRegistry = new BukkitBiomeRegistry();
private final ItemRegistry itemRegistry = new BukkitItemRegistry();
private final EntityRegistry entityRegistry = new BukkitEntityRegistry();
private final BlockCategoryRegistry blockCategoryRegistry = new BukkitBlockCategoryRegistry();
private final ItemCategoryRegistry itemCategoryRegistry = new BukkitItemCategoryRegistry();
@ -71,11 +70,6 @@ class BukkitRegistries extends BundledRegistries {
return itemCategoryRegistry;
}
@Override
public EntityRegistry getEntityRegistry() {
return entityRegistry;
}
/**
* Get a static instance.
*

View File

@ -67,7 +67,9 @@ public class BukkitServerInterface extends AbstractPlatform implements MultiUser
public final WorldEditPlugin plugin;
private final CommandRegistration dynamicCommands;
private final Lifecycled<Watchdog> watchdog;
//FAWE start
private RelighterFactory relighterFactory;
//FAWE end
private boolean hookingEvents;
public BukkitServerInterface(WorldEditPlugin plugin, Server server) {
@ -247,15 +249,6 @@ public class BukkitServerInterface extends AbstractPlatform implements MultiUser
return SUPPORTED_SIDE_EFFECTS;
}
@Override
public @NotNull RelighterFactory getRelighterFactory() {
if (this.relighterFactory == null) {
this.relighterFactory = this.plugin.getBukkitImplAdapter().getRelighterFactory();
LOGGER.info("Using " + this.relighterFactory.getClass().getCanonicalName() + " as relighter factory.");
}
return this.relighterFactory;
}
public void unregisterCommands() {
dynamicCommands.unregisterCommands();
}
@ -268,4 +261,15 @@ public class BukkitServerInterface extends AbstractPlatform implements MultiUser
}
return users;
}
//FAWE start
@Override
public @NotNull RelighterFactory getRelighterFactory() {
if (this.relighterFactory == null) {
this.relighterFactory = this.plugin.getBukkitImplAdapter().getRelighterFactory();
LOGGER.info("Using " + this.relighterFactory.getClass().getCanonicalName() + " as relighter factory.");
}
return this.relighterFactory;
}
//FAWE end
}

View File

@ -19,6 +19,7 @@
package com.sk89q.worldedit.bukkit;
import com.fastasyncworldedit.bukkit.util.WorldUnloadedException;
import com.fastasyncworldedit.core.Fawe;
import com.fastasyncworldedit.core.beta.IChunkGet;
import com.fastasyncworldedit.core.beta.implementation.packet.ChunkPacket;
@ -109,7 +110,9 @@ public class BukkitWorld extends AbstractWorld {
}
private WeakReference<World> worldRef;
//FAWE start
private final String worldNameRef;
//FAWE end
private final WorldNativeAccess<?, ?, ?> worldNativeAccess;
/**
@ -119,7 +122,9 @@ public class BukkitWorld extends AbstractWorld {
*/
public BukkitWorld(World world) {
this.worldRef = new WeakReference<>(world);
//FAWE start
this.worldNameRef = world.getName();
//FAWE end
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
this.worldNativeAccess = adapter.createWorldNativeAccess(world);
@ -151,7 +156,7 @@ public class BukkitWorld extends AbstractWorld {
return list;
}
//createEntity was moved to IChunkExtent to prevent issues with Async Entity Add.
//FAWE: createEntity was moved to IChunkExtent to prevent issues with Async Entity Add.
/**
* Get the world handle.
@ -159,6 +164,7 @@ public class BukkitWorld extends AbstractWorld {
* @return the world
*/
public World getWorld() {
//FAWE start
World tmp = worldRef.get();
if (tmp == null) {
tmp = Bukkit.getWorld(worldNameRef);
@ -166,9 +172,11 @@ public class BukkitWorld extends AbstractWorld {
worldRef = new WeakReference<>(tmp);
}
}
//FAWE end
return checkNotNull(tmp, "The world was unloaded and the reference is unavailable");
}
//FAWE start
/**
* Get the world handle.
*
@ -181,6 +189,7 @@ public class BukkitWorld extends AbstractWorld {
}
return world;
}
//FAWE end
@Override
public String getName() {
@ -218,7 +227,7 @@ public class BukkitWorld extends AbstractWorld {
if (adapter != null) {
return adapter.regenerate(getWorld(), region, extent, options);
} else {
throw new UnsupportedOperationException("Missing BukkitImplAdapater for this version.");
throw new UnsupportedOperationException("Missing BukkitImplAdapter for this version.");
}
} catch (Exception e) {
LOGGER.warn("Regeneration via adapter failed.", e);
@ -303,7 +312,9 @@ public class BukkitWorld extends AbstractWorld {
if (treeTypeMapping.get(type) == null) {
LOGGER.error("No TreeType mapping for TreeGenerator.TreeType." + type);
// FAWE start
LOGGER.warn("Your FAWE version is newer than " + Bukkit.getVersion() + " and contains features of future minecraft versions which do not exist in " + Bukkit.getVersion() + ", hence the tree type " + type + " is not available.");
LOGGER.warn("Your FAWE version is newer than " + Bukkit.getVersion() +
" and contains features of future minecraft versions which do not exist in "
+ Bukkit.getVersion() + ", hence the tree type " + type + " is not available.");
// FAWE end
}
}
@ -333,6 +344,7 @@ public class BukkitWorld extends AbstractWorld {
@Override
public void checkLoadedChunk(BlockVector3 pt) {
World world = getWorld();
//FAWE start
int X = pt.getBlockX() >> 4;
int Z = pt.getBlockZ() >> 4;
if (Fawe.isMainThread()) {
@ -340,6 +352,7 @@ public class BukkitWorld extends AbstractWorld {
} else {
PaperLib.getChunkAtAsync(world, X, Z, true);
}
//FAWE end
}
@Override
@ -455,6 +468,16 @@ public class BukkitWorld extends AbstractWorld {
getWorld().getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()).breakNaturally();
}
@Override
public boolean canPlaceAt(BlockVector3 position, com.sk89q.worldedit.world.block.BlockState blockState) {
BukkitImplAdapter adapter = WorldEditPlugin.getInstance().getBukkitImplAdapter();
if (adapter != null) {
return adapter.canPlaceAt(getWorld(), position, blockState);
}
// We can't check, so assume yes.
return true;
}
private static volatile boolean hasWarnedImplError = false;
@Override
@ -554,6 +577,8 @@ public class BukkitWorld extends AbstractWorld {
return true;
}
//FAWE start
@Override
public <T extends BlockStateHolder<T>> boolean setBlock(int x, int y, int z, T block)
throws WorldEditException {
@ -592,4 +617,5 @@ public class BukkitWorld extends AbstractWorld {
worldNativeAccess.flush();
}
}
//FAWE end
}

View File

@ -25,6 +25,7 @@ import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.event.platform.SessionIdleEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.World;
import org.bukkit.block.Block;
@ -107,13 +108,14 @@ public class WorldEditListener implements Listener {
final Player player = plugin.wrapPlayer(event.getPlayer());
final World world = player.getWorld();
final WorldEdit we = plugin.getWorldEdit();
final Direction direction = BukkitAdapter.adapt(event.getBlockFace());
Action action = event.getAction();
if (action == Action.LEFT_CLICK_BLOCK) {
final Block clickedBlock = event.getClickedBlock();
final Location pos = new Location(world, clickedBlock.getX(), clickedBlock.getY(), clickedBlock.getZ());
if (we.handleBlockLeftClick(player, pos)) {
if (we.handleBlockLeftClick(player, pos, direction)) {
event.setCancelled(true);
}
@ -131,7 +133,7 @@ public class WorldEditListener implements Listener {
final Block clickedBlock = event.getClickedBlock();
final Location pos = new Location(world, clickedBlock.getX(), clickedBlock.getY(), clickedBlock.getZ());
if (we.handleBlockRightClick(player, pos)) {
if (we.handleBlockRightClick(player, pos, direction)) {
event.setCancelled(true);
}

View File

@ -23,6 +23,8 @@ import com.fastasyncworldedit.bukkit.BukkitPermissionAttachmentManager;
import com.fastasyncworldedit.bukkit.FaweBukkit;
import com.fastasyncworldedit.core.Fawe;
import com.google.common.base.Joiner;
import com.google.common.collect.ImmutableList;
import com.sk89q.bukkit.util.ClassSourceValidator;
import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.wepif.PermissionsResolverManager;
import com.sk89q.worldedit.EditSession;
@ -45,6 +47,7 @@ import com.sk89q.worldedit.internal.command.CommandUtil;
import com.sk89q.worldedit.internal.util.LogManagerCompat;
import com.sk89q.worldedit.util.lifecycle.Lifecycled;
import com.sk89q.worldedit.util.lifecycle.SimpleLifecycled;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockCategory;
import com.sk89q.worldedit.world.entity.EntityType;
@ -70,6 +73,7 @@ import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.java.JavaPlugin;
import org.enginehub.piston.CommandManager;
import org.incendo.serverlib.ServerLib;
import java.io.File;
@ -90,7 +94,9 @@ import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAM
/**
* Plugin for Bukkit.
*/
public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
//FAWE start - Don't implement TabCompleter, we use Paper's AsyncTabCompleteListener
public class WorldEditPlugin extends JavaPlugin {
//FAWE end
private static final Logger LOGGER = LogManagerCompat.getLogger();
public static final String CUI_PLUGIN_CHANNEL = "worldedit:cui";
@ -129,17 +135,24 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
platform = new BukkitServerInterface(this, getServer());
worldEdit.getPlatformManager().register(platform);
createDefaultConfiguration("config-legacy.yml"); // Create the default configuration file for WorldEdit, for it's config-legacy.yml
//FAWE start - Rename config to config-legacy.yml TODO: Chose a better name in the future
createDefaultConfiguration("config-legacy.yml"); // Create the default configuration file for WorldEdit, for us it's 'config-legacy.yml'
//FAWE end
//FAWE start - Modify WorldEdit config name
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "config-legacy.yml"), true), this);
//FAWE end
//FAWE start - Setup permission attachments
permissionAttachmentManager = new BukkitPermissionAttachmentManager(this);
//FAWE end
Path delChunks = Paths.get(getDataFolder().getPath(), DELCHUNKS_FILE_NAME);
if (Files.exists(delChunks)) {
ChunkDeleter.runFromFile(delChunks, true);
}
//FAWE start - Delete obsolete DummyFawe from pre 1.14 days
if (this.getDataFolder().getParentFile().listFiles(file -> {
if (file.getName().equals("DummyFawe.jar")) {
file.delete();
@ -149,6 +162,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
}).length > 0) {
LOGGER.warn("DummyFawe detected and automatically deleted! This file is no longer necessary.");
}
//FAWE end
}
/**
@ -157,17 +171,22 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
@Override
public void onEnable() {
// Catch bad things being done by naughty plugins that include
// WorldEdit's classes
ClassSourceValidator verifier = new ClassSourceValidator(this);
verifier.reportMismatches(ImmutableList.of(World.class, CommandManager.class, EditSession.class, Actor.class));
//FAWE start
new FaweBukkit(this);
//FAWE end
WorldEdit.getInstance().getEventBus().post(new PlatformsRegisteredEvent());
PermissionsResolverManager.initialize(this); // Setup permission resolver
// Register CUI
fail(() -> {
getServer().getMessenger().registerIncomingPluginChannel(this, CUI_PLUGIN_CHANNEL, new CUIChannelListener(this));
getServer().getMessenger().registerOutgoingPluginChannel(this, CUI_PLUGIN_CHANNEL);
}, "Failed to register CUI");
// Now we can register events
getServer().getPluginManager().registerEvents(new WorldEditListener(this), this);
@ -182,8 +201,10 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
// register this so we can load world-dependent data right as the first world is loading
getServer().getPluginManager().registerEvents(new WorldInitListener(), this);
} else {
//FAWE start
LOGGER.warn("Server reload detected. This may cause various issues with FastAsyncWorldEdit and dependent plugins. Reloading the server is not advised.");
LOGGER.warn("For more information why reloading is bad, see https://madelinemiller.dev/blog/problem-with-reload/");
//FAWE end
try {
setupPreWorldData();
// since worlds are loaded already, we can do this now
@ -192,7 +213,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
}
}
// Setup metrics
// Enable metrics
new Metrics(this, BSTATS_ID);
// Check whether the server runs on 11 or greater
@ -281,15 +302,6 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
}
}
private void fail(Runnable run, String message) {
try {
run.run();
} catch (Throwable e) {
getLogger().severe(message);
e.printStackTrace();
}
}
private void loadAdapter() {
WorldEdit worldEdit = WorldEdit.getInstance();
@ -315,9 +327,11 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
if (platform instanceof BukkitServerInterface) {
LOGGER.warn(e.getMessage());
} else {
//FAWE start - Identify as FAWE
LOGGER.info("FastAsyncWorldEdit could not find a Bukkit adapter for this MC version, "
+ "but it seems that you have another implementation of FastAsyncWorldEdit installed (" + platform.getPlatformName() + ") "
+ "that handles the world editing.");
//FAWE end
}
this.adapter.invalidate();
}
@ -398,25 +412,6 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
return true;
}
/*
@Override
public List<String> onTabComplete(CommandSender sender, Command cmd, String commandLabel, String[] args) {
int plSep = commandLabel.indexOf(":");
if (plSep >= 0 && plSep < commandLabel.length() + 1) {
commandLabel = commandLabel.substring(plSep + 1);
}
StringBuilder sb = new StringBuilder("/").append(commandLabel);
if (args.length > 0) {
sb.append(" ");
}
String arguments = Joiner.on(" ").appendTo(sb, args).toString();
CommandSuggestionEvent event = new CommandSuggestionEvent(wrapCommandSender(sender), arguments);
getWorldEdit().getEventBus().post(event);
return CommandUtil.fixSuggestions(arguments, event.getSuggestions());
}
*/
/**
* Gets the session for the player.
*
@ -456,7 +451,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
LocalSession session = WorldEdit.getInstance().getSessionManager().get(wePlayer);
session.remember(editSession);
editSession.flushSession();
editSession.close();
WorldEdit.getInstance().flushBlockBag(wePlayer, editSession);
}
@ -479,14 +474,16 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
return PermissionsResolverManager.getInstance();
}
//FAWE start
/**
* Get the permissions resolver in use.
* Get the permissions attachment manager in use
*
* @return the permissions resolver
* @return the permissions attachment manager
*/
public BukkitPermissionAttachmentManager getPermissionAttachmentManager() {
return permissionAttachmentManager;
}
//FAWE end
/**
* Used to wrap a Bukkit Player as a WorldEdit Player.
@ -495,6 +492,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
* @return a wrapped player
*/
public BukkitPlayer wrapPlayer(Player player) {
//FAWE start - Use cache over returning a direct BukkitPlayer
BukkitPlayer wePlayer = getCachedPlayer(player);
if (wePlayer == null) {
synchronized (player) {
@ -507,8 +505,10 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
}
}
return wePlayer;
//FAWE end
}
//FAWE start
public BukkitPlayer getCachedPlayer(Player player) {
List<MetadataValue> meta = player.getMetadata("WE");
if (meta.isEmpty()) {
@ -516,6 +516,7 @@ public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
}
return (BukkitPlayer) meta.get(0).value();
}
//FAWE end
public Actor wrapCommandSender(CommandSender sender) {
if (sender instanceof Player) {

View File

@ -67,7 +67,9 @@ import javax.annotation.Nullable;
/**
* An interface for adapters of various Bukkit implementations.
*/
// FAWE start - Generic & extends IBukkitAdapter
public interface BukkitImplAdapter<T> extends IBukkitAdapter {
// FAWE end
/**
* Get a data fixer, or null if not supported.
@ -189,6 +191,16 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
return false;
}
/**
* Gets whether the given {@link BlockState} can be placed here.
*
* @param world The world
* @param position The position
* @param blockState The blockstate
* @return If it can be placed
*/
boolean canPlaceAt(World world, BlockVector3 position, BlockState blockState);
/**
* Create a Bukkit ItemStack with NBT, if available.
*
@ -213,8 +225,10 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
Set<SideEffect> getSupportedSideEffects();
default OptionalInt getInternalBlockStateId(BlockData data) {
// FAWE start
// return OptionalInt.empty();
return getInternalBlockStateId(BukkitAdapter.adapt(data));
// FAWE end
}
/**
@ -227,8 +241,19 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
return OptionalInt.empty();
}
/**
* Regenerate a region in the given world, so it appears "as new".
* @param world the world to regen in
* @param region the region to regen
* @param extent the extent to use for setting blocks
* @param options the regeneration options
* @return true on success, false on failure
*/
default boolean regenerate(World world, Region region, Extent extent, RegenOptions options) throws Exception {
throw new UnsupportedOperationException("This adapter does not support regeneration.");
}
// FAWE ADDITIONS
// FAWE start
default BlockMaterial getMaterial(BlockType blockType) {
return getMaterial(blockType.getDefaultState());
}
@ -270,18 +295,6 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
throw new UnsupportedOperationException("Cannot send fake chunks");
}
/**
* Regenerate a region in the given world, so it appears "as new".
* @param world the world to regen in
* @param region the region to regen
* @param extent the extent to use for setting blocks
* @param options the regeneration options
* @return true on success, false on failure
*/
default boolean regenerate(World world, Region region, Extent extent, RegenOptions options) throws Exception{
throw new UnsupportedOperationException("This adapter does not support regeneration.");
}
default IChunkGet get(World world, int chunkX, int chunkZ) {
throw new UnsupportedOperationException();
}
@ -293,4 +306,5 @@ public interface BukkitImplAdapter<T> extends IBukkitAdapter {
default RelighterFactory getRelighterFactory() {
return new NMSRelighterFactory(); // TODO implement in adapters instead
}
// FAWE end
}

View File

@ -47,6 +47,7 @@ public class BukkitImplLoader {
private static final String CLASS_SUFFIX = ".class";
private static final String LOAD_ERROR_MESSAGE =
//FAWE start - exchange WorldEdit to FAWE & suggest to update Fawe & the server software
"\n**********************************************\n"
+ "** This FastAsyncWorldEdit version does not fully support your version of Bukkit.\n"
+ "** You can fix this by:\n"
@ -55,6 +56,7 @@ public class BukkitImplLoader {
+ "** will be blank, and so on. There will be no support for entity\n"
+ "** and block property-related functions.\n"
+ "**********************************************\n";
//FAWE end
/**
* Create a new instance.

View File

@ -213,6 +213,17 @@ public interface World extends Extent, Keyed, IChunkCache<IChunkGet> {
*/
void simulateBlockMine(BlockVector3 position);
/**
* Gets whether the given {@link BlockState} can be placed here.
*
* @param position The position
* @param blockState The blockstate
* @return If it can be placed
*/
default boolean canPlaceAt(BlockVector3 position, BlockState blockState) {
return true;
}
/**
* Regenerate an area.
*