Merge remote-tracking branch 'upstream/master' into breaking

This commit is contained in:
Jesse Boyd
2019-04-03 16:53:34 +11:00
281 changed files with 5963 additions and 5444 deletions

View File

@ -1,59 +1,76 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
maven { url = "http://files.minecraftforge.net/maven" }
maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" }
maven { url = "https://files.minecraftforge.net/maven" }
jcenter()
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
}
}
apply plugin: 'net.minecraftforge.gradle.forge'
apply plugin: 'net.minecraftforge.gradle'
def minecraftVersion = "1.13.2"
def forgeVersion = "25.0.76"
dependencies {
compile project(':worldedit-core')
compile 'org.spongepowered:spongeapi:6.0.0-SNAPSHOT'
compile 'org.apache.logging.log4j:log4j-slf4j-impl:2.11.2'
minecraft "net.minecraftforge:forge:${minecraftVersion}-${forgeVersion}"
testCompile group: 'org.mockito', name: 'mockito-core', version: '1.9.0-rc1'
}
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
maven {
name = "Sponge"
url = "https://repo.spongepowered.org/maven"
}
}
ext.forgeVersion = "14.22.0.2456"
minecraft {
version = "1.12.1-${project.forgeVersion}"
mappings = "snapshot_20170815"
runDir = 'run'
mappings channel: 'snapshot', version: '20190311-1.13.2'
replaceIn "com/sk89q/worldedit/forge/ForgeWorldEdit.java"
replace "%VERSION%", project.version
runs {
client = {
// recommended logging data for a userdev environment
properties 'forge.logging.markers': 'SCAN,REGISTRIES,REGISTRYDUMP'
// recommended logging level for the console
properties 'forge.logging.console.level': 'debug'
workingDirectory project.file('run').canonicalPath
source sourceSets.main
}
server = {
// recommended logging data for a userdev environment
properties 'forge.logging.markers': 'SCAN,REGISTRIES,REGISTRYDUMP'
// recommended logging level for the console
properties 'forge.logging.console.level': 'debug'
workingDirectory project.file('run').canonicalPath
source sourceSets.main
}
}
accessTransformer = file('worldedit_at.cfg')
}
project.archivesBaseName = "${project.archivesBaseName}-mc${minecraft.version}"
project.archivesBaseName = "${project.archivesBaseName}-mc${minecraftVersion}"
processResources {
from (sourceSets.main.resources.srcDirs) {
expand 'version': project.version,
'mcVersion': project.minecraft.version,
'forgeVersion': project.forgeVersion,
'internalVersion': project.internalVersion
include 'mcmod.info'
// this will ensure that this task is redone when the versions change.
inputs.property 'version', project.internalVersion
inputs.property 'forgeVersion', forgeVersion
// replace stuff in mcmod.info, nothing else
from(sourceSets.main.resources.srcDirs) {
include 'META-INF/mods.toml'
// replace version and mcversion
expand 'version': project.internalVersion, 'forgeVersion': forgeVersion
}
from (sourceSets.main.resources.srcDirs) {
exclude 'mcmod.info'
// copy everything else except the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'META-INF/mods.toml'
}
}
@ -67,13 +84,20 @@ jar {
shadowJar {
dependencies {
relocate "org.slf4j", "com.sk89q.worldedit.slf4j"
relocate "org.apache.logging.slf4j", "com.sk89q.worldedit.log4jbridge"
include(dependency(':worldedit-core'))
include(dependency('org.slf4j:slf4j-api'))
include(dependency("org.apache.logging.log4j:log4j-slf4j-impl"))
}
}
reobf {
shadowJar {
mappingType = 'SEARGE'
afterEvaluate {
reobf {
shadowJar {
mappings = createMcpToSrg.output
}
}
}

View File

@ -1,150 +0,0 @@
<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

@ -19,60 +19,50 @@
package com.sk89q.worldedit.forge;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.sk89q.worldedit.util.command.CommandMapping;
import net.minecraft.command.CommandBase;
import net.minecraft.command.CommandException;
import net.minecraft.command.ICommand;
import net.minecraft.command.ICommandSender;
import net.minecraft.server.MinecraftServer;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.player.EntityPlayerMP;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import javax.annotation.Nullable;
import static net.minecraft.command.Commands.literal;
public class CommandWrapper extends CommandBase {
private CommandMapping command;
protected CommandWrapper(CommandMapping command) {
this.command = command;
public final class CommandWrapper {
private CommandWrapper() {
}
@Override
public String getName() {
return command.getPrimaryAlias();
}
@Override
public List<String> getAliases() {
return Arrays.asList(command.getAllAliases());
}
@Override
public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException {
}
@Override
public String getUsage(ICommandSender icommandsender) {
return "/" + command.getPrimaryAlias() + " " + command.getDescription().getUsage();
}
@Override
public int getRequiredPermissionLevel() {
return 0;
}
@Override
public boolean checkPermission(MinecraftServer server, ICommandSender sender) {
return true;
}
@Override
public int compareTo(@Nullable ICommand o) {
if (o == null) {
return 0;
} else {
return super.compareTo(o);
public static void register(CommandDispatcher<CommandSource> dispatcher, CommandMapping command) {
for (String alias : command.getAllAliases()) {
LiteralArgumentBuilder<CommandSource> base = literal(alias)
.executes(FAKE_COMMAND);
if (command.getDescription().getPermissions().size() > 0) {
base.requires(requirementsFor(command));
}
dispatcher.register(base);
}
}
public static final Command<CommandSource> FAKE_COMMAND = ctx -> {
EntityPlayerMP player = ctx.getSource().asPlayer();
if (player.world.isRemote()) {
return 0;
}
return 1;
};
private static Predicate<CommandSource> requirementsFor(CommandMapping mapping) {
return ctx -> {
ForgePermissionsProvider permsProvider = ForgeWorldEdit.inst.getPermissionsProvider();
return ctx.getEntity() instanceof EntityPlayerMP &&
mapping.getDescription().getPermissions().stream()
.allMatch(perm -> permsProvider.hasPermission(
(EntityPlayerMP) ctx.getEntity(), perm
));
};
}
}

View File

@ -20,6 +20,8 @@
package com.sk89q.worldedit.forge;
import com.google.common.collect.ImmutableList;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.registry.state.BooleanProperty;
@ -29,19 +31,38 @@ import com.sk89q.worldedit.registry.state.IntegerProperty;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.world.World;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyBool;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.properties.PropertyInteger;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.biome.BiomeTypes;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.state.DirectionProperty;
import net.minecraft.state.IProperty;
import net.minecraft.state.StateContainer;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.biome.Biome;
import net.minecraftforge.registries.ForgeRegistries;
import java.util.Comparator;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Collectors;
final class ForgeAdapter {
import static com.google.common.base.Preconditions.checkNotNull;
public final class ForgeAdapter {
private ForgeAdapter() {
}
@ -50,6 +71,14 @@ final class ForgeAdapter {
return new ForgeWorld(world);
}
public static Biome adapt(BiomeType biomeType) {
return ForgeRegistries.BIOMES.getValue(new ResourceLocation(biomeType.getId()));
}
public static BiomeType adapt(Biome biome) {
return BiomeTypes.get(biome.getRegistryName().toString());
}
public static Vector3 adapt(Vec3d vector) {
return Vector3.at(vector.x, vector.y, vector.z);
}
@ -93,23 +122,110 @@ final class ForgeAdapter {
}
public static Property<?> adaptProperty(IProperty<?> property) {
if (property instanceof PropertyBool) {
return new BooleanProperty(property.getName(), ImmutableList.copyOf(((PropertyBool) property).getAllowedValues()));
if (property instanceof net.minecraft.state.BooleanProperty) {
return new BooleanProperty(property.getName(), ImmutableList.copyOf(((net.minecraft.state.BooleanProperty) property).getAllowedValues()));
}
if (property instanceof PropertyInteger) {
return new IntegerProperty(property.getName(), ImmutableList.copyOf(((PropertyInteger) property).getAllowedValues()));
if (property instanceof net.minecraft.state.IntegerProperty) {
return new IntegerProperty(property.getName(), ImmutableList.copyOf(((net.minecraft.state.IntegerProperty) property).getAllowedValues()));
}
if (property instanceof PropertyDirection) {
return new DirectionalProperty(property.getName(), ((PropertyDirection) property).getAllowedValues().stream()
if (property instanceof DirectionProperty) {
return new DirectionalProperty(property.getName(), ((DirectionProperty) property).getAllowedValues().stream()
.map(ForgeAdapter::adaptEnumFacing)
.collect(Collectors.toList()));
}
if (property instanceof PropertyEnum) {
return new EnumProperty(property.getName(), ((PropertyEnum<?>) property).getAllowedValues().stream()
.map(e -> e.getName())
if (property instanceof net.minecraft.state.EnumProperty) {
// Note: do not make x.getName a method reference.
// It will cause runtime bootstrap exceptions.
return new EnumProperty(property.getName(), ((net.minecraft.state.EnumProperty<?>) property).getAllowedValues().stream()
.map(x -> x.getName())
.collect(Collectors.toList()));
}
return new IPropertyAdapter<>(property);
}
public static Map<Property<?>, Object> adaptProperties(BlockType block, Map<IProperty<?>, Comparable<?>> mcProps) {
Map<Property<?>, Object> props = new TreeMap<>(Comparator.comparing(Property::getName));
for (Map.Entry<IProperty<?>, Comparable<?>> prop : mcProps.entrySet()) {
Object value = prop.getValue();
if (prop.getKey() instanceof DirectionProperty) {
value = adaptEnumFacing((EnumFacing) value);
} else if (prop.getKey() instanceof net.minecraft.state.EnumProperty) {
value = ((IStringSerializable) value).getName();
}
props.put(block.getProperty(prop.getKey().getName()), value);
}
return props;
}
private static IBlockState applyProperties(StateContainer<Block, IBlockState> stateContainer, IBlockState newState, Map<Property<?>, Object> states) {
for (Map.Entry<Property<?>, Object> state : states.entrySet()) {
IProperty property = stateContainer.getProperty(state.getKey().getName());
Comparable value = (Comparable) state.getValue();
// we may need to adapt this value, depending on the source prop
if (property instanceof DirectionProperty) {
Direction dir = (Direction) value;
value = ForgeAdapter.adapt(dir);
} else if (property instanceof net.minecraft.state.EnumProperty) {
String enumName = (String) value;
value = ((net.minecraft.state.EnumProperty<?>) property).parseValue((String) value).orElseGet(() -> {
throw new IllegalStateException("Enum property " + property.getName() + " does not contain " + enumName);
});
}
newState = newState.with(property, value);
}
return newState;
}
public static IBlockState adapt(BlockState blockState) {
Block mcBlock = ForgeAdapter.adapt(blockState.getBlockType());
IBlockState newState = mcBlock.getDefaultState();
Map<Property<?>, Object> states = blockState.getStates();
return applyProperties(mcBlock.getStateContainer(), newState, states);
}
public static BlockState adapt(IBlockState blockState) {
BlockType blockType = adapt(blockState.getBlock());
return blockType.getState(ForgeAdapter.adaptProperties(blockType, blockState.getValues()));
}
public static Block adapt(BlockType blockType) {
return ForgeRegistries.BLOCKS.getValue(new ResourceLocation(blockType.getId()));
}
public static BlockType adapt(Block block) {
return BlockTypes.get(ForgeRegistries.BLOCKS.getKey(block).toString());
}
public static Item adapt(ItemType itemType) {
return ForgeRegistries.ITEMS.getValue(new ResourceLocation(itemType.getId()));
}
public static ItemType adapt(Item item) {
return ItemTypes.get(ForgeRegistries.ITEMS.getKey(item).toString());
}
public static ItemStack adapt(BaseItemStack baseItemStack) {
NBTTagCompound forgeCompound = null;
if (baseItemStack.getNbtData() != null) {
forgeCompound = NBTConverter.toNative(baseItemStack.getNbtData());
}
return new ItemStack(adapt(baseItemStack.getType()), baseItemStack.getAmount(), forgeCompound);
}
public static BaseItemStack adapt(ItemStack itemStack) {
CompoundTag tag = NBTConverter.fromNative(itemStack.serializeNBT());
return new BaseItemStack(adapt(itemStack.getItem()), tag, itemStack.getCount());
}
/**
* Get the WorldEdit proxy for the given player.
*
* @param player the player
* @return the WorldEdit player
*/
public static ForgePlayer adaptPlayer(EntityPlayerMP player) {
checkNotNull(player);
return new ForgePlayer(player);
}
}

View File

@ -19,36 +19,19 @@
package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.biome.BiomeData;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import net.minecraft.world.biome.Biome;
import java.util.ArrayList;
import java.util.List;
/**
* Provides access to biome data in Forge.
*/
class ForgeBiomeRegistry implements BiomeRegistry {
@Override
public BaseBiome createFromId(int id) {
return new BaseBiome(id);
}
@Override
public List<BaseBiome> getBiomes() {
List<BaseBiome> list = new ArrayList<>();
for (Biome biome : Biome.REGISTRY) {
list.add(new BaseBiome(Biome.getIdForBiome(biome)));
}
return list;
}
@Override
public BiomeData getData(BaseBiome biome) {
return new ForgeBiomeData(Biome.getBiome(biome.getId()));
public BiomeData getData(BiomeType biome) {
return new ForgeBiomeData(ForgeAdapter.adapt(biome));
}
/**
@ -68,7 +51,7 @@ class ForgeBiomeRegistry implements BiomeRegistry {
@Override
public String getName() {
return biome.getBiomeName();
return biome.getDisplayName().getString();
}
}

View File

@ -63,12 +63,12 @@ public class ForgeBlockMaterial extends PassthroughBlockMaterial {
@Override
public boolean isFragileWhenPushed() {
return delegate.getMobilityFlag() == EnumPushReaction.DESTROY;
return delegate.getPushReaction() == EnumPushReaction.DESTROY;
}
@Override
public boolean isUnpushable() {
return delegate.getMobilityFlag() == EnumPushReaction.BLOCK;
return delegate.getPushReaction() == EnumPushReaction.BLOCK;
}
@Override
@ -78,7 +78,7 @@ public class ForgeBlockMaterial extends PassthroughBlockMaterial {
@Override
public boolean isBurnable() {
return delegate.getCanBurn();
return delegate.isFlammable();
}
@Override

View File

@ -23,11 +23,11 @@ import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import com.sk89q.worldedit.world.registry.BundledBlockRegistry;
import net.minecraft.block.Block;
import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty;
import net.minecraft.util.ResourceLocation;
import net.minecraft.state.IProperty;
import java.util.Collection;
import java.util.HashMap;
@ -43,21 +43,31 @@ public class ForgeBlockRegistry extends BundledBlockRegistry {
@Nullable
@Override
public String getName(BlockType blockType) {
return Block.REGISTRY.getObject(new ResourceLocation(blockType.getId())).getLocalizedName();
Block block = ForgeAdapter.adapt(blockType);
if (block != null) {
return block.getNameTextComponent().getFormattedText();
} else {
return super.getName(blockType);
}
}
@Override
public BlockMaterial getMaterial(BlockType blockType) {
return materialMap.computeIfAbsent(Block.getBlockFromName(blockType.getId()).getDefaultState().getMaterial(),
Block block = ForgeAdapter.adapt(blockType);
if (block == null) {
return super.getMaterial(blockType);
}
return materialMap.computeIfAbsent(block.getDefaultState().getMaterial(),
m -> new ForgeBlockMaterial(m, super.getMaterial(blockType)));
}
@Override
public Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
Block block = ForgeAdapter.adapt(blockType);
Map<String, Property<?>> map = new TreeMap<>();
Collection<IProperty<?>> propertyKeys = Block.getBlockFromName(blockType.getId())
Collection<IProperty<?>> propertyKeys = block
.getDefaultState()
.getPropertyKeys();
.getProperties();
for (IProperty<?> key : propertyKeys) {
map.put(key.getName(), ForgeAdapter.adaptProperty(key));
}

View File

@ -29,8 +29,8 @@ import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.NullWorld;
import com.sk89q.worldedit.world.entity.EntityTypes;
import net.minecraft.entity.EntityList;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation;
import java.lang.ref.WeakReference;
@ -49,11 +49,11 @@ class ForgeEntity implements Entity {
public BaseEntity getState() {
net.minecraft.entity.Entity entity = entityRef.get();
if (entity != null) {
String id = EntityList.getEntityString(entity);
ResourceLocation id = entity.getType().getRegistryName();
if (id != null) {
NBTTagCompound tag = new NBTTagCompound();
entity.writeToNBT(tag);
return new BaseEntity(EntityTypes.get(id), NBTConverter.fromNative(tag));
entity.writeWithoutTypeId(tag);
return new BaseEntity(EntityTypes.get(id.toString()), NBTConverter.fromNative(tag));
} else {
return null;
}
@ -96,7 +96,7 @@ class ForgeEntity implements Entity {
public boolean remove() {
net.minecraft.entity.Entity entity = entityRef.get();
if (entity != null) {
entity.setDead();
entity.remove();
}
return true;
}

View File

@ -136,7 +136,7 @@ public class ForgeEntityProperties implements EntityProperties {
@Override
public boolean isTagged() {
return entity instanceof EntityLiving && ((EntityLiving) entity).hasCustomName();
return entity.hasCustomName();
}
@Override

View File

@ -19,26 +19,11 @@
package com.sk89q.worldedit.forge;
<<<<<<< HEAD
import com.sk89q.worldedit.blocks.BaseItem;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.registry.ItemRegistry;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import javax.annotation.Nullable;
public class ForgeItemRegistry implements ItemRegistry {
@Nullable
@Override
public BaseItem createFromId(String id) {
Item match = Item.REGISTRY.getObject(new ResourceLocation(id));
if (match != null) {
return new BaseItem(ItemTypes.get(id));
} else {
return null;
}
=======
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.BundledItemRegistry;
@ -50,6 +35,5 @@ public class ForgeItemRegistry extends BundledItemRegistry {
@Override
public String getName(ItemType itemType) {
return super.getName(itemType); // TODO
>>>>>>> b75d5149... Fixed the bundle being directly used outside of the registry system.
}
}

View File

@ -19,17 +19,15 @@
package com.sk89q.worldedit.forge;
import net.minecraft.command.ICommand;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.world.GameType;
import net.minecraftforge.fml.common.FMLCommonHandler;
import org.spongepowered.api.entity.living.player.Player;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
public interface ForgePermissionsProvider {
boolean hasPermission(EntityPlayerMP player, String permission);
void registerPermission(ICommand command, String permission);
void registerPermission(String permission);
class VanillaPermissionsProvider implements ForgePermissionsProvider {
@ -43,24 +41,25 @@ public interface ForgePermissionsProvider {
public boolean hasPermission(EntityPlayerMP player, String permission) {
ForgeConfiguration configuration = platform.getConfiguration();
return configuration.cheatMode ||
FMLCommonHandler.instance().getMinecraftServerInstance().getPlayerList().canSendCommands(player.getGameProfile()) ||
ServerLifecycleHooks.getCurrentServer().getPlayerList().canSendCommands(player.getGameProfile()) ||
(configuration.creativeEnable && player.interactionManager.getGameType() == GameType.CREATIVE);
}
@Override
public void registerPermission(ICommand command, String permission) {}
public void registerPermission(String permission) {}
}
class SpongePermissionsProvider implements ForgePermissionsProvider {
@Override
public boolean hasPermission(EntityPlayerMP player, String permission) {
return ((Player) player).hasPermission(permission);
}
@Override
public void registerPermission(ICommand command, String permission) {
}
}
// TODO Re-add when Sponge for 1.13 is out
// class SpongePermissionsProvider implements ForgePermissionsProvider {
//
// @Override
// public boolean hasPermission(EntityPlayerMP player, String permission) {
// return ((Player) player).hasPermission(permission);
// }
//
// @Override
// public void registerPermission(ICommand command, String permission) {
//
// }
// }
}

View File

@ -29,24 +29,21 @@ import com.sk89q.worldedit.util.command.CommandMapping;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.registry.Registries;
import net.minecraft.command.ServerCommandManager;
import net.minecraft.entity.EntityList;
import net.minecraft.command.Commands;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.management.PlayerList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.WorldServer;
import net.minecraftforge.common.DimensionManager;
import net.minecraftforge.fml.common.FMLCommonHandler;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
private final ForgeWorldEdit mod;
@ -55,7 +52,7 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
ForgePlatform(ForgeWorldEdit mod) {
this.mod = mod;
this.server = FMLCommonHandler.instance().getMinecraftServerInstance();
this.server = ServerLifecycleHooks.getCurrentServer();
}
boolean isHookingEvents() {
@ -69,7 +66,7 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
@Override
public boolean isValidMobType(String type) {
return EntityList.isRegistered(new ResourceLocation(type));
return net.minecraftforge.registries.ForgeRegistries.ENTITIES.containsKey(new ResourceLocation(type));
}
@Override
@ -84,8 +81,8 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
@Override
public List<? extends com.sk89q.worldedit.world.World> getWorlds() {
WorldServer[] worlds = DimensionManager.getWorlds();
List<com.sk89q.worldedit.world.World> ret = new ArrayList<>(worlds.length);
Iterable<WorldServer> worlds = server.getWorlds();
List<com.sk89q.worldedit.world.World> ret = new ArrayList<>();
for (WorldServer world : worlds) {
ret.add(new ForgeWorld(world));
}
@ -109,7 +106,7 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
if (world instanceof ForgeWorld) {
return world;
} else {
for (WorldServer ws : DimensionManager.getWorlds()) {
for (WorldServer ws : server.getWorlds()) {
if (ws.getWorldInfo().getWorldName().equals(world.getName())) {
return new ForgeWorld(ws);
}
@ -122,15 +119,13 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
@Override
public void registerCommands(Dispatcher dispatcher) {
if (server == null) return;
ServerCommandManager mcMan = (ServerCommandManager) server.getCommandManager();
Commands mcMan = server.getCommandManager();
for (final CommandMapping command : dispatcher.getCommands()) {
CommandWrapper wrapper = new CommandWrapper(command);
mcMan.registerCommand(wrapper);
CommandWrapper.register(mcMan.getDispatcher(), command);
if (command.getDescription().getPermissions().size() > 0) {
ForgeWorldEdit.inst.getPermissionsProvider().registerPermission(wrapper, command.getDescription().getPermissions().get(0));
for (int i = 1; i < command.getDescription().getPermissions().size(); i++) {
ForgeWorldEdit.inst.getPermissionsProvider().registerPermission(null, command.getDescription().getPermissions().get(i));
ForgeWorldEdit.inst.getPermissionsProvider().registerPermission(command.getDescription().getPermissions().get(i));
}
}
}

View File

@ -24,23 +24,25 @@ import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extension.platform.AbstractPlayerActor;
import com.sk89q.worldedit.extent.inventory.BlockBag;
import com.sk89q.worldedit.forge.net.handler.WECUIPacketHandler;
import com.sk89q.worldedit.internal.cui.CUIEvent;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.session.SessionKey;
import com.sk89q.worldedit.util.HandSide;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.play.server.SPacketCustomPayload;
import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
import java.util.UUID;
@ -65,12 +67,12 @@ public class ForgePlayer extends AbstractPlayerActor {
@Override
public BaseItemStack getItemInHand(HandSide handSide) {
ItemStack is = this.player.getHeldItem(handSide == HandSide.MAIN_HAND ? EnumHand.MAIN_HAND : EnumHand.OFF_HAND);
return new BaseItemStack(ItemTypes.get(ForgeRegistries.ITEMS.getKey(is.getItem()).toString()));
return ForgeAdapter.adapt(is);
}
@Override
public String getName() {
return this.player.getName();
return this.player.getName().getFormattedText();
}
@Override
@ -101,8 +103,7 @@ public class ForgePlayer extends AbstractPlayerActor {
@Override
public void giveItem(BaseItemStack itemStack) {
this.player.inventory.addItemStackToInventory(
new ItemStack(Item.getByNameOrId(itemStack.getType().getId()), itemStack.getAmount(), 0));
this.player.inventory.addItemStackToInventory(ForgeAdapter.adapt(itemStack));
}
@Override
@ -113,7 +114,7 @@ public class ForgePlayer extends AbstractPlayerActor {
send = send + "|" + StringUtil.joinString(params, "|");
}
PacketBuffer buffer = new PacketBuffer(Unpooled.copiedBuffer(send.getBytes(WECUIPacketHandler.UTF_8_CHARSET)));
SPacketCustomPayload packet = new SPacketCustomPayload(ForgeWorldEdit.CUI_PLUGIN_CHANNEL, buffer);
SPacketCustomPayload packet = new SPacketCustomPayload(new ResourceLocation(ForgeWorldEdit.CUI_PLUGIN_CHANNEL), buffer);
this.player.connection.sendPacket(packet);
}
@ -174,13 +175,7 @@ public class ForgePlayer extends AbstractPlayerActor {
}
@Override
<<<<<<< HEAD
<<<<<<< HEAD
=======
public void sendFakeBlock(BlockVector3 pos, BlockStateHolder block) {
=======
public <B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, B block) {
>>>>>>> 3fefcbf9... Remove all raw usages of BSH, improve API generics
BlockPos loc = ForgeAdapter.toBlockPos(pos);
if (block == null) {
// TODO
@ -198,9 +193,8 @@ public class ForgePlayer extends AbstractPlayerActor {
}
@Override
>>>>>>> 399e0ad5... Refactor vector system to be cleaner
public SessionKey getSessionKey() {
return new SessionKeyImpl(player.getUniqueID(), player.getName());
return new SessionKeyImpl(player.getUniqueID(), player.getName().getString());
}
private static class SessionKeyImpl implements SessionKey {

View File

@ -21,93 +21,70 @@ package com.sk89q.worldedit.forge;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.io.Files;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.BlockVector;
import com.sk89q.worldedit.BlockVector2D;
import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.WorldEditException;
import com.sk89q.worldedit.blocks.BaseItem;
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.CuboidRegion;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TreeGenerator.TreeType;
import com.sk89q.worldedit.world.AbstractWorld;
import com.sk89q.worldedit.world.biome.BaseBiome;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.item.ItemTypes;
import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldedit.world.weather.WeatherTypes;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLeaves;
import net.minecraft.block.BlockOldLeaf;
import net.minecraft.block.BlockOldLog;
import net.minecraft.block.BlockPlanks;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.properties.PropertyDirection;
import net.minecraft.block.properties.PropertyEnum;
import net.minecraft.block.state.BlockStateContainer;
import net.minecraft.block.state.IBlockState;
import net.minecraft.entity.EntityList;
import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.init.Blocks;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.EnumHand;
import net.minecraft.util.IStringSerializable;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunkProvider;
import net.minecraft.world.chunk.storage.AnvilSaveHandler;
import net.minecraft.world.gen.ChunkProviderServer;
import net.minecraft.world.gen.feature.WorldGenBigMushroom;
import net.minecraft.world.gen.feature.WorldGenBigTree;
import net.minecraft.world.gen.feature.WorldGenBirchTree;
import net.minecraft.world.gen.feature.WorldGenCanopyTree;
import net.minecraft.world.gen.feature.WorldGenMegaJungle;
import net.minecraft.world.gen.feature.WorldGenMegaPineTree;
import net.minecraft.world.gen.feature.WorldGenSavannaTree;
import net.minecraft.world.gen.feature.WorldGenShrub;
import net.minecraft.world.gen.feature.WorldGenSwamp;
import net.minecraft.world.gen.feature.WorldGenTaiga1;
import net.minecraft.world.gen.feature.WorldGenTaiga2;
import net.minecraft.world.gen.feature.WorldGenTrees;
import net.minecraft.world.gen.feature.WorldGenerator;
import net.minecraft.world.gen.feature.BigBrownMushroomFeature;
import net.minecraft.world.gen.feature.BigRedMushroomFeature;
import net.minecraft.world.gen.feature.BigTreeFeature;
import net.minecraft.world.gen.feature.BirchTreeFeature;
import net.minecraft.world.gen.feature.CanopyTreeFeature;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.JungleTreeFeature;
import net.minecraft.world.gen.feature.MegaJungleFeature;
import net.minecraft.world.gen.feature.MegaPineTree;
import net.minecraft.world.gen.feature.NoFeatureConfig;
import net.minecraft.world.gen.feature.PointyTaigaTreeFeature;
import net.minecraft.world.gen.feature.SavannaTreeFeature;
import net.minecraft.world.gen.feature.ShrubFeature;
import net.minecraft.world.gen.feature.SwampTreeFeature;
import net.minecraft.world.gen.feature.TallTaigaTreeFeature;
import net.minecraft.world.gen.feature.TreeFeature;
import net.minecraft.world.storage.WorldInfo;
import net.minecraftforge.common.DimensionManager;
import java.io.File;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.TreeMap;
import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.Nullable;
@ -119,9 +96,9 @@ public class ForgeWorld extends AbstractWorld {
private static final Random random = new Random();
private static final int UPDATE = 1, NOTIFY = 2;
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));
private static final IBlockState JUNGLE_LOG = Blocks.JUNGLE_LOG.getDefaultState();
private static final IBlockState JUNGLE_LEAF = Blocks.JUNGLE_LEAVES.getDefaultState().with(BlockLeaves.PERSISTENT, Boolean.TRUE);
private static final IBlockState JUNGLE_SHRUB = Blocks.OAK_LEAVES.getDefaultState().with(BlockLeaves.PERSISTENT, Boolean.TRUE);
private final WeakReference<World> worldRef;
@ -181,32 +158,27 @@ public class ForgeWorld extends AbstractWorld {
int z = position.getBlockZ();
// First set the block
Chunk chunk = world.getChunkFromChunkCoords(x >> 4, z >> 4);
Chunk chunk = world.getChunk(x >> 4, z >> 4);
BlockPos pos = new BlockPos(x, y, z);
IBlockState old = chunk.getBlockState(pos);
Block mcBlock = Block.getBlockFromName(block.getBlockType().getId());
IBlockState newState = mcBlock.getDefaultState();
Map<Property<?>, Object> states = block.getStates();
newState = applyProperties(mcBlock.getBlockState(), newState, states);
IBlockState successState = chunk.setBlockState(pos, newState);
IBlockState newState = ForgeAdapter.adapt(block.toImmutableState());
IBlockState successState = chunk.setBlockState(pos, newState, false);
boolean successful = successState != null;
// Create the TileEntity
if (successful) {
if (block instanceof BaseBlock && ((BaseBlock) block).hasNbtData()) {
// Kill the old TileEntity
world.removeTileEntity(pos);
NBTTagCompound nativeTag = NBTConverter.toNative(((BaseBlock) block).getNbtData());
nativeTag.setString("id", ((BaseBlock) block).getNbtId());
TileEntityUtils.setTileEntity(world, position, nativeTag);
if (successful || old == newState) {
if (block instanceof BaseBlock) {
CompoundTag tag = ((BaseBlock) block).getNbtData();
if (tag != null) {
NBTTagCompound nativeTag = NBTConverter.toNative(tag);
nativeTag.putString("id", ((BaseBlock) block).getNbtId());
TileEntityUtils.setTileEntity(world, position, nativeTag);
}
}
}
if (notifyAndLight) {
if (!successful) {
newState = old;
}
world.checkLight(pos);
if (successful && notifyAndLight) {
//world.checkLight(pos);
world.markAndNotifyBlock(pos, chunk, old, newState, UPDATE | NOTIFY);
}
@ -215,43 +187,21 @@ public class ForgeWorld extends AbstractWorld {
@Override
public boolean notifyAndLightBlock(BlockVector3 position, BlockState previousType) throws WorldEditException {
// TODO Implement
return false;
}
// Can't get the "Object" to be right for withProperty w/o this
@SuppressWarnings({ "rawtypes", "unchecked" })
private IBlockState applyProperties(BlockStateContainer stateContainer, IBlockState newState, Map<Property<?>, Object> states) {
for (Map.Entry<Property<?>, Object> state : states.entrySet()) {
IProperty property = stateContainer.getProperty(state.getKey().getName());
Comparable value = (Comparable) state.getValue();
// we may need to adapt this value, depending on the source prop
if (property instanceof PropertyDirection) {
Direction dir = (Direction) value;
value = ForgeAdapter.adapt(dir);
} else if (property instanceof PropertyEnum) {
String enumName = (String) value;
value = ((PropertyEnum<?>) property).parseValue((String) value).or(() -> {
throw new IllegalStateException("Enum property " + property.getName() + " does not contain " + enumName);
});
}
newState = newState.withProperty(property, value);
}
return newState;
BlockPos pos = new BlockPos(position.getX(), position.getY(), position.getZ());
getWorld().notifyBlockUpdate(pos, ForgeAdapter.adapt(previousType), getWorld().getBlockState(pos), 1 | 2);
return true;
}
@Override
public int getBlockLightLevel(BlockVector3 position) {
checkNotNull(position);
return getWorld().getLight(new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()));
return getWorld().getLight(ForgeAdapter.toBlockPos(position));
}
@Override
public boolean clearContainerBlockContents(BlockVector3 position) {
checkNotNull(position);
TileEntity tile = getWorld().getTileEntity(new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()));
TileEntity tile = getWorld().getTileEntity(ForgeAdapter.toBlockPos(position));
if ((tile instanceof IInventory)) {
IInventory inv = (IInventory) tile;
int size = inv.getSizeInventory();
@ -264,19 +214,19 @@ public class ForgeWorld extends AbstractWorld {
}
@Override
public BaseBiome getBiome(BlockVector2 position) {
public BiomeType getBiome(BlockVector2 position) {
checkNotNull(position);
return new BaseBiome(Biome.getIdForBiome(getWorld().getBiomeForCoordsBody(new BlockPos(position.getBlockX(), 0, position.getBlockZ()))));
return ForgeAdapter.adapt(getWorld().getBiomeBody(new BlockPos(position.getBlockX(), 0, position.getBlockZ())));
}
@Override
public boolean setBiome(BlockVector2 position, BaseBiome biome) {
public boolean setBiome(BlockVector2 position, BiomeType biome) {
checkNotNull(position);
checkNotNull(biome);
Chunk chunk = getWorld().getChunkFromBlockCoords(new BlockPos(position.getBlockX(), 0, position.getBlockZ()));
Chunk chunk = getWorld().getChunk(new BlockPos(position.getBlockX(), 0, position.getBlockZ()));
if (chunk.isLoaded()) {
chunk.getBiomeArray()[((position.getBlockZ() & 0xF) << 4 | position.getBlockX() & 0xF)] = (byte) biome.getId();
chunk.getBiomes()[((position.getBlockZ() & 0xF) << 4 | position.getBlockX() & 0xF)] = ForgeAdapter.adapt(biome);
return true;
}
@ -285,16 +235,24 @@ public class ForgeWorld extends AbstractWorld {
@Override
public boolean useItem(BlockVector3 position, BaseItem item, Direction face) {
Item nativeItem = Item.getByNameOrId(item.getType().getId());
ItemStack stack = null;
Item nativeItem = ForgeAdapter.adapt(item.getType());
ItemStack stack;
if (item.getNbtData() == null) {
stack = new ItemStack(nativeItem, 1, 0);
stack = new ItemStack(nativeItem, 1);
} else {
stack = new ItemStack(nativeItem, 1, 0, NBTConverter.toNative(item.getNbtData()));
stack = new ItemStack(nativeItem, 1, NBTConverter.toNative(item.getNbtData()));
}
World world = getWorld();
EnumActionResult used = stack.onItemUse(new WorldEditFakePlayer((WorldServer) world), world, ForgeAdapter.toBlockPos(position),
EnumHand.MAIN_HAND, ForgeAdapter.adapt(face), 0, 0, 0);
ItemUseContext itemUseContext = new ItemUseContext(
new WorldEditFakePlayer((WorldServer) world),
stack,
ForgeAdapter.toBlockPos(position),
ForgeAdapter.adapt(face),
0f,
0f,
0f
);
EnumActionResult used = stack.onItemUse(itemUseContext);
return used != EnumActionResult.FAIL;
}
@ -307,7 +265,7 @@ public class ForgeWorld extends AbstractWorld {
return;
}
EntityItem entity = new EntityItem(getWorld(), position.getX(), position.getY(), position.getZ(), ForgeWorldEdit.toForgeItemStack(item));
EntityItem entity = new EntityItem(getWorld(), position.getX(), position.getY(), position.getZ(), ForgeAdapter.adapt(item));
entity.setPickupDelay(10);
getWorld().spawnEntity(entity);
}
@ -316,75 +274,75 @@ public class ForgeWorld extends AbstractWorld {
public void simulateBlockMine(BlockVector3 position) {
BlockPos pos = ForgeAdapter.toBlockPos(position);
IBlockState state = getWorld().getBlockState(pos);
state.getBlock().dropBlockAsItem(getWorld(), pos, state, 0);
getWorld().setBlockToAir(pos);
state.dropBlockAsItem(getWorld(), pos, 0);
getWorld().removeBlock(pos);
}
@Override
public boolean regenerate(Region region, EditSession editSession) {
// Don't even try to regen if it's going to fail.
IChunkProvider provider = getWorld().getChunkProvider();
if (!(provider instanceof ChunkProviderServer)) {
return false;
}
File saveFolder = Files.createTempDir();
// register this just in case something goes wrong
// normally it should be deleted at the end of this method
saveFolder.deleteOnExit();
WorldServer originalWorld = (WorldServer) getWorld();
MinecraftServer server = originalWorld.getMinecraftServer();
AnvilSaveHandler saveHandler = new AnvilSaveHandler(saveFolder,
originalWorld.getSaveHandler().getWorldDirectory().getName(), true, server.getDataFixer());
World freshWorld = new WorldServer(server, saveHandler, originalWorld.getWorldInfo(),
originalWorld.provider.getDimension(), originalWorld.profiler).init();
// Pre-gen all the chunks
// We need to also pull one more chunk in every direction
CuboidRegion expandedPreGen = new CuboidRegion(region.getMinimumPoint().subtract(16, 0, 16), region.getMaximumPoint().add(16, 0, 16));
for (BlockVector2 chunk : expandedPreGen.getChunks()) {
freshWorld.getChunkFromChunkCoords(chunk.getBlockX(), chunk.getBlockZ());
}
ForgeWorld from = new ForgeWorld(freshWorld);
try {
for (BlockVector3 vec : region) {
editSession.setBlock(vec, from.getFullBlock(vec));
}
} catch (MaxChangedBlocksException e) {
throw new RuntimeException(e);
} finally {
saveFolder.delete();
DimensionManager.setWorld(originalWorld.provider.getDimension(), null, server);
DimensionManager.setWorld(originalWorld.provider.getDimension(), originalWorld, server);
}
return true;
// TODO Fix for 1.13
return false;
// // Don't even try to regen if it's going to fail.
// IChunkProvider provider = getWorld().getChunkProvider();
// if (!(provider instanceof ChunkProviderServer)) {
// return false;
// }
//
// File saveFolder = Files.createTempDir();
// // register this just in case something goes wrong
// // normally it should be deleted at the end of this method
// saveFolder.deleteOnExit();
//
// WorldServer originalWorld = (WorldServer) getWorld();
//
// MinecraftServer server = originalWorld.getServer();
// AnvilSaveHandler saveHandler = new AnvilSaveHandler(saveFolder, originalWorld.getSaveHandler().getWorldDirectory().getName(), server, server.getDataFixer());
// World freshWorld = new WorldServer(server, saveHandler, originalWorld.getSavedDataStorage(), originalWorld.getWorldInfo(), originalWorld.dimension.getType(), originalWorld.profiler).func_212251_i__();
//
// // Pre-gen all the chunks
// // We need to also pull one more chunk in every direction
// CuboidRegion expandedPreGen = new CuboidRegion(region.getMinimumPoint().subtract(16, 0, 16), region.getMaximumPoint().add(16, 0, 16));
// for (BlockVector2 chunk : expandedPreGen.getChunks()) {
// freshWorld.getChunk(chunk.getBlockX(), chunk.getBlockZ());
// }
//
// ForgeWorld from = new ForgeWorld(freshWorld);
// try {
// for (BlockVector3 vec : region) {
// editSession.setBlock(vec, from.getFullBlock(vec));
// }
// } catch (MaxChangedBlocksException e) {
// throw new RuntimeException(e);
// } finally {
// saveFolder.delete();
// DimensionManager.setWorld(originalWorld.dimension.getType(), null, server);
// DimensionManager.setWorld(originalWorld.dimension.getType(), originalWorld, server);
// }
//
// return true;
}
@Nullable
private static WorldGenerator createWorldGenerator(TreeType type) {
private static Feature<NoFeatureConfig> createTreeFeatureGenerator(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 WorldGenBirchTree(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 WorldGenBirchTree(true, true);
case RANDOM:
case TREE: return new TreeFeature(true);
case BIG_TREE: return new BigTreeFeature(true);
case PINE:
case REDWOOD: return new PointyTaigaTreeFeature();
case TALL_REDWOOD: return new TallTaigaTreeFeature(true);
case BIRCH: return new BirchTreeFeature(true, false);
case JUNGLE: return new MegaJungleFeature(true, 10, 20, JUNGLE_LOG, JUNGLE_LEAF);
case SMALL_JUNGLE: return new JungleTreeFeature(true, 4 + random.nextInt(7), JUNGLE_LOG, JUNGLE_LEAF, false);
case SHORT_JUNGLE: return new JungleTreeFeature(true, 4 + random.nextInt(7), JUNGLE_LOG, JUNGLE_LEAF, true);
case JUNGLE_BUSH: return new ShrubFeature(JUNGLE_LOG, JUNGLE_SHRUB);
case RED_MUSHROOM: return new BigBrownMushroomFeature();
case BROWN_MUSHROOM: return new BigRedMushroomFeature();
case SWAMP: return new SwampTreeFeature();
case ACACIA: return new SavannaTreeFeature(true);
case DARK_OAK: return new CanopyTreeFeature(true);
case MEGA_REDWOOD: return new MegaPineTree(false, random.nextBoolean());
case TALL_BIRCH: return new BirchTreeFeature(true, true);
case RANDOM: return createTreeFeatureGenerator(TreeType.values()[ThreadLocalRandom.current().nextInt(TreeType.values().length)]);
case RANDOM_REDWOOD:
default:
return null;
@ -393,13 +351,13 @@ public class ForgeWorld extends AbstractWorld {
@Override
public boolean generateTree(TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException {
WorldGenerator generator = createWorldGenerator(type);
return generator != null && generator.generate(getWorld(), random, ForgeAdapter.toBlockPos(position));
Feature<NoFeatureConfig> generator = createTreeFeatureGenerator(type);
return generator != null && generator.place(getWorld(), getWorld().getChunkProvider().getChunkGenerator(), random, ForgeAdapter.toBlockPos(position), new NoFeatureConfig());
}
@Override
public void checkLoadedChunk(BlockVector3 pt) {
getWorld().getChunkFromBlockCoords(ForgeAdapter.toBlockPos(pt));
getWorld().getChunk(ForgeAdapter.toBlockPos(pt));
}
@Override
@ -411,7 +369,7 @@ public class ForgeWorld extends AbstractWorld {
public void fixLighting(Iterable<BlockVector2> chunks) {
World world = getWorld();
for (BlockVector2 chunk : chunks) {
world.getChunkFromChunkCoords(chunk.getBlockX(), chunk.getBlockZ()).resetRelightChecks();
world.getChunk(chunk.getBlockX(), chunk.getBlockZ()).resetRelightChecks();
}
}
@ -442,7 +400,7 @@ public class ForgeWorld extends AbstractWorld {
if (info.isRaining()) {
return info.getRainTime();
}
return info.getCleanWeatherTime();
return info.getClearWeatherTime();
}
@Override
@ -453,18 +411,18 @@ public class ForgeWorld extends AbstractWorld {
@Override
public void setWeather(WeatherType weatherType, long duration) {
WorldInfo info = getWorld().getWorldInfo();
if (WeatherTypes.THUNDER_STORM.equals(weatherType)) {
info.setCleanWeatherTime(0);
if (weatherType == WeatherTypes.THUNDER_STORM) {
info.setClearWeatherTime(0);
info.setThundering(true);
info.setThunderTime((int) duration);
} else if (WeatherTypes.RAIN.equals(weatherType)) {
info.setCleanWeatherTime(0);
} else if (weatherType == WeatherTypes.RAIN) {
info.setClearWeatherTime(0);
info.setRaining(true);
info.setRainTime((int) duration);
} else if (WeatherTypes.CLEAR.equals(weatherType)) {
} else if (weatherType == WeatherTypes.CLEAR) {
info.setRaining(false);
info.setThundering(false);
info.setCleanWeatherTime((int) duration);
info.setClearWeatherTime((int) duration);
}
}
@ -475,26 +433,13 @@ public class ForgeWorld extends AbstractWorld {
@Override
public BlockState getBlock(BlockVector3 position) {
World world = getWorld();
BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ());
IBlockState mcState = world.getBlockState(pos);
IBlockState mcState = getWorld().getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).getBlockState(
position.getBlockX(),
position.getBlockY(),
position.getBlockZ()
);
BlockType blockType = BlockType.REGISTRY.get(Block.REGISTRY.getNameForObject(mcState.getBlock()).toString());
return blockType.getState(adaptProperties(blockType, mcState.getProperties()));
}
private Map<Property<?>, Object> adaptProperties(BlockType block, Map<IProperty<?>, Comparable<?>> mcProps) {
Map<Property<?>, Object> props = new TreeMap<>(Comparator.comparing(Property::getName));
for (Map.Entry<IProperty<?>, Comparable<?>> prop : mcProps.entrySet()) {
Object value = prop.getValue();
if (prop.getKey() instanceof PropertyDirection) {
value = ForgeAdapter.adaptEnumFacing((EnumFacing) value);
} else if (prop.getKey() instanceof PropertyEnum) {
value = ((IStringSerializable) value).getName();
}
props.put(block.getProperty(prop.getKey().getName()), value);
}
return props;
return ForgeAdapter.adapt(mcState);
}
@Override
@ -554,15 +499,15 @@ public class ForgeWorld extends AbstractWorld {
@Override
public Entity createEntity(Location location, BaseEntity entity) {
World world = getWorld();
net.minecraft.entity.Entity createdEntity = EntityList.createEntityByIDFromName(new ResourceLocation(entity.getType().getId()), world);
net.minecraft.entity.Entity createdEntity = EntityType.create(world, new ResourceLocation(entity.getType().getId()));
if (createdEntity != null) {
CompoundTag nativeTag = entity.getNbtData();
if (nativeTag != null) {
NBTTagCompound tag = NBTConverter.toNative(entity.getNbtData());
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
tag.removeTag(name);
tag.remove(name);
}
createdEntity.readFromNBT(tag);
createdEntity.read(tag);
}
createdEntity.setLocationAndAngles(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());

View File

@ -20,150 +20,201 @@
package com.sk89q.worldedit.forge;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.forge.ForgeAdapter.adaptPlayer;
import com.google.common.base.Joiner;
import com.mojang.brigadier.ParseResults;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
import com.sk89q.worldedit.extension.platform.Platform;
import com.sk89q.worldedit.forge.net.LeftClickAirEventMessage;
import com.sk89q.worldedit.forge.net.handler.InternalPacketHandler;
import com.sk89q.worldedit.forge.net.handler.WECUIPacketHandler;
import com.sk89q.worldedit.forge.net.packet.LeftClickAirEventMessage;
import com.sk89q.worldedit.forge.proxy.ClientProxy;
import com.sk89q.worldedit.forge.proxy.CommonProxy;
import com.sk89q.worldedit.forge.proxy.ServerProxy;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockCategory;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.block.BlockTypes;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.item.ItemCategory;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.ItemTags;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.CommandEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickEmpty;
import net.minecraftforge.fml.common.Loader;
import net.minecraftforge.eventbus.api.Event;
import net.minecraftforge.eventbus.api.IEventBus;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.DistExecutor;
import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
import net.minecraftforge.fml.common.Mod.EventHandler;
import net.minecraftforge.fml.common.Mod.Instance;
import net.minecraftforge.fml.common.SidedProxy;
import net.minecraftforge.fml.common.event.FMLInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent;
import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent;
import net.minecraftforge.fml.common.event.FMLServerStartedEvent;
import net.minecraftforge.fml.common.event.FMLServerStoppingEvent;
import net.minecraftforge.fml.common.eventhandler.Event.Result;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent;
import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent;
import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fml.loading.FMLPaths;
import net.minecraftforge.registries.ForgeRegistries;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
/**
* The Forge implementation of WorldEdit.
*/
@Mod(modid = ForgeWorldEdit.MOD_ID, name = "WorldEdit", version = "%VERSION%", acceptableRemoteVersions = "*")
@Mod(ForgeWorldEdit.MOD_ID)
public class ForgeWorldEdit {
public static Logger logger;
private static final Logger LOGGER = LogManager.getLogger();
public static final String MOD_ID = "worldedit";
public static final String CUI_PLUGIN_CHANNEL = "worldedit:cui";
public static final String CUI_PLUGIN_CHANNEL = "cui";
private ForgePermissionsProvider provider;
@Instance(MOD_ID)
public static ForgeWorldEdit inst;
@SidedProxy(serverSide = "com.sk89q.worldedit.forge.CommonProxy", clientSide = "com.sk89q.worldedit.forge.ClientProxy")
public static CommonProxy proxy;
public static CommonProxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> ServerProxy::new);
private ForgePlatform platform;
private ForgeConfiguration config;
private File workingDir;
private Path workingDir;
@EventHandler
public void preInit(FMLPreInitializationEvent event) {
logger = event.getModLog();
// Setup working directory
workingDir = new File(event.getModConfigurationDirectory() + File.separator + "worldedit");
workingDir.mkdir();
private ModContainer container;
config = new ForgeConfiguration(this);
config.load();
public ForgeWorldEdit() {
inst = this;
IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus();
modBus.addListener(this::init);
modBus.addListener(this::load);
MinecraftForge.EVENT_BUS.register(ThreadSafeCache.getInstance());
MinecraftForge.EVENT_BUS.register(this);
}
@EventHandler
public void init(FMLInitializationEvent event) {
MinecraftForge.EVENT_BUS.register(this);
private void init(FMLCommonSetupEvent event) {
this.container = ModLoadingContext.get().getActiveContainer();
// Setup working directory
workingDir = FMLPaths.CONFIGDIR.get().resolve("worldedit");
if (!Files.exists(workingDir)) {
try {
Files.createDirectory(workingDir);
} catch (IOException e) {
throw new UncheckedIOException(e);
}
}
WECUIPacketHandler.init();
InternalPacketHandler.init();
proxy.registerHandlers();
LOGGER.info("WorldEdit for Forge (version " + getInternalVersion() + ") is loaded");
}
@EventHandler
public void postInit(FMLPostInitializationEvent event) {
logger.info("WorldEdit for Forge (version " + getInternalVersion() + ") is loaded");
private void load(FMLLoadCompleteEvent event) {
if (FMLLoader.getDist() == Dist.CLIENT) {
// we want to setup platform before we hit the main menu
// but this event is async -- so we must delay until the first game loop:
Minecraft.getInstance().addScheduledTask(this::setupPlatform);
}
}
@EventHandler
@SubscribeEvent
public void serverAboutToStart(FMLServerAboutToStartEvent event) {
if (this.platform != null) {
logger.warn("FMLServerStartingEvent occurred when FMLServerStoppingEvent hasn't");
LOGGER.warn("FMLServerStartingEvent occurred when FMLServerStoppingEvent hasn't");
WorldEdit.getInstance().getPlatformManager().unregister(platform);
}
setupPlatform();
}
private void setupPlatform() {
this.platform = new ForgePlatform(this);
WorldEdit.getInstance().getPlatformManager().register(platform);
if (Loader.isModLoaded("sponge")) {
this.provider = new ForgePermissionsProvider.SpongePermissionsProvider();
} else {
this.provider = new ForgePermissionsProvider.VanillaPermissionsProvider(platform);
}
// TODO if (ModList.get().isLoaded("sponge")) {
// this.provider = new ForgePermissionsProvider.SpongePermissionsProvider();
// } else {
this.provider = new ForgePermissionsProvider.VanillaPermissionsProvider(platform);
// }
for (ResourceLocation name : Block.REGISTRY.getKeys()) {
String nameStr = name.toString();
if (!BlockType.REGISTRY.keySet().contains(nameStr)) {
BlockTypes.register(new BlockType(nameStr));
setupRegistries();
config = new ForgeConfiguration(this);
config.load();
}
private void setupRegistries() {
// Blocks
for (ResourceLocation name : ForgeRegistries.BLOCKS.getKeys()) {
if (BlockType.REGISTRY.get(name.toString()) == null) {
BlockType.REGISTRY.register(name.toString(), new BlockType(name.toString(),
input -> ForgeAdapter.adapt(ForgeAdapter.adapt(input.getBlockType()).getDefaultState())));
}
}
for (ResourceLocation name : Item.REGISTRY.getKeys()) {
String nameStr = name.toString();
if (!ItemType.REGISTRY.keySet().contains(nameStr)) {
ItemTypes.register(new ItemType(nameStr));
// Items
for (ResourceLocation name : ForgeRegistries.ITEMS.getKeys()) {
if (ItemType.REGISTRY.get(name.toString()) == null) {
ItemType.REGISTRY.register(name.toString(), new ItemType(name.toString()));
}
}
// Entities
for (ResourceLocation name : ForgeRegistries.ENTITIES.getKeys()) {
if (EntityType.REGISTRY.get(name.toString()) == null) {
EntityType.REGISTRY.register(name.toString(), new EntityType(name.toString()));
}
}
// Biomes
for (ResourceLocation name : ForgeRegistries.BIOMES.getKeys()) {
if (BiomeType.REGISTRY.get(name.toString()) == null) {
BiomeType.REGISTRY.register(name.toString(), new BiomeType(name.toString()));
}
}
// Tags
for (ResourceLocation name : BlockTags.getCollection().getRegisteredTags()) {
if (BlockCategory.REGISTRY.get(name.toString()) == null) {
BlockCategory.REGISTRY.register(name.toString(), new BlockCategory(name.toString()));
}
}
for (ResourceLocation name : ItemTags.getCollection().getRegisteredTags()) {
if (ItemCategory.REGISTRY.get(name.toString()) == null) {
ItemCategory.REGISTRY.register(name.toString(), new ItemCategory(name.toString()));
}
}
}
@EventHandler
@SubscribeEvent
public void serverStopping(FMLServerStoppingEvent event) {
WorldEdit.getInstance().getPlatformManager().unregister(platform);
}
@EventHandler
@SubscribeEvent
public void serverStarted(FMLServerStartedEvent event) {
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
}
@SubscribeEvent
public void onCommandEvent(CommandEvent event) {
if ((event.getSender() instanceof EntityPlayerMP)) {
if (((EntityPlayerMP) event.getSender()).world.isRemote) return;
String[] split = new String[event.getParameters().length + 1];
System.arraycopy(event.getParameters(), 0, split, 1, event.getParameters().length);
split[0] = event.getCommand().getName();
com.sk89q.worldedit.event.platform.CommandEvent weEvent =
new com.sk89q.worldedit.event.platform.CommandEvent(wrap((EntityPlayerMP) event.getSender()), Joiner.on(" ").join(split));
WorldEdit.getInstance().getEventBus().post(weEvent);
}
}
@SubscribeEvent
public void onPlayerInteract(PlayerInteractEvent event) {
if (platform == null) {
@ -175,23 +226,23 @@ public class ForgeWorldEdit {
if (event.getWorld().isRemote && event instanceof LeftClickEmpty) {
// catch LCE, pass it to server
InternalPacketHandler.CHANNEL.sendToServer(new LeftClickAirEventMessage());
InternalPacketHandler.HANDLER.sendToServer(new LeftClickAirEventMessage());
return;
}
boolean isLeftDeny = event instanceof PlayerInteractEvent.LeftClickBlock
&& ((PlayerInteractEvent.LeftClickBlock) event)
.getUseItem() == Result.DENY;
.getUseItem() == Event.Result.DENY;
boolean isRightDeny =
event instanceof PlayerInteractEvent.RightClickBlock
&& ((PlayerInteractEvent.RightClickBlock) event)
.getUseItem() == Result.DENY;
.getUseItem() == Event.Result.DENY;
if (isLeftDeny || isRightDeny || event.getEntity().world.isRemote) {
return;
}
WorldEdit we = WorldEdit.getInstance();
ForgePlayer player = wrap((EntityPlayerMP) event.getEntityPlayer());
ForgePlayer player = adaptPlayer((EntityPlayerMP) event.getEntityPlayer());
ForgeWorld world = getWorld(event.getEntityPlayer().world);
if (event instanceof PlayerInteractEvent.LeftClickEmpty) {
@ -226,12 +277,24 @@ public class ForgeWorldEdit {
}
}
public static ItemStack toForgeItemStack(BaseItemStack item) {
NBTTagCompound forgeCompound = null;
if (item.getNbtData() != null) {
forgeCompound = NBTConverter.toNative(item.getNbtData());
@SubscribeEvent
public void onCommandEvent(CommandEvent event) throws CommandSyntaxException {
ParseResults<CommandSource> parseResults = event.getParseResults();
if (!(parseResults.getContext().getSource().getEntity() instanceof EntityPlayerMP)) {
return;
}
return new ItemStack(Item.getByNameOrId(item.getType().getId()), item.getAmount(), 0, forgeCompound);
EntityPlayerMP player = parseResults.getContext().getSource().asPlayer();
if (player.world.isRemote()) {
return;
}
if (parseResults.getContext().getCommand() != CommandWrapper.FAKE_COMMAND) {
return;
}
event.setCanceled(true);
WorldEdit.getInstance().getEventBus().post(new com.sk89q.worldedit.event.platform.CommandEvent(
adaptPlayer(parseResults.getContext().getSource().asPlayer()),
parseResults.getReader().getString()
));
}
/**
@ -243,17 +306,6 @@ public class ForgeWorldEdit {
return this.config;
}
/**
* Get the WorldEdit proxy for the given player.
*
* @param player the player
* @return the WorldEdit player
*/
public ForgePlayer wrap(EntityPlayerMP player) {
checkNotNull(player);
return new ForgePlayer(player);
}
/**
* Get the session for a player.
*
@ -262,7 +314,7 @@ public class ForgeWorldEdit {
*/
public LocalSession getSession(EntityPlayerMP player) {
checkNotNull(player);
return WorldEdit.getInstance().getSessionManager().get(wrap(player));
return WorldEdit.getInstance().getSessionManager().get(adaptPlayer(player));
}
/**
@ -291,7 +343,7 @@ public class ForgeWorldEdit {
* @return the working directory
*/
public File getWorkingDir() {
return this.workingDir;
return this.workingDir.toFile();
}
/**
@ -300,7 +352,7 @@ public class ForgeWorldEdit {
* @return a version string
*/
String getInternalVersion() {
return ForgeWorldEdit.class.getAnnotation(Mod.class).version();
return container.getModInfo().getVersion().toString();
}
public void setPermissionsProvider(ForgePermissionsProvider provider) {

View File

@ -21,13 +21,12 @@ package com.sk89q.worldedit.forge;
import static com.google.common.base.Preconditions.checkArgument;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.sk89q.worldedit.registry.state.Property;
import net.minecraft.block.properties.IProperty;
import net.minecraft.state.IProperty;
import java.util.List;
import java.util.Optional;
class IPropertyAdapter<T extends Comparable<T>> implements Property<T> {

View File

@ -1,40 +0,0 @@
/*
* 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.forge;
import com.sk89q.worldedit.forge.net.LeftClickAirEventMessage;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.relauncher.Side;
import java.nio.charset.Charset;
public class InternalPacketHandler {
public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");
public static SimpleNetworkWrapper CHANNEL;
public static void init() {
CHANNEL = NetworkRegistry.INSTANCE.newSimpleChannel(ForgeWorldEdit.MOD_ID);
CHANNEL.registerMessage(LeftClickAirEventMessage.Handler.class, LeftClickAirEventMessage.class, 0, Side.SERVER);
}
private InternalPacketHandler() {
}
}

View File

@ -19,18 +19,18 @@
package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.forge.gui.GuiHandler;
import com.sk89q.worldedit.forge.gui.GuiReferenceCard;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent.KeyInputEvent;
import org.lwjgl.input.Keyboard;
import org.lwjgl.glfw.GLFW;
public class KeyHandler {
private static Minecraft mc = Minecraft.getMinecraft();
private static KeyBinding mainKey = new KeyBinding("WorldEdit Reference", Keyboard.KEY_L, "WorldEdit");
private static Minecraft mc = Minecraft.getInstance();
private static KeyBinding mainKey = new KeyBinding("WorldEdit Reference", GLFW.GLFW_KEY_L, "WorldEdit");
public KeyHandler() {
ClientRegistry.registerKeyBinding(mainKey);
@ -39,7 +39,9 @@ public class KeyHandler {
@SubscribeEvent
public void onKey(KeyInputEvent evt) {
if (mc.player != null && mc.world != null && mainKey.isPressed()) {
mc.player.openGui(ForgeWorldEdit.inst, GuiHandler.REFERENCE_ID, mc.world, 0, 0, 0);
mc.displayGuiScreen(new GuiReferenceCard());
// TODO Seems GuiHandlers don't work on client right now
// NetworkHooks.openGui(mc.player, new ResourceLocationInteractionObject(ServerProxy.REFERENCE_GUI));
}
}

View File

@ -32,7 +32,7 @@ import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import net.minecraft.nbt.NBTBase;
import net.minecraft.nbt.INBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagByteArray;
import net.minecraft.nbt.NBTTagCompound;
@ -62,7 +62,7 @@ final class NBTConverter {
private NBTConverter() {
}
public static NBTBase toNative(Tag tag) {
public static INBTBase toNative(Tag tag) {
if (tag instanceof IntArrayTag) {
return toNative((IntArrayTag) tag);
@ -111,7 +111,7 @@ final class NBTConverter {
if (child instanceof EndTag) {
continue;
}
list.appendTag(toNative(child));
list.add(toNative(child));
}
return list;
}
@ -140,7 +140,7 @@ final class NBTConverter {
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()));
compound.put(child.getKey(), toNative(child.getValue()));
}
return compound;
}
@ -157,7 +157,7 @@ final class NBTConverter {
return new NBTTagDouble(tag.getValue());
}
public static Tag fromNative(NBTBase other) {
public static Tag fromNative(INBTBase other) {
if (other instanceof NBTTagIntArray) {
return fromNative((NBTTagIntArray) other);
@ -207,9 +207,9 @@ final class NBTConverter {
other = other.copy();
List<Tag> list = new ArrayList<>();
Class<? extends Tag> listClass = StringTag.class;
int tags = other.tagCount();
int tags = other.size();
for (int i = 0; i < tags; i++) {
Tag child = fromNative(other.removeTag(0));
Tag child = fromNative(other.remove(0));
list.add(child);
listClass = child.getClass();
}
@ -242,10 +242,10 @@ final class NBTConverter {
}
public static CompoundTag fromNative(NBTTagCompound other) {
Set<String> tags = other.getKeySet();
Set<String> tags = other.keySet();
Map<String, Tag> map = new HashMap<>();
for (String tagName : tags) {
map.put(tagName, fromNative(other.getTag(tagName)));
map.put(tagName, fromNative(other.get(tagName)));
}
return new CompoundTag(map);
}

View File

@ -21,9 +21,9 @@ package com.sk89q.worldedit.forge;
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.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import java.util.Collections;
import java.util.HashSet;
@ -57,7 +57,7 @@ public class ThreadSafeCache {
if (now - lastRefresh > REFRESH_DELAY) {
Set<UUID> onlineIds = new HashSet<>();
MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance();
MinecraftServer server = ServerLifecycleHooks.getCurrentServer();
if (server == null || server.getPlayerList() == null) {
return;
}

View File

@ -29,8 +29,6 @@ import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
import java.lang.reflect.Constructor;
import javax.annotation.Nullable;
/**
@ -46,45 +44,14 @@ final class TileEntityUtils {
*
* @param tag the tag
* @param position the position
* @return a tag compound
*/
private static NBTTagCompound updateForSet(NBTTagCompound tag, BlockVector3 position) {
private static void updateForSet(NBTTagCompound tag, BlockVector3 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, BlockVector3 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);
tag.put("x", new NBTTagInt(position.getBlockX()));
tag.put("y", new NBTTagInt(position.getBlockY()));
tag.put("z", new NBTTagInt(position.getBlockZ()));
}
/**
@ -98,52 +65,16 @@ final class TileEntityUtils {
static void setTileEntity(World world, BlockVector3 position, @Nullable NBTTagCompound tag) {
if (tag != null) {
updateForSet(tag, position);
TileEntity tileEntity = TileEntity.create(world, tag);
TileEntity tileEntity = TileEntity.create(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, BlockVector3 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 {
genericTE = 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;
}
public static NBTTagCompound copyNbtData(TileEntity tile) {
NBTTagCompound tag = new NBTTagCompound();
tile.writeToNBT(tag);
tile.write(tag);
return tag;
}
}

View File

@ -1,72 +0,0 @@
/*
* 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.forge;
import com.sk89q.worldedit.LocalSession;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.NetHandlerPlayServer;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.ThreadQuickExitException;
import net.minecraft.network.play.server.SPacketCustomPayload;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.network.FMLEventChannel;
import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientCustomPacketEvent;
import net.minecraftforge.fml.common.network.FMLNetworkEvent.ServerCustomPacketEvent;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import java.nio.charset.Charset;
public class WECUIPacketHandler {
public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");
public static FMLEventChannel WECUI_CHANNEL;
public static void init() {
WECUI_CHANNEL = NetworkRegistry.INSTANCE.newEventDrivenChannel(ForgeWorldEdit.CUI_PLUGIN_CHANNEL);
WECUI_CHANNEL.register(new WECUIPacketHandler());
}
@SubscribeEvent
public void onPacketData(ServerCustomPacketEvent event) {
if (event.getPacket().channel().equals(ForgeWorldEdit.CUI_PLUGIN_CHANNEL)) {
EntityPlayerMP player = getPlayerFromEvent(event);
LocalSession session = ForgeWorldEdit.inst.getSession(player);
if (session.hasCUISupport()) {
return;
}
String text = event.getPacket().payload().toString(UTF_8_CHARSET);
session.handleCUIInitializationMessage(text);
session.describeCUI(ForgeWorldEdit.inst.wrap(player));
}
}
@SubscribeEvent
public void callProcessPacket(ClientCustomPacketEvent event) {
try {
new SPacketCustomPayload(event.getPacket().channel(), new PacketBuffer(event.getPacket().payload())).processPacket(event.getHandler());
} catch (ThreadQuickExitException suppress) {
}
}
private static EntityPlayerMP getPlayerFromEvent(ServerCustomPacketEvent event) {
return ((NetHandlerPlayServer) event.getHandler()).player;
}
}

View File

@ -23,8 +23,11 @@ import com.sk89q.worldedit.forge.ForgeWorldEdit;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import org.lwjgl.opengl.GL11;
@OnlyIn(Dist.CLIENT)
public class GuiReferenceCard extends GuiScreen {
private GuiButton closeButton;
@ -33,25 +36,26 @@ public class GuiReferenceCard extends GuiScreen {
@Override
public void initGui() {
this.buttonList.add(this.closeButton = new GuiButton(0, (this.width - this.backgroundWidth + 100) / 2, (this.height + this.backgroundHeight - 60) / 2, this.backgroundWidth - 100, 20, "Close"));
this.closeButton = new GuiButton(0, (this.width - this.backgroundWidth + 100) / 2,
(this.height + this.backgroundHeight - 60) / 2, this.backgroundWidth - 100, 20, "Close") {
@Override
public void onClick(double mouseX, double mouseY) {
super.onClick(mouseX, mouseY);
mc.player.closeScreen();
}
};
}
@Override
public void drawScreen(int mouseX, int mouseY, float par3) {
public void render(int mouseX, int mouseY, float par3) {
int x = (this.width - this.backgroundWidth) / 2;
int y = (this.height - this.backgroundHeight) / 2 - this.closeButton.height;
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.renderEngine.bindTexture(new ResourceLocation(ForgeWorldEdit.MOD_ID, "textures/gui/reference.png"));
this.mc.textureManager.bindTexture(new ResourceLocation(ForgeWorldEdit.MOD_ID, "textures/gui/reference.png"));
this.drawTexturedModalRect(x, y, 0, 0, this.backgroundWidth, this.backgroundHeight);
super.drawScreen(mouseX, mouseY, par3);
}
@Override
protected void actionPerformed(GuiButton button) {
if (button.id == 0) {
this.mc.player.closeScreen();
}
super.render(mouseX, mouseY, par3);
}
@Override

View File

@ -0,0 +1,65 @@
/*
* 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.forge.gui;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.IInteractionObject;
import javax.annotation.Nullable;
public class ResourceLocationInteractionObject implements IInteractionObject {
private ResourceLocation resourceLocation;
public ResourceLocationInteractionObject(ResourceLocation resourceLocation) {
this.resourceLocation = resourceLocation;
}
@Override
public Container createContainer(InventoryPlayer inventoryPlayer, EntityPlayer entityPlayer) {
throw new UnsupportedOperationException();
}
@Override
public String getGuiID() {
return resourceLocation.toString();
}
@Override
public ITextComponent getName() {
return new TextComponentString(resourceLocation.toString());
}
@Override
public boolean hasCustomName() {
return false;
}
@Nullable
@Override
public ITextComponent getCustomName() {
return null;
}
}

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.forge.net.handler;
import com.sk89q.worldedit.forge.ForgeWorldEdit;
import com.sk89q.worldedit.forge.net.packet.LeftClickAirEventMessage;
import com.sk89q.worldedit.forge.net.packet.LeftClickAirEventMessage.Handler;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.network.NetworkRegistry.ChannelBuilder;
import net.minecraftforge.fml.network.simple.SimpleChannel;
public final class InternalPacketHandler {
private static final String PROTOCOL_VERSION = Integer.toString(1);
public static SimpleChannel HANDLER = ChannelBuilder
.named(new ResourceLocation(ForgeWorldEdit.MOD_ID, "internal"))
.clientAcceptedVersions(PROTOCOL_VERSION::equals)
.serverAcceptedVersions(PROTOCOL_VERSION::equals)
.networkProtocolVersion(() -> PROTOCOL_VERSION)
.simpleChannel();
private InternalPacketHandler() {
}
public static void init() {
HANDLER.registerMessage(0, LeftClickAirEventMessage.class,
LeftClickAirEventMessage::encode, LeftClickAirEventMessage::decode, Handler::handle);
}
}

View File

@ -0,0 +1,78 @@
/*
* 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.forge.net.handler;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.forge.ForgeWorldEdit;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.ThreadQuickExitException;
import net.minecraft.network.play.server.SPacketCustomPayload;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.network.NetworkEvent.ClientCustomPayloadEvent;
import net.minecraftforge.fml.network.NetworkEvent.ServerCustomPayloadEvent;
import net.minecraftforge.fml.network.NetworkRegistry.ChannelBuilder;
import net.minecraftforge.fml.network.event.EventNetworkChannel;
import java.nio.charset.Charset;
import static com.sk89q.worldedit.forge.ForgeAdapter.adaptPlayer;
public final class WECUIPacketHandler {
private WECUIPacketHandler() {
}
public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");
private static final String PROTOCOL_VERSION = Integer.toString(1);
public static EventNetworkChannel HANDLER = ChannelBuilder
.named(new ResourceLocation(ForgeWorldEdit.MOD_ID, ForgeWorldEdit.CUI_PLUGIN_CHANNEL))
.clientAcceptedVersions(PROTOCOL_VERSION::equals)
.serverAcceptedVersions(PROTOCOL_VERSION::equals)
.networkProtocolVersion(() -> PROTOCOL_VERSION)
.eventNetworkChannel();
public static void init() {
HANDLER.addListener(WECUIPacketHandler::onPacketData);
HANDLER.addListener(WECUIPacketHandler::callProcessPacket);
}
public static void onPacketData(ServerCustomPayloadEvent event) {
EntityPlayerMP player = event.getSource().get().getSender();
LocalSession session = ForgeWorldEdit.inst.getSession(player);
if (session.hasCUISupport()) {
return;
}
String text = event.getPayload().toString(UTF_8_CHARSET);
session.handleCUIInitializationMessage(text);
session.describeCUI(adaptPlayer(player));
}
public static void callProcessPacket(ClientCustomPayloadEvent event) {
try {
new SPacketCustomPayload(
new ResourceLocation(ForgeWorldEdit.MOD_ID, ForgeWorldEdit.CUI_PLUGIN_CHANNEL),
event.getPayload()
).processPacket(Minecraft.getInstance().player.connection);
} catch (ThreadQuickExitException ignored) {
}
}
}

View File

@ -17,34 +17,32 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.forge.net;
package com.sk89q.worldedit.forge.net.packet;
import com.sk89q.worldedit.forge.ForgeWorldEdit;
import io.netty.buffer.ByteBuf;
import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.fml.common.network.simpleimpl.IMessage;
import net.minecraftforge.fml.common.network.simpleimpl.IMessageHandler;
import net.minecraftforge.fml.common.network.simpleimpl.MessageContext;
import net.minecraft.network.PacketBuffer;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickEmpty;
import net.minecraftforge.fml.network.NetworkEvent.Context;
public class LeftClickAirEventMessage implements IMessage {
import java.util.Objects;
import java.util.function.Supplier;
public static final class Handler implements IMessageHandler<LeftClickAirEventMessage, IMessage> {
@SuppressWarnings({"NonFinalUtilityClass", "checkstyle:hideutilityclassconstructor"})
public class LeftClickAirEventMessage {
@Override
public IMessage onMessage(LeftClickAirEventMessage message, final MessageContext ctx) {
ctx.getServerHandler().player.mcServer.addScheduledTask(
() -> ForgeWorldEdit.inst.onPlayerInteract(new PlayerInteractEvent.LeftClickEmpty(ctx.getServerHandler().player)));
return null;
public static final class Handler {
public static void handle(final LeftClickAirEventMessage message, Supplier<Context> ctx) {
Context context = ctx.get();
context.enqueueWork(() -> ForgeWorldEdit.inst.onPlayerInteract(new LeftClickEmpty(Objects.requireNonNull(context.getSender()))));
}
}
@Override
public void fromBytes(ByteBuf buf) {
public static LeftClickAirEventMessage decode(ByteBuf buf) {
return new LeftClickAirEventMessage();
}
@Override
public void toBytes(ByteBuf buf) {
public static void encode(LeftClickAirEventMessage msg, PacketBuffer buf) {
}
}

View File

@ -17,15 +17,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.forge;
package com.sk89q.worldedit.forge.proxy;
import com.sk89q.worldedit.forge.KeyHandler;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
import net.minecraftforge.common.MinecraftForge;
public class ClientProxy extends CommonProxy {
@OnlyIn(Dist.CLIENT)
public class ClientProxy implements CommonProxy {
@Override
public void registerHandlers() {
super.registerHandlers();
MinecraftForge.EVENT_BUS.register(new KeyHandler());
}

View File

@ -17,15 +17,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.forge;
package com.sk89q.worldedit.forge.proxy;
import com.sk89q.worldedit.forge.gui.GuiHandler;
import net.minecraftforge.fml.common.network.NetworkRegistry;
public class CommonProxy {
public void registerHandlers() {
NetworkRegistry.INSTANCE.registerGuiHandler(ForgeWorldEdit.inst, new GuiHandler());
}
public interface CommonProxy {
void registerHandlers();
}

View File

@ -17,29 +17,24 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.forge.gui;
package com.sk89q.worldedit.forge.proxy;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.world.World;
import net.minecraftforge.fml.common.network.IGuiHandler;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.api.distmarker.OnlyIn;
public class GuiHandler implements IGuiHandler {
@OnlyIn(Dist.DEDICATED_SERVER)
public class ServerProxy implements CommonProxy {
public static final int REFERENCE_ID = 0;
// public static ResourceLocation REFERENCE_GUI = new ResourceLocation("worldedit", "resource_gui");
@Override
public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
return null;
public void registerHandlers() {
// ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.GUIFACTORY, () -> openContainer -> {
// if (openContainer.getId().equals(REFERENCE_GUI)) {
// return new GuiReferenceCard();
// }
// return null;
// });
}
@Override
public Object getClientGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) {
switch (id) {
case REFERENCE_ID:
return new GuiReferenceCard();
}
return null;
}
}
}

View File

@ -0,0 +1,36 @@
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
modLoader="javafml"
# A version range to match for said mod loader - for regular FML @Mod it will be the minecraft version (without the 1.)
loaderVersion="[24,)"
# A URL to refer people to when problems occur with this mod
issueTrackerURL="https://discord.gg/enginehub"
# A URL for the "homepage" for this mod, displayed in the mod UI
displayURL="http://wiki.sk89q.com/wiki/WorldEdit/"
# A file name (in the root of the mod JAR) containing a logo for display
logoFile="worldedit-icon.png"
# A text field displayed in the mod UI
authors="sk89q, wizjany, TomyLobo, kenzierocks, Me4502"
# A list of mods - how many allowed here is determined by the individual mod loader
[[mods]]
# The modid of the mod
modId="worldedit"
# The version number of the mod - there's a few well known ${} variables useable here or just hardcode it
version="${version}"
# A display name for the mod
displayName="WorldEdit"
# The description text for the mod (multi line!)
description='''
WorldEdit is an easy-to-use in-game world editor for Minecraft, supporting both single- and multi-player.
'''
[[dependencies.worldedit]]
modId="forge"
mandatory=true
versionRange="[${forgeVersion},)"
ordering="NONE"
side="BOTH"
[[dependencies.worldedit]]
modId="sponge"
mandatory=false
versionRange="[1.13]"
ordering="BEFORE"
side="SERVER"

View File

@ -1,13 +1,13 @@
#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=minecraft:compass
profile=false
trace-unflushed-sessions=false
super-pickaxe-drop-items=true
disallowed-blocks=minecraft:oak_sapling,minecraft:jungle_sapling,minecraft:dark_oak_sapling:,minecraft:spruce_sapling,minecraft:birch_sapling,minecraft:acacia_sapling,minecraft:black_bed,minecraft:blue_bed,minecraft:brown_bed,minecraft:cyan_bed,minecraft:gray_bed,minecraft:green_bed,minecraft:light_blue_bed,minecraft:light_gray_bed,minecraft:lime_bed,minecraft:magenta_bed,minecraft:orange_bed,minecraft:pink_bed,minecraft:purple_bed,minecraft:red_bed,minecraft:white_bed,minecraft:yellow_bed,minecraft:powered_rail,minecraft:detector_rail,minecraft:grass,minecraft:dead_bush,minecraft:moving_piston,minecraft:piston_head,minecraft:sunflower,minecraft:rose_bush,minecraft:dandelion,minecraft:poppy,minecraft:brown_mushroom,minecraft:red_mushroom,minecraft:tnt,minecraft:torch,minecraft:fire,minecraft:redstone_wire,minecraft:wheat,minecraft:potatoes,minecraft:carrots,minecraft:melon_stem,minecraft:pumpkin_stem,minecraft:beetroots,minecraft:rail,minecraft:lever,minecraft:redstone_torch,minecraft:redstone_wall_torch,minecraft:repeater,minecraft:comparator,minecraft:stone_button,minecraft:birch_button,minecraft:acacia_button,minecraft:dark_oak_button,minecraft:jungle_button,minecraft:oak_button,minecraft:spruce_button,minecraft:cactus,minecraft:sugar_cane,minecraft:bedrock
disallowed-blocks=minecraft:oak_sapling,minecraft:jungle_sapling,minecraft:dark_oak_sapling,minecraft:spruce_sapling,minecraft:birch_sapling,minecraft:acacia_sapling,minecraft:black_bed,minecraft:blue_bed,minecraft:brown_bed,minecraft:cyan_bed,minecraft:gray_bed,minecraft:green_bed,minecraft:light_blue_bed,minecraft:light_gray_bed,minecraft:lime_bed,minecraft:magenta_bed,minecraft:orange_bed,minecraft:pink_bed,minecraft:purple_bed,minecraft:red_bed,minecraft:white_bed,minecraft:yellow_bed,minecraft:powered_rail,minecraft:detector_rail,minecraft:grass,minecraft:dead_bush,minecraft:moving_piston,minecraft:piston_head,minecraft:sunflower,minecraft:rose_bush,minecraft:dandelion,minecraft:poppy,minecraft:brown_mushroom,minecraft:red_mushroom,minecraft:tnt,minecraft:torch,minecraft:fire,minecraft:redstone_wire,minecraft:wheat,minecraft:potatoes,minecraft:carrots,minecraft:melon_stem,minecraft:pumpkin_stem,minecraft:beetroots,minecraft:rail,minecraft:lever,minecraft:redstone_torch,minecraft:redstone_wall_torch,minecraft:repeater,minecraft:comparator,minecraft:stone_button,minecraft:birch_button,minecraft:acacia_button,minecraft:dark_oak_button,minecraft:jungle_button,minecraft:oak_button,minecraft:spruce_button,minecraft:cactus,minecraft:sugar_cane,minecraft:bedrock
max-super-pickaxe-size=5
max-brush-radius=10
craftscript-dir=craftscripts

View File

@ -1,21 +0,0 @@
[{
"modid": "worldedit",
"name": "WorldEdit",
"description": "WorldEdit is an easy-to-use in-game world editor for Minecraft, supporting both single player and multiplayer.",
"version": "${internalVersion}",
"mcversion": "${mcVersion}",
"url": "http://wiki.sk89q.com/wiki/WorldEdit",
"updateUrl": "",
"authors": [ "sk89q", "wizjany", "TomyLobo", "kenzierocks", "Me4502" ],
"credits": "",
"logoFile": "",
"screenshots": [],
"requiredMods": [
"Forge@[${forgeVersion},)"
],
"dependencies": [
"Forge@[${forgeVersion},)",
"sponge"
],
"dependants": []
}]

View File

@ -0,0 +1,6 @@
{
"pack": {
"description": "WorldEdit Resources",
"pack_format": 4
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB