2016-02-02 06:28:27 +00:00
|
|
|
/*
|
|
|
|
* 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 Lesser 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 Lesser General Public License
|
|
|
|
* for more details.
|
|
|
|
*
|
|
|
|
* 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/>.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package com.sk89q.worldedit.sponge;
|
|
|
|
|
2018-06-16 05:29:48 +00:00
|
|
|
import static com.google.common.base.Preconditions.checkNotNull;
|
|
|
|
|
2016-02-02 06:28:27 +00:00
|
|
|
import com.google.inject.Inject;
|
|
|
|
import com.sk89q.worldedit.LocalSession;
|
|
|
|
import com.sk89q.worldedit.WorldEdit;
|
|
|
|
import com.sk89q.worldedit.blocks.BaseItemStack;
|
|
|
|
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
|
2016-02-03 00:28:05 +00:00
|
|
|
import com.sk89q.worldedit.extension.platform.Actor;
|
2016-11-17 07:58:34 +00:00
|
|
|
import com.sk89q.worldedit.extension.platform.Capability;
|
2016-02-02 06:28:27 +00:00
|
|
|
import com.sk89q.worldedit.extension.platform.Platform;
|
2016-11-17 07:58:34 +00:00
|
|
|
import com.sk89q.worldedit.sponge.adapter.AdapterLoadException;
|
|
|
|
import com.sk89q.worldedit.sponge.adapter.SpongeImplAdapter;
|
|
|
|
import com.sk89q.worldedit.sponge.adapter.SpongeImplLoader;
|
2016-05-18 22:30:22 +00:00
|
|
|
import com.sk89q.worldedit.sponge.config.SpongeConfiguration;
|
2018-07-05 08:15:51 +00:00
|
|
|
import com.sk89q.worldedit.world.item.ItemTypes;
|
2016-05-19 01:03:29 +00:00
|
|
|
import org.slf4j.Logger;
|
2018-01-03 05:35:51 +00:00
|
|
|
import org.spongepowered.api.Sponge;
|
2016-02-02 06:28:27 +00:00
|
|
|
import org.spongepowered.api.block.BlockSnapshot;
|
|
|
|
import org.spongepowered.api.block.BlockType;
|
|
|
|
import org.spongepowered.api.block.BlockTypes;
|
2016-02-02 23:14:30 +00:00
|
|
|
import org.spongepowered.api.command.CommandSource;
|
2016-05-21 10:28:22 +00:00
|
|
|
import org.spongepowered.api.config.ConfigDir;
|
2016-02-02 06:28:27 +00:00
|
|
|
import org.spongepowered.api.entity.living.player.Player;
|
|
|
|
import org.spongepowered.api.event.Listener;
|
|
|
|
import org.spongepowered.api.event.block.InteractBlockEvent;
|
2016-05-21 10:28:22 +00:00
|
|
|
import org.spongepowered.api.event.filter.cause.Root;
|
2018-06-16 05:29:48 +00:00
|
|
|
import org.spongepowered.api.event.game.state.GameAboutToStartServerEvent;
|
|
|
|
import org.spongepowered.api.event.game.state.GameInitializationEvent;
|
|
|
|
import org.spongepowered.api.event.game.state.GamePostInitializationEvent;
|
|
|
|
import org.spongepowered.api.event.game.state.GamePreInitializationEvent;
|
|
|
|
import org.spongepowered.api.event.game.state.GameStartedServerEvent;
|
|
|
|
import org.spongepowered.api.event.game.state.GameStoppingServerEvent;
|
2018-06-17 12:04:35 +00:00
|
|
|
import org.spongepowered.api.item.ItemType;
|
2016-02-02 06:28:27 +00:00
|
|
|
import org.spongepowered.api.item.inventory.ItemStack;
|
|
|
|
import org.spongepowered.api.plugin.Plugin;
|
2016-02-06 00:30:11 +00:00
|
|
|
import org.spongepowered.api.plugin.PluginContainer;
|
2016-02-02 23:14:30 +00:00
|
|
|
import org.spongepowered.api.scheduler.Task;
|
2016-02-02 06:28:27 +00:00
|
|
|
import org.spongepowered.api.world.Location;
|
|
|
|
import org.spongepowered.api.world.World;
|
|
|
|
|
2016-02-03 00:28:05 +00:00
|
|
|
import java.io.File;
|
2016-11-17 07:58:34 +00:00
|
|
|
import java.io.IOException;
|
2016-02-03 00:28:05 +00:00
|
|
|
import java.util.Optional;
|
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
|
2016-02-02 06:28:27 +00:00
|
|
|
/**
|
|
|
|
* The Sponge implementation of WorldEdit.
|
|
|
|
*/
|
2016-05-21 10:28:22 +00:00
|
|
|
@Plugin(id = SpongeWorldEdit.MOD_ID, name = "WorldEdit",
|
|
|
|
description = "WorldEdit is an easy-to-use in-game world editor for Minecraft",
|
|
|
|
url = "http://www.enginehub.org/worldedit")
|
2016-02-02 06:28:27 +00:00
|
|
|
public class SpongeWorldEdit {
|
|
|
|
|
|
|
|
@Inject
|
2016-05-19 01:03:29 +00:00
|
|
|
private Logger logger;
|
2016-02-02 06:28:27 +00:00
|
|
|
|
|
|
|
public static final String MOD_ID = "worldedit";
|
|
|
|
|
2016-05-18 22:18:14 +00:00
|
|
|
private SpongePermissionsProvider provider;
|
2016-02-02 06:28:27 +00:00
|
|
|
|
2016-02-06 00:30:11 +00:00
|
|
|
@Inject
|
|
|
|
private PluginContainer container;
|
|
|
|
|
|
|
|
private static SpongeWorldEdit inst;
|
|
|
|
|
|
|
|
public static PluginContainer container() {
|
|
|
|
return inst.container;
|
|
|
|
}
|
|
|
|
|
|
|
|
public static SpongeWorldEdit inst() {
|
|
|
|
return inst;
|
|
|
|
}
|
2016-02-02 06:28:27 +00:00
|
|
|
|
|
|
|
private SpongePlatform platform;
|
2016-11-17 07:58:34 +00:00
|
|
|
private SpongeImplAdapter spongeAdapter;
|
2016-05-21 10:28:22 +00:00
|
|
|
|
|
|
|
@Inject
|
2016-02-02 06:28:27 +00:00
|
|
|
private SpongeConfiguration config;
|
2016-05-21 10:28:22 +00:00
|
|
|
|
|
|
|
@Inject @ConfigDir(sharedRoot = false)
|
2016-02-02 06:28:27 +00:00
|
|
|
private File workingDir;
|
|
|
|
|
2016-02-02 23:14:30 +00:00
|
|
|
public SpongeWorldEdit() {
|
|
|
|
inst = this;
|
|
|
|
}
|
|
|
|
|
2016-02-02 06:28:27 +00:00
|
|
|
@Listener
|
|
|
|
public void preInit(GamePreInitializationEvent event) {
|
2016-05-21 10:28:22 +00:00
|
|
|
// Load configuration
|
2016-02-02 06:28:27 +00:00
|
|
|
config.load();
|
|
|
|
|
2016-02-02 23:14:30 +00:00
|
|
|
Task.builder().interval(30, TimeUnit.SECONDS).execute(ThreadSafeCache.getInstance()).submit(this);
|
2016-02-02 06:28:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Listener
|
|
|
|
public void init(GameInitializationEvent event) {
|
2016-05-18 21:38:46 +00:00
|
|
|
CUIChannelHandler.init();
|
2016-02-02 06:28:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Listener
|
|
|
|
public void postInit(GamePostInitializationEvent event) {
|
2016-02-02 23:14:30 +00:00
|
|
|
logger.info("WorldEdit for Sponge (version " + getInternalVersion() + ") is loaded");
|
2016-02-02 06:28:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Listener
|
|
|
|
public void serverAboutToStart(GameAboutToStartServerEvent event) {
|
|
|
|
if (this.platform != null) {
|
2016-05-19 01:03:29 +00:00
|
|
|
logger.warn("GameAboutToStartServerEvent occurred when GameStoppingServerEvent hasn't");
|
2016-02-02 06:28:27 +00:00
|
|
|
WorldEdit.getInstance().getPlatformManager().unregister(platform);
|
|
|
|
}
|
|
|
|
|
|
|
|
this.platform = new SpongePlatform(this);
|
2016-05-18 22:18:14 +00:00
|
|
|
this.provider = new SpongePermissionsProvider();
|
2016-02-02 06:28:27 +00:00
|
|
|
|
2018-01-03 05:35:51 +00:00
|
|
|
for (BlockType blockType : Sponge.getRegistry().getAllOf(BlockType.class)) {
|
2018-06-17 12:04:35 +00:00
|
|
|
// TODO Handle blockstate stuff
|
2018-07-05 08:48:37 +00:00
|
|
|
com.sk89q.worldedit.world.block.BlockTypes.register(new com.sk89q.worldedit.world.block.BlockType(blockType.getId()));
|
2018-01-03 05:35:51 +00:00
|
|
|
}
|
|
|
|
|
2018-06-17 12:04:35 +00:00
|
|
|
for (ItemType itemType : Sponge.getRegistry().getAllOf(ItemType.class)) {
|
2018-07-05 08:48:37 +00:00
|
|
|
ItemTypes.register(new com.sk89q.worldedit.world.item.ItemType(itemType.getId()));
|
2018-06-17 12:04:35 +00:00
|
|
|
}
|
|
|
|
|
2016-02-02 06:28:27 +00:00
|
|
|
WorldEdit.getInstance().getPlatformManager().register(platform);
|
|
|
|
}
|
|
|
|
|
|
|
|
@Listener
|
|
|
|
public void serverStopping(GameStoppingServerEvent event) {
|
2018-08-19 03:01:08 +00:00
|
|
|
WorldEdit worldEdit = WorldEdit.getInstance();
|
|
|
|
worldEdit.getSessionManager().unload();
|
|
|
|
worldEdit.getPlatformManager().unregister(platform);
|
2016-02-02 06:28:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Listener
|
|
|
|
public void serverStarted(GameStartedServerEvent event) {
|
|
|
|
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
|
2016-11-17 07:58:34 +00:00
|
|
|
|
|
|
|
loadAdapter();
|
|
|
|
}
|
|
|
|
|
|
|
|
private void loadAdapter() {
|
|
|
|
WorldEdit worldEdit = WorldEdit.getInstance();
|
|
|
|
|
|
|
|
// Attempt to load a Sponge adapter
|
|
|
|
SpongeImplLoader adapterLoader = new SpongeImplLoader();
|
|
|
|
|
|
|
|
try {
|
|
|
|
adapterLoader.addFromPath(getClass().getClassLoader());
|
|
|
|
} catch (IOException e) {
|
|
|
|
logger.warn("Failed to search path for Sponge adapters");
|
|
|
|
}
|
|
|
|
|
|
|
|
try {
|
|
|
|
adapterLoader.addFromJar(container.getSource().get().toFile());
|
|
|
|
} catch (IOException e) {
|
|
|
|
logger.warn("Failed to search " + container.getSource().get().toFile() + " for Sponge adapters", e);
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
spongeAdapter = adapterLoader.loadAdapter();
|
|
|
|
logger.info("Using " + spongeAdapter.getClass().getCanonicalName() + " as the Sponge adapter");
|
|
|
|
} catch (AdapterLoadException e) {
|
|
|
|
Platform platform = worldEdit.getPlatformManager().queryCapability(Capability.WORLD_EDITING);
|
|
|
|
if (platform instanceof SpongePlatform) {
|
|
|
|
logger.warn(e.getMessage());
|
|
|
|
} else {
|
|
|
|
logger.info("WorldEdit could not find a Sponge adapter for this MC version, " +
|
|
|
|
"but it seems that you have another implementation of WorldEdit installed (" + platform.getPlatformName() + ") " +
|
|
|
|
"that handles the world editing.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public SpongeImplAdapter getAdapter() {
|
|
|
|
return this.spongeAdapter;
|
2016-02-02 06:28:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
@Listener
|
2016-05-21 10:28:22 +00:00
|
|
|
public void onPlayerInteract(InteractBlockEvent event, @Root Player spongePlayer) {
|
2016-02-02 06:28:27 +00:00
|
|
|
if (platform == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!platform.isHookingEvents()) return; // We have to be told to catch these events
|
|
|
|
|
|
|
|
WorldEdit we = WorldEdit.getInstance();
|
2016-04-15 01:55:15 +00:00
|
|
|
|
2016-05-21 10:28:22 +00:00
|
|
|
SpongePlayer player = wrapPlayer(spongePlayer);
|
2016-02-02 06:28:27 +00:00
|
|
|
com.sk89q.worldedit.world.World world = player.getWorld();
|
|
|
|
|
|
|
|
BlockSnapshot targetBlock = event.getTargetBlock();
|
2016-04-16 21:18:48 +00:00
|
|
|
Optional<Location<World>> optLoc = targetBlock.getLocation();
|
|
|
|
|
2016-02-02 06:28:27 +00:00
|
|
|
BlockType interactedType = targetBlock.getState().getType();
|
|
|
|
if (event instanceof InteractBlockEvent.Primary) {
|
|
|
|
if (interactedType != BlockTypes.AIR) {
|
2016-05-01 17:39:09 +00:00
|
|
|
if (!optLoc.isPresent()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Location<World> loc = optLoc.get();
|
2018-06-16 05:29:48 +00:00
|
|
|
com.sk89q.worldedit.util.Location pos = new com.sk89q.worldedit.util.Location(
|
|
|
|
world, loc.getX(), loc.getY(), loc.getZ());
|
2016-02-02 06:28:27 +00:00
|
|
|
|
|
|
|
if (we.handleBlockLeftClick(player, pos)) {
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (we.handleArmSwing(player)) {
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
2016-05-01 17:39:09 +00:00
|
|
|
} else {
|
|
|
|
if (we.handleArmSwing(player)) {
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
2016-02-02 06:28:27 +00:00
|
|
|
}
|
|
|
|
} else if (event instanceof InteractBlockEvent.Secondary) {
|
|
|
|
if (interactedType != BlockTypes.AIR) {
|
2016-05-01 17:39:09 +00:00
|
|
|
if (!optLoc.isPresent()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
Location<World> loc = optLoc.get();
|
2018-06-16 05:29:48 +00:00
|
|
|
com.sk89q.worldedit.util.Location pos = new com.sk89q.worldedit.util.Location(
|
|
|
|
world, loc.getX(), loc.getY(), loc.getZ());
|
2016-02-02 06:28:27 +00:00
|
|
|
|
|
|
|
if (we.handleBlockRightClick(player, pos)) {
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (we.handleRightClick(player)) {
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (we.handleRightClick(player)) {
|
|
|
|
event.setCancelled(true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public static ItemStack toSpongeItemStack(BaseItemStack item) {
|
2016-11-17 07:58:34 +00:00
|
|
|
return inst().getAdapter().makeSpongeStack(item);
|
2016-02-02 06:28:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the configuration.
|
|
|
|
*
|
2016-05-19 01:03:29 +00:00
|
|
|
* @return the Sponge configuration
|
2016-02-02 06:28:27 +00:00
|
|
|
*/
|
|
|
|
SpongeConfiguration getConfig() {
|
|
|
|
return this.config;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the WorldEdit proxy for the given player.
|
|
|
|
*
|
|
|
|
* @param player the player
|
|
|
|
* @return the WorldEdit player
|
|
|
|
*/
|
2016-02-02 23:14:30 +00:00
|
|
|
public SpongePlayer wrapPlayer(Player player) {
|
2016-02-02 06:28:27 +00:00
|
|
|
checkNotNull(player);
|
|
|
|
return new SpongePlayer(platform, player);
|
|
|
|
}
|
|
|
|
|
2016-02-02 23:14:30 +00:00
|
|
|
public Actor wrapCommandSource(CommandSource sender) {
|
|
|
|
if (sender instanceof Player) {
|
|
|
|
return wrapPlayer((Player) sender);
|
|
|
|
}
|
|
|
|
|
|
|
|
return new SpongeCommandSender(this, sender);
|
|
|
|
}
|
|
|
|
|
2016-02-02 06:28:27 +00:00
|
|
|
/**
|
|
|
|
* Get the session for a player.
|
|
|
|
*
|
|
|
|
* @param player the player
|
|
|
|
* @return the session
|
|
|
|
*/
|
|
|
|
public LocalSession getSession(Player player) {
|
|
|
|
checkNotNull(player);
|
2016-02-02 23:14:30 +00:00
|
|
|
return WorldEdit.getInstance().getSessionManager().get(wrapPlayer(player));
|
2016-02-02 06:28:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the WorldEdit proxy for the given world.
|
|
|
|
*
|
|
|
|
* @param world the world
|
|
|
|
* @return the WorldEdit world
|
|
|
|
*/
|
|
|
|
public SpongeWorld getWorld(World world) {
|
|
|
|
checkNotNull(world);
|
2016-11-17 07:58:34 +00:00
|
|
|
return getAdapter().getWorld(world);
|
2016-02-02 06:28:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the WorldEdit proxy for the platform.
|
|
|
|
*
|
|
|
|
* @return the WorldEdit platform
|
|
|
|
*/
|
|
|
|
public Platform getPlatform() {
|
|
|
|
return this.platform;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get the working directory where WorldEdit's files are stored.
|
|
|
|
*
|
|
|
|
* @return the working directory
|
|
|
|
*/
|
|
|
|
public File getWorkingDir() {
|
|
|
|
return this.workingDir;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2016-05-19 01:03:29 +00:00
|
|
|
* Get the version of the WorldEdit Sponge implementation.
|
2016-02-02 06:28:27 +00:00
|
|
|
*
|
|
|
|
* @return a version string
|
|
|
|
*/
|
|
|
|
String getInternalVersion() {
|
2016-05-21 10:28:22 +00:00
|
|
|
return container.getVersion().orElse("Unknown");
|
2016-02-02 06:28:27 +00:00
|
|
|
}
|
|
|
|
|
2016-05-18 22:18:14 +00:00
|
|
|
public void setPermissionsProvider(SpongePermissionsProvider provider) {
|
2016-02-02 06:28:27 +00:00
|
|
|
this.provider = provider;
|
|
|
|
}
|
|
|
|
|
2016-05-18 22:18:14 +00:00
|
|
|
public SpongePermissionsProvider getPermissionsProvider() {
|
2016-02-02 06:28:27 +00:00
|
|
|
return provider;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|