From 2db47f8fd434066013e96f56315273a303a2ea36 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Tue, 2 Feb 2016 01:28:27 -0500 Subject: [PATCH 01/39] Initial work on WorldEdit Sponge --- settings.gradle | 2 +- worldedit-sponge/build.gradle | 99 +++++++ worldedit-sponge/src/main/ant/build.xml | 150 ++++++++++ .../worldedit/sponge/CommandWrapper.java | 71 +++++ .../worldedit/sponge/ForgeWorldData.java | 47 +++ .../com/sk89q/worldedit/sponge/IDHelper.java | 58 ++++ .../sk89q/worldedit/sponge/NBTConverter.java | 236 ++++++++++++++++ .../com/sk89q/worldedit/sponge/NMSHelper.java | 49 ++++ .../sponge/SponePermissionsProvider.java | 32 +++ .../sk89q/worldedit/sponge/SpongeAdapter.java | 45 +++ .../worldedit/sponge/SpongeBiomeRegistry.java | 81 ++++++ .../worldedit/sponge/SpongeConfiguration.java | 45 +++ .../sk89q/worldedit/sponge/SpongeEntity.java | 102 +++++++ .../worldedit/sponge/SpongeEntityType.java | 142 ++++++++++ .../worldedit/sponge/SpongeForgeWorld.java | 246 ++++++++++++++++ .../worldedit/sponge/SpongePlatform.java | 174 ++++++++++++ .../sk89q/worldedit/sponge/SpongePlayer.java | 220 +++++++++++++++ .../sk89q/worldedit/sponge/SpongeWorld.java | 251 ++++++++++++++++ .../worldedit/sponge/SpongeWorldEdit.java | 267 ++++++++++++++++++ .../worldedit/sponge/ThreadSafeCache.java | 81 ++++++ .../worldedit/sponge/TileEntityBaseBlock.java | 40 +++ .../worldedit/sponge/TileEntityUtils.java | 146 ++++++++++ .../main/resources/META-INF/worldedit_at.cfg | 4 + .../resources/defaults/worldedit.properties | 32 +++ 24 files changed, 2619 insertions(+), 1 deletion(-) create mode 100644 worldedit-sponge/build.gradle create mode 100644 worldedit-sponge/src/main/ant/build.xml create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandWrapper.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ForgeWorldData.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NBTConverter.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NMSHelper.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SponePermissionsProvider.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntity.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntityType.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityBaseBlock.java create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityUtils.java create mode 100644 worldedit-sponge/src/main/resources/META-INF/worldedit_at.cfg create mode 100644 worldedit-sponge/src/main/resources/defaults/worldedit.properties diff --git a/settings.gradle b/settings.gradle index 271359482..576283ecc 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,3 +1,3 @@ rootProject.name = 'worldedit' -include 'worldedit-core', 'worldedit-bukkit', 'worldedit-forge' \ No newline at end of file +include 'worldedit-core', 'worldedit-bukkit', 'worldedit-forge', 'worldedit-sponge' \ No newline at end of file diff --git a/worldedit-sponge/build.gradle b/worldedit-sponge/build.gradle new file mode 100644 index 000000000..b5f073a29 --- /dev/null +++ b/worldedit-sponge/build.gradle @@ -0,0 +1,99 @@ +apply plugin: 'eclipse' +apply plugin: 'idea' + +buildscript { + repositories { + mavenCentral() + maven { url = "http://files.minecraftforge.net/maven" } + maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" } + jcenter() + } + + dependencies { + classpath 'net.minecraftforge.gradle:ForgeGradle:2.1-SNAPSHOT' + } +} + +apply plugin: 'net.minecraftforge.gradle.forge' + +dependencies { + compile project(':worldedit-core') + compile 'org.spongepowered:spongeapi:3.1.0-SNAPSHOT' + compile('org.spongepowered:spongeforge:1.8-1577-2.1-DEV-957') { + exclude module: 'spongeapi' + exclude module: 'spongecommon' + } + testCompile group: 'org.mockito', name: 'mockito-core', version:'1.9.0-rc1' +} + +repositories { + maven { + name = 'forge' + url = 'http://files.minecraftforge.net/maven' + } + maven { + name = "Sponge" + url = "https://repo.spongepowered.org/maven" + } +} + +sourceCompatibility = 1.8 +targetCompatibility = 1.8 + +version = "6.1.1" +ext.forgeVersion = "11.15.0.1695" +ext.internalVersion = version + ";" + gitCommitHash + +minecraft { + version = "1.8.9-${project.forgeVersion}" + mappings = "snapshot_20160111" + runDir = 'run' + + replaceIn "com/sk89q/worldedit/forge/ForgeWorldEdit.java" + replace "%VERSION%", project.version +} + +project.archivesBaseName = "${project.archivesBaseName}-mc${minecraft.version}" + +processResources { + from (sourceSets.main.resources.srcDirs) { + expand 'version': project.version, + 'mcVersion': project.minecraft.version, + 'forgeVersion': project.forgeVersion, + 'internalVersion': project.internalVersion + include 'mcmod.info' + } + + from (sourceSets.main.resources.srcDirs) { + exclude 'mcmod.info' + } +} + +jar { + manifest { + attributes("Class-Path": "truezip.jar WorldEdit/truezip.jar js.jar WorldEdit/js.jar", + "WorldEdit-Version": version, + "FMLAT": "worldedit_at.cfg") + } +} + +shadowJar { + dependencies { + include(dependency(':worldedit-core')) + } +} + +reobf { + shadowJar { + mappingType = 'SEARGE' + } +} + +task deobfJar(type: Jar) { + from sourceSets.main.output + classifier = 'dev' +} + +artifacts { + archives deobfJar +} diff --git a/worldedit-sponge/src/main/ant/build.xml b/worldedit-sponge/src/main/ant/build.xml new file mode 100644 index 000000000..5753b52ce --- /dev/null +++ b/worldedit-sponge/src/main/ant/build.xml @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandWrapper.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandWrapper.java new file mode 100644 index 000000000..62b0dadd6 --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandWrapper.java @@ -0,0 +1,71 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.sk89q.worldedit.util.command.CommandMapping; +import org.spongepowered.api.command.CommandCallable; +import org.spongepowered.api.command.CommandException; +import org.spongepowered.api.command.CommandResult; +import org.spongepowered.api.command.CommandSource; +import org.spongepowered.api.text.Text; +import org.spongepowered.api.text.Texts; + +import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +public class CommandWrapper implements CommandCallable { + private CommandMapping command; + + protected CommandWrapper(CommandMapping command) { + this.command = command; + } + + @Override + public CommandResult process(CommandSource source, String arguments) throws CommandException { + return null; + } + + @Override + public List getSuggestions(CommandSource source, String arguments) throws CommandException { + return null; + } + + @Override + public boolean testPermission(CommandSource source) { + return true; + } + + @Override + public Optional getShortDescription(CommandSource source) { + return null; + } + + @Override + public Optional getHelp(CommandSource source) { + return null; + } + + @Override + public Text getUsage(CommandSource source) { + return Text.of(command.getDescription().getUsage()); + } +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ForgeWorldData.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ForgeWorldData.java new file mode 100644 index 000000000..177932daf --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ForgeWorldData.java @@ -0,0 +1,47 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.sk89q.worldedit.world.registry.BiomeRegistry; +import com.sk89q.worldedit.world.registry.LegacyWorldData; + +/** + * World data for the Forge platform. + */ +class ForgeWorldData extends LegacyWorldData { + + private static final ForgeWorldData INSTANCE = new ForgeWorldData(); + private final BiomeRegistry biomeRegistry = new SpongeBiomeRegistry(); + + @Override + public BiomeRegistry getBiomeRegistry() { + return biomeRegistry; + } + + /** + * Get a static instance. + * + * @return an instance + */ + public static ForgeWorldData getInstance() { + return INSTANCE; + } + +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java new file mode 100644 index 000000000..13fc241bb --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java @@ -0,0 +1,58 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.sk89q.worldedit.entity.BaseEntity; +import org.spongepowered.api.block.BlockType; +import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.item.ItemType; +import org.spongepowered.api.world.biome.BiomeType; + +final class IDHelper { + + private IDHelper() { } + + public static int resolve(ItemType type) { + return 0; + } + + public static int resolve(BlockType type) { + return 0; + } + + public static int resolve(BiomeType type) { + return 0; + } + + + public static ItemType resolveItem(int ID) { + return null; + } + + public static BlockType resolveBlock(int ID) { + return null; + } + + public static BiomeType resolveBiome(int ID) { + return null; + } + + +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NBTConverter.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NBTConverter.java new file mode 100644 index 000000000..a026a51cf --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NBTConverter.java @@ -0,0 +1,236 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.sk89q.jnbt.*; +import net.minecraft.nbt.*; + +import java.util.*; +import java.util.Map.Entry; + +/** + * Converts between JNBT and Minecraft NBT classes. + */ +final class NBTConverter { + + private NBTConverter() { + } + + public static NBTBase 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()); + } + } + + public static NBTTagIntArray toNative(IntArrayTag tag) { + int[] value = tag.getValue(); + return new NBTTagIntArray(Arrays.copyOf(value, value.length)); + } + + public static NBTTagList toNative(ListTag tag) { + NBTTagList list = new NBTTagList(); + for (Tag child : tag.getValue()) { + if (child instanceof EndTag) { + continue; + } + list.appendTag(toNative(child)); + } + return list; + } + + public static NBTTagLong toNative(LongTag tag) { + return new NBTTagLong(tag.getValue()); + } + + public static NBTTagString toNative(StringTag tag) { + return new NBTTagString(tag.getValue()); + } + + public static NBTTagInt toNative(IntTag tag) { + return new NBTTagInt(tag.getValue()); + } + + public static NBTTagByte toNative(ByteTag tag) { + return new NBTTagByte(tag.getValue()); + } + + public static NBTTagByteArray toNative(ByteArrayTag tag) { + byte[] value = tag.getValue(); + return new NBTTagByteArray(Arrays.copyOf(value, value.length)); + } + + public static NBTTagCompound toNative(CompoundTag tag) { + NBTTagCompound compound = new NBTTagCompound(); + for (Entry child : tag.getValue().entrySet()) { + compound.setTag(child.getKey(), toNative(child.getValue())); + } + return compound; + } + + public static NBTTagFloat toNative(FloatTag tag) { + return new NBTTagFloat(tag.getValue()); + } + + public static NBTTagShort toNative(ShortTag tag) { + return new NBTTagShort(tag.getValue()); + } + + public static NBTTagDouble toNative(DoubleTag tag) { + return new NBTTagDouble(tag.getValue()); + } + + public static Tag fromNative(NBTBase other) { + if (other instanceof NBTTagIntArray) { + return fromNative((NBTTagIntArray) other); + + } else if (other instanceof NBTTagList) { + return fromNative((NBTTagList) other); + + } else if (other instanceof NBTTagEnd) { + return fromNative((NBTTagEnd) other); + + } else if (other instanceof NBTTagLong) { + return fromNative((NBTTagLong) other); + + } else if (other instanceof NBTTagString) { + return fromNative((NBTTagString) other); + + } else if (other instanceof NBTTagInt) { + return fromNative((NBTTagInt) other); + + } else if (other instanceof NBTTagByte) { + return fromNative((NBTTagByte) other); + + } else if (other instanceof NBTTagByteArray) { + return fromNative((NBTTagByteArray) other); + + } else if (other instanceof NBTTagCompound) { + return fromNative((NBTTagCompound) other); + + } else if (other instanceof NBTTagFloat) { + return fromNative((NBTTagFloat) other); + + } else if (other instanceof NBTTagShort) { + return fromNative((NBTTagShort) other); + + } else if (other instanceof NBTTagDouble) { + return fromNative((NBTTagDouble) other); + } else { + throw new IllegalArgumentException("Can't convert other of type " + other.getClass().getCanonicalName()); + } + } + + public static IntArrayTag fromNative(NBTTagIntArray other) { + int[] value = other.getIntArray(); + return new IntArrayTag(Arrays.copyOf(value, value.length)); + } + + public static ListTag fromNative(NBTTagList other) { + other = (NBTTagList) other.copy(); + List list = new ArrayList(); + Class listClass = StringTag.class; + int tags = other.tagCount(); + for (int i = 0; i < tags; i++) { + Tag child = fromNative(other.removeTag(0)); + list.add(child); + listClass = child.getClass(); + } + return new ListTag(listClass, list); + } + + public static EndTag fromNative(NBTTagEnd other) { + return new EndTag(); + } + + public static LongTag fromNative(NBTTagLong other) { + return new LongTag(other.getLong()); + } + + public static StringTag fromNative(NBTTagString other) { + return new StringTag(other.getString()); + } + + public static IntTag fromNative(NBTTagInt other) { + return new IntTag(other.getInt()); + } + + public static ByteTag fromNative(NBTTagByte other) { + return new ByteTag(other.getByte()); + } + + public static ByteArrayTag fromNative(NBTTagByteArray other) { + byte[] value = other.getByteArray(); + return new ByteArrayTag(Arrays.copyOf(value, value.length)); + } + + public static CompoundTag fromNative(NBTTagCompound other) { + @SuppressWarnings("unchecked") Set tags = other.getKeySet(); + Map map = new HashMap(); + for (String tagName : tags) { + map.put(tagName, fromNative(other.getTag(tagName))); + } + return new CompoundTag(map); + } + + public static FloatTag fromNative(NBTTagFloat other) { + return new FloatTag(other.getFloat()); + } + + public static ShortTag fromNative(NBTTagShort other) { + return new ShortTag(other.getShort()); + } + + public static DoubleTag fromNative(NBTTagDouble other) { + return new DoubleTag(other.getDouble()); + } + +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NMSHelper.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NMSHelper.java new file mode 100644 index 000000000..da8abf3e5 --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NMSHelper.java @@ -0,0 +1,49 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.sk89q.worldedit.blocks.BaseItemStack; +import com.sk89q.worldedit.entity.BaseEntity; +import net.minecraft.item.Item; +import net.minecraft.nbt.NBTTagCompound; +import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.item.inventory.ItemStack; + +import java.util.Map; + +final class NMSHelper { + + private NMSHelper() { } + + public static ItemStack makeSpongeStack(BaseItemStack itemStack) { + net.minecraft.item.ItemStack newStack = new net.minecraft.item.ItemStack(Item.getItemById(itemStack.getType()), itemStack.getAmount(), itemStack.getData()); + for (Map.Entry entry : itemStack.getEnchantments().entrySet()) { + newStack.addEnchantment(net.minecraft.enchantment.Enchantment.getEnchantmentById(entry.getKey()), entry.getValue()); + } + return (ItemStack) (Object) newStack; + } + + public static BaseEntity createBaseEntity(Entity entity) { + String id = entity.getType().getId(); + NBTTagCompound tag = new NBTTagCompound(); + ((net.minecraft.entity.Entity) entity).writeToNBT(tag); + return new BaseEntity(id, NBTConverter.fromNative(tag)); + } +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SponePermissionsProvider.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SponePermissionsProvider.java new file mode 100644 index 000000000..967b25a55 --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SponePermissionsProvider.java @@ -0,0 +1,32 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import org.spongepowered.api.command.CommandCallable; +import org.spongepowered.api.entity.living.player.Player; + +public class SponePermissionsProvider { + + public boolean hasPermission(Player player, String permission) { + return player.hasPermission(permission); + } + + public void registerPermission(CommandCallable command, String permission) { } +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java new file mode 100644 index 000000000..3d9c756d6 --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java @@ -0,0 +1,45 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.flowpowered.math.vector.Vector3d; +import com.flowpowered.math.vector.Vector3i; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.world.NullWorld; +import com.sk89q.worldedit.world.World; + +final class SpongeAdapter { + + private SpongeAdapter() { + } + + public static World adapt(org.spongepowered.api.world.World world) { + return new SpongeForgeWorld(world); + } + + public static Location adapt(org.spongepowered.api.world.Location loc, Vector3d rot) { + Vector position = new Vector(loc.getX(), loc.getY(), loc.getZ()); + Vector dir = new Vector(rot.getX(), rot.getY(), rot.getZ()); + + return new Location(SpongeAdapter.adapt(loc.getExtent()), position, dir); + } +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java new file mode 100644 index 000000000..5bf2ef088 --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java @@ -0,0 +1,81 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.biome.BiomeData; +import com.sk89q.worldedit.world.registry.BiomeRegistry; + +import org.spongepowered.api.Sponge; +import org.spongepowered.api.world.biome.BiomeType; + +import javax.annotation.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Provides access to biome data in Forge. + */ +class SpongeBiomeRegistry implements BiomeRegistry { + + @Nullable + @Override + public BaseBiome createFromId(int id) { + return new BaseBiome(id); + } + + @Override + public List getBiomes() { + List list = new ArrayList(); + for (BiomeType biome : Sponge.getGame().getRegistry().getAllOf(BiomeType.class)) { + list.add(new BaseBiome(IDHelper.resolve(biome))); + } + return list; + } + + @Nullable + @Override + public BiomeData getData(BaseBiome biome) { + return new SpongeBiomeData(IDHelper.resolveBiome(biome.getId())); + } + + /** + * Cached biome data information. + */ + private static class SpongeBiomeData implements BiomeData { + private final BiomeType biome; + + /** + * Create a new instance. + * + * @param biome the base biome + */ + private SpongeBiomeData(BiomeType biome) { + this.biome = biome; + } + + @Override + public String getName() { + return biome.getName(); + } + } + +} \ No newline at end of file diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java new file mode 100644 index 000000000..13c755fd4 --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java @@ -0,0 +1,45 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.sk89q.worldedit.util.PropertiesConfiguration; + +import java.io.File; + +public class SpongeConfiguration extends PropertiesConfiguration { + + public boolean creativeEnable = false; + public boolean cheatMode = false; + + public SpongeConfiguration(SpongeWorldEdit mod) { + super(new File(mod.getWorkingDir() + File.separator + "worldedit.properties")); + } + + @Override + protected void loadExtra() { + creativeEnable = getBool("use-in-creative", false); + cheatMode = getBool("cheat-mode", false); + } + + @Override + public File getWorkingDirectory() { + return SpongeWorldEdit.inst.getWorkingDir(); + } +} \ No newline at end of file diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntity.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntity.java new file mode 100644 index 000000000..5c93aeafe --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntity.java @@ -0,0 +1,102 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.flowpowered.math.vector.Vector3d; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; +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 org.spongepowered.api.world.World; + +import javax.annotation.Nullable; +import java.lang.ref.WeakReference; + +import static com.google.common.base.Preconditions.checkNotNull; + +class SpongeEntity implements Entity { + + private final WeakReference entityRef; + + SpongeEntity(org.spongepowered.api.entity.Entity entity) { + checkNotNull(entity); + this.entityRef = new WeakReference<>(entity); + } + + @Override + public BaseEntity getState() { + org.spongepowered.api.entity.Entity entity = entityRef.get(); + if (entity != null) { + return NMSHelper.createBaseEntity(entity); + } else { + return null; + } + } + + @Override + public Location getLocation() { + org.spongepowered.api.entity.Entity entity = entityRef.get(); + if (entity != null) { + org.spongepowered.api.world.Location entityLoc = entity.getLocation(); + Vector3d entityRot = entity.getRotation(); + + return SpongeAdapter.adapt(entityLoc, entityRot); + } else { + return new Location(NullWorld.getInstance()); + } + } + + @Override + public Extent getExtent() { + org.spongepowered.api.entity.Entity entity = entityRef.get(); + if (entity != null) { + return SpongeAdapter.adapt(entity.getWorld()); + } else { + return NullWorld.getInstance(); + } + } + + @Override + public boolean remove() { + org.spongepowered.api.entity.Entity entity = entityRef.get(); + if (entity != null) { + entity.remove(); + } + return true; + } + + @SuppressWarnings("unchecked") + @Nullable + @Override + public T getFacet(Class cls) { + org.spongepowered.api.entity.Entity entity = entityRef.get(); + if (entity != null) { + if (EntityType.class.isAssignableFrom(cls)) { + return (T) new SpongeEntityType(entity); + } else { + return null; + } + } else { + return null; + } + } +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntityType.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntityType.java new file mode 100644 index 000000000..afd2393cc --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntityType.java @@ -0,0 +1,142 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.sk89q.worldedit.entity.metadata.EntityType; +import org.spongepowered.api.data.key.Keys; +import org.spongepowered.api.entity.Entity; +import org.spongepowered.api.entity.ExperienceOrb; +import org.spongepowered.api.entity.FallingBlock; +import org.spongepowered.api.entity.Item; +import org.spongepowered.api.entity.explosive.PrimedTNT; +import org.spongepowered.api.entity.hanging.ItemFrame; +import org.spongepowered.api.entity.hanging.Painting; +import org.spongepowered.api.entity.living.*; +import org.spongepowered.api.entity.living.animal.Animal; +import org.spongepowered.api.entity.living.golem.Golem; +import org.spongepowered.api.entity.projectile.Projectile; +import org.spongepowered.api.entity.vehicle.Boat; +import org.spongepowered.api.entity.vehicle.minecart.Minecart; +import org.spongepowered.api.text.Text; + +import java.util.Optional; +import java.util.UUID; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class SpongeEntityType implements EntityType { + + private final Entity entity; + + public SpongeEntityType(Entity entity) { + checkNotNull(entity); + this.entity = entity; + } + + @Override + public boolean isPlayerDerived() { + return entity instanceof Humanoid; + } + + @Override + public boolean isProjectile() { + return entity instanceof Projectile; + } + + @Override + public boolean isItem() { + return entity instanceof Item; + } + + @Override + public boolean isFallingBlock() { + return entity instanceof FallingBlock; + } + + @Override + public boolean isPainting() { + return entity instanceof Painting; + } + + @Override + public boolean isItemFrame() { + return entity instanceof ItemFrame; + } + + @Override + public boolean isBoat() { + return entity instanceof Boat; + } + + @Override + public boolean isMinecart() { + return entity instanceof Minecart; + } + + @Override + public boolean isTNT() { + return entity instanceof PrimedTNT; + } + + @Override + public boolean isExperienceOrb() { + return entity instanceof ExperienceOrb; + } + + @Override + public boolean isLiving() { + return entity instanceof Living; + } + + @Override + public boolean isAnimal() { + return entity instanceof Animal; + } + + @Override + public boolean isAmbient() { + return entity instanceof Ambient; + } + + @Override + public boolean isNPC() { + return entity instanceof Villager; + } + + @Override + public boolean isGolem() { + return entity instanceof Golem; + } + + @Override + public boolean isTamed() { + return entity.get(Keys.TAMED_OWNER).orElse(Optional.empty()).isPresent(); + } + + @Override + public boolean isTagged() { + return entity.get(Keys.DISPLAY_NAME).orElse(Text.EMPTY).isEmpty(); + } + + @Override + public boolean isArmorStand() { + return entity instanceof ArmorStand; + } +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java new file mode 100644 index 000000000..c6c16cf1e --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java @@ -0,0 +1,246 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.flowpowered.math.vector.Vector3d; +import com.flowpowered.math.vector.Vector3i; +import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.*; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.LazyBlock; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.internal.Constants; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.*; +import net.minecraft.block.*; +import net.minecraft.block.state.IBlockState; +import net.minecraft.init.Blocks; +import net.minecraft.inventory.IInventory; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.BlockPos; +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.IChunkProvider; +import net.minecraft.world.gen.ChunkProviderServer; +import net.minecraft.world.gen.feature.*; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.block.BlockSnapshot; +import org.spongepowered.api.block.BlockState; +import org.spongepowered.api.entity.EntitySnapshot; +import org.spongepowered.api.entity.EntityType; +import org.spongepowered.api.world.Location; +import org.spongepowered.api.world.World; +import org.spongepowered.common.block.SpongeBlockSnapshot; +import org.spongepowered.common.block.SpongeBlockSnapshotBuilder; +import org.spongepowered.common.entity.SpongeEntitySnapshot; +import org.spongepowered.common.entity.SpongeEntitySnapshotBuilder; + +import javax.annotation.Nullable; +import java.util.*; +import java.util.logging.Level; + +import static com.google.common.base.Preconditions.checkNotNull; + +public class SpongeForgeWorld extends SpongeWorld { + + private final SpongeBlockSnapshotBuilder blockBuilder = new SpongeBlockSnapshotBuilder(); + private final SpongeEntitySnapshotBuilder entityBuilder = new SpongeEntitySnapshotBuilder(); + + private static final IBlockState JUNGLE_LOG = Blocks.log.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE); + private static final IBlockState JUNGLE_LEAF = Blocks.leaves.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE).withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); + private static final IBlockState JUNGLE_SHRUB = Blocks.leaves.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.OAK).withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); + + /** + * Construct a new world. + * + * @param world the world + */ + public SpongeForgeWorld(World world) { + super(world); + } + + @Override + protected BlockSnapshot createBlockSnapshot(Vector position, BaseBlock block) { + this.blockBuilder.reset(); + Location location = new Location<>(getWorld(), new Vector3i(position.getX(), position.getY(), position.getZ())); + + this.blockBuilder.blockState((BlockState) Block.getBlockById(block.getId()).getStateFromMeta(block.getData())); + this.blockBuilder.worldId(location.getExtent().getUniqueId()); + this.blockBuilder.position(location.getBlockPosition()); + + if (block.hasNbtData()) { + this.blockBuilder.unsafeNbt(NBTConverter.toNative(block.getNbtData())); + } + + return new SpongeBlockSnapshot(this.blockBuilder, 0); + } + + @Override + protected EntitySnapshot createEntitySnapshot(com.sk89q.worldedit.util.Location location, BaseEntity entity) { + this.entityBuilder.reset(); + + this.entityBuilder.position(new Vector3d(location.getX(), location.getY(), location.getZ())); + // TODO Rotation code + // this.entityBuilder.rotation() + this.entityBuilder.type(Sponge.getRegistry().getType(EntityType.class, entity.getTypeId()).get()); + if (entity.hasNbtData()) { + this.entityBuilder.unsafeCompound(NBTConverter.toNative(entity.getNbtData())); + } + return this.entityBuilder.build(); + } + + @Override + public boolean clearContainerBlockContents(Vector position) { + BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + TileEntity tile =((net.minecraft.world.World) getWorld()).getTileEntity(pos); + if (tile instanceof IInventory) { + IInventory inv = (IInventory) tile; + int size = inv.getSizeInventory(); + for (int i = 0; i < size; i++) { + inv.setInventorySlotContents(i, null); + } + return true; + } + return false; + } + + @Override + public boolean regenerate(Region region, EditSession editSession) { + BaseBlock[] history = new BaseBlock[256 * (getMaxY() + 1)]; + + for (Vector2D chunk : region.getChunks()) { + Vector min = new Vector(chunk.getBlockX() * 16, 0, chunk.getBlockZ() * 16); + + 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 { + Set chunks = region.getChunks(); + IChunkProvider provider = ((net.minecraft.world.World) getWorld()).getChunkProvider(); + if (!(provider instanceof ChunkProviderServer)) { + return false; + } + ChunkProviderServer chunkServer = (ChunkProviderServer) provider; + IChunkProvider chunkProvider = chunkServer.serverChunkGenerator; + + for (Vector2D coord : chunks) { + long pos = ChunkCoordIntPair.chunkXZ2Int(coord.getBlockX(), coord.getBlockZ()); + Chunk mcChunk; + if (chunkServer.chunkExists(coord.getBlockX(), coord.getBlockZ())) { + mcChunk = chunkServer.loadChunk(coord.getBlockX(), coord.getBlockZ()); + mcChunk.onChunkUnload(); + } + chunkServer.droppedChunksSet.remove(pos); + chunkServer.id2ChunkMap.remove(pos); + mcChunk = chunkProvider.provideChunk(coord.getBlockX(), coord.getBlockZ()); + chunkServer.id2ChunkMap.add(pos, mcChunk); + chunkServer.loadedChunks.add(mcChunk); + if (mcChunk != null) { + mcChunk.onChunkLoad(); + mcChunk.populateChunk(chunkProvider, chunkProvider, coord.getBlockX(), coord.getBlockZ()); + } + } + } catch (Throwable t) { + logger.log(Level.WARNING, "Failed to generate chunk", t); + return false; + } + + 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; + + if (!region.contains(pt)) + editSession.smartSetBlock(pt, history[index]); + else { + editSession.rememberChange(pt, history[index], editSession.rawGetBlock(pt)); + } + } + } + } + } + + return false; + } + + @Nullable + private static WorldGenerator createWorldGenerator(TreeGenerator.TreeType type) { + switch (type) { + case TREE: return new WorldGenTrees(true); + case BIG_TREE: return new WorldGenBigTree(true); + case REDWOOD: return new WorldGenTaiga2(true); + case TALL_REDWOOD: return new WorldGenTaiga1(); + case BIRCH: return new WorldGenForest(true, false); + case JUNGLE: return new WorldGenMegaJungle(true, 10, 20, JUNGLE_LOG, JUNGLE_LEAF); + case SMALL_JUNGLE: return new WorldGenTrees(true, 4 + random.nextInt(7), JUNGLE_LOG, JUNGLE_LEAF, false); + case SHORT_JUNGLE: return new WorldGenTrees(true, 4 + random.nextInt(7), JUNGLE_LOG, JUNGLE_LEAF, true); + case JUNGLE_BUSH: return new WorldGenShrub(JUNGLE_LOG, JUNGLE_SHRUB); + case RED_MUSHROOM: return new WorldGenBigMushroom(Blocks.brown_mushroom_block); + case BROWN_MUSHROOM: return new WorldGenBigMushroom(Blocks.red_mushroom_block); + case SWAMP: return new WorldGenSwamp(); + case ACACIA: return new WorldGenSavannaTree(true); + case DARK_OAK: return new WorldGenCanopyTree(true); + case MEGA_REDWOOD: return new WorldGenMegaPineTree(false, random.nextBoolean()); + case TALL_BIRCH: return new WorldGenForest(true, true); + case RANDOM: + case PINE: + case RANDOM_REDWOOD: + default: + return null; + } + } + + @Override + public boolean generateTree(TreeGenerator.TreeType type, EditSession editSession, Vector pos) throws MaxChangedBlocksException { + WorldGenerator generator = createWorldGenerator(type); + return generator != null && generator.generate((net.minecraft.world.World) getWorld(), random, new BlockPos(pos.getX(), pos.getY(), pos.getZ())); + } + + @Override + public BaseBlock getBlock(Vector position) { + World world = getWorld(); + BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + IBlockState state = ((net.minecraft.world.World) world).getBlockState(pos); + TileEntity tile = ((net.minecraft.world.World) world).getTileEntity(pos); + + if (tile != null) { + return new TileEntityBaseBlock(Block.getIdFromBlock(state.getBlock()), state.getBlock().getMetaFromState(state), tile); + } else { + return new BaseBlock(Block.getIdFromBlock(state.getBlock()), state.getBlock().getMetaFromState(state)); + } + } + + @Override + public BaseBlock getLazyBlock(Vector position) { + World world = getWorld(); + BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()); + IBlockState state = ((net.minecraft.world.World) world).getBlockState(pos); + return new LazyBlock(Block.getIdFromBlock(state.getBlock()), state.getBlock().getMetaFromState(state), this, position); + } +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java new file mode 100644 index 000000000..6790ccc61 --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java @@ -0,0 +1,174 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +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.Dispatcher; +import com.sk89q.worldedit.world.World; + +import org.spongepowered.api.Sponge; +import org.spongepowered.api.entity.EntityType; +import org.spongepowered.api.item.ItemType; +import org.spongepowered.api.scheduler.Task; + +import javax.annotation.Nullable; + +import java.util.*; + +class SpongePlatform extends AbstractPlatform implements MultiUserPlatform { + + private final SpongeWorldEdit mod; + private boolean hookingEvents = false; + + SpongePlatform(SpongeWorldEdit mod) { + this.mod = mod; + } + + boolean isHookingEvents() { + return hookingEvents; + } + + @Override + public int resolveItem(String name) { + if (name == null) return 0; + + Optional optType = Sponge.getRegistry().getType(ItemType.class, name); + + if (optType.isPresent()) { + return IDHelper.resolve(optType.get()); + } + + return 0; + } + + @Override + public boolean isValidMobType(String type) { + return Sponge.getRegistry().getType(EntityType.class, type).isPresent(); + } + + @Override + public void reload() { + getConfiguration().load(); + } + + @Override + public int schedule(long delay, long period, Runnable task) { + Task.builder().delayTicks(delay).intervalTicks(period).execute(task).submit(SpongeWorldEdit.inst); + return 0; // TODO This isn't right, but we only check for -1 values + } + + @Override + public List getWorlds() { + Collection worlds = Sponge.getServer().getWorlds(); + List ret = new ArrayList<>(worlds.size()); + for (org.spongepowered.api.world.World world : worlds) { + ret.add(new SpongeForgeWorld(world)); + } + return ret; + } + + @Nullable + @Override + public Player matchPlayer(Player player) { + if (player instanceof SpongePlayer) { + return player; + } else { + Optional optPlayer = Sponge.getServer().getPlayer(player.getUniqueId()); + return optPlayer.isPresent() ? new SpongePlayer(this, optPlayer.get()) : null; + } + } + + @Nullable + @Override + public World matchWorld(World world) { + if (world instanceof SpongeWorld) { + return world; + } else { + for (org.spongepowered.api.world.World ws : Sponge.getServer().getWorlds()) { + if (ws.getName().equals(world.getName())) { + return new SpongeForgeWorld(ws); + } + } + + return null; + } + } + + @Override + public void registerCommands(Dispatcher dispatcher) { + for (final CommandMapping command : dispatcher.getCommands()) { + Sponge.getCommandManager().register(SpongeWorldEdit.inst, new CommandWrapper(command), command.getAllAliases()); + } + } + + @Override + public void registerGameHooks() { + // We registered the events already anyway, so we just 'turn them on' + hookingEvents = true; + } + + @Override + public SpongeConfiguration getConfiguration() { + return mod.getConfig(); + } + + @Override + public String getVersion() { + return mod.getInternalVersion(); + } + + @Override + public String getPlatformName() { + return "Sponge-Official"; + } + + @Override + public String getPlatformVersion() { + return mod.getInternalVersion(); + } + + @Override + public Map getCapabilities() { + Map capabilities = new EnumMap<>(Capability.class); + capabilities.put(Capability.CONFIGURATION, Preference.PREFER_OTHERS); + // TODO WorldEditCUI Support + // 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 getConnectedUsers() { + List users = new ArrayList(); + for (org.spongepowered.api.entity.living.player.Player player : Sponge.getServer().getOnlinePlayers()) { + users.add(new SpongePlayer(this, player)); + } + return users; + } +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java new file mode 100644 index 000000000..d2086533b --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -0,0 +1,220 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.flowpowered.math.vector.Vector3d; +import com.sk89q.util.StringUtil; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.extension.platform.AbstractPlayerActor; +import com.sk89q.worldedit.extent.inventory.BlockBag; +import com.sk89q.worldedit.internal.LocalWorldAdapter; +import com.sk89q.worldedit.internal.cui.CUIEvent; +import com.sk89q.worldedit.session.SessionKey; +import com.sk89q.worldedit.util.Location; + +import org.spongepowered.api.Sponge; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.item.inventory.ItemStack; +import org.spongepowered.api.text.Text; +import org.spongepowered.api.text.format.TextColor; +import org.spongepowered.api.text.format.TextColors; +import org.spongepowered.api.world.World; + +import javax.annotation.Nullable; + +import java.util.Optional; +import java.util.UUID; + +public class SpongePlayer extends AbstractPlayerActor { + + private final Player player; + + protected SpongePlayer(SpongePlatform platform, Player player) { + this.player = player; + ThreadSafeCache.getInstance().getOnlineIds().add(getUniqueId()); + } + + @Override + public UUID getUniqueId() { + return player.getUniqueId(); + } + + @Override + public int getItemInHand() { + Optional is = this.player.getItemInHand(); + return is.isPresent() ? IDHelper.resolve(is.get().getItem()) : 0; + } + + @Override + public String getName() { + return this.player.getName(); + } + + @Override + public BaseEntity getState() { + throw new UnsupportedOperationException("Cannot create a state from this object"); + } + + @Override + public Location getLocation() { + org.spongepowered.api.world.Location entityLoc = this.player.getLocation(); + Vector3d entityRot = this.player.getRotation(); + + return SpongeAdapter.adapt(entityLoc, entityRot); + } + + @Override + public WorldVector getPosition() { + Vector3d pos = this.player.getLocation().getPosition(); + return new WorldVector(LocalWorldAdapter.adapt(SpongeAdapter.adapt(this.player.getWorld())), pos.getX(), pos.getY(), pos.getZ()); + } + + @Override + public com.sk89q.worldedit.world.World getWorld() { + return SpongeAdapter.adapt(player.getWorld()); + } + + @Override + public double getPitch() { + return getLocation().getPitch(); + } + + @Override + public double getYaw() { + return getLocation().getYaw(); + } + + @Override + public void giveItem(int type, int amt) { + this.player.getInventory().offer(ItemStack.of(IDHelper.resolveItem(type), amt)); + } + + @Override + public void dispatchCUIEvent(CUIEvent event) { + String[] params = event.getParameters(); + String send = event.getTypeId(); + if (params.length > 0) { + send = send + "|" + StringUtil.joinString(params, "|"); + } + } + + @Override + public void printRaw(String msg) { + for (String part : msg.split("\n")) { + this.player.sendMessage(Text.of(part)); + } + } + + @Override + public void printDebug(String msg) { + sendColorized(msg, TextColors.GRAY); + } + + @Override + public void print(String msg) { + sendColorized(msg, TextColors.LIGHT_PURPLE); + } + + @Override + public void printError(String msg) { + sendColorized(msg, TextColors.RED); + } + + private void sendColorized(String msg, TextColor formatting) { + for (String part : msg.split("\n")) { + this.player.sendMessage(Text.of(formatting, part)); + } + } + + @Override + public void setPosition(Vector pos, float pitch, float yaw) { + org.spongepowered.api.world.Location loc = new org.spongepowered.api.world.Location( + this.player.getWorld(), pos.getX(), pos.getY(), pos.getZ() + ); + + // TODO Rotation code + this.player.setLocation(loc); + } + + @Override + public String[] getGroups() { + return new String[]{}; // WorldEditMod.inst.getPermissionsResolver().getGroups(this.player.username); + } + + @Override + public BlockBag getInventoryBlockBag() { + return null; + } + + @Override + public boolean hasPermission(String perm) { + return SpongeWorldEdit.inst.getPermissionsProvider().hasPermission(player, perm); + } + + @Nullable + @Override + public T getFacet(Class cls) { + return null; + } + + @Override + public SessionKey getSessionKey() { + return new SessionKeyImpl(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() { + // We can't directly check if the player is online because + // the list of players is not thread safe + return ThreadSafeCache.getInstance().getOnlineIds().contains(uuid); + } + + @Override + public boolean isPersistent() { + return true; + } + + } + +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java new file mode 100644 index 000000000..c6b8a979d --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java @@ -0,0 +1,251 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.flowpowered.math.vector.Vector3d; +import com.flowpowered.math.vector.Vector3i; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.WorldEditException; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BaseItemStack; +import com.sk89q.worldedit.entity.BaseEntity; +import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.util.Location; +import com.sk89q.worldedit.world.AbstractWorld; +import com.sk89q.worldedit.world.biome.BaseBiome; +import com.sk89q.worldedit.world.registry.WorldData; + +import java.lang.ref.WeakReference; +import java.util.*; +import java.util.logging.Logger; +import javax.annotation.Nullable; +import org.spongepowered.api.block.BlockSnapshot; +import org.spongepowered.api.block.BlockState; +import org.spongepowered.api.data.key.Keys; +import org.spongepowered.api.data.property.block.GroundLuminanceProperty; +import org.spongepowered.api.data.property.block.SkyLuminanceProperty; +import org.spongepowered.api.entity.EntitySnapshot; +import org.spongepowered.api.entity.EntityTypes; +import org.spongepowered.api.event.cause.Cause; +import org.spongepowered.api.world.World; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * An adapter to Minecraft worlds for WorldEdit. + */ +public abstract class SpongeWorld extends AbstractWorld { + + protected static final Random random = new Random(); + protected static final int UPDATE = 1, NOTIFY = 2, NOTIFY_CLIENT = 4; + protected static final Logger logger = Logger.getLogger(SpongeWorld.class.getCanonicalName()); + + private final WeakReference worldRef; + + /** + * Construct a new world. + * + * @param world the world + */ + SpongeWorld(World world) { + checkNotNull(world); + this.worldRef = new WeakReference(world); + } + + /** + * Get the underlying handle to the world. + * + * @return the world + * @throws WorldEditException thrown if a reference to the world was lost (i.e. world was unloaded) + */ + public World getWorldChecked() throws WorldEditException { + World world = worldRef.get(); + if (world != null) { + return world; + } else { + throw new WorldReferenceLostException("The reference to the world was lost (i.e. the world may have been unloaded)"); + } + } + + /** + * Get the underlying handle to the world. + * + * @return the world + * @throws RuntimeException thrown if a reference to the world was lost (i.e. world was unloaded) + */ + public World getWorld() { + World world = worldRef.get(); + if (world != null) { + return world; + } else { + throw new RuntimeException("The reference to the world was lost (i.e. the world may have been unloaded)"); + } + } + + @Override + public String getName() { + return getWorld().getName(); + } + + protected abstract BlockSnapshot createBlockSnapshot(Vector position, BaseBlock block); + + @Override + public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) throws WorldEditException { + checkNotNull(position); + checkNotNull(block); + + return createBlockSnapshot(position, block).restore(true, notifyAndLight); + } + + @Override + public int getBlockLightLevel(Vector position) { + checkNotNull(position); + + BlockState state = getWorld().getBlock(new Vector3i(position.getX(), position.getY(), position.getZ())); + + Optional groundLuminanceProperty = state.getProperty(GroundLuminanceProperty.class); + Optional skyLuminanceProperty = state.getProperty(SkyLuminanceProperty.class); + + if (!groundLuminanceProperty.isPresent() || !skyLuminanceProperty.isPresent()) { + return 0; + } + + //noinspection ConstantConditions + return (int) Math.max(groundLuminanceProperty.get().getValue(), skyLuminanceProperty.get().getValue()); + + } + + @Override + public BaseBiome getBiome(Vector2D position) { + checkNotNull(position); + return new BaseBiome(IDHelper.resolve(getWorld().getBiome(position.getBlockX(), position.getBlockZ()))); + } + + @Override + public boolean setBiome(Vector2D position, BaseBiome biome) { + checkNotNull(position); + checkNotNull(biome); + + getWorld().setBiome(position.getBlockX(), position.getBlockZ(), IDHelper.resolveBiome(biome.getId())); + return true; + } + + @Override + public void dropItem(Vector position, BaseItemStack item) { + checkNotNull(position); + checkNotNull(item); + + if (item.getType() == 0) { + return; + } + + Optional optItem = getWorld().createEntity( + EntityTypes.ITEM, + new Vector3d(position.getX(), position.getY(), position.getZ()) + ); + + if (optItem.isPresent()) { + org.spongepowered.api.entity.Entity entity = optItem.get(); + entity.offer(Keys.REPRESENTED_ITEM, SpongeWorldEdit.toSpongeItemStack(item).createSnapshot()); + getWorld().spawnEntity(entity, Cause.of(SpongeWorldEdit.inst)); + } + } + + + + @Override + public WorldData getWorldData() { + return ForgeWorldData.getInstance(); + } + + @Override + public boolean isValidBlockType(int id) { + return (id == 0) || (IDHelper.resolveItem(id) != null); + } + + @Override + public int hashCode() { + return getWorld().hashCode(); + } + + @Override + public boolean equals(Object o) { + if (o == null) { + return false; + } else if ((o instanceof SpongeWorld)) { + SpongeWorld other = ((SpongeWorld) o); + World otherWorld = other.worldRef.get(); + World thisWorld = worldRef.get(); + return otherWorld != null && thisWorld != null && otherWorld.equals(thisWorld); + } else if (o instanceof com.sk89q.worldedit.world.World) { + return ((com.sk89q.worldedit.world.World) o).getName().equals(getName()); + } else { + return false; + } + } + + @Override + public List getEntities(Region region) { + List entities = new ArrayList<>(); + for (org.spongepowered.api.entity.Entity entity : getWorld().getEntities()) { + org.spongepowered.api.world.Location loc = entity.getLocation(); + if (region.contains(new Vector(loc.getX(), loc.getY(), loc.getZ()))) { + entities.add(new SpongeEntity(entity)); + } + } + return entities; + } + + @Override + public List getEntities() { + List entities = new ArrayList<>(); + for (org.spongepowered.api.entity.Entity entity : getWorld().getEntities()) { + entities.add(new SpongeEntity(entity)); + } + return entities; + } + + protected abstract EntitySnapshot createEntitySnapshot(Location location, BaseEntity entity); + + @Nullable + @Override + public Entity createEntity(Location location, BaseEntity entity) { + EntitySnapshot snapshot = createEntitySnapshot(location, entity); + if (snapshot != null) { + Optional restoredEnt = snapshot.restore(); + if (restoredEnt.isPresent()) { + return new SpongeEntity(restoredEnt.get()); + } + } + return null; + } + + /** + * Thrown when the reference to the world is lost. + */ + private static class WorldReferenceLostException extends WorldEditException { + private WorldReferenceLostException(String message) { + super(message); + } + } + +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java new file mode 100644 index 000000000..173e7e8e7 --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -0,0 +1,267 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.google.inject.Inject; +import org.apache.logging.log4j.Logger; + +import com.google.common.base.Joiner; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.blocks.BaseItemStack; +import com.sk89q.worldedit.event.platform.PlatformReadyEvent; +import com.sk89q.worldedit.extension.platform.Platform; +import com.sk89q.worldedit.internal.LocalWorldAdapter; + +import java.io.File; +import java.nio.file.Path; +import java.util.Map; +import java.util.Optional; + +import org.spongepowered.api.Sponge; +import org.spongepowered.api.block.BlockSnapshot; +import org.spongepowered.api.block.BlockType; +import org.spongepowered.api.block.BlockTypes; +import org.spongepowered.api.config.ConfigManager; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.event.Listener; +import org.spongepowered.api.event.block.InteractBlockEvent; +import org.spongepowered.api.event.cause.NamedCause; +import org.spongepowered.api.event.game.state.*; +import org.spongepowered.api.item.inventory.ItemStack; +import org.spongepowered.api.plugin.Plugin; +import org.spongepowered.api.world.Location; +import org.spongepowered.api.world.World; +import org.spongepowered.mod.mixin.core.event.state.MixinEventServerAboutToStart; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * The Sponge implementation of WorldEdit. + */ +@Plugin(id = "SpongeWorldEdit.MOD_ID", name = "WorldEdit", version = "%VERSION%") +public class SpongeWorldEdit { + + @Inject + private java.util.logging.Logger logger; + + public static final String MOD_ID = "worldedit"; + public static final String CUI_PLUGIN_CHANNEL = "WECUI"; + + private SponePermissionsProvider provider; + + public static SpongeWorldEdit inst; + + private SpongePlatform platform; + private SpongeConfiguration config; + private File workingDir; + + @Listener + public void preInit(GamePreInitializationEvent event) { + // Setup working directory + ConfigManager service = Sponge.getGame().getConfigManager(); + Path path = service.getPluginConfig(this).getDirectory(); + + workingDir = path.toFile(); + workingDir.mkdir(); + + config = new SpongeConfiguration(this); + config.load(); + + Sponge.getEventManager().registerListeners(this, ThreadSafeCache.getInstance()); + } + + @Listener + public void init(GameInitializationEvent event) { + // WECUIPacketHandler.init(); + } + + @Listener + public void postInit(GamePostInitializationEvent event) { + logger.info("WorldEdit for Forge (version " + getInternalVersion() + ") is loaded"); + } + + @Listener + public void serverAboutToStart(GameAboutToStartServerEvent event) { + if (this.platform != null) { + logger.warning("FMLServerStartingEvent occurred when FMLServerStoppingEvent hasn't"); + WorldEdit.getInstance().getPlatformManager().unregister(platform); + } + + this.platform = new SpongePlatform(this); + this.provider = new SponePermissionsProvider(); + + WorldEdit.getInstance().getPlatformManager().register(platform); + } + + @Listener + public void serverStopping(GameStoppingServerEvent event) { + WorldEdit.getInstance().getPlatformManager().unregister(platform); + } + + @Listener + public void serverStarted(GameStartedServerEvent event) { + WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent()); + } + + /*@Listener + public void onCommandEvent(CommandEvent event) { + if ((event.sender instanceof EntityPlayerMP)) { + if (((EntityPlayerMP) event.sender).worldObj.isRemote) return; + String[] split = new String[event.parameters.length + 1]; + System.arraycopy(event.parameters, 0, split, 1, event.parameters.length); + split[0] = event.command.getCommandName(); + com.sk89q.worldedit.event.platform.CommandEvent weEvent = + new com.sk89q.worldedit.event.platform.CommandEvent(wrap((EntityPlayerMP) event.sender), Joiner.on(" ").join(split)); + WorldEdit.getInstance().getEventBus().post(weEvent); + } + }*/ + + @Listener + public void onPlayerInteract(InteractBlockEvent event) { + if (platform == null) { + return; + } + + if (!platform.isHookingEvents()) return; // We have to be told to catch these events + + WorldEdit we = WorldEdit.getInstance(); + Optional optPlayer = event.getCause().get(NamedCause.SOURCE, Player.class); + SpongePlayer player = wrap(optPlayer.get()); + com.sk89q.worldedit.world.World world = player.getWorld(); + + BlockSnapshot targetBlock = event.getTargetBlock(); + Location loc = targetBlock.getLocation().get(); + BlockType interactedType = targetBlock.getState().getType(); + + if (event instanceof InteractBlockEvent.Primary) { + if (interactedType != BlockTypes.AIR) { + WorldVector pos = new WorldVector(LocalWorldAdapter.adapt(world), loc.getX(), loc.getY(), loc.getZ()); + + if (we.handleBlockLeftClick(player, pos)) { + event.setCancelled(true); + } + + if (we.handleArmSwing(player)) { + event.setCancelled(true); + } + } + } else if (event instanceof InteractBlockEvent.Secondary) { + if (interactedType != BlockTypes.AIR) { + WorldVector pos = new WorldVector(LocalWorldAdapter.adapt(world), loc.getX(), loc.getY(), loc.getZ()); + + 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) { + return NMSHelper.makeSpongeStack(item); + } + + /** + * Get the configuration. + * + * @return the Forge configuration + */ + SpongeConfiguration getConfig() { + return this.config; + } + + /** + * Get the WorldEdit proxy for the given player. + * + * @param player the player + * @return the WorldEdit player + */ + public SpongePlayer wrap(Player player) { + checkNotNull(player); + return new SpongePlayer(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(wrap(player)); + } + + /** + * Get the WorldEdit proxy for the given world. + * + * @param world the world + * @return the WorldEdit world + */ + public SpongeWorld getWorld(World world) { + checkNotNull(world); + return new SpongeForgeWorld(world); + } + + /** + * 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-for-Forge implementation. + * + * @return a version string + */ + String getInternalVersion() { + return SpongeWorldEdit.class.getAnnotation(Plugin.class).version(); + } + + public void setPermissionsProvider(SponePermissionsProvider provider) { + this.provider = provider; + } + + public SponePermissionsProvider getPermissionsProvider() { + return provider; + } + +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java new file mode 100644 index 000000000..9655e015e --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java @@ -0,0 +1,81 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.server.MinecraftServer; +import net.minecraftforge.fml.common.FMLCommonHandler; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; +import java.util.UUID; +import java.util.concurrent.CopyOnWriteArraySet; + +/** + * Caches data that cannot be accessed from another thread safely. + */ +public class ThreadSafeCache { + + private static final long REFRESH_DELAY = 1000 * 30; + private static final ThreadSafeCache INSTANCE = new ThreadSafeCache(); + private Set onlineIds = Collections.emptySet(); + private long lastRefresh = 0; + + /** + * Get an concurrent-safe set of UUIDs of online players. + * + * @return a set of UUIDs + */ + public Set getOnlineIds() { + return onlineIds; + } + + @SubscribeEvent + public void tickStart(TickEvent event) { + long now = System.currentTimeMillis(); + + if (now - lastRefresh > REFRESH_DELAY) { + Set onlineIds = new HashSet(); + + MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance(); + if (server == null || server.getConfigurationManager() == null) { + return; + } + for (Object object : FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().playerEntityList) { + if (object != null) { + EntityPlayerMP player = (EntityPlayerMP) object; + onlineIds.add(player.getUniqueID()); + } + } + + this.onlineIds = new CopyOnWriteArraySet(onlineIds); + + lastRefresh = now; + } + } + + public static ThreadSafeCache getInstance() { + return INSTANCE; + } + +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityBaseBlock.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityBaseBlock.java new file mode 100644 index 000000000..9004474b5 --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityBaseBlock.java @@ -0,0 +1,40 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.TileEntityBlock; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; + +public class TileEntityBaseBlock extends BaseBlock implements TileEntityBlock { + + public TileEntityBaseBlock(int type, int data, TileEntity tile) { + super(type, data); + setNbtData(NBTConverter.fromNative(copyNbtData(tile))); + } + + private static NBTTagCompound copyNbtData(TileEntity tile) { + NBTTagCompound tag = new NBTTagCompound(); + tile.writeToNBT(tag); + return tag; + } + +} \ No newline at end of file diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityUtils.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityUtils.java new file mode 100644 index 000000000..2be2092d0 --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityUtils.java @@ -0,0 +1,146 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.sk89q.worldedit.Vector; + +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagInt; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.BlockPos; +import net.minecraft.world.World; + +import javax.annotation.Nullable; + +import java.lang.reflect.Constructor; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Utility methods for setting tile entities in the world. + */ +final class TileEntityUtils { + + private TileEntityUtils() { + } + + /** + * Update the given tag compound with position information. + * + * @param tag the tag + * @param position the position + * @return a tag compound + */ + private static NBTTagCompound updateForSet(NBTTagCompound tag, Vector position) { + checkNotNull(tag); + checkNotNull(position); + + tag.setTag("x", new NBTTagInt(position.getBlockX())); + tag.setTag("y", new NBTTagInt(position.getBlockY())); + tag.setTag("z", new NBTTagInt(position.getBlockZ())); + + return tag; + } + + /** + * Set a tile entity at the given location. + * + * @param world the world + * @param position the position + * @param clazz the tile entity class + * @param tag the tag for the tile entity (may be null to not set NBT data) + */ + static void setTileEntity(World world, Vector position, Class clazz, @Nullable NBTTagCompound tag) { + checkNotNull(world); + checkNotNull(position); + checkNotNull(clazz); + + TileEntity tileEntity = constructTileEntity(world, position, clazz); + + if (tileEntity == null) { + return; + } + + if (tag != null) { + // Set X, Y, Z + updateForSet(tag, position); + tileEntity.readFromNBT(tag); + } + + world.setTileEntity(new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()), tileEntity); + } + + /** + * Set a tile entity at the given location using the tile entity ID from + * the tag. + * + * @param world the world + * @param position the position + * @param tag the tag for the tile entity (may be null to do nothing) + */ + static void setTileEntity(World world, Vector position, @Nullable NBTTagCompound tag) { + if (tag != null) { + updateForSet(tag, position); + TileEntity tileEntity = TileEntity.createAndLoadEntity(tag); + if (tileEntity != null) { + world.setTileEntity(new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()), tileEntity); + } + } + } + + /** + * Construct a tile entity from the given class. + * + * @param world the world + * @param position the position + * @param clazz the class + * @return a tile entity (may be null if it failed) + */ + @Nullable + static TileEntity constructTileEntity(World world, Vector position, Class clazz) { + Constructor baseConstructor; + try { + baseConstructor = clazz.getConstructor(); // creates "blank" TE + } catch (Throwable e) { + return null; // every TE *should* have this constructor, so this isn't necessary + } + + TileEntity genericTE; + try { + // Downcast here for return while retaining the type + genericTE = (TileEntity) baseConstructor.newInstance(); + } catch (Throwable e) { + return null; + } + + /* + genericTE.blockType = Block.blocksList[block.getId()]; + genericTE.blockMetadata = block.getData(); + genericTE.xCoord = pt.getBlockX(); + genericTE.yCoord = pt.getBlockY(); + genericTE.zCoord = pt.getBlockZ(); + genericTE.worldObj = world; + */ // handled by internal code + + return genericTE; + } + + +} diff --git a/worldedit-sponge/src/main/resources/META-INF/worldedit_at.cfg b/worldedit-sponge/src/main/resources/META-INF/worldedit_at.cfg new file mode 100644 index 000000000..33f039ce3 --- /dev/null +++ b/worldedit-sponge/src/main/resources/META-INF/worldedit_at.cfg @@ -0,0 +1,4 @@ +public net.minecraft.world.gen.ChunkProviderServer field_73248_b # droppedChunksSet +public net.minecraft.world.gen.ChunkProviderServer field_73244_f # id2ChunkMap +public net.minecraft.world.gen.ChunkProviderServer field_73245_g # loadedChunks +public net.minecraft.world.gen.ChunkProviderServer field_73246_d # serverChunkGenerator diff --git a/worldedit-sponge/src/main/resources/defaults/worldedit.properties b/worldedit-sponge/src/main/resources/defaults/worldedit.properties new file mode 100644 index 000000000..9c3f5d327 --- /dev/null +++ b/worldedit-sponge/src/main/resources/defaults/worldedit.properties @@ -0,0 +1,32 @@ +#Don't put comments; they get removed +default-max-polygon-points=-1 +schematic-save-dir=schematics +allow-extra-data-values=false +super-pickaxe-many-drop-items=true +register-help=true +nav-wand-item=345 +profile=false +super-pickaxe-drop-items=true +disallowed-blocks=6,26,27,28,31,32,34,36,37,38,39,40,46,50,51,55,59,66,69,75,76,93,94,77,81,83,7,14,15,16,56 +max-super-pickaxe-size=5 +max-brush-radius=10 +craftscript-dir=craftscripts +no-double-slash=false +wand-item=271 +shell-save-type= +scripting-timeout=3000 +snapshots-dir= +use-inventory-creative-override=false +log-file=worldedit.log +max-changed-blocks=-1 +nav-wand-distance=50 +butcher-default-radius=-1 +default-max-changed-blocks=-1 +history-size=15 +use-inventory=false +allow-symbolic-links=false +use-inventory-override=false +log-commands=false +butcher-max-radius=-1 +max-polygon-points=20 +max-radius=-1 From d468557e79cca824e10c091f0ffa8a87288d9493 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Tue, 2 Feb 2016 15:04:29 -0500 Subject: [PATCH 02/39] Implemented the ID helper --- .../com/sk89q/worldedit/sponge/IDHelper.java | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java index 13fc241bb..c19ccf06f 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java @@ -19,9 +19,10 @@ package com.sk89q.worldedit.sponge; -import com.sk89q.worldedit.entity.BaseEntity; +import net.minecraft.block.Block; +import net.minecraft.item.Item; +import net.minecraft.world.biome.BiomeGenBase; import org.spongepowered.api.block.BlockType; -import org.spongepowered.api.entity.Entity; import org.spongepowered.api.item.ItemType; import org.spongepowered.api.world.biome.BiomeType; @@ -30,29 +31,26 @@ final class IDHelper { private IDHelper() { } public static int resolve(ItemType type) { - return 0; + return Item.getIdFromItem((Item) type); } public static int resolve(BlockType type) { - return 0; + return Block.getIdFromBlock((Block) type); } public static int resolve(BiomeType type) { - return 0; + return ((BiomeGenBase) type).biomeID; } - public static ItemType resolveItem(int ID) { - return null; + return (ItemType) Item.getItemById(ID); } public static BlockType resolveBlock(int ID) { - return null; + return (BlockType) Block.getBlockById(ID); } public static BiomeType resolveBiome(int ID) { - return null; + return (BiomeType) BiomeGenBase.getBiome(ID); } - - } From 8e49538e6e865b8f5256b6e0f52426adf4d181fa Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Tue, 2 Feb 2016 15:12:54 -0500 Subject: [PATCH 03/39] A few cleanup things --- build.gradle | 2 +- worldedit-sponge/build.gradle | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/build.gradle b/build.gradle index fbe0f78ad..6d316e9b6 100644 --- a/build.gradle +++ b/build.gradle @@ -85,7 +85,7 @@ subprojects { archives javadocJar } - if (!name.equals('worldedit-forge')) { + if (!(name.equals('worldedit-forge') || name.equals('worldedit-sponge'))) { task sourcesJar(type: Jar, dependsOn: classes) { classifier = 'sources' from sourceSets.main.allSource diff --git a/worldedit-sponge/build.gradle b/worldedit-sponge/build.gradle index b5f073a29..3e9c87bff 100644 --- a/worldedit-sponge/build.gradle +++ b/worldedit-sponge/build.gradle @@ -49,7 +49,7 @@ minecraft { mappings = "snapshot_20160111" runDir = 'run' - replaceIn "com/sk89q/worldedit/forge/ForgeWorldEdit.java" + replaceIn "com/sk89q/worldedit/sponge/SpongeWorldEdit.java" replace "%VERSION%", project.version } @@ -61,11 +61,6 @@ processResources { 'mcVersion': project.minecraft.version, 'forgeVersion': project.forgeVersion, 'internalVersion': project.internalVersion - include 'mcmod.info' - } - - from (sourceSets.main.resources.srcDirs) { - exclude 'mcmod.info' } } From c3c787bc9aac22f2bb6bf5fa7863ae5c0a344300 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Tue, 2 Feb 2016 18:14:30 -0500 Subject: [PATCH 04/39] Fixed the command system --- ...ommandWrapper.java => CommandAdapter.java} | 34 ++-- .../worldedit/sponge/SpongeCommandSender.java | 158 ++++++++++++++++++ .../worldedit/sponge/SpongePlatform.java | 46 +++-- .../worldedit/sponge/SpongeWorldEdit.java | 45 +++-- 4 files changed, 232 insertions(+), 51 deletions(-) rename worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/{CommandWrapper.java => CommandAdapter.java} (70%) create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeCommandSender.java diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandWrapper.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandAdapter.java similarity index 70% rename from worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandWrapper.java rename to worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandAdapter.java index 62b0dadd6..00cfdd1c0 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandWrapper.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandAdapter.java @@ -25,43 +25,43 @@ import org.spongepowered.api.command.CommandException; import org.spongepowered.api.command.CommandResult; import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.text.Text; -import org.spongepowered.api.text.Texts; -import javax.annotation.Nullable; -import java.util.Arrays; import java.util.List; import java.util.Optional; -public class CommandWrapper implements CommandCallable { +public abstract class CommandAdapter implements CommandCallable { private CommandMapping command; - protected CommandWrapper(CommandMapping command) { + protected CommandAdapter(CommandMapping command) { this.command = command; } - @Override - public CommandResult process(CommandSource source, String arguments) throws CommandException { - return null; - } - - @Override - public List getSuggestions(CommandSource source, String arguments) throws CommandException { - return null; - } - @Override public boolean testPermission(CommandSource source) { + for (String perm : command.getDescription().getPermissions()) { + if (!source.hasPermission(perm)) { + return false; + } + } return true; } @Override public Optional getShortDescription(CommandSource source) { - return null; + String description = command.getDescription().getDescription(); + if (description != null && !description.isEmpty()) { + return Optional.of(Text.of(description)); + } + return Optional.empty(); } @Override public Optional getHelp(CommandSource source) { - return null; + String help = command.getDescription().getHelp(); + if (help != null && !help.isEmpty()) { + return Optional.of(Text.of(help)); + } + return Optional.empty(); } @Override diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeCommandSender.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeCommandSender.java new file mode 100644 index 000000000..f9986101f --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeCommandSender.java @@ -0,0 +1,158 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.sk89q.worldedit.extension.platform.Actor; +import com.sk89q.worldedit.internal.cui.CUIEvent; +import com.sk89q.worldedit.session.SessionKey; +import com.sk89q.worldedit.util.auth.AuthorizationException; +import org.spongepowered.api.command.CommandSource; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.text.Text; +import org.spongepowered.api.text.format.TextColors; + +import javax.annotation.Nullable; +import java.io.File; +import java.util.UUID; + +import static com.google.common.base.Preconditions.checkArgument; +import static com.google.common.base.Preconditions.checkNotNull; + +public class SpongeCommandSender implements Actor { + + /** + * One time generated ID. + */ + private static final UUID DEFAULT_ID = UUID.fromString("a233eb4b-4cab-42cd-9fd9-7e7b9a3f74be"); + + private CommandSource sender; + private SpongeWorldEdit plugin; + + public SpongeCommandSender(SpongeWorldEdit plugin, CommandSource sender) { + checkNotNull(plugin); + checkNotNull(sender); + checkArgument(!(sender instanceof Player), "Cannot wrap a player"); + + this.plugin = plugin; + this.sender = sender; + } + + @Override + public UUID getUniqueId() { + return DEFAULT_ID; + } + + @Override + public String getName() { + return sender.getName(); + } + + @Override + public void printRaw(String msg) { + for (String part : msg.split("\n")) { + sender.sendMessage(Text.of(part)); + } + } + + @Override + public void print(String msg) { + for (String part : msg.split("\n")) { + sender.sendMessage(Text.of(TextColors.LIGHT_PURPLE, part)); + } + } + + @Override + public void printDebug(String msg) { + for (String part : msg.split("\n")) { + sender.sendMessage(Text.of(TextColors.GRAY, part)); + } + } + + @Override + public void printError(String msg) { + for (String part : msg.split("\n")) { + sender.sendMessage(Text.of(TextColors.RED, part)); + } + } + + @Override + public boolean canDestroyBedrock() { + return true; + } + + @Override + public String[] getGroups() { + return new String[0]; + } + + @Override + public boolean hasPermission(String perm) { + return true; + } + + @Override + public void checkPermission(String permission) throws AuthorizationException { + } + + @Override + public boolean isPlayer() { + return false; + } + + @Override + public File openFileOpenDialog(String[] extensions) { + return null; + } + + @Override + public File openFileSaveDialog(String[] extensions) { + return null; + } + + @Override + public void dispatchCUIEvent(CUIEvent event) { + } + + @Override + public SessionKey getSessionKey() { + return new SessionKey() { + @Nullable + @Override + public String getName() { + return null; + } + + @Override + public boolean isActive() { + return false; + } + + @Override + public boolean isPersistent() { + return false; + } + + @Override + public UUID getUniqueId() { + return DEFAULT_ID; + } + }; + } +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java index 6790ccc61..746077905 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java @@ -19,23 +19,33 @@ package com.sk89q.worldedit.sponge; +import com.google.common.base.Joiner; +import com.google.common.collect.Lists; +import com.sk89q.minecraft.util.commands.CommandException; +import com.sk89q.minecraft.util.commands.CommandLocals; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.LocalConfiguration; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.WorldEdit; 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.event.platform.CommandEvent; +import com.sk89q.worldedit.event.platform.CommandSuggestionEvent; +import com.sk89q.worldedit.extension.platform.*; import com.sk89q.worldedit.util.command.CommandMapping; import com.sk89q.worldedit.util.command.Dispatcher; +import com.sk89q.worldedit.util.command.InvalidUsageException; import com.sk89q.worldedit.world.World; - +import net.minecraft.entity.player.EntityPlayerMP; import org.spongepowered.api.Sponge; +import org.spongepowered.api.command.CommandResult; +import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.entity.EntityType; import org.spongepowered.api.item.ItemType; import org.spongepowered.api.scheduler.Task; +import org.spongepowered.api.text.Text; +import org.spongepowered.api.text.format.TextColors; import javax.annotation.Nullable; - import java.util.*; class SpongePlatform extends AbstractPlatform implements MultiUserPlatform { @@ -119,8 +129,23 @@ class SpongePlatform extends AbstractPlatform implements MultiUserPlatform { @Override public void registerCommands(Dispatcher dispatcher) { - for (final CommandMapping command : dispatcher.getCommands()) { - Sponge.getCommandManager().register(SpongeWorldEdit.inst, new CommandWrapper(command), command.getAllAliases()); + for (CommandMapping command : dispatcher.getCommands()) { + CommandAdapter adapter = new CommandAdapter(command) { + @Override + public CommandResult process(CommandSource source, String arguments) throws org.spongepowered.api.command.CommandException { + CommandEvent weEvent = new CommandEvent(SpongeWorldEdit.inst.wrapCommandSource(source), command.getPrimaryAlias() + " " + arguments); + WorldEdit.getInstance().getEventBus().post(weEvent); + return weEvent.isCancelled() ? CommandResult.success() : CommandResult.empty(); + } + + @Override + public List getSuggestions(CommandSource source, String arguments) throws org.spongepowered.api.command.CommandException { + CommandSuggestionEvent weEvent = new CommandSuggestionEvent(SpongeWorldEdit.inst.wrapCommandSource(source), command.getPrimaryAlias() + " " + arguments); + WorldEdit.getInstance().getEventBus().post(weEvent); + return weEvent.getSuggestions(); + } + }; + Sponge.getCommandManager().register(SpongeWorldEdit.inst, adapter, command.getAllAliases()); } } @@ -154,8 +179,7 @@ class SpongePlatform extends AbstractPlatform implements MultiUserPlatform { public Map getCapabilities() { Map capabilities = new EnumMap<>(Capability.class); capabilities.put(Capability.CONFIGURATION, Preference.PREFER_OTHERS); - // TODO WorldEditCUI Support - // capabilities.put(Capability.WORLDEDIT_CUI, 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); diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index 173e7e8e7..418a4aff1 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -20,9 +20,8 @@ package com.sk89q.worldedit.sponge; import com.google.inject.Inject; -import org.apache.logging.log4j.Logger; +import com.sk89q.worldedit.extension.platform.Actor; -import com.google.common.base.Joiner; import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldVector; @@ -33,13 +32,14 @@ import com.sk89q.worldedit.internal.LocalWorldAdapter; import java.io.File; import java.nio.file.Path; -import java.util.Map; import java.util.Optional; +import java.util.concurrent.TimeUnit; import org.spongepowered.api.Sponge; import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockType; import org.spongepowered.api.block.BlockTypes; +import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.config.ConfigManager; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Listener; @@ -48,16 +48,16 @@ import org.spongepowered.api.event.cause.NamedCause; import org.spongepowered.api.event.game.state.*; import org.spongepowered.api.item.inventory.ItemStack; import org.spongepowered.api.plugin.Plugin; +import org.spongepowered.api.scheduler.Task; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; -import org.spongepowered.mod.mixin.core.event.state.MixinEventServerAboutToStart; import static com.google.common.base.Preconditions.checkNotNull; /** * The Sponge implementation of WorldEdit. */ -@Plugin(id = "SpongeWorldEdit.MOD_ID", name = "WorldEdit", version = "%VERSION%") +@Plugin(id = SpongeWorldEdit.MOD_ID, name = "WorldEdit", version = "%VERSION%") public class SpongeWorldEdit { @Inject @@ -74,6 +74,10 @@ public class SpongeWorldEdit { private SpongeConfiguration config; private File workingDir; + public SpongeWorldEdit() { + inst = this; + } + @Listener public void preInit(GamePreInitializationEvent event) { // Setup working directory @@ -86,7 +90,7 @@ public class SpongeWorldEdit { config = new SpongeConfiguration(this); config.load(); - Sponge.getEventManager().registerListeners(this, ThreadSafeCache.getInstance()); + Task.builder().interval(30, TimeUnit.SECONDS).execute(ThreadSafeCache.getInstance()).submit(this); } @Listener @@ -96,7 +100,7 @@ public class SpongeWorldEdit { @Listener public void postInit(GamePostInitializationEvent event) { - logger.info("WorldEdit for Forge (version " + getInternalVersion() + ") is loaded"); + logger.info("WorldEdit for Sponge (version " + getInternalVersion() + ") is loaded"); } @Listener @@ -122,19 +126,6 @@ public class SpongeWorldEdit { WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent()); } - /*@Listener - public void onCommandEvent(CommandEvent event) { - if ((event.sender instanceof EntityPlayerMP)) { - if (((EntityPlayerMP) event.sender).worldObj.isRemote) return; - String[] split = new String[event.parameters.length + 1]; - System.arraycopy(event.parameters, 0, split, 1, event.parameters.length); - split[0] = event.command.getCommandName(); - com.sk89q.worldedit.event.platform.CommandEvent weEvent = - new com.sk89q.worldedit.event.platform.CommandEvent(wrap((EntityPlayerMP) event.sender), Joiner.on(" ").join(split)); - WorldEdit.getInstance().getEventBus().post(weEvent); - } - }*/ - @Listener public void onPlayerInteract(InteractBlockEvent event) { if (platform == null) { @@ -145,7 +136,7 @@ public class SpongeWorldEdit { WorldEdit we = WorldEdit.getInstance(); Optional optPlayer = event.getCause().get(NamedCause.SOURCE, Player.class); - SpongePlayer player = wrap(optPlayer.get()); + SpongePlayer player = wrapPlayer(optPlayer.get()); com.sk89q.worldedit.world.World world = player.getWorld(); BlockSnapshot targetBlock = event.getTargetBlock(); @@ -202,11 +193,19 @@ public class SpongeWorldEdit { * @param player the player * @return the WorldEdit player */ - public SpongePlayer wrap(Player player) { + public SpongePlayer wrapPlayer(Player player) { checkNotNull(player); return new SpongePlayer(platform, player); } + public Actor wrapCommandSource(CommandSource sender) { + if (sender instanceof Player) { + return wrapPlayer((Player) sender); + } + + return new SpongeCommandSender(this, sender); + } + /** * Get the session for a player. * @@ -215,7 +214,7 @@ public class SpongeWorldEdit { */ public LocalSession getSession(Player player) { checkNotNull(player); - return WorldEdit.getInstance().getSessionManager().get(wrap(player)); + return WorldEdit.getInstance().getSessionManager().get(wrapPlayer(player)); } /** From 81960c6b546f15902be228a86ca01e60d3008e09 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Tue, 2 Feb 2016 18:15:10 -0500 Subject: [PATCH 05/39] Further work on snapshot restores --- .../worldedit/sponge/SpongeForgeWorld.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java index c6c16cf1e..40a6d41d2 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java @@ -38,6 +38,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.IBlockAccess; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.ChunkProviderServer; @@ -47,12 +48,15 @@ import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockState; import org.spongepowered.api.entity.EntitySnapshot; import org.spongepowered.api.entity.EntityType; +import org.spongepowered.api.text.Text; +import org.spongepowered.api.text.channel.MessageChannel; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; import org.spongepowered.common.block.SpongeBlockSnapshot; import org.spongepowered.common.block.SpongeBlockSnapshotBuilder; import org.spongepowered.common.entity.SpongeEntitySnapshot; import org.spongepowered.common.entity.SpongeEntitySnapshotBuilder; +import scala.xml.Null; import javax.annotation.Nullable; import java.util.*; @@ -81,29 +85,40 @@ public class SpongeForgeWorld extends SpongeWorld { @Override protected BlockSnapshot createBlockSnapshot(Vector position, BaseBlock block) { this.blockBuilder.reset(); - Location location = new Location<>(getWorld(), new Vector3i(position.getX(), position.getY(), position.getZ())); - this.blockBuilder.blockState((BlockState) Block.getBlockById(block.getId()).getStateFromMeta(block.getData())); - this.blockBuilder.worldId(location.getExtent().getUniqueId()); + Location location = new Location<>(getWorld(), new Vector3i(position.getX(), position.getY(), position.getZ())); + IBlockState baseState = Block.getBlockById(block.getId()).getStateFromMeta(block.getData()); + + this.blockBuilder.blockState((BlockState) baseState); + this.blockBuilder.worldId(getWorld().getUniqueId()); this.blockBuilder.position(location.getBlockPosition()); if (block.hasNbtData()) { - this.blockBuilder.unsafeNbt(NBTConverter.toNative(block.getNbtData())); + NBTTagCompound tag = NBTConverter.toNative(block.getNbtData()); + tag.setString("id", block.getNbtId()); + + this.blockBuilder.unsafeNbt(tag); } - return new SpongeBlockSnapshot(this.blockBuilder, 0); + return this.blockBuilder.build(); } @Override protected EntitySnapshot createEntitySnapshot(com.sk89q.worldedit.util.Location location, BaseEntity entity) { this.entityBuilder.reset(); + this.entityBuilder.worldId(getWorld().getUniqueId()); this.entityBuilder.position(new Vector3d(location.getX(), location.getY(), location.getZ())); // TODO Rotation code // this.entityBuilder.rotation() this.entityBuilder.type(Sponge.getRegistry().getType(EntityType.class, entity.getTypeId()).get()); if (entity.hasNbtData()) { - this.entityBuilder.unsafeCompound(NBTConverter.toNative(entity.getNbtData())); + NBTTagCompound tag = NBTConverter.toNative(entity.getNbtData()); + for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { + tag.removeTag(name); + } + + this.entityBuilder.unsafeCompound(tag); } return this.entityBuilder.build(); } From c62125cd702dd61516e935395f761d0c52bd14d0 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Tue, 2 Feb 2016 18:15:33 -0500 Subject: [PATCH 06/39] Fixed the Thread Safe Cache --- .../worldedit/sponge/ThreadSafeCache.java | 34 ++++++------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java index 9655e015e..b0e42a7b3 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java @@ -24,6 +24,9 @@ import net.minecraft.server.MinecraftServer; import net.minecraftforge.fml.common.FMLCommonHandler; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.event.Listener; import java.util.Collections; import java.util.HashSet; @@ -34,12 +37,10 @@ import java.util.concurrent.CopyOnWriteArraySet; /** * Caches data that cannot be accessed from another thread safely. */ -public class ThreadSafeCache { +public class ThreadSafeCache implements Runnable { - private static final long REFRESH_DELAY = 1000 * 30; private static final ThreadSafeCache INSTANCE = new ThreadSafeCache(); private Set onlineIds = Collections.emptySet(); - private long lastRefresh = 0; /** * Get an concurrent-safe set of UUIDs of online players. @@ -50,28 +51,15 @@ public class ThreadSafeCache { return onlineIds; } - @SubscribeEvent - public void tickStart(TickEvent event) { - long now = System.currentTimeMillis(); + @Override + public void run() { + Set onlineIds = new HashSet<>(); - if (now - lastRefresh > REFRESH_DELAY) { - Set onlineIds = new HashSet(); - - MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance(); - if (server == null || server.getConfigurationManager() == null) { - return; - } - for (Object object : FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().playerEntityList) { - if (object != null) { - EntityPlayerMP player = (EntityPlayerMP) object; - onlineIds.add(player.getUniqueID()); - } - } - - this.onlineIds = new CopyOnWriteArraySet(onlineIds); - - lastRefresh = now; + for (Player player : Sponge.getServer().getOnlinePlayers()) { + onlineIds.add(player.getUniqueId()); } + + this.onlineIds = new CopyOnWriteArraySet<>(onlineIds); } public static ThreadSafeCache getInstance() { From 5efbeec44f8a986d784536ff6483422406e78ce8 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Tue, 2 Feb 2016 18:15:47 -0500 Subject: [PATCH 07/39] General cleanup --- .../main/java/com/sk89q/worldedit/sponge/SpongeWorld.java | 8 ++++---- .../sponge/{ForgeWorldData.java => SpongeWorldData.java} | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-) rename worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/{ForgeWorldData.java => SpongeWorldData.java} (88%) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java index c6b8a979d..1b22ccf80 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java @@ -46,6 +46,8 @@ import org.spongepowered.api.data.property.block.SkyLuminanceProperty; import org.spongepowered.api.entity.EntitySnapshot; import org.spongepowered.api.entity.EntityTypes; import org.spongepowered.api.event.cause.Cause; +import org.spongepowered.api.text.Text; +import org.spongepowered.api.text.channel.MessageChannel; import org.spongepowered.api.world.World; import static com.google.common.base.Preconditions.checkNotNull; @@ -170,16 +172,14 @@ public abstract class SpongeWorld extends AbstractWorld { } } - - @Override public WorldData getWorldData() { - return ForgeWorldData.getInstance(); + return SpongeWorldData.getInstance(); } @Override public boolean isValidBlockType(int id) { - return (id == 0) || (IDHelper.resolveItem(id) != null); + return (id == 0) || (IDHelper.resolveBlock(id) != null); } @Override diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ForgeWorldData.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldData.java similarity index 88% rename from worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ForgeWorldData.java rename to worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldData.java index 177932daf..bc0d18069 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ForgeWorldData.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldData.java @@ -25,9 +25,9 @@ import com.sk89q.worldedit.world.registry.LegacyWorldData; /** * World data for the Forge platform. */ -class ForgeWorldData extends LegacyWorldData { +class SpongeWorldData extends LegacyWorldData { - private static final ForgeWorldData INSTANCE = new ForgeWorldData(); + private static final SpongeWorldData INSTANCE = new SpongeWorldData(); private final BiomeRegistry biomeRegistry = new SpongeBiomeRegistry(); @Override @@ -40,7 +40,7 @@ class ForgeWorldData extends LegacyWorldData { * * @return an instance */ - public static ForgeWorldData getInstance() { + public static SpongeWorldData getInstance() { return INSTANCE; } From 61cba3ce072b9d1fea9934e8c9bbf0f02cba9d54 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Tue, 2 Feb 2016 19:28:05 -0500 Subject: [PATCH 08/39] Import cleanup --- .../sk89q/worldedit/sponge/CommandAdapter.java | 3 --- .../sk89q/worldedit/sponge/SpongeAdapter.java | 3 --- .../worldedit/sponge/SpongeBiomeRegistry.java | 2 -- .../worldedit/sponge/SpongeForgeWorld.java | 17 +++++------------ .../sk89q/worldedit/sponge/SpongePlatform.java | 11 ----------- .../sk89q/worldedit/sponge/SpongePlayer.java | 3 --- .../com/sk89q/worldedit/sponge/SpongeWorld.java | 15 ++++++++------- .../sk89q/worldedit/sponge/SpongeWorldEdit.java | 14 ++++++-------- .../sk89q/worldedit/sponge/ThreadSafeCache.java | 6 ------ .../sk89q/worldedit/sponge/TileEntityUtils.java | 2 -- 10 files changed, 19 insertions(+), 57 deletions(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandAdapter.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandAdapter.java index 00cfdd1c0..1398ba389 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandAdapter.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CommandAdapter.java @@ -21,12 +21,9 @@ package com.sk89q.worldedit.sponge; import com.sk89q.worldedit.util.command.CommandMapping; import org.spongepowered.api.command.CommandCallable; -import org.spongepowered.api.command.CommandException; -import org.spongepowered.api.command.CommandResult; import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.text.Text; -import java.util.List; import java.util.Optional; public abstract class CommandAdapter implements CommandCallable { diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java index 3d9c756d6..b1eb2ebb2 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java @@ -20,11 +20,8 @@ package com.sk89q.worldedit.sponge; import com.flowpowered.math.vector.Vector3d; -import com.flowpowered.math.vector.Vector3i; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.extent.Extent; import com.sk89q.worldedit.util.Location; -import com.sk89q.worldedit.world.NullWorld; import com.sk89q.worldedit.world.World; final class SpongeAdapter { diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java index 5bf2ef088..d65c59f2b 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java @@ -22,12 +22,10 @@ package com.sk89q.worldedit.sponge; import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.biome.BiomeData; import com.sk89q.worldedit.world.registry.BiomeRegistry; - import org.spongepowered.api.Sponge; import org.spongepowered.api.world.biome.BiomeType; import javax.annotation.Nullable; - import java.util.ArrayList; import java.util.List; diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java index 40a6d41d2..00c12c60a 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java @@ -21,15 +21,16 @@ package com.sk89q.worldedit.sponge; import com.flowpowered.math.vector.Vector3d; import com.flowpowered.math.vector.Vector3i; -import com.sk89q.jnbt.CompoundTag; -import com.sk89q.worldedit.*; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.LazyBlock; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.regions.Region; -import com.sk89q.worldedit.util.*; +import com.sk89q.worldedit.util.TreeGenerator; import net.minecraft.block.*; import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; @@ -38,7 +39,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.world.IBlockAccess; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.ChunkProviderServer; @@ -48,22 +48,15 @@ import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockState; import org.spongepowered.api.entity.EntitySnapshot; import org.spongepowered.api.entity.EntityType; -import org.spongepowered.api.text.Text; -import org.spongepowered.api.text.channel.MessageChannel; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; -import org.spongepowered.common.block.SpongeBlockSnapshot; import org.spongepowered.common.block.SpongeBlockSnapshotBuilder; -import org.spongepowered.common.entity.SpongeEntitySnapshot; import org.spongepowered.common.entity.SpongeEntitySnapshotBuilder; -import scala.xml.Null; import javax.annotation.Nullable; -import java.util.*; +import java.util.Set; import java.util.logging.Level; -import static com.google.common.base.Preconditions.checkNotNull; - public class SpongeForgeWorld extends SpongeWorld { private final SpongeBlockSnapshotBuilder blockBuilder = new SpongeBlockSnapshotBuilder(); diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java index 746077905..c8cb19f5e 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java @@ -19,13 +19,6 @@ package com.sk89q.worldedit.sponge; -import com.google.common.base.Joiner; -import com.google.common.collect.Lists; -import com.sk89q.minecraft.util.commands.CommandException; -import com.sk89q.minecraft.util.commands.CommandLocals; -import com.sk89q.worldedit.EditSession; -import com.sk89q.worldedit.LocalConfiguration; -import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.event.platform.CommandEvent; @@ -33,17 +26,13 @@ import com.sk89q.worldedit.event.platform.CommandSuggestionEvent; import com.sk89q.worldedit.extension.platform.*; import com.sk89q.worldedit.util.command.CommandMapping; import com.sk89q.worldedit.util.command.Dispatcher; -import com.sk89q.worldedit.util.command.InvalidUsageException; import com.sk89q.worldedit.world.World; -import net.minecraft.entity.player.EntityPlayerMP; import org.spongepowered.api.Sponge; import org.spongepowered.api.command.CommandResult; import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.entity.EntityType; import org.spongepowered.api.item.ItemType; import org.spongepowered.api.scheduler.Task; -import org.spongepowered.api.text.Text; -import org.spongepowered.api.text.format.TextColors; import javax.annotation.Nullable; import java.util.*; diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java index d2086533b..3a11c8bb8 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -30,8 +30,6 @@ import com.sk89q.worldedit.internal.LocalWorldAdapter; import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.session.SessionKey; import com.sk89q.worldedit.util.Location; - -import org.spongepowered.api.Sponge; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.item.inventory.ItemStack; import org.spongepowered.api.text.Text; @@ -40,7 +38,6 @@ import org.spongepowered.api.text.format.TextColors; import org.spongepowered.api.world.World; import javax.annotation.Nullable; - import java.util.Optional; import java.util.UUID; diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java index 1b22ccf80..f615b5239 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java @@ -33,11 +33,6 @@ import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.registry.WorldData; - -import java.lang.ref.WeakReference; -import java.util.*; -import java.util.logging.Logger; -import javax.annotation.Nullable; import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockState; import org.spongepowered.api.data.key.Keys; @@ -46,10 +41,16 @@ import org.spongepowered.api.data.property.block.SkyLuminanceProperty; import org.spongepowered.api.entity.EntitySnapshot; import org.spongepowered.api.entity.EntityTypes; import org.spongepowered.api.event.cause.Cause; -import org.spongepowered.api.text.Text; -import org.spongepowered.api.text.channel.MessageChannel; import org.spongepowered.api.world.World; +import javax.annotation.Nullable; +import java.lang.ref.WeakReference; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.Random; +import java.util.logging.Logger; + import static com.google.common.base.Preconditions.checkNotNull; /** diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index 418a4aff1..64072acfb 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -20,21 +20,14 @@ package com.sk89q.worldedit.sponge; import com.google.inject.Inject; -import com.sk89q.worldedit.extension.platform.Actor; - import com.sk89q.worldedit.LocalSession; import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldVector; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.event.platform.PlatformReadyEvent; +import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.internal.LocalWorldAdapter; - -import java.io.File; -import java.nio.file.Path; -import java.util.Optional; -import java.util.concurrent.TimeUnit; - import org.spongepowered.api.Sponge; import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockType; @@ -52,6 +45,11 @@ import org.spongepowered.api.scheduler.Task; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; +import java.io.File; +import java.nio.file.Path; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + import static com.google.common.base.Preconditions.checkNotNull; /** diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java index b0e42a7b3..f273b972c 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java @@ -19,14 +19,8 @@ package com.sk89q.worldedit.sponge; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.server.MinecraftServer; -import net.minecraftforge.fml.common.FMLCommonHandler; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent; import org.spongepowered.api.Sponge; import org.spongepowered.api.entity.living.player.Player; -import org.spongepowered.api.event.Listener; import java.util.Collections; import java.util.HashSet; diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityUtils.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityUtils.java index 2be2092d0..3c9f3d587 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityUtils.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityUtils.java @@ -20,7 +20,6 @@ package com.sk89q.worldedit.sponge; import com.sk89q.worldedit.Vector; - import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagInt; import net.minecraft.tileentity.TileEntity; @@ -28,7 +27,6 @@ import net.minecraft.util.BlockPos; import net.minecraft.world.World; import javax.annotation.Nullable; - import java.lang.reflect.Constructor; import static com.google.common.base.Preconditions.checkNotNull; From 124308c4ce5c475519c9f2f53686b86ec4be81a7 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Fri, 5 Feb 2016 19:08:26 -0500 Subject: [PATCH 09/39] Fixed an issue where an entity could fail to spawn, and this would end the edit --- .../main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java index 84af07ab3..794183355 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/extent/ChangeSetExtent.java @@ -68,7 +68,7 @@ public class ChangeSetExtent extends AbstractDelegateExtent { @Override public Entity createEntity(Location location, BaseEntity state) { Entity entity = super.createEntity(location, state); - if (state != null) { + if (entity != null) { changeSet.add(new EntityCreate(location, state, entity)); } return entity; From 12a8a858b97c6fa0627a525ef22585e8c4ddf965 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Fri, 5 Feb 2016 19:29:45 -0500 Subject: [PATCH 10/39] Removed the dependency on SpongeForge --- worldedit-sponge/build.gradle | 4 ---- 1 file changed, 4 deletions(-) diff --git a/worldedit-sponge/build.gradle b/worldedit-sponge/build.gradle index 3e9c87bff..6a6c6f139 100644 --- a/worldedit-sponge/build.gradle +++ b/worldedit-sponge/build.gradle @@ -19,10 +19,6 @@ apply plugin: 'net.minecraftforge.gradle.forge' dependencies { compile project(':worldedit-core') compile 'org.spongepowered:spongeapi:3.1.0-SNAPSHOT' - compile('org.spongepowered:spongeforge:1.8-1577-2.1-DEV-957') { - exclude module: 'spongeapi' - exclude module: 'spongecommon' - } testCompile group: 'org.mockito', name: 'mockito-core', version:'1.9.0-rc1' } From f09fff949194636bae9b1089c5441aa544613b30 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Fri, 5 Feb 2016 19:30:11 -0500 Subject: [PATCH 11/39] Fixed setting blocks, entities, and implemented entity rotation --- .../worldedit/sponge/SpongeConfiguration.java | 2 +- .../worldedit/sponge/SpongeForgeWorld.java | 67 +++++++---------- .../worldedit/sponge/SpongePlatform.java | 8 +-- .../sk89q/worldedit/sponge/SpongePlayer.java | 18 +++-- .../sk89q/worldedit/sponge/SpongeWorld.java | 71 ++++++++++++++++--- .../worldedit/sponge/SpongeWorldEdit.java | 14 +++- 6 files changed, 121 insertions(+), 59 deletions(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java index 13c755fd4..ee8470d77 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java @@ -40,6 +40,6 @@ public class SpongeConfiguration extends PropertiesConfiguration { @Override public File getWorkingDirectory() { - return SpongeWorldEdit.inst.getWorkingDir(); + return SpongeWorldEdit.inst().getWorkingDir(); } } \ No newline at end of file diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java index 00c12c60a..09d0264bc 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java @@ -19,8 +19,6 @@ package com.sk89q.worldedit.sponge; -import com.flowpowered.math.vector.Vector3d; -import com.flowpowered.math.vector.Vector3i; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; @@ -36,6 +34,7 @@ import net.minecraft.block.state.IBlockState; import net.minecraft.init.Blocks; import net.minecraft.inventory.IInventory; import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagInt; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; import net.minecraft.world.ChunkCoordIntPair; @@ -43,24 +42,18 @@ import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.ChunkProviderServer; import net.minecraft.world.gen.feature.*; -import org.spongepowered.api.Sponge; -import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockState; -import org.spongepowered.api.entity.EntitySnapshot; -import org.spongepowered.api.entity.EntityType; +import org.spongepowered.api.entity.Entity; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; -import org.spongepowered.common.block.SpongeBlockSnapshotBuilder; -import org.spongepowered.common.entity.SpongeEntitySnapshotBuilder; import javax.annotation.Nullable; import java.util.Set; import java.util.logging.Level; -public class SpongeForgeWorld extends SpongeWorld { +import static com.google.common.base.Preconditions.checkNotNull; - private final SpongeBlockSnapshotBuilder blockBuilder = new SpongeBlockSnapshotBuilder(); - private final SpongeEntitySnapshotBuilder entityBuilder = new SpongeEntitySnapshotBuilder(); +public class SpongeForgeWorld extends SpongeWorld { private static final IBlockState JUNGLE_LOG = Blocks.log.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE); private static final IBlockState JUNGLE_LEAF = Blocks.leaves.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE).withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); @@ -76,44 +69,38 @@ public class SpongeForgeWorld extends SpongeWorld { } @Override - protected BlockSnapshot createBlockSnapshot(Vector position, BaseBlock block) { - this.blockBuilder.reset(); + protected BlockState getBlockState(BaseBlock block) { + return (BlockState) Block.getBlockById(block.getId()).getStateFromMeta(block.getData()); + } - Location location = new Location<>(getWorld(), new Vector3i(position.getX(), position.getY(), position.getZ())); - IBlockState baseState = Block.getBlockById(block.getId()).getStateFromMeta(block.getData()); + private NBTTagCompound updateForSet(NBTTagCompound tag, Vector position) { + checkNotNull(tag); + checkNotNull(position); - this.blockBuilder.blockState((BlockState) baseState); - this.blockBuilder.worldId(getWorld().getUniqueId()); - this.blockBuilder.position(location.getBlockPosition()); + tag.setTag("x", new NBTTagInt(position.getBlockX())); + tag.setTag("y", new NBTTagInt(position.getBlockY())); + tag.setTag("z", new NBTTagInt(position.getBlockZ())); - if (block.hasNbtData()) { - NBTTagCompound tag = NBTConverter.toNative(block.getNbtData()); - tag.setString("id", block.getNbtId()); - - this.blockBuilder.unsafeNbt(tag); - } - - return this.blockBuilder.build(); + return tag; } @Override - protected EntitySnapshot createEntitySnapshot(com.sk89q.worldedit.util.Location location, BaseEntity entity) { - this.entityBuilder.reset(); + protected void applyTileEntityData(org.spongepowered.api.block.tileentity.TileEntity entity, BaseBlock block) { + NBTTagCompound tag = NBTConverter.toNative(block.getNbtData()); - this.entityBuilder.worldId(getWorld().getUniqueId()); - this.entityBuilder.position(new Vector3d(location.getX(), location.getY(), location.getZ())); - // TODO Rotation code - // this.entityBuilder.rotation() - this.entityBuilder.type(Sponge.getRegistry().getType(EntityType.class, entity.getTypeId()).get()); - if (entity.hasNbtData()) { - NBTTagCompound tag = NBTConverter.toNative(entity.getNbtData()); - for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { - tag.removeTag(name); - } + Location loc = entity.getLocation(); - this.entityBuilder.unsafeCompound(tag); + updateForSet(tag, new Vector(loc.getX(), loc.getY(), loc.getZ())); + ((TileEntity) entity).readFromNBT(tag); + } + + @Override + protected void applyEntityData(Entity entity, BaseEntity data) { + NBTTagCompound tag = NBTConverter.toNative(data.getNbtData()); + for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { + tag.removeTag(name); } - return this.entityBuilder.build(); + ((net.minecraft.entity.Entity) entity).readFromNBT(tag); } @Override diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java index c8cb19f5e..f390138f7 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java @@ -75,7 +75,7 @@ class SpongePlatform extends AbstractPlatform implements MultiUserPlatform { @Override public int schedule(long delay, long period, Runnable task) { - Task.builder().delayTicks(delay).intervalTicks(period).execute(task).submit(SpongeWorldEdit.inst); + Task.builder().delayTicks(delay).intervalTicks(period).execute(task).submit(SpongeWorldEdit.inst()); return 0; // TODO This isn't right, but we only check for -1 values } @@ -122,19 +122,19 @@ class SpongePlatform extends AbstractPlatform implements MultiUserPlatform { CommandAdapter adapter = new CommandAdapter(command) { @Override public CommandResult process(CommandSource source, String arguments) throws org.spongepowered.api.command.CommandException { - CommandEvent weEvent = new CommandEvent(SpongeWorldEdit.inst.wrapCommandSource(source), command.getPrimaryAlias() + " " + arguments); + CommandEvent weEvent = new CommandEvent(SpongeWorldEdit.inst().wrapCommandSource(source), command.getPrimaryAlias() + " " + arguments); WorldEdit.getInstance().getEventBus().post(weEvent); return weEvent.isCancelled() ? CommandResult.success() : CommandResult.empty(); } @Override public List getSuggestions(CommandSource source, String arguments) throws org.spongepowered.api.command.CommandException { - CommandSuggestionEvent weEvent = new CommandSuggestionEvent(SpongeWorldEdit.inst.wrapCommandSource(source), command.getPrimaryAlias() + " " + arguments); + CommandSuggestionEvent weEvent = new CommandSuggestionEvent(SpongeWorldEdit.inst().wrapCommandSource(source), command.getPrimaryAlias() + " " + arguments); WorldEdit.getInstance().getEventBus().post(weEvent); return weEvent.getSuggestions(); } }; - Sponge.getCommandManager().register(SpongeWorldEdit.inst, adapter, command.getAllAliases()); + Sponge.getCommandManager().register(SpongeWorldEdit.inst(), adapter, command.getAllAliases()); } } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java index 3a11c8bb8..2b9af46d7 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -144,12 +144,22 @@ public class SpongePlayer extends AbstractPlayerActor { @Override public void setPosition(Vector pos, float pitch, float yaw) { - org.spongepowered.api.world.Location loc = new org.spongepowered.api.world.Location( + org.spongepowered.api.world.Location loc = new org.spongepowered.api.world.Location<>( this.player.getWorld(), pos.getX(), pos.getY(), pos.getZ() ); - // TODO Rotation code - this.player.setLocation(loc); + double yawR = Math.toRadians(yaw); + double pitchR = Math.toRadians(pitch); + double xz = Math.cos(pitch); + + this.player.setLocationAndRotation( + loc, + new Vector3d( + -xz * Math.sin(yawR), + -Math.sin(pitchR), + xz * Math.cos(yawR) + ) + ); } @Override @@ -164,7 +174,7 @@ public class SpongePlayer extends AbstractPlayerActor { @Override public boolean hasPermission(String perm) { - return SpongeWorldEdit.inst.getPermissionsProvider().hasPermission(player, perm); + return SpongeWorldEdit.inst().getPermissionsProvider().hasPermission(player, perm); } @Nullable diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java index f615b5239..eaf265718 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit.sponge; import com.flowpowered.math.vector.Vector3d; import com.flowpowered.math.vector.Vector3i; +import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.WorldEditException; @@ -28,19 +29,30 @@ import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; +import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.registry.WorldData; +import net.minecraft.block.Block; +import net.minecraft.block.state.IBlockState; +import net.minecraft.entity.EntityList; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.BlockPos; +import net.minecraft.world.chunk.Chunk; +import org.spongepowered.api.Sponge; import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockState; +import org.spongepowered.api.block.tileentity.TileEntity; import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.data.property.block.GroundLuminanceProperty; import org.spongepowered.api.data.property.block.SkyLuminanceProperty; import org.spongepowered.api.entity.EntitySnapshot; +import org.spongepowered.api.entity.EntityType; import org.spongepowered.api.entity.EntityTypes; import org.spongepowered.api.event.cause.Cause; +import org.spongepowered.api.util.PositionOutOfBoundsException; import org.spongepowered.api.world.World; import javax.annotation.Nullable; @@ -109,14 +121,37 @@ public abstract class SpongeWorld extends AbstractWorld { return getWorld().getName(); } - protected abstract BlockSnapshot createBlockSnapshot(Vector position, BaseBlock block); + protected abstract BlockState getBlockState(BaseBlock block); + + protected abstract void applyTileEntityData(TileEntity entity, BaseBlock block); @Override public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) throws WorldEditException { checkNotNull(position); checkNotNull(block); - return createBlockSnapshot(position, block).restore(true, notifyAndLight); + World world = getWorldChecked(); + + // First set the block + Vector3i pos = new Vector3i(position.getX(), position.getY(), position.getZ()); + BlockState newState = getBlockState(block); + + try { + world.setBlock(pos, newState, notifyAndLight, Cause.of(SpongeWorldEdit.container())); + } catch (PositionOutOfBoundsException ex) { + return false; + } + + // Create the TileEntity + if (block.hasNbtData()) { + // Kill the old TileEntity + Optional optTile = world.getTileEntity(pos); + if (optTile.isPresent()) { + applyTileEntityData(optTile.get(), block); + } + } + + return true; } @Override @@ -169,7 +204,7 @@ public abstract class SpongeWorld extends AbstractWorld { if (optItem.isPresent()) { org.spongepowered.api.entity.Entity entity = optItem.get(); entity.offer(Keys.REPRESENTED_ITEM, SpongeWorldEdit.toSpongeItemStack(item).createSnapshot()); - getWorld().spawnEntity(entity, Cause.of(SpongeWorldEdit.inst)); + getWorld().spawnEntity(entity, Cause.of(SpongeWorldEdit.container())); } } @@ -225,18 +260,36 @@ public abstract class SpongeWorld extends AbstractWorld { return entities; } - protected abstract EntitySnapshot createEntitySnapshot(Location location, BaseEntity entity); + protected abstract void applyEntityData(org.spongepowered.api.entity.Entity entity, BaseEntity data); @Nullable @Override public Entity createEntity(Location location, BaseEntity entity) { - EntitySnapshot snapshot = createEntitySnapshot(location, entity); - if (snapshot != null) { - Optional restoredEnt = snapshot.restore(); - if (restoredEnt.isPresent()) { - return new SpongeEntity(restoredEnt.get()); + World world = getWorld(); + + EntityType entityType = Sponge.getRegistry().getType(EntityType.class, entity.getTypeId()).get(); + Vector3d pos = new Vector3d(location.getX(), location.getY(), location.getZ()); + + Optional optNewEnt = world.createEntity(entityType, pos); + if (optNewEnt.isPresent()) { + org.spongepowered.api.entity.Entity newEnt = optNewEnt.get(); + if (entity.hasNbtData()) { + applyEntityData(newEnt, entity); + } + + // Overwrite any data set by the NBT application + Vector dir = location.getDirection(); + + newEnt.setLocationAndRotation( + new org.spongepowered.api.world.Location<>(getWorld(), pos), + new Vector3d(dir.getX(), dir.getY(), dir.getZ()) + ); + + if (world.spawnEntity(newEnt, Cause.of(SpongeWorldEdit.container()))) { + return new SpongeEntity(newEnt); } } + return null; } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index 64072acfb..8e8c7668a 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -41,6 +41,7 @@ import org.spongepowered.api.event.cause.NamedCause; import org.spongepowered.api.event.game.state.*; import org.spongepowered.api.item.inventory.ItemStack; import org.spongepowered.api.plugin.Plugin; +import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.scheduler.Task; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; @@ -66,7 +67,18 @@ public class SpongeWorldEdit { private SponePermissionsProvider provider; - public static SpongeWorldEdit inst; + @Inject + private PluginContainer container; + + private static SpongeWorldEdit inst; + + public static PluginContainer container() { + return inst.container; + } + + public static SpongeWorldEdit inst() { + return inst; + } private SpongePlatform platform; private SpongeConfiguration config; From 222ba33aa43dd1c2204375fd19960a1a0cab92a5 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Thu, 3 Mar 2016 20:31:44 -0500 Subject: [PATCH 12/39] Fixed Sponge implementation player rotations --- .../java/com/sk89q/worldedit/sponge/SpongeAdapter.java | 3 +-- .../java/com/sk89q/worldedit/sponge/SpongePlayer.java | 10 +++------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java index b1eb2ebb2..92a81d380 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java @@ -35,8 +35,7 @@ final class SpongeAdapter { public static Location adapt(org.spongepowered.api.world.Location loc, Vector3d rot) { Vector position = new Vector(loc.getX(), loc.getY(), loc.getZ()); - Vector dir = new Vector(rot.getX(), rot.getY(), rot.getZ()); - return new Location(SpongeAdapter.adapt(loc.getExtent()), position, dir); + return new Location(SpongeAdapter.adapt(loc.getExtent()), position, (float) rot.getY(), (float) rot.getX()); } } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java index 2b9af46d7..7a681a787 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -148,16 +148,12 @@ public class SpongePlayer extends AbstractPlayerActor { this.player.getWorld(), pos.getX(), pos.getY(), pos.getZ() ); - double yawR = Math.toRadians(yaw); - double pitchR = Math.toRadians(pitch); - double xz = Math.cos(pitch); - this.player.setLocationAndRotation( loc, new Vector3d( - -xz * Math.sin(yawR), - -Math.sin(pitchR), - xz * Math.cos(yawR) + pitch, + yaw, + 0 ) ); } From 3b176038bf1c39e675f26b3cab075c4c0ee6d93c Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Sat, 5 Mar 2016 15:59:22 -0500 Subject: [PATCH 13/39] Fixed a bug where some mobs were incorrectly determined to be tagged on the Sponge platform --- .../main/java/com/sk89q/worldedit/sponge/SpongeEntityType.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntityType.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntityType.java index afd2393cc..d3d73cffa 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntityType.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntityType.java @@ -132,7 +132,7 @@ public class SpongeEntityType implements EntityType { @Override public boolean isTagged() { - return entity.get(Keys.DISPLAY_NAME).orElse(Text.EMPTY).isEmpty(); + return !entity.get(Keys.DISPLAY_NAME).orElse(Text.EMPTY).isEmpty(); } @Override From 25c4a56e8958df2f7c2a299a1690a3edd5751c74 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Sat, 5 Mar 2016 16:10:03 -0500 Subject: [PATCH 14/39] Fixed a bug where virtually all mobs were determined to be Animals on the Forge 1.8 platform --- .../main/java/com/sk89q/worldedit/forge/ForgeEntityType.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntityType.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntityType.java index 8fb19f3cd..c56375105 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntityType.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntityType.java @@ -36,6 +36,7 @@ import net.minecraft.entity.item.EntityTNTPrimed; import net.minecraft.entity.item.EntityXPOrb; import net.minecraft.entity.monster.EntityGolem; import net.minecraft.entity.passive.EntityAmbientCreature; +import net.minecraft.entity.passive.EntityAnimal; import net.minecraft.entity.passive.EntityTameable; import net.minecraft.entity.passive.IAnimals; import net.minecraft.entity.player.EntityPlayer; @@ -108,7 +109,7 @@ public class ForgeEntityType implements EntityType { @Override public boolean isAnimal() { - return entity instanceof IAnimals; + return entity instanceof EntityAnimal; } @Override From 0fd603bbd8dc4d94480f8de0b076dee03e1652aa Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Sat, 5 Mar 2016 17:35:45 -0500 Subject: [PATCH 15/39] Corrected some issues with sending raw messages on the Sponge platform --- .../main/java/com/sk89q/worldedit/sponge/SpongePlayer.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java index 7a681a787..54195e67a 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -30,11 +30,15 @@ import com.sk89q.worldedit.internal.LocalWorldAdapter; import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.session.SessionKey; import com.sk89q.worldedit.util.Location; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.util.ChatComponentText; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.item.inventory.ItemStack; +import org.spongepowered.api.text.LiteralText; import org.spongepowered.api.text.Text; import org.spongepowered.api.text.format.TextColor; import org.spongepowered.api.text.format.TextColors; +import org.spongepowered.api.text.serializer.TextSerializers; import org.spongepowered.api.world.World; import javax.annotation.Nullable; @@ -117,7 +121,7 @@ public class SpongePlayer extends AbstractPlayerActor { @Override public void printRaw(String msg) { for (String part : msg.split("\n")) { - this.player.sendMessage(Text.of(part)); + this.player.sendMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(part)); } } From 04cf831a33ef08396944db0a285190cee19a0c44 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Wed, 9 Mar 2016 21:33:20 -0500 Subject: [PATCH 16/39] Updated to Sponge 4.0 --- worldedit-sponge/build.gradle | 2 +- .../main/java/com/sk89q/worldedit/sponge/SpongeWorld.java | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/worldedit-sponge/build.gradle b/worldedit-sponge/build.gradle index 6a6c6f139..8aff6e572 100644 --- a/worldedit-sponge/build.gradle +++ b/worldedit-sponge/build.gradle @@ -18,7 +18,7 @@ apply plugin: 'net.minecraftforge.gradle.forge' dependencies { compile project(':worldedit-core') - compile 'org.spongepowered:spongeapi:3.1.0-SNAPSHOT' + compile 'org.spongepowered:spongeapi:4.+' testCompile group: 'org.mockito', name: 'mockito-core', version:'1.9.0-rc1' } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java index eaf265718..353f74d5c 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java @@ -137,7 +137,7 @@ public abstract class SpongeWorld extends AbstractWorld { BlockState newState = getBlockState(block); try { - world.setBlock(pos, newState, notifyAndLight, Cause.of(SpongeWorldEdit.container())); + world.setBlock(pos, newState, notifyAndLight, Cause.source(SpongeWorldEdit.container()).build()); } catch (PositionOutOfBoundsException ex) { return false; } @@ -204,7 +204,7 @@ public abstract class SpongeWorld extends AbstractWorld { if (optItem.isPresent()) { org.spongepowered.api.entity.Entity entity = optItem.get(); entity.offer(Keys.REPRESENTED_ITEM, SpongeWorldEdit.toSpongeItemStack(item).createSnapshot()); - getWorld().spawnEntity(entity, Cause.of(SpongeWorldEdit.container())); + getWorld().spawnEntity(entity, Cause.source(SpongeWorldEdit.container()).build()); } } @@ -285,7 +285,7 @@ public abstract class SpongeWorld extends AbstractWorld { new Vector3d(dir.getX(), dir.getY(), dir.getZ()) ); - if (world.spawnEntity(newEnt, Cause.of(SpongeWorldEdit.container()))) { + if (world.spawnEntity(newEnt, Cause.source(SpongeWorldEdit.container()).build())) { return new SpongeEntity(newEnt); } } From a91d881d736d4d01bc70a4cc369cf1e00989a38a Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Sat, 19 Mar 2016 14:32:01 -0400 Subject: [PATCH 17/39] Fixed checkstyle test for the Sponge platform --- config/checkstyle/import-control.xml | 13 +++++++------ .../java/com/sk89q/worldedit/sponge/IDHelper.java | 12 ++++++------ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/config/checkstyle/import-control.xml b/config/checkstyle/import-control.xml index 3e4233471..66d38b3ea 100644 --- a/config/checkstyle/import-control.xml +++ b/config/checkstyle/import-control.xml @@ -41,12 +41,6 @@ - - - - - - @@ -57,5 +51,12 @@ + + + + + + + diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java index c19ccf06f..be717fa3d 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java @@ -42,15 +42,15 @@ final class IDHelper { return ((BiomeGenBase) type).biomeID; } - public static ItemType resolveItem(int ID) { - return (ItemType) Item.getItemById(ID); + public static ItemType resolveItem(int intID) { + return (ItemType) Item.getItemById(intID); } - public static BlockType resolveBlock(int ID) { - return (BlockType) Block.getBlockById(ID); + public static BlockType resolveBlock(int intID) { + return (BlockType) Block.getBlockById(intID); } - public static BiomeType resolveBiome(int ID) { - return (BiomeType) BiomeGenBase.getBiome(ID); + public static BiomeType resolveBiome(int intID) { + return (BiomeType) BiomeGenBase.getBiome(intID); } } From 7d957081a907833cd9c2d509d3e8960a1c85ef88 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Sat, 19 Mar 2016 14:47:35 -0400 Subject: [PATCH 18/39] Build against only oraclejdk8 until a better solution is found --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 9321cf073..f8b8492f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -6,8 +6,6 @@ install: ./gradlew setupCIWorkspace -s script: ./gradlew build -s jdk: - oraclejdk8 - - oraclejdk7 - - openjdk6 # Caching for Gradle files, prevents hitting Maven too much. before_cache: - find $HOME/.gradle/ -name '*.lock' -print -exec rm -f {} \; From de0da7d3e9974931767491deaa5771bcbb6cc5bf Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Tue, 22 Mar 2016 00:24:02 -0400 Subject: [PATCH 19/39] Updated for support with Sponge Vanilla --- worldedit-sponge/build.gradle | 10 +-- .../sk89q/worldedit/sponge/SpongeAdapter.java | 2 +- ...ngeForgeWorld.java => SpongeNMSWorld.java} | 69 +++++++++++++++---- .../worldedit/sponge/SpongePlatform.java | 4 +- .../worldedit/sponge/SpongeWorldEdit.java | 2 +- 5 files changed, 65 insertions(+), 22 deletions(-) rename worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/{SpongeForgeWorld.java => SpongeNMSWorld.java} (82%) diff --git a/worldedit-sponge/build.gradle b/worldedit-sponge/build.gradle index 8aff6e572..8668cee0a 100644 --- a/worldedit-sponge/build.gradle +++ b/worldedit-sponge/build.gradle @@ -5,16 +5,18 @@ buildscript { repositories { mavenCentral() maven { url = "http://files.minecraftforge.net/maven" } + maven { url = "http://repo.minecrell.net/snapshots" } maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" } jcenter() } dependencies { + classpath 'net.minecrell:VanillaGradle:2.0.3-SNAPSHOT' classpath 'net.minecraftforge.gradle:ForgeGradle:2.1-SNAPSHOT' } } -apply plugin: 'net.minecraftforge.gradle.forge' +apply plugin: 'net.minecrell.vanilla.server.library' dependencies { compile project(':worldedit-core') @@ -37,12 +39,11 @@ sourceCompatibility = 1.8 targetCompatibility = 1.8 version = "6.1.1" -ext.forgeVersion = "11.15.0.1695" ext.internalVersion = version + ";" + gitCommitHash minecraft { - version = "1.8.9-${project.forgeVersion}" - mappings = "snapshot_20160111" + version = "1.8.9" + mappings = "stable_22" runDir = 'run' replaceIn "com/sk89q/worldedit/sponge/SpongeWorldEdit.java" @@ -55,7 +56,6 @@ processResources { from (sourceSets.main.resources.srcDirs) { expand 'version': project.version, 'mcVersion': project.minecraft.version, - 'forgeVersion': project.forgeVersion, 'internalVersion': project.internalVersion } } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java index 92a81d380..ab4bceedb 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java @@ -30,7 +30,7 @@ final class SpongeAdapter { } public static World adapt(org.spongepowered.api.world.World world) { - return new SpongeForgeWorld(world); + return new SpongeNMSWorld(world); } public static Location adapt(org.spongepowered.api.world.Location loc, Vector3d rot) { diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeNMSWorld.java similarity index 82% rename from worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java rename to worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeNMSWorld.java index 09d0264bc..2a2a04ac8 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeForgeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeNMSWorld.java @@ -37,6 +37,7 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagInt; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; +import net.minecraft.util.LongHashMap; import net.minecraft.world.ChunkCoordIntPair; import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.IChunkProvider; @@ -48,12 +49,14 @@ import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; import javax.annotation.Nullable; +import java.lang.reflect.Field; +import java.util.List; import java.util.Set; import java.util.logging.Level; import static com.google.common.base.Preconditions.checkNotNull; -public class SpongeForgeWorld extends SpongeWorld { +public class SpongeNMSWorld extends SpongeWorld { private static final IBlockState JUNGLE_LOG = Blocks.log.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE); private static final IBlockState JUNGLE_LEAF = Blocks.leaves.getDefaultState().withProperty(BlockOldLeaf.VARIANT, BlockPlanks.EnumType.JUNGLE).withProperty(BlockLeaves.CHECK_DECAY, Boolean.valueOf(false)); @@ -64,7 +67,7 @@ public class SpongeForgeWorld extends SpongeWorld { * * @param world the world */ - public SpongeForgeWorld(World world) { + public SpongeNMSWorld(World world) { super(world); } @@ -118,10 +121,57 @@ public class SpongeForgeWorld extends SpongeWorld { return false; } + private static K getFieldValue(Class clazz, T object, String feildName, Class valueClazz) { + try { + Field field = clazz.getDeclaredField(feildName); // Found in the MCP Mappings + field.setAccessible(true); + + return valueClazz.cast(field.get(object)); + } catch (NoSuchFieldException | IllegalAccessException e) { + System.out.println("Exception while modifying inaccessible variable: " + e.getMessage()); + } + throw new IllegalStateException("Invalid variable state"); + } + + @SuppressWarnings("unchecked") @Override public boolean regenerate(Region region, EditSession editSession) { BaseBlock[] history = new BaseBlock[256 * (getMaxY() + 1)]; + IChunkProvider provider = ((net.minecraft.world.World) getWorld()).getChunkProvider(); + if (!(provider instanceof ChunkProviderServer)) { + return false; + } + ChunkProviderServer chunkServer = (ChunkProviderServer) provider; + + IChunkProvider chunkProvider = getFieldValue( + ChunkProviderServer.class, + chunkServer, + "field_73246_d", // serverChunkGenerator + IChunkProvider.class + ); + + Set droppedChunksSet = getFieldValue( + ChunkProviderServer.class, + chunkServer, + "field_73248_b", // droppedChunksSet, + Set.class + ); + + LongHashMap id2ChunkMap = getFieldValue( + ChunkProviderServer.class, + chunkServer, + "field_73244_f", // id2ChunkMap + LongHashMap.class + ); + + List loadedChunks = getFieldValue( + ChunkProviderServer.class, + chunkServer, + "field_73245_g", // loadedChunks + List.class + ); + for (Vector2D chunk : region.getChunks()) { Vector min = new Vector(chunk.getBlockX() * 16, 0, chunk.getBlockZ() * 16); @@ -136,13 +186,6 @@ public class SpongeForgeWorld extends SpongeWorld { } try { Set chunks = region.getChunks(); - IChunkProvider provider = ((net.minecraft.world.World) getWorld()).getChunkProvider(); - if (!(provider instanceof ChunkProviderServer)) { - return false; - } - ChunkProviderServer chunkServer = (ChunkProviderServer) provider; - IChunkProvider chunkProvider = chunkServer.serverChunkGenerator; - for (Vector2D coord : chunks) { long pos = ChunkCoordIntPair.chunkXZ2Int(coord.getBlockX(), coord.getBlockZ()); Chunk mcChunk; @@ -150,11 +193,11 @@ public class SpongeForgeWorld extends SpongeWorld { mcChunk = chunkServer.loadChunk(coord.getBlockX(), coord.getBlockZ()); mcChunk.onChunkUnload(); } - chunkServer.droppedChunksSet.remove(pos); - chunkServer.id2ChunkMap.remove(pos); + droppedChunksSet.remove(pos); + id2ChunkMap.remove(pos); mcChunk = chunkProvider.provideChunk(coord.getBlockX(), coord.getBlockZ()); - chunkServer.id2ChunkMap.add(pos, mcChunk); - chunkServer.loadedChunks.add(mcChunk); + id2ChunkMap.add(pos, mcChunk); + loadedChunks.add(mcChunk); if (mcChunk != null) { mcChunk.onChunkLoad(); mcChunk.populateChunk(chunkProvider, chunkProvider, coord.getBlockX(), coord.getBlockZ()); diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java index f390138f7..4b006660e 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java @@ -84,7 +84,7 @@ class SpongePlatform extends AbstractPlatform implements MultiUserPlatform { Collection worlds = Sponge.getServer().getWorlds(); List ret = new ArrayList<>(worlds.size()); for (org.spongepowered.api.world.World world : worlds) { - ret.add(new SpongeForgeWorld(world)); + ret.add(new SpongeNMSWorld(world)); } return ret; } @@ -108,7 +108,7 @@ class SpongePlatform extends AbstractPlatform implements MultiUserPlatform { } else { for (org.spongepowered.api.world.World ws : Sponge.getServer().getWorlds()) { if (ws.getName().equals(world.getName())) { - return new SpongeForgeWorld(ws); + return new SpongeNMSWorld(ws); } } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index 8e8c7668a..d6882cb7f 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -235,7 +235,7 @@ public class SpongeWorldEdit { */ public SpongeWorld getWorld(World world) { checkNotNull(world); - return new SpongeForgeWorld(world); + return new SpongeNMSWorld(world); } /** From 23f2930aaddf7e55e8d79765df516631ad048be8 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Tue, 22 Mar 2016 00:45:54 -0400 Subject: [PATCH 20/39] Removed the regeneration code for the Sponge platform --- .../worldedit/sponge/SpongeNMSWorld.java | 106 ------------------ .../sk89q/worldedit/sponge/SpongeWorld.java | 6 + 2 files changed, 6 insertions(+), 106 deletions(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeNMSWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeNMSWorld.java index 2a2a04ac8..ecdfc8677 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeNMSWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeNMSWorld.java @@ -121,112 +121,6 @@ public class SpongeNMSWorld extends SpongeWorld { return false; } - private static K getFieldValue(Class clazz, T object, String feildName, Class valueClazz) { - try { - Field field = clazz.getDeclaredField(feildName); // Found in the MCP Mappings - field.setAccessible(true); - - return valueClazz.cast(field.get(object)); - } catch (NoSuchFieldException | IllegalAccessException e) { - System.out.println("Exception while modifying inaccessible variable: " + e.getMessage()); - } - throw new IllegalStateException("Invalid variable state"); - } - - @SuppressWarnings("unchecked") - @Override - public boolean regenerate(Region region, EditSession editSession) { - BaseBlock[] history = new BaseBlock[256 * (getMaxY() + 1)]; - - IChunkProvider provider = ((net.minecraft.world.World) getWorld()).getChunkProvider(); - if (!(provider instanceof ChunkProviderServer)) { - return false; - } - ChunkProviderServer chunkServer = (ChunkProviderServer) provider; - - IChunkProvider chunkProvider = getFieldValue( - ChunkProviderServer.class, - chunkServer, - "field_73246_d", // serverChunkGenerator - IChunkProvider.class - ); - - Set droppedChunksSet = getFieldValue( - ChunkProviderServer.class, - chunkServer, - "field_73248_b", // droppedChunksSet, - Set.class - ); - - LongHashMap id2ChunkMap = getFieldValue( - ChunkProviderServer.class, - chunkServer, - "field_73244_f", // id2ChunkMap - LongHashMap.class - ); - - List loadedChunks = getFieldValue( - ChunkProviderServer.class, - chunkServer, - "field_73245_g", // loadedChunks - List.class - ); - - for (Vector2D chunk : region.getChunks()) { - Vector min = new Vector(chunk.getBlockX() * 16, 0, chunk.getBlockZ() * 16); - - 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 { - Set chunks = region.getChunks(); - for (Vector2D coord : chunks) { - long pos = ChunkCoordIntPair.chunkXZ2Int(coord.getBlockX(), coord.getBlockZ()); - Chunk mcChunk; - if (chunkServer.chunkExists(coord.getBlockX(), coord.getBlockZ())) { - mcChunk = chunkServer.loadChunk(coord.getBlockX(), coord.getBlockZ()); - mcChunk.onChunkUnload(); - } - droppedChunksSet.remove(pos); - id2ChunkMap.remove(pos); - mcChunk = chunkProvider.provideChunk(coord.getBlockX(), coord.getBlockZ()); - id2ChunkMap.add(pos, mcChunk); - loadedChunks.add(mcChunk); - if (mcChunk != null) { - mcChunk.onChunkLoad(); - mcChunk.populateChunk(chunkProvider, chunkProvider, coord.getBlockX(), coord.getBlockZ()); - } - } - } catch (Throwable t) { - logger.log(Level.WARNING, "Failed to generate chunk", t); - return false; - } - - 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; - - if (!region.contains(pt)) - editSession.smartSetBlock(pt, history[index]); - else { - editSession.rememberChange(pt, history[index], editSession.rawGetBlock(pt)); - } - } - } - } - } - - return false; - } - @Nullable private static WorldGenerator createWorldGenerator(TreeGenerator.TreeType type) { switch (type) { diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java index 353f74d5c..7518eb80f 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java @@ -22,6 +22,7 @@ package com.sk89q.worldedit.sponge; import com.flowpowered.math.vector.Vector3d; import com.flowpowered.math.vector.Vector3i; import com.sk89q.jnbt.CompoundTag; +import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.WorldEditException; @@ -154,6 +155,11 @@ public abstract class SpongeWorld extends AbstractWorld { return true; } + @Override + public boolean regenerate(Region region, EditSession editSession) { + return false; + } + @Override public int getBlockLightLevel(Vector position) { checkNotNull(position); From 0cca831116edf474a94fb7277ad9180f3df32aed Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Thu, 24 Mar 2016 18:14:28 -0400 Subject: [PATCH 21/39] Fixed additional formatting bugs --- .../src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java index 54195e67a..bed23f3cc 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -142,7 +142,7 @@ public class SpongePlayer extends AbstractPlayerActor { private void sendColorized(String msg, TextColor formatting) { for (String part : msg.split("\n")) { - this.player.sendMessage(Text.of(formatting, part)); + this.player.sendMessage(Text.of(formatting, TextSerializers.LEGACY_FORMATTING_CODE.deserialize(part))); } } From 7fb763f7e6e0149b766c5b9ffc88e097b15036df Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Thu, 24 Mar 2016 18:15:04 -0400 Subject: [PATCH 22/39] Removed the ant build from WorldEdit Sponge --- worldedit-sponge/src/main/ant/build.xml | 150 ------------------------ 1 file changed, 150 deletions(-) delete mode 100644 worldedit-sponge/src/main/ant/build.xml diff --git a/worldedit-sponge/src/main/ant/build.xml b/worldedit-sponge/src/main/ant/build.xml deleted file mode 100644 index 5753b52ce..000000000 --- a/worldedit-sponge/src/main/ant/build.xml +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - From 205e2d212e7538c691a4c00903e10ac814284d8f Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Mon, 4 Apr 2016 23:34:20 -0400 Subject: [PATCH 23/39] Cleaned up the Sponge Command Sender chat implementation --- .../worldedit/sponge/SpongeCommandSender.java | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeCommandSender.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeCommandSender.java index f9986101f..a2a3fa138 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeCommandSender.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeCommandSender.java @@ -26,7 +26,9 @@ import com.sk89q.worldedit.util.auth.AuthorizationException; import org.spongepowered.api.command.CommandSource; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.text.Text; +import org.spongepowered.api.text.format.TextColor; import org.spongepowered.api.text.format.TextColors; +import org.spongepowered.api.text.serializer.TextSerializers; import javax.annotation.Nullable; import java.io.File; @@ -67,28 +69,28 @@ public class SpongeCommandSender implements Actor { @Override public void printRaw(String msg) { for (String part : msg.split("\n")) { - sender.sendMessage(Text.of(part)); + sender.sendMessage(TextSerializers.LEGACY_FORMATTING_CODE.deserialize(part)); } } @Override public void print(String msg) { - for (String part : msg.split("\n")) { - sender.sendMessage(Text.of(TextColors.LIGHT_PURPLE, part)); - } + sendColorized(msg, TextColors.LIGHT_PURPLE); } @Override public void printDebug(String msg) { - for (String part : msg.split("\n")) { - sender.sendMessage(Text.of(TextColors.GRAY, part)); - } + sendColorized(msg, TextColors.GRAY); } @Override public void printError(String msg) { + sendColorized(msg, TextColors.RED); + } + + private void sendColorized(String msg, TextColor formatting) { for (String part : msg.split("\n")) { - sender.sendMessage(Text.of(TextColors.RED, part)); + sender.sendMessage(Text.of(formatting, TextSerializers.LEGACY_FORMATTING_CODE.deserialize(part))); } } From a50e337224090e825755e14356730ef65c79df53 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Thu, 14 Apr 2016 21:55:15 -0400 Subject: [PATCH 24/39] A player is not always present when the InteractBlockEvent is fired anymore --- .../main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index d6882cb7f..e9a8fa208 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -146,6 +146,10 @@ public class SpongeWorldEdit { WorldEdit we = WorldEdit.getInstance(); Optional optPlayer = event.getCause().get(NamedCause.SOURCE, Player.class); + if (!optPlayer.isPresent()) { + return; + } + SpongePlayer player = wrapPlayer(optPlayer.get()); com.sk89q.worldedit.world.World world = player.getWorld(); From 330523bac4a173e88e30f59a7d7000b690a6d2c1 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Sat, 16 Apr 2016 17:18:48 -0400 Subject: [PATCH 25/39] A BlockSnapot does not always have a location in the InteractBlockEvent --- .../java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index e9a8fa208..6c9cac5f0 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -154,7 +154,13 @@ public class SpongeWorldEdit { com.sk89q.worldedit.world.World world = player.getWorld(); BlockSnapshot targetBlock = event.getTargetBlock(); - Location loc = targetBlock.getLocation().get(); + Optional> optLoc = targetBlock.getLocation(); + + if (!optLoc.isPresent()) { + return; + } + + Location loc = optLoc.get(); BlockType interactedType = targetBlock.getState().getType(); if (event instanceof InteractBlockEvent.Primary) { From 96798bbb908a436a61cb7220314270efd561d5ea Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Sun, 1 May 2016 13:39:09 -0400 Subject: [PATCH 26/39] Fixed an issue where a block had to be clicked for WorldEdit to receive event information --- .../worldedit/sponge/SpongeWorldEdit.java | 37 ++++++++++++++++--- 1 file changed, 31 insertions(+), 6 deletions(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index 6c9cac5f0..27a2291b7 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -43,6 +43,8 @@ import org.spongepowered.api.item.inventory.ItemStack; import org.spongepowered.api.plugin.Plugin; import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.scheduler.Task; +import org.spongepowered.api.text.Text; +import org.spongepowered.api.text.channel.MessageChannel; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; @@ -136,6 +138,8 @@ public class SpongeWorldEdit { WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent()); } + private boolean ignoreLeftClickAir = false; + @Listener public void onPlayerInteract(InteractBlockEvent event) { if (platform == null) { @@ -156,15 +160,14 @@ public class SpongeWorldEdit { BlockSnapshot targetBlock = event.getTargetBlock(); Optional> optLoc = targetBlock.getLocation(); - if (!optLoc.isPresent()) { - return; - } - - Location loc = optLoc.get(); BlockType interactedType = targetBlock.getState().getType(); - if (event instanceof InteractBlockEvent.Primary) { if (interactedType != BlockTypes.AIR) { + if (!optLoc.isPresent()) { + return; + } + + Location loc = optLoc.get(); WorldVector pos = new WorldVector(LocalWorldAdapter.adapt(world), loc.getX(), loc.getY(), loc.getZ()); if (we.handleBlockLeftClick(player, pos)) { @@ -174,9 +177,31 @@ public class SpongeWorldEdit { if (we.handleArmSwing(player)) { event.setCancelled(true); } + + if (!ignoreLeftClickAir) { + Task.builder().delayTicks(2).execute(() -> { + ignoreLeftClickAir = false; + + }).submit(this); + + ignoreLeftClickAir = true; + } + } else { + if (ignoreLeftClickAir) { + return; + } + + if (we.handleArmSwing(player)) { + event.setCancelled(true); + } } } else if (event instanceof InteractBlockEvent.Secondary) { if (interactedType != BlockTypes.AIR) { + if (!optLoc.isPresent()) { + return; + } + + Location loc = optLoc.get(); WorldVector pos = new WorldVector(LocalWorldAdapter.adapt(world), loc.getX(), loc.getY(), loc.getZ()); if (we.handleBlockRightClick(player, pos)) { From 2fd5c2f887d3d4287767a9d725ab35a88a19a90a Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Sun, 1 May 2016 13:39:09 -0400 Subject: [PATCH 27/39] Check for the root cause instead of the source when handling the InteractBlockEvent --- .../java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index 27a2291b7..7b241cbd4 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -149,12 +149,12 @@ public class SpongeWorldEdit { if (!platform.isHookingEvents()) return; // We have to be told to catch these events WorldEdit we = WorldEdit.getInstance(); - Optional optPlayer = event.getCause().get(NamedCause.SOURCE, Player.class); - if (!optPlayer.isPresent()) { + Object rootObj = event.getCause().root(); + if (!(rootObj instanceof Player)) { return; } - SpongePlayer player = wrapPlayer(optPlayer.get()); + SpongePlayer player = wrapPlayer((Player) rootObj); com.sk89q.worldedit.world.World world = player.getWorld(); BlockSnapshot targetBlock = event.getTargetBlock(); From a31546eda27f8ed5c08853a577482640dcb5d4fa Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Mon, 16 May 2016 15:16:34 -0400 Subject: [PATCH 28/39] Changed WorldEdit to use BlockSnapshots to create blocks --- .../sk89q/worldedit/sponge/SpongeWorld.java | 22 ++++++------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java index 7518eb80f..d7b6f7803 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java @@ -21,7 +21,6 @@ package com.sk89q.worldedit.sponge; import com.flowpowered.math.vector.Vector3d; import com.flowpowered.math.vector.Vector3i; -import com.sk89q.jnbt.CompoundTag; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.Vector; import com.sk89q.worldedit.Vector2D; @@ -30,18 +29,11 @@ import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; -import com.sk89q.worldedit.internal.Constants; import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.registry.WorldData; -import net.minecraft.block.Block; -import net.minecraft.block.state.IBlockState; -import net.minecraft.entity.EntityList; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.util.BlockPos; -import net.minecraft.world.chunk.Chunk; import org.spongepowered.api.Sponge; import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockState; @@ -49,11 +41,9 @@ import org.spongepowered.api.block.tileentity.TileEntity; import org.spongepowered.api.data.key.Keys; import org.spongepowered.api.data.property.block.GroundLuminanceProperty; import org.spongepowered.api.data.property.block.SkyLuminanceProperty; -import org.spongepowered.api.entity.EntitySnapshot; import org.spongepowered.api.entity.EntityType; import org.spongepowered.api.entity.EntityTypes; import org.spongepowered.api.event.cause.Cause; -import org.spongepowered.api.util.PositionOutOfBoundsException; import org.spongepowered.api.world.World; import javax.annotation.Nullable; @@ -137,11 +127,13 @@ public abstract class SpongeWorld extends AbstractWorld { Vector3i pos = new Vector3i(position.getX(), position.getY(), position.getZ()); BlockState newState = getBlockState(block); - try { - world.setBlock(pos, newState, notifyAndLight, Cause.source(SpongeWorldEdit.container()).build()); - } catch (PositionOutOfBoundsException ex) { - return false; - } + BlockSnapshot snapshot = BlockSnapshot.builder() + .blockState(newState) + .position(pos) + .world(world.getProperties()) + .build(); + + snapshot.restore(true, notifyAndLight); // Create the TileEntity if (block.hasNbtData()) { From d1e9446d476890e5cec4f468ba03eb54e4ccb052 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Mon, 16 May 2016 15:49:49 -0400 Subject: [PATCH 29/39] Use a static builder and reset it, rather than asking the Sponge registry for a new builder --- .../src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java index d7b6f7803..c6309cb22 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java @@ -116,6 +116,8 @@ public abstract class SpongeWorld extends AbstractWorld { protected abstract void applyTileEntityData(TileEntity entity, BaseBlock block); + private static final BlockSnapshot.Builder builder = BlockSnapshot.builder(); + @Override public boolean setBlock(Vector position, BaseBlock block, boolean notifyAndLight) throws WorldEditException { checkNotNull(position); @@ -127,7 +129,7 @@ public abstract class SpongeWorld extends AbstractWorld { Vector3i pos = new Vector3i(position.getX(), position.getY(), position.getZ()); BlockState newState = getBlockState(block); - BlockSnapshot snapshot = BlockSnapshot.builder() + BlockSnapshot snapshot = builder.reset() .blockState(newState) .position(pos) .world(world.getProperties()) From 03819a23426db5296164e0a1524308772c63d981 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Tue, 17 May 2016 00:58:07 -0400 Subject: [PATCH 30/39] Use a fixed entity spawn cause of PLUGIN type for creating entities --- .../main/java/com/sk89q/worldedit/sponge/SpongeWorld.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java index c6309cb22..33914c626 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java @@ -44,6 +44,8 @@ import org.spongepowered.api.data.property.block.SkyLuminanceProperty; import org.spongepowered.api.entity.EntityType; import org.spongepowered.api.entity.EntityTypes; import org.spongepowered.api.event.cause.Cause; +import org.spongepowered.api.event.cause.entity.spawn.SpawnCause; +import org.spongepowered.api.event.cause.entity.spawn.SpawnTypes; import org.spongepowered.api.world.World; import javax.annotation.Nullable; @@ -262,6 +264,8 @@ public abstract class SpongeWorld extends AbstractWorld { protected abstract void applyEntityData(org.spongepowered.api.entity.Entity entity, BaseEntity data); + private static final Cause ENTITY_SPAWN_CAUSE = Cause.source(SpawnCause.builder().type(SpawnTypes.PLUGIN).build()).build(); + @Nullable @Override public Entity createEntity(Location location, BaseEntity entity) { @@ -285,7 +289,7 @@ public abstract class SpongeWorld extends AbstractWorld { new Vector3d(dir.getX(), dir.getY(), dir.getZ()) ); - if (world.spawnEntity(newEnt, Cause.source(SpongeWorldEdit.container()).build())) { + if (world.spawnEntity(newEnt, ENTITY_SPAWN_CAUSE)) { return new SpongeEntity(newEnt); } } From baa3a0a8b501750ce2812be91b5b7c1605676a24 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Wed, 18 May 2016 17:38:46 -0400 Subject: [PATCH 31/39] Added WorldEdit CUI support --- .../worldedit/sponge/CUIChannelHandler.java | 60 +++++++++++++++++++ .../sk89q/worldedit/sponge/SpongePlayer.java | 7 ++- .../worldedit/sponge/SpongeWorldEdit.java | 5 +- 3 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CUIChannelHandler.java diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CUIChannelHandler.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CUIChannelHandler.java new file mode 100644 index 000000000..1be22b0b0 --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/CUIChannelHandler.java @@ -0,0 +1,60 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge; + +import com.sk89q.worldedit.LocalSession; +import org.spongepowered.api.Platform; +import org.spongepowered.api.Sponge; +import org.spongepowered.api.entity.living.player.Player; +import org.spongepowered.api.network.*; + +import java.nio.charset.StandardCharsets; + +public class CUIChannelHandler implements RawDataListener { + public static final String CUI_PLUGIN_CHANNEL = "WECUI"; + + private static ChannelBinding.RawDataChannel channel; + + public static void init() { + channel = Sponge.getChannelRegistrar().createRawChannel(SpongeWorldEdit.inst(), CUI_PLUGIN_CHANNEL); + channel.addListener(Platform.Type.SERVER, new CUIChannelHandler()); + } + + + public static ChannelBinding.RawDataChannel getActiveChannel() { + return channel; + } + + @Override + public void handlePayload(ChannelBuf data, RemoteConnection connection, Platform.Type side) { + if (connection instanceof PlayerConnection) { + Player player = ((PlayerConnection) connection).getPlayer(); + + LocalSession session = SpongeWorldEdit.inst().getSession(player); + + if (session.hasCUISupport()) { + return; + } + + session.handleCUIInitializationMessage(new String(data.readBytes(data.available()), StandardCharsets.UTF_8)); + session.describeCUI(SpongeWorldEdit.inst().wrapPlayer(player)); + } + } +} diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java index bed23f3cc..30b1ea0c1 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -30,11 +30,8 @@ import com.sk89q.worldedit.internal.LocalWorldAdapter; import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.session.SessionKey; import com.sk89q.worldedit.util.Location; -import net.minecraft.entity.player.EntityPlayerMP; -import net.minecraft.util.ChatComponentText; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.item.inventory.ItemStack; -import org.spongepowered.api.text.LiteralText; import org.spongepowered.api.text.Text; import org.spongepowered.api.text.format.TextColor; import org.spongepowered.api.text.format.TextColors; @@ -42,6 +39,7 @@ import org.spongepowered.api.text.serializer.TextSerializers; import org.spongepowered.api.world.World; import javax.annotation.Nullable; +import java.nio.charset.StandardCharsets; import java.util.Optional; import java.util.UUID; @@ -116,6 +114,9 @@ public class SpongePlayer extends AbstractPlayerActor { if (params.length > 0) { send = send + "|" + StringUtil.joinString(params, "|"); } + + String finalData = send; + CUIChannelHandler.getActiveChannel().sendTo(player, buffer -> buffer.writeBytes(finalData.getBytes(StandardCharsets.UTF_8))); } @Override diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index 7b241cbd4..0ff60109a 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -37,14 +37,11 @@ import org.spongepowered.api.config.ConfigManager; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.event.Listener; import org.spongepowered.api.event.block.InteractBlockEvent; -import org.spongepowered.api.event.cause.NamedCause; import org.spongepowered.api.event.game.state.*; import org.spongepowered.api.item.inventory.ItemStack; import org.spongepowered.api.plugin.Plugin; import org.spongepowered.api.plugin.PluginContainer; import org.spongepowered.api.scheduler.Task; -import org.spongepowered.api.text.Text; -import org.spongepowered.api.text.channel.MessageChannel; import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; @@ -107,7 +104,7 @@ public class SpongeWorldEdit { @Listener public void init(GameInitializationEvent event) { - // WECUIPacketHandler.init(); + CUIChannelHandler.init(); } @Listener From 785a827f0117e3c82005ef9b269fb61551eeb42d Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Wed, 18 May 2016 18:18:14 -0400 Subject: [PATCH 32/39] The SpongePermissionsProvider is not the SponePermissionsProvider --- ...ssionsProvider.java => SpongePermissionsProvider.java} | 2 +- .../java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) rename worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/{SponePermissionsProvider.java => SpongePermissionsProvider.java} (96%) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SponePermissionsProvider.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePermissionsProvider.java similarity index 96% rename from worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SponePermissionsProvider.java rename to worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePermissionsProvider.java index 967b25a55..62c75d5f3 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SponePermissionsProvider.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePermissionsProvider.java @@ -22,7 +22,7 @@ package com.sk89q.worldedit.sponge; import org.spongepowered.api.command.CommandCallable; import org.spongepowered.api.entity.living.player.Player; -public class SponePermissionsProvider { +public class SpongePermissionsProvider { public boolean hasPermission(Player player, String permission) { return player.hasPermission(permission); diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index 0ff60109a..1e198fa90 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -64,7 +64,7 @@ public class SpongeWorldEdit { public static final String MOD_ID = "worldedit"; public static final String CUI_PLUGIN_CHANNEL = "WECUI"; - private SponePermissionsProvider provider; + private SpongePermissionsProvider provider; @Inject private PluginContainer container; @@ -120,7 +120,7 @@ public class SpongeWorldEdit { } this.platform = new SpongePlatform(this); - this.provider = new SponePermissionsProvider(); + this.provider = new SpongePermissionsProvider(); WorldEdit.getInstance().getPlatformManager().register(platform); } @@ -297,11 +297,11 @@ public class SpongeWorldEdit { return SpongeWorldEdit.class.getAnnotation(Plugin.class).version(); } - public void setPermissionsProvider(SponePermissionsProvider provider) { + public void setPermissionsProvider(SpongePermissionsProvider provider) { this.provider = provider; } - public SponePermissionsProvider getPermissionsProvider() { + public SpongePermissionsProvider getPermissionsProvider() { return provider; } From da3324584251484b35dd291975886a7513eb8345 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Wed, 18 May 2016 18:30:22 -0400 Subject: [PATCH 33/39] Perform some restructuring --- .../com/sk89q/worldedit/sponge/SpongeAdapter.java | 1 + .../worldedit/sponge/SpongeBiomeRegistry.java | 1 + .../com/sk89q/worldedit/sponge/SpongeEntity.java | 1 + .../sk89q/worldedit/sponge/SpongePlatform.java | 3 +++ .../com/sk89q/worldedit/sponge/SpongePlayer.java | 1 + .../com/sk89q/worldedit/sponge/SpongeWorld.java | 8 +++----- .../sk89q/worldedit/sponge/SpongeWorldEdit.java | 3 +++ .../sponge/{ => config}/SpongeConfiguration.java | 3 ++- .../worldedit/sponge/{ => nms}/IDHelper.java | 5 +++-- .../worldedit/sponge/{ => nms}/NBTConverter.java | 3 ++- .../worldedit/sponge/{ => nms}/NMSHelper.java | 5 +++-- .../sponge/{ => nms}/SpongeNMSWorld.java | 15 +++------------ .../sponge/{ => nms}/TileEntityBaseBlock.java | 3 ++- .../sponge/{ => nms}/TileEntityUtils.java | 3 ++- 14 files changed, 30 insertions(+), 25 deletions(-) rename worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/{ => config}/SpongeConfiguration.java (93%) rename worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/{ => nms}/IDHelper.java (95%) rename worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/{ => nms}/NBTConverter.java (99%) rename worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/{ => nms}/NMSHelper.java (95%) rename worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/{ => nms}/SpongeNMSWorld.java (94%) rename worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/{ => nms}/TileEntityBaseBlock.java (96%) rename worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/{ => nms}/TileEntityUtils.java (98%) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java index ab4bceedb..51723964f 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeAdapter.java @@ -21,6 +21,7 @@ package com.sk89q.worldedit.sponge; import com.flowpowered.math.vector.Vector3d; import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.sponge.nms.SpongeNMSWorld; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.World; diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java index d65c59f2b..837463139 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java @@ -19,6 +19,7 @@ package com.sk89q.worldedit.sponge; +import com.sk89q.worldedit.sponge.nms.IDHelper; import com.sk89q.worldedit.world.biome.BaseBiome; import com.sk89q.worldedit.world.biome.BiomeData; import com.sk89q.worldedit.world.registry.BiomeRegistry; diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntity.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntity.java index 5c93aeafe..b078f7fa2 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntity.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeEntity.java @@ -24,6 +24,7 @@ import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.entity.metadata.EntityType; import com.sk89q.worldedit.extent.Extent; +import com.sk89q.worldedit.sponge.nms.NMSHelper; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.NullWorld; import org.spongepowered.api.world.World; diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java index 4b006660e..b2db5060a 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java @@ -24,6 +24,9 @@ import com.sk89q.worldedit.entity.Player; import com.sk89q.worldedit.event.platform.CommandEvent; import com.sk89q.worldedit.event.platform.CommandSuggestionEvent; import com.sk89q.worldedit.extension.platform.*; +import com.sk89q.worldedit.sponge.config.SpongeConfiguration; +import com.sk89q.worldedit.sponge.nms.IDHelper; +import com.sk89q.worldedit.sponge.nms.SpongeNMSWorld; import com.sk89q.worldedit.util.command.CommandMapping; import com.sk89q.worldedit.util.command.Dispatcher; import com.sk89q.worldedit.world.World; diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java index 30b1ea0c1..64a553b68 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -29,6 +29,7 @@ import com.sk89q.worldedit.extent.inventory.BlockBag; import com.sk89q.worldedit.internal.LocalWorldAdapter; import com.sk89q.worldedit.internal.cui.CUIEvent; import com.sk89q.worldedit.session.SessionKey; +import com.sk89q.worldedit.sponge.nms.IDHelper; import com.sk89q.worldedit.util.Location; import org.spongepowered.api.entity.living.player.Player; import org.spongepowered.api.item.inventory.ItemStack; diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java index 33914c626..34a3efa54 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java @@ -30,6 +30,7 @@ import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.Entity; import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.sponge.nms.IDHelper; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.AbstractWorld; import com.sk89q.worldedit.world.biome.BaseBiome; @@ -54,7 +55,6 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; import java.util.Random; -import java.util.logging.Logger; import static com.google.common.base.Preconditions.checkNotNull; @@ -64,8 +64,6 @@ import static com.google.common.base.Preconditions.checkNotNull; public abstract class SpongeWorld extends AbstractWorld { protected static final Random random = new Random(); - protected static final int UPDATE = 1, NOTIFY = 2, NOTIFY_CLIENT = 4; - protected static final Logger logger = Logger.getLogger(SpongeWorld.class.getCanonicalName()); private final WeakReference worldRef; @@ -74,9 +72,9 @@ public abstract class SpongeWorld extends AbstractWorld { * * @param world the world */ - SpongeWorld(World world) { + protected SpongeWorld(World world) { checkNotNull(world); - this.worldRef = new WeakReference(world); + this.worldRef = new WeakReference<>(world); } /** diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index 1e198fa90..320c92b67 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -28,6 +28,9 @@ import com.sk89q.worldedit.event.platform.PlatformReadyEvent; import com.sk89q.worldedit.extension.platform.Actor; import com.sk89q.worldedit.extension.platform.Platform; import com.sk89q.worldedit.internal.LocalWorldAdapter; +import com.sk89q.worldedit.sponge.config.SpongeConfiguration; +import com.sk89q.worldedit.sponge.nms.NMSHelper; +import com.sk89q.worldedit.sponge.nms.SpongeNMSWorld; import org.spongepowered.api.Sponge; import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockType; diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java similarity index 93% rename from worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java rename to worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java index ee8470d77..947e0750f 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeConfiguration.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java @@ -17,8 +17,9 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.sponge; +package com.sk89q.worldedit.sponge.config; +import com.sk89q.worldedit.sponge.SpongeWorldEdit; import com.sk89q.worldedit.util.PropertiesConfiguration; import java.io.File; diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/IDHelper.java similarity index 95% rename from worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java rename to worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/IDHelper.java index be717fa3d..52aa06c0c 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/IDHelper.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/IDHelper.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.sponge; +package com.sk89q.worldedit.sponge.nms; import net.minecraft.block.Block; import net.minecraft.item.Item; @@ -26,7 +26,8 @@ import org.spongepowered.api.block.BlockType; import org.spongepowered.api.item.ItemType; import org.spongepowered.api.world.biome.BiomeType; -final class IDHelper { +@Deprecated +public final class IDHelper { private IDHelper() { } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NBTConverter.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/NBTConverter.java similarity index 99% rename from worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NBTConverter.java rename to worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/NBTConverter.java index a026a51cf..48e8b5da0 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NBTConverter.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/NBTConverter.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.sponge; +package com.sk89q.worldedit.sponge.nms; import com.sk89q.jnbt.*; import net.minecraft.nbt.*; @@ -28,6 +28,7 @@ import java.util.Map.Entry; /** * Converts between JNBT and Minecraft NBT classes. */ +@Deprecated final class NBTConverter { private NBTConverter() { diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NMSHelper.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/NMSHelper.java similarity index 95% rename from worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NMSHelper.java rename to worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/NMSHelper.java index da8abf3e5..4917c1f68 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/NMSHelper.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/NMSHelper.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.sponge; +package com.sk89q.worldedit.sponge.nms; import com.sk89q.worldedit.blocks.BaseItemStack; import com.sk89q.worldedit.entity.BaseEntity; @@ -28,7 +28,8 @@ import org.spongepowered.api.item.inventory.ItemStack; import java.util.Map; -final class NMSHelper { +@Deprecated +public final class NMSHelper { private NMSHelper() { } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeNMSWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/SpongeNMSWorld.java similarity index 94% rename from worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeNMSWorld.java rename to worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/SpongeNMSWorld.java index ecdfc8677..4e1c38d23 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeNMSWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/SpongeNMSWorld.java @@ -17,17 +17,16 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.sponge; +package com.sk89q.worldedit.sponge.nms; import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; import com.sk89q.worldedit.Vector; -import com.sk89q.worldedit.Vector2D; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.LazyBlock; import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.internal.Constants; -import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.sponge.SpongeWorld; import com.sk89q.worldedit.util.TreeGenerator; import net.minecraft.block.*; import net.minecraft.block.state.IBlockState; @@ -37,11 +36,6 @@ import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagInt; import net.minecraft.tileentity.TileEntity; import net.minecraft.util.BlockPos; -import net.minecraft.util.LongHashMap; -import net.minecraft.world.ChunkCoordIntPair; -import net.minecraft.world.chunk.Chunk; -import net.minecraft.world.chunk.IChunkProvider; -import net.minecraft.world.gen.ChunkProviderServer; import net.minecraft.world.gen.feature.*; import org.spongepowered.api.block.BlockState; import org.spongepowered.api.entity.Entity; @@ -49,13 +43,10 @@ import org.spongepowered.api.world.Location; import org.spongepowered.api.world.World; import javax.annotation.Nullable; -import java.lang.reflect.Field; -import java.util.List; -import java.util.Set; -import java.util.logging.Level; import static com.google.common.base.Preconditions.checkNotNull; +@Deprecated public class SpongeNMSWorld extends SpongeWorld { private static final IBlockState JUNGLE_LOG = Blocks.log.getDefaultState().withProperty(BlockOldLog.VARIANT, BlockPlanks.EnumType.JUNGLE); diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityBaseBlock.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/TileEntityBaseBlock.java similarity index 96% rename from worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityBaseBlock.java rename to worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/TileEntityBaseBlock.java index 9004474b5..524d680de 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityBaseBlock.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/TileEntityBaseBlock.java @@ -17,13 +17,14 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.sponge; +package com.sk89q.worldedit.sponge.nms; import com.sk89q.worldedit.blocks.BaseBlock; import com.sk89q.worldedit.blocks.TileEntityBlock; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.tileentity.TileEntity; +@Deprecated public class TileEntityBaseBlock extends BaseBlock implements TileEntityBlock { public TileEntityBaseBlock(int type, int data, TileEntity tile) { diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityUtils.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/TileEntityUtils.java similarity index 98% rename from worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityUtils.java rename to worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/TileEntityUtils.java index 3c9f3d587..357cf53ad 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/TileEntityUtils.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/nms/TileEntityUtils.java @@ -17,7 +17,7 @@ * along with this program. If not, see . */ -package com.sk89q.worldedit.sponge; +package com.sk89q.worldedit.sponge.nms; import com.sk89q.worldedit.Vector; import net.minecraft.nbt.NBTTagCompound; @@ -34,6 +34,7 @@ import static com.google.common.base.Preconditions.checkNotNull; /** * Utility methods for setting tile entities in the world. */ +@Deprecated final class TileEntityUtils { private TileEntityUtils() { From 27b6efefdbfdd03a085c60d887db13cf7ea1e94c Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Wed, 18 May 2016 19:27:38 -0400 Subject: [PATCH 34/39] Use configurate for configuration --- worldedit-sponge/build.gradle | 1 + .../worldedit/sponge/SpongeWorldEdit.java | 4 +- .../config/ConfigurateConfiguration.java | 123 ++++++++++++++++++ .../sponge/config/SpongeConfiguration.java | 18 ++- 4 files changed, 137 insertions(+), 9 deletions(-) create mode 100644 worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/ConfigurateConfiguration.java diff --git a/worldedit-sponge/build.gradle b/worldedit-sponge/build.gradle index 8668cee0a..8d8e81f2b 100644 --- a/worldedit-sponge/build.gradle +++ b/worldedit-sponge/build.gradle @@ -21,6 +21,7 @@ apply plugin: 'net.minecrell.vanilla.server.library' dependencies { compile project(':worldedit-core') compile 'org.spongepowered:spongeapi:4.+' + compile 'ninja.leaping.configurate:configurate-hocon:3.1' testCompile group: 'org.mockito', name: 'mockito-core', version:'1.9.0-rc1' } diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index 320c92b67..7c923b0e4 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -94,12 +94,12 @@ public class SpongeWorldEdit { public void preInit(GamePreInitializationEvent event) { // Setup working directory ConfigManager service = Sponge.getGame().getConfigManager(); - Path path = service.getPluginConfig(this).getDirectory(); + Path path = service.getPluginConfig(this).getDirectory(); workingDir = path.toFile(); workingDir.mkdir(); - config = new SpongeConfiguration(this); + config = new SpongeConfiguration(service.getPluginConfig(this).getConfig(), logger); config.load(); Task.builder().interval(30, TimeUnit.SECONDS).execute(ThreadSafeCache.getInstance()).submit(this); diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/ConfigurateConfiguration.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/ConfigurateConfiguration.java new file mode 100644 index 000000000..4a5a03d03 --- /dev/null +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/ConfigurateConfiguration.java @@ -0,0 +1,123 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * 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 . + */ + +package com.sk89q.worldedit.sponge.config; + +import com.google.common.reflect.TypeToken; +import com.sk89q.worldedit.LocalConfiguration; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.session.SessionManager; +import com.sk89q.worldedit.world.snapshot.SnapshotRepository; +import ninja.leaping.configurate.ConfigurationOptions; +import ninja.leaping.configurate.commented.CommentedConfigurationNode; +import ninja.leaping.configurate.loader.ConfigurationLoader; +import ninja.leaping.configurate.objectmapping.ObjectMappingException; + +import java.io.IOException; +import java.util.HashSet; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ConfigurateConfiguration extends LocalConfiguration { + + private final ConfigurationLoader config; + protected final Logger logger; + + protected CommentedConfigurationNode node; + + public ConfigurateConfiguration(ConfigurationLoader config, Logger logger) { + this.config = config; + this.logger = logger; + } + + @Override + public void load() { + try { + ConfigurationOptions options = ConfigurationOptions.defaults(); + options.setShouldCopyDefaults(true); + + node = config.load(options); + } catch (IOException e) { + logger.log(Level.WARNING, "Error loading WorldEdit configuration", e); + } + + profile = node.getNode("debug").getBoolean(profile); + wandItem = node.getNode("wand-item").getInt(wandItem); + + defaultChangeLimit = Math.max(-1, node.getNode("limits", "max-blocks-changed", "default").getInt(defaultChangeLimit)); + maxChangeLimit = Math.max(-1, node.getNode("limits", "max-blocks-changed", "maximum").getInt(maxChangeLimit)); + + defaultMaxPolygonalPoints = Math.max(-1, node.getNode("limits", "max-polygonal-points", "default").getInt(defaultMaxPolygonalPoints)); + maxPolygonalPoints = Math.max(-1, node.getNode("limits", "max-polygonal-points", "maximum").getInt(maxPolygonalPoints)); + + maxRadius = Math.max(-1, node.getNode("limits", "max-radius").getInt(maxRadius)); + maxBrushRadius = node.getNode("limits", "max-brush-radius").getInt(maxBrushRadius); + maxSuperPickaxeSize = Math.max(1, node.getNode("limits", "max-super-pickaxe-size").getInt(maxSuperPickaxeSize)); + + butcherDefaultRadius = Math.max(-1, node.getNode("limits", "butcher-radius", "default").getInt(butcherDefaultRadius)); + butcherMaxRadius = Math.max(-1, node.getNode("limits", "butcher-radius", "maximum").getInt(butcherMaxRadius)); + + try { + disallowedBlocks = new HashSet<>(node.getNode("limits", "disallowed-blocks").getList(TypeToken.of(Integer.class))); + } catch (ObjectMappingException e) { + logger.log(Level.WARNING, "Error loading WorldEdit configuration", e); + } + try { + allowedDataCycleBlocks = new HashSet<>(node.getNode("limits", "allowed-data-cycle-blocks").getList(TypeToken.of(Integer.class))); + } catch (ObjectMappingException e) { + logger.log(Level.WARNING, "Error loading WorldEdit configuration", e); + } + + registerHelp = node.getNode("register-help").getBoolean(true); + logCommands = node.getNode("logging", "log-commands").getBoolean(logCommands); + logFile = node.getNode("logging", "file").getString(logFile); + + superPickaxeDrop = node.getNode("super-pickaxe", "drop-items").getBoolean(superPickaxeDrop); + superPickaxeManyDrop = node.getNode("super-pickaxe", "many-drop-items").getBoolean(superPickaxeManyDrop); + + noDoubleSlash = node.getNode("no-double-slash").getBoolean(noDoubleSlash); + + useInventory = node.getNode("use-inventory", "enable").getBoolean(useInventory); + useInventoryOverride = node.getNode("use-inventory", "allow-override").getBoolean(useInventoryOverride); + useInventoryCreativeOverride = node.getNode("use-inventory", "creative-mode-overrides").getBoolean(useInventoryCreativeOverride); + + navigationWand = node.getNode("navigation-wand", "item").getInt(navigationWand); + navigationWandMaxDistance = node.getNode("navigation-wand", "max-distance").getInt(navigationWandMaxDistance); + navigationUseGlass = node.getNode("navigation", "use-glass").getBoolean(navigationUseGlass); + + scriptTimeout = node.getNode("scripting", "timeout").getInt(scriptTimeout); + scriptsDir = node.getNode("scripting", "dir").getString(scriptsDir); + + saveDir = node.getNode("saving", "dir").getString(saveDir); + + allowSymlinks = node.getNode("files", "allow-symbolic-links").getBoolean(false); + LocalSession.MAX_HISTORY_SIZE = Math.max(0, node.getNode("history", "size").getInt(15)); + SessionManager.EXPIRATION_GRACE = node.getNode("history", "expiration").getInt(10) * 60 * 1000; + + showHelpInfo = node.getNode("show-help-on-first-use").getBoolean(true); + + String snapshotsDir = node.getNode("snapshots", "directory").getString(""); + if (!snapshotsDir.isEmpty()) { + snapshotRepo = new SnapshotRepository(snapshotsDir); + } + + String type = node.getNode("shell-save-type").getString("").trim(); + shellSaveType = type.equals("") ? null : type; + } +} \ No newline at end of file diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java index 947e0750f..7a3b908be 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java @@ -20,23 +20,27 @@ package com.sk89q.worldedit.sponge.config; import com.sk89q.worldedit.sponge.SpongeWorldEdit; -import com.sk89q.worldedit.util.PropertiesConfiguration; +import ninja.leaping.configurate.commented.CommentedConfigurationNode; +import ninja.leaping.configurate.loader.ConfigurationLoader; import java.io.File; +import java.util.logging.Logger; -public class SpongeConfiguration extends PropertiesConfiguration { +public class SpongeConfiguration extends ConfigurateConfiguration { public boolean creativeEnable = false; public boolean cheatMode = false; - public SpongeConfiguration(SpongeWorldEdit mod) { - super(new File(mod.getWorkingDir() + File.separator + "worldedit.properties")); + public SpongeConfiguration(ConfigurationLoader config, Logger logger) { + super(config, logger); } @Override - protected void loadExtra() { - creativeEnable = getBool("use-in-creative", false); - cheatMode = getBool("cheat-mode", false); + public void load() { + super.load(); + + creativeEnable = node.getNode("use-in-creative").getBoolean(false); + cheatMode = node.getNode("cheat-mode").getBoolean(false); } @Override From 1c2348cd41ec8e83e4baa73ce738ed1318d5c4f7 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Wed, 18 May 2016 19:35:24 -0400 Subject: [PATCH 35/39] Properly generate the default configuration --- .../worldedit/sponge/config/ConfigurateConfiguration.java | 4 ++-- .../worldedit/sponge/config/SpongeConfiguration.java | 8 ++++++++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/ConfigurateConfiguration.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/ConfigurateConfiguration.java index 4a5a03d03..d53625c8e 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/ConfigurateConfiguration.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/ConfigurateConfiguration.java @@ -36,7 +36,7 @@ import java.util.logging.Logger; public class ConfigurateConfiguration extends LocalConfiguration { - private final ConfigurationLoader config; + protected final ConfigurationLoader config; protected final Logger logger; protected CommentedConfigurationNode node; @@ -50,7 +50,7 @@ public class ConfigurateConfiguration extends LocalConfiguration { public void load() { try { ConfigurationOptions options = ConfigurationOptions.defaults(); - options.setShouldCopyDefaults(true); + options = options.setShouldCopyDefaults(true); node = config.load(options); } catch (IOException e) { diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java index 7a3b908be..afd7047ab 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java @@ -24,6 +24,8 @@ import ninja.leaping.configurate.commented.CommentedConfigurationNode; import ninja.leaping.configurate.loader.ConfigurationLoader; import java.io.File; +import java.io.IOException; +import java.util.logging.Level; import java.util.logging.Logger; public class SpongeConfiguration extends ConfigurateConfiguration { @@ -41,6 +43,12 @@ public class SpongeConfiguration extends ConfigurateConfiguration { creativeEnable = node.getNode("use-in-creative").getBoolean(false); cheatMode = node.getNode("cheat-mode").getBoolean(false); + + try { + config.save(node); + } catch (IOException e) { + logger.log(Level.WARNING, "Error loading WorldEdit configuration", e); + } } @Override From 991aaa05415a99facf92cf6f30f2ebf4a8f45ac7 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Wed, 18 May 2016 19:46:49 -0400 Subject: [PATCH 36/39] Update the check style rules to allow configurate --- config/checkstyle/import-control.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/config/checkstyle/import-control.xml b/config/checkstyle/import-control.xml index 66d38b3ea..04dfec2ed 100644 --- a/config/checkstyle/import-control.xml +++ b/config/checkstyle/import-control.xml @@ -57,6 +57,7 @@ + From bc29bff0721f82f95386cf49170014390256d149 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Wed, 18 May 2016 21:03:29 -0400 Subject: [PATCH 37/39] Additional cleanup for the Sponge implementation --- config/checkstyle/import-control.xml | 1 + .../worldedit/sponge/SpongeBiomeRegistry.java | 5 +-- .../worldedit/sponge/SpongePlatform.java | 2 +- .../sk89q/worldedit/sponge/SpongePlayer.java | 9 +----- .../sk89q/worldedit/sponge/SpongeWorld.java | 6 +++- .../worldedit/sponge/SpongeWorldData.java | 2 +- .../worldedit/sponge/SpongeWorldEdit.java | 10 +++--- .../worldedit/sponge/ThreadSafeCache.java | 8 ++--- .../config/ConfigurateConfiguration.java | 9 +++--- .../sponge/config/SpongeConfiguration.java | 5 ++- .../main/resources/META-INF/worldedit_at.cfg | 4 --- .../resources/defaults/worldedit.properties | 32 ------------------- 12 files changed, 25 insertions(+), 68 deletions(-) delete mode 100644 worldedit-sponge/src/main/resources/META-INF/worldedit_at.cfg delete mode 100644 worldedit-sponge/src/main/resources/defaults/worldedit.properties diff --git a/config/checkstyle/import-control.xml b/config/checkstyle/import-control.xml index 04dfec2ed..d620978fd 100644 --- a/config/checkstyle/import-control.xml +++ b/config/checkstyle/import-control.xml @@ -57,6 +57,7 @@ + diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java index 837463139..3e5a0a2f1 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeBiomeRegistry.java @@ -31,7 +31,7 @@ import java.util.ArrayList; import java.util.List; /** - * Provides access to biome data in Forge. + * Provides access to biome data in Sponge. */ class SpongeBiomeRegistry implements BiomeRegistry { @@ -56,9 +56,6 @@ class SpongeBiomeRegistry implements BiomeRegistry { return new SpongeBiomeData(IDHelper.resolveBiome(biome.getId())); } - /** - * Cached biome data information. - */ private static class SpongeBiomeData implements BiomeData { private final BiomeType biome; diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java index b2db5060a..93dbc0174 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlatform.java @@ -170,7 +170,7 @@ class SpongePlatform extends AbstractPlatform implements MultiUserPlatform { @Override public Map getCapabilities() { Map capabilities = new EnumMap<>(Capability.class); - capabilities.put(Capability.CONFIGURATION, Preference.PREFER_OTHERS); + 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); diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java index 64a553b68..d88f6ecc2 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongePlayer.java @@ -154,14 +154,7 @@ public class SpongePlayer extends AbstractPlayerActor { this.player.getWorld(), pos.getX(), pos.getY(), pos.getZ() ); - this.player.setLocationAndRotation( - loc, - new Vector3d( - pitch, - yaw, - 0 - ) - ); + this.player.setLocationAndRotation(loc, new Vector3d(pitch, yaw, 0)); } @Override diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java index 34a3efa54..7d97bc7b4 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorld.java @@ -45,6 +45,7 @@ import org.spongepowered.api.data.property.block.SkyLuminanceProperty; import org.spongepowered.api.entity.EntityType; import org.spongepowered.api.entity.EntityTypes; import org.spongepowered.api.event.cause.Cause; +import org.spongepowered.api.event.cause.NamedCause; import org.spongepowered.api.event.cause.entity.spawn.SpawnCause; import org.spongepowered.api.event.cause.entity.spawn.SpawnTypes; import org.spongepowered.api.world.World; @@ -262,7 +263,10 @@ public abstract class SpongeWorld extends AbstractWorld { protected abstract void applyEntityData(org.spongepowered.api.entity.Entity entity, BaseEntity data); - private static final Cause ENTITY_SPAWN_CAUSE = Cause.source(SpawnCause.builder().type(SpawnTypes.PLUGIN).build()).build(); + private static final Cause ENTITY_SPAWN_CAUSE = Cause + .source(SpawnCause.builder().type(SpawnTypes.PLUGIN).build()) + .suggestNamed(NamedCause.SOURCE, SpongeWorldEdit.inst()) + .build(); @Nullable @Override diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldData.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldData.java index bc0d18069..789dfc0c3 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldData.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldData.java @@ -23,7 +23,7 @@ import com.sk89q.worldedit.world.registry.BiomeRegistry; import com.sk89q.worldedit.world.registry.LegacyWorldData; /** - * World data for the Forge platform. + * World data for the Sponge platform. */ class SpongeWorldData extends LegacyWorldData { diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java index 7c923b0e4..4609c53fa 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/SpongeWorldEdit.java @@ -31,6 +31,7 @@ import com.sk89q.worldedit.internal.LocalWorldAdapter; import com.sk89q.worldedit.sponge.config.SpongeConfiguration; import com.sk89q.worldedit.sponge.nms.NMSHelper; import com.sk89q.worldedit.sponge.nms.SpongeNMSWorld; +import org.slf4j.Logger; import org.spongepowered.api.Sponge; import org.spongepowered.api.block.BlockSnapshot; import org.spongepowered.api.block.BlockType; @@ -62,10 +63,9 @@ import static com.google.common.base.Preconditions.checkNotNull; public class SpongeWorldEdit { @Inject - private java.util.logging.Logger logger; + private Logger logger; public static final String MOD_ID = "worldedit"; - public static final String CUI_PLUGIN_CHANNEL = "WECUI"; private SpongePermissionsProvider provider; @@ -118,7 +118,7 @@ public class SpongeWorldEdit { @Listener public void serverAboutToStart(GameAboutToStartServerEvent event) { if (this.platform != null) { - logger.warning("FMLServerStartingEvent occurred when FMLServerStoppingEvent hasn't"); + logger.warn("GameAboutToStartServerEvent occurred when GameStoppingServerEvent hasn't"); WorldEdit.getInstance().getPlatformManager().unregister(platform); } @@ -226,7 +226,7 @@ public class SpongeWorldEdit { /** * Get the configuration. * - * @return the Forge configuration + * @return the Sponge configuration */ SpongeConfiguration getConfig() { return this.config; @@ -292,7 +292,7 @@ public class SpongeWorldEdit { } /** - * Get the version of the WorldEdit-for-Forge implementation. + * Get the version of the WorldEdit Sponge implementation. * * @return a version string */ diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java index f273b972c..43a7c0541 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/ThreadSafeCache.java @@ -22,8 +22,8 @@ package com.sk89q.worldedit.sponge; import org.spongepowered.api.Sponge; import org.spongepowered.api.entity.living.player.Player; -import java.util.Collections; -import java.util.HashSet; +import java.util.ArrayList; +import java.util.List; import java.util.Set; import java.util.UUID; import java.util.concurrent.CopyOnWriteArraySet; @@ -34,7 +34,7 @@ import java.util.concurrent.CopyOnWriteArraySet; public class ThreadSafeCache implements Runnable { private static final ThreadSafeCache INSTANCE = new ThreadSafeCache(); - private Set onlineIds = Collections.emptySet(); + private Set onlineIds = new CopyOnWriteArraySet<>(); /** * Get an concurrent-safe set of UUIDs of online players. @@ -47,7 +47,7 @@ public class ThreadSafeCache implements Runnable { @Override public void run() { - Set onlineIds = new HashSet<>(); + List onlineIds = new ArrayList<>(); for (Player player : Sponge.getServer().getOnlinePlayers()) { onlineIds.add(player.getUniqueId()); diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/ConfigurateConfiguration.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/ConfigurateConfiguration.java index d53625c8e..7db17801b 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/ConfigurateConfiguration.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/ConfigurateConfiguration.java @@ -28,11 +28,10 @@ import ninja.leaping.configurate.ConfigurationOptions; import ninja.leaping.configurate.commented.CommentedConfigurationNode; import ninja.leaping.configurate.loader.ConfigurationLoader; import ninja.leaping.configurate.objectmapping.ObjectMappingException; +import org.slf4j.Logger; import java.io.IOException; import java.util.HashSet; -import java.util.logging.Level; -import java.util.logging.Logger; public class ConfigurateConfiguration extends LocalConfiguration { @@ -54,7 +53,7 @@ public class ConfigurateConfiguration extends LocalConfiguration { node = config.load(options); } catch (IOException e) { - logger.log(Level.WARNING, "Error loading WorldEdit configuration", e); + logger.warn("Error loading WorldEdit configuration", e); } profile = node.getNode("debug").getBoolean(profile); @@ -76,12 +75,12 @@ public class ConfigurateConfiguration extends LocalConfiguration { try { disallowedBlocks = new HashSet<>(node.getNode("limits", "disallowed-blocks").getList(TypeToken.of(Integer.class))); } catch (ObjectMappingException e) { - logger.log(Level.WARNING, "Error loading WorldEdit configuration", e); + logger.warn("Error loading WorldEdit configuration", e); } try { allowedDataCycleBlocks = new HashSet<>(node.getNode("limits", "allowed-data-cycle-blocks").getList(TypeToken.of(Integer.class))); } catch (ObjectMappingException e) { - logger.log(Level.WARNING, "Error loading WorldEdit configuration", e); + logger.warn("Error loading WorldEdit configuration", e); } registerHelp = node.getNode("register-help").getBoolean(true); diff --git a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java index afd7047ab..7fbe941ad 100644 --- a/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java +++ b/worldedit-sponge/src/main/java/com/sk89q/worldedit/sponge/config/SpongeConfiguration.java @@ -22,11 +22,10 @@ package com.sk89q.worldedit.sponge.config; import com.sk89q.worldedit.sponge.SpongeWorldEdit; import ninja.leaping.configurate.commented.CommentedConfigurationNode; import ninja.leaping.configurate.loader.ConfigurationLoader; +import org.slf4j.Logger; import java.io.File; import java.io.IOException; -import java.util.logging.Level; -import java.util.logging.Logger; public class SpongeConfiguration extends ConfigurateConfiguration { @@ -47,7 +46,7 @@ public class SpongeConfiguration extends ConfigurateConfiguration { try { config.save(node); } catch (IOException e) { - logger.log(Level.WARNING, "Error loading WorldEdit configuration", e); + logger.warn("Error loading WorldEdit configuration", e); } } diff --git a/worldedit-sponge/src/main/resources/META-INF/worldedit_at.cfg b/worldedit-sponge/src/main/resources/META-INF/worldedit_at.cfg deleted file mode 100644 index 33f039ce3..000000000 --- a/worldedit-sponge/src/main/resources/META-INF/worldedit_at.cfg +++ /dev/null @@ -1,4 +0,0 @@ -public net.minecraft.world.gen.ChunkProviderServer field_73248_b # droppedChunksSet -public net.minecraft.world.gen.ChunkProviderServer field_73244_f # id2ChunkMap -public net.minecraft.world.gen.ChunkProviderServer field_73245_g # loadedChunks -public net.minecraft.world.gen.ChunkProviderServer field_73246_d # serverChunkGenerator diff --git a/worldedit-sponge/src/main/resources/defaults/worldedit.properties b/worldedit-sponge/src/main/resources/defaults/worldedit.properties deleted file mode 100644 index 9c3f5d327..000000000 --- a/worldedit-sponge/src/main/resources/defaults/worldedit.properties +++ /dev/null @@ -1,32 +0,0 @@ -#Don't put comments; they get removed -default-max-polygon-points=-1 -schematic-save-dir=schematics -allow-extra-data-values=false -super-pickaxe-many-drop-items=true -register-help=true -nav-wand-item=345 -profile=false -super-pickaxe-drop-items=true -disallowed-blocks=6,26,27,28,31,32,34,36,37,38,39,40,46,50,51,55,59,66,69,75,76,93,94,77,81,83,7,14,15,16,56 -max-super-pickaxe-size=5 -max-brush-radius=10 -craftscript-dir=craftscripts -no-double-slash=false -wand-item=271 -shell-save-type= -scripting-timeout=3000 -snapshots-dir= -use-inventory-creative-override=false -log-file=worldedit.log -max-changed-blocks=-1 -nav-wand-distance=50 -butcher-default-radius=-1 -default-max-changed-blocks=-1 -history-size=15 -use-inventory=false -allow-symbolic-links=false -use-inventory-override=false -log-commands=false -butcher-max-radius=-1 -max-polygon-points=20 -max-radius=-1 From 83a3843c15e19873ac91bd08537e59e9547552c0 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Fri, 20 May 2016 13:44:58 -0400 Subject: [PATCH 38/39] Use the main WorldEdit version for Sponge --- worldedit-sponge/build.gradle | 3 --- 1 file changed, 3 deletions(-) diff --git a/worldedit-sponge/build.gradle b/worldedit-sponge/build.gradle index 8d8e81f2b..163e011eb 100644 --- a/worldedit-sponge/build.gradle +++ b/worldedit-sponge/build.gradle @@ -39,9 +39,6 @@ repositories { sourceCompatibility = 1.8 targetCompatibility = 1.8 -version = "6.1.1" -ext.internalVersion = version + ";" + gitCommitHash - minecraft { version = "1.8.9" mappings = "stable_22" From beba8daf458ceaab244f25340c121e57df550964 Mon Sep 17 00:00:00 2001 From: Wyatt Childers Date: Fri, 20 May 2016 14:04:59 -0400 Subject: [PATCH 39/39] Use Sponge version 4.1.0-SNAPSHOT --- worldedit-sponge/build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/worldedit-sponge/build.gradle b/worldedit-sponge/build.gradle index 163e011eb..abdfb6455 100644 --- a/worldedit-sponge/build.gradle +++ b/worldedit-sponge/build.gradle @@ -20,7 +20,7 @@ apply plugin: 'net.minecrell.vanilla.server.library' dependencies { compile project(':worldedit-core') - compile 'org.spongepowered:spongeapi:4.+' + compile 'org.spongepowered:spongeapi:4.1.0-SNAPSHOT' compile 'ninja.leaping.configurate:configurate-hocon:3.1' testCompile group: 'org.mockito', name: 'mockito-core', version:'1.9.0-rc1' }