diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeType.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeType.java new file mode 100644 index 000000000..48fbea3b1 --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeType.java @@ -0,0 +1,16 @@ +package com.sk89q.worldedit.forge; + +import com.sk89q.worldedit.BiomeType; +import net.minecraft.world.biome.BiomeGenBase; + +public class ForgeBiomeType implements BiomeType { + private BiomeGenBase biome; + + public ForgeBiomeType(BiomeGenBase biome) { + this.biome = biome; + } + + public String getName() { + return this.biome.biomeName; + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeTypes.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeTypes.java new file mode 100644 index 000000000..2c0c44611 --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeBiomeTypes.java @@ -0,0 +1,67 @@ +package com.sk89q.worldedit.forge; + +import com.google.common.collect.BiMap; +import com.google.common.collect.HashBiMap; +import com.sk89q.worldedit.BiomeType; +import com.sk89q.worldedit.BiomeTypes; +import com.sk89q.worldedit.UnknownBiomeTypeException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Set; +import net.minecraft.world.biome.BiomeGenBase; + +public class ForgeBiomeTypes implements BiomeTypes { + private static BiMap biomes = HashBiMap.create(); + + public ForgeBiomeTypes() { + all(); + } + + public boolean has(String name) { + for (BiomeGenBase biome : BiomeGenBase.biomeList) { + if ((biome != null) && (biome.biomeName.equalsIgnoreCase(name))) { + return true; + } + } + return false; + } + + public BiomeType get(String name) throws UnknownBiomeTypeException { + if (biomes == null) { + all(); + } + Iterator it = biomes.keySet().iterator(); + while (it.hasNext()) { + BiomeType test = (BiomeType) it.next(); + if (test.getName().equalsIgnoreCase(name)) { + return test; + } + } + throw new UnknownBiomeTypeException(name); + } + + public List all() { + if (biomes.isEmpty()) { + biomes = HashBiMap.create(new HashMap()); + for (BiomeGenBase biome : BiomeGenBase.biomeList) { + if ((biome == null) || (biomes.containsValue(biome))) { + continue; + } + biomes.put(new ForgeBiomeType(biome), biome); + } + } + List retBiomes = new ArrayList(); + retBiomes.addAll(biomes.keySet()); + return retBiomes; + } + + public static BiomeType getFromBaseBiome(BiomeGenBase biome) { + return biomes.containsValue(biome) ? (BiomeType) biomes.inverse().get(biome) : BiomeType.UNKNOWN; + } + + public static BiomeGenBase getFromBiomeType(BiomeType biome) { + return (BiomeGenBase) biomes.get(biome); + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeConfiguration.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeConfiguration.java new file mode 100644 index 000000000..c68effb2e --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeConfiguration.java @@ -0,0 +1,20 @@ +package com.sk89q.worldedit.forge; + +import com.sk89q.worldedit.util.PropertiesConfiguration; +import java.io.File; + +public class ForgeConfiguration extends PropertiesConfiguration { + + public ForgeConfiguration(WorldEditMod mod) { + super(new File(mod.getWorkingDir() + File.separator + "worldedit.properties")); + } + + public void load() { + super.load(); + showFirstUseVersion = false; + } + + public File getWorkingDirectory() { + return WorldEditMod.inst.getWorkingDir(); + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java b/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java new file mode 100644 index 000000000..54c758e86 --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgePlayer.java @@ -0,0 +1,100 @@ +package com.sk89q.worldedit.forge; + +import com.sk89q.util.StringUtil; +import com.sk89q.wepif.PermissionsResolverManager; +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.WorldVector; +import com.sk89q.worldedit.bags.BlockBag; +import com.sk89q.worldedit.cui.CUIEvent; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.entity.player.InventoryPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.network.NetServerHandler; +import net.minecraft.network.packet.Packet250CustomPayload; + +public class ForgePlayer extends LocalPlayer { + private EntityPlayerMP player; + + protected ForgePlayer(EntityPlayerMP player) { + super(WorldEditMod.inst.getServerInterface()); + this.player = player; + } + + public int getItemInHand() { + ItemStack is = this.player.getCurrentEquippedItem(); + return is == null ? 0 : is.itemID; + } + + public String getName() { + return this.player.username; + } + + public WorldVector getPosition() { + return new WorldVector(WorldEditMod.inst.getWorld(this.player.worldObj), this.player.posX, this.player.posY, this.player.posZ); + } + + public LocalWorld getWorld() { + return WorldEditMod.inst.getWorld(this.player.worldObj); + } + + public double getPitch() { + return this.player.cameraPitch; + } + + public double getYaw() { + return this.player.cameraYaw; + } + + public void giveItem(int type, int amt) { + this.player.inventory.addItemStackToInventory(new ItemStack(type, amt, 0)); + } + + public void dispatchCUIEvent(CUIEvent event) { + String[] params = event.getParameters(); + String send = event.getTypeId(); + if (params.length > 0) { + send = send + "|" + StringUtil.joinString(params, "|"); + } + Packet250CustomPayload packet = new Packet250CustomPayload(WorldEditMod.CUI_PLUGIN_CHANNEL, send.getBytes(WECUIPacketHandler.UTF_8_CHARSET)); + this.player.playerNetServerHandler.sendPacketToPlayer(packet); + } + + public void printRaw(String msg) { + for (String part : msg.split("\n")) + this.player.sendChatToPlayer(msg); + } + + public void printDebug(String msg) { + for (String part : msg.split("\n")) + this.player.sendChatToPlayer("\u00a77" + part); + } + + public void print(String msg) { + for (String part : msg.split("\n")) + this.player.sendChatToPlayer("\u00a7d" + part); + } + + public void printError(String msg) { + for (String part : msg.split("\n")) + this.player.sendChatToPlayer("\u00a7c" + part); + } + + public void setPosition(Vector pos, float pitch, float yaw) { + this.player.playerNetServerHandler.setPlayerLocation(pos.getX(), pos.getY(), pos.getZ(), pitch, yaw); + } + + public String[] getGroups() { + return new String[]{}; // WorldEditMod.inst.getPermissionsResolver().getGroups(this.player.username); + } + + public BlockBag getInventoryBlockBag() { + return null; + } + + public boolean hasPermission(String perm) { + return ForgeUtil.hasPermission(this.player, perm); + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeServerInterface.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeServerInterface.java new file mode 100644 index 000000000..0fb26af8c --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeServerInterface.java @@ -0,0 +1,77 @@ +package com.sk89q.worldedit.forge; + +import com.sk89q.minecraft.util.commands.Command; +import com.sk89q.minecraft.util.commands.CommandsManager; +import com.sk89q.worldedit.BiomeTypes; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.ServerInterface; +import cpw.mods.fml.server.FMLServerHandler; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import net.minecraft.command.CommandBase; +import net.minecraft.command.ICommandSender; +import net.minecraft.command.ServerCommandManager; +import net.minecraft.entity.EntityList; +import net.minecraft.server.MinecraftServer; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; + +public class ForgeServerInterface extends ServerInterface { + private WorldEditMod mod; + private MinecraftServer server; + private ForgeBiomeTypes biomes; + + public ForgeServerInterface() { + this.mod = WorldEditMod.inst; + this.server = FMLServerHandler.instance().getServer(); + this.biomes = new ForgeBiomeTypes(); + } + + public int resolveItem(String name) { + return 0; + } + + public boolean isValidMobType(String type) { + return EntityList.stringToClassMapping.containsKey(type); + } + + public void reload() { + } + + public BiomeTypes getBiomes() { + return this.biomes; + } + + public int schedule(long delay, long period, Runnable task) { + return -1; + } + + public List getWorlds() { + List worlds = Arrays.asList(this.server.worldServers); + List ret = new ArrayList(worlds.size()); + for (WorldServer world : worlds) { + ret.add(new ForgeWorld(world)); + } + return ret; + } + + @Override + public void onCommandRegistration(List commands) { + ServerCommandManager mcMan = (ServerCommandManager) FMLServerHandler.instance().getServer().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; + } + + public void processCommand(ICommandSender var1, String[] var2) { + } + }); + } + } + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeUtil.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeUtil.java new file mode 100644 index 000000000..3afa50e9d --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeUtil.java @@ -0,0 +1,27 @@ +package com.sk89q.worldedit.forge; + +import com.sk89q.worldedit.blocks.BaseItemStack; + +import cpw.mods.fml.server.FMLServerHandler; + +import java.util.Map; +import java.util.Map.Entry; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.item.ItemStack; + +public class ForgeUtil { + + public static boolean hasPermission(EntityPlayerMP player, String perm) { + return FMLServerHandler.instance().getServer().getConfigurationManager().getOps().contains(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()) { + ret.addEnchantment(net.minecraft.enchantment.Enchantment.enchantmentsList[((Integer)entry.getKey()).intValue()], ((Integer)entry.getValue()).intValue()); + } + + return ret; + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java new file mode 100644 index 000000000..6d850e841 --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/ForgeWorld.java @@ -0,0 +1,411 @@ +package com.sk89q.worldedit.forge; + +import com.sk89q.worldedit.BiomeType; +import com.sk89q.worldedit.EditSession; +import com.sk89q.worldedit.EntityType; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.Vector2D; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.BaseItemStack; +import com.sk89q.worldedit.blocks.TileEntityBlock; +import com.sk89q.worldedit.blocks.SignBlock; +import com.sk89q.worldedit.blocks.NoteBlock; +import com.sk89q.worldedit.blocks.SkullBlock; +import com.sk89q.worldedit.blocks.DispenserBlock; +import com.sk89q.worldedit.blocks.MobSpawnerBlock; +import com.sk89q.worldedit.blocks.ChestBlock; +import com.sk89q.worldedit.blocks.ContainerBlock; +import com.sk89q.worldedit.blocks.FurnaceBlock; +import com.sk89q.worldedit.foundation.Block; +import com.sk89q.worldedit.regions.Region; +import java.lang.reflect.Field; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityHanging; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.IProjectile; +import net.minecraft.entity.item.EntityBoat; +import net.minecraft.entity.item.EntityEnderEye; +import net.minecraft.entity.item.EntityFallingSand; +import net.minecraft.entity.item.EntityItem; +import net.minecraft.entity.item.EntityItemFrame; +import net.minecraft.entity.item.EntityMinecart; +import net.minecraft.entity.item.EntityPainting; +import net.minecraft.entity.item.EntityTNTPrimed; +import net.minecraft.entity.item.EntityXPOrb; +import net.minecraft.entity.monster.EntityGolem; +import net.minecraft.entity.passive.EntityAmbientCreature; +import net.minecraft.entity.passive.EntityAnimal; +import net.minecraft.entity.passive.EntityTameable; +import net.minecraft.entity.passive.EntityVillager; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.inventory.IInventory; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.tileentity.TileEntityFurnace; +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.World; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.chunk.Chunk; +import net.minecraft.world.chunk.IChunkProvider; +import net.minecraft.world.gen.ChunkProviderServer; + +public class ForgeWorld extends LocalWorld { + private World world; + + public ForgeWorld(World world) { + this.world = world; + } + + public String getName() { + return this.world.provider.getDimensionName(); + } + + public boolean setBlockType(Vector pt, int type) { + return this.world.setBlockWithNotify(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), type); + } + + public boolean setBlockTypeFast(Vector pt, int type) { + return this.world.setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), type); + } + + public boolean setTypeIdAndData(Vector pt, int type, int data) { + return this.world.setBlockAndMetadataWithNotify(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), type, data); + } + + public boolean setTypeIdAndDataFast(Vector pt, int type, int data) { + return this.world.setBlockAndMetadata(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), type, data); + } + + public int getBlockType(Vector pt) { + return this.world.getBlockId(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); + } + + public void setBlockData(Vector pt, int data) { + this.world.setBlockMetadataWithNotify(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), data); + } + + public void setBlockDataFast(Vector pt, int data) { + this.world.setBlockMetadata(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), data); + } + + public int getBlockData(Vector pt) { + return this.world.getBlockMetadata(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); + } + + public int getBlockLightLevel(Vector pt) { + return this.world.getBlockLightValue(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ()); + } + + public boolean isValidBlockType(int id) { + return (id == 0) || (net.minecraft.block.Block.blocksList[id] != null); + } + + public BiomeType getBiome(Vector2D pt) { + return ForgeBiomeTypes.getFromBaseBiome(this.world.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 ((chunk != null) && (chunk.isChunkLoaded)) { + byte[] biomevals = chunk.getBiomeArray(); + biomevals[((pt.getBlockZ() & 0xF) << 4 | pt.getBlockX() & 0xF)] = (byte) ForgeBiomeTypes.getFromBiomeType(biome).biomeID; + } + } + } + + public boolean regenerate(Region region, EditSession editSession) { + // TODO fix this + /* + BaseBlock[] history = new BaseBlock[256 * (getMaxY() + 1)]; + + for (Vector2D chunk : region.getChunks()) { + Vector min = new Vector(chunk.getBlockX() * 16, 0, chunk.getBlockZ() * 16); + + for (int x = 0; x < 16; x++) { + for (int y = 0; y < getMaxY() + 1; y++) { + for (int z = 0; z < 16; z++) { + Vector pt = min.add(x, y, z); + int index = y * 16 * 16 + z * 16 + x; + history[index] = editSession.getBlock(pt); + } + } + } + try { + Set chunks = region.getChunks(); + IChunkProvider provider = this.world.getChunkProvider(); + if (!(provider instanceof ChunkProviderServer)) { + return false; + } + ChunkProviderServer chunkServer = (ChunkProviderServer) provider; + Field u = ChunkProviderServer.class.getDeclaredField("b"); // chunksToUnload + u.setAccessible(true); + Set unloadQueue = (Set) u.get(chunkServer); + Field m = ChunkProviderServer.class.getDeclaredField("f"); // loadedChunkHashMap + m.setAccessible(true); + LongHashMap loadedMap = (LongHashMap) m.get(chunkServer); + Field p = ChunkProviderServer.class.getDeclaredField("d"); // currentChunkProvider + p.setAccessible(true); + IChunkProvider chunkProvider = (IChunkProvider) p.get(chunkServer); + + for (Vector2D coord : chunks) { + 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); + + mcChunk = chunkProvider.provideChunk(coord.getBlockX(), coord.getBlockZ()); + } + } catch (Throwable t) { + t.printStackTrace(); + return false; + } + + for (int x = 0; x < 16; x++) { + for (int y = 0; y < getMaxY() + 1; y++) { + for (int z = 0; z < 16; z++) { + Vector pt = min.add(x, y, z); + int index = y * 16 * 16 + z * 16 + x; + + if (!region.contains(pt)) + editSession.smartSetBlock(pt, history[index]); + else { + editSession.rememberChange(pt, history[index], editSession.rawGetBlock(pt)); + } + } + } + } + } + + */ + return false; + } + + public boolean setBlock(Vector pt, Block block, boolean notify) { + if (!(block instanceof BaseBlock)) { + return false; + } + + boolean successful = this.world.setBlock(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), block.getId()); + + if (successful) { + if (block instanceof TileEntityBlock) { + copyToWorld(pt, (BaseBlock) block); + } + } + this.world.setBlockMetadata(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), block.getData()); + 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()); + if (tile != null) { + TileEntityBaseBlock block = new TileEntityBaseBlock(type, data, tile); + copyFromWorld(pt, block); + + return block; + } + return new BaseBlock(type, data); + } + + public boolean copyToWorld(Vector pt, BaseBlock block) { + return copyToWorld(pt, block, true); + } + + public boolean copyToWorld(Vector pt, BaseBlock block, boolean hardcopy) { + if (!(block instanceof TileEntityBlock)) { + return false; + } + if (block instanceof SignBlock) { + // Signs + TileEntitySign sign = new TileEntitySign(); + sign.signText = ((SignBlock) block).getText(); + world.setBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), sign); + return true; + } + + if (block instanceof MobSpawnerBlock) { + // Mob spawners + TileEntityMobSpawner spawner = new TileEntityMobSpawner(); + spawner.setMobID(((MobSpawnerBlock) block).getMobType()); + world.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); + return true; + } + + if (block instanceof SkullBlock) { + // Skull block + 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); + return true; + } + + if (block instanceof TileEntityBaseBlock) { + TileEntityBaseBlock.set(this.world, pt, (TileEntityBaseBlock) block, hardcopy); + return true; + } + return false; + } + + public boolean copyFromWorld(Vector pt, BaseBlock block) { + if (!(block instanceof TileEntityBaseBlock)) { + return false; + } + ((TileEntityBaseBlock) block).setTile(this.world.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()); + if ((tile instanceof IInventory)) { + IInventory inv = (IInventory) tile; + int size = inv.getSizeInventory(); + for (int i = 0; i < size; i++) { + inv.setInventorySlotContents(i, null); + } + return true; + } + return false; + } + + public void dropItem(Vector pt, BaseItemStack item) { + if ((item == null) || (item.getType() == 0)) { + return; + } + EntityItem entity = new EntityItem(this.world, pt.getX(), pt.getY(), pt.getZ(), ForgeUtil.toForgeItemStack(item)); + entity.delayBeforeCanPickup = 10; + this.world.spawnEntityInWorld(entity); + } + + public int removeEntities(EntityType type, Vector origin, int radius) { + int num = 0; + double radiusSq = Math.pow(radius, 2.0D); + + for (Iterator it = this.world.loadedEntityList.iterator(); it.hasNext();) { + Entity ent = it.next(); + if ((radius != -1) && (origin.distanceSq(new Vector(ent.posX, ent.posY, ent.posZ)) > radiusSq)) { + continue; + } + if (type == EntityType.ALL) { + if (((ent instanceof EntityBoat)) || ((ent instanceof EntityItem)) || ((ent instanceof EntityFallingSand)) || ((ent instanceof EntityMinecart)) || ((ent instanceof EntityHanging)) || ((ent instanceof EntityTNTPrimed)) || ((ent instanceof EntityXPOrb)) || ((ent instanceof EntityEnderEye)) || ((ent instanceof IProjectile))) { + ent.isDead = true; + num++; + } + } else if ((type == EntityType.PROJECTILES) || (type == EntityType.ARROWS)) { + if (((ent instanceof EntityEnderEye)) || ((ent instanceof IProjectile))) { + ent.isDead = true; + num++; + } + } else if (type == EntityType.BOATS) { + if ((ent instanceof EntityBoat)) { + ent.isDead = true; + num++; + } + } else if (type == EntityType.ITEMS) { + if ((ent instanceof EntityItem)) { + ent.isDead = true; + num++; + } + } else if (type == EntityType.FALLING_BLOCKS) { + if ((ent instanceof EntityFallingSand)) { + ent.isDead = true; + num++; + } + } else if (type == EntityType.MINECARTS) { + if ((ent instanceof EntityMinecart)) { + ent.isDead = true; + num++; + } + } else if (type == EntityType.PAINTINGS) { + if ((ent instanceof EntityPainting)) { + ent.isDead = true; + num++; + } + } else if (type == EntityType.ITEM_FRAMES) { + if ((ent instanceof EntityItemFrame)) { + ent.isDead = true; + num++; + } + } else if (type == EntityType.TNT) { + if ((ent instanceof EntityTNTPrimed)) { + ent.isDead = true; + num++; + } + } else if ((type == EntityType.XP_ORBS) && ((ent instanceof EntityXPOrb))) { + ent.isDead = true; + num++; + } + + } + + return num; + } + + public int killMobs(Vector origin, double radius, int flags) { + boolean killPets = (flags & 0x1) != 0; + boolean killNPCs = (flags & 0x2) != 0; + boolean killAnimals = (flags & 0x4) != 0; + + boolean killGolems = (flags & 0x8) != 0; + boolean killAmbient = (flags & 0x10) != 0; + + int num = 0; + double radiusSq = radius * radius; + + for (Iterator it = this.world.loadedEntityList.iterator(); it.hasNext();) { + Entity obj = it.next(); + if (!(obj instanceof EntityLiving)) { + continue; + } + EntityLiving ent = (EntityLiving) obj; + + if (((ent instanceof EntityPlayer)) || ((!killAnimals) && ((ent instanceof EntityAnimal))) || ((!killPets) && ((ent instanceof EntityTameable)) && (((EntityTameable) ent).isTamed())) || ((!killGolems) && ((ent instanceof EntityGolem))) || ((!killNPCs) && ((ent instanceof EntityVillager))) || ((!killAmbient) && ((ent instanceof EntityAmbientCreature)))) { + continue; + } + if ((radius < 0.0D) || (origin.distanceSq(new Vector(ent.posX, ent.posY, ent.posZ)) <= radiusSq)) { + ent.isDead = true; + num++; + } + } + + return num; + } + + public World getWorld() { + return world; + } + + public boolean equals(Object other) { + if ((other instanceof ForgeWorld)) { + return ((ForgeWorld) other).world.equals(this.world); + } + return false; + } + + public int hashCode() { + return this.world.hashCode(); + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/TileEntityBaseBlock.java b/src/forge/java/com/sk89q/worldedit/forge/TileEntityBaseBlock.java new file mode 100644 index 000000000..f82e947c5 --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/TileEntityBaseBlock.java @@ -0,0 +1,98 @@ +package com.sk89q.worldedit.forge; + +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; + +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.blocks.BaseBlock; +import com.sk89q.worldedit.blocks.TileEntityBlock; + +import net.minecraft.block.Block; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagInt; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.World; + +public class TileEntityBaseBlock extends BaseBlock implements TileEntityBlock { + private TileEntity tile; + + public TileEntity getTile() { + return this.tile; + } + + public void setTile(TileEntity tile) { + this.tile = tile; + } + + public TileEntityBaseBlock(int type, int data, TileEntity tile) { + super(type, data); + this.tile = tile; + } + + private static NBTTagCompound getNewData(Vector pt, TileEntityBaseBlock block) { + NBTTagCompound tag = new NBTTagCompound(); + + block.tile.writeToNBT(tag); + + tag.setTag("x", new NBTTagInt("x", pt.getBlockX())); + tag.setTag("y", new NBTTagInt("y", pt.getBlockY())); + tag.setTag("z", new NBTTagInt("z", pt.getBlockZ())); + + return tag; + } + + public static void set(World world, Vector pt, TileEntityBaseBlock block) { + // TODO somehow decide if we want to soft or hard copy based on block type + set(world, pt, block, true); + } + + public static void set(World world, Vector pt, TileEntityBaseBlock block, boolean hardcopy) { + TileEntity newTE = constructTEClass(world, pt, block); + if (newTE == null) { + return; + } + if (hardcopy) { + // this causes issues with certain TEs + NBTTagCompound newTag = getNewData(pt, block); + newTE.readFromNBT(newTag); + } + world.setBlockTileEntity(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ(), newTE); + } + + private static TileEntity constructTEClass(World world, Vector pt, TileEntityBaseBlock block) { + Class clazz = block.tile.getClass(); + Constructor baseConstructor; + try { + baseConstructor = clazz.getConstructor(); // creates "blank" TE + } catch (Throwable e) { + return null; // every TE *should* have this constructor, so this isn't necessary + } + TileEntity genericTE; + try { + // downcast here for return while retaining the type + genericTE = (TileEntity) baseConstructor.newInstance(); + } catch (Throwable e) { + return null; + } + /* + genericTE.blockType = Block.blocksList[block.getId()]; + genericTE.blockMetadata = block.getData(); + genericTE.xCoord = pt.getBlockX(); + genericTE.yCoord = pt.getBlockY(); + genericTE.zCoord = pt.getBlockZ(); + genericTE.worldObj = world; + */ // handled by internal code + return genericTE; + } + + public String getNbtId() { + String id = null; + NBTTagCompound tag = new NBTTagCompound(); + try { + this.tile.writeToNBT(tag); + } catch (Exception e) { + return ""; + } + return tag.getString("id"); + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/WECUIPacketHandler.java b/src/forge/java/com/sk89q/worldedit/forge/WECUIPacketHandler.java new file mode 100644 index 000000000..0f88be7fd --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/WECUIPacketHandler.java @@ -0,0 +1,24 @@ +package com.sk89q.worldedit.forge; + +import com.sk89q.worldedit.LocalSession; +import cpw.mods.fml.common.network.IPacketHandler; +import cpw.mods.fml.common.network.Player; +import java.nio.charset.Charset; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.network.INetworkManager; +import net.minecraft.network.packet.Packet250CustomPayload; + +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 (session.hasCUISupport()) { + return; + } + + String text = new String(packet.data, UTF_8_CHARSET); + session.handleCUIInitializationMessage(text); + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/WorldEditForgeListener.java b/src/forge/java/com/sk89q/worldedit/forge/WorldEditForgeListener.java new file mode 100644 index 000000000..d312602e0 --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/WorldEditForgeListener.java @@ -0,0 +1,62 @@ +package com.sk89q.worldedit.forge; + +import com.sk89q.worldedit.LocalPlayer; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.WorldEdit; +import com.sk89q.worldedit.WorldVector; +import net.minecraft.command.ICommand; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraftforge.event.CommandEvent; +import net.minecraftforge.event.Event.Result; +import net.minecraftforge.event.ForgeSubscribe; +import net.minecraftforge.event.entity.player.PlayerInteractEvent; +import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; + +public class WorldEditForgeListener { + @ForgeSubscribe + public void onCommandEvent(CommandEvent event) { + if ((event.sender instanceof EntityPlayerMP)) { + String[] split = new String[event.parameters.length + 1]; + System.arraycopy(event.parameters, 0, split, 1, event.parameters.length); + split[0] = ("/" + event.command.getCommandName()); + + WorldEditMod.inst.getWorldEdit().handleCommand(WorldEditMod.inst.wrapPlayer((EntityPlayerMP) event.sender), split); + } + } + + @ForgeSubscribe + public void onPlayerInteract(PlayerInteractEvent event) { + if (event.useItem == Result.DENY) { + return; + } + + LocalPlayer player = WorldEditMod.inst.wrapPlayer((EntityPlayerMP) event.entityPlayer); + LocalWorld world = WorldEditMod.inst.getWorld(event.entityPlayer.worldObj); + WorldEdit we = WorldEditMod.inst.getWorldEdit(); + + PlayerInteractEvent.Action action = event.action; + if (action == PlayerInteractEvent.Action.LEFT_CLICK_BLOCK) { + WorldVector pos = new WorldVector(world, event.x, event.y, event.z); + + if (we.handleBlockLeftClick(player, pos)) { + event.setCanceled(true); + } + + if (we.handleArmSwing(player)) { + event.setCanceled(true); + } + } else if (action == PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK) { + WorldVector pos = new WorldVector(world, event.x, event.y, event.z); + + if (we.handleBlockRightClick(player, pos)) { + event.setCanceled(true); + } + + if (we.handleRightClick(player)) + event.setCanceled(true); + } else if ((action == PlayerInteractEvent.Action.RIGHT_CLICK_AIR) && (we.handleRightClick(player))) { + event.setCanceled(true); + } + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/WorldEditMod.java b/src/forge/java/com/sk89q/worldedit/forge/WorldEditMod.java new file mode 100644 index 000000000..59b711f9b --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/WorldEditMod.java @@ -0,0 +1,159 @@ +package com.sk89q.worldedit.forge; + +import com.sk89q.util.yaml.YAMLProcessor; +import com.sk89q.wepif.PermissionsResolverManager; +import com.sk89q.worldedit.LocalSession; +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.ServerInterface; +import com.sk89q.worldedit.WorldEdit; +import cpw.mods.fml.common.FMLLog; +import cpw.mods.fml.common.Mod; +import cpw.mods.fml.common.Mod.Init; +import cpw.mods.fml.common.Mod.Instance; +import cpw.mods.fml.common.Mod.PostInit; +import cpw.mods.fml.common.Mod.PreInit; +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.network.NetworkRegistry; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.jar.JarFile; +import java.util.logging.Logger; +import java.util.zip.ZipEntry; + +import net.minecraft.entity.player.EntityPlayerMP; +import net.minecraft.world.World; +import net.minecraft.world.WorldServer; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.event.EventBus; + +@Mod(modid = "WorldEdit", name = "WorldEdit", version = "5.5.2-forge-alpha1") +public class WorldEditMod { + + @Mod.Instance("WorldEdit") + public static WorldEditMod inst; + + protected static Logger logger; + public static final String CUI_PLUGIN_CHANNEL = "WECUI"; + private ForgeServerInterface server; + private WorldEdit controller; + private ForgeConfiguration config; + private File workingDir; + + @SideOnly(Side.SERVER) + @Mod.PreInit + public void preInit(FMLPreInitializationEvent event) { + logger = Logger.getLogger(((Mod) getClass().getAnnotation(Mod.class)).modid()); + logger.setParent(FMLLog.getLogger()); + String modVersion = ((Mod) WorldEditMod.class.getAnnotation(Mod.class)).version(); + String manifestVersion = WorldEdit.getVersion(); + if (!manifestVersion.equalsIgnoreCase(modVersion)) { + WorldEdit.setVersion(manifestVersion + " (" + modVersion + ")"); + } + + this.workingDir = new File(event.getModConfigurationDirectory() + File.separator + "WorldEdit"); + this.workingDir.mkdir(); + + createDefaultConfiguration(event.getSourceFile(), "worldedit.properties"); + config = new ForgeConfiguration(this); + config.load(); + // PermissionsResolverManager.initialize(this, this.workingDir); + } + + @SideOnly(Side.SERVER) + @Mod.Init + public void init(FMLInitializationEvent event) { + this.server = new ForgeServerInterface(); + this.controller = new WorldEdit(this.server, this.config); + + NetworkRegistry.instance().registerChannel(new WECUIPacketHandler(), "WECUI"); + + MinecraftForge.EVENT_BUS.register(new WorldEditForgeListener()); + } + + @SideOnly(Side.SERVER) + @Mod.PostInit + public void postInit(FMLPostInitializationEvent event) { + logger.info("WorldEdit " + WorldEdit.getVersion() + " Loaded"); + } + + public ForgeConfiguration getConfig() { + return this.config; + } + + /*public PermissionsResolverManager getPermissionsResolver() { + return PermissionsResolverManager.getInstance(); + }*/ + + public LocalSession getSession(EntityPlayerMP player) { + return this.controller.getSession(wrapPlayer(player)); + } + + public LocalWorld getWorld(World world) { + return new ForgeWorld(world); + } + + public ForgePlayer wrapPlayer(EntityPlayerMP player) { + return new ForgePlayer(player); + } + + public WorldEdit getWorldEdit() { + return this.controller; + } + + public ServerInterface getServerInterface() { + return this.server; + } + + public File getWorkingDir() { + return this.workingDir; + } + + private void createDefaultConfiguration(File jar, String name) { + File actual = new File(getWorkingDir(), name); + if (!actual.exists()) { + InputStream input = null; + try { + JarFile 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); + } + if (input != null) { + FileOutputStream output = null; + try { + output = new FileOutputStream(actual); + byte[] buf = new byte[8192]; + int length = 0; + while ((length = input.read(buf)) > 0) { + output.write(buf, 0, length); + } + + logger.info("Default configuration file written: " + name); + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + if (input != null) + input.close(); + } catch (IOException e) { + } + try { + if (output != null) + output.close(); + } catch (IOException e) { + } + } + } + } + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/selections/CuboidSelection.java b/src/forge/java/com/sk89q/worldedit/forge/selections/CuboidSelection.java new file mode 100644 index 000000000..c1359d959 --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/selections/CuboidSelection.java @@ -0,0 +1,44 @@ +package com.sk89q.worldedit.forge.selections; + +import com.sk89q.worldedit.Location; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.forge.WorldEditMod; +import com.sk89q.worldedit.regions.CuboidRegion; +import com.sk89q.worldedit.regions.CuboidRegionSelector; +import com.sk89q.worldedit.regions.RegionSelector; +import net.minecraft.world.World; + +public class CuboidSelection extends RegionSelection { + protected CuboidRegion cuboid; + + public CuboidSelection(World world, Location pt1, Location pt2) { + this(world, pt1 == null ? null : pt1.getPosition(), pt2 == null ? null : pt2.getPosition()); + } + + public CuboidSelection(World world, Vector pt1, Vector pt2) { + super(world); + + if (pt1 == null) { + throw new IllegalArgumentException("Null point 1 not permitted"); + } + + if (pt2 == null) { + throw new IllegalArgumentException("Null point 2 not permitted"); + } + + CuboidRegionSelector sel = new CuboidRegionSelector(WorldEditMod.inst.getWorld(world)); + + sel.selectPrimary(pt1); + sel.selectSecondary(pt2); + + this.cuboid = sel.getIncompleteRegion(); + + setRegionSelector(sel); + setRegion(this.cuboid); + } + + public CuboidSelection(World world, RegionSelector sel, CuboidRegion region) { + super(world, sel, region); + this.cuboid = region; + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/selections/Polygonal2DSelection.java b/src/forge/java/com/sk89q/worldedit/forge/selections/Polygonal2DSelection.java new file mode 100644 index 000000000..aad2be9eb --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/selections/Polygonal2DSelection.java @@ -0,0 +1,38 @@ +package com.sk89q.worldedit.forge.selections; + +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.forge.WorldEditMod; +import com.sk89q.worldedit.regions.Polygonal2DRegion; +import com.sk89q.worldedit.regions.Polygonal2DRegionSelector; +import com.sk89q.worldedit.regions.RegionSelector; +import java.util.Collections; +import java.util.List; +import net.minecraft.world.World; + +public class Polygonal2DSelection extends RegionSelection { + protected Polygonal2DRegion poly2d; + + public Polygonal2DSelection(World world, RegionSelector sel, Polygonal2DRegion region) { + super(world, sel, region); + this.poly2d = region; + } + + public Polygonal2DSelection(World world, List points, int minY, int maxY) { + super(world); + LocalWorld lWorld = WorldEditMod.inst.getWorld(world); + + minY = Math.min(Math.max(0, minY), world.getActualHeight()); + maxY = Math.min(Math.max(0, maxY), world.getActualHeight()); + + Polygonal2DRegionSelector sel = new Polygonal2DRegionSelector(lWorld, points, minY, maxY); + + this.poly2d = sel.getIncompleteRegion(); + + setRegionSelector(sel); + setRegion(this.poly2d); + } + + public List getNativePoints() { + return Collections.unmodifiableList(this.poly2d.getPoints()); + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/selections/RegionSelection.java b/src/forge/java/com/sk89q/worldedit/forge/selections/RegionSelection.java new file mode 100644 index 000000000..1c0d21e5e --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/selections/RegionSelection.java @@ -0,0 +1,85 @@ +package com.sk89q.worldedit.forge.selections; + +import com.sk89q.worldedit.LocalWorld; +import com.sk89q.worldedit.Location; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.forge.WorldEditMod; +import com.sk89q.worldedit.regions.Region; +import com.sk89q.worldedit.regions.RegionSelector; +import net.minecraft.world.World; + +public abstract class RegionSelection implements Selection { + private World world; + private RegionSelector selector; + private Region region; + + public RegionSelection(World world) { + this.world = world; + } + + public RegionSelection(World world, RegionSelector selector, Region region) { + this.world = world; + this.region = region; + this.selector = selector; + } + + protected Region getRegion() { + return this.region; + } + + protected void setRegion(Region region) { + this.region = region; + } + + public RegionSelector getRegionSelector() { + return this.selector; + } + + protected void setRegionSelector(RegionSelector selector) { + this.selector = selector; + } + + public Location getMinimumPoint() { + return new Location(WorldEditMod.inst.getWorld(this.world), this.region.getMinimumPoint()); + } + + public Vector getNativeMinimumPoint() { + return this.region.getMinimumPoint(); + } + + public Location getMaximumPoint() { + return new Location(WorldEditMod.inst.getWorld(this.world), this.region.getMaximumPoint()); + } + + public Vector getNativeMaximumPoint() { + return this.region.getMaximumPoint(); + } + + public World getWorld() { + return this.world; + } + + public int getArea() { + return this.region.getArea(); + } + + public int getWidth() { + return this.region.getWidth(); + } + + public int getHeight() { + return this.region.getHeight(); + } + + public int getLength() { + return this.region.getLength(); + } + + public boolean contains(Location pt) { + if (!pt.getWorld().equals(this.world)) { + return false; + } + + return this.region.contains(new Vector(pt.getPosition())); + } +} \ No newline at end of file diff --git a/src/forge/java/com/sk89q/worldedit/forge/selections/Selection.java b/src/forge/java/com/sk89q/worldedit/forge/selections/Selection.java new file mode 100644 index 000000000..eb1ec8a31 --- /dev/null +++ b/src/forge/java/com/sk89q/worldedit/forge/selections/Selection.java @@ -0,0 +1,30 @@ +package com.sk89q.worldedit.forge.selections; + +import com.sk89q.worldedit.Location; +import com.sk89q.worldedit.Vector; +import com.sk89q.worldedit.regions.RegionSelector; +import net.minecraft.world.World; + +public abstract interface Selection { + public abstract Location getMinimumPoint(); + + public abstract Vector getNativeMinimumPoint(); + + public abstract Location getMaximumPoint(); + + public abstract Vector getNativeMaximumPoint(); + + public abstract RegionSelector getRegionSelector(); + + public abstract World getWorld(); + + public abstract int getArea(); + + public abstract int getWidth(); + + public abstract int getHeight(); + + public abstract int getLength(); + + public abstract boolean contains(Location paramLocation); +} \ No newline at end of file diff --git a/src/forge/resources/worldedit.properties b/src/forge/resources/worldedit.properties new file mode 100644 index 000000000..f7e362f20 --- /dev/null +++ b/src/forge/resources/worldedit.properties @@ -0,0 +1,32 @@ +#Don't put comments; they get removed +default-max-polygon-points=-1 +schematic-save-dir=schematics +allow-extra-data-values=false +super-pickaxe-many-drop-items=true +register-help=true +nav-wand-item=345 +profile=false +super-pickaxe-drop-items=true +disallowed-blocks=6,26,27,28,31,32,34,36,37,38,39,40,46,50,51,55,59,66,69,75,76,93,94,77,81,83,7,14,15,16,56 +max-super-pickaxe-size=5 +max-brush-radius=10 +craftscript-dir=craftscripts +no-double-slash=false +wand-item=271 +shell-save-type= +scripting-timeout=3000 +snapshots-dir= +use-inventory-creative-override=false +log-file=worldedit.log +max-changed-blocks=-1 +nav-wand-distance=50 +butcher-default-radius=-1 +default-max-changed-blocks=-1 +history-size=15 +use-inventory=false +allow-symbolic-links=false +use-inventory-override=false +log-commands=false +butcher-max-radius=-1 +max-polygon-points=20 +max-radius=-1