geforkt von Mirrors/FastAsyncWorldEdit
Update Forge implementation and added build script.
Including: * Update to new MCP names * Adding of an build script (see maven 'forge' profile) * Adding of an regeneration code * Simplifying of the command registration * Added command usage description to avoid empty help pages * Added missing raw information * Used a WeakReference as world reference to avoid keeping a world in memory * Added mcmod.info * Fixed player orientation * Fixed printRaw not splitting the message correct
Dieser Commit ist enthalten in:
Ursprung
4daef4aff2
Commit
bd98e98698
3
.gitignore
vendored
3
.gitignore
vendored
@ -5,4 +5,5 @@
|
||||
/bin
|
||||
/dependency-reduced-pom.xml
|
||||
/*.iml
|
||||
/.idea
|
||||
/.idea
|
||||
/forge-download
|
||||
|
33
pom.xml
33
pom.xml
@ -304,6 +304,39 @@
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<!-- Build WorldEdit for MC-Forge -->
|
||||
<profile>
|
||||
<id>forge</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<version>1.7</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>compile</phase>
|
||||
<configuration>
|
||||
<target>
|
||||
<property name="maven.build.directory" value="${project.build.directory}"/>
|
||||
<property name="jchronic.path" value="${maven.dependency.com.sk89q.jchronic.jar.path}"/>
|
||||
<property name="truezip.path" value="${maven.dependency.de.schlichtherle.truezip.jar.path}"/>
|
||||
<property name="rhino.path" value="${maven.dependency.rhino.js.jar.path}"/>
|
||||
<property name="snakeyaml.path" value="${maven.dependency.org.yaml.snakeyaml.jar.path}"/>
|
||||
<property name="we.version" value="${project.version}"/>
|
||||
<ant antfile="src/forge/ant/build.xml"/>
|
||||
</target>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>run</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
|
||||
<!-- Attach javadocs and source .jars -->
|
||||
<profile>
|
||||
<id>attach-docs</id>
|
||||
|
150
src/forge/ant/build.xml
Normale Datei
150
src/forge/ant/build.xml
Normale Datei
@ -0,0 +1,150 @@
|
||||
<project name="WorldEdit-Forge" default="main">
|
||||
<property environment="env"/>
|
||||
|
||||
<!-- Properties -->
|
||||
<property name="build.dir" value="${maven.build.directory}/forge"/>
|
||||
<property name="resource.dir" value="src/forge/resources"/>
|
||||
<property name="src.forge.dir" value="src/forge/java"/>
|
||||
<property name="src.we.dir" value="src/main/java"/>
|
||||
<property name="bukkit.src.1" value="com/sk89q/bukkit"/>
|
||||
<property name="bukkit.src.2" value="com/sk89q/worldedit/bukkit"/>
|
||||
<property name="wepif.src" value="com/sk89q/wepif"/>
|
||||
<property name="util.yaml.src" value="com/sk89q/util/yaml"/>
|
||||
<property name="we.yaml.src" value="com/sk89q/worldedit/util/YAMLConfiguration.java"/>
|
||||
|
||||
<property name="download.dir" value="forge-download"/>
|
||||
|
||||
<property name="forge.dir" value="${build.dir}/forge"/>
|
||||
<property name="mcp.dir" value="${forge.dir}/mcp"/>
|
||||
|
||||
<property name="minecraftsrc.dir" value="${mcp.dir}/src/minecraft"/>
|
||||
|
||||
<property file="${minecraftsrc.dir}/fmlversion.properties" />
|
||||
|
||||
<property name="mc.version" value="1.6.2"/>
|
||||
<property name="forge.version" value="9.10.1.850"/>
|
||||
|
||||
<!-- Targets -->
|
||||
<target name="init-msg">
|
||||
<echo message="Starting build for ${we.version} for MC ${mc.version}"/>
|
||||
</target>
|
||||
|
||||
<target name="download">
|
||||
<mkdir dir="${download.dir}"/>
|
||||
|
||||
<get src="http://files.minecraftforge.net/minecraftforge/minecraftforge-src-${mc.version}-${forge.version}.zip" dest="${download.dir}" usetimestamp="True"/>
|
||||
<echo message="Download finished"/>
|
||||
</target>
|
||||
|
||||
<target name="check-setup-forge" depends="download">
|
||||
<available file="${download.dir}/minecraftforge-setup-${mc.version}-${forge.version}.zip" property="setup.forge.present"/>
|
||||
</target>
|
||||
|
||||
<target name="setup-forge" depends="check-setup-forge" unless="setup.forge.present">
|
||||
<unzip dest="${build.dir}" failOnEmptyArchive="true">
|
||||
<fileset dir="${download.dir}">
|
||||
<include name="minecraftforge-src-${mc.version}-${forge.version}.zip"/>
|
||||
</fileset>
|
||||
</unzip>
|
||||
|
||||
<!-- Set executable permission on forge's *.sh -->
|
||||
<chmod dir="${forge.dir}" perm="a+rx" includes="**.sh"/>
|
||||
|
||||
<!-- Install forge -->
|
||||
<echo message="Starting forge install process"/>
|
||||
|
||||
<exec dir="${forge.dir}" executable="cmd" osfamily="windows" failonerror="true">
|
||||
<arg value="/c"/>
|
||||
<arg value="install.cmd"/>
|
||||
</exec>
|
||||
|
||||
<exec dir="${forge.dir}" executable="sh" osfamily="unix" failonerror="true">
|
||||
<arg value="install.sh"/>
|
||||
</exec>
|
||||
|
||||
<echo message="Forge installation finished"/>
|
||||
|
||||
<zip destfile="${download.dir}/minecraftforge-setup-${mc.version}-${forge.version}.zip" basedir="${build.dir}"/>
|
||||
</target>
|
||||
|
||||
<target name="unzip-forge" depends="check-setup-forge" if="setup.forge.present">
|
||||
<unzip dest="${build.dir}" failOnEmptyArchive="true">
|
||||
<fileset dir="${download.dir}">
|
||||
<include name="minecraftforge-setup-${mc.version}-${forge.version}.zip"/>
|
||||
</fileset>
|
||||
</unzip>
|
||||
</target>
|
||||
|
||||
<target name="copySRC" >
|
||||
<!-- Copy WE dependencies source -->
|
||||
<copy todir="${mcp.dir}/lib" file="${jchronic.path}"/>
|
||||
<copy todir="${mcp.dir}/lib" file="${truezip.path}"/>
|
||||
<copy todir="${mcp.dir}/lib" file="${rhino.path}"/>
|
||||
<!--<copy todir="${mcp.dir}/lib" file="${snakeyaml.path}"/>-->
|
||||
|
||||
<!-- Copy WE forge source -->
|
||||
<copy todir="${minecraftsrc.dir}">
|
||||
<fileset dir="${src.forge.dir}"/>
|
||||
</copy>
|
||||
<!-- Copy WE source -->
|
||||
<copy todir="${minecraftsrc.dir}">
|
||||
<fileset dir="${src.we.dir}"/>
|
||||
</copy>
|
||||
<!-- Delete bukkit related sources -->
|
||||
<delete dir="${minecraftsrc.dir}/${bukkit.src.1}"/>
|
||||
<delete dir="${minecraftsrc.dir}/${bukkit.src.2}"/>
|
||||
<delete dir="${minecraftsrc.dir}/${wepif.src}"/>
|
||||
<delete dir="${minecraftsrc.dir}/${util.yaml.src}"/>
|
||||
<delete file="${minecraftsrc.dir}/${we.yaml.src}"/>
|
||||
|
||||
<!-- Set Version -->
|
||||
<replace file="${minecraftsrc.dir}/com/sk89q/worldedit/forge/WorldEditMod.java" token="%VERSION%" value="${we.version}"/>
|
||||
</target>
|
||||
|
||||
<target name="compile" depends="copySRC">
|
||||
|
||||
<echo message="Compiling version ${we.version}"/>
|
||||
|
||||
<!-- Recompile -->
|
||||
<exec dir="${mcp.dir}" executable="cmd" osfamily="windows" failonerror="true">
|
||||
<arg line="/c recompile.bat --client"/>
|
||||
</exec>
|
||||
|
||||
<exec dir="${mcp.dir}" executable="sh" osfamily="unix" failonerror="true">
|
||||
<arg line="recompile.sh --client"/>
|
||||
</exec>
|
||||
|
||||
<!-- Reobf -->
|
||||
<exec dir="${mcp.dir}" executable="cmd" osfamily="windows" failonerror="true">
|
||||
<arg line="/c reobfuscate_srg.bat --client"/>
|
||||
</exec>
|
||||
|
||||
<exec dir="${mcp.dir}" executable="sh" osfamily="unix" failonerror="true">
|
||||
<arg line="reobfuscate_srg.sh --client"/>
|
||||
</exec>
|
||||
|
||||
<echo message="Compiling finished"/>
|
||||
</target>
|
||||
|
||||
<target name="copyclasses" depends="compile">
|
||||
<echo message="Adding version ${we.version} to maven result"/>
|
||||
|
||||
<!-- Copy WE classes -->
|
||||
<copy todir="${maven.build.directory}/classes/com/sk89q/worldedit/forge">
|
||||
<fileset dir="${mcp.dir}/reobf/minecraft/com/sk89q/worldedit/forge"/>
|
||||
</copy>
|
||||
|
||||
<!-- Copy resources -->
|
||||
<copy todir="${maven.build.directory}/classes">
|
||||
<fileset dir="${resource.dir}"></fileset>
|
||||
</copy>
|
||||
|
||||
<replace file="${maven.build.directory}/classes/mcmod.info" token="%VERSION%" value="${we.version}"/>
|
||||
<replace file="${maven.build.directory}/classes/mcmod.info" token="%MCVERSION%" value="${mc.version}"/>
|
||||
|
||||
<echo message="Adding finished"/>
|
||||
</target>
|
||||
|
||||
<target name="main" depends="init-msg, unzip-forge, setup-forge, copyclasses"/>
|
||||
|
||||
</project>
|
@ -14,7 +14,7 @@ import com.sk89q.worldedit.BiomeTypes;
|
||||
import com.sk89q.worldedit.UnknownBiomeTypeException;
|
||||
|
||||
public class ForgeBiomeTypes implements BiomeTypes {
|
||||
private static BiMap biomes = HashBiMap.create();
|
||||
private static BiMap<BiomeType, BiomeGenBase> biomes = HashBiMap.create();
|
||||
|
||||
public ForgeBiomeTypes() {
|
||||
all();
|
||||
@ -33,7 +33,7 @@ public class ForgeBiomeTypes implements BiomeTypes {
|
||||
if (biomes == null) {
|
||||
all();
|
||||
}
|
||||
Iterator it = biomes.keySet().iterator();
|
||||
Iterator<BiomeType> it = biomes.keySet().iterator();
|
||||
while (it.hasNext()) {
|
||||
BiomeType test = (BiomeType) it.next();
|
||||
if (test.getName().equalsIgnoreCase(name)) {
|
||||
@ -43,9 +43,9 @@ public class ForgeBiomeTypes implements BiomeTypes {
|
||||
throw new UnknownBiomeTypeException(name);
|
||||
}
|
||||
|
||||
public List all() {
|
||||
public List<BiomeType> all() {
|
||||
if (biomes.isEmpty()) {
|
||||
biomes = HashBiMap.create(new HashMap());
|
||||
biomes = HashBiMap.create(new HashMap<BiomeType, BiomeGenBase>());
|
||||
for (BiomeGenBase biome : BiomeGenBase.biomeList) {
|
||||
if ((biome == null) || (biomes.containsValue(biome))) {
|
||||
continue;
|
||||
@ -53,7 +53,7 @@ public class ForgeBiomeTypes implements BiomeTypes {
|
||||
biomes.put(new ForgeBiomeType(biome), biome);
|
||||
}
|
||||
}
|
||||
List retBiomes = new ArrayList();
|
||||
List<BiomeType> retBiomes = new ArrayList<BiomeType>();
|
||||
retBiomes.addAll(biomes.keySet());
|
||||
return retBiomes;
|
||||
}
|
||||
|
@ -39,11 +39,11 @@ public class ForgePlayer extends LocalPlayer {
|
||||
}
|
||||
|
||||
public double getPitch() {
|
||||
return this.player.cameraPitch;
|
||||
return this.player.rotationPitch;
|
||||
}
|
||||
|
||||
public double getYaw() {
|
||||
return this.player.cameraYaw;
|
||||
return this.player.rotationYaw;
|
||||
}
|
||||
|
||||
public void giveItem(int type, int amt) {
|
||||
@ -62,25 +62,25 @@ public class ForgePlayer extends LocalPlayer {
|
||||
|
||||
public void printRaw(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
this.player.sendChatToPlayer(ChatMessageComponent.func_111077_e(msg));
|
||||
this.player.sendChatToPlayer(ChatMessageComponent.createFromText(part));
|
||||
}
|
||||
}
|
||||
|
||||
public void printDebug(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
this.player.sendChatToPlayer(ChatMessageComponent.func_111077_e("\u00a77" + part));
|
||||
this.player.sendChatToPlayer(ChatMessageComponent.createFromText("\u00a77" + part));
|
||||
}
|
||||
}
|
||||
|
||||
public void print(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
this.player.sendChatToPlayer(ChatMessageComponent.func_111077_e("\u00a7d" + part));
|
||||
this.player.sendChatToPlayer(ChatMessageComponent.createFromText("\u00a7d" + part));
|
||||
}
|
||||
}
|
||||
|
||||
public void printError(String msg) {
|
||||
for (String part : msg.split("\n")) {
|
||||
this.player.sendChatToPlayer(ChatMessageComponent.func_111077_e("\u00a7c" + part));
|
||||
this.player.sendChatToPlayer(ChatMessageComponent.createFromText("\u00a7c" + part));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -8,8 +8,10 @@ import net.minecraft.command.CommandBase;
|
||||
import net.minecraft.command.ICommandSender;
|
||||
import net.minecraft.command.ServerCommandManager;
|
||||
import net.minecraft.entity.EntityList;
|
||||
import net.minecraft.item.Item;
|
||||
import net.minecraft.server.MinecraftServer;
|
||||
import net.minecraft.world.WorldServer;
|
||||
import net.minecraftforge.common.DimensionManager;
|
||||
|
||||
import com.sk89q.minecraft.util.commands.Command;
|
||||
import com.sk89q.worldedit.BiomeTypes;
|
||||
@ -19,17 +21,27 @@ import com.sk89q.worldedit.ServerInterface;
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
|
||||
public class ForgeServerInterface extends ServerInterface {
|
||||
private WorldEditMod mod;
|
||||
private MinecraftServer server;
|
||||
private ForgeBiomeTypes biomes;
|
||||
|
||||
public ForgeServerInterface() {
|
||||
this.mod = WorldEditMod.inst;
|
||||
this.server = FMLCommonHandler.instance().getMinecraftServerInstance();
|
||||
this.biomes = new ForgeBiomeTypes();
|
||||
}
|
||||
|
||||
public int resolveItem(String name) {
|
||||
if (name == null) return 0;
|
||||
for (Item item : Item.itemsList) {
|
||||
if (item == null) continue;
|
||||
if (item.getUnlocalizedName() == null) continue;
|
||||
if (item.getUnlocalizedName().startsWith("item.")) {
|
||||
if (item.getUnlocalizedName().equalsIgnoreCase("item." + name)) return item.itemID;
|
||||
}
|
||||
if (item.getUnlocalizedName().startsWith("tile.")) {
|
||||
if (item.getUnlocalizedName().equalsIgnoreCase("tile." + name)) return item.itemID;
|
||||
}
|
||||
if (item.getUnlocalizedName().equalsIgnoreCase(name)) return item.itemID;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -49,8 +61,8 @@ public class ForgeServerInterface extends ServerInterface {
|
||||
}
|
||||
|
||||
public List<LocalWorld> getWorlds() {
|
||||
List<WorldServer> worlds = Arrays.asList(this.server.worldServers);
|
||||
List<LocalWorld> ret = new ArrayList(worlds.size());
|
||||
List<WorldServer> worlds = Arrays.asList(DimensionManager.getWorlds());
|
||||
List<LocalWorld> ret = new ArrayList<LocalWorld>(worlds.size());
|
||||
for (WorldServer world : worlds) {
|
||||
ret.add(new ForgeWorld(world));
|
||||
}
|
||||
@ -61,22 +73,26 @@ public class ForgeServerInterface extends ServerInterface {
|
||||
public void onCommandRegistration(List<Command> commands) {
|
||||
if (server == null) return;
|
||||
ServerCommandManager mcMan = (ServerCommandManager) server.getCommandManager();
|
||||
for (Command cmd : commands) {
|
||||
for (int i = 0; i < cmd.aliases().length; i++) {
|
||||
final String name = cmd.aliases()[i];
|
||||
mcMan.registerCommand(new CommandBase() {
|
||||
public String getCommandName() {
|
||||
return name;
|
||||
}
|
||||
for (final Command cmd : commands) {
|
||||
mcMan.registerCommand(new CommandBase() {
|
||||
@Override
|
||||
public String getCommandName() {
|
||||
return cmd.aliases()[0];
|
||||
}
|
||||
|
||||
public void processCommand(ICommandSender var1, String[] var2) {
|
||||
}
|
||||
@Override
|
||||
public List<String> getCommandAliases() {
|
||||
return Arrays.asList(cmd.aliases());
|
||||
}
|
||||
|
||||
public String getCommandUsage(ICommandSender icommandsender) {
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public void processCommand(ICommandSender var1, String[] var2) {}
|
||||
|
||||
@Override
|
||||
public String getCommandUsage(ICommandSender icommandsender) {
|
||||
return "/" + cmd.aliases()[0] + " " + cmd.usage();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,12 +13,12 @@ public class ForgeUtil {
|
||||
|
||||
public static boolean hasPermission(EntityPlayerMP player, String perm) {
|
||||
// TODO fix WEPIF
|
||||
return FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().areCommandsAllowed(player.username);
|
||||
return FMLCommonHandler.instance().getMinecraftServerInstance().getConfigurationManager().isPlayerOpped(player.username);
|
||||
}
|
||||
|
||||
public static ItemStack toForgeItemStack(BaseItemStack item) {
|
||||
ItemStack ret = new ItemStack(item.getType(), item.getAmount(), item.getData());
|
||||
for (Map.Entry entry : item.getEnchantments().entrySet()) {
|
||||
for (Map.Entry<Integer, Integer> entry : item.getEnchantments().entrySet()) {
|
||||
ret.addEnchantment(net.minecraft.enchantment.Enchantment.enchantmentsList[((Integer)entry.getKey()).intValue()], ((Integer)entry.getValue()).intValue());
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,10 @@
|
||||
package com.sk89q.worldedit.forge;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import net.minecraft.entity.Entity;
|
||||
import net.minecraft.entity.EntityHanging;
|
||||
@ -20,15 +24,18 @@ import net.minecraft.entity.passive.EntityAmbientCreature;
|
||||
import net.minecraft.entity.passive.EntityAnimal;
|
||||
import net.minecraft.entity.passive.EntityTameable;
|
||||
import net.minecraft.entity.passive.EntityVillager;
|
||||
import net.minecraft.entity.player.EntityPlayer;
|
||||
import net.minecraft.inventory.IInventory;
|
||||
import net.minecraft.tileentity.TileEntity;
|
||||
import net.minecraft.tileentity.TileEntityMobSpawner;
|
||||
import net.minecraft.tileentity.TileEntityNote;
|
||||
import net.minecraft.tileentity.TileEntitySign;
|
||||
import net.minecraft.tileentity.TileEntitySkull;
|
||||
import net.minecraft.util.LongHashMap;
|
||||
import net.minecraft.world.ChunkCoordIntPair;
|
||||
import net.minecraft.world.World;
|
||||
import net.minecraft.world.chunk.Chunk;
|
||||
import net.minecraft.world.chunk.IChunkProvider;
|
||||
import net.minecraft.world.gen.ChunkProviderServer;
|
||||
|
||||
import com.sk89q.worldedit.BiomeType;
|
||||
import com.sk89q.worldedit.EditSession;
|
||||
@ -47,51 +54,50 @@ import com.sk89q.worldedit.foundation.Block;
|
||||
import com.sk89q.worldedit.regions.Region;
|
||||
|
||||
public class ForgeWorld extends LocalWorld {
|
||||
// TODO fix world leaks (see net.minecraftforge.common.getIDs()Z;)
|
||||
private World world;
|
||||
|
||||
private WeakReference<World> world;
|
||||
|
||||
public ForgeWorld(World world) {
|
||||
this.world = world;
|
||||
this.world = new WeakReference<World>(world);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return this.world.provider.getDimensionName();
|
||||
return this.world.get().provider.getDimensionName();
|
||||
}
|
||||
|
||||
public boolean setBlockType(Vector pt, int type) {
|
||||
return this.world.setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), type, 0, 3);
|
||||
return this.world.get().setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), type, 0, 3);
|
||||
}
|
||||
|
||||
public boolean setBlockTypeFast(Vector pt, int type) {
|
||||
return this.world.setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), type);
|
||||
return this.world.get().setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), type);
|
||||
}
|
||||
|
||||
public boolean setTypeIdAndData(Vector pt, int type, int data) {
|
||||
return this.world.setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), type, data, 3);
|
||||
return this.world.get().setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), type, data, 3);
|
||||
}
|
||||
|
||||
public boolean setTypeIdAndDataFast(Vector pt, int type, int data) {
|
||||
return this.world.setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), type, data, 3);
|
||||
return this.world.get().setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), type, data, 3);
|
||||
}
|
||||
|
||||
public int getBlockType(Vector pt) {
|
||||
return this.world.getBlockId(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
return this.world.get().getBlockId(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
}
|
||||
|
||||
public void setBlockData(Vector pt, int data) {
|
||||
this.world.setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), data, 0, 3);
|
||||
this.world.get().setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), data, 0, 3);
|
||||
}
|
||||
|
||||
public void setBlockDataFast(Vector pt, int data) {
|
||||
this.world.setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), data, 0, 3);
|
||||
this.world.get().setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), data, 0, 3);
|
||||
}
|
||||
|
||||
public int getBlockData(Vector pt) {
|
||||
return this.world.getBlockMetadata(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
return this.world.get().getBlockMetadata(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
}
|
||||
|
||||
public int getBlockLightLevel(Vector pt) {
|
||||
return this.world.getBlockLightValue(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
return this.world.get().getBlockLightValue(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
}
|
||||
|
||||
public boolean isValidBlockType(int id) {
|
||||
@ -99,12 +105,12 @@ public class ForgeWorld extends LocalWorld {
|
||||
}
|
||||
|
||||
public BiomeType getBiome(Vector2D pt) {
|
||||
return ForgeBiomeTypes.getFromBaseBiome(this.world.getBiomeGenForCoords(pt.getBlockX(), pt.getBlockZ()));
|
||||
return ForgeBiomeTypes.getFromBaseBiome(this.world.get().getBiomeGenForCoords(pt.getBlockX(), pt.getBlockZ()));
|
||||
}
|
||||
|
||||
public void setBiome(Vector2D pt, BiomeType biome) {
|
||||
if (this.world.getChunkProvider().chunkExists(pt.getBlockX(), pt.getBlockZ())) {
|
||||
Chunk chunk = this.world.getChunkFromBlockCoords(pt.getBlockX(), pt.getBlockZ());
|
||||
if (this.world.get().getChunkProvider().chunkExists(pt.getBlockX(), pt.getBlockZ())) {
|
||||
Chunk chunk = this.world.get().getChunkFromBlockCoords(pt.getBlockX(), pt.getBlockZ());
|
||||
if ((chunk != null) && (chunk.isChunkLoaded)) {
|
||||
byte[] biomevals = chunk.getBiomeArray();
|
||||
biomevals[((pt.getBlockZ() & 0xF) << 4 | pt.getBlockX() & 0xF)] = (byte) ForgeBiomeTypes.getFromBiomeType(biome).biomeID;
|
||||
@ -113,8 +119,6 @@ public class ForgeWorld extends LocalWorld {
|
||||
}
|
||||
|
||||
public boolean regenerate(Region region, EditSession editSession) {
|
||||
// TODO fix this
|
||||
/*
|
||||
BaseBlock[] history = new BaseBlock[256 * (getMaxY() + 1)];
|
||||
|
||||
for (Vector2D chunk : region.getChunks()) {
|
||||
@ -131,31 +135,60 @@ public class ForgeWorld extends LocalWorld {
|
||||
}
|
||||
try {
|
||||
Set<Vector2D> chunks = region.getChunks();
|
||||
IChunkProvider provider = this.world.getChunkProvider();
|
||||
IChunkProvider provider = this.world.get().getChunkProvider();
|
||||
if (!(provider instanceof ChunkProviderServer)) {
|
||||
return false;
|
||||
}
|
||||
ChunkProviderServer chunkServer = (ChunkProviderServer) provider;
|
||||
Field u = ChunkProviderServer.class.getDeclaredField("b"); // chunksToUnload
|
||||
Field u = null;
|
||||
try {
|
||||
u = ChunkProviderServer.class.getDeclaredField("field_73248_b"); // chunksToUnload
|
||||
} catch(NoSuchFieldException e) {
|
||||
u = ChunkProviderServer.class.getDeclaredField("chunksToUnload");
|
||||
}
|
||||
u.setAccessible(true);
|
||||
Set unloadQueue = (Set) u.get(chunkServer);
|
||||
Field m = ChunkProviderServer.class.getDeclaredField("f"); // loadedChunkHashMap
|
||||
Set<?> unloadQueue = (Set<?>) u.get(chunkServer);
|
||||
Field m = null;
|
||||
try {
|
||||
m = ChunkProviderServer.class.getDeclaredField("field_73244_f"); // loadedChunkHashMap
|
||||
} catch(NoSuchFieldException e) {
|
||||
m = ChunkProviderServer.class.getDeclaredField("loadedChunkHashMap");
|
||||
}
|
||||
m.setAccessible(true);
|
||||
LongHashMap loadedMap = (LongHashMap) m.get(chunkServer);
|
||||
Field p = ChunkProviderServer.class.getDeclaredField("d"); // currentChunkProvider
|
||||
Field lc = null;
|
||||
try {
|
||||
lc = ChunkProviderServer.class.getDeclaredField("field_73245_g"); // loadedChunkHashMap
|
||||
} catch(NoSuchFieldException e) {
|
||||
lc = ChunkProviderServer.class.getDeclaredField("loadedChunks");
|
||||
}
|
||||
lc.setAccessible(true);
|
||||
List<Chunk> loaded = (List<Chunk>) lc.get(chunkServer);
|
||||
Field p = null;
|
||||
try {
|
||||
p = ChunkProviderServer.class.getDeclaredField("field_73246_d"); // currentChunkProvider
|
||||
} catch(NoSuchFieldException e) {
|
||||
p = ChunkProviderServer.class.getDeclaredField("currentChunkProvider");
|
||||
}
|
||||
p.setAccessible(true);
|
||||
IChunkProvider chunkProvider = (IChunkProvider) p.get(chunkServer);
|
||||
|
||||
for (Vector2D coord : chunks) {
|
||||
long pos = ChunkCoordIntPair.chunkXZ2Int(coord.getBlockX(), coord.getBlockZ());
|
||||
Chunk mcChunk = null;
|
||||
if (chunkServer.chunkExists(coord.getBlockX(), coord.getBlockZ())) {
|
||||
mcChunk = chunkServer.loadChunk(coord.getBlockX(), coord.getBlockZ());
|
||||
mcChunk.onChunkUnload();
|
||||
}
|
||||
unloadQueue.remove(Long.valueOf((coord.getBlockX() << 32) + coord.getBlockZ() - -2147483648L));
|
||||
loadedMap.remove(((long) coord.getBlockX() << 32) + coord.getBlockZ() - Integer.MIN_VALUE);
|
||||
|
||||
unloadQueue.remove(pos);
|
||||
loadedMap.remove(pos);
|
||||
mcChunk = chunkProvider.provideChunk(coord.getBlockX(), coord.getBlockZ());
|
||||
loadedMap.add(pos, mcChunk);
|
||||
loaded.add(mcChunk);
|
||||
if (mcChunk != null) {
|
||||
mcChunk.onChunkLoad();
|
||||
}
|
||||
mcChunk.populateChunk(chunkProvider, chunkProvider, coord.getBlockX(), coord.getBlockZ());
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
@ -178,7 +211,6 @@ public class ForgeWorld extends LocalWorld {
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -187,21 +219,21 @@ public class ForgeWorld extends LocalWorld {
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean successful = this.world.setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), block.getId());
|
||||
boolean successful = this.world.get().setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), block.getId());
|
||||
|
||||
if (successful) {
|
||||
if (block instanceof TileEntityBlock) {
|
||||
copyToWorld(pt, (BaseBlock) block);
|
||||
}
|
||||
}
|
||||
this.world.setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), block.getId(), block.getData(), 3);
|
||||
this.world.get().setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), block.getId(), block.getData(), 3);
|
||||
return successful;
|
||||
}
|
||||
|
||||
public BaseBlock getBlock(Vector pt) {
|
||||
int type = getBlockType(pt);
|
||||
int data = getBlockData(pt);
|
||||
TileEntity tile = this.world.getBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
TileEntity tile = this.world.get().getBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
if (tile != null) {
|
||||
TileEntityBaseBlock block = new TileEntityBaseBlock(type, data, tile);
|
||||
copyFromWorld(pt, block);
|
||||
@ -223,25 +255,23 @@ public class ForgeWorld extends LocalWorld {
|
||||
// Signs
|
||||
TileEntitySign sign = new TileEntitySign();
|
||||
sign.signText = ((SignBlock) block).getText();
|
||||
world.setBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), sign);
|
||||
world.get().setBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), sign);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
if (block instanceof MobSpawnerBlock) {
|
||||
// Mob spawners
|
||||
TileEntityMobSpawner spawner = new TileEntityMobSpawner();
|
||||
spawner.getSpawnerLogic().setMobID(((MobSpawnerBlock) block).getMobType());
|
||||
world.setBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), spawner);
|
||||
world.get().setBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), spawner);
|
||||
return true;
|
||||
}
|
||||
*/
|
||||
|
||||
if (block instanceof NoteBlock) {
|
||||
// Note block
|
||||
TileEntityNote note = new TileEntityNote();
|
||||
note.note = ((NoteBlock) block).getNote();
|
||||
world.setBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), note);
|
||||
world.get().setBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), note);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -250,12 +280,12 @@ public class ForgeWorld extends LocalWorld {
|
||||
TileEntitySkull skull = new TileEntitySkull();
|
||||
skull.setSkullType(((SkullBlock) block).getSkullType(), ((SkullBlock) block).getOwner());
|
||||
skull.setSkullRotation(((SkullBlock) block).getRot());
|
||||
world.setBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), skull);
|
||||
world.get().setBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), skull);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (block instanceof TileEntityBaseBlock) {
|
||||
TileEntityBaseBlock.set(this.world, pt, (TileEntityBaseBlock) block, hardcopy);
|
||||
TileEntityBaseBlock.set(this.world.get(), pt, (TileEntityBaseBlock) block, hardcopy);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@ -265,12 +295,12 @@ public class ForgeWorld extends LocalWorld {
|
||||
if (!(block instanceof TileEntityBaseBlock)) {
|
||||
return false;
|
||||
}
|
||||
((TileEntityBaseBlock) block).setTile(this.world.getBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()));
|
||||
((TileEntityBaseBlock) block).setTile(this.world.get().getBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()));
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean clearContainerBlockContents(Vector pt) {
|
||||
TileEntity tile = this.world.getBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
TileEntity tile = this.world.get().getBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
|
||||
if ((tile instanceof IInventory)) {
|
||||
IInventory inv = (IInventory) tile;
|
||||
int size = inv.getSizeInventory();
|
||||
@ -286,16 +316,16 @@ public class ForgeWorld extends LocalWorld {
|
||||
if ((item == null) || (item.getType() == 0)) {
|
||||
return;
|
||||
}
|
||||
EntityItem entity = new EntityItem(this.world, pt.getX(), pt.getY(), pt.getZ(), ForgeUtil.toForgeItemStack(item));
|
||||
EntityItem entity = new EntityItem(this.world.get(), pt.getX(), pt.getY(), pt.getZ(), ForgeUtil.toForgeItemStack(item));
|
||||
entity.delayBeforeCanPickup = 10;
|
||||
this.world.spawnEntityInWorld(entity);
|
||||
this.world.get().spawnEntityInWorld(entity);
|
||||
}
|
||||
|
||||
public int removeEntities(EntityType type, Vector origin, int radius) {
|
||||
int num = 0;
|
||||
double radiusSq = Math.pow(radius, 2.0D);
|
||||
|
||||
for (Iterator<Entity> it = this.world.loadedEntityList.iterator(); it.hasNext();) {
|
||||
for (Iterator<Entity> it = this.world.get().loadedEntityList.iterator(); it.hasNext();) {
|
||||
Entity ent = it.next();
|
||||
if ((radius != -1) && (origin.distanceSq(new Vector(ent.posX, ent.posY, ent.posZ)) > radiusSq)) {
|
||||
continue;
|
||||
@ -366,7 +396,7 @@ public class ForgeWorld extends LocalWorld {
|
||||
int num = 0;
|
||||
double radiusSq = radius * radius;
|
||||
|
||||
for (Iterator<Entity> it = this.world.loadedEntityList.iterator(); it.hasNext();) {
|
||||
for (Iterator<Entity> it = this.world.get().loadedEntityList.iterator(); it.hasNext();) {
|
||||
Entity obj = it.next();
|
||||
if (!(obj instanceof EntityLiving)) {
|
||||
continue;
|
||||
@ -404,17 +434,17 @@ public class ForgeWorld extends LocalWorld {
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return world;
|
||||
return world.get();
|
||||
}
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if ((other instanceof ForgeWorld)) {
|
||||
return ((ForgeWorld) other).world.equals(this.world);
|
||||
return ((ForgeWorld) other).world.get().equals(this.world.get());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return this.world.hashCode();
|
||||
return this.world.get().hashCode();
|
||||
}
|
||||
}
|
@ -59,7 +59,7 @@ public class TileEntityBaseBlock extends BaseBlock implements TileEntityBlock {
|
||||
|
||||
private static TileEntity constructTEClass(World world, Vector pt, TileEntityBaseBlock block) {
|
||||
Class<? extends TileEntity> clazz = block.tile.getClass();
|
||||
Constructor baseConstructor;
|
||||
Constructor<? extends TileEntity> baseConstructor;
|
||||
try {
|
||||
baseConstructor = clazz.getConstructor(); // creates "blank" TE
|
||||
} catch (Throwable e) {
|
||||
@ -84,7 +84,6 @@ public class TileEntityBaseBlock extends BaseBlock implements TileEntityBlock {
|
||||
}
|
||||
|
||||
public String getNbtId() {
|
||||
String id = null;
|
||||
NBTTagCompound tag = new NBTTagCompound();
|
||||
try {
|
||||
this.tile.writeToNBT(tag);
|
||||
|
@ -15,13 +15,15 @@ public class WECUIPacketHandler implements IPacketHandler {
|
||||
public static final Charset UTF_8_CHARSET = Charset.forName("UTF-8");
|
||||
|
||||
public void onPacketData(INetworkManager manager, Packet250CustomPayload packet, Player player) {
|
||||
LocalSession session = WorldEditMod.inst.getSession((EntityPlayerMP) player);
|
||||
if (player instanceof EntityPlayerMP) {
|
||||
LocalSession session = WorldEditMod.inst.getSession((EntityPlayerMP) player);
|
||||
|
||||
if (session.hasCUISupport()) {
|
||||
return;
|
||||
if (session.hasCUISupport()) {
|
||||
return;
|
||||
}
|
||||
|
||||
String text = new String(packet.data, UTF_8_CHARSET);
|
||||
session.handleCUIInitializationMessage(text);
|
||||
}
|
||||
|
||||
String text = new String(packet.data, UTF_8_CHARSET);
|
||||
session.handleCUIInitializationMessage(text);
|
||||
}
|
||||
}
|
@ -18,23 +18,21 @@ import com.sk89q.worldedit.LocalWorld;
|
||||
import com.sk89q.worldedit.ServerInterface;
|
||||
import com.sk89q.worldedit.WorldEdit;
|
||||
|
||||
import cpw.mods.fml.common.FMLCommonHandler;
|
||||
import cpw.mods.fml.common.FMLLog;
|
||||
import cpw.mods.fml.common.Mod;
|
||||
import cpw.mods.fml.common.Mod.ServerStarting;
|
||||
import cpw.mods.fml.common.Mod.ServerStopping;
|
||||
import cpw.mods.fml.common.Mod.EventHandler;
|
||||
import cpw.mods.fml.common.Mod.Instance;
|
||||
import cpw.mods.fml.common.event.FMLInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPostInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLPreInitializationEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStartingEvent;
|
||||
import cpw.mods.fml.common.event.FMLServerStoppingEvent;
|
||||
import cpw.mods.fml.common.network.NetworkRegistry;
|
||||
import cpw.mods.fml.relauncher.Side;
|
||||
import cpw.mods.fml.common.network.NetworkMod;
|
||||
|
||||
@Mod(modid = "WorldEdit", name = "WorldEdit", version = "5.5.2-forge-alpha1")
|
||||
@Mod(modid = "WorldEdit", name = "WorldEdit", version = "%VERSION%")
|
||||
@NetworkMod(channels="WECUI", packetHandler=WECUIPacketHandler.class)
|
||||
public class WorldEditMod {
|
||||
|
||||
@Mod.Instance("WorldEdit")
|
||||
@Instance("WorldEdit")
|
||||
public static WorldEditMod inst;
|
||||
|
||||
protected static Logger logger;
|
||||
@ -44,11 +42,11 @@ public class WorldEditMod {
|
||||
private ForgeConfiguration config;
|
||||
private File workingDir;
|
||||
|
||||
@Mod.PreInit
|
||||
@EventHandler
|
||||
public void preInit(FMLPreInitializationEvent event) {
|
||||
logger = Logger.getLogger(((Mod) getClass().getAnnotation(Mod.class)).modid());
|
||||
logger = Logger.getLogger(getClass().getAnnotation(Mod.class).modid());
|
||||
logger.setParent(FMLLog.getLogger());
|
||||
String modVersion = ((Mod) WorldEditMod.class.getAnnotation(Mod.class)).version();
|
||||
String modVersion = WorldEditMod.class.getAnnotation(Mod.class).version();
|
||||
String manifestVersion = WorldEdit.getVersion();
|
||||
if (!manifestVersion.equalsIgnoreCase(modVersion)) {
|
||||
WorldEdit.setVersion(manifestVersion + " (" + modVersion + ")");
|
||||
@ -63,23 +61,17 @@ public class WorldEditMod {
|
||||
// PermissionsResolverManager.initialize(this, this.workingDir);
|
||||
}
|
||||
|
||||
@Mod.Init
|
||||
@EventHandler
|
||||
public void init(FMLInitializationEvent event) {
|
||||
if (FMLCommonHandler.instance().getEffectiveSide() == Side.SERVER) {
|
||||
NetworkRegistry.instance().registerChannel(new WECUIPacketHandler(), "WECUI");
|
||||
} /* else {
|
||||
WE CUI stuff here?
|
||||
} */
|
||||
|
||||
MinecraftForge.EVENT_BUS.register(new WorldEditForgeListener());
|
||||
}
|
||||
|
||||
@Mod.PostInit
|
||||
@EventHandler
|
||||
public void postInit(FMLPostInitializationEvent event) {
|
||||
logger.info("WorldEdit " + WorldEdit.getVersion() + " Loaded");
|
||||
}
|
||||
|
||||
@ServerStarting
|
||||
@EventHandler
|
||||
public void serverStarting(FMLServerStartingEvent event) {
|
||||
this.server = new ForgeServerInterface();
|
||||
this.controller = new WorldEdit(this.server, this.config);
|
||||
@ -121,14 +113,19 @@ public class WorldEditMod {
|
||||
File actual = new File(getWorkingDir(), name);
|
||||
if (!actual.exists()) {
|
||||
InputStream input = null;
|
||||
JarFile file = null;
|
||||
try {
|
||||
JarFile file = new JarFile(jar);
|
||||
file = new JarFile(jar);
|
||||
ZipEntry copy = file.getEntry("defaults/" + name);
|
||||
if (copy == null)
|
||||
throw new FileNotFoundException();
|
||||
input = file.getInputStream(copy);
|
||||
} catch (IOException e) {
|
||||
logger.severe("Unable to read default configuration: " + name);
|
||||
} finally {
|
||||
try {
|
||||
file.close();
|
||||
} catch (Exception e) {}
|
||||
}
|
||||
if (input != null) {
|
||||
FileOutputStream output = null;
|
||||
|
@ -1,5 +1,7 @@
|
||||
package com.sk89q.worldedit.forge.selections;
|
||||
|
||||
import java.lang.ref.WeakReference;
|
||||
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import com.sk89q.worldedit.Location;
|
||||
@ -9,16 +11,16 @@ import com.sk89q.worldedit.regions.Region;
|
||||
import com.sk89q.worldedit.regions.RegionSelector;
|
||||
|
||||
public abstract class RegionSelection implements Selection {
|
||||
private World world;
|
||||
private WeakReference<World> world;
|
||||
private RegionSelector selector;
|
||||
private Region region;
|
||||
|
||||
public RegionSelection(World world) {
|
||||
this.world = world;
|
||||
this.world = new WeakReference<World>(world);
|
||||
}
|
||||
|
||||
public RegionSelection(World world, RegionSelector selector, Region region) {
|
||||
this.world = world;
|
||||
this(world);
|
||||
this.region = region;
|
||||
this.selector = selector;
|
||||
}
|
||||
@ -40,7 +42,7 @@ public abstract class RegionSelection implements Selection {
|
||||
}
|
||||
|
||||
public Location getMinimumPoint() {
|
||||
return new Location(WorldEditMod.inst.getWorld(this.world), this.region.getMinimumPoint());
|
||||
return new Location(WorldEditMod.inst.getWorld(this.world.get()), this.region.getMinimumPoint());
|
||||
}
|
||||
|
||||
public Vector getNativeMinimumPoint() {
|
||||
@ -48,7 +50,7 @@ public abstract class RegionSelection implements Selection {
|
||||
}
|
||||
|
||||
public Location getMaximumPoint() {
|
||||
return new Location(WorldEditMod.inst.getWorld(this.world), this.region.getMaximumPoint());
|
||||
return new Location(WorldEditMod.inst.getWorld(this.world.get()), this.region.getMaximumPoint());
|
||||
}
|
||||
|
||||
public Vector getNativeMaximumPoint() {
|
||||
@ -56,7 +58,7 @@ public abstract class RegionSelection implements Selection {
|
||||
}
|
||||
|
||||
public World getWorld() {
|
||||
return this.world;
|
||||
return this.world.get();
|
||||
}
|
||||
|
||||
public int getArea() {
|
||||
@ -76,7 +78,7 @@ public abstract class RegionSelection implements Selection {
|
||||
}
|
||||
|
||||
public boolean contains(Location pt) {
|
||||
if (!pt.getWorld().equals(this.world)) {
|
||||
if (!pt.getWorld().equals(this.world.get())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
23
src/forge/resources/mcmod.info
Normale Datei
23
src/forge/resources/mcmod.info
Normale Datei
@ -0,0 +1,23 @@
|
||||
{
|
||||
"modinfoversion": 2,
|
||||
"modlist": [{
|
||||
"modid": "WorldEdit",
|
||||
"name": "WorldEdit",
|
||||
"description": "WorldEdit is an easy-to-use in-game world editor for Minecraft, supporting both single player and multiplayer.",
|
||||
"version": "%VERSION%",
|
||||
"mcversion": "%MCVERSION%",
|
||||
"url": "http://wiki.sk89q.com/wiki/WorldEdit",
|
||||
"updateUrl": "",
|
||||
"authors": [ "sk89q" ],
|
||||
"credits": "",
|
||||
"logoFile": "",
|
||||
"screenshots": [],
|
||||
"requiredMods": [
|
||||
"Forge@[9.10.1.850,)"
|
||||
],
|
||||
"dependencies": [
|
||||
"Forge@[9.10.1.850,)"
|
||||
],
|
||||
"dependants": []
|
||||
}]
|
||||
}
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren