FAWE for MCPE (WIP)

This commit is contained in:
Jesse Boyd 2016-09-05 01:34:38 +10:00
parent 9f93f56c05
commit e68530e8f8
19 changed files with 2085 additions and 2 deletions

View File

@ -57,6 +57,7 @@ subprojects {
repositories {
mavenCentral()
maven {url "http://ci.regularbox.com/plugin/repository/everything/"}
maven {url "http://empcraft.com/maven2"}
maven {url "http://repo.mcstats.org/content/repositories/public"}
maven {url "https://hub.spigotmc.org/nexus/content/groups/public/"}

View File

@ -17,7 +17,6 @@ apply plugin: 'com.github.johnrengelman.shadow'
dependencies {
compile project(':core')
compile 'org.spongepowered:spongeapi:4.+'
compile 'com.sk89q.worldedit:worldedit-forge-mc1.8.9:6.1.1'
}

31
nukkit/build.gradle Normal file
View File

@ -0,0 +1,31 @@
dependencies {
compile project(':core')
compile 'cn.nukkit:nukkit:1.0-SNAPSHOT'
}
processResources {
from('src/main/resources') {
include 'plugin.yml'
expand(
name: project.parent.name,
version: project.parent.version
)
}
}
apply plugin: 'com.github.johnrengelman.shadow'
// We only want the shadow jar produced
jar.enabled = false
shadowJar {
dependencies {
include(dependency(':core'))
}
archiveName = "${parent.name}-${project.name}-${parent.version}.jar"
destinationDir = file '../target'
}
shadowJar.doLast {
task ->
ant.checksum file: task.archivePath
}
build.dependsOn(shadowJar);

View File

@ -0,0 +1,41 @@
package com.boydti.fawe.nukkit.core;
public class CommandInfo {
private final String[] aliases;
private final String usage, desc;
private final String[] permissions;
public CommandInfo(String usage, String desc, String[] aliases) {
this(usage, desc, aliases, null);
}
public CommandInfo(String usage, String desc, String[] aliases, String[] permissions) {
this.usage = usage;
this.desc = desc;
this.aliases = aliases;
this.permissions = permissions;
}
public String[] getAliases() {
return aliases;
}
public String getName() {
return aliases[0];
}
public String getUsage() {
return usage;
}
public String getDesc() {
return desc;
}
public String[] getPermissions() {
return permissions;
}
}

View File

@ -0,0 +1,54 @@
package com.boydti.fawe.nukkit.core;
import cn.nukkit.command.Command;
import cn.nukkit.command.CommandExecutor;
import cn.nukkit.command.CommandSender;
import cn.nukkit.command.PluginIdentifiableCommand;
import cn.nukkit.plugin.Plugin;
import com.sk89q.util.StringUtil;
/**
* An implementation of a dynamically registered {@link org.bukkit.command.Command} attached to a plugin
*/
public class DynamicPluginCommand extends Command implements PluginIdentifiableCommand {
protected final CommandExecutor owner;
private final Plugin plugin;
protected String[] permissions = new String[0];
public DynamicPluginCommand(String[] aliases, String desc, String usage, CommandExecutor owner, Plugin plugin) {
super(aliases[0], desc, usage, aliases);
this.owner = owner;
this.plugin = plugin;
}
@Override
public boolean execute(CommandSender sender, String label, String[] args) {
return owner.onCommand(sender, this, label, args);
}
public Object getOwner() {
return owner;
}
public void setPermissions(String[] permissions) {
this.permissions = permissions;
if (permissions != null) {
super.setPermission(StringUtil.joinString(permissions, ";"));
}
}
public String[] getPermissions() {
return permissions;
}
@Override
public boolean testPermissionSilent(CommandSender sender) {
return super.testPermissionSilent(sender);
}
@Override
public Plugin getPlugin() {
return plugin;
}
}

View File

@ -0,0 +1,244 @@
package com.boydti.fawe.nukkit.core;
import com.sk89q.jnbt.ByteArrayTag;
import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.DoubleTag;
import com.sk89q.jnbt.EndTag;
import com.sk89q.jnbt.FloatTag;
import com.sk89q.jnbt.IntArrayTag;
import com.sk89q.jnbt.IntTag;
import com.sk89q.jnbt.ListTag;
import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
/**
* Converts between Jcn.nukkit.nbt.tag. and Minecraft cn.nukkit.nbt.tag. classes.
*/
final class NBTConverter {
private NBTConverter() {
}
// private static Tag fromNativeSlow(cn.nukkit.nbt.tag.CompoundTag other) {
// try {
// byte[] bytes = NBTIO.write(other);
// FastByteArrayInputStream in = new FastByteArrayInputStream(bytes);
// NBTInputStream nin = new NBTInputStream(in);
// return nin.readNamedTag();
// } catch (IOException e) {
// e.printStackTrace();
// }
// }
public static CompoundTag fromNative(cn.nukkit.nbt.tag.CompoundTag other) {
Map<String, cn.nukkit.nbt.tag.Tag> tags = other.getTags();
Map<String, Tag> map = new HashMap<String, Tag>();
for (Entry<String, cn.nukkit.nbt.tag.Tag> entry : tags.entrySet()) {
map.put(entry.getKey(), fromNative(entry.getValue()));
}
return new CompoundTag(map);
}
public static cn.nukkit.nbt.tag.Tag toNative(Tag tag) {
if (tag instanceof IntArrayTag) {
return toNative((IntArrayTag) tag);
} else if (tag instanceof ListTag) {
return toNative((ListTag) tag);
} else if (tag instanceof LongTag) {
return toNative((LongTag) tag);
} else if (tag instanceof StringTag) {
return toNative((StringTag) tag);
} else if (tag instanceof IntTag) {
return toNative((IntTag) tag);
} else if (tag instanceof ByteTag) {
return toNative((ByteTag) tag);
} else if (tag instanceof ByteArrayTag) {
return toNative((ByteArrayTag) tag);
} else if (tag instanceof CompoundTag) {
return toNative((CompoundTag) tag);
} else if (tag instanceof FloatTag) {
return toNative((FloatTag) tag);
} else if (tag instanceof ShortTag) {
return toNative((ShortTag) tag);
} else if (tag instanceof DoubleTag) {
return toNative((DoubleTag) tag);
} else {
throw new IllegalArgumentException("Can't convert tag of type " + tag.getClass().getCanonicalName());
}
}
private static cn.nukkit.nbt.tag.IntArrayTag toNative(IntArrayTag tag) {
int[] value = tag.getValue();
return new cn.nukkit.nbt.tag.IntArrayTag("", Arrays.copyOf(value, value.length));
}
private static cn.nukkit.nbt.tag.ListTag toNative(ListTag tag) {
cn.nukkit.nbt.tag.ListTag list = new cn.nukkit.nbt.tag.ListTag();
for (Tag child : tag.getValue()) {
if (child instanceof EndTag) {
continue;
}
list.add(toNative(child));
}
return list;
}
private static cn.nukkit.nbt.tag.LongTag toNative(LongTag tag) {
return new cn.nukkit.nbt.tag.LongTag("", tag.getValue());
}
private static cn.nukkit.nbt.tag.StringTag toNative(StringTag tag) {
return new cn.nukkit.nbt.tag.StringTag("", tag.getValue());
}
private static cn.nukkit.nbt.tag.IntTag toNative(IntTag tag) {
return new cn.nukkit.nbt.tag.IntTag("", tag.getValue());
}
private static cn.nukkit.nbt.tag.ByteTag toNative(ByteTag tag) {
return new cn.nukkit.nbt.tag.ByteTag("", tag.getValue());
}
private static cn.nukkit.nbt.tag.ByteArrayTag toNative(ByteArrayTag tag) {
byte[] value = tag.getValue();
return new cn.nukkit.nbt.tag.ByteArrayTag("", Arrays.copyOf(value, value.length));
}
private static cn.nukkit.nbt.tag.CompoundTag toNative(CompoundTag tag) {
cn.nukkit.nbt.tag.CompoundTag compound = new cn.nukkit.nbt.tag.CompoundTag();
for (Entry<String, Tag> child : tag.getValue().entrySet()) {
compound.put(child.getKey(), toNative(child.getValue()));
}
return compound;
}
private static cn.nukkit.nbt.tag.FloatTag toNative(FloatTag tag) {
return new cn.nukkit.nbt.tag.FloatTag("", tag.getValue());
}
private static cn.nukkit.nbt.tag.ShortTag toNative(ShortTag tag) {
return new cn.nukkit.nbt.tag.ShortTag("", tag.getValue());
}
private static cn.nukkit.nbt.tag.DoubleTag toNative(DoubleTag tag) {
return new cn.nukkit.nbt.tag.DoubleTag("", tag.getValue());
}
private static Tag fromNative(cn.nukkit.nbt.tag.Tag other) {
if (other instanceof cn.nukkit.nbt.tag.IntArrayTag) {
return fromNative((cn.nukkit.nbt.tag.IntArrayTag) other);
} else if (other instanceof cn.nukkit.nbt.tag.ListTag) {
return fromNative((cn.nukkit.nbt.tag.ListTag) other);
} else if (other instanceof cn.nukkit.nbt.tag.EndTag) {
return fromNative((cn.nukkit.nbt.tag.EndTag) other);
} else if (other instanceof cn.nukkit.nbt.tag.LongTag) {
return fromNative((cn.nukkit.nbt.tag.LongTag) other);
} else if (other instanceof cn.nukkit.nbt.tag.StringTag) {
return fromNative((cn.nukkit.nbt.tag.StringTag) other);
} else if (other instanceof cn.nukkit.nbt.tag.IntTag) {
return fromNative((cn.nukkit.nbt.tag.IntTag) other);
} else if (other instanceof cn.nukkit.nbt.tag.ByteTag) {
return fromNative((cn.nukkit.nbt.tag.ByteTag) other);
} else if (other instanceof cn.nukkit.nbt.tag.ByteArrayTag) {
return fromNative((cn.nukkit.nbt.tag.ByteArrayTag) other);
} else if (other instanceof cn.nukkit.nbt.tag.CompoundTag) {
return fromNative((cn.nukkit.nbt.tag.CompoundTag) other);
} else if (other instanceof cn.nukkit.nbt.tag.FloatTag) {
return fromNative((cn.nukkit.nbt.tag.FloatTag) other);
} else if (other instanceof cn.nukkit.nbt.tag.ShortTag) {
return fromNative((cn.nukkit.nbt.tag.ShortTag) other);
} else if (other instanceof cn.nukkit.nbt.tag.DoubleTag) {
return fromNative((cn.nukkit.nbt.tag.DoubleTag) other);
} else {
throw new IllegalArgumentException("Can't convert other of type " + other.getClass().getCanonicalName());
}
}
private static IntArrayTag fromNative(cn.nukkit.nbt.tag.IntArrayTag other) {
int[] value = other.data;
return new IntArrayTag(Arrays.copyOf(value, value.length));
}
private static ListTag fromNative(cn.nukkit.nbt.tag.ListTag other) {
other = (cn.nukkit.nbt.tag.ListTag) other.copy();
List<Tag> list = new ArrayList<Tag>();
Class<? extends Tag> listClass = StringTag.class;
int tags = other.size();
for (int i = 0; i < tags; i++) {
Tag child = fromNative(other.get(0));
other.remove(0);
list.add(child);
listClass = child.getClass();
}
return new ListTag(listClass, list);
}
private static EndTag fromNative(cn.nukkit.nbt.tag.EndTag other) {
return new EndTag();
}
private static LongTag fromNative(cn.nukkit.nbt.tag.LongTag other) {
return new LongTag(other.data);
}
private static StringTag fromNative(cn.nukkit.nbt.tag.StringTag other) {
return new StringTag(other.data);
}
private static IntTag fromNative(cn.nukkit.nbt.tag.IntTag other) {
return new IntTag(other.data);
}
private static ByteTag fromNative(cn.nukkit.nbt.tag.ByteTag other) {
return new ByteTag((byte) other.data);
}
private static ByteArrayTag fromNative(cn.nukkit.nbt.tag.ByteArrayTag other) {
byte[] value = other.data;
return new ByteArrayTag(Arrays.copyOf(value, value.length));
}
private static FloatTag fromNative(cn.nukkit.nbt.tag.FloatTag other) {
return new FloatTag(other.data);
}
private static ShortTag fromNative(cn.nukkit.nbt.tag.ShortTag other) {
return new ShortTag((short) other.data);
}
private static DoubleTag fromNative(cn.nukkit.nbt.tag.DoubleTag other) {
return new DoubleTag(other.data);
}
}

View File

@ -0,0 +1,27 @@
package com.boydti.fawe.nukkit.core;
import cn.nukkit.command.CommandExecutor;
import cn.nukkit.command.SimpleCommandMap;
import cn.nukkit.plugin.Plugin;
public class NukkitCommandManager {
private final SimpleCommandMap commandMap;
public NukkitCommandManager(SimpleCommandMap map) {
this.commandMap = map;
}
public boolean register(CommandInfo command, Plugin plugin, CommandExecutor executor) {
if (command == null || commandMap == null) {
return false;
}
DynamicPluginCommand cmd = new DynamicPluginCommand(
command.getAliases(),
command.getDesc(), "/" + command.getAliases()[0] + " " + command.getUsage(),
executor,
plugin);
cmd.setPermissions(command.getPermissions());
commandMap.register(plugin.getDescription().getName(), cmd);
return true;
}
}

View File

@ -0,0 +1,48 @@
package com.boydti.fawe.nukkit.core;
import com.sk89q.util.yaml.YAMLProcessor;
import com.sk89q.worldedit.bukkit.WorldEditPlugin;
import com.sk89q.worldedit.util.YAMLConfiguration;
import java.io.File;
public class NukkitConfiguration extends YAMLConfiguration {
public boolean noOpPermissions = false;
private final WorldEditPlugin plugin;
public NukkitConfiguration(YAMLProcessor config, WorldEditPlugin plugin) {
super(config, plugin.getLogger());
this.plugin = plugin;
}
@Override
public void load() {
super.load();
noOpPermissions = config.getBoolean("no-op-permissions", false);
migrateLegacyFolders();
}
private void migrateLegacyFolders() {
migrate(scriptsDir, "craftscripts");
migrate(saveDir, "schematics");
migrate("drawings", "draw.js images");
}
private void migrate(String file, String name) {
File fromDir = new File(".", file);
File toDir = new File(getWorkingDirectory(), file);
if (fromDir.exists() & !toDir.exists()) {
if (fromDir.renameTo(toDir)) {
plugin.getLogger().info("Migrated " + name + " folder '" + file +
"' from server root to plugin data folder.");
} else {
plugin.getLogger().warning("Error while migrating " + name + " folder!");
}
}
}
@Override
public File getWorkingDirectory() {
return plugin.getDataFolder();
}
}

View File

@ -0,0 +1,109 @@
/*
* 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.boydti.fawe.nukkit.core;
import cn.nukkit.entity.Entity;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.entity.metadata.EntityType;
import com.sk89q.worldedit.extent.Extent;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.NullWorld;
import java.lang.ref.WeakReference;
import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An adapter to adapt a Bukkit entity into a WorldEdit one.
*/
class NukkitEntity implements com.sk89q.worldedit.entity.Entity {
private final WeakReference<cn.nukkit.entity.Entity> entityRef;
/**
* Create a new instance.
*
* @param entity the entity
*/
NukkitEntity(cn.nukkit.entity.Entity entity) {
checkNotNull(entity);
this.entityRef = new WeakReference<Entity>(entity);
}
@Override
public Extent getExtent() {
Entity entity = entityRef.get();
if (entity != null) {
return new NukkitWorld(entity.getLevel());
} else {
return NullWorld.getInstance();
}
}
@Override
public Location getLocation() {
Entity entity = entityRef.get();
if (entity != null) {
return NukkitUtil.toLocation(entity.getLocation());
} else {
return new Location(NullWorld.getInstance());
}
}
@Override
public BaseEntity getState() {
Entity entity = entityRef.get();
if (entity != null) {
if (entity instanceof Player) {
return null;
}
CompoundTag tag = NBTConverter.fromNative(entity.namedTag);
return new BaseEntity(entity.getSaveId(), tag);
} else {
return null;
}
}
@Override
public boolean remove() {
Entity entity = entityRef.get();
if (entity != null) {
entity.kill();
return !entity.isAlive();
} else {
return true;
}
}
@SuppressWarnings("unchecked")
@Nullable
@Override
public <T> T getFacet(Class<? extends T> cls) {
Entity entity = entityRef.get();
if (entity != null && EntityType.class.isAssignableFrom(cls)) {
return (T) new NukkitEntityType(entity);
} else {
return null;
}
}
}

View File

@ -0,0 +1,124 @@
package com.boydti.fawe.nukkit.core;
import cn.nukkit.Player;
import cn.nukkit.entity.Entity;
import cn.nukkit.entity.EntityLiving;
import cn.nukkit.entity.item.EntityBoat;
import cn.nukkit.entity.item.EntityFallingBlock;
import cn.nukkit.entity.item.EntityItem;
import cn.nukkit.entity.item.EntityMinecartEmpty;
import cn.nukkit.entity.item.EntityPainting;
import cn.nukkit.entity.item.EntityPrimedTNT;
import cn.nukkit.entity.item.EntityXPOrb;
import cn.nukkit.entity.passive.EntityAnimal;
import cn.nukkit.entity.passive.EntityNPC;
import cn.nukkit.entity.passive.EntityTameable;
import cn.nukkit.entity.projectile.EntityProjectile;
import com.sk89q.worldedit.entity.metadata.EntityType;
import static com.google.common.base.Preconditions.checkNotNull;
public class NukkitEntityType implements EntityType {
private final Entity entity;
public NukkitEntityType(Entity entity) {
checkNotNull(entity);
this.entity = entity;
}
@Override
public boolean isPlayerDerived() {
return entity instanceof Player;
}
@Override
public boolean isProjectile() {
return entity instanceof EntityProjectile;
}
@Override
public boolean isItem() {
return entity instanceof EntityItem;
}
@Override
public boolean isFallingBlock() {
return entity instanceof EntityFallingBlock;
}
@Override
public boolean isPainting() {
return entity instanceof EntityPainting;
}
@Override
public boolean isItemFrame() {
// No item frames on MCPE
return false;
}
@Override
public boolean isBoat() {
return entity instanceof EntityBoat;
}
@Override
public boolean isMinecart() {
return entity instanceof EntityMinecartEmpty;
}
@Override
public boolean isTNT() {
return entity instanceof EntityPrimedTNT;
}
@Override
public boolean isExperienceOrb() {
return entity instanceof EntityXPOrb;
}
@Override
public boolean isLiving() {
return entity instanceof EntityLiving;
}
@Override
public boolean isAnimal() {
return entity instanceof EntityAnimal;
}
@Override
public boolean isAmbient() {
// No bats implemented on MCPE
return false;
}
@Override
public boolean isNPC() {
return entity instanceof EntityNPC;
}
@Override
public boolean isGolem() {
// No golem on MCPE
return false;
}
@Override
public boolean isTamed() {
return entity instanceof EntityTameable && ((EntityTameable) entity).isTamed();
}
@Override
public boolean isTagged() {
return entity.hasCustomName();
}
@Override
public boolean isArmorStand() {
// No armor stand
return false;
}
}

View File

@ -0,0 +1,174 @@
/*
* 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.boydti.fawe.nukkit.core;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
import com.boydti.fawe.util.TaskManager;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.AbstractPlatform;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.MultiUserPlatform;
import com.sk89q.worldedit.extension.platform.Preference;
import com.sk89q.worldedit.util.command.CommandMapping;
import com.sk89q.worldedit.util.command.Description;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.world.World;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import javax.annotation.Nullable;
class NukkitPlatform extends AbstractPlatform implements MultiUserPlatform {
private final NukkitWorldEdit mod;
private boolean hookingEvents = false;
private NukkitCommandManager commandManager;
NukkitPlatform(NukkitWorldEdit mod) {
this.mod = mod;
this.commandManager = new NukkitCommandManager(mod.getServer().getCommandMap());
}
boolean isHookingEvents() {
return hookingEvents;
}
@Override
public int resolveItem(String name) {
Item item = Item.fromString(name);
return item == null ? 0 : item.getId();
}
public NukkitWorldEdit getMod() {
return mod;
}
@Override
public boolean isValidMobType(String type) {
System.out.print("Not implemented: isValidMobType");
return true;
}
@Override
public void reload() {
getConfiguration().load();
}
@Override
public int schedule(long delay, long period, Runnable task) {
TaskManager.IMP.repeat(task, (int) period);
return 0; // TODO This isn't right, but we only check for -1 values
}
@Override
public List<? extends com.sk89q.worldedit.world.World> getWorlds() {
Collection<Level> levels = mod.getServer().getLevels().values();
List<com.sk89q.worldedit.world.World> ret = new ArrayList<>(levels.size());
for (Level level : levels) {
ret.add(new NukkitWorld(level));
}
return ret;
}
@Nullable
@Override
public Player matchPlayer(Player player) {
if (player instanceof NukkitPlayer) {
return player;
} else {
cn.nukkit.Player currentPlayer = mod.getServer().getPlayer(player.getName());
return currentPlayer != null ? new NukkitPlayer(this, currentPlayer) : null;
}
}
@Nullable
@Override
public World matchWorld(World world) {
if (world instanceof NukkitWorld) {
return world;
} else {
Level level = NukkitWorldEdit.inst().getServer().getLevelByName(world.getName());
return level != null ? new NukkitWorld(level) : null;
}
}
@Override
public void registerCommands(Dispatcher dispatcher) {
for (CommandMapping command : dispatcher.getCommands()) {
Description description = command.getDescription();
List<String> permissions = description.getPermissions();
String[] permissionsArray = new String[permissions.size()];
permissions.toArray(permissionsArray);
commandManager.register(new CommandInfo(description.getUsage(), description.getDescription(), command.getAllAliases(), permissionsArray), mod, mod);
}
}
@Override
public void registerGameHooks() {
// We registered the events already anyway, so we just 'turn them on'
hookingEvents = true;
}
@Override
public NukkitConfiguration getConfiguration() {
return mod.getWEConfig();
}
@Override
public String getVersion() {
return mod.getInternalVersion();
}
@Override
public String getPlatformName() {
return "Nukkit-Official";
}
@Override
public String getPlatformVersion() {
return mod.getInternalVersion();
}
@Override
public Map<Capability, Preference> getCapabilities() {
Map<Capability, Preference> capabilities = new EnumMap<>(Capability.class);
capabilities.put(Capability.CONFIGURATION, Preference.NORMAL);
capabilities.put(Capability.WORLDEDIT_CUI, Preference.NORMAL);
capabilities.put(Capability.GAME_HOOKS, Preference.NORMAL);
capabilities.put(Capability.PERMISSIONS, Preference.NORMAL);
capabilities.put(Capability.USER_COMMANDS, Preference.NORMAL);
capabilities.put(Capability.WORLD_EDITING, Preference.PREFERRED);
return capabilities;
}
@Override
public Collection<Actor> getConnectedUsers() {
List<Actor> users = new ArrayList<Actor>();
for (Map.Entry<UUID, cn.nukkit.Player> entry : mod.getServer().getOnlinePlayers().entrySet()) {
users.add(new NukkitPlayer(this, entry.getValue()));
}
return users;
}
}

View File

@ -0,0 +1,245 @@
/*
* 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.boydti.fawe.nukkit.core;
import cn.nukkit.Player;
import cn.nukkit.inventory.PlayerInventory;
import cn.nukkit.item.Item;
import cn.nukkit.level.Location;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.WorldVector;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.session.SessionKey;
import java.util.UUID;
import javax.annotation.Nullable;
public class NukkitPlayer extends LocalPlayer {
private final NukkitPlatform platform;
private Player player;
public NukkitPlayer(NukkitPlatform platform, Player player) {
this.platform = platform;
this.player = player;
}
@Override
public UUID getUniqueId() {
return player.getUniqueId();
}
@Override
public int getItemInHand() {
PlayerInventory inv = player.getInventory();
Item itemStack = inv.getItemInHand();
return itemStack != null ? itemStack.getId() : 0;
}
@Override
public BaseBlock getBlockInHand() throws WorldEditException {
PlayerInventory inv = player.getInventory();
Item itemStack = inv.getItemInHand();
if (itemStack == null) {
return new BaseBlock(0, 0);
}
return new BaseBlock(itemStack.getId(), itemStack.getDamage());
}
@Override
public String getName() {
return player.getName();
}
@Override
public WorldVector getPosition() {
Location loc = player.getLocation();
return new WorldVector(NukkitUtil.getLocalWorld(loc.getLevel()),
loc.getX(), loc.getY(), loc.getZ());
}
@Override
public double getPitch() {
return player.getLocation().getPitch();
}
@Override
public double getYaw() {
return player.getLocation().getYaw();
}
@Override
public void giveItem(int type, int amt) {
player.getInventory().addItem(new Item(type, 0, amt));
}
@Override
public void printRaw(String msg) {
for (String part : msg.split("\n")) {
player.sendMessage(part);
}
}
@Override
public void print(String msg) {
for (String part : msg.split("\n")) {
player.sendMessage("\u00A7d" + part);
}
}
@Override
public void printDebug(String msg) {
for (String part : msg.split("\n")) {
player.sendMessage("\u00A77" + part);
}
}
@Override
public void printError(String msg) {
for (String part : msg.split("\n")) {
player.sendMessage("\u00A7c" + part);
}
}
@Override
public void setPosition(Vector pos, float pitch, float yaw) {
player.teleport(new Location(pos.getX(), pos.getY(), pos.getZ(), yaw, pitch, player.getLevel()));
}
@Override
public String[] getGroups() {
// Is this ever used?
return new String[0];
}
@Override
public BlockBag getInventoryBlockBag() {
return new NukkitPlayerBlockBag(player);
}
@Override
public boolean hasPermission(String perm) {
NukkitConfiguration config = platform.getMod().getWEConfig();
return (!config.noOpPermissions && player.isOp()) || player.hasPermission(perm);
}
@Override
public LocalWorld getWorld() {
return NukkitUtil.getLocalWorld(player.getLevel());
}
@Override
public void dispatchCUIEvent(CUIEvent event) {
// No WE-CUI on MCPE
return;
}
public Player getPlayer() {
return player;
}
@Override
public boolean hasCreativeMode() {
return player.getGamemode() == 1;
}
@Override
public void floatAt(int x, int y, int z, boolean alwaysGlass) {
if (alwaysGlass || !player.getAllowFlight()) {
super.floatAt(x, y, z, alwaysGlass);
return;
}
setPosition(new Vector(x + 0.5, y, z + 0.5));
player.getAdventureSettings().setCanFly(true);
player.getAdventureSettings().update();
}
@Override
public BaseEntity getState() {
throw new UnsupportedOperationException("Cannot create a state from this object");
}
@Override
public com.sk89q.worldedit.util.Location getLocation() {
Location nativeLocation = player.getLocation();
Vector position = NukkitUtil.toVector(nativeLocation);
return new com.sk89q.worldedit.util.Location(
getWorld(),
position,
(float) nativeLocation.getYaw(),
(float) nativeLocation.getPitch());
}
@Nullable
@Override
public <T> T getFacet(Class<? extends T> cls) {
return null;
}
@Override
public SessionKey getSessionKey() {
return new SessionKeyImpl(this.player.getUniqueId(), player.getName());
}
private static class SessionKeyImpl implements SessionKey {
// If not static, this will leak a reference
private final UUID uuid;
private final String name;
private SessionKeyImpl(UUID uuid, String name) {
this.uuid = uuid;
this.name = name;
}
@Override
public UUID getUniqueId() {
return uuid;
}
@Nullable
@Override
public String getName() {
return name;
}
@Override
public boolean isActive() {
// This is a thread safe call on CraftNukkit because it uses a
// CopyOnWrite list for the list of players, but the Nukkit
// specification doesn't require thread safety (though the
// spec is extremely incomplete)
return NukkitWorldEdit.inst().getServer().getPlayer(name) != null;
}
@Override
public boolean isPersistent() {
return true;
}
}
}

View File

@ -0,0 +1,206 @@
/*
* 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.boydti.fawe.nukkit.core;
import cn.nukkit.Player;
import cn.nukkit.inventory.PlayerInventory;
import cn.nukkit.item.Item;
import com.sk89q.worldedit.WorldVector;
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.blocks.BlockID;
import com.sk89q.worldedit.blocks.ItemType;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.extent.inventory.BlockBagException;
import com.sk89q.worldedit.extent.inventory.OutOfBlocksException;
import com.sk89q.worldedit.extent.inventory.OutOfSpaceException;
import java.util.Map;
public class NukkitPlayerBlockBag extends BlockBag {
private Player player;
private Map<Integer, Item> items;
private int size;
/**
* Construct the object.
*
* @param player the player
*/
public NukkitPlayerBlockBag(Player player) {
this.player = player;
}
/**
* Loads inventory on first use.
*/
private void loadInventory() {
if (items == null) {
PlayerInventory inv = player.getInventory();
items = inv.getContents();
this.size = inv.getSize();
}
}
/**
* Get the player.
*
* @return the player
*/
public Player getPlayer() {
return player;
}
@Override
public void fetchItem(BaseItem item) throws BlockBagException {
final int id = item.getType();
final int damage = item.getData();
int amount = (item instanceof BaseItemStack) ? ((BaseItemStack) item).getAmount() : 1;
assert(amount == 1);
boolean usesDamageValue = ItemType.usesDamageValue(id);
if (id == BlockID.AIR) {
throw new IllegalArgumentException("Can't fetch air block");
}
loadInventory();
boolean found = false;
for (Map.Entry<Integer, Item> entry : items.entrySet()) {
int slot = entry.getKey();
Item nukkitItem = entry.getValue();
if (nukkitItem == null) {
continue;
}
if (nukkitItem.getId() != id) {
// Type id doesn't fit
continue;
}
if (usesDamageValue && nukkitItem.getDamage() != damage) {
// Damage value doesn't fit.
continue;
}
int currentCount = nukkitItem.getCount();
if (currentCount < 0) {
// Unlimited
return;
}
if (currentCount > 1) {
nukkitItem.setCount(currentCount - 1);
found = true;
} else {
items.remove(slot);
found = true;
}
break;
}
if (!found) {
throw new OutOfBlocksException();
}
}
@Override
public void storeItem(BaseItem item) throws BlockBagException {
final int id = item.getType();
final int damage = item.getData();
int amount = (item instanceof BaseItemStack) ? ((BaseItemStack) item).getAmount() : 1;
assert(amount <= 64);
boolean usesDamageValue = ItemType.usesDamageValue(id);
if (id == BlockID.AIR) {
throw new IllegalArgumentException("Can't store air block");
}
loadInventory();
int freeSlot = -1;
for (int slot = 0; slot < size; ++slot) {
Item nukkitItem = items.get(slot);
if (nukkitItem == null) {
// Delay using up a free slot until we know there are no stacks
// of this item to merge into
if (freeSlot == -1) {
freeSlot = slot;
}
continue;
}
if (nukkitItem.getId() != id) {
// Type id doesn't fit
continue;
}
if (usesDamageValue && nukkitItem.getDamage() != damage) {
// Damage value doesn't fit.
continue;
}
int currentCount = nukkitItem.getCount();
if (currentCount < 0) {
// Unlimited
return;
}
if (currentCount >= 64) {
// Full stack
continue;
}
int spaceLeft = 64 - currentCount;
if (spaceLeft >= amount) {
nukkitItem.setCount(currentCount + amount);
return;
}
nukkitItem.setCount(64);
amount -= spaceLeft;
}
if (freeSlot > -1) {
items.put(freeSlot, new Item(id, 0, amount));
return;
}
throw new OutOfSpaceException(id);
}
@Override
public void flushChanges() {
if (items != null) {
player.getInventory().setContents(items);
items = null;
}
}
@Override
public void addSourcePosition(WorldVector pos) {
}
@Override
public void addSingleSourcePosition(WorldVector pos) {
}
}

View File

@ -0,0 +1,67 @@
package com.boydti.fawe.nukkit.core;
import cn.nukkit.plugin.Plugin;
import cn.nukkit.scheduler.TaskHandler;
import com.boydti.fawe.util.TaskManager;
import java.util.HashMap;
import org.apache.commons.lang.mutable.MutableInt;
public class NukkitTaskManager extends TaskManager {
private final Plugin plugin;
public NukkitTaskManager(final Plugin plugin) {
this.plugin = plugin;
}
@Override
public int repeat(final Runnable r, final int interval) {
TaskHandler task = this.plugin.getServer().getScheduler().scheduleRepeatingTask(r, interval, false);
return task.getTaskId();
}
@Override
public int repeatAsync(final Runnable r, final int interval) {
TaskHandler task = this.plugin.getServer().getScheduler().scheduleRepeatingTask(r, interval, true);
return task.getTaskId();
}
public MutableInt index = new MutableInt(0);
public HashMap<Integer, Integer> tasks = new HashMap<>();
@Override
public void async(final Runnable r) {
if (r == null) {
return;
}
this.plugin.getServer().getScheduler().scheduleTask(r, true);
}
@Override
public void task(final Runnable r) {
if (r == null) {
return;
}
this.plugin.getServer().getScheduler().scheduleTask(r, false);
}
@Override
public void later(final Runnable r, final int delay) {
if (r == null) {
return;
}
this.plugin.getServer().getScheduler().scheduleDelayedTask(r, delay);
}
@Override
public void laterAsync(final Runnable r, final int delay) {
this.plugin.getServer().getScheduler().scheduleDelayedTask(r, delay, true);
}
@Override
public void cancel(final int task) {
if (task != -1) {
this.plugin.getServer().getScheduler().cancelTask(task);
}
}
}

View File

@ -0,0 +1,139 @@
/*
* LevelEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) LevelEdit 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.boydti.fawe.nukkit.core;
import cn.nukkit.Player;
import cn.nukkit.Server;
import cn.nukkit.block.Block;
import cn.nukkit.entity.Entity;
import cn.nukkit.level.Level;
import cn.nukkit.math.Vector3;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockWorldVector;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.WorldVector;
public final class NukkitUtil {
private NukkitUtil() {
}
public static LocalWorld getLocalWorld(Level w) {
return new NukkitWorld(w);
}
public static BlockVector toVector(Block block) {
return new BlockVector(block.getX(), block.getY(), block.getZ());
}
public static BlockWorldVector toWorldVector(Block block) {
return new BlockWorldVector(getLocalWorld(block.getLevel()), block.getX(), block.getY(), block.getZ());
}
public static Vector toVector(cn.nukkit.level.Location loc) {
return new Vector(loc.getX(), loc.getY(), loc.getZ());
}
public static Location toLocation(cn.nukkit.level.Location loc) {
return new Location(
getLocalWorld(loc.getLevel()),
new Vector(loc.getX(), loc.getY(), loc.getZ()),
(float) loc.getYaw(), (float) loc.getPitch()
);
}
public static Vector toVector(Vector3 vector) {
return new Vector(vector.getX(), vector.getY(), vector.getZ());
}
public static cn.nukkit.level.Location toLocation(WorldVector pt) {
return new cn.nukkit.level.Location(pt.getX(), pt.getY(), pt.getZ(), 0, 0, toLevel(pt));
}
public static cn.nukkit.level.Location toLocation(Level world, Vector pt) {
return new cn.nukkit.level.Location(pt.getX(), pt.getY(), pt.getZ(), 0, 0, world);
}
public static cn.nukkit.level.Location center(cn.nukkit.level.Location loc) {
return new cn.nukkit.level.Location(
loc.getFloorX() + 0.5,
loc.getFloorY() + 0.5,
loc.getFloorZ() + 0.5,
loc.getPitch(),
loc.getYaw(),
loc.getLevel()
);
}
public static Player matchSinglePlayer(Server server, String name) {
Player[] players = server.matchPlayer(name);
return players.length > 0 ? players[0] : null;
}
public static Block toBlock(BlockWorldVector pt) {
return toLevel(pt).getBlock(toLocation(pt));
}
public static Level toLevel(WorldVector pt) {
return ((NukkitWorld) pt.getWorld()).getLevel();
}
/**
* Nukkit's Location class has serious problems with floating point
* precision.
*/
@SuppressWarnings("RedundantIfStatement")
public static boolean equals(cn.nukkit.level.Location a, cn.nukkit.level.Location b) {
if (Math.abs(a.getX() - b.getX()) > EQUALS_PRECISION) return false;
if (Math.abs(a.getY() - b.getY()) > EQUALS_PRECISION) return false;
if (Math.abs(a.getZ() - b.getZ()) > EQUALS_PRECISION) return false;
return true;
}
public static final double EQUALS_PRECISION = 0.0001;
public static cn.nukkit.level.Location toLocation(Location location) {
return new cn.nukkit.level.Location(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch(), toLevel((LocalWorld) location.getExtent()));
}
public static Level toLevel(final LocalWorld world) {
return ((NukkitWorld) world).getLevel();
}
public static NukkitEntity toLocalEntity(Entity e) {
return new NukkitEntity(e);
}
public static com.sk89q.worldedit.entity.Entity createEntity(Location location, BaseEntity entity) {
return null;
}
public static BaseBlock getBlock(Level level, Vector position) {
return null;
}
public static boolean setBlock(Level level, Vector position, BaseBlock block) {
return false;
}
}

View File

@ -0,0 +1,299 @@
package com.boydti.fawe.nukkit.core;
import cn.nukkit.block.Block;
import cn.nukkit.blockentity.BlockEntity;
import cn.nukkit.blockentity.BlockEntityChest;
import cn.nukkit.entity.Entity;
import cn.nukkit.inventory.InventoryHolder;
import cn.nukkit.item.Item;
import cn.nukkit.level.Level;
import cn.nukkit.math.Vector3;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.LocalWorld;
import com.sk89q.worldedit.Vector;
import com.sk89q.worldedit.Vector2D;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseBlock;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator;
import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.registry.WorldData;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import javax.annotation.Nullable;
import org.bukkit.Material;
import static com.google.common.base.Preconditions.checkNotNull;
public class NukkitWorld extends LocalWorld {
private static final Logger logger = WorldEdit.logger;
private final WeakReference<Level> worldRef;
/**
* Construct the object.
*
* @param world the world
*/
@SuppressWarnings("unchecked")
public NukkitWorld(Level world) {
this.worldRef = new WeakReference<Level>(world);
}
private Vector3 mutable = new Vector3(0, 0, 0);
private Vector3 setMutable(Vector pt) {
mutable.x = pt.getX();
mutable.y = pt.getY();
mutable.z = pt.getZ();
return mutable;
}
@Override
public List<com.sk89q.worldedit.entity.Entity> getEntities(Region region) {
Level world = getLevel();
cn.nukkit.entity.Entity[] ents = world.getEntities();
List<com.sk89q.worldedit.entity.Entity> entities = new ArrayList<com.sk89q.worldedit.entity.Entity>();
for (cn.nukkit.entity.Entity ent : ents) {
if (region.contains(NukkitUtil.toVector(ent.getLocation()))) {
entities.add(new NukkitEntity(ent));
}
}
return entities;
}
@Override
public List<com.sk89q.worldedit.entity.Entity> getEntities() {
List<com.sk89q.worldedit.entity.Entity> list = new ArrayList<com.sk89q.worldedit.entity.Entity>();
for (Entity entity : getLevel().getEntities()) {
list.add(new NukkitEntity(entity));
}
return list;
}
@Nullable
@Override
public com.sk89q.worldedit.entity.Entity createEntity(com.sk89q.worldedit.util.Location location, BaseEntity entity) {
return NukkitUtil.createEntity(location, entity);
}
/**
* Get the world handle.
*
* @return the world
*/
public Level getLevel() {
return checkNotNull(worldRef.get(), "The world was unloaded and the reference is unavailable");
}
@Override
public String getName() {
return getLevel().getName();
}
@Override
public int getBlockLightLevel(Vector pt) {
return getLevel().getBlockLightAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
}
@Override
public boolean regenerate(Region region, EditSession editSession) {
BaseBlock[] history = new BaseBlock[16 * 16 * (getMaxY() + 1)];
for (Vector2D chunk : region.getChunks()) {
Vector min = new Vector(chunk.getBlockX() * 16, 0, chunk.getBlockZ() * 16);
// First save all the blocks inside
for (int x = 0; x < 16; ++x) {
for (int y = 0; y < (getMaxY() + 1); ++y) {
for (int z = 0; z < 16; ++z) {
Vector pt = min.add(x, y, z);
int index = y * 16 * 16 + z * 16 + x;
history[index] = editSession.getBlock(pt);
}
}
}
try {
getLevel().regenerateChunk(chunk.getBlockX(), chunk.getBlockZ());
} catch (Throwable t) {
logger.log(java.util.logging.Level.WARNING, "Chunk generation via Nukkit raised an error", t);
}
// Then restore
for (int x = 0; x < 16; ++x) {
for (int y = 0; y < (getMaxY() + 1); ++y) {
for (int z = 0; z < 16; ++z) {
Vector pt = min.add(x, y, z);
int index = y * 16 * 16 + z * 16 + x;
// We have to restore the block if it was outside
if (!region.contains(pt)) {
editSession.smartSetBlock(pt, history[index]);
} else { // Otherwise fool with history
editSession.rememberChange(pt, history[index],
editSession.rawGetBlock(pt));
}
}
}
}
}
return true;
}
@Override
public boolean clearContainerBlockContents(Vector pt) {
BlockEntity block = getLevel().getBlockEntity(setMutable(pt));
if (block == null) {
return false;
}
if (block instanceof InventoryHolder) {
if (block instanceof BlockEntityChest) {
((BlockEntityChest) block).getRealInventory().clearAll();
} else {
((InventoryHolder) block).getInventory().clearAll();
}
return true;
}
return false;
}
@Override
@Deprecated
public boolean generateTree(EditSession editSession, Vector pt) {
return generateTree(TreeGenerator.TreeType.TREE, editSession, pt);
}
@Override
@Deprecated
public boolean generateBigTree(EditSession editSession, Vector pt) {
return generateTree(TreeGenerator.TreeType.BIG_TREE, editSession, pt);
}
@Override
@Deprecated
public boolean generateBirchTree(EditSession editSession, Vector pt) {
return generateTree(TreeGenerator.TreeType.BIRCH, editSession, pt);
}
@Override
@Deprecated
public boolean generateRedwoodTree(EditSession editSession, Vector pt) {
return generateTree(TreeGenerator.TreeType.REDWOOD, editSession, pt);
}
@Override
@Deprecated
public boolean generateTallRedwoodTree(EditSession editSession, Vector pt) {
return generateTree(TreeGenerator.TreeType.TALL_REDWOOD, editSession, pt);
}
@Override
public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, Vector pt) {
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public void dropItem(Vector pt, BaseItemStack item) {
Level world = getLevel();
Item nukkitItem = new Item(item.getType(), item.getAmount(),
item.getData());
world.dropItem(NukkitUtil.toLocation(world, pt), nukkitItem);
}
@SuppressWarnings("deprecation")
@Override
public boolean isValidBlockType(int type) {
Item item = Item.get(type);
return item != null && item.getId() < 256 && item.canBePlaced();
}
@Override
public void checkLoadedChunk(Vector pt) {
Level world = getLevel();
if (!world.isChunkLoaded(pt.getBlockX() >> 4, pt.getBlockZ() >> 4)) {
world.loadChunk(pt.getBlockX() >> 4, pt.getBlockZ() >> 4);
}
}
@Override
public boolean equals(Object other) {
if (other == null) {
return false;
} else if ((other instanceof NukkitWorld)) {
return ((NukkitWorld) other).getLevel().equals(getLevel());
} else if (other instanceof com.sk89q.worldedit.world.World) {
return ((com.sk89q.worldedit.world.World) other).getName().equals(getName());
} else {
return false;
}
}
@Override
public int hashCode() {
return getLevel().hashCode();
}
@Override
public int getMaxY() {
return 255;
}
@Override
public void fixAfterFastMode(Iterable<BlockVector2D> chunks) {
}
@Override
public boolean playEffect(Vector position, int type, int data) {
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public WorldData getWorldData() {
throw new UnsupportedOperationException("Not implemented yet");
}
@Override
public void simulateBlockMine(Vector pt) {
getLevel().getBlock(setMutable(pt)).onBreak(null);
}
@Override
public BaseBlock getBlock(Vector position) {
return NukkitUtil.getBlock(getLevel(), position);
}
@Override
public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) {
return NukkitUtil.setBlock(getLevel(), position, block);
}
@SuppressWarnings("deprecation")
@Override
public BaseBlock getLazyBlock(Vector position) {
return getBlock(position);
}
@Override
public BaseBiome getBiome(Vector2D position) {
int id = getLevel().getBiomeId(position.getBlockX(), position.getBlockZ());
return new BaseBiome(id);
}
@Override
public boolean setBiome(Vector2D position, BaseBiome biome) {
getLevel().setBiomeId(position.getBlockX(), position.getBlockZ(), biome.getId());
return true;
}
}

View File

@ -0,0 +1,130 @@
/*
* 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.boydti.fawe.nukkit.core;
import cn.nukkit.Nukkit;
import cn.nukkit.Player;
import cn.nukkit.plugin.PluginBase;
import cn.nukkit.utils.Logger;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
import com.sk89q.worldedit.extension.platform.Platform;
import java.io.File;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* The Nukkit implementation of WorldEdit.
*/
public class NukkitWorldEdit extends PluginBase {
private Logger logger;
private static NukkitWorldEdit inst;
public static NukkitWorldEdit inst() {
return inst;
}
private NukkitPlatform platform;
private NukkitConfiguration config;
private File workingDir;
public NukkitWorldEdit() {
inst = this;
}
@Override
public void onEnable() {
// TODO load FAWE
config.load();
this.platform = new NukkitPlatform(this);
WorldEdit.getInstance().getPlatformManager().register(platform);
logger.info("WorldEdit for Nukkit (version " + getInternalVersion() + ") is loaded");
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
}
@Override
public void onDisable() {
WorldEdit.getInstance().getPlatformManager().unregister(platform);
}
/**
* Get the configuration.
*
* @return the Nukkit configuration
*/
public NukkitConfiguration getWEConfig() {
return this.config;
}
/**
* Get the WorldEdit proxy for the given player.
*
* @param player the player
* @return the WorldEdit player
*/
public NukkitPlayer wrapPlayer(Player player) {
checkNotNull(player);
return new NukkitPlayer(platform, player);
}
/**
* Get the session for a player.
*
* @param player the player
* @return the session
*/
public LocalSession getSession(Player player) {
checkNotNull(player);
return WorldEdit.getInstance().getSessionManager().get(wrapPlayer(player));
}
/**
* 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;
}
/**
* Get the version of the WorldEdit Nukkit implementation.
*
* @return a version string
*/
public String getInternalVersion() {
return Nukkit.API_VERSION;
}
}

