Initial work on WorldEdit Sponge

This commit is contained in:
Wyatt Childers 2016-02-02 01:28:27 -05:00
parent 1fe197df98
commit 2db47f8fd4
24 changed files with 2619 additions and 1 deletions

View File

@ -1,3 +1,3 @@
rootProject.name = 'worldedit' rootProject.name = 'worldedit'
include 'worldedit-core', 'worldedit-bukkit', 'worldedit-forge' include 'worldedit-core', 'worldedit-bukkit', 'worldedit-forge', 'worldedit-sponge'

View File

@ -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
}

View File

@ -0,0 +1,150 @@
<project name="WorldEdit-Forge" default="main">
<property environment="env"/>
<!-- Properties -->
<property name="build.dir" value="${maven.build.directory}/forge"/>
<property name="resource.dir" value="src/forge/resources"/>
<property name="src.forge.dir" value="src/forge/java"/>
<property name="src.we.dir" value="src/main/java"/>
<property name="bukkit.src.1" value="com/sk89q/bukkit"/>
<property name="bukkit.src.2" value="com/sk89q/worldedit/bukkit"/>
<property name="wepif.src" value="com/sk89q/wepif"/>
<property name="util.yaml.src" value="com/sk89q/util/yaml"/>
<property name="we.yaml.src" value="com/sk89q/worldedit/util/YAMLConfiguration.java"/>
<property name="download.dir" value="forge-download"/>
<property name="forge.dir" value="${build.dir}/forge"/>
<property name="mcp.dir" value="${forge.dir}/mcp"/>
<property name="minecraftsrc.dir" value="${mcp.dir}/src/minecraft"/>
<property file="${minecraftsrc.dir}/fmlversion.properties" />
<property name="mc.version" value="1.6.2"/>
<property name="forge.version" value="9.10.1.850"/>
<!-- Targets -->
<target name="init-msg">
<echo message="Starting build for ${we.version} for MC ${mc.version}"/>
</target>
<target name="download">
<mkdir dir="${download.dir}"/>
<get src="http://files.minecraftforge.net/minecraftforge/minecraftforge-src-${mc.version}-${forge.version}.zip" dest="${download.dir}" usetimestamp="True"/>
<echo message="Download finished"/>
</target>
<target name="check-setup-forge" depends="download">
<available file="${download.dir}/minecraftforge-setup-${mc.version}-${forge.version}.zip" property="setup.forge.present"/>
</target>
<target name="setup-forge" depends="check-setup-forge" unless="setup.forge.present">
<unzip dest="${build.dir}" failOnEmptyArchive="true">
<fileset dir="${download.dir}">
<include name="minecraftforge-src-${mc.version}-${forge.version}.zip"/>
</fileset>
</unzip>
<!-- Set executable permission on forge's *.sh -->
<chmod dir="${forge.dir}" perm="a+rx" includes="**.sh"/>
<!-- Install forge -->
<echo message="Starting forge install process"/>
<exec dir="${forge.dir}" executable="cmd" osfamily="windows" failonerror="true">
<arg value="/c"/>
<arg value="install.cmd"/>
</exec>
<exec dir="${forge.dir}" executable="sh" osfamily="unix" failonerror="true">
<arg value="install.sh"/>
</exec>
<echo message="Forge installation finished"/>
<zip destfile="${download.dir}/minecraftforge-setup-${mc.version}-${forge.version}.zip" basedir="${build.dir}"/>
</target>
<target name="unzip-forge" depends="check-setup-forge" if="setup.forge.present">
<unzip dest="${build.dir}" failOnEmptyArchive="true">
<fileset dir="${download.dir}">
<include name="minecraftforge-setup-${mc.version}-${forge.version}.zip"/>
</fileset>
</unzip>
</target>
<target name="copySRC" >
<!-- Copy WE dependencies source -->
<copy todir="${mcp.dir}/lib" file="${jchronic.path}"/>
<copy todir="${mcp.dir}/lib" file="${truezip.path}"/>
<copy todir="${mcp.dir}/lib" file="${rhino.path}"/>
<!--<copy todir="${mcp.dir}/lib" file="${snakeyaml.path}"/>-->
<!-- Copy WE forge source -->
<copy todir="${minecraftsrc.dir}">
<fileset dir="${src.forge.dir}"/>
</copy>
<!-- Copy WE source -->
<copy todir="${minecraftsrc.dir}">
<fileset dir="${src.we.dir}"/>
</copy>
<!-- Delete bukkit related sources -->
<delete dir="${minecraftsrc.dir}/${bukkit.src.1}"/>
<delete dir="${minecraftsrc.dir}/${bukkit.src.2}"/>
<delete dir="${minecraftsrc.dir}/${wepif.src}"/>
<delete dir="${minecraftsrc.dir}/${util.yaml.src}"/>
<delete file="${minecraftsrc.dir}/${we.yaml.src}"/>
<!-- Set Version -->
<replace file="${minecraftsrc.dir}/com/sk89q/worldedit/forge/WorldEditMod.java" token="%VERSION%" value="${we.version}"/>
</target>
<target name="compile" depends="copySRC">
<echo message="Compiling version ${we.version}"/>
<!-- Recompile -->
<exec dir="${mcp.dir}" executable="cmd" osfamily="windows" failonerror="true">
<arg line="/c recompile.bat --client"/>
</exec>
<exec dir="${mcp.dir}" executable="sh" osfamily="unix" failonerror="true">
<arg line="recompile.sh --client"/>
</exec>
<!-- Reobf -->
<exec dir="${mcp.dir}" executable="cmd" osfamily="windows" failonerror="true">
<arg line="/c reobfuscate_srg.bat --client"/>
</exec>
<exec dir="${mcp.dir}" executable="sh" osfamily="unix" failonerror="true">
<arg line="reobfuscate_srg.sh --client"/>
</exec>
<echo message="Compiling finished"/>
</target>
<target name="copyclasses" depends="compile">
<echo message="Adding version ${we.version} to maven result"/>
<!-- Copy WE classes -->
<copy todir="${maven.build.directory}/classes/com/sk89q/worldedit/forge">
<fileset dir="${mcp.dir}/reobf/minecraft/com/sk89q/worldedit/forge"/>
</copy>
<!-- Copy resources -->
<copy todir="${maven.build.directory}/classes">
<fileset dir="${resource.dir}"></fileset>
</copy>
<replace file="${maven.build.directory}/classes/mcmod.info" token="%VERSION%" value="${we.version}"/>
<replace file="${maven.build.directory}/classes/mcmod.info" token="%MCVERSION%" value="${mc.version}"/>
<echo message="Adding finished"/>
</target>
<target name="main" depends="init-msg, unzip-forge, setup-forge, copyclasses"/>
</project>

View File

@ -0,0 +1,71 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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<String> getSuggestions(CommandSource source, String arguments) throws CommandException {
return null;
}
@Override
public boolean testPermission(CommandSource source) {
return true;
}
@Override
public Optional<? extends Text> getShortDescription(CommandSource source) {
return null;
}
@Override
public Optional<? extends Text> getHelp(CommandSource source) {
return null;
}
@Override
public Text getUsage(CommandSource source) {
return Text.of(command.getDescription().getUsage());
}
}

View File

@ -0,0 +1,47 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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;
}
}

View File

@ -0,0 +1,58 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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;
}
}

View File

@ -0,0 +1,236 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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<String, Tag> 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<Tag> list = new ArrayList<Tag>();
Class<? extends Tag> 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<String> tags = other.getKeySet();
Map<String, Tag> map = new HashMap<String, Tag>();
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());
}
}

View File

@ -0,0 +1,49 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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<Integer, Integer> 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));
}
}

View File

@ -0,0 +1,32 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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) { }
}

View File

@ -0,0 +1,45 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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<org.spongepowered.api.world.World> 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);
}
}

View File

@ -0,0 +1,81 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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<BaseBiome> getBiomes() {
List<BaseBiome> list = new ArrayList<BaseBiome>();
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();
}
}
}

View File

@ -0,0 +1,45 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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();
}
}

View File

@ -0,0 +1,102 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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<org.spongepowered.api.entity.Entity> 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<World> 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> T getFacet(Class<? extends T> 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;
}
}
}

View File

@ -0,0 +1,142 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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.<UUID>empty()).isPresent();
}
@Override
public boolean isTagged() {
return entity.get(Keys.DISPLAY_NAME).orElse(Text.EMPTY).isEmpty();
}
@Override
public boolean isArmorStand() {
return entity instanceof ArmorStand;
}
}

View File

@ -0,0 +1,246 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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<World> 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<Vector2D> 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);
}
}

View File

@ -0,0 +1,174 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.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<ItemType> 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<? extends com.sk89q.worldedit.world.World> getWorlds() {
Collection<org.spongepowered.api.world.World> worlds = Sponge.getServer().getWorlds();
List<com.sk89q.worldedit.world.World> 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<org.spongepowered.api.entity.living.player.Player> 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<Capability, Preference> getCapabilities() {
Map<Capability, Preference> 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<Actor> getConnectedUsers() {
List<Actor> users = new ArrayList<Actor>();
for (org.spongepowered.api.entity.living.player.Player player : Sponge.getServer().getOnlinePlayers()) {
users.add(new SpongePlayer(this, player));
}
return users;
}
}

View File

@ -0,0 +1,220 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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<ItemStack> 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<World> 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<World> loc = new org.spongepowered.api.world.Location<World>(
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> T getFacet(Class<? extends T> 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;
}
}
}

View File

@ -0,0 +1,251 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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<World> worldRef;
/**
* Construct a new world.
*
* @param world the world
*/
SpongeWorld(World world) {
checkNotNull(world);
this.worldRef = new WeakReference<World>(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> groundLuminanceProperty = state.getProperty(GroundLuminanceProperty.class);
Optional<SkyLuminanceProperty> 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<org.spongepowered.api.entity.Entity> 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<? extends Entity> getEntities(Region region) {
List<Entity> entities = new ArrayList<>();
for (org.spongepowered.api.entity.Entity entity : getWorld().getEntities()) {
org.spongepowered.api.world.Location<World> loc = entity.getLocation();
if (region.contains(new Vector(loc.getX(), loc.getY(), loc.getZ()))) {
entities.add(new SpongeEntity(entity));
}
}
return entities;
}
@Override
public List<? extends Entity> getEntities() {
List<Entity> 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<org.spongepowered.api.entity.Entity> 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);
}
}
}

View File

@ -0,0 +1,267 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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<Player> 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<World> 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;
}
}

View File

@ -0,0 +1,81 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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<UUID> onlineIds = Collections.emptySet();
private long lastRefresh = 0;
/**
* Get an concurrent-safe set of UUIDs of online players.
*
* @return a set of UUIDs
*/
public Set<UUID> getOnlineIds() {
return onlineIds;
}
@SubscribeEvent
public void tickStart(TickEvent event) {
long now = System.currentTimeMillis();
if (now - lastRefresh > REFRESH_DELAY) {
Set<UUID> onlineIds = new HashSet<UUID>();
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<UUID>(onlineIds);
lastRefresh = now;
}
}
public static ThreadSafeCache getInstance() {
return INSTANCE;
}
}

View File

@ -0,0 +1,40 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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;
}
}

View File

@ -0,0 +1,146 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.sponge;
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<? extends TileEntity> 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<? extends TileEntity> clazz) {
Constructor<? extends TileEntity> 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;
}
}

View File

@ -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

View File

@ -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