diff --git a/.travis.yml b/.travis.yml index f8b8492f7..1c581a696 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,7 +2,6 @@ language: java notifications: email: false before_install: chmod +x gradlew -install: ./gradlew setupCIWorkspace -s script: ./gradlew build -s jdk: - oraclejdk8 diff --git a/build.gradle b/build.gradle index 2c70494c0..8bdb1a122 100644 --- a/build.gradle +++ b/build.gradle @@ -7,20 +7,19 @@ buildscript { configurations.all { resolutionStrategy { - force 'com.google.guava:guava:21.0' - force 'org.ow2.asm:asm:6.0_BETA' + force 'commons-io:commons-io:2.4' } } dependencies { classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4' - classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.7.5' - classpath 'org.ajoberstar:gradle-git:1.7.2' + classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.8.1' } } plugins { id 'net.minecrell.licenser' version '0.4.1' apply false + id "org.ajoberstar.grgit" version "2.3.0" } println """ @@ -48,7 +47,7 @@ if (!project.hasProperty("artifactory_password")) ext.artifactory_password = "" if (!project.hasProperty("gitCommitHash") && !JavaVersion.current().isJava6()) { try { - def repo = org.ajoberstar.grgit.Grgit.open(dir: '.') + def repo = grgit.open() ext.gitCommitHash = repo.head().abbreviatedId } catch (Exception e) { println "Error getting commit hash: " + e.getMessage() diff --git a/config/checkstyle/checkstyle.xml b/config/checkstyle/checkstyle.xml index 7872f45bc..a2d043d73 100644 --- a/config/checkstyle/checkstyle.xml +++ b/config/checkstyle/checkstyle.xml @@ -5,8 +5,9 @@ - + + diff --git a/config/checkstyle/import-control.xml b/config/checkstyle/import-control.xml index eedd07857..9cc735070 100644 --- a/config/checkstyle/import-control.xml +++ b/config/checkstyle/import-control.xml @@ -53,6 +53,7 @@ + diff --git a/gradle.properties b/gradle.properties new file mode 100644 index 000000000..878bf1f7e --- /dev/null +++ b/gradle.properties @@ -0,0 +1,4 @@ +# Sets default memory used for gradle commands. Can be overridden by user or command line properties. +# This is required to provide enough memory for the Minecraft decompilation process. +org.gradle.jvmargs=-Xmx3G +org.gradle.daemon=false \ No newline at end of file diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 29953ea14..0d4a95168 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index e0b3fb8d7..a95009c3b 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/LegacyMapper.java b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/LegacyMapper.java index e59cd762a..ad2eac4c0 100644 --- a/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/LegacyMapper.java +++ b/worldedit-core/src/main/java/com/sk89q/worldedit/world/registry/LegacyMapper.java @@ -43,6 +43,8 @@ import java.util.logging.Logger; import javax.annotation.Nullable; +import static com.google.common.base.Preconditions.checkNotNull; + public class LegacyMapper { private static final Logger log = Logger.getLogger(LegacyMapper.class.getCanonicalName()); @@ -100,6 +102,7 @@ public class LegacyMapper { try { String id = itemEntry.getKey(); ItemType type = ItemTypes.get(itemEntry.getValue()); + checkNotNull(type); itemToStringMap.put(type, id); stringToItemMap.put(id, type); } catch (Exception e) { diff --git a/worldedit-core/src/main/resources/com/sk89q/worldedit/world/registry/legacy.json b/worldedit-core/src/main/resources/com/sk89q/worldedit/world/registry/legacy.json index 4bc2907a2..ec4c09040 100644 --- a/worldedit-core/src/main/resources/com/sk89q/worldedit/world/registry/legacy.json +++ b/worldedit-core/src/main/resources/com/sk89q/worldedit/world/registry/legacy.json @@ -1785,7 +1785,7 @@ "48:0": "minecraft:mossy_cobblestone", "49:0": "minecraft:obsidian", "50:0": "minecraft:torch", - "52:0": "minecraft:mob_spawner", + "52:0": "minecraft:spawner", "53:0": "minecraft:oak_stairs", "54:0": "minecraft:chest", "56:0": "minecraft:diamond_ore", diff --git a/worldedit-forge/build.gradle b/worldedit-forge/build.gradle index b558a41ea..e9dff30ae 100644 --- a/worldedit-forge/build.gradle +++ b/worldedit-forge/build.gradle @@ -1,64 +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' -configurations.all { - resolutionStrategy { - force 'org.ow2.asm:asm:5.2' - } -} +def minecraftVersion = "1.13.2" +def forgeVersion = "25.0.76" dependencies { compile project(':worldedit-core') - compile 'org.spongepowered:spongeapi:6.0.0-SNAPSHOT' + + 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.version + inputs.property 'mcversion', minecraftVersion + inputs.property 'internalVersion', internalVersion + + // replace stuff in mcmod.info, nothing else + from(sourceSets.main.resources.srcDirs) { + include 'META_INF/mods.toml' + + // replace version and mcversion + expand 'version':project.version, 'mcversion': minecraftVersion, 'internalVersion': internalVersion } - 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' } } @@ -76,9 +88,11 @@ shadowJar { } } -reobf { - shadowJar { - mappingType = 'SEARGE' +afterEvaluate { + reobf { + shadowJar { + mappings = createMcpToSrg.output + } } } diff --git a/worldedit-forge/src/main/ant/build.xml b/worldedit-forge/src/main/ant/build.xml deleted file mode 100644 index 5753b52ce..000000000 --- a/worldedit-forge/src/main/ant/build.xml +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/CommandWrapper.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/CommandWrapper.java index 1ad0f10ca..6089040be 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/CommandWrapper.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/CommandWrapper.java @@ -19,60 +19,119 @@ package com.sk89q.worldedit.forge; +import com.mojang.brigadier.Command; +import com.mojang.brigadier.CommandDispatcher; +import com.mojang.brigadier.arguments.StringArgumentType; +import com.mojang.brigadier.builder.ArgumentBuilder; +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 com.sk89q.worldedit.util.command.Parameter; +import net.minecraft.command.CommandSource; +import net.minecraft.entity.player.EntityPlayerMP; -import java.util.Arrays; -import java.util.List; +import java.util.LinkedList; +import java.util.function.Predicate; -import javax.annotation.Nullable; +import static net.minecraft.command.Commands.argument; +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(); - } + public static void register(CommandDispatcher dispatcher, CommandMapping command) { + LiteralArgumentBuilder base = literal(command.getPrimaryAlias()); + LinkedList> parameterStack = new LinkedList<>(); + LinkedList> optionalParameterStack = new LinkedList<>(); + boolean hasFlag = false; + for (Parameter parameter : command.getDescription().getParameters()) { + if (parameter.isValueFlag()) { + if (!hasFlag) { + hasFlag = true; + optionalParameterStack.push(argument("flags", StringArgumentType.string())); + } + } else if (parameter.isOptional()) { + optionalParameterStack.push(argument(parameter.getName(), StringArgumentType.string())); + } else { + parameterStack.push(argument(parameter.getName(), StringArgumentType.string())); + } + } - @Override - public List 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; + ArgumentBuilder argument = buildChildNodes(parameterStack, optionalParameterStack, command); + if (argument != null) { + base.then(argument); } else { - return super.compareTo(o); + base.executes(commandFor(command)); + } + LiteralCommandNode registered = + dispatcher.register( + base.requires(requirementsFor(command)) + ); + for (String alias : command.getAllAliases()) { + dispatcher.register( + literal(alias).redirect(registered) + ); } } + + /** + * Make the appropriate {@code then()} and {@code execute()} calls to emulate required and + * optional parameters, given the argument orders. + * + * @param parameterStack required parameters + * @param optionalParameterStack optional parameters + * @return the node with all calls chained + */ + private static ArgumentBuilder buildChildNodes(LinkedList> parameterStack, + LinkedList> optionalParameterStack, + CommandMapping mapping) { + ArgumentBuilder currentChild = null; + Command command = commandFor(mapping); + while (!optionalParameterStack.isEmpty()) { + ArgumentBuilder next = optionalParameterStack.removeLast(); + if (currentChild != null) { + next.then(currentChild.executes(command)); + } + currentChild = next; + } + boolean requiredExecute = false; + while (!parameterStack.isEmpty()) { + ArgumentBuilder next = parameterStack.removeLast(); + if (currentChild != null) { + next.then(currentChild); + } + if (!requiredExecute) { + // first required parameter also gets execute + requiredExecute = true; + next.executes(command); + } + currentChild = next; + } + return currentChild; + } + + private static Command commandFor(CommandMapping mapping) { + return FAKE_COMMAND; + } + + public static final Command FAKE_COMMAND = ctx -> { + EntityPlayerMP player = ctx.getSource().asPlayer(); + if (player.world.isRemote()) { + return 0; + } + return 1; + }; + + private static Predicate 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 + )); + }; + } + } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/CommonProxy.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/CommonProxy.java index 18a7de68f..7c5708358 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/CommonProxy.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/CommonProxy.java @@ -19,13 +19,22 @@ package com.sk89q.worldedit.forge; -import com.sk89q.worldedit.forge.gui.GuiHandler; -import net.minecraftforge.fml.common.network.NetworkRegistry; +import com.sk89q.worldedit.forge.gui.GuiReferenceCard; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.fml.ExtensionPoint; +import net.minecraftforge.fml.ModLoadingContext; public class CommonProxy { + public static ResourceLocation REFERENCE_GUI = new ResourceLocation("worldedit", "resource_gui"); + public void registerHandlers() { - NetworkRegistry.INSTANCE.registerGuiHandler(ForgeWorldEdit.inst, new GuiHandler()); + ModLoadingContext.get().registerExtensionPoint(ExtensionPoint.GUIFACTORY, () -> openContainer -> { + if (openContainer.getId().equals(REFERENCE_GUI)) { + return new GuiReferenceCard(); + } + return null; + }); } } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeAdapter.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeAdapter.java index f28e35a0b..164ac65cf 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeAdapter.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeAdapter.java @@ -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,23 +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 com.sk89q.worldedit.world.biome.BiomeType; import com.sk89q.worldedit.world.biome.BiomeTypes; -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.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() { } @@ -55,7 +72,7 @@ final class ForgeAdapter { } public static Biome adapt(BiomeType biomeType) { - return Biome.REGISTRY.getObject(new ResourceLocation(biomeType.getId())); + return ForgeRegistries.BIOMES.getValue(new ResourceLocation(biomeType.getId())); } public static BiomeType adapt(Biome biome) { @@ -105,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, Object> adaptProperties(BlockType block, Map, Comparable> mcProps) { + Map, Object> props = new TreeMap<>(Comparator.comparing(Property::getName)); + for (Map.Entry, 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 stateContainer, IBlockState newState, Map, Object> states) { + for (Map.Entry, 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, 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); + } } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBiomeRegistry.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBiomeRegistry.java index 986a3afc2..e0337d735 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBiomeRegistry.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBiomeRegistry.java @@ -29,7 +29,6 @@ import net.minecraft.world.biome.Biome; */ class ForgeBiomeRegistry implements BiomeRegistry { - @Override public BiomeData getData(BiomeType biome) { return new ForgeBiomeData(ForgeAdapter.adapt(biome)); @@ -52,7 +51,7 @@ class ForgeBiomeRegistry implements BiomeRegistry { @Override public String getName() { - return biome.getBiomeName(); + return biome.getDisplayName().getString(); } } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockMaterial.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockMaterial.java index 9d98f39ef..5f15a683b 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockMaterial.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockMaterial.java @@ -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 diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockRegistry.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockRegistry.java index ddf3762bb..91c0b4cc8 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockRegistry.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeBlockRegistry.java @@ -23,11 +23,9 @@ 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 +41,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> getProperties(BlockType blockType) { + Block block = ForgeAdapter.adapt(blockType); Map> map = new TreeMap<>(); - Collection> propertyKeys = Block.getBlockFromName(blockType.getId()) + Collection> propertyKeys = block .getDefaultState() - .getPropertyKeys(); + .getProperties(); for (IProperty key : propertyKeys) { map.put(key.getName(), ForgeAdapter.adaptProperty(key)); } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntity.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntity.java index e4b391fe0..96e97cf29 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntity.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntity.java @@ -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; } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntityProperties.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntityProperties.java index bf6a16ae2..6e07e18ad 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntityProperties.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeEntityProperties.java @@ -136,7 +136,7 @@ public class ForgeEntityProperties implements EntityProperties { @Override public boolean isTagged() { - return entity instanceof EntityLiving && ((EntityLiving) entity).hasCustomName(); + return entity.hasCustomName(); } @Override diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePermissionsProvider.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePermissionsProvider.java index bc6820c0d..6129cb31b 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePermissionsProvider.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePermissionsProvider.java @@ -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) { +// +// } +// } } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java index 2eb66bf14..0530acc54 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlatform.java @@ -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 getWorlds() { - WorldServer[] worlds = DimensionManager.getWorlds(); - List ret = new ArrayList<>(worlds.length); + Iterable worlds = server.getWorlds(); + List 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)); } } } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java index a20abd100..5b3b2ca84 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -24,6 +24,7 @@ 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; @@ -32,19 +33,17 @@ import com.sk89q.worldedit.util.HandSide; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BlockStateHolder; -import com.sk89q.worldedit.world.item.ItemTypes; 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.network.play.server.SPacketUpdateTileEntity; 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; @@ -69,12 +68,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 @@ -105,8 +104,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 @@ -117,7 +115,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); } @@ -197,7 +195,7 @@ public class ForgePlayer extends AbstractPlayerActor { @Override public SessionKey getSessionKey() { - return new SessionKeyImpl(player.getUniqueID(), player.getName()); + return new SessionKeyImpl(player.getUniqueID(), player.getName().getString()); } private static class SessionKeyImpl implements SessionKey { diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java index 09fcc4241..8291f50ae 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorld.java @@ -21,7 +21,6 @@ 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.EditSession; import com.sk89q.worldedit.MaxChangedBlocksException; @@ -34,9 +33,7 @@ import com.sk89q.worldedit.internal.Constants; 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.registry.state.Property; import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.TreeGenerator.TreeType; @@ -45,66 +42,49 @@ 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; @@ -116,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 worldRef; @@ -178,14 +158,11 @@ 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, 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 @@ -194,7 +171,7 @@ public class ForgeWorld extends AbstractWorld { // Kill the old TileEntity world.removeTileEntity(pos); NBTTagCompound nativeTag = NBTConverter.toNative(((BaseBlock) block).getNbtData()); - nativeTag.setString("id", ((BaseBlock) block).getNbtId()); + nativeTag.putString("id", ((BaseBlock) block).getNbtId()); TileEntityUtils.setTileEntity(world, position, nativeTag); } } @@ -216,29 +193,6 @@ public class ForgeWorld extends AbstractWorld { 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, Object> states) { - for (Map.Entry, 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; - } - @Override public int getBlockLightLevel(BlockVector3 position) { checkNotNull(position); @@ -263,7 +217,7 @@ public class ForgeWorld extends AbstractWorld { @Override public BiomeType getBiome(BlockVector2 position) { checkNotNull(position); - return ForgeAdapter.adapt(getWorld().getBiomeForCoordsBody(new BlockPos(position.getBlockX(), 0, position.getBlockZ()))); + return ForgeAdapter.adapt(getWorld().getBiomeBody(new BlockPos(position.getBlockX(), 0, position.getBlockZ()))); } @Override @@ -271,9 +225,9 @@ public class ForgeWorld extends AbstractWorld { 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.getIdForBiome(ForgeAdapter.adapt(biome)); + chunk.getBiomes()[((position.getBlockZ() & 0xF) << 4 | position.getBlockX() & 0xF)] = ForgeAdapter.adapt(biome); return true; } @@ -282,16 +236,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; } @@ -304,7 +266,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); } @@ -313,75 +275,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 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; @@ -390,13 +352,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 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 @@ -408,7 +370,7 @@ public class ForgeWorld extends AbstractWorld { public void fixLighting(Iterable chunks) { World world = getWorld(); for (BlockVector2 chunk : chunks) { - world.getChunkFromChunkCoords(chunk.getBlockX(), chunk.getBlockZ()).resetRelightChecks(); + world.getChunk(chunk.getBlockX(), chunk.getBlockZ()).resetRelightChecks(); } } @@ -439,7 +401,7 @@ public class ForgeWorld extends AbstractWorld { if (info.isRaining()) { return info.getRainTime(); } - return info.getCleanWeatherTime(); + return info.getClearWeatherTime(); } @Override @@ -450,18 +412,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); } } @@ -472,26 +434,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, Object> adaptProperties(BlockType block, Map, Comparable> mcProps) { - Map, Object> props = new TreeMap<>(Comparator.comparing(Property::getName)); - for (Map.Entry, 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 @@ -551,15 +500,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()); diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java index 5a5a217ad..07bf6c4d9 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ForgeWorldEdit.java @@ -20,152 +20,200 @@ 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.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, () -> CommonProxy::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)) { - BlockType.REGISTRY.register(nameStr, 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)) { - ItemType.REGISTRY.register(nameStr, 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 worldEdit = WorldEdit.getInstance(); worldEdit.getSessionManager().unload(); worldEdit.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) { @@ -177,23 +225,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) { @@ -228,12 +276,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 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() + )); } /** @@ -245,17 +305,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. * @@ -264,7 +313,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)); } /** @@ -293,7 +342,7 @@ public class ForgeWorldEdit { * @return the working directory */ public File getWorkingDir() { - return this.workingDir; + return this.workingDir.toFile(); } /** @@ -302,7 +351,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) { diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/IPropertyAdapter.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/IPropertyAdapter.java index 0ac900a55..e024f6e93 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/IPropertyAdapter.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/IPropertyAdapter.java @@ -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> implements Property { diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/InternalPacketHandler.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/InternalPacketHandler.java deleted file mode 100644 index afac351ac..000000000 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/InternalPacketHandler.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.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() { - } -} diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/KeyHandler.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/KeyHandler.java index 76e726884..d0a23fcf1 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/KeyHandler.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/KeyHandler.java @@ -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(CommonProxy.REFERENCE_GUI)); } } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/NBTConverter.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/NBTConverter.java index 0992d3d4f..bae43851c 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/NBTConverter.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/NBTConverter.java @@ -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 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 list = new ArrayList<>(); Class 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 tags = other.getKeySet(); + Set tags = other.keySet(); Map 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); } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ThreadSafeCache.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ThreadSafeCache.java index a52233564..5f80516eb 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ThreadSafeCache.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/ThreadSafeCache.java @@ -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 onlineIds = new HashSet<>(); - MinecraftServer server = FMLCommonHandler.instance().getMinecraftServerInstance(); + MinecraftServer server = ServerLifecycleHooks.getCurrentServer(); if (server == null || server.getPlayerList() == null) { return; } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/TileEntityUtils.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/TileEntityUtils.java index 4147d835c..52f027f51 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/TileEntityUtils.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/TileEntityUtils.java @@ -52,9 +52,9 @@ final class TileEntityUtils { 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())); + tag.put("x", new NBTTagInt(position.getBlockX())); + tag.put("y", new NBTTagInt(position.getBlockY())); + tag.put("z", new NBTTagInt(position.getBlockZ())); return tag; } @@ -81,7 +81,7 @@ final class TileEntityUtils { if (tag != null) { // Set X, Y, Z updateForSet(tag, position); - tileEntity.readFromNBT(tag); + tileEntity.read(tag); } world.setTileEntity(new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()), tileEntity); @@ -98,7 +98,7 @@ 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); } @@ -143,7 +143,7 @@ final class TileEntityUtils { public static NBTTagCompound copyNbtData(TileEntity tile) { NBTTagCompound tag = new NBTTagCompound(); - tile.writeToNBT(tag); + tile.write(tag); return tag; } } diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/WECUIPacketHandler.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/WECUIPacketHandler.java deleted file mode 100644 index c6cf673e4..000000000 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/WECUIPacketHandler.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.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; - } -} \ No newline at end of file diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/gui/GuiHandler.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/gui/GuiHandler.java deleted file mode 100644 index d88b97379..000000000 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/gui/GuiHandler.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * WorldEdit, a Minecraft world manipulation toolkit - * Copyright (C) sk89q - * Copyright (C) WorldEdit team and contributors - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU Lesser General Public License as published by the - * Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License - * for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with this program. If not, see . - */ - -package com.sk89q.worldedit.forge.gui; - -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.world.World; -import net.minecraftforge.fml.common.network.IGuiHandler; - -public class GuiHandler implements IGuiHandler { - - public static final int REFERENCE_ID = 0; - - @Override - public Object getServerGuiElement(int id, EntityPlayer player, World world, int x, int y, int z) { - 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; - } - -} \ No newline at end of file diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/gui/GuiReferenceCard.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/gui/GuiReferenceCard.java index a9e53d36d..d15642934 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/gui/GuiReferenceCard.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/gui/GuiReferenceCard.java @@ -33,25 +33,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 diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/gui/ResourceLocationInteractionObject.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/gui/ResourceLocationInteractionObject.java new file mode 100644 index 000000000..6e11d02dd --- /dev/null +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/gui/ResourceLocationInteractionObject.java @@ -0,0 +1,65 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.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; + } +} diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/handler/InternalPacketHandler.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/handler/InternalPacketHandler.java new file mode 100644 index 000000000..17b81a852 --- /dev/null +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/handler/InternalPacketHandler.java @@ -0,0 +1,45 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.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); + } +} diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/handler/WECUIPacketHandler.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/handler/WECUIPacketHandler.java new file mode 100644 index 000000000..541577e1f --- /dev/null +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/handler/WECUIPacketHandler.java @@ -0,0 +1,78 @@ +/* + * WorldEdit, a Minecraft world manipulation toolkit + * Copyright (C) sk89q + * Copyright (C) WorldEdit team and contributors + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + */ + +package com.sk89q.worldedit.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) { + } + } +} \ No newline at end of file diff --git a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/LeftClickAirEventMessage.java b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/packet/LeftClickAirEventMessage.java similarity index 53% rename from worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/LeftClickAirEventMessage.java rename to worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/packet/LeftClickAirEventMessage.java index 1e3b2b20e..e5e5d8cdc 100644 --- a/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/LeftClickAirEventMessage.java +++ b/worldedit-forge/src/main/java/com/sk89q/worldedit/forge/net/packet/LeftClickAirEventMessage.java @@ -17,34 +17,32 @@ * along with this program. If not, see . */ -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 { +@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 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) { } } diff --git a/worldedit-forge/src/main/resources/META-INF/mods.toml b/worldedit-forge/src/main/resources/META-INF/mods.toml new file mode 100644 index 000000000..c89f9c261 --- /dev/null +++ b/worldedit-forge/src/main/resources/META-INF/mods.toml @@ -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/YKbmj7V" +# 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="[${forge_version},)" + ordering="NONE" + side="BOTH" +[[dependencies.worldedit]] + modId="sponge" + mandatory=false + versionRange="[1.13]" + ordering="BEFORE" + side="SERVER" \ No newline at end of file diff --git a/worldedit-forge/src/main/resources/mcmod.info b/worldedit-forge/src/main/resources/mcmod.info deleted file mode 100644 index bcee1cd4a..000000000 --- a/worldedit-forge/src/main/resources/mcmod.info +++ /dev/null @@ -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": [] -}] diff --git a/worldedit-forge/src/main/resources/pack.mcmeta b/worldedit-forge/src/main/resources/pack.mcmeta new file mode 100644 index 000000000..b48da3b7d --- /dev/null +++ b/worldedit-forge/src/main/resources/pack.mcmeta @@ -0,0 +1,6 @@ +{ + "pack": { + "description": "WorldEdit Resources", + "pack_format": 4 + } +} \ No newline at end of file diff --git a/worldedit-forge/src/main/resources/worldedit-icon.png b/worldedit-forge/src/main/resources/worldedit-icon.png new file mode 100644 index 000000000..dc269dcf7 Binary files /dev/null and b/worldedit-forge/src/main/resources/worldedit-icon.png differ