Working on fixing dead chunks.

Fixed Blizzard memory issue.
This commit is contained in:
Jonathan Williams 2014-05-04 09:31:04 -07:00
parent fe7ed5c96a
commit a9f4a900f0
4 changed files with 275 additions and 136 deletions

View File

@ -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<net.minecraft.server.v1_7_R3.Chunk> 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<net.minecraft.server.v1_7_R3.Chunk> arraylist = new ArrayList<net.minecraft.server.v1_7_R3.Chunk>();
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<net.minecraft.server.v1_7_R3.Chunk> 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<net.minecraft.server.v1_7_R3.Chunk> 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<String, World> worlds = (Map<String, World>)f.get(server);
Map<String, World> worlds = (Map<String, World>) 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();

View File

@ -211,6 +211,9 @@ public class UtilText
for (Chunk c : chunks)
{
if (c == null)
continue;
c.initLighting();
}

View File

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

View File

@ -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<Entry<Projectile, Player>> snowBallIterator = _snowball.entrySet().iterator(); snowBallIterator.hasNext();)
{
Entry<Projectile, Player> entry = snowBallIterator.next();
if (!entry.getValue().isOnline())
snowBallIterator.remove();
}
}
@Override
public void Reset(Player player)