View File

@ -0,0 +1,145 @@
/*
* 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/>.
*/
// $Id$
package com.boydti.fawe.nukkit.core;
import cn.nukkit.block.Block;
import cn.nukkit.event.EventHandler;
import cn.nukkit.event.EventPriority;
import cn.nukkit.event.Listener;
import cn.nukkit.event.player.PlayerCommandPreprocessEvent;
import cn.nukkit.event.player.PlayerGameModeChangeEvent;
import cn.nukkit.event.player.PlayerInteractEvent;
import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.LocalPlayer;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.WorldVector;
import com.sk89q.worldedit.internal.LocalWorldAdapter;
import com.sk89q.worldedit.world.World;
/**
* Handles all events thrown in relation to a Player
*/
public class WorldEditListener implements Listener {
private NukkitWorldEdit plugin;
/**
* Called when a player plays an animation, such as an arm swing
*
* @param event Relevant event details
*/
/**
* Construct the object;
*
* @param plugin the plugin
*/
public WorldEditListener(NukkitWorldEdit plugin) {
this.plugin = plugin;
}
@EventHandler(priority = EventPriority.MONITOR, ignoreCancelled = true)
public void onGamemode(PlayerGameModeChangeEvent event) {
// this will automatically refresh their session, we don't have to do anything
WorldEdit.getInstance().getSession(plugin.wrapPlayer(event.getPlayer()));
}
/**
* Called when a player attempts to use a command
*
* @param event Relevant event details
*/
@EventHandler(ignoreCancelled = true,priority = EventPriority.MONITOR)
public void onPlayerCommandPreprocess(PlayerCommandPreprocessEvent event) {
String[] split = event.getMessage().split(" ");
if (split.length > 0) {
split[0] = split[0].substring(1);
split = WorldEdit.getInstance().getPlatformManager().getCommandManager().commandDetection(split);
}
final String newMessage = "/" + StringUtil.joinString(split, " ");
if (!newMessage.equals(event.getMessage())) {
event.setMessage(newMessage);
plugin.getServer().getPluginManager().callEvent(event);
if (!event.isCancelled()) {
if (!event.getMessage().isEmpty()) {
plugin.getServer().dispatchCommand(event.getPlayer(), event.getMessage().substring(1));
}
event.setCancelled(true);
}
}
}
/**
* Called when a player interacts
*
* @param event Relevant event details
*/
@EventHandler(ignoreCancelled = true,priority = EventPriority.MONITOR)
public void onPlayerInteract(PlayerInteractEvent event) {
final LocalPlayer player = plugin.wrapPlayer(event.getPlayer());
final World world = player.getWorld();
final WorldEdit we = WorldEdit.getInstance();
int action = event.getAction();
if (action == PlayerInteractEvent.LEFT_CLICK_BLOCK) {
final Block clickedBlock = event.getBlock();
final WorldVector pos = new WorldVector(LocalWorldAdapter.adapt(world), clickedBlock.getX(), clickedBlock.getY(), clickedBlock.getZ());
if (we.handleBlockLeftClick(player, pos)) {
event.setCancelled(true);
}
if (we.handleArmSwing(player)) {
event.setCancelled(true);
}
} else if (action == PlayerInteractEvent.LEFT_CLICK_AIR) {
if (we.handleArmSwing(player)) {
event.setCancelled(true);
}
} else if (action == PlayerInteractEvent.RIGHT_CLICK_BLOCK) {
final Block clickedBlock = event.getBlock();
final WorldVector pos = new WorldVector(LocalWorldAdapter.adapt(world), clickedBlock.getX(),
clickedBlock.getY(), clickedBlock.getZ());
if (we.handleBlockRightClick(player, pos)) {
event.setCancelled(true);
}
if (we.handleRightClick(player)) {
event.setCancelled(true);
}
} else if (action == PlayerInteractEvent.RIGHT_CLICK_AIR) {
if (we.handleRightClick(player)) {
event.setCancelled(true);
}
}
}
}

View File

@ -1,3 +1,3 @@
rootProject.name = 'FastAsyncWorldEdit'
include 'core', 'bukkit0', 'bukkit1710', 'bukkit18', 'bukkit19', 'bukkit110', 'forge1710', 'forge189', 'forge194', 'forge110', 'favs'
include 'core', 'bukkit0', 'bukkit1710', 'bukkit18', 'bukkit19', 'bukkit110', 'forge1710', 'forge189', 'forge194', 'forge110', 'favs', 'nukkit'