From be7292673512843c7f34ba499c9e5f398870671d Mon Sep 17 00:00:00 2001 From: Yive Date: Tue, 12 Jan 2016 08:31:30 -0800 Subject: [PATCH] Merge With KCauldron Official More of the unofficial fixes/modifications will come in later commits --- .../fml/common/registry/GameData.java.patch | 2 +- .../minecraft/entity/EntityTracker.java.patch | 23 ++- .../entity/item/EntityItemFrame.java.patch | 9 ++ .../entity/item/EntityTNTPrimed.java.patch | 14 +- .../network/NetHandlerPlayServer.java.patch | 6 +- .../network/NetworkManager.java.patch | 22 ++- .../ServerConfigurationManager.java.patch | 33 +++-- .../network/NetHandlerHandshakeTCP.java.patch | 16 ++- .../tileentity/TileEntity.java.patch | 12 -- .../net/minecraft/world/Explosion.java.patch | 24 +++- patches/net/minecraft/world/World.java.patch | 131 ++++++++++++++---- .../minecraft/world/WorldServer.java.patch | 30 ++-- .../minecraft/world/chunk/Chunk.java.patch | 110 ++++++++++++--- .../world/chunk/storage/RegionFile.java.patch | 40 ++++++ .../world/gen/ChunkProviderServer.java.patch | 109 ++++++++++----- .../world/storage/MapData.java.patch | 65 ++++++++- .../storage/ThreadedFileIOBase.java.patch | 20 +++ .../common/chunkio/ChunkIOProvider.java.patch | 18 ++- .../oredict/OreDictionary.java.patch | 4 +- reformat.sh | 4 + src/main/java/kcauldron/KCauldron.java | 17 +++ src/main/java/kcauldron/KCauldronCommand.java | 127 +++++++++++++++-- src/main/java/kcauldron/KCauldronConfig.java | 2 +- .../updater/DefaultUpdateCallback.java | 15 +- .../kcauldron/updater/KCauldronUpdater.java | 3 +- .../kcauldron/updater/KVersionRetriever.java | 4 +- .../network/ThreadPlayerLookupUUID.java | 2 +- .../configuration/CauldronConfig.java | 4 +- .../cauldron/configuration/StringSetting.java | 32 ++--- .../org/bukkit/craftbukkit/CraftServer.java | 6 +- .../org/bukkit/craftbukkit/CraftWorld.java | 38 ++--- .../bukkit/craftbukkit/block/CraftSkull.java | 2 +- .../craftbukkit/entity/CraftEntity.java | 2 +- .../craftbukkit/entity/CraftHumanEntity.java | 4 +- .../craftbukkit/inventory/CraftMetaSkull.java | 3 +- .../craftbukkit/map/CraftMapRenderer.java | 5 +- .../craftbukkit/util/CraftChatMessage.java | 6 +- .../bukkit/craftbukkit/util/LongHashSet.java | 110 +++++++-------- .../craftbukkit/util/LongObjectHashMap.java | 64 ++++----- .../java/org/spigotmc/RestartCommand.java | 32 ++--- src/main/java/org/spigotmc/SpigotConfig.java | 13 +- .../java/org/spigotmc/SpigotWorldConfig.java | 54 +++++--- src/main/java/org/spigotmc/TickLimiter.java | 35 +++-- src/main/resources/configurations/bukkit.yml | 24 ++-- 44 files changed, 920 insertions(+), 376 deletions(-) create mode 100644 patches/net/minecraft/world/chunk/storage/RegionFile.java.patch create mode 100644 patches/net/minecraft/world/storage/ThreadedFileIOBase.java.patch create mode 100644 reformat.sh diff --git a/patches/cpw/mods/fml/common/registry/GameData.java.patch b/patches/cpw/mods/fml/common/registry/GameData.java.patch index f9056ee..a2e2237 100644 --- a/patches/cpw/mods/fml/common/registry/GameData.java.patch +++ b/patches/cpw/mods/fml/common/registry/GameData.java.patch @@ -10,7 +10,7 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; -@@ -1032,4 +1034,56 @@ +@@ -1036,4 +1038,56 @@ throw new RuntimeException("WHAT?"); } } diff --git a/patches/net/minecraft/entity/EntityTracker.java.patch b/patches/net/minecraft/entity/EntityTracker.java.patch index 363ad34..68c0eee 100644 --- a/patches/net/minecraft/entity/EntityTracker.java.patch +++ b/patches/net/minecraft/entity/EntityTracker.java.patch @@ -8,11 +8,13 @@ import cpw.mods.fml.common.registry.EntityRegistry; -@@ -46,7 +47,7 @@ +@@ -45,8 +46,8 @@ + { private static final Logger logger = LogManager.getLogger(); private final WorldServer theWorld; - private Set trackedEntities = new HashSet(); +- private Set trackedEntities = new HashSet(); - private IntHashMap trackedEntityIDs = new IntHashMap(); ++ private Set trackedEntities = new pw.prok.imagine.collections.IndirectSet(); + public IntHashMap trackedEntityIDs = new IntHashMap(); // CraftBukkit - private -> public private int entityViewDistance; private static final String __OBFID = "CL_00001431"; @@ -52,7 +54,7 @@ entitytrackerentry.removeFromWatchingList(entityplayermp); } } -@@ -267,11 +272,13 @@ +@@ -267,12 +272,14 @@ while (iterator.hasNext()) { EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next(); @@ -62,11 +64,12 @@ if (entitytrackerentry.playerEntitiesUpdated && entitytrackerentry.myEntity instanceof EntityPlayerMP) { arraylist.add((EntityPlayerMP)entitytrackerentry.myEntity); -+ } } ++ } } -@@ -284,7 +291,7 @@ + for (int i = 0; i < arraylist.size(); ++i) +@@ -284,12 +291,13 @@ { EntityTrackerEntry entitytrackerentry1 = (EntityTrackerEntry)iterator1.next(); @@ -75,7 +78,13 @@ { entitytrackerentry1.tryStartWachingThis(entityplayermp); } -@@ -319,6 +326,7 @@ + } + } ++ ((pw.prok.imagine.collections.Indirect) trackedEntities).compat(theWorld.getTotalWorldTime() % 100 == 0); + } + + public void func_151247_a(Entity p_151247_1_, Packet p_151247_2_) +@@ -319,6 +327,7 @@ while (iterator.hasNext()) { EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next(); @@ -83,7 +92,7 @@ entitytrackerentry.removePlayerFromTracker(p_72787_1_); } } -@@ -331,7 +339,7 @@ +@@ -331,7 +340,7 @@ { EntityTrackerEntry entitytrackerentry = (EntityTrackerEntry)iterator.next(); diff --git a/patches/net/minecraft/entity/item/EntityItemFrame.java.patch b/patches/net/minecraft/entity/item/EntityItemFrame.java.patch index 2edbf57..e33c03f 100644 --- a/patches/net/minecraft/entity/item/EntityItemFrame.java.patch +++ b/patches/net/minecraft/entity/item/EntityItemFrame.java.patch @@ -14,6 +14,15 @@ this.func_146065_b(p_70097_1_.getEntity(), false); this.setDisplayedItem((ItemStack)null); } +@@ -115,7 +122,7 @@ + if (p_110131_1_.getItem() == Items.filled_map) + { + MapData mapdata = ((ItemMap)p_110131_1_.getItem()).getMapData(p_110131_1_, this.worldObj); +- mapdata.playersVisibleOnMap.remove("frame-" + this.getEntityId()); ++ mapdata.playersVisibleOnMap.remove(java.util.UUID.nameUUIDFromBytes(("frame-" + this.getEntityId()).getBytes(org.apache.commons.codec.Charsets.US_ASCII))); // Spigot + } + + p_110131_1_.setItemFrame((EntityItemFrame)null); @@ -203,4 +210,11 @@ return true; diff --git a/patches/net/minecraft/entity/item/EntityTNTPrimed.java.patch b/patches/net/minecraft/entity/item/EntityTNTPrimed.java.patch index fb2f909..51b6d61 100644 --- a/patches/net/minecraft/entity/item/EntityTNTPrimed.java.patch +++ b/patches/net/minecraft/entity/item/EntityTNTPrimed.java.patch @@ -16,7 +16,15 @@ public EntityTNTPrimed(World p_i1729_1_) { -@@ -68,12 +72,14 @@ +@@ -50,6 +54,7 @@ + + public void onUpdate() + { ++ if (worldObj.spigotConfig.currentPrimedTnt++ > worldObj.spigotConfig.maxTntTicksPerTick) { return; } // Spigot + this.prevPosX = this.posX; + this.prevPosY = this.posY; + this.prevPosZ = this.posZ; +@@ -68,12 +73,14 @@ if (this.fuse-- <= 0) { @@ -33,7 +41,7 @@ } else { -@@ -83,8 +89,19 @@ +@@ -83,8 +90,19 @@ private void explode() { @@ -55,7 +63,7 @@ } protected void writeEntityToNBT(NBTTagCompound p_70014_1_) -@@ -107,4 +124,11 @@ +@@ -107,4 +125,11 @@ { return this.tntPlacedBy; } diff --git a/patches/net/minecraft/network/NetHandlerPlayServer.java.patch b/patches/net/minecraft/network/NetHandlerPlayServer.java.patch index d5b5bdf..8c696cd 100644 --- a/patches/net/minecraft/network/NetHandlerPlayServer.java.patch +++ b/patches/net/minecraft/network/NetHandlerPlayServer.java.patch @@ -125,7 +125,7 @@ this.playerEntity = p_i1530_3_; p_i1530_3_.playerNetServerHandler = this; + // CraftBukkit start -+ this.server = p_i1530_1_.server; ++ this.server = p_i1530_1_ == null ? null : p_i1530_1_.server; } + private final org.bukkit.craftbukkit.CraftServer server; @@ -1795,7 +1795,7 @@ { packetbuffer = new PacketBuffer(Unpooled.wrappedBuffer(p_147349_1_.func_149558_e())); @@ -1093,16 +2398,18 @@ - + { if (itemstack.getItem() == Items.writable_book && itemstack.getItem() == itemstack1.getItem()) { - itemstack1.setTagInfo("pages", itemstack.getTagCompound().getTagList("pages", 8)); @@ -1818,7 +1818,7 @@ finally { @@ -1135,19 +2442,18 @@ - { + if (itemstack.getItem() == Items.written_book && itemstack1.getItem() == Items.writable_book) { - itemstack1.setTagInfo("author", new NBTTagString(this.playerEntity.getCommandSenderName())); diff --git a/patches/net/minecraft/network/NetworkManager.java.patch b/patches/net/minecraft/network/NetworkManager.java.patch index 98f6fce..64181b2 100644 --- a/patches/net/minecraft/network/NetworkManager.java.patch +++ b/patches/net/minecraft/network/NetworkManager.java.patch @@ -60,7 +60,15 @@ this.setConnectionState(EnumConnectionState.HANDSHAKING); } -@@ -208,7 +232,15 @@ +@@ -128,6 +152,7 @@ + + public void scheduleOutboundPacket(Packet p_150725_1_, GenericFutureListener ... p_150725_2_) + { ++ if (p_150725_1_ == null) return; + if (this.channel != null && this.channel.isOpen()) + { + this.flushOutboundQueue(); +@@ -208,7 +233,15 @@ { for (int i = 1000; !this.receivedPacketsQueue.isEmpty() && i >= 0; --i) { @@ -77,7 +85,7 @@ packet.processPacket(this.netHandler); } -@@ -225,6 +257,8 @@ +@@ -225,11 +258,14 @@ public void closeChannel(IChatComponent p_150718_1_) { @@ -86,7 +94,13 @@ if (this.channel.isOpen()) { this.channel.close(); -@@ -254,7 +288,7 @@ + this.terminationReason = p_150718_1_; + } ++ outboundPacketsQueue.clear(); + } + + public boolean isLocalChannel() +@@ -254,7 +290,7 @@ { ; } @@ -95,7 +109,7 @@ try { p_initChannel_1_.config().setOption(ChannelOption.TCP_NODELAY, Boolean.valueOf(false)); -@@ -322,6 +356,13 @@ +@@ -322,6 +358,13 @@ return channel; } diff --git a/patches/net/minecraft/server/management/ServerConfigurationManager.java.patch b/patches/net/minecraft/server/management/ServerConfigurationManager.java.patch index 74fd628..610de25 100644 --- a/patches/net/minecraft/server/management/ServerConfigurationManager.java.patch +++ b/patches/net/minecraft/server/management/ServerConfigurationManager.java.patch @@ -294,7 +294,21 @@ } public String allowUserToConnect(SocketAddress p_148542_1_, GameProfile p_148542_2_) -@@ -372,6 +516,71 @@ +@@ -352,7 +496,7 @@ + } + else if (!this.func_152607_e(p_148542_2_)) + { +- return "You are not white-listed on this server!"; ++ return org.spigotmc.SpigotConfig.whitelistMessage; + } + else if (this.bannedIPs.func_152708_a(p_148542_1_)) + { +@@ -368,10 +512,75 @@ + } + else + { +- return this.playerEntityList.size() >= this.maxPlayers ? "The server is full!" : null; ++ return this.playerEntityList.size() >= this.maxPlayers ? org.spigotmc.SpigotConfig.serverFullMessage : null; } } @@ -366,7 +380,7 @@ public EntityPlayerMP createPlayerForUser(GameProfile p_148545_1_) { UUID uuid = EntityPlayer.func_146094_a(p_148545_1_); -@@ -410,80 +619,199 @@ +@@ -410,80 +619,200 @@ return new EntityPlayerMP(this.mcServer, this.mcServer.worldServerForDimension(0), p_148545_1_, (ItemInWorldManager)object); } @@ -490,6 +504,7 @@ + par1EntityPlayerMP.dimension = targetDimension; + // CraftBukkit start + EntityPlayerMP entityplayermp1 = par1EntityPlayerMP; ++ entityplayermp1.clonePlayer(par1EntityPlayerMP, returnFromEnd); // KCauldron - clone player + entityplayermp1.setWorld(this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension)); // make sure to update reference for bed spawn logic + entityplayermp1.playerConqueredTheEnd = false; ChunkCoordinates chunkcoordinates1; @@ -606,7 +621,7 @@ return entityplayermp1; } -@@ -492,34 +820,112 @@ +@@ -492,34 +821,112 @@ transferPlayerToDimension(p_72356_1_, p_72356_2_, mcServer.worldServerForDimension(p_72356_2_).getDefaultTeleporter()); } @@ -738,7 +753,7 @@ } public void transferEntityToWorld(Entity p_82448_1_, int p_82448_2_, WorldServer p_82448_3_, WorldServer p_82448_4_, Teleporter teleporter) -@@ -605,6 +1011,109 @@ +@@ -605,6 +1012,109 @@ p_82448_1_.setWorld(p_82448_4_); } @@ -848,7 +863,7 @@ public void sendPlayerInfoToAllPlayers() { if (++this.playerPingIndex > 600) -@@ -612,11 +1121,13 @@ +@@ -612,11 +1122,13 @@ this.playerPingIndex = 0; } @@ -862,7 +877,7 @@ } public void sendPacketToAllPlayers(Packet p_148540_1_) -@@ -877,13 +1388,24 @@ +@@ -877,13 +1389,24 @@ for (int j = 0; j < this.playerEntityList.size(); ++j) { EntityPlayerMP entityplayermp = (EntityPlayerMP)this.playerEntityList.get(j); @@ -889,7 +904,7 @@ if (d4 * d4 + d5 * d5 + d6 * d6 < p_148543_8_ * p_148543_8_) { entityplayermp.playerNetServerHandler.sendPacket(p_148543_11_); -@@ -941,13 +1463,16 @@ +@@ -941,13 +1464,16 @@ p_72354_1_.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(1, 0.0F)); p_72354_1_.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(7, p_72354_2_.getRainStrength(1.0F))); p_72354_1_.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(8, p_72354_2_.getWeightedThunderStrength(1.0F))); @@ -907,7 +922,7 @@ p_72385_1_.playerNetServerHandler.sendPacket(new S09PacketHeldItemChange(p_72385_1_.inventory.currentItem)); } -@@ -961,9 +1486,17 @@ +@@ -961,9 +1487,17 @@ return this.maxPlayers; } @@ -926,7 +941,7 @@ } public void setWhiteListEnabled(boolean p_72371_1_) -@@ -1032,12 +1565,30 @@ +@@ -1032,12 +1566,30 @@ public void removeAllPlayers() { diff --git a/patches/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch b/patches/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch index e961924..2f2cc2a 100644 --- a/patches/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch +++ b/patches/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch @@ -33,7 +33,7 @@ private final MinecraftServer field_147387_a; private final NetworkManager field_147386_b; private static final String __OBFID = "CL_00001456"; -@@ -39,6 +56,52 @@ +@@ -39,21 +56,94 @@ this.field_147386_b.setConnectionState(EnumConnectionState.LOGIN); ChatComponentText chatcomponenttext; @@ -85,8 +85,18 @@ + if (p_147383_1_.func_149595_d() > 5) { - chatcomponenttext = new ChatComponentText("Outdated server! I\'m still on 1.7.10"); -@@ -54,6 +117,33 @@ +- chatcomponenttext = new ChatComponentText("Outdated server! I\'m still on 1.7.10"); ++ chatcomponenttext = new ChatComponentText(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedServerMessage, "1.7.10")); + this.field_147386_b.scheduleOutboundPacket(new S00PacketDisconnect(chatcomponenttext), new GenericFutureListener[0]); + this.field_147386_b.closeChannel(chatcomponenttext); + } + else if (p_147383_1_.func_149595_d() < 5) + { +- chatcomponenttext = new ChatComponentText("Outdated client! Please use 1.7.10"); ++ chatcomponenttext = new ChatComponentText(java.text.MessageFormat.format(org.spigotmc.SpigotConfig.outdatedClientMessage, "1.7.10")); + this.field_147386_b.scheduleOutboundPacket(new S00PacketDisconnect(chatcomponenttext), new GenericFutureListener[0]); + this.field_147386_b.closeChannel(chatcomponenttext); + } else { this.field_147386_b.setNetHandler(new NetHandlerLoginServer(this.field_147387_a, this.field_147386_b)); diff --git a/patches/net/minecraft/tileentity/TileEntity.java.patch b/patches/net/minecraft/tileentity/TileEntity.java.patch index 1fc3eaa..8b36b9b 100644 --- a/patches/net/minecraft/tileentity/TileEntity.java.patch +++ b/patches/net/minecraft/tileentity/TileEntity.java.patch @@ -15,7 +15,6 @@ - protected World worldObj; + public static Map classToNameMap = new HashMap(); // Cauldron - private -> public + public World worldObj; // CraftBukkit - protected -> public -+ private boolean GC = false; public int xCoord; public int yCoord; public int zCoord; @@ -56,17 +55,6 @@ + return null; + } + // CraftBukkit end -+ //KCauldron start -+ public boolean isGC() -+ { -+ return this.GC; //Returns true if the chunk it is inside of has marked it for unloading -+ } -+ -+ public void setGC(boolean state) -+ { -+ this.GC = state; //Should never be touched by a mod. Would make it package-private but not sure if that would still work -+ } -+ // KCauldron end + // -- BEGIN FORGE PATCHES -- /** diff --git a/patches/net/minecraft/world/Explosion.java.patch b/patches/net/minecraft/world/Explosion.java.patch index c0589c2..abad780 100644 --- a/patches/net/minecraft/world/Explosion.java.patch +++ b/patches/net/minecraft/world/Explosion.java.patch @@ -49,7 +49,23 @@ float f = this.explosionSize; HashSet hashset = new HashSet(); int i; -@@ -135,7 +151,15 @@ +@@ -112,7 +128,14 @@ + int i2 = MathHelper.floor_double(this.explosionY + (double)this.explosionSize + 1.0D); + int l = MathHelper.floor_double(this.explosionZ - (double)this.explosionSize - 1.0D); + int j2 = MathHelper.floor_double(this.explosionZ + (double)this.explosionSize + 1.0D); +- List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this.exploder, AxisAlignedBB.getBoundingBox((double)i, (double)k, (double)l, (double)j, (double)i2, (double)j2)); ++ // PaperSpigot start - Fix lag from explosions processing dead entities ++ List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this.exploder, AxisAlignedBB.getBoundingBox((double)i, (double)k, (double)l, (double)j, (double)i2, (double)j2), new net.minecraft.command.IEntitySelector() { ++ @Override ++ public boolean isEntityApplicable(Entity entity) { ++ return !entity.isDead; ++ } ++ }); ++ // PaperSpigot end + net.minecraftforge.event.ForgeEventFactory.onExplosionDetonate(this.worldObj, this, list, this.explosionSize); + Vec3 vec3 = Vec3.createVectorHelper(this.explosionX, this.explosionY, this.explosionZ); + +@@ -135,7 +158,15 @@ d7 /= d9; double d10 = (double)this.worldObj.getBlockDensity(vec3, entity.boundingBox); double d11 = (1.0D - d4) * d10; @@ -66,7 +82,7 @@ double d8 = EnchantmentProtection.func_92092_a(entity, d11); entity.motionX += d5 * d8; entity.motionY += d6 * d8; -@@ -174,6 +198,39 @@ +@@ -174,6 +205,39 @@ if (this.isSmoking) { @@ -106,7 +122,7 @@ iterator = this.affectedBlockPositions.iterator(); while (iterator.hasNext()) -@@ -209,7 +266,8 @@ +@@ -209,7 +273,8 @@ { if (block.canDropFromExplosion(this)) { @@ -116,7 +132,7 @@ } block.onBlockExploded(this.worldObj, i, j, k, this); -@@ -232,7 +290,12 @@ +@@ -232,7 +297,12 @@ if (block.getMaterial() == Material.air && block1.func_149730_j() && this.explosionRNG.nextInt(3) == 0) { diff --git a/patches/net/minecraft/world/World.java.patch b/patches/net/minecraft/world/World.java.patch index 9a3b6ec..d10e86c 100644 --- a/patches/net/minecraft/world/World.java.patch +++ b/patches/net/minecraft/world/World.java.patch @@ -923,20 +923,9 @@ - TileEntity tileentity = (TileEntity)iterator.next(); + for (Object tile : field_147483_b) + { -+ TileEntity te = (TileEntity)tile; -+ te.setGC(true); -+ te.onChunkUnload(); -+ } -+ List temporary_tile_entity_list = new ArrayList(this.loadedTileEntityList.size()); -+ for(Object tile : loadedTileEntityList) -+ if(!((TileEntity)tile).isGC()) -+ temporary_tile_entity_list.add(tile); -+ this.loadedTileEntityList = temporary_tile_entity_list; -+ for (Object tile : field_147483_b) -+ { -+ TileEntity te = (TileEntity)tile; -+ te.setGC(false); ++ ((TileEntity) tile).onChunkUnload(); + } ++ this.loadedTileEntityList.removeAll(this.field_147483_b); + this.field_147483_b.clear(); + } + // CraftBukkit end @@ -1047,7 +1036,7 @@ } public void updateEntity(Entity p_72870_1_) -@@ -2036,21 +2609,33 @@ +@@ -2036,21 +2609,36 @@ public void updateEntityWithOptionalForce(Entity p_72866_1_, boolean p_72866_2_) { @@ -1056,7 +1045,11 @@ int j = MathHelper.floor_double(p_72866_1_.posZ); boolean isForced = getPersistentChunks().containsKey(new ChunkCoordIntPair(i >> 4, j >> 4)); byte b0 = isForced ? (byte)0 : 32; - boolean canUpdate = !p_72866_2_ || this.checkChunksExist(i - b0, 0, j - b0, i + b0, 0, j + b0); +- boolean canUpdate = !p_72866_2_ || this.checkChunksExist(i - b0, 0, j - b0, i + b0, 0, j + b0); ++ // CraftBukkit start - Use neighbor cache instead of looking up ++ Chunk startingChunk = this.getChunkIfLoaded(i >> 4, j >> 4); ++ boolean canUpdate = !p_72866_2_ || (startingChunk != null && startingChunk.areNeighborsLoaded(2)); ++ // CraftBukkit end + boolean forceUpdate = false; // Cauldron if (!canUpdate) @@ -1082,7 +1075,7 @@ p_72866_1_.lastTickPosX = p_72866_1_.posX; p_72866_1_.lastTickPosY = p_72866_1_.posY; p_72866_1_.lastTickPosZ = p_72866_1_.posZ; -@@ -2134,6 +2719,7 @@ +@@ -2134,6 +2722,7 @@ p_72866_1_.riddenByEntity = null; } } @@ -1090,7 +1083,7 @@ } } -@@ -2570,7 +3156,7 @@ +@@ -2570,7 +3159,7 @@ return; } @@ -1099,7 +1092,7 @@ { if (this.field_147481_N) { -@@ -2718,7 +3304,15 @@ +@@ -2718,7 +3307,15 @@ if (i <= 0) { @@ -1116,7 +1109,7 @@ } } -@@ -2754,7 +3348,15 @@ +@@ -2754,7 +3351,15 @@ if (j <= 0) { @@ -1133,7 +1126,7 @@ } } -@@ -2777,8 +3379,41 @@ +@@ -2777,8 +3382,41 @@ protected void setActivePlayerChunksAndCheckLight() { this.activeChunkSet.clear(); @@ -1176,7 +1169,7 @@ int i; EntityPlayer entityplayer; int j; -@@ -2788,17 +3423,28 @@ +@@ -2788,17 +3426,28 @@ for (i = 0; i < this.playerEntities.size(); ++i) { entityplayer = (EntityPlayer)this.playerEntities.get(i); @@ -1211,7 +1204,7 @@ } this.theProfiler.endSection(); -@@ -2810,7 +3456,7 @@ +@@ -2810,7 +3459,7 @@ this.theProfiler.startSection("playerCheckLight"); @@ -1220,7 +1213,36 @@ { i = this.rand.nextInt(this.playerEntities.size()); entityplayer = (EntityPlayer)this.playerEntities.get(i); -@@ -3284,8 +3930,21 @@ +@@ -3034,9 +3683,9 @@ + } + } + +- public boolean updateLightByType(EnumSkyBlock p_147463_1_, int p_147463_2_, int p_147463_3_, int p_147463_4_) ++ public boolean updateLightByType(EnumSkyBlock p_147463_1_, int p_147463_2_, int p_147463_3_, int p_147463_4_, Chunk chunk, List neighbors) + { +- if (!this.doChunksNearChunkExist(p_147463_2_, p_147463_3_, p_147463_4_, 17)) ++ if (chunk == null) // CraftBukkit / PaperSpigot + { + return false; + } +@@ -3166,6 +3815,16 @@ + } + } + ++ // PaperSpigot start - Asynchronous light updates ++ if (chunk.worldObj.spigotConfig.useAsyncLighting) { ++ chunk.pendingLightUpdates.decrementAndGet(); ++ if (neighbors != null) { ++ for (Chunk neighbor : neighbors) { ++ neighbor.pendingLightUpdates.decrementAndGet(); ++ } ++ } ++ } ++ // PaperSpigot end + this.theProfiler.endSection(); + return true; + } +@@ -3284,8 +3943,21 @@ { Entity entity = (Entity)this.loadedEntityList.get(j); @@ -1243,7 +1265,7 @@ ++i; } } -@@ -3298,6 +3957,7 @@ +@@ -3298,6 +3970,7 @@ for (int i = 0; i < p_72868_1_.size(); ++i) { Entity entity = (Entity)p_72868_1_.get(i); @@ -1251,7 +1273,7 @@ if (!MinecraftForge.EVENT_BUS.post(new EntityJoinWorldEvent(entity, this))) { loadedEntityList.add(entity); -@@ -3314,8 +3974,17 @@ +@@ -3314,8 +3987,17 @@ public boolean canPlaceEntityOnSide(Block p_147472_1_, int p_147472_2_, int p_147472_3_, int p_147472_4_, boolean p_147472_5_, int p_147472_6_, Entity p_147472_7_, ItemStack p_147472_8_) { Block block1 = this.getBlock(p_147472_2_, p_147472_3_, p_147472_4_); @@ -1270,7 +1292,7 @@ } public PathEntity getPathEntityToEntity(Entity p_72865_1_, Entity p_72865_2_, float p_72865_3_, boolean p_72865_4_, boolean p_72865_5_, boolean p_72865_6_, boolean p_72865_7_) -@@ -3464,6 +4133,12 @@ +@@ -3464,6 +4146,12 @@ for (int i = 0; i < this.playerEntities.size(); ++i) { EntityPlayer entityplayer1 = (EntityPlayer)this.playerEntities.get(i); @@ -1283,7 +1305,7 @@ double d5 = entityplayer1.getDistanceSq(p_72977_1_, p_72977_3_, p_72977_5_); if ((p_72977_7_ < 0.0D || d5 < p_72977_7_ * p_72977_7_) && (d4 == -1.0D || d5 < d4)) -@@ -3489,7 +4164,12 @@ +@@ -3489,7 +4177,12 @@ for (int i = 0; i < this.playerEntities.size(); ++i) { EntityPlayer entityplayer1 = (EntityPlayer)this.playerEntities.get(i); @@ -1297,7 +1319,7 @@ if (!entityplayer1.capabilities.disableDamage && entityplayer1.isEntityAlive()) { double d5 = entityplayer1.getDistanceSq(p_72846_1_, p_72846_3_, p_72846_5_); -@@ -3660,6 +4340,18 @@ +@@ -3660,6 +4353,18 @@ public void updateAllPlayersSleepingFlag() {} @@ -1316,7 +1338,7 @@ public float getWeightedThunderStrength(float p_72819_1_) { return (this.prevThunderingStrength + (this.thunderingStrength - this.prevThunderingStrength) * p_72819_1_) * this.getRainStrength(p_72819_1_); -@@ -3932,8 +4624,8 @@ +@@ -3932,8 +4637,8 @@ */ public void addTileEntity(TileEntity entity) { @@ -1327,7 +1349,7 @@ { dest.add(entity); } -@@ -4029,4 +4721,73 @@ +@@ -4029,4 +4734,122 @@ } return count; } @@ -1400,4 +1422,53 @@ + return provider.dimensionId == Integer.MIN_VALUE; // Mystcraft + } + // Cauldron end ++ ++ public Chunk getChunkIfLoaded(int x, int z) { ++ return ((ChunkProviderServer) this.chunkProvider).getChunkIfLoaded(x, z); ++ } ++ ++ public java.util.concurrent.ExecutorService lightingExecutor = java.util.concurrent.Executors.newSingleThreadExecutor(new com.google.common.util.concurrent.ThreadFactoryBuilder().setNameFormat("PaperSpigot - Lighting Thread").build()); // PaperSpigot - Asynchronous lighting updates ++ ++ /** ++ * PaperSpigot - Asynchronous lighting updates ++ */ ++ public boolean updateLightByType(final EnumSkyBlock enumskyblock, final int x, final int y, final int z) { ++ final Chunk chunk = this.getChunkIfLoaded(x >> 4, z >> 4); ++ if (chunk == null || !chunk.areNeighborsLoaded(1)) { ++ return false; ++ } ++ ++ if (!chunk.worldObj.spigotConfig.useAsyncLighting) { ++ return this.updateLightByType(enumskyblock, x, y, z, chunk, null); ++ } ++ ++ chunk.pendingLightUpdates.incrementAndGet(); ++ chunk.lightUpdateTime = chunk.worldObj.getTotalWorldTime(); ++ ++ final List neighbors = new ArrayList(); ++ for (int cx = (x >> 4) - 1; cx <= (x >> 4) + 1; ++cx) { ++ for (int cz = (z >> 4) - 1; cz <= (z >> 4) + 1; ++cz) { ++ if (cx != x >> 4 && cz != z >> 4) { ++ Chunk neighbor = this.getChunkIfLoaded(cx, cz); ++ if (neighbor != null) { ++ neighbor.pendingLightUpdates.incrementAndGet(); ++ neighbor.lightUpdateTime = chunk.worldObj.getTotalWorldTime(); ++ neighbors.add(neighbor); ++ } ++ } ++ } ++ } ++ ++ if (!Bukkit.isPrimaryThread()) { ++ return this.updateLightByType(enumskyblock, x, y, z, chunk, neighbors); ++ } ++ ++ lightingExecutor.submit(new Runnable() { ++ @Override ++ public void run() { ++ World.this.updateLightByType(enumskyblock, x, y, z, chunk, neighbors); ++ } ++ }); ++ return true; ++ } } diff --git a/patches/net/minecraft/world/WorldServer.java.patch b/patches/net/minecraft/world/WorldServer.java.patch index 68b2a73..7b278c6 100644 --- a/patches/net/minecraft/world/WorldServer.java.patch +++ b/patches/net/minecraft/world/WorldServer.java.patch @@ -188,7 +188,7 @@ this.theProfiler.endStartSection("tickPending"); + timings.doTickPending.startTiming(); // Spigot this.tickUpdates(false); -+ timings.doChunkUnload.stopTiming(); // Spigot ++ timings.doTickPending.stopTiming(); // Spigot this.theProfiler.endStartSection("tickBlocks"); + timings.doTickTiles.startTiming(); // Spigot this.func_147456_g(); @@ -389,7 +389,15 @@ { if (this.updateEntityTick++ >= 1200) { -@@ -506,7 +686,16 @@ +@@ -487,6 +667,7 @@ + } + + super.updateEntities(); ++ spigotConfig.currentPrimedTnt = 0; // Spigot + } + + public void resetUpdateEntityTick() +@@ -506,7 +687,16 @@ { if (i > 1000) { @@ -407,7 +415,7 @@ } this.theProfiler.startSection("cleaning"); -@@ -651,7 +840,37 @@ +@@ -651,7 +841,37 @@ protected IChunkProvider createChunkProvider() { IChunkLoader ichunkloader = this.saveHandler.getChunkLoader(this.provider); @@ -446,7 +454,7 @@ return this.theChunkProviderServer; } -@@ -659,29 +878,31 @@ +@@ -659,29 +879,31 @@ { ArrayList arraylist = new ArrayList(); @@ -493,7 +501,7 @@ return arraylist; } -@@ -733,7 +954,28 @@ +@@ -733,7 +955,28 @@ int i = 0; int j = this.provider.getAverageGroundLevel(); int k = 0; @@ -522,7 +530,7 @@ if (chunkposition != null) { i = chunkposition.chunkPosX; -@@ -876,6 +1118,20 @@ +@@ -876,6 +1119,20 @@ public boolean addWeatherEffect(Entity p_72942_1_) { @@ -543,7 +551,7 @@ if (super.addWeatherEffect(p_72942_1_)) { this.mcServer.getConfigurationManager().sendToAllNear(p_72942_1_.posX, p_72942_1_.posY, p_72942_1_.posZ, 512.0D, this.provider.dimensionId, new S2CPacketSpawnGlobalEntity(p_72942_1_)); -@@ -894,13 +1150,23 @@ +@@ -894,13 +1151,23 @@ public Explosion newExplosion(Entity p_72885_1_, double p_72885_2_, double p_72885_4_, double p_72885_6_, float p_72885_8_, boolean p_72885_9_, boolean p_72885_10_) { @@ -568,7 +576,7 @@ if (!p_72885_10_) { explosion.affectedBlockPositions.clear(); -@@ -977,7 +1243,7 @@ +@@ -977,7 +1244,7 @@ { boolean flag = this.isRaining(); super.updateWeather(); @@ -577,7 +585,7 @@ if (this.prevRainingStrength != this.rainingStrength) { this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(7, this.rainingStrength), this.provider.dimensionId); -@@ -988,10 +1254,6 @@ +@@ -988,10 +1255,6 @@ this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(8, this.thunderingStrength), this.provider.dimensionId); } @@ -588,7 +596,7 @@ if (flag != this.isRaining()) { if (flag) -@@ -1006,6 +1268,33 @@ +@@ -1006,6 +1269,33 @@ this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(7, this.rainingStrength), this.provider.dimensionId); this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(8, this.thunderingStrength), this.provider.dimensionId); } @@ -622,7 +630,7 @@ } protected int func_152379_p() -@@ -1069,4 +1358,51 @@ +@@ -1069,4 +1359,51 @@ this(); } } diff --git a/patches/net/minecraft/world/chunk/Chunk.java.patch b/patches/net/minecraft/world/chunk/Chunk.java.patch index b3cb8a3..5ff7522 100644 --- a/patches/net/minecraft/world/chunk/Chunk.java.patch +++ b/patches/net/minecraft/world/chunk/Chunk.java.patch @@ -18,16 +18,50 @@ public class Chunk { private static final Logger logger = LogManager.getLogger(); -@@ -62,6 +73,8 @@ +@@ -62,8 +73,42 @@ public int heightMapMinimum; public long inhabitedTime; private int queuedLightChecks; + public gnu.trove.map.hash.TObjectIntHashMap entityCount = new gnu.trove.map.hash.TObjectIntHashMap(); // Spigot (Cauldron protected -> public) ++ // PaperSpigot start - Asynchronous light updates ++ public java.util.concurrent.atomic.AtomicInteger pendingLightUpdates = new java.util.concurrent.atomic.AtomicInteger(); ++ public long lightUpdateTime; ++ // PaperSpigot end + public int lastAccessedTick; // Cauldron track last time the chunk was accessed private static final String __OBFID = "CL_00000373"; ++ // CraftBukkit start - Neighbor loaded cache for chunk lighting and entity ticking ++ private int neighbors = 0x1 << 12; ++ ++ public boolean areNeighborsLoaded(final int radius) { ++ switch(radius) { ++ case 2: ++ return this.neighbors == Integer.MAX_VALUE >> 6; ++ case 1: ++ final int mask = ++ // x z offset x z offset x z offset ++ ( 0x1 << (1 * 5 + 1 + 12) ) | ( 0x1 << (0 * 5 + 1 + 12) ) | ( 0x1 << (-1 * 5 + 1 + 12) ) | ++ ( 0x1 << (1 * 5 + 0 + 12) ) | ( 0x1 << (0 * 5 + 0 + 12) ) | ( 0x1 << (-1 * 5 + 0 + 12) ) | ++ ( 0x1 << (1 * 5 + -1 + 12) ) | ( 0x1 << (0 * 5 + -1 + 12) ) | ( 0x1 << (-1 * 5 + -1 + 12) ); ++ return (this.neighbors & mask) == mask; ++ default: ++ throw new UnsupportedOperationException(String.valueOf(radius)); ++ } ++ } ++ ++ public void setNeighborLoaded(final int x, final int z) { ++ this.neighbors |= 0x1 << (x * 5 + 12 + z); ++ } ++ ++ public void setNeighborUnloaded(final int x, final int z) { ++ this.neighbors &= ~(0x1 << (x * 5 + 12 + z)); ++ } ++ // CraftBukkit end ++ public Chunk(World p_i1995_1_, int p_i1995_2_, int p_i1995_3_) -@@ -80,13 +93,22 @@ + { + this.storageArrays = new ExtendedBlockStorage[16]; +@@ -80,13 +125,22 @@ for (int k = 0; k < this.entityLists.length; ++k) { @@ -51,7 +85,7 @@ public Chunk(World p_i45446_1_, Block[] p_i45446_2_, int p_i45446_3_, int p_i45446_4_) { this(p_i45446_1_, p_i45446_3_, p_i45446_4_); -@@ -512,10 +534,10 @@ +@@ -512,10 +566,10 @@ if (extendedblockstorage != null) { @@ -65,7 +99,7 @@ catch (Throwable throwable) { CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Getting block"); -@@ -529,7 +551,7 @@ +@@ -529,7 +583,7 @@ } }); throw new ReportedException(crashreport); @@ -74,7 +108,7 @@ } } -@@ -589,9 +611,10 @@ +@@ -589,9 +643,10 @@ if (!this.worldObj.isRemote) { @@ -86,7 +120,7 @@ extendedblockstorage.func_150818_a(p_150807_1_, p_150807_2_ & 15, p_150807_3_, p_150807_4_); extendedblockstorage.setExtBlockMetadata(p_150807_1_, p_150807_2_ & 15, p_150807_3_, p_150807_5_); // This line duplicates the one below, so breakBlock fires with valid worldstate -@@ -777,8 +800,20 @@ +@@ -777,8 +832,20 @@ if (i != this.xPosition || j != this.zPosition) { @@ -109,7 +143,7 @@ } int k = MathHelper.floor_double(p_76612_1_.posY / 16.0D); -@@ -799,6 +834,26 @@ +@@ -799,6 +866,26 @@ p_76612_1_.chunkCoordY = k; p_76612_1_.chunkCoordZ = this.zPosition; this.entityLists[k].add(p_76612_1_); @@ -136,7 +170,7 @@ } public void removeEntity(Entity p_76622_1_) -@@ -819,6 +874,26 @@ +@@ -819,6 +906,26 @@ } this.entityLists[p_76608_2_].remove(p_76608_1_); @@ -163,7 +197,7 @@ } public boolean canBlockSeeTheSky(int p_76619_1_, int p_76619_2_, int p_76619_3_) -@@ -874,9 +949,23 @@ +@@ -874,9 +981,23 @@ p_150812_4_.xCoord = this.xPosition * 16 + p_150812_1_; p_150812_4_.yCoord = p_150812_2_; p_150812_4_.zCoord = this.zPosition * 16 + p_150812_3_; @@ -188,7 +222,7 @@ { if (this.chunkTileEntityMap.containsKey(chunkposition)) { -@@ -886,6 +975,16 @@ +@@ -886,6 +1007,16 @@ p_150812_4_.validate(); this.chunkTileEntityMap.put(chunkposition, p_150812_4_); } @@ -205,7 +239,7 @@ } public void removeTileEntity(int p_150805_1_, int p_150805_2_, int p_150805_3_) -@@ -936,6 +1035,21 @@ +@@ -936,6 +1067,21 @@ for (int i = 0; i < this.entityLists.length; ++i) { @@ -227,7 +261,16 @@ this.worldObj.unloadEntities(this.entityLists[i]); } MinecraftForge.EVENT_BUS.post(new ChunkEvent.Unload(this)); -@@ -1025,7 +1139,7 @@ +@@ -1015,7 +1161,7 @@ + return true; + } + } +- else if (this.hasEntities && this.worldObj.getTotalWorldTime() >= this.lastSaveTime + 600L) ++ else if (this.hasEntities && this.worldObj.getTotalWorldTime() >= this.lastSaveTime + net.minecraft.server.MinecraftServer.getServer().autosavePeriod * 4) // PaperSpigot - Only save if we've passed 4 auto save intervals without modification + { + return true; + } +@@ -1025,7 +1171,7 @@ public Random getRandomWithSeed(long p_76617_1_) { @@ -236,7 +279,7 @@ } public boolean isEmpty() -@@ -1035,6 +1149,7 @@ +@@ -1035,6 +1181,7 @@ public void populateChunk(IChunkProvider p_76624_1_, IChunkProvider p_76624_2_, int p_76624_3_, int p_76624_4_) { @@ -244,7 +287,7 @@ if (!this.isTerrainPopulated && p_76624_1_.chunkExists(p_76624_3_ + 1, p_76624_4_ + 1) && p_76624_1_.chunkExists(p_76624_3_, p_76624_4_ + 1) && p_76624_1_.chunkExists(p_76624_3_ + 1, p_76624_4_)) { p_76624_1_.populate(p_76624_2_, p_76624_3_, p_76624_4_); -@@ -1054,6 +1169,7 @@ +@@ -1054,6 +1201,7 @@ { p_76624_1_.populate(p_76624_2_, p_76624_3_ - 1, p_76624_4_ - 1); } @@ -252,7 +295,16 @@ } public int getPrecipitationHeight(int p_76626_1_, int p_76626_2_) -@@ -1184,8 +1300,10 @@ +@@ -1091,7 +1239,7 @@ + { + if (this.isGapLightingUpdated && !this.worldObj.provider.hasNoSky && !p_150804_1_) + { +- this.recheckGaps(this.worldObj.isRemote); ++ this.recheckGapsAsync(this.worldObj.isRemote); + } + + this.field_150815_m = true; +@@ -1184,8 +1332,10 @@ if ((p_76607_2_ & 1 << l) != 0 && this.storageArrays[l] != null) { nibblearray = this.storageArrays[l].getMetadataArray(); @@ -265,7 +317,7 @@ } } -@@ -1194,8 +1312,10 @@ +@@ -1194,8 +1344,10 @@ if ((p_76607_2_ & 1 << l) != 0 && this.storageArrays[l] != null) { nibblearray = this.storageArrays[l].getBlocklightArray(); @@ -278,7 +330,7 @@ } } -@@ -1206,8 +1326,10 @@ +@@ -1206,8 +1358,10 @@ if ((p_76607_2_ & 1 << l) != 0 && this.storageArrays[l] != null) { nibblearray = this.storageArrays[l].getSkylightArray(); @@ -291,7 +343,7 @@ } } } -@@ -1229,8 +1351,8 @@ +@@ -1229,8 +1383,8 @@ nibblearray = this.storageArrays[l].createBlockMSBArray(); } @@ -302,3 +354,25 @@ } } else if (p_76607_4_ && this.storageArrays[l] != null && this.storageArrays[l].getBlockMSBArray() != null) +@@ -1523,4 +1677,21 @@ + } + } + } ++ ++ /** ++ * PaperSpigot - Recheck gaps asynchronously. ++ */ ++ public void recheckGapsAsync(final boolean isStatic) { ++ if (!worldObj.spigotConfig.useAsyncLighting) { ++ this.recheckGaps(isStatic); ++ return; ++ } ++ ++ worldObj.lightingExecutor.submit(new Runnable() { ++ @Override ++ public void run() { ++ Chunk.this.recheckGaps(isStatic); ++ } ++ }); ++ } + } diff --git a/patches/net/minecraft/world/chunk/storage/RegionFile.java.patch b/patches/net/minecraft/world/chunk/storage/RegionFile.java.patch new file mode 100644 index 0000000..155fae6 --- /dev/null +++ b/patches/net/minecraft/world/chunk/storage/RegionFile.java.patch @@ -0,0 +1,40 @@ +--- ../src-base/minecraft/net/minecraft/world/chunk/storage/RegionFile.java ++++ ../src-work/minecraft/net/minecraft/world/chunk/storage/RegionFile.java +@@ -16,7 +16,7 @@ + + public class RegionFile + { +- private static final byte[] emptySector = new byte[4096]; ++ private static final byte[] emptySector = new byte[4096]; // Spigot - note: if this ever changes to not be 4096 bytes, update constructor! + private final File fileName; + private RandomAccessFile dataFile; + private final int[] offsets = new int[1024]; +@@ -43,16 +43,10 @@ + + if (this.dataFile.length() < 4096L) + { +- for (i = 0; i < 1024; ++i) +- { +- this.dataFile.writeInt(0); +- } ++ // Spigot - more effecient chunk zero'ing ++ this.dataFile.write(RegionFile.emptySector); // Spigot ++ this.dataFile.write(RegionFile.emptySector); // Spigot + +- for (i = 0; i < 1024; ++i) +- { +- this.dataFile.writeInt(0); +- } +- + this.sizeDelta += 8192; + } + +@@ -209,7 +203,7 @@ + + public DataOutputStream getChunkDataOutputStream(int p_76710_1_, int p_76710_2_) + { +- return this.outOfBounds(p_76710_1_, p_76710_2_) ? null : new DataOutputStream(new DeflaterOutputStream(new RegionFile.ChunkBuffer(p_76710_1_, p_76710_2_))); ++ return this.outOfBounds(p_76710_1_, p_76710_2_) ? null : new DataOutputStream(new java.io.BufferedOutputStream(new DeflaterOutputStream(new RegionFile.ChunkBuffer(p_76710_1_, p_76710_2_)))); // Spigot - use a BufferedOutputStream to greatly improve file write performance + } + + protected synchronized void write(int p_76706_1_, int p_76706_2_, byte[] p_76706_3_, int p_76706_4_) diff --git a/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch b/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch index 1bc3731..b482d0d 100644 --- a/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch +++ b/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch @@ -80,7 +80,7 @@ this.defaultEmptyChunk = new EmptyChunk(p_i1520_1_, 0, 0); this.worldObj = p_i1520_1_; this.currentChunkLoader = p_i1520_2_; -@@ -57,10 +94,10 @@ +@@ -57,16 +94,22 @@ public boolean chunkExists(int p_73149_1_, int p_73149_2_) { @@ -93,7 +93,19 @@ { return this.loadedChunks; } -@@ -74,26 +111,45 @@ + + public void unloadChunksIfNotNearSpawn(int p_73241_1_, int p_73241_2_) + { ++ // PaperSpigot start - Asynchronous lighting updates ++ Chunk chunk = this.loadedChunkHashMap_KC.get(LongHash.toLong(p_73241_1_, p_73241_2_)); ++ if (chunk != null && chunk.worldObj.spigotConfig.useAsyncLighting && (chunk.pendingLightUpdates.get() > 0 || chunk.worldObj.getTotalWorldTime() - chunk.lightUpdateTime < 20)) { ++ return; ++ } ++ // PaperSpigot end + if (this.worldObj.provider.canRespawnHere() && DimensionManager.shouldLoadSpawn(this.worldObj.provider.dimensionId)) + { + ChunkCoordinates chunkcoordinates = this.worldObj.getSpawnPoint(); +@@ -74,26 +117,49 @@ int l = p_73241_2_ * 16 + 8 - chunkcoordinates.posZ; short short1 = 128; @@ -132,12 +144,6 @@ public void unloadAllChunks() { - Iterator iterator = this.loadedChunks.iterator(); -- -- while (iterator.hasNext()) -- { -- Chunk chunk = (Chunk)iterator.next(); -- this.unloadChunksIfNotNearSpawn(chunk.xPosition, chunk.zPosition); -- } + this.loadedChunkHashMap_KC.forEachValue(new TObjectProcedure() { + @Override + public boolean execute(Chunk chunk) { @@ -145,10 +151,19 @@ + return true; + } + }); ++ } + +- while (iterator.hasNext()) +- { +- Chunk chunk = (Chunk)iterator.next(); +- this.unloadChunksIfNotNearSpawn(chunk.xPosition, chunk.zPosition); +- } ++ public Chunk getChunkIfLoaded(int x, int z) { ++ return this.loadedChunkHashMap_KC.get(LongHash.toLong(x, z)); } public Chunk loadChunk(int p_73158_1_, int p_73158_2_) -@@ -103,9 +159,9 @@ +@@ -103,9 +169,9 @@ public Chunk loadChunk(int par1, int par2, Runnable runnable) { @@ -161,7 +176,7 @@ AnvilChunkLoader loader = null; if (this.currentChunkLoader instanceof AnvilChunkLoader) -@@ -113,6 +169,8 @@ +@@ -113,6 +179,8 @@ loader = (AnvilChunkLoader) this.currentChunkLoader; } @@ -170,7 +185,7 @@ // We can only use the queue for already generated chunks if (chunk == null && loader != null && loader.chunkExists(this.worldObj, par1, par2)) { -@@ -142,18 +200,19 @@ +@@ -142,18 +210,19 @@ public Chunk originalLoadChunk(int p_73158_1_, int p_73158_2_) { @@ -195,7 +210,7 @@ if (chunk == null) { chunk = this.safeLoadChunk(p_73158_1_, p_73158_2_); -@@ -176,18 +235,39 @@ +@@ -176,18 +245,53 @@ CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Exception generating new chunk"); CrashReportCategory crashreportcategory = crashreport.makeCategory("Chunk to be generated"); crashreportcategory.addCrashSection("Location", String.format("%d,%d", new Object[] {Integer.valueOf(p_73158_1_), Integer.valueOf(p_73158_2_)})); @@ -234,13 +249,27 @@ + server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(chunk.bukkitChunk, newChunk)); + } + ++ // Update neighbor counts ++ for (int x = -2; x < 3; x++) { ++ for (int z = -2; z < 3; z++) { ++ if (x == 0 && z == 0) { ++ continue; ++ } ++ ++ Chunk neighbor = this.getChunkIfLoaded(chunk.xPosition + x, chunk.zPosition + z); ++ if (neighbor != null) { ++ neighbor.setNeighborLoaded(-x, -z); ++ chunk.setNeighborLoaded(x, z); ++ } ++ } ++ } + // CraftBukkit end chunk.populateChunk(this, this, p_73158_1_, p_73158_2_); + worldObj.timings.syncChunkLoadTimer.stopTiming(); // Spigot } return chunk; -@@ -195,11 +275,29 @@ +@@ -195,11 +299,29 @@ public Chunk provideChunk(int p_73154_1_, int p_73154_2_) { @@ -273,7 +302,7 @@ { if (this.currentChunkLoader == null) { -@@ -209,6 +307,7 @@ +@@ -209,6 +331,7 @@ { try { @@ -281,7 +310,7 @@ Chunk chunk = this.currentChunkLoader.loadChunk(this.worldObj, p_73239_1_, p_73239_2_); if (chunk != null) -@@ -217,8 +316,11 @@ +@@ -217,8 +340,11 @@ if (this.currentChunkProvider != null) { @@ -293,7 +322,7 @@ } return chunk; -@@ -231,7 +333,7 @@ +@@ -231,7 +357,7 @@ } } @@ -302,7 +331,7 @@ { if (this.currentChunkLoader != null) { -@@ -246,7 +348,7 @@ +@@ -246,7 +372,7 @@ } } @@ -311,7 +340,7 @@ { if (this.currentChunkLoader != null) { -@@ -254,15 +356,18 @@ +@@ -254,15 +380,18 @@ { p_73242_1_.lastSaveTime = this.worldObj.getTotalWorldTime(); this.currentChunkLoader.saveChunk(this.worldObj, p_73242_1_); @@ -331,7 +360,7 @@ } } -@@ -277,6 +382,35 @@ +@@ -277,6 +406,35 @@ if (this.currentChunkProvider != null) { this.currentChunkProvider.populate(p_73153_1_, p_73153_2_, p_73153_3_); @@ -367,7 +396,7 @@ GameRegistry.generateWorld(p_73153_2_, p_73153_3_, worldObj, currentChunkProvider, p_73153_1_); chunk.setChunkModified(); } -@@ -286,11 +420,13 @@ +@@ -286,11 +444,13 @@ public boolean saveChunks(boolean p_73151_1_, IProgressUpdate p_73151_2_) { int i = 0; @@ -384,7 +413,7 @@ if (p_73151_1_) { -@@ -325,36 +461,60 @@ +@@ -325,36 +485,73 @@ { if (!this.worldObj.levelSaving) { @@ -426,18 +455,14 @@ - if(loadedChunks.size() == 0 && ForgeChunkManager.getPersistentChunksFor(this.worldObj).size() == 0 && !DimensionManager.shouldLoadSpawn(this.worldObj.provider.dimensionId)){ - DimensionManager.unloadWorld(this.worldObj.provider.dimensionId); - return currentChunkProvider.unloadQueuedChunks(); -- } -- } + // Cauldron static - check if the chunk was accessed recently and keep it loaded if there are players in world -+ if (!shouldUnloadChunk(chunk) && this.worldObj.playerEntities.size() > 0) ++ /*if (!shouldUnloadChunk(chunk) && this.worldObj.playerEntities.size() > 0) + { + CauldronHooks.logChunkUnload(this, chunk.xPosition, chunk.zPosition, "** Chunk kept from unloading due to recent activity"); + continue; -+ } ++ }*/ + // Cauldron end - -- this.chunksToUnload.remove(olong); -- this.loadedChunkHashMap.remove(olong.longValue()); ++ + + ChunkUnloadEvent event = new ChunkUnloadEvent(chunk.bukkitChunk); + server.getPluginManager().callEvent(event); @@ -449,7 +474,23 @@ + chunk.onChunkUnload(); + this.safeSaveChunk(chunk); + this.safeSaveExtraChunkData(chunk); -+ // this.unloadQueue.remove(olong); ++ // Update neighbor counts ++ for (int x = -2; x < 3; x++) { ++ for (int z = -2; z < 3; z++) { ++ if (x == 0 && z == 0) { ++ continue; ++ } ++ ++ Chunk neighbor = this.getChunkIfLoaded(chunk.xPosition + x, chunk.zPosition + z); ++ if (neighbor != null) { ++ neighbor.setNeighborUnloaded(-x, -z); ++ chunk.setNeighborUnloaded(x, z); ++ } + } + } +- +- this.chunksToUnload.remove(olong); +- this.loadedChunkHashMap.remove(olong.longValue()); + this.loadedChunkHashMap_KC.remove(chunkcoordinates); // CraftBukkit + this.loadedChunks.remove(chunk); // Cauldron - vanilla compatibility + ForgeChunkManager.putDormantChunk(chunkcoordinates, chunk); @@ -465,7 +506,7 @@ if (this.currentChunkLoader != null) { this.currentChunkLoader.chunkTick(); -@@ -371,7 +531,7 @@ +@@ -371,7 +568,7 @@ public String makeString() { @@ -474,7 +515,7 @@ } public List getPossibleCreatures(EnumCreatureType p_73155_1_, int p_73155_2_, int p_73155_3_, int p_73155_4_) -@@ -386,8 +546,31 @@ +@@ -386,8 +583,31 @@ public int getLoadedChunkCount() { @@ -500,10 +541,10 @@ + return loadedChunkHashMap_KC.get(chunkHash).lastAccessedTick; + } + -+ private boolean shouldUnloadChunk(Chunk chunk) ++ /*private boolean shouldUnloadChunk(Chunk chunk) + { + if (chunk == null) return false; -+ return MinecraftServer.getServer().getTickCounter() - chunk.lastAccessedTick > MinecraftServer.getServer().cauldronConfig.chunkGCGracePeriod.getValue(); -+ } ++ return MinecraftServer.getServer().getTickCounter() - chunk.lastAccessedTick > CauldronConfig.chunkGCGracePeriod.getValue(); ++ }*/ + // Cauldron end } diff --git a/patches/net/minecraft/world/storage/MapData.java.patch b/patches/net/minecraft/world/storage/MapData.java.patch index fb5fc73..cc26319 100644 --- a/patches/net/minecraft/world/storage/MapData.java.patch +++ b/patches/net/minecraft/world/storage/MapData.java.patch @@ -15,10 +15,16 @@ public class MapData extends WorldSavedData { public int xCenter; -@@ -24,11 +32,21 @@ - public List playersArrayList = new ArrayList(); - private Map playersHashMap = new HashMap(); - public Map playersVisibleOnMap = new LinkedHashMap(); +@@ -21,14 +29,24 @@ + public int dimension; + public byte scale; + public byte[] colors = new byte[16384]; +- public List playersArrayList = new ArrayList(); +- private Map playersHashMap = new HashMap(); +- public Map playersVisibleOnMap = new LinkedHashMap(); ++ public List playersArrayList = new ArrayList(); // Spigot ++ private Map playersHashMap = new HashMap(); // Spigot ++ public Map playersVisibleOnMap = new LinkedHashMap(); // Spigot + + // CraftBukkit start + public final CraftMapView mapView; @@ -37,7 +43,7 @@ } public void readFromNBT(NBTTagCompound p_76184_1_) -@@ -107,7 +125,7 @@ +@@ -107,14 +125,14 @@ { if (!this.playersHashMap.containsKey(p_76191_1_)) { @@ -46,6 +52,55 @@ this.playersHashMap.put(p_76191_1_, mapinfo); this.playersArrayList.add(mapinfo); } + + if (!p_76191_1_.inventory.hasItemStack(p_76191_2_)) + { +- this.playersVisibleOnMap.remove(p_76191_1_.getCommandSenderName()); ++ this.playersVisibleOnMap.remove(p_76191_1_.getUniqueID()); + } + + for (int i = 0; i < this.playersArrayList.size(); ++i) +@@ -125,7 +143,7 @@ + { + if (!p_76191_2_.isOnItemFrame() && mapinfo1.entityplayerObj.dimension == this.dimension) + { +- this.func_82567_a(0, mapinfo1.entityplayerObj.worldObj, mapinfo1.entityplayerObj.getCommandSenderName(), mapinfo1.entityplayerObj.posX, mapinfo1.entityplayerObj.posZ, (double)mapinfo1.entityplayerObj.rotationYaw); ++ this.func_82567_a(0, mapinfo1.entityplayerObj.worldObj, mapinfo1.entityplayerObj.getCommandSenderName(), mapinfo1.entityplayerObj.getUniqueID(), mapinfo1.entityplayerObj.posX, mapinfo1.entityplayerObj.posZ, (double)mapinfo1.entityplayerObj.rotationYaw); + } + } + else +@@ -137,11 +155,11 @@ + + if (p_76191_2_.isOnItemFrame()) + { +- this.func_82567_a(1, p_76191_1_.worldObj, "frame-" + p_76191_2_.getItemFrame().getEntityId(), (double)p_76191_2_.getItemFrame().field_146063_b, (double)p_76191_2_.getItemFrame().field_146062_d, (double)(p_76191_2_.getItemFrame().hangingDirection * 90)); ++ this.func_82567_a(1, p_76191_1_.worldObj, "frame-" + p_76191_2_.getItemFrame().getEntityId(), UUID.nameUUIDFromBytes(("frame-" + p_76191_2_.getItemFrame().getEntityId()).getBytes(org.apache.commons.codec.Charsets.US_ASCII)), (double)p_76191_2_.getItemFrame().field_146063_b, (double)p_76191_2_.getItemFrame().field_146062_d, (double)(p_76191_2_.getItemFrame().hangingDirection * 90)); + } + } + +- private void func_82567_a(int p_82567_1_, World p_82567_2_, String p_82567_3_, double p_82567_4_, double p_82567_6_, double p_82567_8_) ++ private void func_82567_a(int p_82567_1_, World p_82567_2_, String entityName, UUID p_82567_3_, double p_82567_4_, double p_82567_6_, double p_82567_8_) + { + int j = 1 << this.scale; + float f = (float)(p_82567_4_ - (double)this.xCenter) / (float)j; +@@ -156,7 +174,7 @@ + p_82567_8_ += p_82567_8_ < 0.0D ? -8.0D : 8.0D; + b2 = (byte)((int)(p_82567_8_ * 16.0D / 360.0D)); + +- if (p_82567_2_.provider.shouldMapSpin(p_82567_3_, p_82567_4_, p_82567_6_, p_82567_8_)) ++ if (p_82567_2_.provider.shouldMapSpin(entityName, p_82567_4_, p_82567_6_, p_82567_8_)) + { + int k = (int)(p_82567_2_.getWorldInfo().getWorldTime() / 10L); + b2 = (byte)(k * k * 34187121 + k * 121 >> 15 & 15); +@@ -250,7 +268,7 @@ + byte b3 = p_76192_1_[i * 3 + 2]; + byte b0 = p_76192_1_[i * 3 + 3]; + byte b1 = (byte)(p_76192_1_[i * 3 + 1] & 15); +- this.playersVisibleOnMap.put("icon-" + i, new MapData.MapCoord(b2, b3, b0, b1)); ++ this.playersVisibleOnMap.put(UUID.nameUUIDFromBytes(("icon-" + i).getBytes(org.apache.commons.codec.Charsets.US_ASCII)), new MapData.MapCoord(b2, b3, b0, b1)); + } + } + else if (p_76192_1_[0] == 2) @@ -265,7 +283,7 @@ if (mapinfo == null) diff --git a/patches/net/minecraft/world/storage/ThreadedFileIOBase.java.patch b/patches/net/minecraft/world/storage/ThreadedFileIOBase.java.patch new file mode 100644 index 0000000..de7f435 --- /dev/null +++ b/patches/net/minecraft/world/storage/ThreadedFileIOBase.java.patch @@ -0,0 +1,20 @@ +--- ../src-base/minecraft/net/minecraft/world/storage/ThreadedFileIOBase.java ++++ ../src-work/minecraft/net/minecraft/world/storage/ThreadedFileIOBase.java +@@ -38,7 +38,7 @@ + this.threadedIOQueue.remove(i--); + ++this.savedIOCounter; + } +- ++ /* // Spigot start - don't sleep in between chunks so we unload faster. + try + { + Thread.sleep(this.isThreadWaiting ? 0L : 10L); +@@ -46,7 +46,7 @@ + catch (InterruptedException interruptedexception1) + { + interruptedexception1.printStackTrace(); +- } ++ } */ // Spigot end + } + + if (this.threadedIOQueue.isEmpty()) diff --git a/patches/net/minecraftforge/common/chunkio/ChunkIOProvider.java.patch b/patches/net/minecraftforge/common/chunkio/ChunkIOProvider.java.patch index b97f5fb..8ab053a 100644 --- a/patches/net/minecraftforge/common/chunkio/ChunkIOProvider.java.patch +++ b/patches/net/minecraftforge/common/chunkio/ChunkIOProvider.java.patch @@ -10,7 +10,7 @@ class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider { private final AtomicInteger threadNumber = new AtomicInteger(1); -@@ -41,13 +44,20 @@ +@@ -41,14 +44,36 @@ queuedChunk.loader.loadEntities(queuedChunk.world, queuedChunk.compound.getCompoundTag("Level"), chunk); MinecraftForge.EVENT_BUS.post(new ChunkDataEvent.Load(chunk, queuedChunk.compound)); // Don't call ChunkDataEvent.Load async chunk.lastSaveTime = queuedChunk.provider.worldObj.getTotalWorldTime(); @@ -30,5 +30,21 @@ + server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(chunk.bukkitChunk, false)); + } ++ // Update neighbor counts ++ for (int x = -2; x < 3; x++) { ++ for (int z = -2; z < 3; z++) { ++ if (x == 0 && z == 0) { ++ continue; ++ } ++ ++ net.minecraft.world.chunk.Chunk neighbor = queuedChunk.provider.getChunkIfLoaded(chunk.xPosition + x, chunk.zPosition + z); ++ if (neighbor != null) { ++ neighbor.setNeighborLoaded(-x, -z); ++ chunk.setNeighborLoaded(x, z); ++ } ++ } ++ } ++ chunk.populateChunk(queuedChunk.provider, queuedChunk.provider, queuedChunk.x, queuedChunk.z); } + diff --git a/patches/net/minecraftforge/oredict/OreDictionary.java.patch b/patches/net/minecraftforge/oredict/OreDictionary.java.patch index 05f2f2a..2118eae 100644 --- a/patches/net/minecraftforge/oredict/OreDictionary.java.patch +++ b/patches/net/minecraftforge/oredict/OreDictionary.java.patch @@ -1,6 +1,6 @@ --- ../src-base/minecraft/net/minecraftforge/oredict/OreDictionary.java +++ ../src-work/minecraft/net/minecraftforge/oredict/OreDictionary.java -@@ -216,7 +216,7 @@ +@@ -221,7 +221,7 @@ { ShapedRecipes recipe = (ShapedRecipes)obj; ItemStack output = recipe.getRecipeOutput(); @@ -9,7 +9,7 @@ { continue; } -@@ -231,7 +231,7 @@ +@@ -236,7 +236,7 @@ { ShapelessRecipes recipe = (ShapelessRecipes)obj; ItemStack output = recipe.getRecipeOutput(); diff --git a/reformat.sh b/reformat.sh new file mode 100644 index 0000000..989fc15 --- /dev/null +++ b/reformat.sh @@ -0,0 +1,4 @@ +#!/bin/sh +find patches -type f -name '*.java.patch' -exec sed -i "s/\t/ /g" {} \; +find src/main/java -type f -name '*.java' -exec sed -i "s/\t/ /g" {} \; + diff --git a/src/main/java/kcauldron/KCauldron.java b/src/main/java/kcauldron/KCauldron.java index eb86a1b..9430ead 100644 --- a/src/main/java/kcauldron/KCauldron.java +++ b/src/main/java/kcauldron/KCauldron.java @@ -13,6 +13,8 @@ import cpw.mods.fml.common.FMLCommonHandler; import cpw.mods.fml.common.FMLLog; public class KCauldron { + public static final ThreadGroup sKCauldronThreadGroup = new ThreadGroup("KCauldron"); + private static boolean sManifestParsed = false; private static void parseManifest() { @@ -39,6 +41,8 @@ public class KCauldron { sGroup = manifest.getProperty("KCauldron-Group"); sBranch = manifest.getProperty("KCauldron-Branch"); sChannel = manifest.getProperty("KCauldron-Channel"); + sLegacy = Boolean.parseBoolean(manifest.getProperty("KCauldron-Legacy")); + sOfficial = Boolean.parseBoolean(manifest.getProperty("KCauldron-Official")); break; } manifest.clear(); @@ -97,6 +101,18 @@ public class KCauldron { parseManifest(); return sChannel; } + + private static boolean sLegacy, sOfficial; + + public static boolean isLegacy() { + parseManifest(); + return sLegacy; + } + + public static boolean isOfficial() { + parseManifest(); + return sOfficial; + } public static File sNewServerLocation; public static String sNewServerVersion; @@ -111,6 +127,7 @@ public class KCauldron { public static int lookupForgeRevision() { if (sForgeRevision != 0) return sForgeRevision; int revision = Integer.parseInt(System.getProperty("kcauldron.forgeRevision", "0")); + if (revision != 0) return sForgeRevision = revision; try { Properties p = new Properties(); p.load(KCauldron.class diff --git a/src/main/java/kcauldron/KCauldronCommand.java b/src/main/java/kcauldron/KCauldronCommand.java index 5798396..6176151 100644 --- a/src/main/java/kcauldron/KCauldronCommand.java +++ b/src/main/java/kcauldron/KCauldronCommand.java @@ -1,31 +1,51 @@ package kcauldron; -import kcauldron.updater.CommandSenderUpdateCallback; -import kcauldron.updater.KCauldronUpdater; -import kcauldron.updater.KVersionRetriever; +import java.io.File; +import java.io.FileOutputStream; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Writer; +import java.util.List; import org.bukkit.ChatColor; +import org.bukkit.World; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.entity.CraftPlayer; + +import kcauldron.updater.CommandSenderUpdateCallback; +import kcauldron.updater.KCauldronUpdater; +import kcauldron.updater.KVersionRetriever; +import net.minecraft.entity.Entity; +import net.minecraft.server.MinecraftServer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.NextTickListEntry; +import net.minecraft.world.WorldServer; +import net.minecraft.world.chunk.Chunk; +import net.minecraftforge.common.DimensionManager; public class KCauldronCommand extends Command { public static final String NAME = "kc"; public static final String CHECK = NAME + ".check"; public static final String UPDATE = NAME + ".update"; + public static final String TPS = NAME + ".tps"; public static final String RESTART = NAME + ".restart"; + public static final String DUMP = NAME + ".dump"; public KCauldronCommand() { super(NAME); StringBuilder builder = new StringBuilder(); builder.append(String.format("/%s check - Check to update\n", NAME)); - builder.append(String - .format("/%s update [version] - Update to specified or latest version\n", - NAME)); + builder.append(String.format("/%s update [version] - Update to specified or latest version\n", NAME)); + builder.append(String.format("/%s tps - Show tps statistics\n", NAME)); builder.append(String.format("/%s restart - Restart server\n", NAME)); + builder.append(String.format("/%s dump - Dump statistics into kcauldron.dump file\n", NAME)); setUsage(builder.toString()); - setPermission("kcauldron"); + setPermission("kc"); } public boolean testPermission(CommandSender target, String permission) { @@ -48,8 +68,7 @@ public class KCauldronCommand extends Command { } @Override - public boolean execute(CommandSender sender, String commandLabel, - String[] args) { + public boolean execute(CommandSender sender, String commandLabel, String[] args) { if (!testPermission(sender)) return true; if (args.length == 0) { @@ -62,19 +81,101 @@ public class KCauldronCommand extends Command { if (!testPermission(sender, CHECK)) return true; sender.sendMessage(ChatColor.GREEN + "Initiated version check..."); - KVersionRetriever.startServer(new CommandSenderUpdateCallback( - sender), false); + KVersionRetriever.startServer(new CommandSenderUpdateCallback(sender), false); } else if ("update".equals(action)) { - KCauldronUpdater.initUpdate(sender, args.length > 1 ? args[1] - : null); + KCauldronUpdater.initUpdate(sender, args.length > 1 ? args[1] : null); + } else if ("tps".equals(action)) { + if (!testPermission(sender, TPS)) + return true; + World currentWorld = null; + if (sender instanceof CraftPlayer) { + currentWorld = ((CraftPlayer) sender).getWorld(); + } + sender.sendMessage(ChatColor.DARK_BLUE + "---------------------------------------"); + final MinecraftServer server = MinecraftServer.getServer(); + for (World world : server.server.getWorlds()) { + if (world instanceof CraftWorld) { + boolean current = currentWorld != null && currentWorld == world; + net.minecraft.world.World mcWorld = ((CraftWorld) world).getHandle(); + String bukkitName = world.getName(); + int dimensionId = mcWorld.provider.dimensionId; + String name = mcWorld.provider.getDimensionName(); + String displayName = name.equals(bukkitName) ? name : String.format("%s | %s", name, bukkitName); + + double worldTickTime = mean(server.worldTickTimes.get(dimensionId)) * 1.0E-6D; + double worldTPS = Math.min(1000.0 / worldTickTime, 20); + + sender.sendMessage(String.format("%s[%d] %s%s %s- %s%.2fms / %.2ftps", ChatColor.GOLD, dimensionId, + current ? ChatColor.GREEN : ChatColor.YELLOW, displayName, ChatColor.RESET, + ChatColor.DARK_RED, worldTickTime, worldTPS)); + } + } + double meanTickTime = mean(server.tickTimeArray) * 1.0E-6D; + double meanTPS = Math.min(1000.0 / meanTickTime, 20); + sender.sendMessage(String.format("%sOverall - %s%s%.2fms / %.2ftps", ChatColor.BLUE, ChatColor.RESET, + ChatColor.DARK_RED, meanTickTime, meanTPS)); } else if ("restart".equals(action)) { if (!testPermission(sender, RESTART)) return true; KCauldron.restart(); + } else if ("dump".equals(action)) { + if (!testPermission(sender, DUMP)) + return true; + try { + File outputFile = new File("kcauldron.dump"); + OutputStream os = new FileOutputStream(outputFile); + Writer writer = new OutputStreamWriter(os); + for (WorldServer world : DimensionManager.getWorlds()) { + writer.write(String.format("Stats for %s [%s] with id %d\n", world, + world.provider.getDimensionName(), world.dimension)); + writer.write("Current tick: " + world.worldInfo.getWorldTotalTime() + "\n"); + writer.write("\nEntities: "); + writer.write("count - " + world.loadedEntityList.size() + "\n"); + for (Entity entity : (Iterable) world.loadedEntityList) { + writer.write(String.format(" %s at (%.4f;%.4f;%.4f)\n", entity.getClass().getName(), + entity.posX, entity.posY, entity.posZ)); + } + writer.write("\nTileEntities: "); + writer.write("count - " + world.loadedTileEntityList.size() + "\n"); + for (TileEntity entity : (Iterable) world.loadedTileEntityList) { + writer.write(String.format(" %s at (%d;%d;%d)\n", entity.getClass().getName(), entity.xCoord, + entity.yCoord, entity.zCoord)); + } + writer.write("\nLoaded chunks: "); + writer.write("count - " + world.activeChunkSet.size() + "\n"); + for (ChunkCoordIntPair chunkCoords : (Iterable) world.activeChunkSet) { + final int x = chunkCoords.chunkXPos; + final int z = chunkCoords.chunkZPos; + Chunk chunk = world.chunkProvider.provideChunk(x, z); + if (chunk == null) + continue; + writer.write(String.format("Chunk at (%d;%d)\n", x, z)); + @SuppressWarnings("unchecked") + List updates = world.getPendingBlockUpdates(chunk, false); + writer.write("Pending block updates [" + updates.size() + "]:\n"); + for (NextTickListEntry entry : updates) { + writer.write(String.format("(%d;%d;%d) at %d with priority %d\n", entry.xCoord, + entry.yCoord, entry.zCoord, entry.scheduledTime, entry.priority)); + } + } + writer.write("-------------------------\n"); + } + writer.close(); + sender.sendMessage(ChatColor.RED + "Dump saved!"); + } catch (Exception e) { + e.printStackTrace(); + } } else { sender.sendMessage(ChatColor.RED + "Unknown action"); } return true; } + private static final long mean(long[] array) { + long r = 0; + for (long i : array) + r += i; + return r / array.length; + } + } diff --git a/src/main/java/kcauldron/KCauldronConfig.java b/src/main/java/kcauldron/KCauldronConfig.java index 6654028..1416047 100644 --- a/src/main/java/kcauldron/KCauldronConfig.java +++ b/src/main/java/kcauldron/KCauldronConfig.java @@ -12,7 +12,7 @@ public class KCauldronConfig extends ConfigBase { public BoolSetting commandEnable = new BoolSetting(this, "command.enable", true, "Enable KCauldron command"); public BoolSetting updatecheckerEnable = new BoolSetting(this, - "updatechecker.enable", false, "Enable KCauldron update checker"); + "updatechecker.enable", true, "Enable KCauldron update checker"); public StringSetting updatecheckerSymlinks = new StringSetting(this, "updatechecker.symlinks", "KCauldron.jar", "(Re)create symlinks after update"); public BoolSetting updatecheckerAutoinstall = new BoolSetting(this, diff --git a/src/main/java/kcauldron/updater/DefaultUpdateCallback.java b/src/main/java/kcauldron/updater/DefaultUpdateCallback.java index ecab5bd..2980c31 100644 --- a/src/main/java/kcauldron/updater/DefaultUpdateCallback.java +++ b/src/main/java/kcauldron/updater/DefaultUpdateCallback.java @@ -6,6 +6,7 @@ import kcauldron.updater.KVersionRetriever.IVersionCheckCallback; import net.minecraft.server.MinecraftServer; import org.bukkit.Bukkit; +import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.entity.Player; import org.bukkit.event.player.PlayerJoinEvent; @@ -19,13 +20,21 @@ public class DefaultUpdateCallback implements IVersionCheckCallback { public void onPlayerJoin(PlayerJoinEvent event) { Player player = event.getPlayer(); - if (mHasUpdate && hasPermission(player)) { - sendUpdate(player); + if (hasPermission(player)) { + if (KCauldron.isLegacy()) { + player.sendMessage(ChatColor.YELLOW + "We're running on legacy version on KCauldron, please update your version"); + } + if (!KCauldron.isOfficial()) { + player.sendMessage(ChatColor.YELLOW + "We're running on non-official version on KCauldron, please update your version"); + } + if (mHasUpdate) { + sendUpdate(player); + } } } private boolean hasPermission(CommandSender player) { - return player.hasPermission(KCauldronCommand.UPDATE); + return player.hasPermission(KCauldronCommand.UPDATE) || player.isOp(); } private void sendUpdate(CommandSender player) { diff --git a/src/main/java/kcauldron/updater/KCauldronUpdater.java b/src/main/java/kcauldron/updater/KCauldronUpdater.java index 87eaac7..84bae69 100644 --- a/src/main/java/kcauldron/updater/KCauldronUpdater.java +++ b/src/main/java/kcauldron/updater/KCauldronUpdater.java @@ -86,8 +86,7 @@ public class KCauldronUpdater implements Runnable, IVersionCheckCallback { public KCauldronUpdater(CommandSender sender, String version) { mSender = sender; mVersion = version; - mThread = new Thread(this); - mThread.setName("KCauldron updater"); + mThread = new Thread(KCauldron.sKCauldronThreadGroup, this, "KCauldron updated"); mThread.setPriority(Thread.MIN_PRIORITY); mThread.start(); } diff --git a/src/main/java/kcauldron/updater/KVersionRetriever.java b/src/main/java/kcauldron/updater/KVersionRetriever.java index 54a2baa..a351958 100644 --- a/src/main/java/kcauldron/updater/KVersionRetriever.java +++ b/src/main/java/kcauldron/updater/KVersionRetriever.java @@ -56,8 +56,7 @@ public class KVersionRetriever implements Runnable, UncaughtExceptionHandler { mUpToDateSupport = upToDateSupport; mGroup = group; mName = name; - mThread = new Thread(this); - mThread.setName("KCauldron version retrievier"); + mThread = new Thread(KCauldron.sKCauldronThreadGroup, this, "KCauldron version retrievier"); mThread.setPriority(Thread.MIN_PRIORITY); mThread.setDaemon(true); mThread.setUncaughtExceptionHandler(this); @@ -84,6 +83,7 @@ public class KVersionRetriever implements Runnable, UncaughtExceptionHandler { .get() .setUri("https://api.prok.pw/repo/version/" + mGroup + "/" + mName) + .addParameter("version", KCauldron.getCurrentVersion()) .addParameter("hostname", sServer.getHostname()) .addParameter("port", "" + sServer.getPort()).build(); HttpResponse response = HttpClientBuilder.create() diff --git a/src/main/java/net/minecraft/server/network/ThreadPlayerLookupUUID.java b/src/main/java/net/minecraft/server/network/ThreadPlayerLookupUUID.java index 5f43d99..16baa9a 100644 --- a/src/main/java/net/minecraft/server/network/ThreadPlayerLookupUUID.java +++ b/src/main/java/net/minecraft/server/network/ThreadPlayerLookupUUID.java @@ -44,7 +44,7 @@ class ThreadPlayerLookupUUID extends Thread String s = (new BigInteger(CryptManager.getServerIdHash(NetHandlerLoginServer.getLoginServerId(this.field_151292_a), this.mcServer.getKeyPair().getPublic(), NetHandlerLoginServer.getSecretKey(this.field_151292_a)))).toString(16); GameProfile profile = this.mcServer.func_147130_as().hasJoinedServer(new GameProfile((UUID)null, gameprofile.getName()), s); if (profile != null) { - NetHandlerLoginServer.processPlayerLoginGameProfile(this.field_151292_a, profile); + NetHandlerLoginServer.processPlayerLoginGameProfile(this.field_151292_a, profile); fireLoginEvents(); // Spigot } else if (this.mcServer.isSinglePlayer()) diff --git a/src/main/java/net/minecraftforge/cauldron/configuration/CauldronConfig.java b/src/main/java/net/minecraftforge/cauldron/configuration/CauldronConfig.java index 69abe12..e8a566b 100644 --- a/src/main/java/net/minecraftforge/cauldron/configuration/CauldronConfig.java +++ b/src/main/java/net/minecraftforge/cauldron/configuration/CauldronConfig.java @@ -45,8 +45,7 @@ public class CauldronConfig extends ConfigBase public final BoolSetting checkEntityMaxSpeeds = new BoolSetting(this, "settings.check-entity-max-speeds", false, "Removes any entity that exceeds max speed."); public final IntSetting largeBoundingBoxLogSize = new IntSetting(this, "settings.entity-bounding-box-max-size", 1000, "Max size of an entity's bounding box before removing it (either being too large or bugged and 'moving' too fast)"); public final IntSetting entityMaxSpeed = new IntSetting(this, "settings.entity-max-speed", 100, "Square of the max speed of an entity before removing it"); - public final IntSetting chunkGCGracePeriod = new IntSetting(this, "settings.chunk-gc-grace-period",0,"Grace period of no-ticks before unload"); - + // Debug settings public final BoolSetting enableThreadContentionMonitoring = new BoolSetting(this, "debug.thread-contention-monitoring", false, "Set true to enable Java's thread contention monitoring for thread dumps"); @@ -101,7 +100,6 @@ public class CauldronConfig extends ConfigBase settings.put(userLogin.path, userLogin); settings.put(allowTntPunishment.path, allowTntPunishment); settings.put(maxPlayersVisible.path, maxPlayersVisible); - settings.put(chunkGCGracePeriod.path,chunkGCGracePeriod); load(); } diff --git a/src/main/java/net/minecraftforge/cauldron/configuration/StringSetting.java b/src/main/java/net/minecraftforge/cauldron/configuration/StringSetting.java index 6ff9d36..c394741 100644 --- a/src/main/java/net/minecraftforge/cauldron/configuration/StringSetting.java +++ b/src/main/java/net/minecraftforge/cauldron/configuration/StringSetting.java @@ -1,23 +1,23 @@ package net.minecraftforge.cauldron.configuration; public class StringSetting extends Setting { - private String value; - private ConfigBase config; + private String value; + private ConfigBase config; - public StringSetting(ConfigBase config, String path, String def, - String description) { - super(path, def, description); - this.value = def; - this.config = config; - } + public StringSetting(ConfigBase config, String path, String def, + String description) { + super(path, def, description); + this.value = def; + this.config = config; + } - @Override - public String getValue() { - return value; - } + @Override + public String getValue() { + return value; + } - @Override - public void setValue(String value) { - config.set(path, this.value = value); - } + @Override + public void setValue(String value) { + config.set(path, this.value = value); + } } diff --git a/src/main/java/org/bukkit/craftbukkit/CraftServer.java b/src/main/java/org/bukkit/craftbukkit/CraftServer.java index b9910a3..a2468b9 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftServer.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftServer.java @@ -140,7 +140,7 @@ import jline.console.ConsoleReader; public final class CraftServer implements Server { private static final Player[] EMPTY_PLAYER_ARRAY = new Player[0]; - private final String serverName = "Cauldron"; // Cauldron - temporarily keep MCPC-Plus name until plugins adapt + private final String serverName = "KCauldron"; // Cauldron - temporarily keep MCPC-Plus name until plugins adapt private final String serverVersion; private final String bukkitVersion = Versioning.getBukkitVersion(); private final Logger logger = Logger.getLogger("Minecraft"); @@ -452,7 +452,7 @@ public final class CraftServer implements Server { @Override public List getOnlinePlayers() { - return this.playerView; + return ImmutableList.copyOf(this.playerView); } @Override @@ -1307,7 +1307,7 @@ public final class CraftServer implements Server { // Spigot start GameProfile profile = null; if (MinecraftServer.getServer().isServerInOnlineMode() || org.spigotmc.SpigotConfig.bungee) { - profile = MinecraftServer.getServer().func_152358_ax().func_152655_a(name); + profile = MinecraftServer.getServer().func_152358_ax().func_152655_a(name); } if (profile == null) { // Make an OfflinePlayer using an offline mode UUID since the name has no profile diff --git a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java index 9318634..8e94643 100644 --- a/src/main/java/org/bukkit/craftbukkit/CraftWorld.java +++ b/src/main/java/org/bukkit/craftbukkit/CraftWorld.java @@ -88,7 +88,7 @@ public class CraftWorld implements World { } public Block getBlockAt(int x, int y, int z) { - Chunk chunk = getChunkAt(x >> 4, z >> 4); + Chunk chunk = getChunkAt(x >> 4, z >> 4); return chunk == null ? null : chunk.getBlock(x & 0xF, y & 0xFF, z & 0xF); } @@ -125,7 +125,7 @@ public class CraftWorld implements World { } public Chunk getChunkAt(int x, int z) { - net.minecraft.world.chunk.Chunk chunk = this.world.theChunkProviderServer.loadChunk(x, z); + net.minecraft.world.chunk.Chunk chunk = this.world.theChunkProviderServer.loadChunk(x, z); return chunk == null ? null : chunk.bukkitChunk; } @@ -1395,23 +1395,23 @@ public class CraftWorld implements World { final net.minecraft.world.gen.ChunkProviderServer cps = world.theChunkProviderServer; cps.loadedChunkHashMap_KC.forEachValue(new TObjectProcedure() { - @Override - public boolean execute(net.minecraft.world.chunk.Chunk chunk) { - // If in use, skip it - if (isChunkInUse(chunk.xPosition, chunk.zPosition)) { - return true; - } - - // Already unloading? - if (cps.chunksToUnload.contains(chunk.xPosition, chunk.zPosition)) { - return true; - } - - // Add unload request - cps.unloadChunksIfNotNearSpawn(chunk.xPosition, chunk.zPosition); - return true; - } - }); + @Override + public boolean execute(net.minecraft.world.chunk.Chunk chunk) { + // If in use, skip it + if (isChunkInUse(chunk.xPosition, chunk.zPosition)) { + return true; + } + + // Already unloading? + if (cps.chunksToUnload.contains(chunk.xPosition, chunk.zPosition)) { + return true; + } + + // Add unload request + cps.unloadChunksIfNotNearSpawn(chunk.xPosition, chunk.zPosition); + return true; + } + }); } // Spigot start diff --git a/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java b/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java index ae7e4d8..edfa12e 100644 --- a/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java +++ b/src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java @@ -166,7 +166,7 @@ public class CraftSkull extends CraftBlockState implements Skull { } public BlockFace getRotation() { - return getBlockFace(rotation); + return getBlockFace(rotation); } public void setRotation(BlockFace rotation) { diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java index 7385be6..9c87aa4 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java @@ -416,7 +416,7 @@ public abstract class CraftEntity implements org.bukkit.entity.Entity { // Spigot start net.minecraft.world.WorldServer newWorld = ((CraftWorld) location.getWorld()).getHandle(); if (newWorld != entity.worldObj) { - entity.teleportTo(location, cause.isPortal()); + entity.teleportTo(location, cause.isPortal()); return true; } // Spigot diff --git a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java index f790554..d128163 100644 --- a/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java +++ b/src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java @@ -44,7 +44,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { } public PlayerInventory getInventory() { - if (inventory == null) inventory = new CraftInventoryPlayer(((net.minecraft.entity.player.EntityPlayer) entity).inventory); + if (inventory == null) inventory = new CraftInventoryPlayer(((net.minecraft.entity.player.EntityPlayer) entity).inventory); return inventory; } @@ -53,7 +53,7 @@ public class CraftHumanEntity extends CraftLivingEntity implements HumanEntity { } public Inventory getEnderChest() { - if (enderChest == null) enderChest = new CraftInventory(((net.minecraft.entity.player.EntityPlayer) entity).getInventoryEnderChest()); + if (enderChest == null) enderChest = new CraftInventory(((net.minecraft.entity.player.EntityPlayer) entity).getInventoryEnderChest()); return enderChest; } diff --git a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java index ed2ff4a..dcefc9b 100644 --- a/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java +++ b/src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java @@ -97,7 +97,8 @@ class CraftMetaSkull extends CraftMetaItem implements SkullMeta { if (name == null) { profile = null; } else { - profile = new GameProfile(null, name); + profile = net.minecraft.server.MinecraftServer.getServer().func_152358_ax().func_152655_a(name); + if (profile == null) profile = new GameProfile(null, name); } return true; diff --git a/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java b/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java index 4dbbca5..5f5339e 100644 --- a/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java +++ b/src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java @@ -1,5 +1,6 @@ package org.bukkit.craftbukkit.map; +import java.util.UUID; import org.bukkit.Bukkit; import org.bukkit.entity.Player; @@ -32,9 +33,9 @@ public class CraftMapRenderer extends MapRenderer { cursors.removeCursor(cursors.getCursor(0)); } - for (Object key : worldMap.playersVisibleOnMap.keySet()) { + for (UUID key : worldMap.playersVisibleOnMap.keySet()) { // Spigot string -> uuid // If this cursor is for a player check visibility with vanish system - Player other = Bukkit.getPlayerExact((String) key); + Player other = Bukkit.getPlayer(key); // Spigot if (other != null && !player.canSee(other)) { continue; } diff --git a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java index be574ce..e90d539 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java +++ b/src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java @@ -80,9 +80,9 @@ public final class CraftChatMessage { currentChatComponent = null; break; case 3: - if (match.indexOf("://") < 0) { - match = "http://" + match; - } + if (match.indexOf("://") < 0) { + match = "http://" + match; + } modifier.setChatClickEvent(new net.minecraft.event.ClickEvent(net.minecraft.event.ClickEvent.Action.OPEN_URL, match)); // Should be setChatClickable appendNewComponent(matcher.end(groupId)); modifier.setChatClickEvent((net.minecraft.event.ClickEvent) null); diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java b/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java index 4277d36..f339c05 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java +++ b/src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java @@ -188,7 +188,7 @@ public class LongHashSet implements Set { } } - @Override + @Override public void clear() { elements = 0; for (int ix = 0; ix < values.length; ix++) { @@ -214,9 +214,9 @@ public class LongHashSet implements Set { return result; } - @Override + @Override public Long[] toArray() { - Long[] result = new Long[elements]; + Long[] result = new Long[elements]; long[] values = Java15Compat.Arrays_copyOf(this.values, this.values.length); int pos = 0; @@ -229,10 +229,10 @@ public class LongHashSet implements Set { return result; } - @Override - public T[] toArray(T[] arg0) { - throw new UnsupportedOperationException(); - } + @Override + public T[] toArray(T[] arg0) { + throw new UnsupportedOperationException(); + } public long popFirst() { for (long value : values) { @@ -359,52 +359,52 @@ public class LongHashSet implements Set { } } - @Override - public boolean add(Long value) { - return add(value.longValue()); - } - - @Override - public boolean addAll(Collection collection) { - boolean result = false; - for (Long value : collection) result |= add(value.longValue()); - return result; - } - - @Override - public boolean contains(Object o) { - return o instanceof Long ? contains(((Long) o).longValue()) : false; - } - - @Override - public boolean containsAll(Collection collection) { - for (Object value : collection) if (!contains(value)) return false; - return true; - } - - @Override - public boolean remove(Object o) { - return o instanceof Long ? remove(((Long) o).longValue()) : false; - } - - @Override - public boolean removeAll(Collection collection) { - boolean result = false; - for (Object value : collection) result |= remove(value); - return result; - } - - @Override - public boolean retainAll(Collection collection) { - boolean result = false; - Iterator iterator = iterator(); - while(iterator.hasNext()) { - Long l = iterator.next(); - if (!collection.contains(l)) { - iterator.remove(); - result = true; - } - } - return result; - } + @Override + public boolean add(Long value) { + return add(value.longValue()); + } + + @Override + public boolean addAll(Collection collection) { + boolean result = false; + for (Long value : collection) result |= add(value.longValue()); + return result; + } + + @Override + public boolean contains(Object o) { + return o instanceof Long ? contains(((Long) o).longValue()) : false; + } + + @Override + public boolean containsAll(Collection collection) { + for (Object value : collection) if (!contains(value)) return false; + return true; + } + + @Override + public boolean remove(Object o) { + return o instanceof Long ? remove(((Long) o).longValue()) : false; + } + + @Override + public boolean removeAll(Collection collection) { + boolean result = false; + for (Object value : collection) result |= remove(value); + return result; + } + + @Override + public boolean retainAll(Collection collection) { + boolean result = false; + Iterator iterator = iterator(); + while(iterator.hasNext()) { + Long l = iterator.next(); + if (!collection.contains(l)) { + iterator.remove(); + result = true; + } + } + return result; + } } diff --git a/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java b/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java index 7adfb2a..edf748e 100644 --- a/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java +++ b/src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java @@ -207,7 +207,7 @@ public class LongObjectHashMap implements Cloneable, Serializable { * @return Set of Entry objects */ public Set> entrySet() { - return new EntrySet(); + return new EntrySet(); } public Object clone() throws CloneNotSupportedException { @@ -425,40 +425,40 @@ public class LongObjectHashMap implements Cloneable, Serializable { } private void bind(long key, V value) { - this.key = key; - this.value = value; + this.key = key; + this.value = value; } } private class EntrySet extends AbstractSet> { - @Override - public Iterator> iterator() { - return new Iterator>() { - final Entry entry = new Entry(); - final ValueIterator valueIterator = new ValueIterator(); - - @Override - public boolean hasNext() { - return valueIterator.hasNext(); - } - - @Override - public LongObjectHashMap.Entry next() { - V value = valueIterator.next(); - entry.bind(valueIterator.prevKey, value); - return entry; - } - - @Override - public void remove() { - valueIterator.remove(); - } - }; - } - - @Override - public int size() { - return LongObjectHashMap.this.size; - } + @Override + public Iterator> iterator() { + return new Iterator>() { + final Entry entry = new Entry(); + final ValueIterator valueIterator = new ValueIterator(); + + @Override + public boolean hasNext() { + return valueIterator.hasNext(); + } + + @Override + public LongObjectHashMap.Entry next() { + V value = valueIterator.next(); + entry.bind(valueIterator.prevKey, value); + return entry; + } + + @Override + public void remove() { + valueIterator.remove(); + } + }; + } + + @Override + public int size() { + return LongObjectHashMap.this.size; + } } } diff --git a/src/main/java/org/spigotmc/RestartCommand.java b/src/main/java/org/spigotmc/RestartCommand.java index 5427f91..44691a4 100644 --- a/src/main/java/org/spigotmc/RestartCommand.java +++ b/src/main/java/org/spigotmc/RestartCommand.java @@ -2,9 +2,12 @@ package org.spigotmc; import java.io.File; import java.util.List; + +import org.bukkit.Bukkit; import org.bukkit.command.Command; import org.bukkit.command.CommandSender; import org.bukkit.craftbukkit.util.CraftChatMessage; +import org.bukkit.entity.Player; public class RestartCommand extends Command { @@ -28,7 +31,7 @@ public class RestartCommand extends Command } public static void restart() { - restart(false); + restart(false); } public static void restart(boolean forbidShutdown) @@ -40,17 +43,14 @@ public class RestartCommand extends Command { System.out.println( "Attempting to restart with " + SpigotConfig.restartScript ); - // Kick all players - for ( Object p : net.minecraft.server.MinecraftServer.getServer().getConfigurationManager().playerEntityList.toArray() ) - { - if(p instanceof net.minecraft.entity.player.EntityPlayerMP) - { - net.minecraft.entity.player.EntityPlayerMP mp = ( net.minecraft.entity.player.EntityPlayerMP)p; - mp.playerNetServerHandler.kickPlayerFromServer(SpigotConfig.restartMessage); - mp.playerNetServerHandler.netManager.isChannelOpen(); - } + // Forbid new logons + net.minecraft.server.dedicated.DedicatedServer.allowPlayerLogins = false; + // Kick all players + for (Player player : Bukkit.getOnlinePlayers()) { + player.kickPlayer(SpigotConfig.restartMessage); } + // Give the socket a chance to send the packets try { @@ -72,7 +72,7 @@ public class RestartCommand extends Command // Actually shutdown try { - net.minecraft.server.MinecraftServer.getServer().stopServer(); + Bukkit.shutdown(); } catch ( Throwable t ) { } @@ -93,7 +93,7 @@ public class RestartCommand extends Command { Runtime.getRuntime().exec( new String[] { - "sh", file.getPath() + "/bin/sh", file.getPath() } ); } } catch ( Exception e ) @@ -107,10 +107,10 @@ public class RestartCommand extends Command Runtime.getRuntime().addShutdownHook( shutdownHook ); } else { - if (forbidShutdown) { - System.out.println("Attempt to restart server without restart script, decline request"); - return; - } + if (forbidShutdown) { + System.out.println("Attempt to restart server without restart script, decline request"); + return; + } System.out.println( "Startup script '" + SpigotConfig.restartScript + "' does not exist! Stopping server." ); } cpw.mods.fml.common.FMLCommonHandler.instance().exitJava(0, false); diff --git a/src/main/java/org/spigotmc/SpigotConfig.java b/src/main/java/org/spigotmc/SpigotConfig.java index e0a5207..b721cc4 100644 --- a/src/main/java/org/spigotmc/SpigotConfig.java +++ b/src/main/java/org/spigotmc/SpigotConfig.java @@ -50,8 +50,8 @@ public class SpigotConfig commands = new HashMap(); - version = getInt( "config-version", 5 ); - set( "config-version", 5 ); + version = getInt( "config-version", 7 ); + set( "config-version", 7 ); readConfig( SpigotConfig.class, null ); } @@ -152,7 +152,7 @@ public class SpigotConfig public static String unknownCommandMessage; public static String serverFullMessage; public static String outdatedClientMessage = "Outdated client! Please use {}"; - public static String outdatedServerMessage = "Outdated server! I\'m still on {0}"; + public static String outdatedServerMessage = "Outdated server! I\'m still on {}"; private static String transform(String s) { return ChatColor.translateAlternateColorCodes( '&', s ).replaceAll( "\\n", "\n" ); @@ -199,7 +199,10 @@ public class SpigotConfig private static void nettyThreads() { - int count = getInt( "settings.netty-threads", 4 ); + if (version < 7) + set("settings.netty-threads", -1); + int count = getInt( "settings.netty-threads", -1 ); + count = count == -1 ? Runtime.getRuntime().availableProcessors() : count; System.setProperty( "io.netty.eventLoopThreads", Integer.toString( count ) ); Bukkit.getLogger().log( Level.INFO, "Using {0} threads for Netty based IO", count ); } @@ -271,6 +274,6 @@ public class SpigotConfig public static int fullMatchRate; private static void fullMatchRate() { - fullMatchRate = getInt( "settings.fullMatchRate", 10); + fullMatchRate = getInt( "settings.fullMatchRate", 10); } } diff --git a/src/main/java/org/spigotmc/SpigotWorldConfig.java b/src/main/java/org/spigotmc/SpigotWorldConfig.java index f56af89..86f60df 100644 --- a/src/main/java/org/spigotmc/SpigotWorldConfig.java +++ b/src/main/java/org/spigotmc/SpigotWorldConfig.java @@ -115,14 +115,14 @@ public class SpigotWorldConfig public double itemMerge; private void itemMerge() { - itemMerge = getDouble("merge-radius.item", 4 ); + itemMerge = getDouble("merge-radius.item", 2.5 ); log( "Item Merge Radius: " + itemMerge ); } public double expMerge; private void expMerge() { - expMerge = getDouble("merge-radius.exp", 6 ); + expMerge = getDouble("merge-radius.exp", 3.0 ); log( "Experience Merge Radius: " + expMerge ); } @@ -140,9 +140,9 @@ public class SpigotWorldConfig log( "Mob Spawn Range: " + mobSpawnRange ); } - public int animalActivationRange = 8; - public int monsterActivationRange = 10; - public int miscActivationRange = 2; + public int animalActivationRange = 32; + public int monsterActivationRange = 32; + public int miscActivationRange = 16; private void activationRange() { animalActivationRange = getInt( "entity-activation-range.animals", animalActivationRange ); @@ -151,11 +151,11 @@ public class SpigotWorldConfig log( "Entity Activation Range: An " + animalActivationRange + " / Mo " + monsterActivationRange + " / Mi " + miscActivationRange ); } - public int playerTrackingRange = 32; - public int animalTrackingRange = 32; - public int monsterTrackingRange = 32; - public int miscTrackingRange = 24; - public int maxTrackingRange = 24; + public int playerTrackingRange = 48; + public int animalTrackingRange = 48; + public int monsterTrackingRange = 48; + public int miscTrackingRange = 32; + public int maxTrackingRange = 64; private void trackingRange() { playerTrackingRange = getInt( "entity-tracking-range.players", playerTrackingRange ); @@ -182,7 +182,7 @@ public class SpigotWorldConfig public boolean randomLightUpdates; private void lightUpdates() { - randomLightUpdates = getBoolean( "random-light-updates", true ); + randomLightUpdates = getBoolean( "random-light-updates", false ); log( "Random Lighting Updates: " + randomLightUpdates ); } @@ -201,14 +201,14 @@ public class SpigotWorldConfig public int itemDespawnRate; private void itemDespawnRate() { - itemDespawnRate = getInt( "item-despawn-rate", 3000 ); + itemDespawnRate = getInt( "item-despawn-rate", 6000 ); log( "Item Despawn Rate: " + itemDespawnRate ); } public int arrowDespawnRate; private void arrowDespawnRate() { - arrowDespawnRate = getInt( "arrow-despawn-rate", 120 ); + arrowDespawnRate = getInt( "arrow-despawn-rate", 1200 ); log( "Arrow Despawn Rate: " + arrowDespawnRate ); } @@ -219,7 +219,7 @@ public class SpigotWorldConfig public AntiXray antiXrayInstance; private void antiXray() { - antiXray = getBoolean( "anti-xray.enabled", false ); + antiXray = getBoolean( "anti-xray.enabled", true ); log( "Anti X-Ray: " + antiXray ); engineMode = getInt( "anti-xray.engine-mode", 1 ); @@ -275,7 +275,7 @@ public class SpigotWorldConfig public int maxCollisionsPerEntity; private void maxEntityCollision() { - maxCollisionsPerEntity = getInt( "max-entity-collisions", 2 ); + maxCollisionsPerEntity = getInt( "max-entity-collisions", 8 ); log( "Max Entity Collisions: " + maxCollisionsPerEntity ); } @@ -283,8 +283,26 @@ public class SpigotWorldConfig public int entityMaxTickTime; private void maxTickTimes() { - tileMaxTickTime = getInt("max-tick-time.tile", 50); - entityMaxTickTime = getInt("max-tick-time.entity", 50); - log("Tile Max Tick Time: " + tileMaxTickTime + "ms Entity max Tick Time: " + entityMaxTickTime + "ms"); + tileMaxTickTime = getInt("max-tick-time.tile", 50); + entityMaxTickTime = getInt("max-tick-time.entity", 50); + log("Tile Max Tick Time: " + tileMaxTickTime + "ms Entity max Tick Time: " + entityMaxTickTime + "ms"); + } + + public int currentPrimedTnt = 0; + public int maxTntTicksPerTick; + private void maxTntPerTick() { + if ( SpigotConfig.version < 7 ) + { + set( "max-tnt-per-tick", 100 ); + } + maxTntTicksPerTick = getInt( "max-tnt-per-tick", 100 ); + log( "Max TNT Explosions: " + maxTntTicksPerTick ); + } + + public boolean useAsyncLighting; + private void useAsyncLighting() + { + useAsyncLighting = getBoolean( "use-async-lighting", true ); + log( "World async lighting: " + useAsyncLighting ); } } diff --git a/src/main/java/org/spigotmc/TickLimiter.java b/src/main/java/org/spigotmc/TickLimiter.java index 74ac1fb..c1d15e3 100644 --- a/src/main/java/org/spigotmc/TickLimiter.java +++ b/src/main/java/org/spigotmc/TickLimiter.java @@ -1,18 +1,25 @@ package org.spigotmc; public class TickLimiter { - private final int maxTime; - private long startTime; - - public TickLimiter(int maxTime) { - this.maxTime = maxTime; - } - - public void initTick() { - startTime = System.currentTimeMillis(); - } - - public boolean shouldContinue() { - return System.currentTimeMillis() - startTime < maxTime; - } + private final int maxTime; + private long startTime; + private int tick; + private boolean shouldContinue; + public TickLimiter(int maxTime) { + this.maxTime = maxTime; + } + + public void initTick() { + startTime = System.currentTimeMillis(); + tick = 0; + shouldContinue = true; + } + + public boolean shouldContinue() { + if (++tick >= 300 && shouldContinue) { + tick = 0; + shouldContinue = System.currentTimeMillis() - startTime < maxTime; + } + return shouldContinue; + } } diff --git a/src/main/resources/configurations/bukkit.yml b/src/main/resources/configurations/bukkit.yml index d0b5e89..b2a7bea 100644 --- a/src/main/resources/configurations/bukkit.yml +++ b/src/main/resources/configurations/bukkit.yml @@ -11,14 +11,6 @@ # Forums: http://forums.bukkit.org/forums/bukkit-help.6/ # Twitter: http://twitter.com/CraftBukkit # Bug tracker: http://leaky.bukkit.org/ -# -# Replace the database section if you have access to a MySQL server for better performance with what's below -# database: -# username: {USERNAME} -# isolation: SERIALIZABLE -# driver: com.mysql.jdbc.Driver -# password: {PASSWORD} -# url: jdbc:mysql://{IP}:{PORT}/{DATABASENAME} settings: @@ -34,17 +26,17 @@ settings: deprecated-verbose: default shutdown-message: Server closed spawn-limits: - monsters: 50 - animals: 10 - water-animals: 3 - ambient: 5 + monsters: 70 + animals: 15 + water-animals: 5 + ambient: 15 chunk-gc: - enabled: true - period-in-ticks: 300 - load-threshold: 300 + enabled: false + period-in-ticks: 600 + load-threshold: 0 ticks-per: animal-spawns: 400 - monster-spawns: 20 + monster-spawns: 1 autosave: 6000 auto-updater: enabled: false