Merge pull request #452 from EngineHub/forge-1.13

Added support for Forge 1.13
This commit is contained in:
Matthew Miller 2019-03-11 22:52:30 +10:00 committed by GitHub
commit a5cec7728d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 918 additions and 826 deletions

View File

@ -2,7 +2,6 @@ language: java
notifications: notifications:
email: false email: false
before_install: chmod +x gradlew before_install: chmod +x gradlew
install: ./gradlew setupCIWorkspace -s
script: ./gradlew build -s script: ./gradlew build -s
jdk: jdk:
- oraclejdk8 - oraclejdk8

View File

@ -7,20 +7,19 @@ buildscript {
configurations.all { configurations.all {
resolutionStrategy { resolutionStrategy {
force 'com.google.guava:guava:21.0' force 'commons-io:commons-io:2.4'
force 'org.ow2.asm:asm:6.0_BETA'
} }
} }
dependencies { dependencies {
classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4' classpath 'com.github.jengelman.gradle.plugins:shadow:2.0.4'
classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.7.5' classpath 'org.jfrog.buildinfo:build-info-extractor-gradle:4.8.1'
classpath 'org.ajoberstar:gradle-git:1.7.2'
} }
} }
plugins { plugins {
id 'net.minecrell.licenser' version '0.4.1' apply false id 'net.minecrell.licenser' version '0.4.1' apply false
id "org.ajoberstar.grgit" version "2.3.0"
} }
println """ println """
@ -48,7 +47,7 @@ if (!project.hasProperty("artifactory_password")) ext.artifactory_password = ""
if (!project.hasProperty("gitCommitHash") && !JavaVersion.current().isJava6()) { if (!project.hasProperty("gitCommitHash") && !JavaVersion.current().isJava6()) {
try { try {
def repo = org.ajoberstar.grgit.Grgit.open(dir: '.') def repo = grgit.open()
ext.gitCommitHash = repo.head().abbreviatedId ext.gitCommitHash = repo.head().abbreviatedId
} catch (Exception e) { } catch (Exception e) {
println "Error getting commit hash: " + e.getMessage() println "Error getting commit hash: " + e.getMessage()

View File

@ -5,8 +5,9 @@
<module name="Checker"> <module name="Checker">
<!-- Tabs are strictly banned --> <!-- Tabs are strictly banned -->
<module name="FileTabCharacter"/> <module name="FileTabCharacter"/>
<module name="SuppressWarningsFilter" />
<module name="TreeWalker"> <module name="TreeWalker">
<module name="SuppressWarningsHolder" /> <!-- allows for @SuppressWarnings annotation -->
<!-- Important basics --> <!-- Important basics -->
<!-- <module name="PackageDeclaration"/> Unlikely that we would miss this in a PR --> <!-- <module name="PackageDeclaration"/> Unlikely that we would miss this in a PR -->
<module name="OuterTypeFilename"/> <!-- TypeName -> TypeName.java --> <module name="OuterTypeFilename"/> <!-- TypeName -> TypeName.java -->

View File

@ -53,6 +53,7 @@
<allow pkg="org.lwjgl"/> <allow pkg="org.lwjgl"/>
<allow pkg="io.netty.buffer"/> <allow pkg="io.netty.buffer"/>
<allow pkg="org.spongepowered.api" /> <allow pkg="org.spongepowered.api" />
<allow pkg="com.mojang.brigadier" />
</subpackage> </subpackage>
<subpackage name="sponge"> <subpackage name="sponge">

4
gradle.properties Normal file
View File

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

Binary file not shown.

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists 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 zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

View File

@ -43,6 +43,8 @@ import java.util.logging.Logger;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import static com.google.common.base.Preconditions.checkNotNull;
public class LegacyMapper { public class LegacyMapper {
private static final Logger log = Logger.getLogger(LegacyMapper.class.getCanonicalName()); private static final Logger log = Logger.getLogger(LegacyMapper.class.getCanonicalName());
@ -100,6 +102,7 @@ public class LegacyMapper {
try { try {
String id = itemEntry.getKey(); String id = itemEntry.getKey();
ItemType type = ItemTypes.get(itemEntry.getValue()); ItemType type = ItemTypes.get(itemEntry.getValue());
checkNotNull(type);
itemToStringMap.put(type, id); itemToStringMap.put(type, id);
stringToItemMap.put(id, type); stringToItemMap.put(id, type);
} catch (Exception e) { } catch (Exception e) {

View File

@ -1785,7 +1785,7 @@
"48:0": "minecraft:mossy_cobblestone", "48:0": "minecraft:mossy_cobblestone",
"49:0": "minecraft:obsidian", "49:0": "minecraft:obsidian",
"50:0": "minecraft:torch", "50:0": "minecraft:torch",
"52:0": "minecraft:mob_spawner", "52:0": "minecraft:spawner",
"53:0": "minecraft:oak_stairs", "53:0": "minecraft:oak_stairs",
"54:0": "minecraft:chest", "54:0": "minecraft:chest",
"56:0": "minecraft:diamond_ore", "56:0": "minecraft:diamond_ore",

View File

@ -1,64 +1,76 @@
buildscript { buildscript {
repositories { repositories {
mavenLocal()
mavenCentral() mavenCentral()
maven { url = "http://files.minecraftforge.net/maven" } maven { url = "https://files.minecraftforge.net/maven" }
maven { url = "https://oss.sonatype.org/content/repositories/snapshots/" }
jcenter() jcenter()
} }
dependencies { 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 { def minecraftVersion = "1.13.2"
resolutionStrategy { def forgeVersion = "25.0.76"
force 'org.ow2.asm:asm:5.2'
}
}
dependencies { dependencies {
compile project(':worldedit-core') 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' testCompile group: 'org.mockito', name: 'mockito-core', version: '1.9.0-rc1'
} }
sourceCompatibility = 1.8 sourceCompatibility = 1.8
targetCompatibility = 1.8 targetCompatibility = 1.8
repositories {
maven {
name = "Sponge"
url = "https://repo.spongepowered.org/maven"
}
}
ext.forgeVersion = "14.22.0.2456"
minecraft { minecraft {
version = "1.12.1-${project.forgeVersion}" mappings channel: 'snapshot', version: '20190311-1.13.2'
mappings = "snapshot_20170815"
runDir = 'run'
replaceIn "com/sk89q/worldedit/forge/ForgeWorldEdit.java" runs {
replace "%VERSION%", project.version 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 { processResources {
from (sourceSets.main.resources.srcDirs) { // this will ensure that this task is redone when the versions change.
expand 'version': project.version, inputs.property 'version', project.version
'mcVersion': project.minecraft.version, inputs.property 'mcversion', minecraftVersion
'forgeVersion': project.forgeVersion, inputs.property 'internalVersion', internalVersion
'internalVersion': project.internalVersion
include 'mcmod.info' // 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) { // copy everything else except the mcmod.info
exclude 'mcmod.info' from(sourceSets.main.resources.srcDirs) {
exclude 'META_INF/mods.toml'
} }
} }
@ -76,9 +88,11 @@ shadowJar {
} }
} }
reobf { afterEvaluate {
shadowJar { reobf {
mappingType = 'SEARGE' shadowJar {
mappings = createMcpToSrg.output
}
} }
} }

View File

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

View File

@ -19,60 +19,119 @@
package com.sk89q.worldedit.forge; 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 com.sk89q.worldedit.util.command.CommandMapping;
import net.minecraft.command.CommandBase; import com.sk89q.worldedit.util.command.Parameter;
import net.minecraft.command.CommandException; import net.minecraft.command.CommandSource;
import net.minecraft.command.ICommand; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.command.ICommandSender;
import net.minecraft.server.MinecraftServer;
import java.util.Arrays; import java.util.LinkedList;
import java.util.List; 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 { public final class CommandWrapper {
private CommandMapping command; private CommandWrapper() {
protected CommandWrapper(CommandMapping command) {
this.command = command;
} }
@Override public static void register(CommandDispatcher<CommandSource> dispatcher, CommandMapping command) {
public String getName() { LiteralArgumentBuilder<CommandSource> base = literal(command.getPrimaryAlias());
return command.getPrimaryAlias(); LinkedList<ArgumentBuilder<CommandSource, ?>> parameterStack = new LinkedList<>();
} LinkedList<ArgumentBuilder<CommandSource, ?>> 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 ArgumentBuilder<CommandSource, ?> argument = buildChildNodes(parameterStack, optionalParameterStack, command);
public List<String> getAliases() { if (argument != null) {
return Arrays.asList(command.getAllAliases()); base.then(argument);
}
@Override
public void execute(MinecraftServer server, ICommandSender sender, String[] args) throws CommandException {
}
@Override
public String getUsage(ICommandSender icommandsender) {
return "/" + command.getPrimaryAlias() + " " + command.getDescription().getUsage();
}
@Override
public int getRequiredPermissionLevel() {
return 0;
}
@Override
public boolean checkPermission(MinecraftServer server, ICommandSender sender) {
return true;
}
@Override
public int compareTo(@Nullable ICommand o) {
if (o == null) {
return 0;
} else { } else {
return super.compareTo(o); base.executes(commandFor(command));
}
LiteralCommandNode<CommandSource> 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<CommandSource, ?> buildChildNodes(LinkedList<ArgumentBuilder<CommandSource, ?>> parameterStack,
LinkedList<ArgumentBuilder<CommandSource, ?>> optionalParameterStack,
CommandMapping mapping) {
ArgumentBuilder<CommandSource, ?> currentChild = null;
Command<CommandSource> command = commandFor(mapping);
while (!optionalParameterStack.isEmpty()) {
ArgumentBuilder<CommandSource, ?> next = optionalParameterStack.removeLast();
if (currentChild != null) {
next.then(currentChild.executes(command));
}
currentChild = next;
}
boolean requiredExecute = false;
while (!parameterStack.isEmpty()) {
ArgumentBuilder<CommandSource, ?> 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<CommandSource> commandFor(CommandMapping mapping) {
return FAKE_COMMAND;
}
public static final Command<CommandSource> FAKE_COMMAND = ctx -> {
EntityPlayerMP player = ctx.getSource().asPlayer();
if (player.world.isRemote()) {
return 0;
}
return 1;
};
private static Predicate<CommandSource> requirementsFor(CommandMapping mapping) {
return ctx -> {
ForgePermissionsProvider permsProvider = ForgeWorldEdit.inst.getPermissionsProvider();
return ctx.getEntity() instanceof EntityPlayerMP &&
mapping.getDescription().getPermissions().stream()
.allMatch(perm -> permsProvider.hasPermission(
(EntityPlayerMP) ctx.getEntity(), perm
));
};
}
} }

View File

@ -19,13 +19,22 @@
package com.sk89q.worldedit.forge; package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.forge.gui.GuiHandler; import com.sk89q.worldedit.forge.gui.GuiReferenceCard;
import net.minecraftforge.fml.common.network.NetworkRegistry; import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.ExtensionPoint;
import net.minecraftforge.fml.ModLoadingContext;
public class CommonProxy { public class CommonProxy {
public static ResourceLocation REFERENCE_GUI = new ResourceLocation("worldedit", "resource_gui");
public void registerHandlers() { 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;
});
} }
} }

View File

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

View File

@ -29,7 +29,6 @@ import net.minecraft.world.biome.Biome;
*/ */
class ForgeBiomeRegistry implements BiomeRegistry { class ForgeBiomeRegistry implements BiomeRegistry {
@Override @Override
public BiomeData getData(BiomeType biome) { public BiomeData getData(BiomeType biome) {
return new ForgeBiomeData(ForgeAdapter.adapt(biome)); return new ForgeBiomeData(ForgeAdapter.adapt(biome));
@ -52,7 +51,7 @@ class ForgeBiomeRegistry implements BiomeRegistry {
@Override @Override
public String getName() { public String getName() {
return biome.getBiomeName(); return biome.getDisplayName().getString();
} }
} }

View File

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

View File

@ -23,11 +23,9 @@ import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.world.block.BlockType; import com.sk89q.worldedit.world.block.BlockType;
import com.sk89q.worldedit.world.registry.BlockMaterial; import com.sk89q.worldedit.world.registry.BlockMaterial;
import com.sk89q.worldedit.world.registry.BundledBlockRegistry; import com.sk89q.worldedit.world.registry.BundledBlockRegistry;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.material.Material; import net.minecraft.block.material.Material;
import net.minecraft.block.properties.IProperty; import net.minecraft.state.IProperty;
import net.minecraft.util.ResourceLocation;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
@ -43,21 +41,31 @@ public class ForgeBlockRegistry extends BundledBlockRegistry {
@Nullable @Nullable
@Override @Override
public String getName(BlockType blockType) { 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 @Override
public BlockMaterial getMaterial(BlockType blockType) { 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))); m -> new ForgeBlockMaterial(m, super.getMaterial(blockType)));
} }
@Override @Override
public Map<String, ? extends Property<?>> getProperties(BlockType blockType) { public Map<String, ? extends Property<?>> getProperties(BlockType blockType) {
Block block = ForgeAdapter.adapt(blockType);
Map<String, Property<?>> map = new TreeMap<>(); Map<String, Property<?>> map = new TreeMap<>();
Collection<IProperty<?>> propertyKeys = Block.getBlockFromName(blockType.getId()) Collection<IProperty<?>> propertyKeys = block
.getDefaultState() .getDefaultState()
.getPropertyKeys(); .getProperties();
for (IProperty<?> key : propertyKeys) { for (IProperty<?> key : propertyKeys) {
map.put(key.getName(), ForgeAdapter.adaptProperty(key)); map.put(key.getName(), ForgeAdapter.adaptProperty(key));
} }

View File

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

View File

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

View File

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

View File

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

View File

@ -24,6 +24,7 @@ import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.entity.BaseEntity; import com.sk89q.worldedit.entity.BaseEntity;
import com.sk89q.worldedit.extension.platform.AbstractPlayerActor; import com.sk89q.worldedit.extension.platform.AbstractPlayerActor;
import com.sk89q.worldedit.extent.inventory.BlockBag; 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.internal.cui.CUIEvent;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3; 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.util.Location;
import com.sk89q.worldedit.world.block.BaseBlock; import com.sk89q.worldedit.world.block.BaseBlock;
import com.sk89q.worldedit.world.block.BlockStateHolder; import com.sk89q.worldedit.world.block.BlockStateHolder;
import com.sk89q.worldedit.world.item.ItemTypes;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.network.PacketBuffer; import net.minecraft.network.PacketBuffer;
import net.minecraft.network.play.server.SPacketCustomPayload; import net.minecraft.network.play.server.SPacketCustomPayload;
import net.minecraft.network.play.server.SPacketUpdateTileEntity; import net.minecraft.network.play.server.SPacketUpdateTileEntity;
import net.minecraft.util.EnumHand; import net.minecraft.util.EnumHand;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.TextComponentString; import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting; import net.minecraft.util.text.TextFormatting;
import net.minecraftforge.fml.common.registry.ForgeRegistries;
import java.util.UUID; import java.util.UUID;
@ -69,12 +68,12 @@ public class ForgePlayer extends AbstractPlayerActor {
@Override @Override
public BaseItemStack getItemInHand(HandSide handSide) { public BaseItemStack getItemInHand(HandSide handSide) {
ItemStack is = this.player.getHeldItem(handSide == HandSide.MAIN_HAND ? EnumHand.MAIN_HAND : EnumHand.OFF_HAND); ItemStack is = this.player.getHeldItem(handSide == HandSide.MAIN_HAND ? EnumHand.MAIN_HAND : EnumHand.OFF_HAND);
return new BaseItemStack(ItemTypes.get(ForgeRegistries.ITEMS.getKey(is.getItem()).toString())); return ForgeAdapter.adapt(is);
} }
@Override @Override
public String getName() { public String getName() {
return this.player.getName(); return this.player.getName().getFormattedText();
} }
@Override @Override
@ -105,8 +104,7 @@ public class ForgePlayer extends AbstractPlayerActor {
@Override @Override
public void giveItem(BaseItemStack itemStack) { public void giveItem(BaseItemStack itemStack) {
this.player.inventory.addItemStackToInventory( this.player.inventory.addItemStackToInventory(ForgeAdapter.adapt(itemStack));
new ItemStack(Item.getByNameOrId(itemStack.getType().getId()), itemStack.getAmount(), 0));
} }
@Override @Override
@ -117,7 +115,7 @@ public class ForgePlayer extends AbstractPlayerActor {
send = send + "|" + StringUtil.joinString(params, "|"); send = send + "|" + StringUtil.joinString(params, "|");
} }
PacketBuffer buffer = new PacketBuffer(Unpooled.copiedBuffer(send.getBytes(WECUIPacketHandler.UTF_8_CHARSET))); 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); this.player.connection.sendPacket(packet);
} }
@ -197,7 +195,7 @@ public class ForgePlayer extends AbstractPlayerActor {
@Override @Override
public SessionKey getSessionKey() { public SessionKey getSessionKey() {
return new SessionKeyImpl(player.getUniqueID(), player.getName()); return new SessionKeyImpl(player.getUniqueID(), player.getName().getString());
} }
private static class SessionKeyImpl implements SessionKey { private static class SessionKeyImpl implements SessionKey {

View File

@ -21,7 +21,6 @@ package com.sk89q.worldedit.forge;
import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.io.Files;
import com.sk89q.jnbt.CompoundTag; import com.sk89q.jnbt.CompoundTag;
import com.sk89q.worldedit.EditSession; import com.sk89q.worldedit.EditSession;
import com.sk89q.worldedit.MaxChangedBlocksException; 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.BlockVector2;
import com.sk89q.worldedit.math.BlockVector3; import com.sk89q.worldedit.math.BlockVector3;
import com.sk89q.worldedit.math.Vector3; import com.sk89q.worldedit.math.Vector3;
import com.sk89q.worldedit.regions.CuboidRegion;
import com.sk89q.worldedit.regions.Region; import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.registry.state.Property;
import com.sk89q.worldedit.util.Direction; import com.sk89q.worldedit.util.Direction;
import com.sk89q.worldedit.util.Location; import com.sk89q.worldedit.util.Location;
import com.sk89q.worldedit.util.TreeGenerator.TreeType; 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.BaseBlock;
import com.sk89q.worldedit.world.block.BlockState; import com.sk89q.worldedit.world.block.BlockState;
import com.sk89q.worldedit.world.block.BlockStateHolder; 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.item.ItemTypes;
import com.sk89q.worldedit.world.weather.WeatherType; import com.sk89q.worldedit.world.weather.WeatherType;
import com.sk89q.worldedit.world.weather.WeatherTypes; import com.sk89q.worldedit.world.weather.WeatherTypes;
import net.minecraft.block.Block;
import net.minecraft.block.BlockLeaves; 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.block.state.IBlockState;
import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityType;
import net.minecraft.entity.item.EntityItem; import net.minecraft.entity.item.EntityItem;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.inventory.IInventory; import net.minecraft.inventory.IInventory;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import net.minecraft.item.ItemUseContext;
import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.server.MinecraftServer;
import net.minecraft.tileentity.TileEntity; import net.minecraft.tileentity.TileEntity;
import net.minecraft.util.EnumActionResult; 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.ResourceLocation;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.WorldServer; import net.minecraft.world.WorldServer;
import net.minecraft.world.biome.Biome;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.IChunkProvider; import net.minecraft.world.gen.feature.BigBrownMushroomFeature;
import net.minecraft.world.chunk.storage.AnvilSaveHandler; import net.minecraft.world.gen.feature.BigRedMushroomFeature;
import net.minecraft.world.gen.ChunkProviderServer; import net.minecraft.world.gen.feature.BigTreeFeature;
import net.minecraft.world.gen.feature.WorldGenBigMushroom; import net.minecraft.world.gen.feature.BirchTreeFeature;
import net.minecraft.world.gen.feature.WorldGenBigTree; import net.minecraft.world.gen.feature.CanopyTreeFeature;
import net.minecraft.world.gen.feature.WorldGenBirchTree; import net.minecraft.world.gen.feature.Feature;
import net.minecraft.world.gen.feature.WorldGenCanopyTree; import net.minecraft.world.gen.feature.JungleTreeFeature;
import net.minecraft.world.gen.feature.WorldGenMegaJungle; import net.minecraft.world.gen.feature.MegaJungleFeature;
import net.minecraft.world.gen.feature.WorldGenMegaPineTree; import net.minecraft.world.gen.feature.MegaPineTree;
import net.minecraft.world.gen.feature.WorldGenSavannaTree; import net.minecraft.world.gen.feature.NoFeatureConfig;
import net.minecraft.world.gen.feature.WorldGenShrub; import net.minecraft.world.gen.feature.PointyTaigaTreeFeature;
import net.minecraft.world.gen.feature.WorldGenSwamp; import net.minecraft.world.gen.feature.SavannaTreeFeature;
import net.minecraft.world.gen.feature.WorldGenTaiga1; import net.minecraft.world.gen.feature.ShrubFeature;
import net.minecraft.world.gen.feature.WorldGenTaiga2; import net.minecraft.world.gen.feature.SwampTreeFeature;
import net.minecraft.world.gen.feature.WorldGenTrees; import net.minecraft.world.gen.feature.TallTaigaTreeFeature;
import net.minecraft.world.gen.feature.WorldGenerator; import net.minecraft.world.gen.feature.TreeFeature;
import net.minecraft.world.storage.WorldInfo; import net.minecraft.world.storage.WorldInfo;
import net.minecraftforge.common.DimensionManager;
import java.io.File;
import java.lang.ref.WeakReference; import java.lang.ref.WeakReference;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.Random; import java.util.Random;
import java.util.TreeMap; import java.util.concurrent.ThreadLocalRandom;
import javax.annotation.Nullable; import javax.annotation.Nullable;
@ -116,9 +96,9 @@ public class ForgeWorld extends AbstractWorld {
private static final Random random = new Random(); private static final Random random = new Random();
private static final int UPDATE = 1, NOTIFY = 2; 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_LOG = Blocks.JUNGLE_LOG.getDefaultState();
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_LEAF = Blocks.JUNGLE_LEAVES.getDefaultState().with(BlockLeaves.PERSISTENT, Boolean.TRUE);
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_SHRUB = Blocks.OAK_LEAVES.getDefaultState().with(BlockLeaves.PERSISTENT, Boolean.TRUE);
private final WeakReference<World> worldRef; private final WeakReference<World> worldRef;
@ -178,14 +158,11 @@ public class ForgeWorld extends AbstractWorld {
int z = position.getBlockZ(); int z = position.getBlockZ();
// First set the block // 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); BlockPos pos = new BlockPos(x, y, z);
IBlockState old = chunk.getBlockState(pos); IBlockState old = chunk.getBlockState(pos);
Block mcBlock = Block.getBlockFromName(block.getBlockType().getId()); IBlockState newState = ForgeAdapter.adapt(block.toImmutableState());
IBlockState newState = mcBlock.getDefaultState(); IBlockState successState = chunk.setBlockState(pos, newState, false);
Map<Property<?>, Object> states = block.getStates();
newState = applyProperties(mcBlock.getBlockState(), newState, states);
IBlockState successState = chunk.setBlockState(pos, newState);
boolean successful = successState != null; boolean successful = successState != null;
// Create the TileEntity // Create the TileEntity
@ -194,7 +171,7 @@ public class ForgeWorld extends AbstractWorld {
// Kill the old TileEntity // Kill the old TileEntity
world.removeTileEntity(pos); world.removeTileEntity(pos);
NBTTagCompound nativeTag = NBTConverter.toNative(((BaseBlock) block).getNbtData()); NBTTagCompound nativeTag = NBTConverter.toNative(((BaseBlock) block).getNbtData());
nativeTag.setString("id", ((BaseBlock) block).getNbtId()); nativeTag.putString("id", ((BaseBlock) block).getNbtId());
TileEntityUtils.setTileEntity(world, position, nativeTag); TileEntityUtils.setTileEntity(world, position, nativeTag);
} }
} }
@ -216,29 +193,6 @@ public class ForgeWorld extends AbstractWorld {
return false; return false;
} }
// Can't get the "Object" to be right for withProperty w/o this
@SuppressWarnings({ "rawtypes", "unchecked" })
private IBlockState applyProperties(BlockStateContainer stateContainer, IBlockState newState, Map<Property<?>, Object> states) {
for (Map.Entry<Property<?>, Object> state : states.entrySet()) {
IProperty property = stateContainer.getProperty(state.getKey().getName());
Comparable value = (Comparable) state.getValue();
// we may need to adapt this value, depending on the source prop
if (property instanceof PropertyDirection) {
Direction dir = (Direction) value;
value = ForgeAdapter.adapt(dir);
} else if (property instanceof PropertyEnum) {
String enumName = (String) value;
value = ((PropertyEnum<?>) property).parseValue((String) value).or(() -> {
throw new IllegalStateException("Enum property " + property.getName() + " does not contain " + enumName);
});
}
newState = newState.withProperty(property, value);
}
return newState;
}
@Override @Override
public int getBlockLightLevel(BlockVector3 position) { public int getBlockLightLevel(BlockVector3 position) {
checkNotNull(position); checkNotNull(position);
@ -263,7 +217,7 @@ public class ForgeWorld extends AbstractWorld {
@Override @Override
public BiomeType getBiome(BlockVector2 position) { public BiomeType getBiome(BlockVector2 position) {
checkNotNull(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 @Override
@ -271,9 +225,9 @@ public class ForgeWorld extends AbstractWorld {
checkNotNull(position); checkNotNull(position);
checkNotNull(biome); 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()) { 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; return true;
} }
@ -282,16 +236,24 @@ public class ForgeWorld extends AbstractWorld {
@Override @Override
public boolean useItem(BlockVector3 position, BaseItem item, Direction face) { public boolean useItem(BlockVector3 position, BaseItem item, Direction face) {
Item nativeItem = Item.getByNameOrId(item.getType().getId()); Item nativeItem = ForgeAdapter.adapt(item.getType());
ItemStack stack = null; ItemStack stack;
if (item.getNbtData() == null) { if (item.getNbtData() == null) {
stack = new ItemStack(nativeItem, 1, 0); stack = new ItemStack(nativeItem, 1);
} else { } else {
stack = new ItemStack(nativeItem, 1, 0, NBTConverter.toNative(item.getNbtData())); stack = new ItemStack(nativeItem, 1, NBTConverter.toNative(item.getNbtData()));
} }
World world = getWorld(); World world = getWorld();
EnumActionResult used = stack.onItemUse(new WorldEditFakePlayer((WorldServer) world), world, ForgeAdapter.toBlockPos(position), ItemUseContext itemUseContext = new ItemUseContext(
EnumHand.MAIN_HAND, ForgeAdapter.adapt(face), 0, 0, 0); new WorldEditFakePlayer((WorldServer) world),
stack,
ForgeAdapter.toBlockPos(position),
ForgeAdapter.adapt(face),
0f,
0f,
0f
);
EnumActionResult used = stack.onItemUse(itemUseContext);
return used != EnumActionResult.FAIL; return used != EnumActionResult.FAIL;
} }
@ -304,7 +266,7 @@ public class ForgeWorld extends AbstractWorld {
return; 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); entity.setPickupDelay(10);
getWorld().spawnEntity(entity); getWorld().spawnEntity(entity);
} }
@ -313,75 +275,75 @@ public class ForgeWorld extends AbstractWorld {
public void simulateBlockMine(BlockVector3 position) { public void simulateBlockMine(BlockVector3 position) {
BlockPos pos = ForgeAdapter.toBlockPos(position); BlockPos pos = ForgeAdapter.toBlockPos(position);
IBlockState state = getWorld().getBlockState(pos); IBlockState state = getWorld().getBlockState(pos);
state.getBlock().dropBlockAsItem(getWorld(), pos, state, 0); state.dropBlockAsItem(getWorld(), pos, 0);
getWorld().setBlockToAir(pos); getWorld().removeBlock(pos);
} }
@Override @Override
public boolean regenerate(Region region, EditSession editSession) { public boolean regenerate(Region region, EditSession editSession) {
// Don't even try to regen if it's going to fail. // TODO Fix for 1.13
IChunkProvider provider = getWorld().getChunkProvider(); return false;
if (!(provider instanceof ChunkProviderServer)) { // // Don't even try to regen if it's going to fail.
return false; // 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 // File saveFolder = Files.createTempDir();
saveFolder.deleteOnExit(); // // register this just in case something goes wrong
// // normally it should be deleted at the end of this method
WorldServer originalWorld = (WorldServer) getWorld(); // saveFolder.deleteOnExit();
//
MinecraftServer server = originalWorld.getMinecraftServer(); // WorldServer originalWorld = (WorldServer) getWorld();
AnvilSaveHandler saveHandler = new AnvilSaveHandler(saveFolder, //
originalWorld.getSaveHandler().getWorldDirectory().getName(), true, server.getDataFixer()); // MinecraftServer server = originalWorld.getServer();
World freshWorld = new WorldServer(server, saveHandler, originalWorld.getWorldInfo(), // AnvilSaveHandler saveHandler = new AnvilSaveHandler(saveFolder, originalWorld.getSaveHandler().getWorldDirectory().getName(), server, server.getDataFixer());
originalWorld.provider.getDimension(), originalWorld.profiler).init(); // World freshWorld = new WorldServer(server, saveHandler, originalWorld.getSavedDataStorage(), originalWorld.getWorldInfo(), originalWorld.dimension.getType(), originalWorld.profiler).func_212251_i__();
//
// Pre-gen all the chunks // // Pre-gen all the chunks
// We need to also pull one more chunk in every direction // // 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)); // CuboidRegion expandedPreGen = new CuboidRegion(region.getMinimumPoint().subtract(16, 0, 16), region.getMaximumPoint().add(16, 0, 16));
for (BlockVector2 chunk : expandedPreGen.getChunks()) { // for (BlockVector2 chunk : expandedPreGen.getChunks()) {
freshWorld.getChunkFromChunkCoords(chunk.getBlockX(), chunk.getBlockZ()); // freshWorld.getChunk(chunk.getBlockX(), chunk.getBlockZ());
} // }
//
ForgeWorld from = new ForgeWorld(freshWorld); // ForgeWorld from = new ForgeWorld(freshWorld);
try { // try {
for (BlockVector3 vec : region) { // for (BlockVector3 vec : region) {
editSession.setBlock(vec, from.getFullBlock(vec)); // editSession.setBlock(vec, from.getFullBlock(vec));
} // }
} catch (MaxChangedBlocksException e) { // } catch (MaxChangedBlocksException e) {
throw new RuntimeException(e); // throw new RuntimeException(e);
} finally { // } finally {
saveFolder.delete(); // saveFolder.delete();
DimensionManager.setWorld(originalWorld.provider.getDimension(), null, server); // DimensionManager.setWorld(originalWorld.dimension.getType(), null, server);
DimensionManager.setWorld(originalWorld.provider.getDimension(), originalWorld, server); // DimensionManager.setWorld(originalWorld.dimension.getType(), originalWorld, server);
} // }
//
return true; // return true;
} }
@Nullable @Nullable
private static WorldGenerator createWorldGenerator(TreeType type) { private static Feature<NoFeatureConfig> createTreeFeatureGenerator(TreeType type) {
switch (type) { switch (type) {
case TREE: return new WorldGenTrees(true); case TREE: return new TreeFeature(true);
case BIG_TREE: return new WorldGenBigTree(true); case BIG_TREE: return new BigTreeFeature(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 PINE: 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: case RANDOM_REDWOOD:
default: default:
return null; return null;
@ -390,13 +352,13 @@ public class ForgeWorld extends AbstractWorld {
@Override @Override
public boolean generateTree(TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException { public boolean generateTree(TreeType type, EditSession editSession, BlockVector3 position) throws MaxChangedBlocksException {
WorldGenerator generator = createWorldGenerator(type); Feature<NoFeatureConfig> generator = createTreeFeatureGenerator(type);
return generator != null && generator.generate(getWorld(), random, ForgeAdapter.toBlockPos(position)); return generator != null && generator.place(getWorld(), getWorld().getChunkProvider().getChunkGenerator(), random, ForgeAdapter.toBlockPos(position), new NoFeatureConfig());
} }
@Override @Override
public void checkLoadedChunk(BlockVector3 pt) { public void checkLoadedChunk(BlockVector3 pt) {
getWorld().getChunkFromBlockCoords(ForgeAdapter.toBlockPos(pt)); getWorld().getChunk(ForgeAdapter.toBlockPos(pt));
} }
@Override @Override
@ -408,7 +370,7 @@ public class ForgeWorld extends AbstractWorld {
public void fixLighting(Iterable<BlockVector2> chunks) { public void fixLighting(Iterable<BlockVector2> chunks) {
World world = getWorld(); World world = getWorld();
for (BlockVector2 chunk : chunks) { 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()) { if (info.isRaining()) {
return info.getRainTime(); return info.getRainTime();
} }
return info.getCleanWeatherTime(); return info.getClearWeatherTime();
} }
@Override @Override
@ -450,18 +412,18 @@ public class ForgeWorld extends AbstractWorld {
@Override @Override
public void setWeather(WeatherType weatherType, long duration) { public void setWeather(WeatherType weatherType, long duration) {
WorldInfo info = getWorld().getWorldInfo(); WorldInfo info = getWorld().getWorldInfo();
if (WeatherTypes.THUNDER_STORM.equals(weatherType)) { if (weatherType == WeatherTypes.THUNDER_STORM) {
info.setCleanWeatherTime(0); info.setClearWeatherTime(0);
info.setThundering(true); info.setThundering(true);
info.setThunderTime((int) duration); info.setThunderTime((int) duration);
} else if (WeatherTypes.RAIN.equals(weatherType)) { } else if (weatherType == WeatherTypes.RAIN) {
info.setCleanWeatherTime(0); info.setClearWeatherTime(0);
info.setRaining(true); info.setRaining(true);
info.setRainTime((int) duration); info.setRainTime((int) duration);
} else if (WeatherTypes.CLEAR.equals(weatherType)) { } else if (weatherType == WeatherTypes.CLEAR) {
info.setRaining(false); info.setRaining(false);
info.setThundering(false); info.setThundering(false);
info.setCleanWeatherTime((int) duration); info.setClearWeatherTime((int) duration);
} }
} }
@ -472,26 +434,13 @@ public class ForgeWorld extends AbstractWorld {
@Override @Override
public BlockState getBlock(BlockVector3 position) { public BlockState getBlock(BlockVector3 position) {
World world = getWorld(); IBlockState mcState = getWorld().getChunk(position.getBlockX() >> 4, position.getBlockZ() >> 4).getBlockState(
BlockPos pos = new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()); position.getBlockX(),
IBlockState mcState = world.getBlockState(pos); position.getBlockY(),
position.getBlockZ()
);
BlockType blockType = BlockType.REGISTRY.get(Block.REGISTRY.getNameForObject(mcState.getBlock()).toString()); return ForgeAdapter.adapt(mcState);
return blockType.getState(adaptProperties(blockType, mcState.getProperties()));
}
private Map<Property<?>, Object> adaptProperties(BlockType block, Map<IProperty<?>, Comparable<?>> mcProps) {
Map<Property<?>, Object> props = new TreeMap<>(Comparator.comparing(Property::getName));
for (Map.Entry<IProperty<?>, Comparable<?>> prop : mcProps.entrySet()) {
Object value = prop.getValue();
if (prop.getKey() instanceof PropertyDirection) {
value = ForgeAdapter.adaptEnumFacing((EnumFacing) value);
} else if (prop.getKey() instanceof PropertyEnum) {
value = ((IStringSerializable) value).getName();
}
props.put(block.getProperty(prop.getKey().getName()), value);
}
return props;
} }
@Override @Override
@ -551,15 +500,15 @@ public class ForgeWorld extends AbstractWorld {
@Override @Override
public Entity createEntity(Location location, BaseEntity entity) { public Entity createEntity(Location location, BaseEntity entity) {
World world = getWorld(); 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) { if (createdEntity != null) {
CompoundTag nativeTag = entity.getNbtData(); CompoundTag nativeTag = entity.getNbtData();
if (nativeTag != null) { if (nativeTag != null) {
NBTTagCompound tag = NBTConverter.toNative(entity.getNbtData()); NBTTagCompound tag = NBTConverter.toNative(entity.getNbtData());
for (String name : Constants.NO_COPY_ENTITY_NBT_FIELDS) { 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()); createdEntity.setLocationAndAngles(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch());

View File

@ -20,152 +20,200 @@
package com.sk89q.worldedit.forge; package com.sk89q.worldedit.forge;
import static com.google.common.base.Preconditions.checkNotNull; 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.LocalSession;
import com.sk89q.worldedit.WorldEdit; import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.blocks.BaseItemStack;
import com.sk89q.worldedit.event.platform.PlatformReadyEvent; import com.sk89q.worldedit.event.platform.PlatformReadyEvent;
import com.sk89q.worldedit.extension.platform.Platform; 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.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.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.ItemType;
import com.sk89q.worldedit.world.item.ItemTypes; import net.minecraft.client.Minecraft;
import net.minecraft.block.Block; import net.minecraft.command.CommandSource;
import net.minecraft.entity.player.EntityPlayerMP; import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.item.Item; import net.minecraft.tags.BlockTags;
import net.minecraft.item.ItemStack; import net.minecraft.tags.ItemTags;
import net.minecraft.nbt.NBTTagCompound;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraftforge.api.distmarker.Dist;
import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.MinecraftForge;
import net.minecraftforge.event.CommandEvent; import net.minecraftforge.event.CommandEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent; import net.minecraftforge.event.entity.player.PlayerInteractEvent;
import net.minecraftforge.event.entity.player.PlayerInteractEvent.LeftClickEmpty; 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;
import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
import net.minecraftforge.fml.common.Mod.Instance; import net.minecraftforge.fml.event.lifecycle.FMLLoadCompleteEvent;
import net.minecraftforge.fml.common.SidedProxy; import net.minecraftforge.fml.event.server.FMLServerAboutToStartEvent;
import net.minecraftforge.fml.common.event.FMLInitializationEvent; import net.minecraftforge.fml.event.server.FMLServerStartedEvent;
import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.event.server.FMLServerStoppingEvent;
import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
import net.minecraftforge.fml.common.event.FMLServerAboutToStartEvent; import net.minecraftforge.fml.loading.FMLLoader;
import net.minecraftforge.fml.common.event.FMLServerStartedEvent; import net.minecraftforge.fml.loading.FMLPaths;
import net.minecraftforge.fml.common.event.FMLServerStoppingEvent; import net.minecraftforge.registries.ForgeRegistries;
import net.minecraftforge.fml.common.eventhandler.Event.Result; import org.apache.logging.log4j.LogManager;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
import java.io.File; 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. * The Forge implementation of WorldEdit.
*/ */
@Mod(modid = ForgeWorldEdit.MOD_ID, name = "WorldEdit", version = "%VERSION%", acceptableRemoteVersions = "*") @Mod(ForgeWorldEdit.MOD_ID)
public class ForgeWorldEdit { 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 MOD_ID = "worldedit";
public static final String CUI_PLUGIN_CHANNEL = "worldedit:cui"; public static final String CUI_PLUGIN_CHANNEL = "cui";
private ForgePermissionsProvider provider; private ForgePermissionsProvider provider;
@Instance(MOD_ID)
public static ForgeWorldEdit inst; public static ForgeWorldEdit inst;
@SidedProxy(serverSide = "com.sk89q.worldedit.forge.CommonProxy", clientSide = "com.sk89q.worldedit.forge.ClientProxy") public static CommonProxy proxy = DistExecutor.runForDist(() -> ClientProxy::new, () -> CommonProxy::new);
public static CommonProxy proxy;
private ForgePlatform platform; private ForgePlatform platform;
private ForgeConfiguration config; private ForgeConfiguration config;
private File workingDir; private Path workingDir;
@EventHandler private ModContainer container;
public void preInit(FMLPreInitializationEvent event) {
logger = event.getModLog();
// Setup working directory
workingDir = new File(event.getModConfigurationDirectory() + File.separator + "worldedit");
workingDir.mkdir();
config = new ForgeConfiguration(this); public ForgeWorldEdit() {
config.load(); 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(ThreadSafeCache.getInstance());
MinecraftForge.EVENT_BUS.register(this);
} }
@EventHandler private void init(FMLCommonSetupEvent event) {
public void init(FMLInitializationEvent event) { this.container = ModLoadingContext.get().getActiveContainer();
MinecraftForge.EVENT_BUS.register(this);
// 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(); WECUIPacketHandler.init();
InternalPacketHandler.init(); InternalPacketHandler.init();
proxy.registerHandlers(); proxy.registerHandlers();
LOGGER.info("WorldEdit for Forge (version " + getInternalVersion() + ") is loaded");
} }
@EventHandler private void load(FMLLoadCompleteEvent event) {
public void postInit(FMLPostInitializationEvent event) { if (FMLLoader.getDist() == Dist.CLIENT) {
logger.info("WorldEdit for Forge (version " + getInternalVersion() + ") is loaded"); // 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) { public void serverAboutToStart(FMLServerAboutToStartEvent event) {
if (this.platform != null) { 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); WorldEdit.getInstance().getPlatformManager().unregister(platform);
} }
setupPlatform();
}
private void setupPlatform() {
this.platform = new ForgePlatform(this); this.platform = new ForgePlatform(this);
WorldEdit.getInstance().getPlatformManager().register(platform); WorldEdit.getInstance().getPlatformManager().register(platform);
if (Loader.isModLoaded("sponge")) { // TODO if (ModList.get().isLoaded("sponge")) {
this.provider = new ForgePermissionsProvider.SpongePermissionsProvider(); // this.provider = new ForgePermissionsProvider.SpongePermissionsProvider();
} else { // } else {
this.provider = new ForgePermissionsProvider.VanillaPermissionsProvider(platform); this.provider = new ForgePermissionsProvider.VanillaPermissionsProvider(platform);
} // }
for (ResourceLocation name : Block.REGISTRY.getKeys()) { setupRegistries();
String nameStr = name.toString();
if (!BlockType.REGISTRY.keySet().contains(nameStr)) { config = new ForgeConfiguration(this);
BlockType.REGISTRY.register(nameStr, new BlockType(nameStr)); 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())));
} }
} }
// Items
for (ResourceLocation name : Item.REGISTRY.getKeys()) { for (ResourceLocation name : ForgeRegistries.ITEMS.getKeys()) {
String nameStr = name.toString(); if (ItemType.REGISTRY.get(name.toString()) == null) {
if (!ItemType.REGISTRY.keySet().contains(nameStr)) { ItemType.REGISTRY.register(name.toString(), new ItemType(name.toString()));
ItemType.REGISTRY.register(nameStr, new ItemType(nameStr)); }
}
// 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) { public void serverStopping(FMLServerStoppingEvent event) {
WorldEdit worldEdit = WorldEdit.getInstance(); WorldEdit worldEdit = WorldEdit.getInstance();
worldEdit.getSessionManager().unload(); worldEdit.getSessionManager().unload();
worldEdit.getPlatformManager().unregister(platform); worldEdit.getPlatformManager().unregister(platform);
} }
@EventHandler @SubscribeEvent
public void serverStarted(FMLServerStartedEvent event) { public void serverStarted(FMLServerStartedEvent event) {
WorldEdit.getInstance().getEventBus().post(new PlatformReadyEvent()); 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 @SubscribeEvent
public void onPlayerInteract(PlayerInteractEvent event) { public void onPlayerInteract(PlayerInteractEvent event) {
if (platform == null) { if (platform == null) {
@ -177,23 +225,23 @@ public class ForgeWorldEdit {
if (event.getWorld().isRemote && event instanceof LeftClickEmpty) { if (event.getWorld().isRemote && event instanceof LeftClickEmpty) {
// catch LCE, pass it to server // catch LCE, pass it to server
InternalPacketHandler.CHANNEL.sendToServer(new LeftClickAirEventMessage()); InternalPacketHandler.HANDLER.sendToServer(new LeftClickAirEventMessage());
return; return;
} }
boolean isLeftDeny = event instanceof PlayerInteractEvent.LeftClickBlock boolean isLeftDeny = event instanceof PlayerInteractEvent.LeftClickBlock
&& ((PlayerInteractEvent.LeftClickBlock) event) && ((PlayerInteractEvent.LeftClickBlock) event)
.getUseItem() == Result.DENY; .getUseItem() == Event.Result.DENY;
boolean isRightDeny = boolean isRightDeny =
event instanceof PlayerInteractEvent.RightClickBlock event instanceof PlayerInteractEvent.RightClickBlock
&& ((PlayerInteractEvent.RightClickBlock) event) && ((PlayerInteractEvent.RightClickBlock) event)
.getUseItem() == Result.DENY; .getUseItem() == Event.Result.DENY;
if (isLeftDeny || isRightDeny || event.getEntity().world.isRemote) { if (isLeftDeny || isRightDeny || event.getEntity().world.isRemote) {
return; return;
} }
WorldEdit we = WorldEdit.getInstance(); WorldEdit we = WorldEdit.getInstance();
ForgePlayer player = wrap((EntityPlayerMP) event.getEntityPlayer()); ForgePlayer player = adaptPlayer((EntityPlayerMP) event.getEntityPlayer());
ForgeWorld world = getWorld(event.getEntityPlayer().world); ForgeWorld world = getWorld(event.getEntityPlayer().world);
if (event instanceof PlayerInteractEvent.LeftClickEmpty) { if (event instanceof PlayerInteractEvent.LeftClickEmpty) {
@ -228,12 +276,24 @@ public class ForgeWorldEdit {
} }
} }
public static ItemStack toForgeItemStack(BaseItemStack item) { @SubscribeEvent
NBTTagCompound forgeCompound = null; public void onCommandEvent(CommandEvent event) throws CommandSyntaxException {
if (item.getNbtData() != null) { ParseResults<CommandSource> parseResults = event.getParseResults();
forgeCompound = NBTConverter.toNative(item.getNbtData()); 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; 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. * Get the session for a player.
* *
@ -264,7 +313,7 @@ public class ForgeWorldEdit {
*/ */
public LocalSession getSession(EntityPlayerMP player) { public LocalSession getSession(EntityPlayerMP player) {
checkNotNull(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 * @return the working directory
*/ */
public File getWorkingDir() { public File getWorkingDir() {
return this.workingDir; return this.workingDir.toFile();
} }
/** /**
@ -302,7 +351,7 @@ public class ForgeWorldEdit {
* @return a version string * @return a version string
*/ */
String getInternalVersion() { String getInternalVersion() {
return ForgeWorldEdit.class.getAnnotation(Mod.class).version(); return container.getModInfo().getVersion().toString();
} }
public void setPermissionsProvider(ForgePermissionsProvider provider) { public void setPermissionsProvider(ForgePermissionsProvider provider) {

View File

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

View File

@ -1,40 +0,0 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.forge.net.LeftClickAirEventMessage;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import net.minecraftforge.fml.common.network.simpleimpl.SimpleNetworkWrapper;
import net.minecraftforge.fml.relauncher.Side;
import java.nio.charset.Charset;
public class InternalPacketHandler {
public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");
public static SimpleNetworkWrapper CHANNEL;
public static void init() {
CHANNEL = NetworkRegistry.INSTANCE.newSimpleChannel(ForgeWorldEdit.MOD_ID);
CHANNEL.registerMessage(LeftClickAirEventMessage.Handler.class, LeftClickAirEventMessage.class, 0, Side.SERVER);
}
private InternalPacketHandler() {
}
}

View File

@ -19,18 +19,18 @@
package com.sk89q.worldedit.forge; 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.Minecraft;
import net.minecraft.client.settings.KeyBinding; import net.minecraft.client.settings.KeyBinding;
import net.minecraftforge.eventbus.api.SubscribeEvent;
import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.client.registry.ClientRegistry;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.gameevent.InputEvent.KeyInputEvent; import net.minecraftforge.fml.common.gameevent.InputEvent.KeyInputEvent;
import org.lwjgl.input.Keyboard; import org.lwjgl.glfw.GLFW;
public class KeyHandler { public class KeyHandler {
private static Minecraft mc = Minecraft.getMinecraft(); private static Minecraft mc = Minecraft.getInstance();
private static KeyBinding mainKey = new KeyBinding("WorldEdit Reference", Keyboard.KEY_L, "WorldEdit"); private static KeyBinding mainKey = new KeyBinding("WorldEdit Reference", GLFW.GLFW_KEY_L, "WorldEdit");
public KeyHandler() { public KeyHandler() {
ClientRegistry.registerKeyBinding(mainKey); ClientRegistry.registerKeyBinding(mainKey);
@ -39,7 +39,9 @@ public class KeyHandler {
@SubscribeEvent @SubscribeEvent
public void onKey(KeyInputEvent evt) { public void onKey(KeyInputEvent evt) {
if (mc.player != null && mc.world != null && mainKey.isPressed()) { 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));
} }
} }

View File

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

View File

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

View File

@ -52,9 +52,9 @@ final class TileEntityUtils {
checkNotNull(tag); checkNotNull(tag);
checkNotNull(position); checkNotNull(position);
tag.setTag("x", new NBTTagInt(position.getBlockX())); tag.put("x", new NBTTagInt(position.getBlockX()));
tag.setTag("y", new NBTTagInt(position.getBlockY())); tag.put("y", new NBTTagInt(position.getBlockY()));
tag.setTag("z", new NBTTagInt(position.getBlockZ())); tag.put("z", new NBTTagInt(position.getBlockZ()));
return tag; return tag;
} }
@ -81,7 +81,7 @@ final class TileEntityUtils {
if (tag != null) { if (tag != null) {
// Set X, Y, Z // Set X, Y, Z
updateForSet(tag, position); updateForSet(tag, position);
tileEntity.readFromNBT(tag); tileEntity.read(tag);
} }
world.setTileEntity(new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()), tileEntity); 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) { static void setTileEntity(World world, BlockVector3 position, @Nullable NBTTagCompound tag) {
if (tag != null) { if (tag != null) {
updateForSet(tag, position); updateForSet(tag, position);
TileEntity tileEntity = TileEntity.create(world, tag); TileEntity tileEntity = TileEntity.create(tag);
if (tileEntity != null) { if (tileEntity != null) {
world.setTileEntity(new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()), tileEntity); world.setTileEntity(new BlockPos(position.getBlockX(), position.getBlockY(), position.getBlockZ()), tileEntity);
} }
@ -143,7 +143,7 @@ final class TileEntityUtils {
public static NBTTagCompound copyNbtData(TileEntity tile) { public static NBTTagCompound copyNbtData(TileEntity tile) {
NBTTagCompound tag = new NBTTagCompound(); NBTTagCompound tag = new NBTTagCompound();
tile.writeToNBT(tag); tile.write(tag);
return tag; return tag;
} }
} }

View File

@ -1,72 +0,0 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.forge;
import com.sk89q.worldedit.LocalSession;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.NetHandlerPlayServer;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.ThreadQuickExitException;
import net.minecraft.network.play.server.SPacketCustomPayload;
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent;
import net.minecraftforge.fml.common.network.FMLEventChannel;
import net.minecraftforge.fml.common.network.FMLNetworkEvent.ClientCustomPacketEvent;
import net.minecraftforge.fml.common.network.FMLNetworkEvent.ServerCustomPacketEvent;
import net.minecraftforge.fml.common.network.NetworkRegistry;
import java.nio.charset.Charset;
public class WECUIPacketHandler {
public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");
public static FMLEventChannel WECUI_CHANNEL;
public static void init() {
WECUI_CHANNEL = NetworkRegistry.INSTANCE.newEventDrivenChannel(ForgeWorldEdit.CUI_PLUGIN_CHANNEL);
WECUI_CHANNEL.register(new WECUIPacketHandler());
}
@SubscribeEvent
public void onPacketData(ServerCustomPacketEvent event) {
if (event.getPacket().channel().equals(ForgeWorldEdit.CUI_PLUGIN_CHANNEL)) {
EntityPlayerMP player = getPlayerFromEvent(event);
LocalSession session = ForgeWorldEdit.inst.getSession(player);
if (session.hasCUISupport()) {
return;
}
String text = event.getPacket().payload().toString(UTF_8_CHARSET);
session.handleCUIInitializationMessage(text);
session.describeCUI(ForgeWorldEdit.inst.wrap(player));
}
}
@SubscribeEvent
public void callProcessPacket(ClientCustomPacketEvent event) {
try {
new SPacketCustomPayload(event.getPacket().channel(), new PacketBuffer(event.getPacket().payload())).processPacket(event.getHandler());
} catch (ThreadQuickExitException suppress) {
}
}
private static EntityPlayerMP getPlayerFromEvent(ServerCustomPacketEvent event) {
return ((NetHandlerPlayServer) event.getHandler()).player;
}
}

View File

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

View File

@ -33,25 +33,26 @@ public class GuiReferenceCard extends GuiScreen {
@Override @Override
public void initGui() { 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 @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 x = (this.width - this.backgroundWidth) / 2;
int y = (this.height - this.backgroundHeight) / 2 - this.closeButton.height; int y = (this.height - this.backgroundHeight) / 2 - this.closeButton.height;
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F); 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); this.drawTexturedModalRect(x, y, 0, 0, this.backgroundWidth, this.backgroundHeight);
super.drawScreen(mouseX, mouseY, par3); super.render(mouseX, mouseY, par3);
}
@Override
protected void actionPerformed(GuiButton button) {
if (button.id == 0) {
this.mc.player.closeScreen();
}
} }
@Override @Override

View File

@ -0,0 +1,65 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.forge.gui;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.entity.player.InventoryPlayer;
import net.minecraft.inventory.Container;
import net.minecraft.util.ResourceLocation;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.world.IInteractionObject;
import javax.annotation.Nullable;
public class ResourceLocationInteractionObject implements IInteractionObject {
private ResourceLocation resourceLocation;
public ResourceLocationInteractionObject(ResourceLocation resourceLocation) {
this.resourceLocation = resourceLocation;
}
@Override
public Container createContainer(InventoryPlayer inventoryPlayer, EntityPlayer entityPlayer) {
throw new UnsupportedOperationException();
}
@Override
public String getGuiID() {
return resourceLocation.toString();
}
@Override
public ITextComponent getName() {
return new TextComponentString(resourceLocation.toString());
}
@Override
public boolean hasCustomName() {
return false;
}
@Nullable
@Override
public ITextComponent getCustomName() {
return null;
}
}

View File

@ -0,0 +1,45 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.forge.net.handler;
import com.sk89q.worldedit.forge.ForgeWorldEdit;
import com.sk89q.worldedit.forge.net.packet.LeftClickAirEventMessage;
import com.sk89q.worldedit.forge.net.packet.LeftClickAirEventMessage.Handler;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.network.NetworkRegistry.ChannelBuilder;
import net.minecraftforge.fml.network.simple.SimpleChannel;
public final class InternalPacketHandler {
private static final String PROTOCOL_VERSION = Integer.toString(1);
public static SimpleChannel HANDLER = ChannelBuilder
.named(new ResourceLocation(ForgeWorldEdit.MOD_ID, "internal"))
.clientAcceptedVersions(PROTOCOL_VERSION::equals)
.serverAcceptedVersions(PROTOCOL_VERSION::equals)
.networkProtocolVersion(() -> PROTOCOL_VERSION)
.simpleChannel();
private InternalPacketHandler() {
}
public static void init() {
HANDLER.registerMessage(0, LeftClickAirEventMessage.class,
LeftClickAirEventMessage::encode, LeftClickAirEventMessage::decode, Handler::handle);
}
}

View File

@ -0,0 +1,78 @@
/*
* WorldEdit, a Minecraft world manipulation toolkit
* Copyright (C) sk89q <http://www.sk89q.com>
* Copyright (C) WorldEdit team and contributors
*
* This program is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.forge.net.handler;
import com.sk89q.worldedit.LocalSession;
import com.sk89q.worldedit.forge.ForgeWorldEdit;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EntityPlayerMP;
import net.minecraft.network.ThreadQuickExitException;
import net.minecraft.network.play.server.SPacketCustomPayload;
import net.minecraft.util.ResourceLocation;
import net.minecraftforge.fml.network.NetworkEvent.ClientCustomPayloadEvent;
import net.minecraftforge.fml.network.NetworkEvent.ServerCustomPayloadEvent;
import net.minecraftforge.fml.network.NetworkRegistry.ChannelBuilder;
import net.minecraftforge.fml.network.event.EventNetworkChannel;
import java.nio.charset.Charset;
import static com.sk89q.worldedit.forge.ForgeAdapter.adaptPlayer;
public final class WECUIPacketHandler {
private WECUIPacketHandler() {
}
public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");
private static final String PROTOCOL_VERSION = Integer.toString(1);
public static EventNetworkChannel HANDLER = ChannelBuilder
.named(new ResourceLocation(ForgeWorldEdit.MOD_ID, ForgeWorldEdit.CUI_PLUGIN_CHANNEL))
.clientAcceptedVersions(PROTOCOL_VERSION::equals)
.serverAcceptedVersions(PROTOCOL_VERSION::equals)
.networkProtocolVersion(() -> PROTOCOL_VERSION)
.eventNetworkChannel();
public static void init() {
HANDLER.addListener(WECUIPacketHandler::onPacketData);
HANDLER.addListener(WECUIPacketHandler::callProcessPacket);
}
public static void onPacketData(ServerCustomPayloadEvent event) {
EntityPlayerMP player = event.getSource().get().getSender();
LocalSession session = ForgeWorldEdit.inst.getSession(player);
if (session.hasCUISupport()) {
return;
}
String text = event.getPayload().toString(UTF_8_CHARSET);
session.handleCUIInitializationMessage(text);
session.describeCUI(adaptPlayer(player));
}
public static void callProcessPacket(ClientCustomPayloadEvent event) {
try {
new SPacketCustomPayload(
new ResourceLocation(ForgeWorldEdit.MOD_ID, ForgeWorldEdit.CUI_PLUGIN_CHANNEL),
event.getPayload()
).processPacket(Minecraft.getInstance().player.connection);
} catch (ThreadQuickExitException ignored) {
}
}
}

View File

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

View File

@ -0,0 +1,36 @@
# The name of the mod loader type to load - for regular FML @Mod mods it should be javafml
modLoader="javafml"
# A version range to match for said mod loader - for regular FML @Mod it will be the minecraft version (without the 1.)
loaderVersion="[24,)"
# A URL to refer people to when problems occur with this mod
issueTrackerURL="https://discord.gg/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"

View File

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

View File

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

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB