Plex-FAWE/worldedit-bukkit/src/main/java/com/sk89q/worldedit/bukkit/WorldEditPlugin.java

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

698 lines
26 KiB
Java
Raw Normal View History

/*
2014-04-04 22:03:18 +00:00
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
2014-04-04 22:03:18 +00:00
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
2014-04-04 22:03:18 +00:00
* 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 Lesser General Public License
* for more details.
*
2014-04-04 22:03:18 +00:00
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
2014-04-04 22:03:18 +00:00
*/
package com.sk89q.worldedit.bukkit;
import com.boydti.fawe.Fawe;
import com.boydti.fawe.bukkit.FaweBukkit;
2020-08-14 09:59:49 +00:00
import com.boydti.fawe.config.Settings;
import com.boydti.fawe.util.MainUtil;
import com.google.common.base.Joiner;
import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.wepif.PermissionsResolverManager;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.bukkit.adapter.AdapterLoadException;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplAdapter;
import com.sk89q.worldedit.bukkit.adapter.BukkitImplLoader;
2020-08-14 09:59:49 +00:00
import com.sk89q.worldedit.bukkit.adapter.impl.FAWE_Spigot_v1_14_R4;
import com.sk89q.worldedit.bukkit.adapter.impl.FAWE_Spigot_v1_15_R2;
import com.sk89q.worldedit.bukkit.adapter.impl.FAWE_Spigot_v1_16_R2;
import com.sk89q.worldedit.event.platform.CommandEvent;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.extent.inventory.BlockBag;
2020-01-31 22:44:50 +00:00
import com.sk89q.worldedit.internal.anvil.ChunkDeleter;
2020-08-14 09:59:49 +00:00
import com.sk89q.worldedit.internal.command.CommandUtil;
2019-04-05 04:15:10 +00:00
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockCategory;
2019-04-05 04:15:10 +00:00
import com.sk89q.worldedit.world.entity.EntityType;
2019-08-26 04:45:03 +00:00
import com.sk89q.worldedit.world.gamemode.GameModes;
import com.sk89q.worldedit.world.item.ItemCategory;
2019-08-26 04:45:03 +00:00
import com.sk89q.worldedit.world.weather.WeatherTypes;
import io.papermc.lib.PaperLib;
import org.bstats.bukkit.Metrics;
import org.bukkit.Bukkit;
import org.bukkit.Material;
import org.bukkit.Tag;
2019-04-05 04:15:10 +00:00
import org.bukkit.block.Biome;
2019-08-18 01:09:09 +00:00
import org.bukkit.command.BlockCommandSender;
import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.world.WorldInitEvent;
2019-10-23 04:23:52 +00:00
import org.bukkit.metadata.FixedMetadataValue;
import org.bukkit.metadata.MetadataValue;
2019-04-02 22:21:02 +00:00
import org.bukkit.plugin.Plugin;
import org.bukkit.plugin.PluginDescriptionFile;
2019-04-05 06:51:42 +00:00
import org.bukkit.plugin.PluginManager;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.plugin.java.JavaPluginLoader;
2019-06-06 22:39:51 +00:00
import org.jetbrains.annotations.NotNull;
2020-08-14 09:59:49 +00:00
import org.jetbrains.annotations.Nullable;
2019-03-14 02:51:48 +00:00
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
2020-01-31 22:44:50 +00:00
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
2020-08-14 09:59:49 +00:00
import java.lang.reflect.Field;
2020-01-31 22:44:50 +00:00
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
2020-08-14 09:59:49 +00:00
import java.util.ArrayList;
2020-01-31 22:44:50 +00:00
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
2020-08-14 09:59:49 +00:00
import java.util.concurrent.ConcurrentHashMap;
2020-01-31 22:44:50 +00:00
import java.util.logging.Level;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAME;
/**
* Plugin for Bukkit.
*/
2019-04-02 22:21:02 +00:00
public class WorldEditPlugin extends JavaPlugin { //implements TabCompleter
2019-03-14 02:51:48 +00:00
private static final Logger log = LoggerFactory.getLogger(WorldEditPlugin.class);
2018-08-14 02:07:11 +00:00
public static final String CUI_PLUGIN_CHANNEL = "worldedit:cui";
private static WorldEditPlugin INSTANCE;
2020-01-31 22:44:50 +00:00
///The BSTATS_ID needs to be modified for FAWE to prevent contaminating WorldEdit stats
2020-02-05 21:27:50 +00:00
private static final int BSTATS_PLUGIN_ID = 1403;
private BukkitImplAdapter bukkitAdapter;
private BukkitServerInterface server;
private BukkitConfiguration config;
private static Map<String, Plugin> lookupNames;
2020-08-14 09:59:49 +00:00
2019-04-04 14:24:47 +00:00
static {
// Disable AWE as otherwise both fail to load
PluginManager manager = Bukkit.getPluginManager();
try {
Field pluginsField = manager.getClass().getDeclaredField("plugins");
Field lookupNamesField = manager.getClass().getDeclaredField("lookupNames");
pluginsField.setAccessible(true);
lookupNamesField.setAccessible(true);
List<Plugin> plugins = (List<Plugin>) pluginsField.get(manager);
lookupNames = (Map<String, Plugin>) lookupNamesField.get(manager);
pluginsField.set(manager, new ArrayList<Plugin>(plugins) {
@Override
public boolean add(Plugin plugin) {
if (plugin.getName().startsWith("AsyncWorldEdit")) {
2019-11-11 21:02:28 +00:00
log.debug("Disabling `" + plugin.getName() + "` as it is incompatible");
} else {
return super.add(plugin);
2019-04-04 14:24:47 +00:00
}
return false;
}
});
lookupNamesField.set(manager, lookupNames = new ConcurrentHashMap<String, Plugin>(lookupNames) {
@Override
public Plugin put(@NotNull String key, @NotNull Plugin plugin) {
2020-01-31 22:44:50 +00:00
if (plugin.getName().startsWith("AsyncWorldEdit")) {
return null;
2019-04-04 14:24:47 +00:00
}
return super.put(key, plugin);
}
});
2020-08-14 09:59:49 +00:00
} catch (Throwable ignored) {
}
2019-04-04 14:24:47 +00:00
}
public WorldEditPlugin() {
init();
}
public WorldEditPlugin(JavaPluginLoader loader, PluginDescriptionFile desc, File dataFolder, File jarFile) {
2018-08-17 08:27:48 +00:00
super(loader, desc, dataFolder, jarFile);
init();
}
private void init() {
if (lookupNames != null) {
2019-07-18 06:56:57 +00:00
lookupNames.putIfAbsent("FastAsyncWorldEdit".toLowerCase(Locale.ROOT), this);
lookupNames.putIfAbsent("WorldEdit".toLowerCase(Locale.ROOT), this);
2018-08-16 17:30:55 +00:00
lookupNames.putIfAbsent("FastAsyncWorldEdit", this);
lookupNames.putIfAbsent("WorldEdit", this);
rename();
}
setEnabled(true);
}
@Override
public void onLoad() {
2020-08-14 09:59:49 +00:00
if (INSTANCE != null) {
return;
}
rename();
2019-06-06 22:39:51 +00:00
INSTANCE = this;
FaweBukkit imp = new FaweBukkit(this);
2014-07-29 18:04:04 +00:00
//noinspection ResultOfMethodCallIgnored
getDataFolder().mkdirs();
WorldEdit worldEdit = WorldEdit.getInstance();
// Setup platform
server = new BukkitServerInterface(this, getServer());
worldEdit.getPlatformManager().register(server);
Path delChunks = Paths.get(getDataFolder().getPath(), DELCHUNKS_FILE_NAME);
if (Files.exists(delChunks)) {
ChunkDeleter.runFromFile(delChunks, true);
}
2020-08-14 09:59:49 +00:00
fail(() -> PermissionsResolverManager.initialize(INSTANCE), "Failed to initialize permissions resolver");
}
/**
* Called on plugin enable.
*/
@Override
public void onEnable() {
2020-08-14 09:59:49 +00:00
if (INSTANCE != null) {
return;
}
2019-04-05 04:15:10 +00:00
onLoad();
PermissionsResolverManager.initialize(this); // Setup permission resolver
// Register CUI
fail(() -> {
2020-08-14 09:59:49 +00:00
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);
// register async tab complete, if available
if (PaperLib.isPaper()) {
getServer().getPluginManager().registerEvents(new AsyncTabCompleteListener(), this);
}
initializeRegistries(); // this creates the objects matching Bukkit's enums - but doesn't fill them with data yet
if (Bukkit.getWorlds().isEmpty()) {
setupPreWorldData();
// register this so we can load world-dependent data right as the first world is loading
getServer().getPluginManager().registerEvents(new WorldInitListener(), this);
} else {
getLogger().warning("Server reload detected. This may cause various issues with WorldEdit and dependent plugins.");
try {
setupPreWorldData();
// since worlds are loaded already, we can do this now
setupWorldData();
} catch (Throwable ignored) {
}
}
2020-08-14 09:59:49 +00:00
// Setup metrics
if (Settings.IMP.ENABLED_COMPONENTS.BSTATS) {
new Metrics(this, BSTATS_PLUGIN_ID);
} else {
getLogger().warning("bStats is disabled. Please enable it in /plugins/FastAsyncWorldEdit/config.yml. It helps the developers to identify the features most used");
getLogger().warning("and organize future updates better. Cheers.");
}
// Suggest PaperMC
PaperLib.suggestPaper(this);
}
private void setupPreWorldData() {
loadAdapter();
loadConfig();
WorldEdit.getInstance().loadMappings();
}
private void setupWorldData() {
setupTags(); // datapacks aren't loaded until just before the world is, and bukkit has no event for this
// so the earliest we can do this is in WorldInit
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
}
private void initializeRegistries() {
2019-04-05 04:15:10 +00:00
// Biome
for (Biome biome : Biome.values()) {
String lowerCaseBiomeName = biome.name().toLowerCase(Locale.ROOT);
2020-08-14 09:59:49 +00:00
BiomeType biomeType = BiomeType.REGISTRY.register(
"minecraft:" + lowerCaseBiomeName, new BiomeType("minecraft:" + lowerCaseBiomeName));
if (bukkitAdapter != null) {
biomeType.setLegacyId(bukkitAdapter.getInternalBiomeId(biomeType));
}
2019-04-05 04:15:10 +00:00
}
2020-02-05 21:27:50 +00:00
// Block & Item
/*for (Material material : Material.values()) {
2019-06-06 22:39:51 +00:00
if (material.isBlock() && !material.isLegacy()) {
BlockType.REGISTRY.register(material.getKey().toString(), new BlockType(material.getKey().toString(), blockState -> {
// TODO Use something way less hacky than this.
ParserContext context = new ParserContext();
context.setPreferringWildcard(true);
context.setTryLegacy(false);
context.setRestricted(false);
try {
FuzzyBlockState state = (FuzzyBlockState) WorldEdit.getInstance().getBlockFactory().parseFromInput(
BukkitAdapter.adapt(blockState.getBlockType()).createBlockData().getAsString(), context
).toImmutableState();
BlockState defaultState = blockState.getBlockType().getAllStates().get(0);
for (Map.Entry<Property<?>, Object> propertyObjectEntry : state.getStates().entrySet()) {
//noinspection unchecked
defaultState = defaultState.with((Property<Object>) propertyObjectEntry.getKey(), propertyObjectEntry.getValue());
2019-06-06 22:39:51 +00:00
}
return defaultState;
} catch (InputParseException e) {
getLogger().log(Level.WARNING, "Error loading block state for " + material.getKey(), e);
2019-06-06 22:39:51 +00:00
return blockState;
}
}));
}
2019-04-05 04:15:10 +00:00
if (material.isItem() && !material.isLegacy()) {
ItemType.REGISTRY.register(material.getKey().toString(), new ItemType(material.getKey().toString()));
}
}
2019-11-19 04:40:40 +00:00
*/
2019-04-05 04:15:10 +00:00
// Entity
for (org.bukkit.entity.EntityType entityType : org.bukkit.entity.EntityType.values()) {
String mcid = entityType.getName();
if (mcid != null) {
String lowerCaseMcId = mcid.toLowerCase(Locale.ROOT);
EntityType.REGISTRY.register("minecraft:" + lowerCaseMcId, new EntityType("minecraft:" + lowerCaseMcId));
2019-04-05 04:15:10 +00:00
}
}
2019-08-26 04:45:03 +00:00
// ... :|
GameModes.get("");
WeatherTypes.get("");
2019-04-05 04:15:10 +00:00
}
private void setupTags() {
// Tags
try {
for (Tag<Material> blockTag : Bukkit.getTags(Tag.REGISTRY_BLOCKS, Material.class)) {
BlockCategory.REGISTRY.register(blockTag.getKey().toString(), new BlockCategory(blockTag.getKey().toString()));
}
for (Tag<Material> itemTag : Bukkit.getTags(Tag.REGISTRY_ITEMS, Material.class)) {
ItemCategory.REGISTRY.register(itemTag.getKey().toString(), new ItemCategory(itemTag.getKey().toString()));
}
} catch (NoSuchMethodError ignored) {
getLogger().warning("The version of Spigot/Paper you are using doesn't support Tags. The usage of tags with WorldEdit will not work until you update.");
}
}
private void rename() {
File dir = new File(getDataFolder().getParentFile(), "FastAsyncWorldEdit");
2019-06-06 22:39:51 +00:00
try {
Field descriptionField = JavaPlugin.class.getDeclaredField("dataFolder");
descriptionField.setAccessible(true);
descriptionField.set(this, dir);
2019-10-23 04:23:52 +00:00
} catch (Throwable e) {
e.printStackTrace();
2019-06-06 22:39:51 +00:00
}
2019-10-23 04:23:52 +00:00
try {
File pluginsFolder = MainUtil.getJarFile().getParentFile();
for (File file : pluginsFolder.listFiles()) {
2020-08-14 09:59:49 +00:00
if (file.length() == 2052) {
return;
}
2019-10-23 04:23:52 +00:00
}
Plugin plugin = Bukkit.getPluginManager().getPlugin("FastAsyncWorldEdit");
File dummy = MainUtil.copyFile(MainUtil.getJarFile(), "DummyFawe.src", pluginsFolder, "DummyFawe.jar");
if (dummy != null && dummy.exists() && plugin == this) {
try {
Bukkit.getPluginManager().loadPlugin(dummy);
} catch (Throwable e) {
if (Bukkit.getUpdateFolderFile().mkdirs()) {
MainUtil.copyFile(MainUtil.getJarFile(), "DummyFawe.src", pluginsFolder, Bukkit.getUpdateFolder() + File.separator + "DummyFawe.jar");
} else {
getLogger().info("Please delete DummyFawe.jar and restart");
}
2019-08-29 12:57:03 +00:00
}
2019-10-23 04:23:52 +00:00
getLogger().info("Please restart the server if you have any plugins which depend on FAWE.");
} else if (dummy == null) {
MainUtil.copyFile(MainUtil.getJarFile(), "DummyFawe.src", pluginsFolder, "update" + File.separator + "DummyFawe.jar");
2018-08-21 18:18:10 +00:00
}
2019-10-23 04:23:52 +00:00
} catch (Throwable e) {
e.printStackTrace();
}
}
private void fail(Runnable run, String message) {
try {
run.run();
} catch (Throwable e) {
2019-04-02 22:21:02 +00:00
getLogger().severe(message);
e.printStackTrace();
}
}
private void loadConfig() {
createDefaultConfiguration("config-legacy.yml"); // Create the default configuration file
2019-09-19 18:56:03 +00:00
config = new BukkitConfiguration(new YAMLProcessor(new File(getDataFolder(), "config-legacy.yml"), true), this);
config.load();
// Create schematics folder
WorldEdit worldEdit = WorldEdit.getInstance();
File dir = worldEdit.getWorkingDirectoryFile(worldEdit.getConfiguration().saveDir);
dir.mkdirs();
}
private void loadAdapter() {
WorldEdit worldEdit = WorldEdit.getInstance();
// Attempt to load a Bukkit adapter
BukkitImplLoader adapterLoader = new BukkitImplLoader();
2018-08-27 16:56:28 +00:00
try {
2019-11-19 04:40:40 +00:00
adapterLoader.addClass(FAWE_Spigot_v1_14_R4.class);
adapterLoader.addClass(FAWE_Spigot_v1_15_R2.class);
adapterLoader.addClass(FAWE_Spigot_v1_16_R2.class);
2019-04-02 22:21:02 +00:00
} catch (Throwable throwable) {
throwable.printStackTrace();
2018-08-27 16:56:28 +00:00
}
try {
adapterLoader.addFromPath(getClass().getClassLoader());
} catch (IOException e) {
2019-03-14 02:51:48 +00:00
log.warn("Failed to search path for Bukkit adapters");
}
try {
adapterLoader.addFromJar(getFile());
} catch (IOException e) {
2019-03-14 02:51:48 +00:00
log.warn("Failed to search " + getFile() + " for Bukkit adapters", e);
}
try {
bukkitAdapter = adapterLoader.loadAdapter();
2019-03-14 02:51:48 +00:00
log.info("Using " + bukkitAdapter.getClass().getCanonicalName() + " as the Bukkit adapter");
} catch (AdapterLoadException e) {
2019-04-02 22:21:02 +00:00
Platform platform = worldEdit.getPlatformManager().queryCapability(Capability.WORLD_EDITING);
if (platform instanceof BukkitServerInterface) {
log.warn(e.getMessage());
} else {
2020-08-14 09:59:49 +00:00
log.info("WorldEdit could not find a Bukkit adapter for this MC version, "
+ "but it seems that you have another implementation of WorldEdit installed (" + platform.getPlatformName() + ") "
+ "that handles the world editing.");
2019-04-02 22:21:02 +00:00
}
}
}
/**
* Called on plugin disable.
*/
@Override
public void onDisable() {
Fawe.get().onDisable();
WorldEdit worldEdit = WorldEdit.getInstance();
worldEdit.getSessionManager().unload();
worldEdit.getPlatformManager().unregister(server);
if (config != null) {
config.unload();
}
if (server != null) {
server.unregisterCommands();
}
this.getServer().getScheduler().cancelTasks(this);
}
/**
* Loads and reloads all configuration.
*/
protected void loadConfiguration() {
config.unload();
config.load();
getPermissionsResolver().load();
}
/**
* Create a default configuration file from the .jar.
*
* @param name the filename
*/
protected void createDefaultConfiguration(String name) {
File actual = new File(getDataFolder(), name);
if (!actual.exists()) {
2020-03-11 05:35:37 +00:00
try (InputStream stream = getResource("defaults/" + name)) {
2020-08-14 09:59:49 +00:00
if (stream == null) {
throw new FileNotFoundException();
}
2020-03-11 05:35:37 +00:00
copyDefaultConfig(stream, actual, name);
} catch (IOException e) {
getLogger().severe("Unable to read default configuration: " + name);
}
2018-12-27 00:50:24 +00:00
}
}
2018-12-27 00:50:24 +00:00
private void copyDefaultConfig(InputStream input, File actual, String name) {
try (FileOutputStream output = new FileOutputStream(actual)) {
byte[] buf = new byte[8192];
int length;
while ((length = input.read(buf)) > 0) {
output.write(buf, 0, length);
}
2018-12-27 00:50:24 +00:00
getLogger().info("Default configuration file written: " + name);
} catch (IOException e) {
getLogger().log(Level.WARNING, "Failed to write default config file", e);
}
}
@Override
public boolean onCommand(CommandSender sender, Command cmd, String commandLabel, String[] args) {
// Add the command to the array because the underlying command handling
// code of WorldEdit expects it
String[] split = new String[args.length + 1];
System.arraycopy(args, 0, split, 1, args.length);
split[0] = commandLabel;
CommandEvent event = new CommandEvent(wrapCommandSender(sender), Joiner.on(" ").join(split));
getWorldEdit().getEventBus().post(event);
return true;
}
2020-01-31 22:44:50 +00:00
/*
@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.
*
2014-07-29 18:04:04 +00:00
* @param player a player
* @return a session
*/
public LocalSession getSession(Player player) {
2018-06-16 06:36:55 +00:00
return WorldEdit.getInstance().getSessionManager().get(wrapPlayer(player));
}
/**
* Gets the session for the player.
*
2014-07-29 18:04:04 +00:00
* @param player a player
* @return a session
*/
public EditSession createEditSession(Player player) {
2018-06-16 05:29:48 +00:00
com.sk89q.worldedit.entity.Player wePlayer = wrapPlayer(player);
LocalSession session = WorldEdit.getInstance().getSessionManager().get(wePlayer);
BlockBag blockBag = session.getBlockBag(wePlayer);
EditSession editSession = WorldEdit.getInstance().getEditSessionFactory()
.getEditSession(wePlayer.getWorld(), session.getBlockChangeLimit(), blockBag, wePlayer);
editSession.enableStandardMode();
return editSession;
}
/**
* Remember an edit session.
*
2014-07-29 18:04:04 +00:00
* @param player a player
* @param editSession an edit session
*/
public void remember(Player player, EditSession editSession) {
2018-06-16 05:29:48 +00:00
com.sk89q.worldedit.entity.Player wePlayer = wrapPlayer(player);
LocalSession session = WorldEdit.getInstance().getSessionManager().get(wePlayer);
session.remember(editSession);
2018-10-21 01:54:58 +00:00
editSession.flushSession();
WorldEdit.getInstance().flushBlockBag(wePlayer, editSession);
}
/**
* Returns the configuration used by WorldEdit.
*
2014-07-29 18:04:04 +00:00
* @return the configuration
*/
public BukkitConfiguration getLocalConfiguration() {
return config;
}
/**
* Get the permissions resolver in use.
*
2014-07-29 18:04:04 +00:00
* @return the permissions resolver
*/
public PermissionsResolverManager getPermissionsResolver() {
return PermissionsResolverManager.getInstance();
}
/**
2018-06-16 05:29:48 +00:00
* Used to wrap a Bukkit Player as a WorldEdit Player.
*
2014-07-29 18:04:04 +00:00
* @param player a player
* @return a wrapped player
*/
public BukkitPlayer wrapPlayer(Player player) {
BukkitPlayer wePlayer = getCachedPlayer(player);
if (wePlayer == null) {
synchronized (player) {
wePlayer = getCachedPlayer(player);
if (wePlayer == null) {
wePlayer = new BukkitPlayer(this, player);
player.setMetadata("WE", new FixedMetadataValue(this, wePlayer));
return wePlayer;
}
2019-10-23 04:23:52 +00:00
}
}
return wePlayer;
}
public BukkitPlayer getCachedPlayer(Player player) {
2019-10-26 13:21:49 +00:00
List<MetadataValue> meta = player.getMetadata("WE");
2020-01-29 22:10:59 +00:00
if (meta.isEmpty()) {
2019-10-26 13:21:49 +00:00
return null;
}
return (BukkitPlayer) meta.get(0).value();
}
public Actor wrapCommandSender(CommandSender sender) {
if (sender instanceof Player) {
return wrapPlayer((Player) sender);
} else if (config.commandBlockSupport && sender instanceof BlockCommandSender) {
2019-08-06 15:28:12 +00:00
return new BukkitBlockCommandSender(this, (BlockCommandSender) sender);
}
return new BukkitCommandSender(this, sender);
}
2018-08-27 16:56:28 +00:00
public BukkitServerInterface getInternalPlatform() {
return server;
}
/**
* Get WorldEdit.
*
2014-07-29 18:04:04 +00:00
* @return an instance
*/
public WorldEdit getWorldEdit() {
return WorldEdit.getInstance();
}
/**
* Gets the instance of this plugin.
*
* @return an instance of the plugin
* @throws NullPointerException if the plugin hasn't been enabled
*/
public static WorldEditPlugin getInstance() {
return checkNotNull(INSTANCE);
}
/**
* Get the Bukkit implementation adapter.
*
* @return the adapter
*/
@Nullable
public BukkitImplAdapter getBukkitImplAdapter() {
return bukkitAdapter;
}
private class WorldInitListener implements Listener {
private boolean loaded = false;
2020-08-14 09:59:49 +00:00
@EventHandler(priority = EventPriority.LOWEST)
public void onWorldInit(@SuppressWarnings("unused") WorldInitEvent event) {
2020-08-14 09:59:49 +00:00
if (loaded) {
return;
}
loaded = true;
setupWorldData();
}
}
private class AsyncTabCompleteListener implements Listener {
AsyncTabCompleteListener() {
}
@SuppressWarnings("UnnecessaryFullyQualifiedName")
@EventHandler(ignoreCancelled = true)
public void onAsyncTabComplete(com.destroystokyo.paper.event.server.AsyncTabCompleteEvent event) {
2020-08-14 09:59:49 +00:00
if (!event.isCommand()) {
return;
}
String buffer = event.getBuffer();
2019-08-26 04:45:03 +00:00
int firstSpace = buffer.indexOf(' ');
2020-08-14 09:59:49 +00:00
if (firstSpace < 0) {
return;
}
String label = buffer.substring(0, firstSpace);
2020-03-19 22:23:11 +00:00
// Strip leading slash, if present.
label = label.startsWith("/") ? label.substring(1) : label;
final Optional<org.enginehub.piston.Command> command
= WorldEdit.getInstance().getPlatformManager().getPlatformCommandManager().getCommandManager().getCommand(label);
2020-08-14 09:59:49 +00:00
if (!command.isPresent()) {
return;
}
CommandSuggestionEvent suggestEvent = new CommandSuggestionEvent(wrapCommandSender(event.getSender()), buffer);
getWorldEdit().getEventBus().post(suggestEvent);
event.setCompletions(CommandUtil.fixSuggestions(buffer, suggestEvent.getSuggestions()));
event.setHandled(true);
}
}
}