From a9f4a900f08ba2f4b7f3f9ad6ade3a60c61bc370 Mon Sep 17 00:00:00 2001 From: Jonathan Williams Date: Sun, 4 May 2014 09:31:04 -0700 Subject: [PATCH] Working on fixing dead chunks. Fixed Blizzard memory issue. --- .../mineplex/core/common/util/MapUtil.java | 389 ++++++++++++------ .../mineplex/core/common/util/UtilText.java | 3 + .../mineplex/core/common/util/WorldUtil.java | 2 +- .../game/classcombat/Skill/Mage/Blizzard.java | 17 + 4 files changed, 275 insertions(+), 136 deletions(-) diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/MapUtil.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/MapUtil.java index 2ff84d032..fc492ead6 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/MapUtil.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/MapUtil.java @@ -1,18 +1,25 @@ package mineplex.core.common.util; import java.lang.reflect.Field; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import net.minecraft.server.v1_7_R3.Block; +import net.minecraft.server.v1_7_R3.BlockContainer; +import net.minecraft.server.v1_7_R3.Blocks; import net.minecraft.server.v1_7_R3.ChunkCoordIntPair; import net.minecraft.server.v1_7_R3.ChunkSection; +import net.minecraft.server.v1_7_R3.EnumSkyBlock; +import net.minecraft.server.v1_7_R3.IContainer; import net.minecraft.server.v1_7_R3.MinecraftServer; +import net.minecraft.server.v1_7_R3.PacketPlayOutMapChunkBulk; import net.minecraft.server.v1_7_R3.PacketPlayOutMultiBlockChange; import net.minecraft.server.v1_7_R3.RegionFile; import net.minecraft.server.v1_7_R3.RegionFileCache; +import net.minecraft.server.v1_7_R3.TileEntity; import org.bukkit.Bukkit; import org.bukkit.Chunk; @@ -29,23 +36,23 @@ import org.bukkit.event.world.WorldUnloadEvent; import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.util.Vector; -public class MapUtil +public class MapUtil { public static void ReplaceOreInChunk(Chunk chunk, Material replacee, Material replacer) { - net.minecraft.server.v1_7_R3.Chunk c = ((CraftChunk)chunk).getHandle(); - - for(int x = 0; x < 16; x++) - { - for(int z = 0; z < 16; z++) + net.minecraft.server.v1_7_R3.Chunk c = ((CraftChunk) chunk).getHandle(); + + for (int x = 0; x < 16; x++) + { + for (int z = 0; z < 16; z++) { - for(int y = 0; y < 18; y++) + for (int y = 0; y < 18; y++) { int bX = c.locX << 4 | x & 0xF; int bY = y & 0xFF; - int bZ = c.locZ << 4 | z & 0xF; + int bZ = c.locZ << 4 | z & 0xF; - if(c.getType(bX & 0xF, bY, bZ & 0xF).k() == replacee.getId()) + if (c.getType(bX & 0xF, bY, bZ & 0xF).k() == replacee.getId()) { c.b(bX & 0xF, bY, bZ & 0xF, replacer.getId()); } @@ -55,182 +62,294 @@ public class MapUtil c.initLighting(); } - + public static void QuickChangeBlockAt(Location location, Material setTo) { QuickChangeBlockAt(location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), setTo); } - + public static void QuickChangeBlockAt(Location location, int id, byte data) { - QuickChangeBlockAt(location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), id, data); + QuickChangeBlockAt(location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), id, + data); } - + public static void QuickChangeBlockAt(World world, int x, int y, int z, Material setTo) - { + { QuickChangeBlockAt(world, x, y, z, setTo, 0); } - - public static void QuickChangeBlockAt(World world, int x, int y, int z, Material setTo, int data) - { - QuickChangeBlockAt(world, x, y, z, setTo.getId(), data); - } - - public static void QuickChangeBlockAt(World world, int x, int y, int z, int id, int data) - { - Chunk chunk = world.getChunkAt(x >> 4, z >> 4); - net.minecraft.server.v1_7_R3.Chunk c = ((CraftChunk)chunk).getHandle(); - - c.a(x & 0xF, y, z & 0xF, Block.e(id), data); - ((CraftWorld)world).getHandle().notify(x, y, z); - } - + + public static void QuickChangeBlockAt(World world, int x, int y, int z, Material setTo, int data) + { + QuickChangeBlockAt(world, x, y, z, setTo.getId(), data); + } + + public static void QuickChangeBlockAt(World world, int x, int y, int z, int id, int data) + { + Chunk chunk = world.getChunkAt(x >> 4, z >> 4); + net.minecraft.server.v1_7_R3.Chunk c = ((CraftChunk) chunk).getHandle(); + + c.a(x & 0xF, y, z & 0xF, Block.e(id), data); + ((CraftWorld) world).getHandle().notify(x, y, z); + } + public static int GetHighestBlockInCircleAt(World world, int bx, int bz, int radius) { - int count = 0; - int totalHeight = 0; + int count = 0; + int totalHeight = 0; - final double invRadiusX = 1 / radius; - final double invRadiusZ = 1 / radius; + final double invRadiusX = 1 / radius; + final double invRadiusZ = 1 / radius; - final int ceilRadiusX = (int) Math.ceil(radius); - final int ceilRadiusZ = (int) Math.ceil(radius); - - double nextXn = 0; - forX: for (int x = 0; x <= ceilRadiusX; ++x) - { - final double xn = nextXn; - nextXn = (x + 1) * invRadiusX; - double nextZn = 0; - forZ: for (int z = 0; z <= ceilRadiusZ; ++z) - { - final double zn = nextZn; - nextZn = (z + 1) * invRadiusZ; + final int ceilRadiusX = (int) Math.ceil(radius); + final int ceilRadiusZ = (int) Math.ceil(radius); - double distanceSq = xn*xn + zn*zn; - if (distanceSq > 1) - { - if (z == 0) { - break forX; - } - break forZ; - } - - totalHeight += world.getHighestBlockAt(bx + x, bz + z).getY(); - count++; - } - } - - return totalHeight / count; + double nextXn = 0; + forX: for (int x = 0; x <= ceilRadiusX; ++x) + { + final double xn = nextXn; + nextXn = (x + 1) * invRadiusX; + double nextZn = 0; + forZ: for (int z = 0; z <= ceilRadiusZ; ++z) + { + final double zn = nextZn; + nextZn = (z + 1) * invRadiusZ; + + double distanceSq = xn * xn + zn * zn; + if (distanceSq > 1) + { + if (z == 0) + { + break forX; + } + break forZ; + } + + totalHeight += world.getHighestBlockAt(bx + x, bz + z).getY(); + count++; + } + } + + return totalHeight / count; } - + public static void ResendChunksForNearbyPlayers(Collection chunks) { - for (net.minecraft.server.v1_7_R3.Chunk c : chunks) - { - - for (Player player : Bukkit.getOnlinePlayers()) - { - Vector pV = player.getLocation().toVector(); - int xDist = Math.abs((pV.getBlockX() >> 4) - c.locX); - int zDist = Math.abs((pV.getBlockZ() >> 4) - c.locZ); - - if (xDist + zDist <= 12) - { - SendChunkForPlayer(c, player); - } - } - } + for (Player player : Bukkit.getOnlinePlayers()) + { + ArrayList arraylist = new ArrayList(); + Vector pV = player.getLocation().toVector(); + + for (net.minecraft.server.v1_7_R3.Chunk c : chunks) + { + if (c == null) + continue; + + int xDist = Math.abs((pV.getBlockX() >> 4) - c.locX); + int zDist = Math.abs((pV.getBlockZ() >> 4) - c.locZ); + + if (xDist + zDist <= 12) + { + arraylist.add(c); + } + } + + if (!arraylist.isEmpty()) + { + //((CraftPlayer) player).getHandle().playerConnection + //.sendPacket(new PacketPlayOutMapChunkBulk(arraylist)); + } + } } - + public static net.minecraft.server.v1_7_R3.Chunk ChunkBlockChange(Location location, int id, byte data) { - return ChunkBlockChange(location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), id, data); + return ChunkBlockChange(location.getWorld(), location.getBlockX(), location.getBlockY(), location.getBlockZ(), + id, data); } - - public static net.minecraft.server.v1_7_R3.Chunk ChunkBlockChange(World world, int x, int y, int z, int id, byte data) + + public static net.minecraft.server.v1_7_R3.Chunk ChunkBlockChange(World world, int x, int y, int z, int id, + byte data) { - net.minecraft.server.v1_7_R3.Chunk c = ((CraftChunk)world.getChunkAt(x >> 4, z >> 4)).getHandle(); - Block block = Block.e(id); - + net.minecraft.server.v1_7_R3.Chunk c = ((CraftChunk) world.getChunkAt(x >> 4, z >> 4)).getHandle(); + Block block = Block.e(id); + + if (c.a(x & 0xF, y, z & 0xF, Block.e(id), data)) + return c; + + return null; + /* x = x & 0xF; z = z & 0xF; - int l1 = c.getType(x, y, z).k(); - int i2 = c.getData(x, y, z); - - ChunkSection chunksection = c.i()[(y >> 4)] == null ? new ChunkSection(y >> 4 << 4, !c.world.worldProvider.g) : c.i()[(y >> 4)]; + int i1 = z << 4 | x; + if (y >= c.b[i1] - 1) + { + c.b[i1] = -999; + } - int j2 = c.locX * 16 + x; - int k2 = c.locZ * 16 + z; + int j1 = c.heightMap[i1]; + Block block1 = c.getType(x, y, z); + int k1 = c.getData(x, y, z); - if ((l1 != 0) && (!c.world.isStatic)) - Block.e(l1).f(c.world, j2, y, k2, i2); - - chunksection.setTypeId(x, y & 0xF, z, block); + if (block1 == block && k1 == data) { + return null; + } else { + ChunkSection chunksection = c.i()[y >> 4]; + boolean flag = false; - if (chunksection.getTypeId(x, y & 0xF, z) != block) - { - return null; - } - - chunksection.setData(x, y & 0xF, z, data); - - return c; + if (chunksection == null) { + if (block == Blocks.AIR) { + return null; + } + + chunksection = c.i()[y >> 4] = new ChunkSection(y >> 4 << 4, !c.world.worldProvider.g); + flag = y >= j1; + } + + int l1 = c.locX * 16 + x; + int i2 = c.locZ * 16 + z; + + if (!c.world.isStatic) { + block1.f(c.world, l1, y, i2, k1); + } + + // CraftBukkit start - Delay removing containers until after they're cleaned up + if (!(block1 instanceof IContainer)) { + chunksection.setTypeId(x, y & 15, z, block); + } + // CraftBukkit end + + if (!c.world.isStatic) { + block1.remove(c.world, l1, y, i2, block1, k1); + } else if (block1 instanceof IContainer && block1 != block) { + c.world.p(l1, y, i2); + } + + // CraftBukkit start - Remove containers now after cleanup + if (block1 instanceof IContainer) { + chunksection.setTypeId(x, y & 15, z, block); + } + // CraftBukkit end + + if (chunksection.getTypeId(x, y & 15, z) != block) { + return null; + } else { + chunksection.setData(x, y & 15, z, data); + if (flag) { + c.initLighting(); + } else { + int j2 = block.k(); + int k2 = block1.k(); + + if (j2 > 0) { + if (y >= j1) { + c.h(x, y + 1, z); + } + } else if (y == j1 - 1) { + c.h(x, y, z); + } + + if (j2 != k2 && (j2 < k2 || c.getBrightness(EnumSkyBlock.SKY, x, y, z) > 0 || c.getBrightness(EnumSkyBlock.BLOCK, x, y, z) > 0)) { + c.e(x, z); + } + } + + TileEntity tileentity; + + if (block1 instanceof IContainer) { + tileentity = c.e(x, y, z); + if (tileentity != null) { + tileentity.u(); + } + } + + // CraftBukkit - Don't place while processing the BlockPlaceEvent, unless it's a BlockContainer. Prevents blocks such as TNT from activating when cancelled. + if (!c.world.isStatic && (!c.world.captureBlockStates || block instanceof BlockContainer)) { + block.onPlace(c.world, l1, y, i2); + } + + if (block instanceof IContainer) { + + tileentity = c.e(x, y, z); + if (tileentity == null) { + tileentity = ((IContainer) block).a(c.world, data); + c.world.setTileEntity(l1, y, i2, tileentity); + } + + if (tileentity != null) { + tileentity.u(); + } + } + + c.n = true; + return c; + */ } - + public static void SendChunkForPlayer(net.minecraft.server.v1_7_R3.Chunk chunk, Player player) - { + { SendChunkForPlayer(chunk.locX, chunk.locZ, player); } - + @SuppressWarnings("unchecked") public static void SendChunkForPlayer(int x, int z, Player player) { - //System.out.println("Sending Chunk " + x + ", " + z); - ((CraftPlayer)player).getHandle().chunkCoordIntPairQueue.add(new ChunkCoordIntPair(x, z)); + // System.out.println("Sending Chunk " + x + ", " + z); + ((CraftPlayer) player).getHandle().chunkCoordIntPairQueue.add(new ChunkCoordIntPair(x, z)); } - + @SuppressWarnings("unchecked") - public static void SendMultiBlockForPlayer(int x, int z, short[] dirtyBlocks, int dirtyCount, World world, Player player) + public static void SendMultiBlockForPlayer(int x, int z, short[] dirtyBlocks, int dirtyCount, World world, + Player player) { - //System.out.println("Sending MultiBlockChunk " + x + ", " + z); - ((CraftPlayer)player).getHandle().playerConnection.sendPacket(new PacketPlayOutMultiBlockChange(dirtyCount, dirtyBlocks, ((CraftWorld)world).getHandle().getChunkAt(x, z))); + // System.out.println("Sending MultiBlockChunk " + x + ", " + z); + ((CraftPlayer) player).getHandle().playerConnection.sendPacket(new PacketPlayOutMultiBlockChange(dirtyCount, + dirtyBlocks, ((CraftWorld) world).getHandle().getChunkAt(x, z))); } - + public static void UnloadWorld(JavaPlugin plugin, World world) { world.setAutoSave(false); - + for (Entity entity : world.getEntities()) { entity.remove(); } - - ((CraftWorld)world).getHandle().entityList.clear(); - - CraftServer server = (CraftServer)plugin.getServer(); - CraftWorld craftWorld = (CraftWorld)world; - - Bukkit.getPluginManager().callEvent(new WorldUnloadEvent(((CraftWorld)world).getHandle().getWorld())); - - Iterator chunkIterator = ((CraftWorld)world).getHandle().chunkProviderServer.chunks.values().iterator(); - + + for (Object entity : ((CraftWorld) world).getHandle().entityList) + { + if (entity instanceof net.minecraft.server.v1_7_R3.Entity) + { + ((net.minecraft.server.v1_7_R3.Entity) entity).world = null; + } + } + + ((CraftWorld) world).getHandle().entityList.clear(); + + CraftServer server = (CraftServer) plugin.getServer(); + CraftWorld craftWorld = (CraftWorld) world; + + Bukkit.getPluginManager().callEvent(new WorldUnloadEvent(((CraftWorld) world).getHandle().getWorld())); + + Iterator chunkIterator = ((CraftWorld) world).getHandle().chunkProviderServer.chunks + .values().iterator(); + while (chunkIterator.hasNext()) { - net.minecraft.server.v1_7_R3.Chunk chunk = chunkIterator.next(); + net.minecraft.server.v1_7_R3.Chunk chunk = chunkIterator.next(); chunk.removeEntities(); } - - ((CraftWorld)world).getHandle().chunkProviderServer.chunks.clear(); - ((CraftWorld)world).getHandle().chunkProviderServer.unloadQueue.clear(); - + + ((CraftWorld) world).getHandle().chunkProviderServer.chunks.clear(); + ((CraftWorld) world).getHandle().chunkProviderServer.unloadQueue.clear(); + try { Field f = server.getClass().getDeclaredField("worlds"); f.setAccessible(true); @SuppressWarnings("unchecked") - Map worlds = (Map)f.get(server); + Map worlds = (Map) f.get(server); worlds.remove(world.getName().toLowerCase()); f.setAccessible(false); } @@ -244,12 +363,12 @@ public class MapUtil } MinecraftServer ms = null; - + try { Field f = server.getClass().getDeclaredField("console"); f.setAccessible(true); - ms = (MinecraftServer)f.get(server); + ms = (MinecraftServer) f.get(server); f.setAccessible(false); } catch (IllegalAccessException ex) @@ -260,11 +379,11 @@ public class MapUtil { System.out.println("Error getting minecraftserver variable: " + ex.getMessage()); } - + ms.worlds.remove(ms.worlds.indexOf(craftWorld.getHandle())); } - - @SuppressWarnings({ "rawtypes"}) + + @SuppressWarnings({ "rawtypes" }) public static boolean ClearWorldReferences(String worldName) { HashMap regionfiles = (HashMap) RegionFileCache.a; @@ -275,7 +394,7 @@ public class MapUtil { Map.Entry e = (Map.Entry) iterator.next(); RegionFile file = (RegionFile) e.getValue(); - + try { file.c(); diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java index 3c5f45612..012ef6011 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java @@ -211,6 +211,9 @@ public class UtilText for (Chunk c : chunks) { + if (c == null) + continue; + c.initLighting(); } diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/WorldUtil.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/WorldUtil.java index 5d349a31b..0f41248cf 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/WorldUtil.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/WorldUtil.java @@ -63,7 +63,7 @@ public class WorldUtil converter.convert(name, new ConvertProgressUpdater(server.getServer())); } - int dimension = server.getServer().worlds.size() + 1; + int dimension = 10; boolean used = false; do { diff --git a/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Mage/Blizzard.java b/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Mage/Blizzard.java index 374dd0a5c..28086f9ee 100644 --- a/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Mage/Blizzard.java +++ b/Plugins/Mineplex.Minecraft.Game.ClassCombat/src/mineplex/minecraft/game/classcombat/Skill/Mage/Blizzard.java @@ -1,6 +1,8 @@ package mineplex.minecraft.game.classcombat.Skill.Mage; import java.util.HashMap; +import java.util.Iterator; +import java.util.Map.Entry; import java.util.WeakHashMap; import java.util.HashSet; @@ -221,6 +223,21 @@ public class Blizzard extends SkillActive Factory.BlockRestore().Snow(event.getEntity().getLocation().getBlock(), (byte)1, (byte)7, 2000, 250, 0); } + + @EventHandler + public void clearInvalidSnowballedPlayers(UpdateEvent event) + { + if (event.getType() != UpdateType.SEC) + return; + + for (Iterator> snowBallIterator = _snowball.entrySet().iterator(); snowBallIterator.hasNext();) + { + Entry entry = snowBallIterator.next(); + + if (!entry.getValue().isOnline()) + snowBallIterator.remove(); + } + } @Override public void Reset(Player player)