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

This commit is contained in:
Jesse Boyd
2019-11-19 21:23:47 +00:00
272 changed files with 16041 additions and 6107 deletions

View File

@ -1,111 +0,0 @@
buildscript {
repositories {
mavenLocal()
mavenCentral()
maven { url = "https://files.minecraftforge.net/maven" }
jcenter()
}
dependencies {
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
}
}
apply plugin: 'net.minecraftforge.gradle'
def minecraftVersion = "1.13.2"
def forgeVersion = "25.0.76"
dependencies {
compile project(':worldedit-core')
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
minecraft {
mappings channel: 'snapshot', version: '20190311-1.13.2'
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${minecraftVersion}"
processResources {
// 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
}
// copy everything else except the mcmod.info
from(sourceSets.main.resources.srcDirs) {
exclude 'META-INF/mods.toml'
}
}
jar {
manifest {
attributes("Class-Path": "truezip.jar WorldEdit/truezip.jar js.jar WorldEdit/js.jar",
"WorldEdit-Version": version,
"FMLAT": "worldedit_at.cfg")
}
}
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"))
}
}
afterEvaluate {
reobf {
shadowJar {
mappings = createMcpToSrg.output
}
}
}
task deobfJar(type: Jar) {
from sourceSets.main.output
classifier = 'dev'
}
artifacts {
archives deobfJar
}

View File

@ -19,27 +19,49 @@
package com.sk89q.worldedit.forge;
import com.google.common.collect.ImmutableList;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
import com.mojang.brigadier.tree.LiteralCommandNode;
import com.sk89q.worldedit.util.command.CommandMapping;
import com.mojang.brigadier.context.CommandContext;
import com.mojang.brigadier.context.StringRange;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.suggestion.Suggestion;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.event.platform.CommandSuggestionEvent;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.internal.util.Substring;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.ServerPlayerEntity;
import org.enginehub.piston.inject.InjectedValueStore;
import org.enginehub.piston.inject.Key;
import org.enginehub.piston.inject.MapBackedValueStore;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.function.Predicate;
import static net.minecraft.command.Commands.argument;
import static net.minecraft.command.Commands.literal;
public final class CommandWrapper {
private CommandWrapper() {
}
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) {
public static void register(CommandDispatcher<CommandSource> dispatcher, org.enginehub.piston.Command command) {
ImmutableList.Builder<String> aliases = ImmutableList.builder();
aliases.add(command.getName()).addAll(command.getAliases());
for (String alias : aliases.build()) {
LiteralArgumentBuilder<CommandSource> base = literal(alias).executes(FAKE_COMMAND)
.then(argument("args", StringArgumentType.greedyString())
.suggests(CommandWrapper::suggest)
.executes(FAKE_COMMAND));
if (command.getCondition() != org.enginehub.piston.Command.Condition.TRUE) {
base.requires(requirementsFor(command));
}
dispatcher.register(base);
@ -47,22 +69,53 @@ public final class CommandWrapper {
}
public static final Command<CommandSource> FAKE_COMMAND = ctx -> {
EntityPlayerMP player = ctx.getSource().asPlayer();
if (player.world.isRemote()) {
if (ctx.getSource().getWorld().isRemote) {
return 0;
}
return 1;
};
private static Predicate<CommandSource> requirementsFor(CommandMapping mapping) {
private static Predicate<CommandSource> requirementsFor(org.enginehub.piston.Command 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
));
final Entity entity = ctx.getEntity();
if (!(entity instanceof ServerPlayerEntity)) return true;
final Actor actor = ForgeAdapter.adaptPlayer(((ServerPlayerEntity) entity));
InjectedValueStore store = MapBackedValueStore.create();
store.injectValue(Key.of(Actor.class), context -> Optional.of(actor));
return mapping.getCondition().satisfied(store);
};
}
private static CompletableFuture<Suggestions> suggest(CommandContext<CommandSource> context,
SuggestionsBuilder builder) throws CommandSyntaxException {
CommandSuggestionEvent event = new CommandSuggestionEvent(
ForgeAdapter.adaptPlayer(context.getSource().asPlayer()),
builder.getInput()
);
WorldEdit.getInstance().getEventBus().post(event);
List<Substring> suggestions = event.getSuggestions();
ImmutableList.Builder<Suggestion> result = ImmutableList.builder();
for (Substring suggestion : suggestions) {
String suggestionText = suggestion.getSubstring();
// If at end, we are actually suggesting the next argument
// Ensure there is a space!
if (suggestion.getStart() == suggestion.getEnd()
&& suggestion.getEnd() == builder.getInput().length()
&& !builder.getInput().endsWith(" ")
&& !builder.getInput().endsWith("\"")) {
suggestionText = " " + suggestionText;
}
result.add(new Suggestion(
StringRange.between(suggestion.getStart(), suggestion.getEnd()),
suggestionText
));
}
return CompletableFuture.completedFuture(
Suggestions.create(builder.getInput(), result.build())
);
}
}

View File

@ -21,6 +21,7 @@ package com.sk89q.worldedit.forge;
import com.google.common.collect.ImmutableList;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
@ -39,15 +40,13 @@ 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.entity.player.ServerPlayerEntity;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.CompoundNBT;
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;
@ -91,20 +90,20 @@ public final class ForgeAdapter {
return new Vec3d(vector.getBlockX(), vector.getBlockY(), vector.getBlockZ());
}
public static EnumFacing adapt(Direction face) {
public static net.minecraft.util.Direction adapt(Direction face) {
switch (face) {
case NORTH: return EnumFacing.NORTH;
case SOUTH: return EnumFacing.SOUTH;
case WEST: return EnumFacing.WEST;
case EAST: return EnumFacing.EAST;
case DOWN: return EnumFacing.DOWN;
case NORTH: return net.minecraft.util.Direction.NORTH;
case SOUTH: return net.minecraft.util.Direction.SOUTH;
case WEST: return net.minecraft.util.Direction.WEST;
case EAST: return net.minecraft.util.Direction.EAST;
case DOWN: return net.minecraft.util.Direction.DOWN;
case UP:
default:
return EnumFacing.UP;
return net.minecraft.util.Direction.UP;
}
}
public static Direction adaptEnumFacing(EnumFacing face) {
public static Direction adaptEnumFacing(net.minecraft.util.Direction face) {
switch (face) {
case NORTH: return Direction.NORTH;
case SOUTH: return Direction.SOUTH;
@ -148,7 +147,7 @@ public final class ForgeAdapter {
for (Map.Entry<IProperty<?>, Comparable<?>> prop : mcProps.entrySet()) {
Object value = prop.getValue();
if (prop.getKey() instanceof DirectionProperty) {
value = adaptEnumFacing((EnumFacing) value);
value = adaptEnumFacing((net.minecraft.util.Direction) value);
} else if (prop.getKey() instanceof net.minecraft.state.EnumProperty) {
value = ((IStringSerializable) value).getName();
}
@ -157,14 +156,14 @@ public final class ForgeAdapter {
return props;
}
private static IBlockState applyProperties(StateContainer<Block, IBlockState> stateContainer, IBlockState newState, Map<Property<?>, Object> states) {
private static net.minecraft.block.BlockState applyProperties(StateContainer<Block, net.minecraft.block.BlockState> stateContainer, net.minecraft.block.BlockState 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);
value = adapt(dir);
} else if (property instanceof net.minecraft.state.EnumProperty) {
String enumName = (String) value;
value = ((net.minecraft.state.EnumProperty<?>) property).parseValue((String) value).orElseGet(() -> {
@ -177,16 +176,16 @@ public final class ForgeAdapter {
return newState;
}
public static IBlockState adapt(BlockState blockState) {
Block mcBlock = ForgeAdapter.adapt(blockState.getBlockType());
IBlockState newState = mcBlock.getDefaultState();
public static net.minecraft.block.BlockState adapt(BlockState blockState) {
Block mcBlock = adapt(blockState.getBlockType());
net.minecraft.block.BlockState newState = mcBlock.getDefaultState();
Map<Property<?>, Object> states = blockState.getStates();
return applyProperties(mcBlock.getStateContainer(), newState, states);
}
public static BlockState adapt(IBlockState blockState) {
public static BlockState adapt(net.minecraft.block.BlockState blockState) {
BlockType blockType = adapt(blockState.getBlock());
return blockType.getState(ForgeAdapter.adaptProperties(blockType, blockState.getValues()));
return blockType.getState(adaptProperties(blockType, blockState.getValues()));
}
public static Block adapt(BlockType blockType) {
@ -206,15 +205,27 @@ public final class ForgeAdapter {
}
public static ItemStack adapt(BaseItemStack baseItemStack) {
NBTTagCompound forgeCompound = null;
CompoundNBT forgeCompound = null;
if (baseItemStack.getNbtData() != null) {
forgeCompound = NBTConverter.toNative(baseItemStack.getNbtData());
}
return new ItemStack(adapt(baseItemStack.getType()), baseItemStack.getAmount(), forgeCompound);
final ItemStack itemStack = new ItemStack(adapt(baseItemStack.getType()), baseItemStack.getAmount());
itemStack.setTag(forgeCompound);
return itemStack;
}
public static BaseItemStack adapt(ItemStack itemStack) {
CompoundTag tag = NBTConverter.fromNative(itemStack.serializeNBT());
if (tag.getValue().isEmpty()) {
tag = null;
} else {
final Tag tagTag = tag.getValue().get("tag");
if (tagTag instanceof CompoundTag) {
tag = ((CompoundTag) tagTag);
} else {
tag = null;
}
}
return new BaseItemStack(adapt(itemStack.getItem()), tag, itemStack.getCount());
}
@ -224,7 +235,7 @@ public final class ForgeAdapter {
* @param player the player
* @return the WorldEdit player
*/
public static ForgePlayer adaptPlayer(EntityPlayerMP player) {
public static ForgePlayer adaptPlayer(ServerPlayerEntity player) {
checkNotNull(player);
return new ForgePlayer(player);
}

View File

@ -0,0 +1,40 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BlockCategoryRegistry;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.Tag;
import net.minecraft.util.ResourceLocation;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
public class ForgeBlockCategoryRegistry implements BlockCategoryRegistry {
@Override
public Set<BlockType> getCategorisedByName(String category) {
return Optional.ofNullable(BlockTags.getCollection().get(new ResourceLocation(category)))
.map(Tag::getAllElements).orElse(Collections.emptySet())
.stream().map(ForgeAdapter::adapt).collect(Collectors.toSet());
}
}

View File

@ -22,7 +22,7 @@ package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import com.sk89q.worldedit.world.registry.PassthroughBlockMaterial;
import net.minecraft.block.material.EnumPushReaction;
import net.minecraft.block.material.PushReaction;
import net.minecraft.block.material.Material;
import javax.annotation.Nullable;
@ -63,12 +63,12 @@ public class ForgeBlockMaterial extends PassthroughBlockMaterial {
@Override
public boolean isFragileWhenPushed() {
return delegate.getPushReaction() == EnumPushReaction.DESTROY;
return delegate.getPushReaction() == PushReaction.DESTROY;
}
@Override
public boolean isUnpushable() {
return delegate.getPushReaction() == EnumPushReaction.BLOCK;
return delegate.getPushReaction() == PushReaction.BLOCK;
}
@Override

View File

@ -20,6 +20,7 @@
package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BlockMaterial;
import com.sk89q.worldedit.world.registry.BundledBlockRegistry;
@ -29,13 +30,15 @@ import net.minecraft.block.properties.IProperty;
import net.minecraft.util.ResourceLocation;
import net.minecraft.state.IProperty;
import javax.annotation.Nullable;
import net.minecraftforge.fml.loading.FMLLoader;
import java.util.OptionalInt;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
import javax.annotation.Nullable;
public class ForgeBlockRegistry extends BundledBlockRegistry {
private Map<Material, ForgeBlockMaterial> materialMap = new HashMap<>();
@ -44,7 +47,7 @@ public class ForgeBlockRegistry extends BundledBlockRegistry {
@Override
public String getName(BlockType blockType) {
Block block = ForgeAdapter.adapt(blockType);
if (block != null) {
if (block != null && FMLLoader.getDist().isClient()) {
return block.getNameTextComponent().getFormattedText();
} else {
return super.getName(blockType);
@ -74,4 +77,9 @@ public class ForgeBlockRegistry extends BundledBlockRegistry {
return map;
}
@Override
public OptionalInt getInternalBlockStateId(BlockState state) {
net.minecraft.block.BlockState equivalent = ForgeAdapter.adapt(state);
return OptionalInt.of(Block.getStateId(equivalent));
}
}

File diff suppressed because it is too large Load Diff

View File

@ -29,7 +29,7 @@ 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.nbt.NBTTagCompound;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.util.ResourceLocation;
import java.lang.ref.WeakReference;
@ -51,7 +51,7 @@ class ForgeEntity implements Entity {
if (entity != null) {
ResourceLocation id = entity.getType().getRegistryName();
if (id != null) {
NBTTagCompound tag = new NBTTagCompound();
CompoundNBT tag = new CompoundNBT();
entity.writeWithoutTypeId(tag);
return new BaseEntity(EntityTypes.get(id.toString()), NBTConverter.fromNative(tag));
} else {
@ -78,7 +78,7 @@ class ForgeEntity implements Entity {
@Override
public boolean setLocation(Location location) {
// TODO
// TODO unused atm
return false;
}

View File

@ -23,27 +23,27 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.entity.metadata.EntityProperties;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLiving;
import net.minecraft.entity.IMerchant;
import net.minecraft.entity.INpc;
import net.minecraft.entity.boss.dragon.EnderDragonPartEntity;
import net.minecraft.entity.item.ArmorStandEntity;
import net.minecraft.entity.item.ExperienceOrbEntity;
import net.minecraft.entity.item.PaintingEntity;
import net.minecraft.entity.item.TNTEntity;
import net.minecraft.entity.merchant.IMerchant;
import net.minecraft.entity.INPC;
import net.minecraft.entity.IProjectile;
import net.minecraft.entity.MultiPartEntityPart;
import net.minecraft.entity.item.EntityArmorStand;
import net.minecraft.entity.item.EntityBoat;
import net.minecraft.entity.item.EntityEnderEye;
import net.minecraft.entity.item.EntityFallingBlock;
import net.minecraft.entity.item.EntityItem;
import net.minecraft.entity.item.EntityItemFrame;
import net.minecraft.entity.item.EntityMinecart;
import net.minecraft.entity.item.EntityPainting;
import net.minecraft.entity.item.EntityTNTPrimed;
import net.minecraft.entity.item.EntityXPOrb;
import net.minecraft.entity.monster.EntityGolem;
import net.minecraft.entity.passive.EntityAmbientCreature;
import net.minecraft.entity.passive.EntityAnimal;
import net.minecraft.entity.passive.EntityTameable;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.MobEntity;
import net.minecraft.entity.item.BoatEntity;
import net.minecraft.entity.item.EyeOfEnderEntity;
import net.minecraft.entity.item.FallingBlockEntity;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.entity.item.ItemFrameEntity;
import net.minecraft.entity.item.minecart.AbstractMinecartEntity;
import net.minecraft.entity.passive.AmbientEntity;
import net.minecraft.entity.passive.AnimalEntity;
import net.minecraft.entity.passive.TameableEntity;
import net.minecraft.entity.passive.GolemEntity;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.entity.player.ServerPlayerEntity;
public class ForgeEntityProperties implements EntityProperties {
@ -56,82 +56,82 @@ public class ForgeEntityProperties implements EntityProperties {
@Override
public boolean isPlayerDerived() {
return entity instanceof EntityPlayer;
return entity instanceof PlayerEntity;
}
@Override
public boolean isProjectile() {
return entity instanceof EntityEnderEye || entity instanceof IProjectile;
return entity instanceof EyeOfEnderEntity || entity instanceof IProjectile;
}
@Override
public boolean isItem() {
return entity instanceof EntityItem;
return entity instanceof ItemEntity;
}
@Override
public boolean isFallingBlock() {
return entity instanceof EntityFallingBlock;
return entity instanceof FallingBlockEntity;
}
@Override
public boolean isPainting() {
return entity instanceof EntityPainting;
return entity instanceof PaintingEntity;
}
@Override
public boolean isItemFrame() {
return entity instanceof EntityItemFrame;
return entity instanceof ItemFrameEntity;
}
@Override
public boolean isBoat() {
return entity instanceof EntityBoat;
return entity instanceof BoatEntity;
}
@Override
public boolean isMinecart() {
return entity instanceof EntityMinecart;
return entity instanceof AbstractMinecartEntity;
}
@Override
public boolean isTNT() {
return entity instanceof EntityTNTPrimed;
return entity instanceof TNTEntity;
}
@Override
public boolean isExperienceOrb() {
return entity instanceof EntityXPOrb;
return entity instanceof ExperienceOrbEntity;
}
@Override
public boolean isLiving() {
return entity instanceof EntityLiving;
return entity instanceof MobEntity;
}
@Override
public boolean isAnimal() {
return entity instanceof EntityAnimal;
return entity instanceof AnimalEntity;
}
@Override
public boolean isAmbient() {
return entity instanceof EntityAmbientCreature;
return entity instanceof AmbientEntity;
}
@Override
public boolean isNPC() {
return entity instanceof INpc || entity instanceof IMerchant;
return entity instanceof INPC || entity instanceof IMerchant;
}
@Override
public boolean isGolem() {
return entity instanceof EntityGolem;
return entity instanceof GolemEntity;
}
@Override
public boolean isTamed() {
return entity instanceof EntityTameable && ((EntityTameable) entity).isTamed();
return entity instanceof TameableEntity && ((TameableEntity) entity).isTamed();
}
@Override
@ -141,11 +141,11 @@ public class ForgeEntityProperties implements EntityProperties {
@Override
public boolean isArmorStand() {
return entity instanceof EntityArmorStand;
return entity instanceof ArmorStandEntity;
}
@Override
public boolean isPasteable() {
return !(entity instanceof EntityPlayerMP || entity instanceof MultiPartEntityPart);
return !(entity instanceof ServerPlayerEntity || entity instanceof EnderDragonPartEntity);
}
}

View File

@ -0,0 +1,40 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.ItemCategoryRegistry;
import net.minecraft.tags.ItemTags;
import net.minecraft.tags.Tag;
import net.minecraft.util.ResourceLocation;
import java.util.Collections;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
public class ForgeItemCategoryRegistry implements ItemCategoryRegistry {
@Override
public Set<ItemType> getCategorisedByName(String category) {
return Optional.ofNullable(ItemTags.getCollection().get(new ResourceLocation(category)))
.map(Tag::getAllElements).orElse(Collections.emptySet())
.stream().map(ForgeAdapter::adapt).collect(Collectors.toSet());
}
}

View File

@ -28,12 +28,24 @@ import com.sk89q.worldedit.world.item.ItemType;
import com.sk89q.worldedit.world.registry.BundledItemRegistry;
import javax.annotation.Nullable;
import net.minecraft.client.resources.I18n;
import net.minecraft.item.Item;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.registries.RegistryManager;
public class ForgeItemRegistry extends BundledItemRegistry {
@Nullable
@Override
public String getName(ItemType itemType) {
return super.getName(itemType); // TODO
if (FMLLoader.getDist().isClient()) {
final Item item = RegistryManager.ACTIVE.getRegistry(Item.class)
.getValue(ResourceLocation.tryCreate(itemType.getId()));
if (item != null) {
return I18n.format(item.getTranslationKey());
}
}
return super.getName(itemType);
}
}

View File

@ -19,13 +19,13 @@
package com.sk89q.worldedit.forge;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.world.GameType;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
public interface ForgePermissionsProvider {
boolean hasPermission(EntityPlayerMP player, String permission);
boolean hasPermission(ServerPlayerEntity player, String permission);
void registerPermission(String permission);
@ -38,7 +38,7 @@ public interface ForgePermissionsProvider {
}
@Override
public boolean hasPermission(EntityPlayerMP player, String permission) {
public boolean hasPermission(ServerPlayerEntity player, String permission) {
ForgeConfiguration configuration = platform.getConfiguration();
return configuration.cheatMode ||
ServerLifecycleHooks.getCurrentServer().getPlayerList().canSendCommands(player.getGameProfile()) ||
@ -49,7 +49,7 @@ public interface ForgePermissionsProvider {
public void registerPermission(String permission) {}
}
// TODO Re-add when Sponge for 1.13 is out
// TODO Re-add when Sponge for 1.14 is out
// class SpongePermissionsProvider implements ForgePermissionsProvider {
//
// @Override

View File

@ -19,31 +19,39 @@
package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.command.util.PermissionCondition;
import com.sk89q.worldedit.entity.Player;
import com.sk89q.worldedit.extension.platform.AbstractPlatform;
import com.sk89q.worldedit.extension.platform.Actor;
import com.sk89q.worldedit.extension.platform.Capability;
import com.sk89q.worldedit.extension.platform.MultiUserPlatform;
import com.sk89q.worldedit.extension.platform.Preference;
import com.sk89q.worldedit.util.command.CommandMapping;
import com.sk89q.worldedit.util.command.Dispatcher;
import com.sk89q.worldedit.world.DataFixer;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.registry.Registries;
import net.minecraft.command.Commands;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.server.MinecraftServer;
import net.minecraft.server.dedicated.DedicatedServer;
import net.minecraft.server.management.PlayerList;
import net.minecraft.util.ResourceLocation;
import net.minecraft.world.WorldServer;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import net.minecraft.util.SharedConstants;
import net.minecraft.world.server.ServerWorld;
import javax.annotation.Nullable;
import org.enginehub.piston.Command;
import org.enginehub.piston.CommandManager;
import java.util.ArrayList;
import java.util.Collection;
import java.util.EnumMap;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static java.util.stream.Collectors.toList;
class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
@ -80,21 +88,33 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
getConfiguration().load();
}
@Override
public int getDataVersion() {
return SharedConstants.getVersion().getWorldVersion();
}
@Override
public DataFixer getDataFixer() {
return dataFixer;
}
@Override
public int schedule(long delay, long period, Runnable task) {
return -1;
}
@Override
public List<? extends com.sk89q.worldedit.world.World> getWorlds() {
Iterable<WorldServer> worlds = server.getWorlds();
List<com.sk89q.worldedit.world.World> ret = new ArrayList<>();
for (WorldServer world : worlds) {
@Nullable
public ForgeWatchdog getWatchdog() {
return watchdog;
}
@Override
public List<? extends World> getWorlds() {
Iterable<ServerWorld> worlds = server.getWorlds();
List<World> ret = new ArrayList<>();
for (ServerWorld world : worlds) {
@Override
public List<? extends World> getWorlds() {
Iterable<ServerWorld> worlds = server.getWorlds();
@ -111,7 +131,7 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
if (player instanceof ForgePlayer) {
return player;
} else {
EntityPlayerMP entity = server.getPlayerList().getPlayerByUsername(player.getName());
ServerPlayerEntity entity = server.getPlayerList().getPlayerByUsername(player.getName());
return entity != null ? new ForgePlayer(entity) : null;
}
}
@ -122,7 +142,7 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
if (world instanceof ForgeWorld) {
return world;
} else {
for (WorldServer ws : server.getWorlds()) {
for (ServerWorld ws : server.getWorlds()) {
if (ws.getWorldInfo().getWorldName().equals(world.getName())) {
return new ForgeWorld(ws);
}
@ -133,16 +153,17 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
}
@Override
public void registerCommands(Dispatcher dispatcher) {
public void registerCommands(CommandManager manager) {
if (server == null) return;
Commands mcMan = server.getCommandManager();
for (final CommandMapping command : dispatcher.getCommands()) {
for (Command command : manager.getAllCommands().collect(toList())) {
CommandWrapper.register(mcMan.getDispatcher(), command);
if (command.getDescription().getPermissions().size() > 0) {
for (int i = 1; i < command.getDescription().getPermissions().size(); i++) {
ForgeWorldEdit.inst.getPermissionsProvider().registerPermission(command.getDescription().getPermissions().get(i));
}
Set<String> perms = command.getCondition().as(PermissionCondition.class)
.map(PermissionCondition::getPermissions)
.orElseGet(Collections::emptySet);
if (!perms.isEmpty()) {
perms.forEach(ForgeWorldEdit.inst.getPermissionsProvider()::registerPermission);
}
}
}
@ -189,7 +210,7 @@ class ForgePlatform extends AbstractPlatform implements MultiUserPlatform {
public Collection<Actor> getConnectedUsers() {
List<Actor> users = new ArrayList<>();
PlayerList scm = server.getPlayerList();
for (EntityPlayerMP entity : scm.getPlayers()) {
for (ServerPlayerEntity entity : scm.getPlayers()) {
if (entity != null) {
users.add(new ForgePlayer(entity));
}

View File

@ -19,6 +19,8 @@
package com.sk89q.worldedit.forge;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.util.StringUtil;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity;
@ -31,30 +33,42 @@ 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.util.formatting.WorldEditText;
import com.sk89q.worldedit.util.formatting.text.Component;
import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.util.formatting.text.serializer.gson.GsonComponentSerializer;
import com.sk89q.worldedit.world.World;
import com.sk89q.worldedit.world.block.BlockStateHolder;
import net.minecraft.entity.player.EntityPlayerMP;
import com.sk89q.worldedit.world.block.BlockTypes;
import net.minecraft.item.ItemStack;
import io.netty.buffer.Unpooled;
import net.minecraft.block.Block;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.play.server.SPacketCustomPayload;
import net.minecraft.util.EnumHand;
import net.minecraft.network.play.server.SChangeBlockPacket;
import net.minecraft.network.play.server.SCustomPayloadPlayPacket;
import net.minecraft.util.ResourceLocation;
import net.minecraft.network.play.server.SUpdateTileEntityPacket;
import net.minecraft.util.Hand;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.StringTextComponent;
import net.minecraft.util.text.TextFormatting;
import java.io.IOException;
import java.util.UUID;
import javax.annotation.Nullable;
import io.netty.buffer.Unpooled;
public class ForgePlayer extends AbstractPlayerActor {
private final EntityPlayerMP player;
// see ClientPlayNetHandler: search for "invalid update packet", lots of hardcoded consts
private static final int STRUCTURE_BLOCK_PACKET_ID = 7;
private final ServerPlayerEntity player;
protected ForgePlayer(EntityPlayerMP player) {
protected ForgePlayer(ServerPlayerEntity player) {
this.player = player;
ThreadSafeCache.getInstance().getOnlineIds().add(getUniqueId());
}
@ -66,7 +80,7 @@ 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);
ItemStack is = this.player.getHeldItem(handSide == HandSide.MAIN_HAND ? Hand.MAIN_HAND : Hand.OFF_HAND);
return ForgeAdapter.adapt(is);
}
@ -97,7 +111,7 @@ public class ForgePlayer extends AbstractPlayerActor {
}
@Override
public com.sk89q.worldedit.world.World getWorld() {
public World getWorld() {
return ForgeWorldEdit.inst.getWorld(this.player.world);
}
@ -114,14 +128,14 @@ 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(new ResourceLocation(ForgeWorldEdit.CUI_PLUGIN_CHANNEL), buffer);
SCustomPayloadPlayPacket packet = new SCustomPayloadPlayPacket(new ResourceLocation(ForgeWorldEdit.MOD_ID, ForgeWorldEdit.CUI_PLUGIN_CHANNEL), buffer);
this.player.connection.sendPacket(packet);
}
@Override
public void printRaw(String msg) {
for (String part : msg.split("\n")) {
this.player.sendMessage(new TextComponentString(part));
this.player.sendMessage(new StringTextComponent(part));
}
}
@ -140,9 +154,14 @@ public class ForgePlayer extends AbstractPlayerActor {
sendColorized(msg, TextFormatting.RED);
}
@Override
public void print(Component component) {
this.player.sendMessage(ITextComponent.Serializer.fromJson(GsonComponentSerializer.INSTANCE.serialize(WorldEditText.format(component))));
}
private void sendColorized(String msg, TextFormatting formatting) {
for (String part : msg.split("\n")) {
TextComponentString component = new TextComponentString(part);
StringTextComponent component = new StringTextComponent(part);
component.getStyle().setColor(formatting);
this.player.sendMessage(component);
}
@ -174,20 +193,50 @@ public class ForgePlayer extends AbstractPlayerActor {
return null;
}
@Override
public boolean isAllowedToFly() {
return player.abilities.allowFlying;
}
@Override
public void setFlying(boolean flying) {
if (player.abilities.isFlying != flying) {
player.abilities.isFlying = flying;
player.sendPlayerAbilities();
}
}
@Override
public <B extends BlockStateHolder<B>> void sendFakeBlock(BlockVector3 pos, B block) {
World world = getWorld();
if (!(world instanceof ForgeWorld)) {
return;
}
BlockPos loc = ForgeAdapter.toBlockPos(pos);
if (block == null) {
// TODO
// player.sendBlockChange(loc, player.getWorld().getBlockAt(loc).getBlockData());
final SChangeBlockPacket packetOut = new SChangeBlockPacket(((ForgeWorld) world).getWorld(), loc);
player.connection.sendPacket(packetOut);
} else {
// TODO
// player.sendBlockChange(loc, BukkitAdapter.adapt(block));
if (block instanceof BaseBlock && ((BaseBlock) block).hasNbtData()) {
player.connection.sendPacket(new SPacketUpdateTileEntity(
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()), 7,
NBTConverter.toNative(((BaseBlock) block).getNbtData()))
);
final SChangeBlockPacket packetOut = new SChangeBlockPacket();
PacketBuffer buf = new PacketBuffer(Unpooled.buffer());
buf.writeBlockPos(loc);
buf.writeVarInt(Block.getStateId(ForgeAdapter.adapt(block.toImmutableState())));
try {
packetOut.readPacketData(buf);
} catch (IOException e) {
return;
}
player.connection.sendPacket(packetOut);
if (block instanceof BaseBlock && block.getBlockType().equals(BlockTypes.STRUCTURE_BLOCK)) {
final BaseBlock baseBlock = (BaseBlock) block;
final CompoundTag nbtData = baseBlock.getNbtData();
if (nbtData != null) {
player.connection.sendPacket(new SUpdateTileEntityPacket(
new BlockPos(pos.getBlockX(), pos.getBlockY(), pos.getBlockZ()),
STRUCTURE_BLOCK_PACKET_ID,
NBTConverter.toNative(nbtData))
);
}
}
}
}

View File

@ -20,8 +20,10 @@
package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.world.registry.BiomeRegistry;
import com.sk89q.worldedit.world.registry.BlockCategoryRegistry;
import com.sk89q.worldedit.world.registry.BlockRegistry;
import com.sk89q.worldedit.world.registry.BundledRegistries;
import com.sk89q.worldedit.world.registry.ItemCategoryRegistry;
import com.sk89q.worldedit.world.registry.ItemRegistry;
/**
@ -33,6 +35,8 @@ class ForgeRegistries extends BundledRegistries {
private final BlockRegistry blockRegistry = new ForgeBlockRegistry();
private final BiomeRegistry biomeRegistry = new ForgeBiomeRegistry();
private final ItemRegistry itemRegistry = new ForgeItemRegistry();
private final BlockCategoryRegistry blockCategoryRegistry = new ForgeBlockCategoryRegistry();
private final ItemCategoryRegistry itemCategoryRegistry = new ForgeItemCategoryRegistry();
@Override
public BlockRegistry getBlockRegistry() {
@ -49,6 +53,16 @@ class ForgeRegistries extends BundledRegistries {
return itemRegistry;
}
@Override
public BlockCategoryRegistry getBlockCategoryRegistry() {
return blockCategoryRegistry;
}
@Override
public ItemCategoryRegistry getItemCategoryRegistry() {
return itemCategoryRegistry;
}
/**
* Get a static instance.
*

View File

@ -19,7 +19,10 @@
package com.sk89q.worldedit.forge;
import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.io.Files;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession;
@ -30,9 +33,11 @@ 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.internal.block.BlockStateIdAccess;
import com.sk89q.worldedit.math.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location;
@ -45,29 +50,36 @@ import com.sk89q.worldedit.world.block.BlockStateHolder;
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.BlockLeaves;
import net.minecraft.block.state.IBlockState;
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.block.Block;
import net.minecraft.block.Blocks;
import net.minecraft.block.LeavesBlock;
import net.minecraft.entity.item.ItemEntity;
import net.minecraft.item.ItemStack;
import net.minecraft.inventory.IClearable;
import net.minecraft.item.ItemUseContext;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumActionResult;
import net.minecraft.util.ResourceLocation;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.server.MinecraftServer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.ActionResultType;
import net.minecraft.util.Hand;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import net.minecraft.util.math.BlockRayTraceResult;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.AbstractChunkProvider;
import net.minecraft.world.gen.feature.BigBrownMushroomFeature;
import net.minecraft.world.chunk.ChunkStatus;
import net.minecraft.world.chunk.IChunk;
import net.minecraft.world.chunk.listener.IChunkStatusListener;
import net.minecraft.world.gen.feature.BigRedMushroomFeature;
import net.minecraft.world.gen.feature.BigMushroomFeatureConfig;
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.DarkOakTreeFeature;
import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.IFeatureConfig;
import net.minecraft.world.gen.feature.JungleTreeFeature;
import net.minecraft.world.gen.feature.MegaJungleFeature;
import net.minecraft.world.gen.feature.MegaPineTree;
@ -81,12 +93,25 @@ import net.minecraft.world.gen.feature.TreeFeature;
import net.minecraft.world.storage.WorldInfo;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.concurrent.ThreadLocalRandom;
import net.minecraft.world.server.ServerChunkProvider;
import net.minecraft.world.server.ServerWorld;
import net.minecraft.world.storage.SaveHandler;
import net.minecraftforge.common.DimensionManager;
import javax.annotation.Nullable;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Random;
import java.util.Optional;
import java.util.OptionalInt;
import java.util.concurrent.ThreadLocalRandom;
import java.util.concurrent.ExecutionException;
import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
/**
* An adapter to Minecraft worlds for WorldEdit.
@ -96,9 +121,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.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 static final net.minecraft.block.BlockState JUNGLE_LOG = Blocks.JUNGLE_LOG.getDefaultState();
private static final net.minecraft.block.BlockState JUNGLE_LEAF = Blocks.JUNGLE_LEAVES.getDefaultState().with(LeavesBlock.PERSISTENT, Boolean.TRUE);
private static final net.minecraft.block.BlockState JUNGLE_SHRUB = Blocks.OAK_LEAVES.getDefaultState().with(LeavesBlock.PERSISTENT, Boolean.TRUE);
private final WeakReference<World> worldRef;
@ -147,6 +172,20 @@ public class ForgeWorld extends AbstractWorld {
return getWorld().getWorldInfo().getWorldName();
}
@Override
public String getId() {
return DimensionManager.getRegistry().getKey(getWorld().dimension.getType()).toString();
}
@Override
public Path getStoragePath() {
final World world = getWorld();
if (world instanceof ServerWorld) {
return ((ServerWorld) world).getSaveHandler().getWorldDirectory().toPath();
}
return null;
}
@Override
public <B extends BlockStateHolder<B>> boolean setBlock(BlockVector3 position, B block, boolean notifyAndLight) throws WorldEditException {
checkNotNull(position);
@ -160,9 +199,10 @@ public class ForgeWorld extends AbstractWorld {
// First set the block
Chunk chunk = world.getChunk(x >> 4, z >> 4);
BlockPos pos = new BlockPos(x, y, z);
IBlockState old = chunk.getBlockState(pos);
IBlockState newState = ForgeAdapter.adapt(block.toImmutableState());
IBlockState successState = chunk.setBlockState(pos, newState, false);
net.minecraft.block.BlockState old = chunk.getBlockState(pos);
OptionalInt stateId = BlockStateIdAccess.getBlockStateId(block.toImmutableState());
net.minecraft.block.BlockState newState = stateId.isPresent() ? Block.getStateById(stateId.getAsInt()) : ForgeAdapter.adapt(block.toImmutableState());
net.minecraft.block.BlockState successState = chunk.setBlockState(pos, newState, false);
boolean successful = successState != null;
// Create the TileEntity
@ -170,15 +210,16 @@ public class ForgeWorld extends AbstractWorld {
if (block instanceof BaseBlock) {
CompoundTag tag = ((BaseBlock) block).getNbtData();
if (tag != null) {
NBTTagCompound nativeTag = NBTConverter.toNative(tag);
CompoundNBT nativeTag = NBTConverter.toNative(tag);
nativeTag.putString("id", ((BaseBlock) block).getNbtId());
TileEntityUtils.setTileEntity(world, position, nativeTag);
successful = true; // update if TE changed as well
}
}
}
if (successful && notifyAndLight) {
//world.checkLight(pos);
world.getChunkProvider().getLightManager().checkBlock(pos);
world.markAndNotifyBlock(pos, chunk, old, newState, UPDATE | NOTIFY);
}
@ -202,12 +243,8 @@ public class ForgeWorld extends AbstractWorld {
public boolean clearContainerBlockContents(BlockVector3 position) {
checkNotNull(position);
TileEntity tile = getWorld().getTileEntity(ForgeAdapter.toBlockPos(position));
if ((tile instanceof IInventory)) {
IInventory inv = (IInventory) tile;
int size = inv.getSizeInventory();
for (int i = 0; i < size; i++) {
inv.setInventorySlotContents(i, ItemStack.EMPTY);
}
if (tile instanceof IClearable) {
((IClearable) tile).clear();
return true;
}
return false;
@ -224,36 +261,45 @@ public class ForgeWorld extends AbstractWorld {
checkNotNull(position);
checkNotNull(biome);
Chunk chunk = getWorld().getChunk(new BlockPos(position.getBlockX(), 0, position.getBlockZ()));
if (chunk.isLoaded()) {
chunk.getBiomes()[((position.getBlockZ() & 0xF) << 4 | position.getBlockX() & 0xF)] = ForgeAdapter.adapt(biome);
return true;
IChunk chunk = getWorld().getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4, ChunkStatus.FULL, false);
if (chunk == null) {
return false;
}
return false;
chunk.getBiomes()[((position.getBlockZ() & 0xF) << 4 | position.getBlockX() & 0xF)] = ForgeAdapter.adapt(biome);
chunk.setModified(true);
return true;
}
private static LoadingCache<ServerWorld, WorldEditFakePlayer> fakePlayers
= CacheBuilder.newBuilder().weakKeys().softValues().build(CacheLoader.from(WorldEditFakePlayer::new));
@Override
public boolean useItem(BlockVector3 position, BaseItem item, Direction face) {
Item nativeItem = ForgeAdapter.adapt(item.getType());
ItemStack stack;
if (item.getNbtData() == null) {
stack = new ItemStack(nativeItem, 1);
} else {
stack = new ItemStack(nativeItem, 1, NBTConverter.toNative(item.getNbtData()));
ItemStack stack = ForgeAdapter.adapt(new BaseItemStack(item.getType(), item.getNbtData(), 1));
ServerWorld world = (ServerWorld) getWorld();
final WorldEditFakePlayer fakePlayer;
try {
fakePlayer = fakePlayers.get(world);
} catch (ExecutionException ignored) {
return false;
}
World world = getWorld();
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;
fakePlayer.setHeldItem(Hand.MAIN_HAND, stack);
fakePlayer.setLocationAndAngles(position.getBlockX(), position.getBlockY(), position.getBlockZ(),
(float) face.toVector().toYaw(), (float) face.toVector().toPitch());
final BlockPos blockPos = ForgeAdapter.toBlockPos(position);
final BlockRayTraceResult rayTraceResult = new BlockRayTraceResult(ForgeAdapter.toVec3(position),
ForgeAdapter.adapt(face), blockPos, false);
ItemUseContext itemUseContext = new ItemUseContext(fakePlayer, Hand.MAIN_HAND, rayTraceResult);
ActionResultType used = stack.onItemUse(itemUseContext);
if (used != ActionResultType.SUCCESS) {
// try activating the block
if (getWorld().getBlockState(blockPos).onBlockActivated(world, fakePlayer, Hand.MAIN_HAND, rayTraceResult)) {
used = ActionResultType.SUCCESS;
} else {
used = stack.getItem().onItemRightClick(world, fakePlayer, Hand.MAIN_HAND).getType();
}
}
return used == ActionResultType.SUCCESS;
}
@Override
@ -265,94 +311,100 @@ public class ForgeWorld extends AbstractWorld {
return;
}
EntityItem entity = new EntityItem(getWorld(), position.getX(), position.getY(), position.getZ(), ForgeAdapter.adapt(item));
ItemEntity entity = new ItemEntity(getWorld(), position.getX(), position.getY(), position.getZ(), ForgeAdapter.adapt(item));
entity.setPickupDelay(10);
getWorld().spawnEntity(entity);
getWorld().addEntity(entity);
}
@Override
public void simulateBlockMine(BlockVector3 position) {
BlockPos pos = ForgeAdapter.toBlockPos(position);
IBlockState state = getWorld().getBlockState(pos);
state.dropBlockAsItem(getWorld(), pos, 0);
getWorld().removeBlock(pos);
getWorld().destroyBlock(pos, true);
}
@Override
public boolean regenerate(Region region, EditSession editSession) {
// 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;
// Don't even try to regen if it's going to fail.
AbstractChunkProvider provider = getWorld().getChunkProvider();
if (!(provider instanceof ServerChunkProvider)) {
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();
try {
ServerWorld originalWorld = (ServerWorld) getWorld();
MinecraftServer server = originalWorld.getServer();
SaveHandler saveHandler = new SaveHandler(saveFolder, originalWorld.getSaveHandler().getWorldDirectory().getName(), server, server.getDataFixer());
try (World freshWorld = new ServerWorld(server, server.getBackgroundExecutor(), saveHandler, originalWorld.getWorldInfo(),
originalWorld.dimension.getType(), originalWorld.getProfiler(), new NoOpChunkStatusListener())) {
// 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);
for (BlockVector3 vec : region) {
editSession.setBlock(vec, from.getFullBlock(vec));
}
} catch (IOException e) {
throw new RuntimeException(e);
}
} catch (MaxChangedBlocksException e) {
throw new RuntimeException(e);
} finally {
saveFolder.delete();
}
return true;
}
@Nullable
private static Feature<NoFeatureConfig> createTreeFeatureGenerator(TreeType type) {
private static Feature<? extends IFeatureConfig> createTreeFeatureGenerator(TreeType type) {
switch (type) {
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 TREE: return new TreeFeature(NoFeatureConfig::deserialize, true);
case BIG_TREE: return new BigTreeFeature(NoFeatureConfig::deserialize, true);
case REDWOOD: return new PointyTaigaTreeFeature(NoFeatureConfig::deserialize);
case TALL_REDWOOD: return new TallTaigaTreeFeature(NoFeatureConfig::deserialize, true);
case BIRCH: return new BirchTreeFeature(NoFeatureConfig::deserialize, true, false);
case JUNGLE: return new MegaJungleFeature(NoFeatureConfig::deserialize, true, 10, 20, JUNGLE_LOG, JUNGLE_LEAF);
case SMALL_JUNGLE: return new JungleTreeFeature(NoFeatureConfig::deserialize, true, 4 + random.nextInt(7), JUNGLE_LOG, JUNGLE_LEAF, false);
case SHORT_JUNGLE: return new JungleTreeFeature(NoFeatureConfig::deserialize, true, 4 + random.nextInt(7), JUNGLE_LOG, JUNGLE_LEAF, true);
case JUNGLE_BUSH: return new ShrubFeature(NoFeatureConfig::deserialize, JUNGLE_LOG, JUNGLE_SHRUB);
case SWAMP: return new SwampTreeFeature(NoFeatureConfig::deserialize);
case ACACIA: return new SavannaTreeFeature(NoFeatureConfig::deserialize, true);
case DARK_OAK: return new DarkOakTreeFeature(NoFeatureConfig::deserialize, true);
case MEGA_REDWOOD: return new MegaPineTree(NoFeatureConfig::deserialize, true, random.nextBoolean());
case TALL_BIRCH: return new BirchTreeFeature(NoFeatureConfig::deserialize, true, true);
case RED_MUSHROOM: return new BigRedMushroomFeature(BigMushroomFeatureConfig::deserialize);
case BROWN_MUSHROOM: return new BigBrownMushroomFeature(BigMushroomFeatureConfig::deserialize);
case RANDOM: return createTreeFeatureGenerator(TreeType.values()[ThreadLocalRandom.current().nextInt(TreeType.values().length)]);
case RANDOM_REDWOOD:
default:
return null;
}
}
private IFeatureConfig createFeatureConfig(TreeType type) {
if (type == TreeType.RED_MUSHROOM || type == TreeType.BROWN_MUSHROOM) {
return new BigMushroomFeatureConfig(true);
} else {
return new NoFeatureConfig();
}
}
@Override
public boolean generateTree(TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException {
Feature<NoFeatureConfig> generator = createTreeFeatureGenerator(type);
return generator != null && generator.place(getWorld(), getWorld().getChunkProvider().getChunkGenerator(), random, ForgeAdapter.toBlockPos(position), new NoFeatureConfig());
@SuppressWarnings("unchecked")
Feature<IFeatureConfig> generator = (Feature<IFeatureConfig>) createTreeFeatureGenerator(type);
return generator != null
&& generator.place(getWorld(), getWorld().getChunkProvider().getChunkGenerator(), random,
ForgeAdapter.toBlockPos(position), createFeatureConfig(type));
}
@Override
@ -369,7 +421,7 @@ public class ForgeWorld extends AbstractWorld {
public void fixLighting(Iterable<BlockVector2> chunks) {
World world = getWorld();
for (BlockVector2 chunk : chunks) {
world.getChunk(chunk.getBlockX(), chunk.getBlockZ()).resetRelightChecks();
world.getChunkProvider().getLightManager().func_215571_a(new ChunkPos(chunk.getBlockX(), chunk.getBlockZ()), true);
}
}
@ -432,20 +484,14 @@ public class ForgeWorld extends AbstractWorld {
}
@Override
public BlockState getBlock(BlockVector3 position) {
IBlockState mcState = getWorld().getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).getBlockState(
position.getBlockX(),
position.getBlockY(),
position.getBlockZ()
);
return ForgeAdapter.adapt(mcState);
public int getMaxY() {
return getWorld().getMaxHeight() - 1;
}
@Override
public BaseBlock getFullBlock(BlockVector3 position) {
BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ());
TileEntity tile = getWorld().getTileEntity(pos);
TileEntity tile = getWorld().getChunk(pos).getTileEntity(pos);
if (tile != null) {
return getBlock(position).toBaseBlock(NBTConverter.fromNative(TileEntityUtils.copyNbtData(tile)));
@ -454,6 +500,20 @@ public class ForgeWorld extends AbstractWorld {
}
}
@Override
public BlockState getBlock(BlockVector3 position) {
net.minecraft.block.BlockState mcState = getWorld()
.getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4)
.getBlockState(ForgeAdapter.toBlockPos(position));
BlockState matchingBlock = BlockStateIdAccess.getBlockStateById(Block.getStateId(mcState));
if (matchingBlock != null) {
return matchingBlock;
}
return ForgeAdapter.adapt(mcState);
}
@Override
public int hashCode() {
return getWorld().hashCode();
@ -477,33 +537,34 @@ public class ForgeWorld extends AbstractWorld {
@Override
public List<? extends Entity> getEntities(Region region) {
List<Entity> entities = new ArrayList<>();
for (net.minecraft.entity.Entity entity : getWorld().loadedEntityList) {
if (region.contains(BlockVector3.at(entity.posX, entity.posY, entity.posZ))) {
entities.add(new ForgeEntity(entity));
}
final World world = getWorld();
if (!(world instanceof ServerWorld)) {
return Collections.emptyList();
}
return entities;
return ((ServerWorld) world).getEntities().filter(e -> region.contains(ForgeAdapter.adapt(e.getPosition())))
.map(ForgeEntity::new).collect(Collectors.toList());
}
@Override
public List<? extends Entity> getEntities() {
List<Entity> entities = new ArrayList<>();
for (net.minecraft.entity.Entity entity : getWorld().loadedEntityList) {
entities.add(new ForgeEntity(entity));
final World world = getWorld();
if (!(world instanceof ServerWorld)) {
return Collections.emptyList();
}
return entities;
return ((ServerWorld) world).getEntities().map(ForgeEntity::new).collect(Collectors.toList());
}
@Nullable
@Override
public Entity createEntity(Location location, BaseEntity entity) {
World world = getWorld();
net.minecraft.entity.Entity createdEntity = EntityType.create(world, new ResourceLocation(entity.getType().getId()));
final Optional<EntityType<?>> entityType = EntityType.byKey(entity.getType().getId());
if (!entityType.isPresent()) return null;
net.minecraft.entity.Entity createdEntity = entityType.get().create(world);
if (createdEntity != null) {
CompoundTag nativeTag = entity.getNbtData();
if (nativeTag != null) {
NBTTagCompound tag = NBTConverter.toNative(entity.getNbtData());
CompoundNBT tag = NBTConverter.toNative(entity.getNbtData());
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) {
tag.remove(name);
}
@ -512,7 +573,7 @@ public class ForgeWorld extends AbstractWorld {
createdEntity.setLocationAndAngles(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());
world.spawnEntity(createdEntity);
world.addEntity(createdEntity);
return new ForgeEntity(createdEntity);
} else {
return null;
@ -523,10 +584,23 @@ public class ForgeWorld extends AbstractWorld {
* Thrown when the reference to the world is lost.
*/
@SuppressWarnings("serial")
private static class WorldReferenceLostException extends WorldEditException {
private static final class WorldReferenceLostException extends WorldEditException {
private WorldReferenceLostException(String message) {
super(message);
}
}
private static class NoOpChunkStatusListener implements IChunkStatusListener {
@Override
public void start(ChunkPos chunkPos) {
}
@Override
public void statusChanged(ChunkPos chunkPos, @Nullable ChunkStatus chunkStatus) {
}
@Override
public void stop() {
}
}
}

View File

@ -19,9 +19,6 @@
package com.sk89q.worldedit.forge;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.forge.ForgeAdapter.adaptPlayer;
import com.mojang.brigadier.ParseResults;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.sk89q.worldedit.LocalSession;
@ -34,6 +31,7 @@ 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.internal.anvil.ChunkDeleter;
import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.world.biome.BiomeType;
import com.sk89q.worldedit.world.block.BlockCategory;
@ -41,14 +39,13 @@ import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.entity.EntityType;
import com.sk89q.worldedit.world.item.ItemCategory;
import com.sk89q.worldedit.world.item.ItemType;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.command.CommandSource;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.tags.BlockTags;
import net.minecraft.tags.ItemTags;
import net.minecraft.util.Hand;
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;
@ -61,12 +58,10 @@ import net.minecraftforge.fml.ModContainer;
import net.minecraftforge.fml.ModLoadingContext;
import net.minecraftforge.fml.common.Mod;
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;
@ -77,6 +72,10 @@ import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Files;
import java.nio.file.Path;
import static com.sk89q.worldedit.internal.anvil.ChunkDeleter.DELCHUNKS_FILE_NAME;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.sk89q.worldedit.forge.ForgeAdapter.adaptPlayer;
/**
* The Forge implementation of WorldEdit.
@ -105,7 +104,6 @@ public class ForgeWorldEdit {
IEventBus modBus = FMLJavaModLoadingContext.get().getModEventBus();
modBus.addListener(this::init);
modBus.addListener(this::load);
MinecraftForge.EVENT_BUS.register(ThreadSafeCache.getInstance());
MinecraftForge.EVENT_BUS.register(this);
@ -131,24 +129,6 @@ public class ForgeWorldEdit {
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);
}
}
@SubscribeEvent
public void serverAboutToStart(FMLServerAboutToStartEvent event) {
if (this.platform != null) {
LOGGER.warn("FMLServerStartingEvent occurred when FMLServerStoppingEvent hasn't");
WorldEdit.getInstance().getPlatformManager().unregister(platform);
}
setupPlatform();
}
private void setupPlatform() {
this.platform = new ForgePlatform(this);
@ -159,11 +139,6 @@ public class ForgeWorldEdit {
// } else {
this.provider = new ForgePermissionsProvider.VanillaPermissionsProvider(platform);
// }
setupRegistries();
config = new ForgeConfiguration(this);
config.load();
}
private void setupRegistries() {
@ -205,6 +180,14 @@ public class ForgeWorldEdit {
}
}
@SubscribeEvent
public void serverAboutToStart(FMLServerAboutToStartEvent event) {
final Path delChunks = workingDir.resolve(DELCHUNKS_FILE_NAME);
if (Files.exists(delChunks)) {
ChunkDeleter.runFromFile(delChunks, true);
}
}
@SubscribeEvent
public void serverStopping(FMLServerStoppingEvent event) {
WorldEdit.getInstance().getPlatformManager().unregister(platform);
@ -212,6 +195,11 @@ public class ForgeWorldEdit {
@SubscribeEvent
public void serverStarted(FMLServerStartedEvent event) {
setupPlatform();
setupRegistries();
config = new ForgeConfiguration(this);
config.load();
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent());
}
@ -226,10 +214,10 @@ public class ForgeWorldEdit {
if (event.getWorld().isRemote && event instanceof LeftClickEmpty) {
// catch LCE, pass it to server
InternalPacketHandler.HANDLER.sendToServer(new LeftClickAirEventMessage());
InternalPacketHandler.getHandler().sendToServer(new LeftClickAirEventMessage());
return;
}
boolean isLeftDeny = event instanceof PlayerInteractEvent.LeftClickBlock
&& ((PlayerInteractEvent.LeftClickBlock) event)
.getUseItem() == Event.Result.DENY;
@ -237,19 +225,16 @@ public class ForgeWorldEdit {
event instanceof PlayerInteractEvent.RightClickBlock
&& ((PlayerInteractEvent.RightClickBlock) event)
.getUseItem() == Event.Result.DENY;
if (isLeftDeny || isRightDeny || event.getEntity().world.isRemote) {
if (isLeftDeny || isRightDeny || event.getEntity().world.isRemote || event.getHand() == Hand.OFF_HAND) {
return;
}
WorldEdit we = WorldEdit.getInstance();
ForgePlayer player = adaptPlayer((EntityPlayerMP) event.getEntityPlayer());
ForgeWorld world = getWorld(event.getEntityPlayer().world);
ForgePlayer player = adaptPlayer((ServerPlayerEntity) event.getPlayer());
ForgeWorld world = getWorld(event.getPlayer().world);
if (event instanceof PlayerInteractEvent.LeftClickEmpty) {
if (we.handleArmSwing(player)) {
// this event cannot be canceled
// event.setCanceled(true);
}
we.handleArmSwing(player); // this event cannot be canceled
} else if (event instanceof PlayerInteractEvent.LeftClickBlock) {
Location pos = new Location(world, event.getPos().getX(), event.getPos().getY(), event.getPos().getZ());
@ -280,10 +265,10 @@ public class ForgeWorldEdit {
@SubscribeEvent
public void onCommandEvent(CommandEvent event) throws CommandSyntaxException {
ParseResults<CommandSource> parseResults = event.getParseResults();
if (!(parseResults.getContext().getSource().getEntity() instanceof EntityPlayerMP)) {
if (!(parseResults.getContext().getSource().getEntity() instanceof ServerPlayerEntity)) {
return;
}
EntityPlayerMP player = parseResults.getContext().getSource().asPlayer();
ServerPlayerEntity player = parseResults.getContext().getSource().asPlayer();
if (player.world.isRemote()) {
return;
}
@ -312,7 +297,7 @@ public class ForgeWorldEdit {
* @param player the player
* @return the session
*/
public LocalSession getSession(EntityPlayerMP player) {
public LocalSession getSession(ServerPlayerEntity player) {
checkNotNull(player);
return WorldEdit.getInstance().getSessionManager().get(adaptPlayer(player));
}

View File

@ -22,9 +22,10 @@ package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.forge.gui.GuiReferenceCard;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.util.text.StringTextComponent;
import net.minecraftforge.client.event.InputEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.gameevent.InputEvent.KeyInputEvent;
import org.lwjgl.glfw.GLFW;
public class KeyHandler {
@ -37,11 +38,9 @@ public class KeyHandler {
}
@SubscribeEvent
public void onKey(KeyInputEvent evt) {
public void onKey(InputEvent.KeyInputEvent evt) {
if (mc.player != null && mc.world != null && mainKey.isPressed()) {
mc.displayGuiScreen(new GuiReferenceCard());
// TODO Seems GuiHandlers don't work on client right now
// NetworkHooks.openGui(mc.player, new ResourceLocationInteractionObject(ServerProxy.REFERENCE_GUI));
mc.displayGuiScreen(new GuiReferenceCard(new StringTextComponent("WorldEdit Reference")));
}
}

View File

@ -32,19 +32,19 @@ import com.sk89q.jnbt.LongTag;
import com.sk89q.jnbt.ShortTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import net.minecraft.nbt.INBTBase;
import net.minecraft.nbt.NBTTagByte;
import net.minecraft.nbt.NBTTagByteArray;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagDouble;
import net.minecraft.nbt.NBTTagEnd;
import net.minecraft.nbt.NBTTagFloat;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.nbt.NBTTagIntArray;
import net.minecraft.nbt.NBTTagList;
import net.minecraft.nbt.NBTTagLong;
import net.minecraft.nbt.NBTTagShort;
import net.minecraft.nbt.NBTTagString;
import net.minecraft.nbt.ByteArrayNBT;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.DoubleNBT;
import net.minecraft.nbt.INBT;
import net.minecraft.nbt.ByteNBT;
import net.minecraft.nbt.EndNBT;
import net.minecraft.nbt.FloatNBT;
import net.minecraft.nbt.IntArrayNBT;
import net.minecraft.nbt.IntNBT;
import net.minecraft.nbt.ListNBT;
import net.minecraft.nbt.LongNBT;
import net.minecraft.nbt.StringNBT;
import net.minecraft.nbt.ShortNBT;
import java.util.ArrayList;
import java.util.Arrays;
@ -62,7 +62,7 @@ final class NBTConverter {
private NBTConverter() {
}
public static INBTBase toNative(Tag tag) {
public static INBT toNative(Tag tag) {
if (tag instanceof IntArrayTag) {
return toNative((IntArrayTag) tag);
@ -100,13 +100,13 @@ final class NBTConverter {
}
}
public static NBTTagIntArray toNative(IntArrayTag tag) {
public static IntArrayNBT toNative(IntArrayTag tag) {
int[] value = tag.getValue();
return new NBTTagIntArray(Arrays.copyOf(value, value.length));
return new IntArrayNBT(Arrays.copyOf(value, value.length));
}
public static NBTTagList toNative(ListTag tag) {
NBTTagList list = new NBTTagList();
public static ListNBT toNative(ListTag tag) {
ListNBT list = new ListNBT();
for (Tag child : tag.getValue()) {
if (child instanceof EndTag) {
continue;
@ -116,94 +116,94 @@ final class NBTConverter {
return list;
}
public static NBTTagLong toNative(LongTag tag) {
return new NBTTagLong(tag.getValue());
public static LongNBT toNative(LongTag tag) {
return new LongNBT(tag.getValue());
}
public static NBTTagString toNative(StringTag tag) {
return new NBTTagString(tag.getValue());
public static StringNBT toNative(StringTag tag) {
return new StringNBT(tag.getValue());
}
public static NBTTagInt toNative(IntTag tag) {
return new NBTTagInt(tag.getValue());
public static IntNBT toNative(IntTag tag) {
return new IntNBT(tag.getValue());
}
public static NBTTagByte toNative(ByteTag tag) {
return new NBTTagByte(tag.getValue());
public static ByteNBT toNative(ByteTag tag) {
return new ByteNBT(tag.getValue());
}
public static NBTTagByteArray toNative(ByteArrayTag tag) {
public static ByteArrayNBT toNative(ByteArrayTag tag) {
byte[] value = tag.getValue();
return new NBTTagByteArray(Arrays.copyOf(value, value.length));
return new ByteArrayNBT(Arrays.copyOf(value, value.length));
}
public static NBTTagCompound toNative(CompoundTag tag) {
NBTTagCompound compound = new NBTTagCompound();
public static CompoundNBT toNative(CompoundTag tag) {
CompoundNBT compound = new CompoundNBT();
for (Entry<String, Tag> child : tag.getValue().entrySet()) {
compound.put(child.getKey(), toNative(child.getValue()));
}
return compound;
}
public static NBTTagFloat toNative(FloatTag tag) {
return new NBTTagFloat(tag.getValue());
public static FloatNBT toNative(FloatTag tag) {
return new FloatNBT(tag.getValue());
}
public static NBTTagShort toNative(ShortTag tag) {
return new NBTTagShort(tag.getValue());
public static ShortNBT toNative(ShortTag tag) {
return new ShortNBT(tag.getValue());
}
public static NBTTagDouble toNative(DoubleTag tag) {
return new NBTTagDouble(tag.getValue());
public static DoubleNBT toNative(DoubleTag tag) {
return new DoubleNBT(tag.getValue());
}
public static Tag fromNative(INBTBase other) {
if (other instanceof NBTTagIntArray) {
return fromNative((NBTTagIntArray) other);
public static Tag fromNative(INBT other) {
if (other instanceof IntArrayNBT) {
return fromNative((IntArrayNBT) other);
} else if (other instanceof NBTTagList) {
return fromNative((NBTTagList) other);
} else if (other instanceof ListNBT) {
return fromNative((ListNBT) other);
} else if (other instanceof NBTTagEnd) {
return fromNative((NBTTagEnd) other);
} else if (other instanceof EndNBT) {
return fromNative((EndNBT) other);
} else if (other instanceof NBTTagLong) {
return fromNative((NBTTagLong) other);
} else if (other instanceof LongNBT) {
return fromNative((LongNBT) other);
} else if (other instanceof NBTTagString) {
return fromNative((NBTTagString) other);
} else if (other instanceof StringNBT) {
return fromNative((StringNBT) other);
} else if (other instanceof NBTTagInt) {
return fromNative((NBTTagInt) other);
} else if (other instanceof IntNBT) {
return fromNative((IntNBT) other);
} else if (other instanceof NBTTagByte) {
return fromNative((NBTTagByte) other);
} else if (other instanceof ByteNBT) {
return fromNative((ByteNBT) other);
} else if (other instanceof NBTTagByteArray) {
return fromNative((NBTTagByteArray) other);
} else if (other instanceof ByteArrayNBT) {
return fromNative((ByteArrayNBT) other);
} else if (other instanceof NBTTagCompound) {
return fromNative((NBTTagCompound) other);
} else if (other instanceof CompoundNBT) {
return fromNative((CompoundNBT) other);
} else if (other instanceof NBTTagFloat) {
return fromNative((NBTTagFloat) other);
} else if (other instanceof FloatNBT) {
return fromNative((FloatNBT) other);
} else if (other instanceof NBTTagShort) {
return fromNative((NBTTagShort) other);
} else if (other instanceof ShortNBT) {
return fromNative((ShortNBT) other);
} else if (other instanceof NBTTagDouble) {
return fromNative((NBTTagDouble) other);
} else if (other instanceof DoubleNBT) {
return fromNative((DoubleNBT) other);
} else {
throw new IllegalArgumentException("Can't convert other of type " + other.getClass().getCanonicalName());
}
}
public static IntArrayTag fromNative(NBTTagIntArray other) {
public static IntArrayTag fromNative(IntArrayNBT other) {
int[] value = other.getIntArray();
return new IntArrayTag(Arrays.copyOf(value, value.length));
}
public static ListTag fromNative(NBTTagList other) {
public static ListTag fromNative(ListNBT other) {
other = other.copy();
List<Tag> list = new ArrayList<>();
Class<? extends Tag> listClass = StringTag.class;
@ -216,32 +216,32 @@ final class NBTConverter {
return new ListTag(listClass, list);
}
public static EndTag fromNative(NBTTagEnd other) {
public static EndTag fromNative(EndNBT other) {
return new EndTag();
}
public static LongTag fromNative(NBTTagLong other) {
public static LongTag fromNative(LongNBT other) {
return new LongTag(other.getLong());
}
public static StringTag fromNative(NBTTagString other) {
public static StringTag fromNative(StringNBT other) {
return new StringTag(other.getString());
}
public static IntTag fromNative(NBTTagInt other) {
public static IntTag fromNative(IntNBT other) {
return new IntTag(other.getInt());
}
public static ByteTag fromNative(NBTTagByte other) {
public static ByteTag fromNative(ByteNBT other) {
return new ByteTag(other.getByte());
}
public static ByteArrayTag fromNative(NBTTagByteArray other) {
public static ByteArrayTag fromNative(ByteArrayNBT other) {
byte[] value = other.getByteArray();
return new ByteArrayTag(Arrays.copyOf(value, value.length));
}
public static CompoundTag fromNative(NBTTagCompound other) {
public static CompoundTag fromNative(CompoundNBT other) {
Set<String> tags = other.keySet();
Map<String, Tag> map = new HashMap<>();
for (String tagName : tags) {
@ -250,15 +250,15 @@ final class NBTConverter {
return new CompoundTag(map);
}
public static FloatTag fromNative(NBTTagFloat other) {
public static FloatTag fromNative(FloatNBT other) {
return new FloatTag(other.getFloat());
}
public static ShortTag fromNative(NBTTagShort other) {
public static ShortTag fromNative(ShortNBT other) {
return new ShortTag(other.getShort());
}
public static DoubleTag fromNative(NBTTagDouble other) {
public static DoubleTag fromNative(DoubleNBT other) {
return new DoubleTag(other.getDouble());
}

View File

@ -19,10 +19,10 @@
package com.sk89q.worldedit.forge;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.entity.player.ServerPlayerEntity;
import net.minecraft.server.MinecraftServer;
import net.minecraftforge.event.TickEvent;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.TickEvent;
import net.minecraftforge.fml.server.ServerLifecycleHooks;
import java.util.Collections;
@ -56,12 +56,12 @@ public class ThreadSafeCache {
if (now - lastRefresh > REFRESH_DELAY) {
Set<UUID> onlineIds = new HashSet<>();
MinecraftServer server = ServerLifecycleHooks.getCurrentServer();
if (server == null || server.getPlayerList() == null) {
if (server == null) {
return;
}
for (EntityPlayerMP player : server.getPlayerList().getPlayers()) {
for (ServerPlayerEntity player : server.getPlayerList().getPlayers()) {
if (player != null) {
onlineIds.add(player.getUniqueID());
}

View File

@ -23,8 +23,8 @@ import static com.google.common.base.Preconditions.checkNotNull;
import com.sk89q.worldedit.math.BlockVector3;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.nbt.NBTTagInt;
import net.minecraft.nbt.CompoundNBT;
import net.minecraft.nbt.IntNBT;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World;
@ -45,13 +45,13 @@ final class TileEntityUtils {
* @param tag the tag
* @param position the position
*/
private static void updateForSet(NBTTagCompound tag, BlockVector3 position) {
private static void updateForSet(CompoundNBT tag, BlockVector3 position) {
checkNotNull(tag);
checkNotNull(position);
tag.put("x", new NBTTagInt(position.getBlockX()));
tag.put("y", new NBTTagInt(position.getBlockY()));
tag.put("z", new NBTTagInt(position.getBlockZ()));
tag.put("x", new IntNBT(position.getBlockX()));
tag.put("y", new IntNBT(position.getBlockY()));
tag.put("z", new IntNBT(position.getBlockZ()));
}
/**
@ -62,7 +62,7 @@ final class TileEntityUtils {
* @param position the position
* @param tag the tag for the tile entity (may be null to do nothing)
*/
static void setTileEntity(World world, BlockVector3 position, @Nullable NBTTagCompound tag) {
static void setTileEntity(World world, BlockVector3 position, @Nullable CompoundNBT tag) {
if (tag != null) {
updateForSet(tag, position);
TileEntity tileEntity = TileEntity.create(tag);
@ -72,8 +72,8 @@ final class TileEntityUtils {
}
}
public static NBTTagCompound copyNbtData(TileEntity tile) {
NBTTagCompound tag = new NBTTagCompound();
public static CompoundNBT copyNbtData(TileEntity tile) {
CompoundNBT tag = new CompoundNBT();
tile.write(tag);
return tag;
}

View File

@ -20,17 +20,29 @@
package com.sk89q.worldedit.forge;
import com.mojang.authlib.GameProfile;
import net.minecraft.world.WorldServer;
import net.minecraft.inventory.container.INamedContainerProvider;
import net.minecraft.world.server.ServerWorld;
import net.minecraftforge.common.util.FakePlayer;
import javax.annotation.Nullable;
import java.util.OptionalInt;
import java.util.UUID;
public class WorldEditFakePlayer extends FakePlayer {
private static final GameProfile FAKE_GAME_PROFILE = new GameProfile(UUID.nameUUIDFromBytes("worldedit".getBytes()), "[WorldEdit]");
public WorldEditFakePlayer(WorldServer world) {
public WorldEditFakePlayer(ServerWorld world) {
super(world, FAKE_GAME_PROFILE);
}
@Override
public boolean canEat(boolean checkHunger) {
return true;
}
@Override
public OptionalInt openContainer(@Nullable INamedContainerProvider container) {
return OptionalInt.empty();
}
}

View File

@ -20,46 +20,46 @@
package com.sk89q.worldedit.forge.gui;
import com.sk89q.worldedit.forge.ForgeWorldEdit;
import net.minecraft.client.gui.GuiButton;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.widget.button.Button;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
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 {
public class GuiReferenceCard extends Screen {
private GuiButton closeButton;
private Button closeButton;
private int backgroundWidth = 256;
private int backgroundHeight = 256;
@Override
public void initGui() {
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);
public GuiReferenceCard(ITextComponent title) {
super(title);
}
mc.player.closeScreen();
}
};
@Override
public void init() {
this.addButton(closeButton = new Button(
(this.width - this.backgroundWidth + 56) / 2, (this.height + this.backgroundHeight) / 2,
200, 20, "Close",
button -> this.minecraft.player.closeScreen()));
}
@Override
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;
int y = (this.height - this.backgroundHeight) / 2 - this.closeButton.getHeight();
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
this.mc.textureManager.bindTexture(new ResourceLocation(ForgeWorldEdit.MOD_ID, "textures/gui/reference.png"));
this.drawTexturedModalRect(x, y, 0, 0, this.backgroundWidth, this.backgroundHeight);
this.minecraft.textureManager.bindTexture(new ResourceLocation(ForgeWorldEdit.MOD_ID, "textures/gui/reference.png"));
this.blit(x, y, 0, 0, this.backgroundWidth, this.backgroundHeight);
super.render(mouseX, mouseY, par3);
}
@Override
public boolean doesGuiPauseGame() {
public boolean isPauseScreen() {
return true;
}

View File

@ -1,65 +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.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

@ -19,20 +19,14 @@
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)
private static final int PROTOCOL_VERSION = 1;
private static SimpleChannel HANDLER = PacketHandlerUtil
.buildLenientHandler("internal", PROTOCOL_VERSION)
.simpleChannel();
private InternalPacketHandler() {
@ -42,4 +36,8 @@ public final class InternalPacketHandler {
HANDLER.registerMessage(0, LeftClickAirEventMessage.class,
LeftClickAirEventMessage::encode, LeftClickAirEventMessage::decode, Handler::handle);
}
public static SimpleChannel getHandler() {
return HANDLER;
}
}

View File

@ -0,0 +1,48 @@
/*
* 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 net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.network.NetworkRegistry;
import java.util.function.Predicate;
final class PacketHandlerUtil {
private PacketHandlerUtil() {
}
static NetworkRegistry.ChannelBuilder buildLenientHandler(String id, int protocolVersion) {
final String verStr = Integer.toString(protocolVersion);
final Predicate<String> validator = validateLenient(verStr);
return NetworkRegistry.ChannelBuilder
.named(new ResourceLocation(ForgeWorldEdit.MOD_ID, id))
.clientAcceptedVersions(validator)
.serverAcceptedVersions(validator)
.networkProtocolVersion(() -> verStr);
}
private static Predicate<String> validateLenient(String protocolVersion) {
return remoteVersion ->
protocolVersion.equals(remoteVersion)
|| NetworkRegistry.ABSENT.equals(remoteVersion)
|| NetworkRegistry.ACCEPTVANILLA.equals(remoteVersion);
}
}

View File

@ -20,15 +20,10 @@
package com.sk89q.worldedit.forge.net.handler;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.forge.ForgePlayer;
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.minecraft.entity.player.ServerPlayerEntity;
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;
@ -40,21 +35,17 @@ public final class 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)
private static final int PROTOCOL_VERSION = 1;
private static EventNetworkChannel HANDLER = PacketHandlerUtil
.buildLenientHandler(ForgeWorldEdit.CUI_PLUGIN_CHANNEL, 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();
public static void onPacketData(ClientCustomPayloadEvent event) {
ServerPlayerEntity player = event.getSource().get().getSender();
LocalSession session = ForgeWorldEdit.inst.getSession(player);
if (session.hasCUISupport()) {
@ -62,17 +53,9 @@ public final class WECUIPacketHandler {
}
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) {
}
final ForgePlayer actor = adaptPlayer(player);
session.handleCUIInitializationMessage(text, actor);
session.describeCUI(actor);
}
}

View File

@ -25,16 +25,8 @@ import net.minecraftforge.api.distmarker.OnlyIn;
@OnlyIn(Dist.DEDICATED_SERVER)
public class ServerProxy implements CommonProxy {
// public static ResourceLocation REFERENCE_GUI = new ResourceLocation("worldedit", "resource_gui");
@Override
public void registerHandlers() {
// ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.GUIFACTORY, () -> openContainer -> {
// if (openContainer.getId().equals(REFERENCE_GUI)) {
// return new GuiReferenceCard();
// }
// return null;
// });
}
}