From 16773ead6a2c9a059d2efa176791c31b74bef119 Mon Sep 17 00:00:00 2001 From: gamerforEA Date: Sun, 22 Mar 2015 20:38:04 +0300 Subject: [PATCH] Initial commit (Forge 1291). --- .gitattributes | 12 + .gitignore | 10 + .gitmodules | 7 + LGPL.txt | 165 ++ LICENCE.txt | 674 ++++++ README.md | 92 + build.gradle | 73 + eclipse-workspace-dev.zip | Bin 0 -> 20444 bytes gradlew | 164 ++ gradlew.bat | 90 + jsons/1.7.10-dev.json | 298 +++ jsons/1.7.10-rel.json | 327 +++ jsons/1.7.10.json | 191 ++ .../fml/common/FMLCommonHandler.java.patch | 58 + .../common/asm/FMLSanityChecker.java.patch | 17 + .../transformers/SideTransformer.java.patch | 19 + .../event/FMLServerStartingEvent.java.patch | 23 + .../ChannelRegistrationHandler.java.patch | 35 + .../handshake/NetworkDispatcher.java.patch | 45 + .../internal/FMLNetworkHandler.java.patch | 51 + .../HandshakeCompletionHandler.java.patch | 18 + .../common/registry/EntityRegistry.java.patch | 79 + .../fml/common/registry/GameData.java.patch | 69 + .../common/registry/GameRegistry.java.patch | 71 + .../fml/relauncher/CoreModManager.java.patch | 47 + patches/net/minecraft/block/Block.java.patch | 52 + .../block/BlockBasePressurePlate.java.patch | 32 + .../minecraft/block/BlockButton.java.patch | 89 + .../minecraft/block/BlockCactus.java.patch | 31 + .../net/minecraft/block/BlockCake.java.patch | 32 + .../net/minecraft/block/BlockCocoa.java.patch | 12 + .../block/BlockCommandBlock.java.patch | 34 + .../net/minecraft/block/BlockCrops.java.patch | 15 + .../block/BlockDaylightDetector.java.patch | 10 + .../minecraft/block/BlockDispenser.java.patch | 28 + .../net/minecraft/block/BlockDoor.java.patch | 48 + .../minecraft/block/BlockDragonEgg.java.patch | 44 + .../minecraft/block/BlockDropper.java.patch | 59 + .../block/BlockDynamicLiquid.java.patch | 162 ++ .../minecraft/block/BlockEndPortal.java.patch | 22 + .../minecraft/block/BlockFarmland.java.patch | 57 + .../net/minecraft/block/BlockFire.java.patch | 129 ++ .../net/minecraft/block/BlockGrass.java.patch | 64 + .../minecraft/block/BlockHopper.java.patch | 19 + .../net/minecraft/block/BlockIce.java.patch | 17 + .../minecraft/block/BlockJukebox.java.patch | 26 + .../minecraft/block/BlockLeaves.java.patch | 28 + .../net/minecraft/block/BlockLever.java.patch | 31 + .../minecraft/block/BlockMushroom.java.patch | 60 + .../minecraft/block/BlockMycelium.java.patch | 64 + .../block/BlockNetherWart.java.patch | 11 + .../block/BlockNetherrack.java.patch | 32 + .../block/BlockPistonBase.java.patch | 116 + .../block/BlockPistonExtension.java.patch | 28 + .../minecraft/block/BlockPortal.java.patch | 383 ++++ .../block/BlockPressurePlate.java.patch | 47 + .../BlockPressurePlateWeighted.java.patch | 63 + .../minecraft/block/BlockPumpkin.java.patch | 126 ++ .../block/BlockRailDetector.java.patch | 29 + .../block/BlockRedstoneDiode.java.patch | 43 + .../block/BlockRedstoneLight.java.patch | 53 + .../block/BlockRedstoneOre.java.patch | 44 + .../block/BlockRedstoneTorch.java.patch | 62 + .../block/BlockRedstoneWire.java.patch | 39 + .../net/minecraft/block/BlockReed.java.patch | 14 + .../minecraft/block/BlockSapling.java.patch | 122 ++ .../net/minecraft/block/BlockSign.java.patch | 29 + .../net/minecraft/block/BlockSkull.java.patch | 156 ++ .../net/minecraft/block/BlockSnow.java.patch | 17 + .../block/BlockStaticLiquid.java.patch | 57 + .../net/minecraft/block/BlockStem.java.patch | 37 + .../minecraft/block/BlockTrapDoor.java.patch | 32 + .../minecraft/block/BlockTripWire.java.patch | 63 + .../block/BlockTripWireHook.java.patch | 29 + .../net/minecraft/block/BlockVine.java.patch | 77 + .../net/minecraft/client/Minecraft.java.patch | 26 + .../command/CommandHandler.java.patch | 74 + .../command/PlayerSelector.java.patch | 24 + .../command/ServerCommandManager.java.patch | 76 + .../server/CommandBlockLogic.java.patch | 212 ++ .../BehaviorDefaultDispenseItem.java.patch | 101 + .../BehaviorProjectileDispense.java.patch | 59 + .../enchantment/Enchantment.java.patch | 11 + .../net/minecraft/entity/Entity.java.patch | 775 +++++++ .../minecraft/entity/EntityAgeable.java.patch | 80 + .../entity/EntityCreature.java.patch | 105 + .../minecraft/entity/EntityHanging.java.patch | 119 + .../entity/EntityLeashKnot.java.patch | 74 + .../minecraft/entity/EntityLiving.java.patch | 162 ++ .../entity/EntityLivingBase.java.patch | 657 ++++++ .../EntityMinecartCommandBlock.java.patch | 39 + .../minecraft/entity/EntityTracker.java.patch | 27 + .../entity/EntityTrackerEntry.java.patch | 216 ++ .../entity/ai/EntityAIArrowAttack.java.patch | 25 + .../ai/EntityAIAttackOnCollide.java.patch | 30 + .../entity/ai/EntityAIBreakDoor.java.patch | 17 + .../entity/ai/EntityAIEatGrass.java.patch | 34 + .../entity/ai/EntityAIMate.java.patch | 42 + .../entity/ai/EntityAIPanic.java.patch | 26 + .../ai/EntityAIRunAroundLikeCrazy.java.patch | 35 + .../entity/ai/EntityAISit.java.patch | 11 + .../entity/ai/EntityAITarget.java.patch | 66 + .../entity/ai/EntityAIVillagerMate.java.patch | 11 + .../entity/ai/EntityLookHelper.java.patch | 24 + .../entity/ai/EntityMoveHelper.java.patch | 12 + .../entity/boss/EntityDragon.java.patch | 258 +++ .../entity/boss/EntityWither.java.patch | 57 + .../effect/EntityLightningBolt.java.patch | 100 + .../entity/item/EntityBoat.java.patch | 239 ++ .../entity/item/EntityEnderCrystal.java.patch | 49 + .../entity/item/EntityEnderPearl.java.patch | 56 + .../entity/item/EntityExpBottle.java.patch | 24 + .../entity/item/EntityFallingBlock.java.patch | 57 + .../item/EntityFireworkRocket.java.patch | 11 + .../entity/item/EntityItem.java.patch | 280 +++ .../entity/item/EntityItemFrame.java.patch | 16 + .../entity/item/EntityMinecart.java.patch | 234 ++ .../item/EntityMinecartContainer.java.patch | 78 + .../entity/item/EntityPainting.java.patch | 10 + .../entity/item/EntityTNTPrimed.java.patch | 57 + .../entity/item/EntityXPOrb.java.patch | 158 ++ .../entity/monster/EntityCreeper.java.patch | 78 + .../entity/monster/EntityEnderman.java.patch | 72 + .../entity/monster/EntityGhast.java.patch | 77 + .../entity/monster/EntityMob.java.patch | 40 + .../entity/monster/EntityPigZombie.java.patch | 42 + .../monster/EntitySilverfish.java.patch | 39 + .../entity/monster/EntitySkeleton.java.patch | 54 + .../entity/monster/EntitySlime.java.patch | 94 + .../entity/monster/EntitySnowman.java.patch | 44 + .../entity/monster/EntitySpider.java.patch | 38 + .../entity/monster/EntityZombie.java.patch | 109 + .../entity/passive/EntityCow.java.patch | 42 + .../entity/passive/EntityHorse.java.patch | 134 ++ .../entity/passive/EntityMooshroom.java.patch | 11 + .../entity/passive/EntityOcelot.java.patch | 21 + .../entity/passive/EntityPig.java.patch | 36 + .../entity/passive/EntitySheep.java.patch | 42 + .../entity/passive/EntitySquid.java.patch | 39 + .../entity/passive/EntityWolf.java.patch | 21 + .../entity/player/EntityPlayer.java.patch | 484 ++++ .../entity/player/EntityPlayerMP.java.patch | 822 +++++++ .../entity/player/InventoryPlayer.java.patch | 140 ++ .../player/PlayerCapabilities.java.patch | 13 + .../entity/projectile/EntityArrow.java.patch | 141 ++ .../entity/projectile/EntityEgg.java.patch | 73 + .../projectile/EntityFireball.java.patch | 122 ++ .../projectile/EntityFishHook.java.patch | 119 + .../projectile/EntityLargeFireball.java.patch | 40 + .../entity/projectile/EntityPotion.java.patch | 89 + .../projectile/EntitySmallFireball.java.patch | 44 + .../projectile/EntityThrowable.java.patch | 45 + .../projectile/EntityWitherSkull.java.patch | 38 + .../net/minecraft/init/Bootstrap.java.patch | 454 ++++ .../inventory/AnimalChest.java.patch | 83 + .../minecraft/inventory/Container.java.patch | 186 ++ .../inventory/ContainerBeacon.java.patch | 62 + .../ContainerBrewingStand.java.patch | 63 + .../inventory/ContainerChest.java.patch | 77 + .../inventory/ContainerDispenser.java.patch | 65 + .../inventory/ContainerEnchantment.java.patch | 208 ++ .../inventory/ContainerFurnace.java.patch | 57 + .../inventory/ContainerHopper.java.patch | 51 + .../inventory/ContainerMerchant.java.patch | 11 + .../inventory/ContainerPlayer.java.patch | 82 + .../inventory/ContainerRepair.java.patch | 71 + .../inventory/ContainerWorkbench.java.patch | 92 + .../minecraft/inventory/IInventory.java.patch | 32 + .../inventory/InventoryBasic.java.patch | 57 + .../inventory/InventoryCraftResult.java.patch | 53 + .../inventory/InventoryCrafting.java.patch | 81 + .../inventory/InventoryEnderChest.java.patch | 64 + .../inventory/InventoryLargeChest.java.patch | 76 + .../inventory/InventoryMerchant.java.patch | 65 + .../net/minecraft/inventory/Slot.java.patch | 11 + .../inventory/SlotFurnace.java.patch | 36 + patches/net/minecraft/item/Item.java.patch | 38 + .../net/minecraft/item/ItemBoat.java.patch | 19 + patches/net/minecraft/item/ItemBow.java.patch | 33 + .../net/minecraft/item/ItemBucket.java.patch | 133 ++ patches/net/minecraft/item/ItemDye.java.patch | 30 + .../minecraft/item/ItemEmptyMap.java.patch | 10 + .../minecraft/item/ItemFireball.java.patch | 21 + .../minecraft/item/ItemFishingRod.java.patch | 35 + .../item/ItemFlintAndSteel.java.patch | 51 + .../item/ItemHangingEntity.java.patch | 44 + .../net/minecraft/item/ItemLead.java.patch | 38 + .../net/minecraft/item/ItemLilyPad.java.patch | 36 + patches/net/minecraft/item/ItemMap.java.patch | 36 + .../minecraft/item/ItemMinecart.java.patch | 18 + .../item/ItemMonsterPlacer.java.patch | 20 + .../net/minecraft/item/ItemShears.java.patch | 28 + .../net/minecraft/item/ItemStack.java.patch | 227 ++ .../item/crafting/CraftingManager.java.patch | 104 + .../item/crafting/FurnaceRecipes.java.patch | 62 + .../item/crafting/IRecipe.java.patch | 9 + .../crafting/RecipeBookCloning.java.patch | 21 + .../item/crafting/RecipeFireworks.java.patch | 22 + .../item/crafting/RecipesArmorDyes.java.patch | 21 + .../crafting/RecipesMapCloning.java.patch | 21 + .../item/crafting/ShapedRecipes.java.patch | 92 + .../item/crafting/ShapelessRecipes.java.patch | 40 + .../network/NetHandlerPlayServer.java.patch | 1940 +++++++++++++++++ .../network/NetworkManager.java.patch | 102 + .../network/NetworkSystem.java.patch | 17 + .../net/minecraft/network/Packet.java.patch | 10 + .../minecraft/network/PacketBuffer.java.patch | 11 + .../handshake/client/C00Handshake.java.patch | 22 + .../client/C01PacketChatMessage.java.patch | 14 + .../play/client/C03PacketPlayer.java.patch | 28 + .../client/C0DPacketCloseWindow.java.patch | 16 + .../client/C17PacketCustomPayload.java.patch | 11 + .../server/S05PacketSpawnPosition.java.patch | 15 + .../play/server/S21PacketChunkData.java.patch | 54 + .../server/S26PacketMapChunkBulk.java.patch | 117 + .../network/rcon/RConConsoleSource.java.patch | 16 + .../net/minecraft/potion/Potion.java.patch | 79 + .../scoreboard/ServerScoreboard.java.patch | 138 ++ .../server/MinecraftServer.java.patch | 1192 ++++++++++ .../dedicated/DedicatedServer.java.patch | 249 +++ .../dedicated/PropertyManager.java.patch | 98 + .../integrated/IntegratedServer.java.patch | 60 + .../server/management/BanEntry.java.patch | 33 + .../management/ItemInWorldManager.java.patch | 298 +++ .../management/PlayerManager.java.patch | 132 ++ .../ServerConfigurationManager.java.patch | 1052 +++++++++ .../server/management/UserList.java.patch | 15 + .../management/UserListEntry.java.patch | 11 + .../server/management/UserListOps.java.patch | 10 + .../network/NetHandlerHandshakeTCP.java.patch | 122 ++ .../network/NetHandlerLoginServer.java.patch | 239 ++ .../network/NetHandlerStatusServer.java.patch | 61 + .../minecraft/stats/StatFileWriter.java.patch | 15 + .../tileentity/MobSpawnerBaseLogic.java.patch | 46 + .../tileentity/TileEntity.java.patch | 61 + .../tileentity/TileEntityBeacon.java.patch | 59 + .../TileEntityBrewingStand.java.patch | 109 + .../tileentity/TileEntityChest.java.patch | 123 ++ .../TileEntityCommandBlock.java.patch | 58 + .../TileEntityComparator.java.patch | 15 + .../tileentity/TileEntityDispenser.java.patch | 87 + .../tileentity/TileEntityDropper.java.patch | 15 + .../tileentity/TileEntityEndPortal.java.patch | 15 + .../tileentity/TileEntityFlowerPot.java.patch | 15 + .../tileentity/TileEntityFurnace.java.patch | 219 ++ .../tileentity/TileEntityHopper.java.patch | 245 +++ .../tileentity/TileEntityNote.java.patch | 27 + .../tileentity/TileEntityPiston.java.patch | 14 + .../tileentity/TileEntitySign.java.patch | 59 + .../tileentity/TileEntitySkull.java.patch | 31 + .../EntityDamageSourceIndirect.java.patch | 14 + .../net/minecraft/util/FoodStats.java.patch | 85 + .../net/minecraft/util/IntHashMap.java.patch | 29 + .../util/RegistryNamespaced.java.patch | 36 + .../util/WeightedRandomFishable.java.patch | 17 + .../net/minecraft/village/Village.java.patch | 11 + .../minecraft/village/VillageSiege.java.patch | 11 + .../net/minecraft/world/Explosion.java.patch | 117 + .../minecraft/world/SpawnerAnimals.java.patch | 130 ++ .../net/minecraft/world/Teleporter.java.patch | 838 +++++++ patches/net/minecraft/world/World.java.patch | 1282 +++++++++++ .../minecraft/world/WorldManager.java.patch | 11 + .../minecraft/world/WorldServer.java.patch | 607 ++++++ .../world/WorldServerMulti.java.patch | 36 + .../net/minecraft/world/WorldType.java.patch | 23 + .../world/biome/BiomeDecorator.java.patch | 164 ++ .../minecraft/world/chunk/Chunk.java.patch | 266 +++ .../world/chunk/NibbleArray.java.patch | 233 ++ .../chunk/storage/AnvilChunkLoader.java.patch | 228 ++ .../chunk/storage/AnvilSaveHandler.java.patch | 25 + .../chunk/storage/ChunkLoader.java.patch | 17 + .../storage/ExtendedBlockStorage.java.patch | 217 ++ .../chunk/storage/RegionFileCache.java.patch | 11 + .../world/gen/ChunkProviderServer.java.patch | 465 ++++ .../gen/feature/WorldGenShrub.java.patch | 16 + .../gen/structure/MapGenStronghold.java.patch | 21 + .../gen/structure/MapGenStructure.java.patch | 21 + .../gen/structure/StructureStart.java.patch | 12 + .../world/storage/ISaveHandler.java.patch | 9 + .../world/storage/MapData.java.patch | 116 + .../world/storage/SaveHandler.java.patch | 233 ++ .../world/storage/SaveHandlerMP.java.patch | 24 + .../world/storage/WorldInfo.java.patch | 48 + .../common/DimensionManager.java.patch | 376 ++++ .../common/ForgeHooks.java.patch | 45 + .../common/ForgeVersion.java.patch | 11 + .../WorldSpecificSaveHandler.java.patch | 22 + .../common/chunkio/ChunkIOProvider.java.patch | 34 + .../network/ForgeNetworkHandler.java.patch | 12 + .../common/util/EnumHelper.java.patch | 195 ++ .../common/util/FakePlayerFactory.java.patch | 31 + .../entity/living/LivingSpawnEvent.java.patch | 18 + .../event/world/BlockEvent.java.patch | 39 + .../oredict/OreDictionary.java.patch | 20 + .../oredict/ShapedOreRecipe.java.patch | 51 + .../oredict/ShapelessOreRecipe.java.patch | 49 + patches/org/bukkit/Bukkit.java.patch | 10 + patches/org/bukkit/Effect.java.patch | 259 +++ patches/org/bukkit/GameMode.java.patch | 16 + patches/org/bukkit/Material.java.patch | 272 +++ patches/org/bukkit/World.java.patch | 72 + patches/org/bukkit/command/Command.java.patch | 26 + .../command/SimpleCommandMap.java.patch | 18 + .../defaults/GameModeCommand.java.patch | 11 + .../defaults/PluginsCommand.java.patch | 15 + .../command/defaults/ReloadCommand.java.patch | 28 + .../command/defaults/TellCommand.java.patch | 19 + .../defaults/TestForCommand.java.patch | 19 + .../defaults/TimingsCommand.java.patch | 160 ++ .../conversations/BooleanPrompt.java.patch | 17 + .../conversations/Conversation.java.patch | 23 + patches/org/bukkit/entity/Arrow.java.patch | 25 + patches/org/bukkit/entity/Entity.java.patch | 25 + patches/org/bukkit/entity/Player.java.patch | 80 + .../EntityDamageByBlockEvent.java.patch | 21 + .../EntityDamageByEntityEvent.java.patch | 21 + .../event/entity/EntityDamageEvent.java.patch | 85 + .../event/player/PlayerLoginEvent.java.patch | 66 + .../player/PlayerTeleportEvent.java.patch | 17 + .../plugin/SimplePluginManager.java.patch | 31 + .../plugin/SimpleServicesManager.java.patch | 12 + .../plugin/TimedRegisteredListener.java.patch | 51 + .../plugin/java/JavaPluginLoader.java.patch | 233 ++ .../plugin/java/PluginClassLoader.java.patch | 486 +++++ .../plugin/messaging/Messenger.java.patch | 11 + .../messaging/StandardMessenger.java.patch | 19 + .../bukkit/potion/PotionEffectType.java.patch | 57 + settings.gradle | 1 + src/main/guava10.zip | Bin 0 -> 1563660 bytes src/main/java/jline/AnsiWindowsTerminal.java | 91 + .../jline/internal/TerminalLineSettings.java | 227 ++ .../EntityMinecartCommandBlockListener.java | 51 + .../ContainerEnchantTableInventory.java | 75 + .../inventory/ContainerRepairInventory.java | 65 + .../network/ThreadPlayerLookupUUID.java | 142 ++ .../TileEntityCommandBlockListener.java | 56 + .../cauldron/CauldronHooks.java | 469 ++++ .../cauldron/CauldronUtils.java | 147 ++ .../cauldron/CompatibilityMarker.java | 5 + .../cauldron/TileEntityCache.java | 21 + .../minecraftforge/cauldron/VersionInfo.java | 109 + .../minecraftforge/cauldron/api/Cauldron.java | 29 + .../cauldron/api/CauldronApi.java | 22 + .../minecraftforge/cauldron/api/Fishing.java | 72 + .../cauldron/api/WeightedRandomFishable.java | 65 + .../api/inventory/BukkitOreDictionary.java | 78 + .../api/inventory/OreDictionaryEntry.java | 62 + .../apiimpl/CauldronPluginInterface.java | 29 + .../cauldron/apiimpl/FishingInterface.java | 81 + .../inventory/OreDictionaryInterface.java | 83 + .../cauldron/block/CraftCustomContainer.java | 27 + .../cauldron/command/CauldronCommand.java | 258 +++ .../cauldron/command/TileEntityCommand.java | 184 ++ .../cauldron/configuration/BoolSetting.java | 30 + .../configuration/CauldronConfig.java | 133 ++ .../configuration/CauldronWorldConfig.java | 18 + .../cauldron/configuration/ConfigBase.java | 175 ++ .../cauldron/configuration/IntSetting.java | 28 + .../cauldron/configuration/Setting.java | 20 + .../configuration/TileEntityConfig.java | 82 + .../configuration/TileEntityWorldConfig.java | 9 + .../cauldron/configuration/WorldConfig.java | 82 + .../cauldron/entity/CraftCustomEntity.java | 40 + .../inventory/CraftCustomInventory.java | 14 + .../inventory/CraftCustomInventoryView.java | 17 + .../cauldron/inventory/CustomModRecipe.java | 26 + .../log4j/core/appender/ConsoleAppender.java | 245 +++ .../java/org/bukkit/craftbukkit/CraftArt.java | 73 + .../org/bukkit/craftbukkit/CraftChunk.java | 346 +++ .../craftbukkit/CraftChunkSnapshot.java | 96 + .../bukkit/craftbukkit/CraftCrashReport.java | 40 + .../org/bukkit/craftbukkit/CraftEffect.java | 63 + .../bukkit/craftbukkit/CraftIpBanEntry.java | 86 + .../bukkit/craftbukkit/CraftIpBanList.java | 77 + .../craftbukkit/CraftOfflinePlayer.java | 268 +++ .../craftbukkit/CraftProfileBanEntry.java | 88 + .../craftbukkit/CraftProfileBanList.java | 97 + .../org/bukkit/craftbukkit/CraftServer.java | 1753 +++++++++++++++ .../org/bukkit/craftbukkit/CraftSound.java | 231 ++ .../bukkit/craftbukkit/CraftStatistic.java | 142 ++ .../bukkit/craftbukkit/CraftTravelAgent.java | 76 + .../org/bukkit/craftbukkit/CraftWorld.java | 1468 +++++++++++++ .../craftbukkit/LoggerOutputStream.java | 31 + .../org/bukkit/craftbukkit/Overridden.java | 14 + .../org/bukkit/craftbukkit/SpigotTimings.java | 178 ++ .../java/org/bukkit/craftbukkit/TrigMath.java | 47 + .../bukkit/craftbukkit/block/CraftBeacon.java | 37 + .../bukkit/craftbukkit/block/CraftBlock.java | 621 ++++++ .../craftbukkit/block/CraftBlockState.java | 284 +++ .../craftbukkit/block/CraftBrewingStand.java | 41 + .../bukkit/craftbukkit/block/CraftChest.java | 72 + .../craftbukkit/block/CraftCommandBlock.java | 49 + .../block/CraftCreatureSpawner.java | 73 + .../craftbukkit/block/CraftDispenser.java | 64 + .../craftbukkit/block/CraftDropper.java | 49 + .../craftbukkit/block/CraftFurnace.java | 49 + .../bukkit/craftbukkit/block/CraftHopper.java | 33 + .../craftbukkit/block/CraftJukebox.java | 60 + .../craftbukkit/block/CraftNoteBlock.java | 74 + .../bukkit/craftbukkit/block/CraftSign.java | 64 + .../bukkit/craftbukkit/block/CraftSkull.java | 205 ++ .../command/ColouredConsoleSender.java | 74 + .../command/ConsoleCommandCompleter.java | 47 + .../command/CraftBlockCommandSender.java | 45 + .../command/CraftConsoleCommandSender.java | 66 + .../CraftRemoteConsoleCommandSender.java | 37 + .../command/CraftSimpleCommandMap.java | 76 + .../craftbukkit/command/ModCustomCommand.java | 28 + .../command/ServerCommandSender.java | 71 + .../command/TicksPerSecondCommand.java | 34 + .../command/VanillaCommandWrapper.java | 180 ++ .../conversations/ConversationTracker.java | 69 + .../enchantments/CraftEnchantment.java | 188 ++ .../entity/AbstractProjectile.java | 23 + .../craftbukkit/entity/CraftAgeable.java | 67 + .../craftbukkit/entity/CraftAmbient.java | 31 + .../craftbukkit/entity/CraftAnimals.java | 22 + .../bukkit/craftbukkit/entity/CraftArrow.java | 96 + .../bukkit/craftbukkit/entity/CraftBat.java | 36 + .../bukkit/craftbukkit/entity/CraftBlaze.java | 27 + .../bukkit/craftbukkit/entity/CraftBoat.java | 63 + .../craftbukkit/entity/CraftCaveSpider.java | 27 + .../craftbukkit/entity/CraftChicken.java | 28 + .../entity/CraftComplexLivingEntity.java | 22 + .../craftbukkit/entity/CraftComplexPart.java | 50 + .../bukkit/craftbukkit/entity/CraftCow.java | 28 + .../craftbukkit/entity/CraftCreature.java | 40 + .../craftbukkit/entity/CraftCreeper.java | 54 + .../bukkit/craftbukkit/entity/CraftEgg.java | 26 + .../craftbukkit/entity/CraftEnderCrystal.java | 26 + .../craftbukkit/entity/CraftEnderDragon.java | 44 + .../entity/CraftEnderDragonPart.java | 87 + .../craftbukkit/entity/CraftEnderPearl.java | 26 + .../craftbukkit/entity/CraftEnderSignal.java | 26 + .../craftbukkit/entity/CraftEnderman.java | 38 + .../craftbukkit/entity/CraftEntity.java | 626 ++++++ .../entity/CraftExperienceOrb.java | 34 + .../craftbukkit/entity/CraftFallingSand.java | 50 + .../craftbukkit/entity/CraftFireball.java | 89 + .../craftbukkit/entity/CraftFirework.java | 74 + .../bukkit/craftbukkit/entity/CraftFish.java | 75 + .../craftbukkit/entity/CraftFlying.java | 22 + .../bukkit/craftbukkit/entity/CraftGhast.java | 28 + .../bukkit/craftbukkit/entity/CraftGiant.java | 28 + .../bukkit/craftbukkit/entity/CraftGolem.java | 21 + .../craftbukkit/entity/CraftHanging.java | 82 + .../bukkit/craftbukkit/entity/CraftHorse.java | 146 ++ .../craftbukkit/entity/CraftHumanEntity.java | 327 +++ .../craftbukkit/entity/CraftIronGolem.java | 34 + .../bukkit/craftbukkit/entity/CraftItem.java | 46 + .../craftbukkit/entity/CraftItemFrame.java | 97 + .../entity/CraftLargeFireball.java | 31 + .../bukkit/craftbukkit/entity/CraftLeash.java | 26 + .../entity/CraftLightningStrike.java | 29 + .../craftbukkit/entity/CraftLivingEntity.java | 506 +++++ .../craftbukkit/entity/CraftMagmaCube.java | 26 + .../craftbukkit/entity/CraftMinecart.java | 76 + .../entity/CraftMinecartChest.java | 31 + .../entity/CraftMinecartCommand.java | 126 ++ .../entity/CraftMinecartFurnace.java | 22 + .../entity/CraftMinecartHopper.java | 30 + .../entity/CraftMinecartMobSpawner.java | 21 + .../entity/CraftMinecartRideable.java | 21 + .../craftbukkit/entity/CraftMinecartTNT.java | 21 + .../craftbukkit/entity/CraftMonster.java | 22 + .../craftbukkit/entity/CraftMushroomCow.java | 26 + .../craftbukkit/entity/CraftOcelot.java | 31 + .../craftbukkit/entity/CraftPainting.java | 78 + .../bukkit/craftbukkit/entity/CraftPig.java | 33 + .../craftbukkit/entity/CraftPigZombie.java | 43 + .../craftbukkit/entity/CraftPlayer.java | 1343 ++++++++++++ .../craftbukkit/entity/CraftProjectile.java | 67 + .../bukkit/craftbukkit/entity/CraftSheep.java | 43 + .../craftbukkit/entity/CraftSilverfish.java | 26 + .../craftbukkit/entity/CraftSkeleton.java | 37 + .../bukkit/craftbukkit/entity/CraftSlime.java | 35 + .../entity/CraftSmallFireball.java | 25 + .../craftbukkit/entity/CraftSnowball.java | 25 + .../craftbukkit/entity/CraftSnowman.java | 25 + .../craftbukkit/entity/CraftSpider.java | 27 + .../bukkit/craftbukkit/entity/CraftSquid.java | 27 + .../craftbukkit/entity/CraftTNTPrimed.java | 66 + .../entity/CraftTameableAnimal.java | 83 + .../entity/CraftThrownExpBottle.java | 25 + .../craftbukkit/entity/CraftThrownPotion.java | 57 + .../craftbukkit/entity/CraftVehicle.java | 15 + .../craftbukkit/entity/CraftVillager.java | 35 + .../craftbukkit/entity/CraftWaterMob.java | 22 + .../craftbukkit/entity/CraftWeather.java | 25 + .../bukkit/craftbukkit/entity/CraftWitch.java | 25 + .../craftbukkit/entity/CraftWither.java | 25 + .../craftbukkit/entity/CraftWitherSkull.java | 35 + .../bukkit/craftbukkit/entity/CraftWolf.java | 38 + .../craftbukkit/entity/CraftZombie.java | 43 + .../craftbukkit/event/CraftEventFactory.java | 1009 +++++++++ .../generator/CustomChunkGenerator.java | 250 +++ .../generator/InternalChunkGenerator.java | 7 + .../generator/NetherChunkGenerator.java | 11 + .../generator/NormalChunkGenerator.java | 118 + .../generator/SkyLandsChunkGenerator.java | 11 + .../help/CommandAliasHelpTopic.java | 46 + .../craftbukkit/help/CustomHelpTopic.java | 31 + .../help/CustomIndexHelpTopic.java | 40 + .../craftbukkit/help/HelpTopicAmendment.java | 50 + .../craftbukkit/help/HelpYamlReader.java | 119 + .../help/MultipleCommandAliasHelpTopic.java | 54 + .../MultipleCommandAliasHelpTopicFactory.java | 15 + .../craftbukkit/help/SimpleHelpMap.java | 219 ++ .../craftbukkit/inventory/CraftContainer.java | 314 +++ .../inventory/CraftEntityEquipment.java | 143 ++ .../inventory/CraftFurnaceRecipe.java | 26 + .../craftbukkit/inventory/CraftInventory.java | 494 +++++ .../inventory/CraftInventoryAnvil.java | 46 + .../inventory/CraftInventoryBeacon.java | 18 + .../inventory/CraftInventoryBrewer.java | 25 + .../inventory/CraftInventoryCrafting.java | 145 ++ .../inventory/CraftInventoryCustom.java | 160 ++ .../inventory/CraftInventoryDoubleChest.java | 59 + .../inventory/CraftInventoryEnchanting.java | 24 + .../inventory/CraftInventoryFurnace.java | 41 + .../inventory/CraftInventoryHorse.java | 27 + .../inventory/CraftInventoryMerchant.java | 9 + .../inventory/CraftInventoryPlayer.java | 171 ++ .../inventory/CraftInventoryView.java | 142 ++ .../inventory/CraftItemFactory.java | 142 ++ .../craftbukkit/inventory/CraftItemStack.java | 414 ++++ .../craftbukkit/inventory/CraftMetaBook.java | 259 +++ .../inventory/CraftMetaCharge.java | 127 ++ .../inventory/CraftMetaEnchantedBook.java | 167 ++ .../inventory/CraftMetaFirework.java | 384 ++++ .../craftbukkit/inventory/CraftMetaItem.java | 661 ++++++ .../inventory/CraftMetaLeatherArmor.java | 133 ++ .../craftbukkit/inventory/CraftMetaMap.java | 134 ++ .../inventory/CraftMetaPotion.java | 253 +++ .../craftbukkit/inventory/CraftMetaSkull.java | 142 ++ .../craftbukkit/inventory/CraftRecipe.java | 7 + .../inventory/CraftShapedRecipe.java | 63 + .../inventory/CraftShapelessRecipe.java | 46 + .../inventory/InventoryIterator.java | 64 + .../craftbukkit/inventory/RecipeIterator.java | 60 + .../craftbukkit/map/CraftMapCanvas.java | 110 + .../craftbukkit/map/CraftMapRenderer.java | 47 + .../bukkit/craftbukkit/map/CraftMapView.java | 162 ++ .../bukkit/craftbukkit/map/RenderData.java | 16 + .../metadata/BlockMetadataStore.java | 94 + .../metadata/EntityMetadataStore.java | 23 + .../metadata/PlayerMetadataStore.java | 23 + .../metadata/WorldMetadataStore.java | 22 + .../craftbukkit/potion/CraftPotionBrewer.java | 46 + .../potion/CraftPotionEffectType.java | 81 + .../CraftBlockProjectileSource.java | 124 ++ .../scheduler/CraftAsyncDebugger.java | 37 + .../craftbukkit/scheduler/CraftAsyncTask.java | 109 + .../craftbukkit/scheduler/CraftFuture.java | 108 + .../craftbukkit/scheduler/CraftScheduler.java | 436 ++++ .../craftbukkit/scheduler/CraftTask.java | 123 ++ .../craftbukkit/scoreboard/CraftCriteria.java | 66 + .../scoreboard/CraftObjective.java | 109 + .../craftbukkit/scoreboard/CraftScore.java | 59 + .../scoreboard/CraftScoreboard.java | 156 ++ .../scoreboard/CraftScoreboardComponent.java | 27 + .../scoreboard/CraftScoreboardManager.java | 109 + .../CraftScoreboardTranslations.java | 25 + .../craftbukkit/scoreboard/CraftTeam.java | 144 ++ .../craftbukkit/updater/ArtifactDetails.java | 128 ++ .../craftbukkit/updater/AutoUpdater.java | 127 ++ .../updater/BukkitDLUpdaterService.java | 102 + .../util/AsynchronousExecutor.java | 359 +++ .../util/BlockStateListPopulator.java | 58 + .../craftbukkit/util/CraftChatMessage.java | 121 + .../craftbukkit/util/CraftDamageSource.java | 30 + .../craftbukkit/util/CraftIconCache.java | 11 + .../craftbukkit/util/CraftMagicNumbers.java | 134 ++ .../craftbukkit/util/DatFileFilter.java | 10 + .../craftbukkit/util/ForwardLogHandler.java | 52 + .../bukkit/craftbukkit/util/Java15Compat.java | 34 + .../bukkit/craftbukkit/util/LazyHashSet.java | 98 + .../craftbukkit/util/LazyPlayerSet.java | 23 + .../org/bukkit/craftbukkit/util/LongHash.java | 15 + .../bukkit/craftbukkit/util/LongHashSet.java | 332 +++ .../craftbukkit/util/LongObjectHashMap.java | 439 ++++ .../craftbukkit/util/MojangNameLookup.java | 63 + .../util/ServerShutdownThread.java | 26 + .../util/ShortConsoleLogFormatter.java | 60 + .../util/StructureGrowDelegate.java | 67 + .../util/TerminalConsoleWriterThread.java | 52 + .../bukkit/craftbukkit/util/UnsafeList.java | 277 +++ .../bukkit/craftbukkit/util/Versioning.java | 32 + .../org/bukkit/craftbukkit/util/Waitable.java | 46 + .../craftbukkit/util/WeakCollection.java | 169 ++ .../event/player/PlayerItemDamageEvent.java | 54 + .../java/org/spigotmc/ActivationRange.java | 327 +++ src/main/java/org/spigotmc/AntiXray.java | 186 ++ .../org/spigotmc/CustomTimingsHandler.java | 165 ++ src/main/java/org/spigotmc/FlatMap.java | 64 + src/main/java/org/spigotmc/Metrics.java | 644 ++++++ .../java/org/spigotmc/RestartCommand.java | 109 + src/main/java/org/spigotmc/SpigotConfig.java | 270 +++ .../java/org/spigotmc/SpigotWorldConfig.java | 281 +++ .../org/spigotmc/TicksPerSecondCommand.java | 44 + src/main/java/org/spigotmc/TrackingRange.java | 51 + .../org/spigotmc/VanillaCommandWrapper.java | 186 ++ .../java/org/spigotmc/WatchdogThread.java | 220 ++ .../event/entity/EntityDismountEvent.java | 39 + .../event/entity/EntityMountEvent.java | 52 + src/main/mappings.zip | Bin 0 -> 2073988 bytes src/main/resources/configurations/bukkit.yml | 54 + .../resources/configurations/commands.yml | 17 + src/main/resources/configurations/help.yml | 55 + src/main/resources/fmlversion.properties | 6 + src/main/resources/log4j2.xml | 62 + 611 files changed, 64826 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 .gitmodules create mode 100644 LGPL.txt create mode 100644 LICENCE.txt create mode 100644 README.md create mode 100644 build.gradle create mode 100644 eclipse-workspace-dev.zip create mode 100644 gradlew create mode 100644 gradlew.bat create mode 100644 jsons/1.7.10-dev.json create mode 100644 jsons/1.7.10-rel.json create mode 100644 jsons/1.7.10.json create mode 100644 patches/cpw/mods/fml/common/FMLCommonHandler.java.patch create mode 100644 patches/cpw/mods/fml/common/asm/FMLSanityChecker.java.patch create mode 100644 patches/cpw/mods/fml/common/asm/transformers/SideTransformer.java.patch create mode 100644 patches/cpw/mods/fml/common/event/FMLServerStartingEvent.java.patch create mode 100644 patches/cpw/mods/fml/common/network/handshake/ChannelRegistrationHandler.java.patch create mode 100644 patches/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java.patch create mode 100644 patches/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java.patch create mode 100644 patches/cpw/mods/fml/common/network/internal/HandshakeCompletionHandler.java.patch create mode 100644 patches/cpw/mods/fml/common/registry/EntityRegistry.java.patch create mode 100644 patches/cpw/mods/fml/common/registry/GameData.java.patch create mode 100644 patches/cpw/mods/fml/common/registry/GameRegistry.java.patch create mode 100644 patches/cpw/mods/fml/relauncher/CoreModManager.java.patch create mode 100644 patches/net/minecraft/block/Block.java.patch create mode 100644 patches/net/minecraft/block/BlockBasePressurePlate.java.patch create mode 100644 patches/net/minecraft/block/BlockButton.java.patch create mode 100644 patches/net/minecraft/block/BlockCactus.java.patch create mode 100644 patches/net/minecraft/block/BlockCake.java.patch create mode 100644 patches/net/minecraft/block/BlockCocoa.java.patch create mode 100644 patches/net/minecraft/block/BlockCommandBlock.java.patch create mode 100644 patches/net/minecraft/block/BlockCrops.java.patch create mode 100644 patches/net/minecraft/block/BlockDaylightDetector.java.patch create mode 100644 patches/net/minecraft/block/BlockDispenser.java.patch create mode 100644 patches/net/minecraft/block/BlockDoor.java.patch create mode 100644 patches/net/minecraft/block/BlockDragonEgg.java.patch create mode 100644 patches/net/minecraft/block/BlockDropper.java.patch create mode 100644 patches/net/minecraft/block/BlockDynamicLiquid.java.patch create mode 100644 patches/net/minecraft/block/BlockEndPortal.java.patch create mode 100644 patches/net/minecraft/block/BlockFarmland.java.patch create mode 100644 patches/net/minecraft/block/BlockFire.java.patch create mode 100644 patches/net/minecraft/block/BlockGrass.java.patch create mode 100644 patches/net/minecraft/block/BlockHopper.java.patch create mode 100644 patches/net/minecraft/block/BlockIce.java.patch create mode 100644 patches/net/minecraft/block/BlockJukebox.java.patch create mode 100644 patches/net/minecraft/block/BlockLeaves.java.patch create mode 100644 patches/net/minecraft/block/BlockLever.java.patch create mode 100644 patches/net/minecraft/block/BlockMushroom.java.patch create mode 100644 patches/net/minecraft/block/BlockMycelium.java.patch create mode 100644 patches/net/minecraft/block/BlockNetherWart.java.patch create mode 100644 patches/net/minecraft/block/BlockNetherrack.java.patch create mode 100644 patches/net/minecraft/block/BlockPistonBase.java.patch create mode 100644 patches/net/minecraft/block/BlockPistonExtension.java.patch create mode 100644 patches/net/minecraft/block/BlockPortal.java.patch create mode 100644 patches/net/minecraft/block/BlockPressurePlate.java.patch create mode 100644 patches/net/minecraft/block/BlockPressurePlateWeighted.java.patch create mode 100644 patches/net/minecraft/block/BlockPumpkin.java.patch create mode 100644 patches/net/minecraft/block/BlockRailDetector.java.patch create mode 100644 patches/net/minecraft/block/BlockRedstoneDiode.java.patch create mode 100644 patches/net/minecraft/block/BlockRedstoneLight.java.patch create mode 100644 patches/net/minecraft/block/BlockRedstoneOre.java.patch create mode 100644 patches/net/minecraft/block/BlockRedstoneTorch.java.patch create mode 100644 patches/net/minecraft/block/BlockRedstoneWire.java.patch create mode 100644 patches/net/minecraft/block/BlockReed.java.patch create mode 100644 patches/net/minecraft/block/BlockSapling.java.patch create mode 100644 patches/net/minecraft/block/BlockSign.java.patch create mode 100644 patches/net/minecraft/block/BlockSkull.java.patch create mode 100644 patches/net/minecraft/block/BlockSnow.java.patch create mode 100644 patches/net/minecraft/block/BlockStaticLiquid.java.patch create mode 100644 patches/net/minecraft/block/BlockStem.java.patch create mode 100644 patches/net/minecraft/block/BlockTrapDoor.java.patch create mode 100644 patches/net/minecraft/block/BlockTripWire.java.patch create mode 100644 patches/net/minecraft/block/BlockTripWireHook.java.patch create mode 100644 patches/net/minecraft/block/BlockVine.java.patch create mode 100644 patches/net/minecraft/client/Minecraft.java.patch create mode 100644 patches/net/minecraft/command/CommandHandler.java.patch create mode 100644 patches/net/minecraft/command/PlayerSelector.java.patch create mode 100644 patches/net/minecraft/command/ServerCommandManager.java.patch create mode 100644 patches/net/minecraft/command/server/CommandBlockLogic.java.patch create mode 100644 patches/net/minecraft/dispenser/BehaviorDefaultDispenseItem.java.patch create mode 100644 patches/net/minecraft/dispenser/BehaviorProjectileDispense.java.patch create mode 100644 patches/net/minecraft/enchantment/Enchantment.java.patch create mode 100644 patches/net/minecraft/entity/Entity.java.patch create mode 100644 patches/net/minecraft/entity/EntityAgeable.java.patch create mode 100644 patches/net/minecraft/entity/EntityCreature.java.patch create mode 100644 patches/net/minecraft/entity/EntityHanging.java.patch create mode 100644 patches/net/minecraft/entity/EntityLeashKnot.java.patch create mode 100644 patches/net/minecraft/entity/EntityLiving.java.patch create mode 100644 patches/net/minecraft/entity/EntityLivingBase.java.patch create mode 100644 patches/net/minecraft/entity/EntityMinecartCommandBlock.java.patch create mode 100644 patches/net/minecraft/entity/EntityTracker.java.patch create mode 100644 patches/net/minecraft/entity/EntityTrackerEntry.java.patch create mode 100644 patches/net/minecraft/entity/ai/EntityAIArrowAttack.java.patch create mode 100644 patches/net/minecraft/entity/ai/EntityAIAttackOnCollide.java.patch create mode 100644 patches/net/minecraft/entity/ai/EntityAIBreakDoor.java.patch create mode 100644 patches/net/minecraft/entity/ai/EntityAIEatGrass.java.patch create mode 100644 patches/net/minecraft/entity/ai/EntityAIMate.java.patch create mode 100644 patches/net/minecraft/entity/ai/EntityAIPanic.java.patch create mode 100644 patches/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java.patch create mode 100644 patches/net/minecraft/entity/ai/EntityAISit.java.patch create mode 100644 patches/net/minecraft/entity/ai/EntityAITarget.java.patch create mode 100644 patches/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch create mode 100644 patches/net/minecraft/entity/ai/EntityLookHelper.java.patch create mode 100644 patches/net/minecraft/entity/ai/EntityMoveHelper.java.patch create mode 100644 patches/net/minecraft/entity/boss/EntityDragon.java.patch create mode 100644 patches/net/minecraft/entity/boss/EntityWither.java.patch create mode 100644 patches/net/minecraft/entity/effect/EntityLightningBolt.java.patch create mode 100644 patches/net/minecraft/entity/item/EntityBoat.java.patch create mode 100644 patches/net/minecraft/entity/item/EntityEnderCrystal.java.patch create mode 100644 patches/net/minecraft/entity/item/EntityEnderPearl.java.patch create mode 100644 patches/net/minecraft/entity/item/EntityExpBottle.java.patch create mode 100644 patches/net/minecraft/entity/item/EntityFallingBlock.java.patch create mode 100644 patches/net/minecraft/entity/item/EntityFireworkRocket.java.patch create mode 100644 patches/net/minecraft/entity/item/EntityItem.java.patch create mode 100644 patches/net/minecraft/entity/item/EntityItemFrame.java.patch create mode 100644 patches/net/minecraft/entity/item/EntityMinecart.java.patch create mode 100644 patches/net/minecraft/entity/item/EntityMinecartContainer.java.patch create mode 100644 patches/net/minecraft/entity/item/EntityPainting.java.patch create mode 100644 patches/net/minecraft/entity/item/EntityTNTPrimed.java.patch create mode 100644 patches/net/minecraft/entity/item/EntityXPOrb.java.patch create mode 100644 patches/net/minecraft/entity/monster/EntityCreeper.java.patch create mode 100644 patches/net/minecraft/entity/monster/EntityEnderman.java.patch create mode 100644 patches/net/minecraft/entity/monster/EntityGhast.java.patch create mode 100644 patches/net/minecraft/entity/monster/EntityMob.java.patch create mode 100644 patches/net/minecraft/entity/monster/EntityPigZombie.java.patch create mode 100644 patches/net/minecraft/entity/monster/EntitySilverfish.java.patch create mode 100644 patches/net/minecraft/entity/monster/EntitySkeleton.java.patch create mode 100644 patches/net/minecraft/entity/monster/EntitySlime.java.patch create mode 100644 patches/net/minecraft/entity/monster/EntitySnowman.java.patch create mode 100644 patches/net/minecraft/entity/monster/EntitySpider.java.patch create mode 100644 patches/net/minecraft/entity/monster/EntityZombie.java.patch create mode 100644 patches/net/minecraft/entity/passive/EntityCow.java.patch create mode 100644 patches/net/minecraft/entity/passive/EntityHorse.java.patch create mode 100644 patches/net/minecraft/entity/passive/EntityMooshroom.java.patch create mode 100644 patches/net/minecraft/entity/passive/EntityOcelot.java.patch create mode 100644 patches/net/minecraft/entity/passive/EntityPig.java.patch create mode 100644 patches/net/minecraft/entity/passive/EntitySheep.java.patch create mode 100644 patches/net/minecraft/entity/passive/EntitySquid.java.patch create mode 100644 patches/net/minecraft/entity/passive/EntityWolf.java.patch create mode 100644 patches/net/minecraft/entity/player/EntityPlayer.java.patch create mode 100644 patches/net/minecraft/entity/player/EntityPlayerMP.java.patch create mode 100644 patches/net/minecraft/entity/player/InventoryPlayer.java.patch create mode 100644 patches/net/minecraft/entity/player/PlayerCapabilities.java.patch create mode 100644 patches/net/minecraft/entity/projectile/EntityArrow.java.patch create mode 100644 patches/net/minecraft/entity/projectile/EntityEgg.java.patch create mode 100644 patches/net/minecraft/entity/projectile/EntityFireball.java.patch create mode 100644 patches/net/minecraft/entity/projectile/EntityFishHook.java.patch create mode 100644 patches/net/minecraft/entity/projectile/EntityLargeFireball.java.patch create mode 100644 patches/net/minecraft/entity/projectile/EntityPotion.java.patch create mode 100644 patches/net/minecraft/entity/projectile/EntitySmallFireball.java.patch create mode 100644 patches/net/minecraft/entity/projectile/EntityThrowable.java.patch create mode 100644 patches/net/minecraft/entity/projectile/EntityWitherSkull.java.patch create mode 100644 patches/net/minecraft/init/Bootstrap.java.patch create mode 100644 patches/net/minecraft/inventory/AnimalChest.java.patch create mode 100644 patches/net/minecraft/inventory/Container.java.patch create mode 100644 patches/net/minecraft/inventory/ContainerBeacon.java.patch create mode 100644 patches/net/minecraft/inventory/ContainerBrewingStand.java.patch create mode 100644 patches/net/minecraft/inventory/ContainerChest.java.patch create mode 100644 patches/net/minecraft/inventory/ContainerDispenser.java.patch create mode 100644 patches/net/minecraft/inventory/ContainerEnchantment.java.patch create mode 100644 patches/net/minecraft/inventory/ContainerFurnace.java.patch create mode 100644 patches/net/minecraft/inventory/ContainerHopper.java.patch create mode 100644 patches/net/minecraft/inventory/ContainerMerchant.java.patch create mode 100644 patches/net/minecraft/inventory/ContainerPlayer.java.patch create mode 100644 patches/net/minecraft/inventory/ContainerRepair.java.patch create mode 100644 patches/net/minecraft/inventory/ContainerWorkbench.java.patch create mode 100644 patches/net/minecraft/inventory/IInventory.java.patch create mode 100644 patches/net/minecraft/inventory/InventoryBasic.java.patch create mode 100644 patches/net/minecraft/inventory/InventoryCraftResult.java.patch create mode 100644 patches/net/minecraft/inventory/InventoryCrafting.java.patch create mode 100644 patches/net/minecraft/inventory/InventoryEnderChest.java.patch create mode 100644 patches/net/minecraft/inventory/InventoryLargeChest.java.patch create mode 100644 patches/net/minecraft/inventory/InventoryMerchant.java.patch create mode 100644 patches/net/minecraft/inventory/Slot.java.patch create mode 100644 patches/net/minecraft/inventory/SlotFurnace.java.patch create mode 100644 patches/net/minecraft/item/Item.java.patch create mode 100644 patches/net/minecraft/item/ItemBoat.java.patch create mode 100644 patches/net/minecraft/item/ItemBow.java.patch create mode 100644 patches/net/minecraft/item/ItemBucket.java.patch create mode 100644 patches/net/minecraft/item/ItemDye.java.patch create mode 100644 patches/net/minecraft/item/ItemEmptyMap.java.patch create mode 100644 patches/net/minecraft/item/ItemFireball.java.patch create mode 100644 patches/net/minecraft/item/ItemFishingRod.java.patch create mode 100644 patches/net/minecraft/item/ItemFlintAndSteel.java.patch create mode 100644 patches/net/minecraft/item/ItemHangingEntity.java.patch create mode 100644 patches/net/minecraft/item/ItemLead.java.patch create mode 100644 patches/net/minecraft/item/ItemLilyPad.java.patch create mode 100644 patches/net/minecraft/item/ItemMap.java.patch create mode 100644 patches/net/minecraft/item/ItemMinecart.java.patch create mode 100644 patches/net/minecraft/item/ItemMonsterPlacer.java.patch create mode 100644 patches/net/minecraft/item/ItemShears.java.patch create mode 100644 patches/net/minecraft/item/ItemStack.java.patch create mode 100644 patches/net/minecraft/item/crafting/CraftingManager.java.patch create mode 100644 patches/net/minecraft/item/crafting/FurnaceRecipes.java.patch create mode 100644 patches/net/minecraft/item/crafting/IRecipe.java.patch create mode 100644 patches/net/minecraft/item/crafting/RecipeBookCloning.java.patch create mode 100644 patches/net/minecraft/item/crafting/RecipeFireworks.java.patch create mode 100644 patches/net/minecraft/item/crafting/RecipesArmorDyes.java.patch create mode 100644 patches/net/minecraft/item/crafting/RecipesMapCloning.java.patch create mode 100644 patches/net/minecraft/item/crafting/ShapedRecipes.java.patch create mode 100644 patches/net/minecraft/item/crafting/ShapelessRecipes.java.patch create mode 100644 patches/net/minecraft/network/NetHandlerPlayServer.java.patch create mode 100644 patches/net/minecraft/network/NetworkManager.java.patch create mode 100644 patches/net/minecraft/network/NetworkSystem.java.patch create mode 100644 patches/net/minecraft/network/Packet.java.patch create mode 100644 patches/net/minecraft/network/PacketBuffer.java.patch create mode 100644 patches/net/minecraft/network/handshake/client/C00Handshake.java.patch create mode 100644 patches/net/minecraft/network/play/client/C01PacketChatMessage.java.patch create mode 100644 patches/net/minecraft/network/play/client/C03PacketPlayer.java.patch create mode 100644 patches/net/minecraft/network/play/client/C0DPacketCloseWindow.java.patch create mode 100644 patches/net/minecraft/network/play/client/C17PacketCustomPayload.java.patch create mode 100644 patches/net/minecraft/network/play/server/S05PacketSpawnPosition.java.patch create mode 100644 patches/net/minecraft/network/play/server/S21PacketChunkData.java.patch create mode 100644 patches/net/minecraft/network/play/server/S26PacketMapChunkBulk.java.patch create mode 100644 patches/net/minecraft/network/rcon/RConConsoleSource.java.patch create mode 100644 patches/net/minecraft/potion/Potion.java.patch create mode 100644 patches/net/minecraft/scoreboard/ServerScoreboard.java.patch create mode 100644 patches/net/minecraft/server/MinecraftServer.java.patch create mode 100644 patches/net/minecraft/server/dedicated/DedicatedServer.java.patch create mode 100644 patches/net/minecraft/server/dedicated/PropertyManager.java.patch create mode 100644 patches/net/minecraft/server/integrated/IntegratedServer.java.patch create mode 100644 patches/net/minecraft/server/management/BanEntry.java.patch create mode 100644 patches/net/minecraft/server/management/ItemInWorldManager.java.patch create mode 100644 patches/net/minecraft/server/management/PlayerManager.java.patch create mode 100644 patches/net/minecraft/server/management/ServerConfigurationManager.java.patch create mode 100644 patches/net/minecraft/server/management/UserList.java.patch create mode 100644 patches/net/minecraft/server/management/UserListEntry.java.patch create mode 100644 patches/net/minecraft/server/management/UserListOps.java.patch create mode 100644 patches/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch create mode 100644 patches/net/minecraft/server/network/NetHandlerLoginServer.java.patch create mode 100644 patches/net/minecraft/server/network/NetHandlerStatusServer.java.patch create mode 100644 patches/net/minecraft/stats/StatFileWriter.java.patch create mode 100644 patches/net/minecraft/tileentity/MobSpawnerBaseLogic.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntity.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntityBeacon.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntityBrewingStand.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntityChest.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntityCommandBlock.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntityComparator.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntityDispenser.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntityDropper.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntityEndPortal.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntityFlowerPot.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntityFurnace.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntityHopper.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntityNote.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntityPiston.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntitySign.java.patch create mode 100644 patches/net/minecraft/tileentity/TileEntitySkull.java.patch create mode 100644 patches/net/minecraft/util/EntityDamageSourceIndirect.java.patch create mode 100644 patches/net/minecraft/util/FoodStats.java.patch create mode 100644 patches/net/minecraft/util/IntHashMap.java.patch create mode 100644 patches/net/minecraft/util/RegistryNamespaced.java.patch create mode 100644 patches/net/minecraft/util/WeightedRandomFishable.java.patch create mode 100644 patches/net/minecraft/village/Village.java.patch create mode 100644 patches/net/minecraft/village/VillageSiege.java.patch create mode 100644 patches/net/minecraft/world/Explosion.java.patch create mode 100644 patches/net/minecraft/world/SpawnerAnimals.java.patch create mode 100644 patches/net/minecraft/world/Teleporter.java.patch create mode 100644 patches/net/minecraft/world/World.java.patch create mode 100644 patches/net/minecraft/world/WorldManager.java.patch create mode 100644 patches/net/minecraft/world/WorldServer.java.patch create mode 100644 patches/net/minecraft/world/WorldServerMulti.java.patch create mode 100644 patches/net/minecraft/world/WorldType.java.patch create mode 100644 patches/net/minecraft/world/biome/BiomeDecorator.java.patch create mode 100644 patches/net/minecraft/world/chunk/Chunk.java.patch create mode 100644 patches/net/minecraft/world/chunk/NibbleArray.java.patch create mode 100644 patches/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch create mode 100644 patches/net/minecraft/world/chunk/storage/AnvilSaveHandler.java.patch create mode 100644 patches/net/minecraft/world/chunk/storage/ChunkLoader.java.patch create mode 100644 patches/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch create mode 100644 patches/net/minecraft/world/chunk/storage/RegionFileCache.java.patch create mode 100644 patches/net/minecraft/world/gen/ChunkProviderServer.java.patch create mode 100644 patches/net/minecraft/world/gen/feature/WorldGenShrub.java.patch create mode 100644 patches/net/minecraft/world/gen/structure/MapGenStronghold.java.patch create mode 100644 patches/net/minecraft/world/gen/structure/MapGenStructure.java.patch create mode 100644 patches/net/minecraft/world/gen/structure/StructureStart.java.patch create mode 100644 patches/net/minecraft/world/storage/ISaveHandler.java.patch create mode 100644 patches/net/minecraft/world/storage/MapData.java.patch create mode 100644 patches/net/minecraft/world/storage/SaveHandler.java.patch create mode 100644 patches/net/minecraft/world/storage/SaveHandlerMP.java.patch create mode 100644 patches/net/minecraft/world/storage/WorldInfo.java.patch create mode 100644 patches/net/minecraftforge/common/DimensionManager.java.patch create mode 100644 patches/net/minecraftforge/common/ForgeHooks.java.patch create mode 100644 patches/net/minecraftforge/common/ForgeVersion.java.patch create mode 100644 patches/net/minecraftforge/common/WorldSpecificSaveHandler.java.patch create mode 100644 patches/net/minecraftforge/common/chunkio/ChunkIOProvider.java.patch create mode 100644 patches/net/minecraftforge/common/network/ForgeNetworkHandler.java.patch create mode 100644 patches/net/minecraftforge/common/util/EnumHelper.java.patch create mode 100644 patches/net/minecraftforge/common/util/FakePlayerFactory.java.patch create mode 100644 patches/net/minecraftforge/event/entity/living/LivingSpawnEvent.java.patch create mode 100644 patches/net/minecraftforge/event/world/BlockEvent.java.patch create mode 100644 patches/net/minecraftforge/oredict/OreDictionary.java.patch create mode 100644 patches/net/minecraftforge/oredict/ShapedOreRecipe.java.patch create mode 100644 patches/net/minecraftforge/oredict/ShapelessOreRecipe.java.patch create mode 100644 patches/org/bukkit/Bukkit.java.patch create mode 100644 patches/org/bukkit/Effect.java.patch create mode 100644 patches/org/bukkit/GameMode.java.patch create mode 100644 patches/org/bukkit/Material.java.patch create mode 100644 patches/org/bukkit/World.java.patch create mode 100644 patches/org/bukkit/command/Command.java.patch create mode 100644 patches/org/bukkit/command/SimpleCommandMap.java.patch create mode 100644 patches/org/bukkit/command/defaults/GameModeCommand.java.patch create mode 100644 patches/org/bukkit/command/defaults/PluginsCommand.java.patch create mode 100644 patches/org/bukkit/command/defaults/ReloadCommand.java.patch create mode 100644 patches/org/bukkit/command/defaults/TellCommand.java.patch create mode 100644 patches/org/bukkit/command/defaults/TestForCommand.java.patch create mode 100644 patches/org/bukkit/command/defaults/TimingsCommand.java.patch create mode 100644 patches/org/bukkit/conversations/BooleanPrompt.java.patch create mode 100644 patches/org/bukkit/conversations/Conversation.java.patch create mode 100644 patches/org/bukkit/entity/Arrow.java.patch create mode 100644 patches/org/bukkit/entity/Entity.java.patch create mode 100644 patches/org/bukkit/entity/Player.java.patch create mode 100644 patches/org/bukkit/event/entity/EntityDamageByBlockEvent.java.patch create mode 100644 patches/org/bukkit/event/entity/EntityDamageByEntityEvent.java.patch create mode 100644 patches/org/bukkit/event/entity/EntityDamageEvent.java.patch create mode 100644 patches/org/bukkit/event/player/PlayerLoginEvent.java.patch create mode 100644 patches/org/bukkit/event/player/PlayerTeleportEvent.java.patch create mode 100644 patches/org/bukkit/plugin/SimplePluginManager.java.patch create mode 100644 patches/org/bukkit/plugin/SimpleServicesManager.java.patch create mode 100644 patches/org/bukkit/plugin/TimedRegisteredListener.java.patch create mode 100644 patches/org/bukkit/plugin/java/JavaPluginLoader.java.patch create mode 100644 patches/org/bukkit/plugin/java/PluginClassLoader.java.patch create mode 100644 patches/org/bukkit/plugin/messaging/Messenger.java.patch create mode 100644 patches/org/bukkit/plugin/messaging/StandardMessenger.java.patch create mode 100644 patches/org/bukkit/potion/PotionEffectType.java.patch create mode 100644 settings.gradle create mode 100644 src/main/guava10.zip create mode 100644 src/main/java/jline/AnsiWindowsTerminal.java create mode 100644 src/main/java/jline/internal/TerminalLineSettings.java create mode 100644 src/main/java/net/minecraft/entity/EntityMinecartCommandBlockListener.java create mode 100644 src/main/java/net/minecraft/inventory/ContainerEnchantTableInventory.java create mode 100644 src/main/java/net/minecraft/inventory/ContainerRepairInventory.java create mode 100644 src/main/java/net/minecraft/server/network/ThreadPlayerLookupUUID.java create mode 100644 src/main/java/net/minecraft/tileentity/TileEntityCommandBlockListener.java create mode 100644 src/main/java/net/minecraftforge/cauldron/CauldronHooks.java create mode 100644 src/main/java/net/minecraftforge/cauldron/CauldronUtils.java create mode 100644 src/main/java/net/minecraftforge/cauldron/CompatibilityMarker.java create mode 100644 src/main/java/net/minecraftforge/cauldron/TileEntityCache.java create mode 100644 src/main/java/net/minecraftforge/cauldron/VersionInfo.java create mode 100644 src/main/java/net/minecraftforge/cauldron/api/Cauldron.java create mode 100644 src/main/java/net/minecraftforge/cauldron/api/CauldronApi.java create mode 100644 src/main/java/net/minecraftforge/cauldron/api/Fishing.java create mode 100644 src/main/java/net/minecraftforge/cauldron/api/WeightedRandomFishable.java create mode 100644 src/main/java/net/minecraftforge/cauldron/api/inventory/BukkitOreDictionary.java create mode 100644 src/main/java/net/minecraftforge/cauldron/api/inventory/OreDictionaryEntry.java create mode 100644 src/main/java/net/minecraftforge/cauldron/apiimpl/CauldronPluginInterface.java create mode 100644 src/main/java/net/minecraftforge/cauldron/apiimpl/FishingInterface.java create mode 100644 src/main/java/net/minecraftforge/cauldron/apiimpl/inventory/OreDictionaryInterface.java create mode 100644 src/main/java/net/minecraftforge/cauldron/block/CraftCustomContainer.java create mode 100644 src/main/java/net/minecraftforge/cauldron/command/CauldronCommand.java create mode 100644 src/main/java/net/minecraftforge/cauldron/command/TileEntityCommand.java create mode 100644 src/main/java/net/minecraftforge/cauldron/configuration/BoolSetting.java create mode 100644 src/main/java/net/minecraftforge/cauldron/configuration/CauldronConfig.java create mode 100644 src/main/java/net/minecraftforge/cauldron/configuration/CauldronWorldConfig.java create mode 100644 src/main/java/net/minecraftforge/cauldron/configuration/ConfigBase.java create mode 100644 src/main/java/net/minecraftforge/cauldron/configuration/IntSetting.java create mode 100644 src/main/java/net/minecraftforge/cauldron/configuration/Setting.java create mode 100644 src/main/java/net/minecraftforge/cauldron/configuration/TileEntityConfig.java create mode 100644 src/main/java/net/minecraftforge/cauldron/configuration/TileEntityWorldConfig.java create mode 100644 src/main/java/net/minecraftforge/cauldron/configuration/WorldConfig.java create mode 100644 src/main/java/net/minecraftforge/cauldron/entity/CraftCustomEntity.java create mode 100644 src/main/java/net/minecraftforge/cauldron/inventory/CraftCustomInventory.java create mode 100644 src/main/java/net/minecraftforge/cauldron/inventory/CraftCustomInventoryView.java create mode 100644 src/main/java/net/minecraftforge/cauldron/inventory/CustomModRecipe.java create mode 100644 src/main/java/org/apache/logging/log4j/core/appender/ConsoleAppender.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftArt.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftChunk.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftChunkSnapshot.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftCrashReport.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftEffect.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftIpBanEntry.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftIpBanList.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftOfflinePlayer.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftProfileBanEntry.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftProfileBanList.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftServer.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftSound.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftStatistic.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftTravelAgent.java create mode 100644 src/main/java/org/bukkit/craftbukkit/CraftWorld.java create mode 100644 src/main/java/org/bukkit/craftbukkit/LoggerOutputStream.java create mode 100644 src/main/java/org/bukkit/craftbukkit/Overridden.java create mode 100644 src/main/java/org/bukkit/craftbukkit/SpigotTimings.java create mode 100644 src/main/java/org/bukkit/craftbukkit/TrigMath.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftBeacon.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftBlock.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftBlockState.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftBrewingStand.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftChest.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftCommandBlock.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftCreatureSpawner.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftDispenser.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftDropper.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftFurnace.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftHopper.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftJukebox.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftNoteBlock.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftSign.java create mode 100644 src/main/java/org/bukkit/craftbukkit/block/CraftSkull.java create mode 100644 src/main/java/org/bukkit/craftbukkit/command/ColouredConsoleSender.java create mode 100644 src/main/java/org/bukkit/craftbukkit/command/ConsoleCommandCompleter.java create mode 100644 src/main/java/org/bukkit/craftbukkit/command/CraftBlockCommandSender.java create mode 100644 src/main/java/org/bukkit/craftbukkit/command/CraftConsoleCommandSender.java create mode 100644 src/main/java/org/bukkit/craftbukkit/command/CraftRemoteConsoleCommandSender.java create mode 100644 src/main/java/org/bukkit/craftbukkit/command/CraftSimpleCommandMap.java create mode 100644 src/main/java/org/bukkit/craftbukkit/command/ModCustomCommand.java create mode 100644 src/main/java/org/bukkit/craftbukkit/command/ServerCommandSender.java create mode 100644 src/main/java/org/bukkit/craftbukkit/command/TicksPerSecondCommand.java create mode 100644 src/main/java/org/bukkit/craftbukkit/command/VanillaCommandWrapper.java create mode 100644 src/main/java/org/bukkit/craftbukkit/conversations/ConversationTracker.java create mode 100644 src/main/java/org/bukkit/craftbukkit/enchantments/CraftEnchantment.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/AbstractProjectile.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftAgeable.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftAmbient.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftAnimals.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftArrow.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftBat.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftBlaze.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftBoat.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftCaveSpider.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftChicken.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftComplexLivingEntity.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftComplexPart.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftCow.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftCreature.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftCreeper.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftEgg.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftEnderCrystal.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragon.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftEnderDragonPart.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftEnderPearl.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftEnderSignal.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftEnderman.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftEntity.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftExperienceOrb.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftFallingSand.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftFireball.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftFirework.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftFish.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftFlying.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftGhast.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftGiant.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftGolem.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftHanging.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftHorse.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftHumanEntity.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftIronGolem.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftItem.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftItemFrame.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftLargeFireball.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftLeash.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftLightningStrike.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftLivingEntity.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftMagmaCube.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftMinecart.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartChest.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartCommand.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartFurnace.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartHopper.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartMobSpawner.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartRideable.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftMinecartTNT.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftMonster.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftMushroomCow.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftOcelot.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftPainting.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftPig.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftPigZombie.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftPlayer.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftProjectile.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftSheep.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftSilverfish.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftSkeleton.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftSlime.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftSmallFireball.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftSnowball.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftSnowman.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftSpider.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftSquid.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftTNTPrimed.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftTameableAnimal.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftThrownExpBottle.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftThrownPotion.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftVehicle.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftVillager.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftWaterMob.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftWeather.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftWitch.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftWither.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftWitherSkull.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftWolf.java create mode 100644 src/main/java/org/bukkit/craftbukkit/entity/CraftZombie.java create mode 100644 src/main/java/org/bukkit/craftbukkit/event/CraftEventFactory.java create mode 100644 src/main/java/org/bukkit/craftbukkit/generator/CustomChunkGenerator.java create mode 100644 src/main/java/org/bukkit/craftbukkit/generator/InternalChunkGenerator.java create mode 100644 src/main/java/org/bukkit/craftbukkit/generator/NetherChunkGenerator.java create mode 100644 src/main/java/org/bukkit/craftbukkit/generator/NormalChunkGenerator.java create mode 100644 src/main/java/org/bukkit/craftbukkit/generator/SkyLandsChunkGenerator.java create mode 100644 src/main/java/org/bukkit/craftbukkit/help/CommandAliasHelpTopic.java create mode 100644 src/main/java/org/bukkit/craftbukkit/help/CustomHelpTopic.java create mode 100644 src/main/java/org/bukkit/craftbukkit/help/CustomIndexHelpTopic.java create mode 100644 src/main/java/org/bukkit/craftbukkit/help/HelpTopicAmendment.java create mode 100644 src/main/java/org/bukkit/craftbukkit/help/HelpYamlReader.java create mode 100644 src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopic.java create mode 100644 src/main/java/org/bukkit/craftbukkit/help/MultipleCommandAliasHelpTopicFactory.java create mode 100644 src/main/java/org/bukkit/craftbukkit/help/SimpleHelpMap.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftContainer.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftEntityEquipment.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftFurnaceRecipe.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftInventory.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryAnvil.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBeacon.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryBrewer.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCrafting.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryCustom.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryDoubleChest.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryEnchanting.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryFurnace.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryHorse.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryMerchant.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryPlayer.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftInventoryView.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftItemFactory.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftItemStack.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaBook.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaCharge.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaEnchantedBook.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaFirework.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaItem.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaLeatherArmor.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaMap.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaPotion.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftMetaSkull.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftRecipe.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftShapedRecipe.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/CraftShapelessRecipe.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/InventoryIterator.java create mode 100644 src/main/java/org/bukkit/craftbukkit/inventory/RecipeIterator.java create mode 100644 src/main/java/org/bukkit/craftbukkit/map/CraftMapCanvas.java create mode 100644 src/main/java/org/bukkit/craftbukkit/map/CraftMapRenderer.java create mode 100644 src/main/java/org/bukkit/craftbukkit/map/CraftMapView.java create mode 100644 src/main/java/org/bukkit/craftbukkit/map/RenderData.java create mode 100644 src/main/java/org/bukkit/craftbukkit/metadata/BlockMetadataStore.java create mode 100644 src/main/java/org/bukkit/craftbukkit/metadata/EntityMetadataStore.java create mode 100644 src/main/java/org/bukkit/craftbukkit/metadata/PlayerMetadataStore.java create mode 100644 src/main/java/org/bukkit/craftbukkit/metadata/WorldMetadataStore.java create mode 100644 src/main/java/org/bukkit/craftbukkit/potion/CraftPotionBrewer.java create mode 100644 src/main/java/org/bukkit/craftbukkit/potion/CraftPotionEffectType.java create mode 100644 src/main/java/org/bukkit/craftbukkit/projectiles/CraftBlockProjectileSource.java create mode 100644 src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncDebugger.java create mode 100644 src/main/java/org/bukkit/craftbukkit/scheduler/CraftAsyncTask.java create mode 100644 src/main/java/org/bukkit/craftbukkit/scheduler/CraftFuture.java create mode 100644 src/main/java/org/bukkit/craftbukkit/scheduler/CraftScheduler.java create mode 100644 src/main/java/org/bukkit/craftbukkit/scheduler/CraftTask.java create mode 100644 src/main/java/org/bukkit/craftbukkit/scoreboard/CraftCriteria.java create mode 100644 src/main/java/org/bukkit/craftbukkit/scoreboard/CraftObjective.java create mode 100644 src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScore.java create mode 100644 src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboard.java create mode 100644 src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardComponent.java create mode 100644 src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardManager.java create mode 100644 src/main/java/org/bukkit/craftbukkit/scoreboard/CraftScoreboardTranslations.java create mode 100644 src/main/java/org/bukkit/craftbukkit/scoreboard/CraftTeam.java create mode 100644 src/main/java/org/bukkit/craftbukkit/updater/ArtifactDetails.java create mode 100644 src/main/java/org/bukkit/craftbukkit/updater/AutoUpdater.java create mode 100644 src/main/java/org/bukkit/craftbukkit/updater/BukkitDLUpdaterService.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/AsynchronousExecutor.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/BlockStateListPopulator.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/CraftChatMessage.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/CraftDamageSource.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/CraftIconCache.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/CraftMagicNumbers.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/DatFileFilter.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/ForwardLogHandler.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/Java15Compat.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/LazyHashSet.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/LazyPlayerSet.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/LongHash.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/LongHashSet.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/LongObjectHashMap.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/MojangNameLookup.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/ServerShutdownThread.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/ShortConsoleLogFormatter.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/StructureGrowDelegate.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/TerminalConsoleWriterThread.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/UnsafeList.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/Versioning.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/Waitable.java create mode 100644 src/main/java/org/bukkit/craftbukkit/util/WeakCollection.java create mode 100644 src/main/java/org/bukkit/event/player/PlayerItemDamageEvent.java create mode 100644 src/main/java/org/spigotmc/ActivationRange.java create mode 100644 src/main/java/org/spigotmc/AntiXray.java create mode 100644 src/main/java/org/spigotmc/CustomTimingsHandler.java create mode 100644 src/main/java/org/spigotmc/FlatMap.java create mode 100644 src/main/java/org/spigotmc/Metrics.java create mode 100644 src/main/java/org/spigotmc/RestartCommand.java create mode 100644 src/main/java/org/spigotmc/SpigotConfig.java create mode 100644 src/main/java/org/spigotmc/SpigotWorldConfig.java create mode 100644 src/main/java/org/spigotmc/TicksPerSecondCommand.java create mode 100644 src/main/java/org/spigotmc/TrackingRange.java create mode 100644 src/main/java/org/spigotmc/VanillaCommandWrapper.java create mode 100644 src/main/java/org/spigotmc/WatchdogThread.java create mode 100644 src/main/java/org/spigotmc/event/entity/EntityDismountEvent.java create mode 100644 src/main/java/org/spigotmc/event/entity/EntityMountEvent.java create mode 100644 src/main/mappings.zip create mode 100644 src/main/resources/configurations/bukkit.yml create mode 100644 src/main/resources/configurations/commands.yml create mode 100644 src/main/resources/configurations/help.yml create mode 100644 src/main/resources/fmlversion.properties create mode 100644 src/main/resources/log4j2.xml diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..c1f84a0 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,12 @@ +* text eol=lf +*.bat text eol=crlf +*.patch text eol=lf +*.cfg text eol=lf +*.py text eol=lf +*.png binary +*.exe binary +*.dll binary +*.zip binary +*.pyd binary +*.jar binary +*.lzma binary \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..56b3125 --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +!.gitignore + +# eclipse +/eclipse + +# gradle +build +.gradle + +*.DS_Store diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..92f7dd2 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,7 @@ +[submodule "bukkit"] + path = bukkit + url = https://github.com/gamerforEA/Bukkit.git +[submodule "forge"] + path = forge + url = https://github.com/gamerforEA/MinecraftForge.git + branch = 1.7.10 diff --git a/LGPL.txt b/LGPL.txt new file mode 100644 index 0000000..65c5ca8 --- /dev/null +++ b/LGPL.txt @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. diff --git a/LICENCE.txt b/LICENCE.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/LICENCE.txt @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/README.md b/README.md new file mode 100644 index 0000000..88b1cb5 --- /dev/null +++ b/README.md @@ -0,0 +1,92 @@ +Cauldron +=========== +Note: 1.7.2 repository has been moved to [branch v172](https://github.com/MinecraftPortCentral/Cauldron/tree/v172) + +A Forge/Bukkit/Spigot Minecraft Server + +Compilation +----------- + +We use Gradle to handle our dependencies. + +1. Checkout project. +2. Init submodules : git submodule update --init --recursive -- depth 1 +3. Setup workspace : gradlew setupCauldron +4. Build binaries : gradlew buildPackages +Note: all binaries will be in distributions folder + +Supporting Cauldron +-------- +Click here to [Donate to bloodmc](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=YNCKCALNQKFAS) +Click here to [Become a Patreon] (http://www.patreon.com/bloodmc) + +Top Patron Supporters +----------- + +* isiliden +* eonic +* trab +* jamescowens +* SFTMedia +* Shmeeb + + +Profiling +--------- + +We use YourKit as our Java Profiler. + +YourKit is kindly supporting open source projects with its full-featured Java Profiler. +YourKit, LLC is the creator of innovative and intelligent tools for profiling +Java and .NET applications. Take a look at YourKit's leading software products: +* [YourKit Java Profiler](http://www.yourkit.com/java/profiler/index.jsp) +* [YourKit .NET Profiler](http://www.yourkit.com/.net/profiler/index.jsp) + + +Coding and Pull Request Conventions +----------- + +* We generally follow the Sun/Oracle coding standards. +* No tabs; use 4 spaces instead. +* No trailing whitespaces. +* No CRLF line endings, LF only; will be converted automatically by git +* No 80 column limit or 'weird' midstatement newlines. +* The number of commits in a pull request should be kept to a minimum (squish them into one most of the time - use common sense!). +* No merges should be included in pull requests unless the pull request's purpose is a merge. +* Pull requests should be tested (does it compile? AND does it work?) before submission. +* Any major additions should have documentation ready and provided if applicable (this is usually the case). +* Most pull requests should be accompanied by a corresponding GitHub ticket so we can associate commits with GitHub issues (this is primarily for changelog generation on ci.md-5.net). +* Try to follow test driven development where applicable. + +If you make changes to or add upstream classes (net.minecraft, net.minecraftforge, cpw.mods.fml, org.bukkit, org.spigotmc) it is mandatory to: + +* Make a separate commit adding the new net.minecraft classes (commit message: "Added x for diff visibility" or so). +* Then make further commits with your changes. +* Mark your changes with: + * 1 line; add a trailing: `// Cauldron [- Optional reason]` + * 2+ lines; add + * Before: `// Cauldron start [- Optional comment]` + * After: `// Cauldron end` +* Keep the diffs to a minimum (*somewhat* important) + +Tips to get your pull request accepted +----------- +Making sure you follow the above conventions is important, but just the beginning. Follow these tips to better the chances of your pull request being accepted and pulled. + +* Make sure you follow all of our conventions to the letter. +* Make sure your code compiles under Java 6. +* Provide proper JavaDocs where appropriate. +* Provide proper accompanying documentation where appropriate. +* Test your code. +* Make sure to follow coding best practices. +* Provide a test plugin/mod binary and source for us to test your code with. +* Your pull request should link to accompanying pull requests. +* The description of your pull request should provide detailed information on the pull along with justification of the changes where applicable. + +Credits +------- + +* [MCP](http://mcp.ocean-labs.de) - permission to use data to make Cauldron. +* [Forge](http://www.minecraftforge.net) - mod support. +* [CraftBukkit](http://bukkit.org) - plugin support. +* [Spigot](http://www.spigotmc.org) - performance optimizations. diff --git a/build.gradle b/build.gradle new file mode 100644 index 0000000..5be9547 --- /dev/null +++ b/build.gradle @@ -0,0 +1,73 @@ +buildscript { + repositories { + mavenCentral() + mavenLocal() + maven { + name = "forge" + url = "http://files.minecraftforge.net/maven" + } + maven { + name = "sonatype" + url = "https://oss.sonatype.org/content/repositories/snapshots/" + } + } + dependencies { + classpath 'net.minecraftforge.gradle:ForgeGradle:1.2-SNAPSHOT' + } +} + +apply plugin: 'maven' +apply plugin: 'cauldron' + +minecraft { + version = '1.7.10' + mcpVersion = '9.05' + mainClass = 'cpw.mods.fml.relauncher.ServerLaunchWrapper' + tweakClass = 'cpw.mods.fml.common.launcher.FMLTweaker' + installerVersion = "1.4" + subprojects { + repositories { + mavenLocal() + maven { + name = "sonatype" + url = "https://oss.sonatype.org/content/repositories/snapshots/" + } + flatDir { + name "fileRepo" + dirs "repo" + } + } + } + srgExtra "PK: org/bukkit/craftbukkit org/bukkit/craftbukkit/v1_7_R4" +} + +group = 'net.minecraftforge' +ext.mcVersion = "1.7.10" +ext.cauldronVersion = "1" +ext.forgeVersion = "1291" +ext.bukkitVersion = "01" +version = "${mcVersion}-${cauldronVersion}.${forgeVersion}.${bukkitVersion}.0" + +jenkins { + job = 'Cauldron' +} + +launch4j { + jreMinVersion = '1.6.0' +} + +tasks.packageUniversal { + classifier = 'server' +} + +tasks.packageUniversal.manifest { + attributes([ + 'Implementation-Vendor': 'Cauldron', + 'Implementation-Title': 'Cauldron', + 'Implementation-Version': 'git-Cauldron-Reloaded-'+project.version, + 'Forge-Version': '10.13.2.1291', + 'Specification-Vendor': 'Bukkit Team', + 'Specification-Title': 'Bukkit', + 'Specification-Version': '1.7.10-R0.1-SNAPSHOT' + ]) +} \ No newline at end of file diff --git a/eclipse-workspace-dev.zip b/eclipse-workspace-dev.zip new file mode 100644 index 0000000000000000000000000000000000000000..ee2cc64dc44fe37b53b478510204ed9fe05e23f3 GIT binary patch literal 20444 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 E4<-yQ$p8QV literal 0 HcmV?d00001 diff --git a/gradlew b/gradlew new file mode 100644 index 0000000..8280e25 --- /dev/null +++ b/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/forge/fml/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/gradlew.bat b/gradlew.bat new file mode 100644 index 0000000..2d56e9d --- /dev/null +++ b/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\forge\fml\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/jsons/1.7.10-dev.json b/jsons/1.7.10-dev.json new file mode 100644 index 0000000..78de829 --- /dev/null +++ b/jsons/1.7.10-dev.json @@ -0,0 +1,298 @@ +{ + "id": "@minecraft_version@-@project@@version@", + "time": "@timestamp@", + "releaseTime": "1960-01-01T00:00:00-0700", + "type": "release", + "minecraftArguments": "--version FML_DEV --tweakClass cpw.mods.fml.common.launcher.FMLTweaker", + "minimumLauncherVersion": 13, + "assets": "1.7.10", + "libraries": [ + { + "name": "net.minecraft:launchwrapper:1.11" + }, + { + "name": "com.google.code.findbugs:jsr305:1.3.9", + "children": ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "org.ow2.asm:asm-debug-all:5.0.3", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "com.typesafe.akka:akka-actor_2.11:2.3.3", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "com.typesafe:config:1.2.1", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "org.scala-lang:scala-actors-migration_2.11:1.1.0", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "org.scala-lang:scala-compiler:2.11.1", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "org.scala-lang.plugins:scala-continuations-library_2.11:1.0.2", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "org.scala-lang.plugins:scala-continuations-plugin_2.11.1:1.0.2", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "org.scala-lang:scala-library:2.11.1", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "org.scala-lang:scala-parser-combinators_2.11:1.0.1", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "org.scala-lang:scala-reflect:2.11.1", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "org.scala-lang:scala-swing_2.11:1.0.1", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "org.scala-lang:scala-xml_2.11:1.0.2", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "net.sf.jopt-simple:jopt-simple:4.5", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "lzma:lzma:0.0.1" + }, + { + "name": "com.mojang:realms:1.3.5" + }, + { + "name": "org.apache.commons:commons-compress:1.8.1" + }, + { + "name": "org.apache.httpcomponents:httpclient:4.3.3" + }, + { + "name": "commons-logging:commons-logging:1.1.3" + }, + { + "name": "org.apache.httpcomponents:httpcore:4.3.2" + }, + { + "name": "java3d:vecmath:1.3.1" + }, + { + "name": "net.sf.trove4j:trove4j:3.0.3" + }, + { + "name": "com.ibm.icu:icu4j-core-mojang:51.2" + }, + { + "name": "com.paulscode:codecjorbis:20101023" + }, + { + "name": "com.paulscode:codecwav:20101023" + }, + { + "name": "com.paulscode:libraryjavasound:20101123" + }, + { + "name": "com.paulscode:librarylwjglopenal:20100824" + }, + { + "name": "com.paulscode:soundsystem:20120107" + }, + { + "name": "io.netty:netty-all:4.0.10.Final" + }, + { + "name": "com.google.guava:guava:16.0" + }, + { + "name": "org.apache.commons:commons-lang3:3.2.1" + }, + { + "name": "commons-io:commons-io:2.4" + }, + { + "name": "commons-codec:commons-codec:1.9" + }, + { + "name": "net.java.jinput:jinput:2.0.5" + }, + { + "name": "net.java.jutils:jutils:1.0.0" + }, + { + "name": "com.google.code.gson:gson:2.2.4" + }, + { + "name": "com.mojang:authlib:1.5.16" + }, + { + "name": "org.apache.logging.log4j:log4j-api:2.0-beta9" + }, + { + "name": "org.apache.logging.log4j:log4j-core:2.0-beta9" + }, + { + "name": "net.sf.jopt-simple:jopt-simple:4.5", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "org.yaml:snakeyaml:1.9", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "commons-lang:commons-lang:2.6", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "org.avaje:ebean:2.7.3", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "jline:jline:2.6", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "net.md-5:SpecialSource:1.7-SNAPSHOT", + "url" : "https://raw.github.com/MinecraftPortCentral/mcpc-mvn-repo/master/snapshots", + "serverreq":true + }, + { + "name": "net.sourceforge.argo:argo:2.25", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "org.fusesource.jansi:jansi:1.8", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "com.googlecode.json-simple:json-simple:1.1", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "org.xerial:sqlite-jdbc:3.7.2", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "mysql:mysql-connector-java:5.1.14", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "javax.persistence:persistence-api:1.0.2", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "org.lwjgl.lwjgl:lwjgl:2.9.1" + }, + { + "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1" + }, + { + "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1", + "natives": { + "linux": "natives-linux", + "windows": "natives-windows", + "osx": "natives-osx" + }, + "extract": { + "exclude": [ + "META-INF/" + ] + } + }, + { + "name": "net.java.jinput:jinput-platform:2.0.5", + "natives": { + "linux": "natives-linux", + "windows": "natives-windows", + "osx": "natives-osx" + }, + "extract": { + "exclude": [ + "META-INF/" + ] + } + }, + { + "name": "tv.twitch:twitch:5.16" + }, + { + "name": "tv.twitch:twitch-platform:5.16", + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux" + } + } + ], + "natives": { + "linux": "natives-linux", + "windows": "natives-windows-${arch}", + "osx": "natives-osx" + }, + "extract": { + "exclude": [ + "META-INF/" + ] + } + }, + { + "name": "tv.twitch:twitch-external-platform:4.5", + "rules": [ + { + "action": "allow", + "os": { + "name": "windows" + } + } + ], + "natives": { + "windows": "natives-windows-${arch}" + }, + "extract": { + "exclude": [ + "META-INF/" + ] + } + } + ], + "mainClass": "net.minecraft.launchwrapper.Launch" +} \ No newline at end of file diff --git a/jsons/1.7.10-rel.json b/jsons/1.7.10-rel.json new file mode 100644 index 0000000..d78ca88 --- /dev/null +++ b/jsons/1.7.10-rel.json @@ -0,0 +1,327 @@ +{ +"install": { + "profileName": "@project@", + "target":"@minecraft_version@-@project@@version@", + "path":"@artifact@", + "version":"@project@ @version@", + "filePath":"@universal_jar@", + "welcome":"Welcome to the simple @project@ installer.", + "minecraft":"@minecraft_version@", + "logo":"/big_logo.png", + "hideClient":true +}, +"versionInfo": { + "id": "@minecraft_version@-@project@@version@", + "time": "@timestamp@", + "releaseTime": "1960-01-01T00:00:00-0700", + "type": "release", + "minecraftArguments": "--username ${auth_player_name} --version ${version_name} --gameDir ${game_directory} --assetsDir ${assets_root} --assetIndex ${assets_index_name} --uuid ${auth_uuid} --accessToken ${auth_access_token} --userProperties ${user_properties} --userType ${user_type} --tweakClass cpw.mods.fml.common.launcher.FMLTweaker", + "minimumLauncherVersion": 13, + "assets": "1.7.10", + "libraries": [ + { + "name": "@artifact@", + "url": "http://files.minecraftforge.net/maven/" + }, + { + "name": "net.minecraft:launchwrapper:1.11", + "serverreq":true + }, + { + "name": "org.ow2.asm:asm-all:5.0.3", + "serverreq":true + }, + { + "name": "com.typesafe.akka:akka-actor_2.11:2.3.3", + "url" : "http://files.minecraftforge.net/maven/", + "checksums" : [ "ed62e9fc709ca0f2ff1a3220daa8b70a2870078e", "25a86ccfdb6f6dfe08971f4825d0a01be83a6f2e" ], + "serverreq":true, + "clientreq":true + }, + { + "name": "com.typesafe:config:1.2.1", + "url" : "http://files.minecraftforge.net/maven/", + "checksums" : [ "f771f71fdae3df231bcd54d5ca2d57f0bf93f467", "7d7bc36df0989d72f2d5d057309675777acc528b" ], + "serverreq":true, + "clientreq":true + }, + { + "name": "org.scala-lang:scala-actors-migration_2.11:1.1.0", + "url" : "http://files.minecraftforge.net/maven/", + "checksums" : [ "dfa8bc42b181d5b9f1a5dd147f8ae308b893eb6f", "8c9aaeeb68487ca519411a14068e1b4d69739207" ], + "serverreq":true, + "clientreq":true + }, + { + "name": "org.scala-lang:scala-compiler:2.11.1", + "url" : "http://files.minecraftforge.net/maven/", + "checksums" : [ "56ea2e6c025e0821f28d73ca271218b8dd04926a", "1444992390544ba3780867a13ff696a89d7d1639" ], + "serverreq":true, + "clientreq":true + }, + { + "name": "org.scala-lang.plugins:scala-continuations-library_2.11:1.0.2", + "url" : "http://files.minecraftforge.net/maven/", + "checksums" : [ "87213338cd5a153a7712cb574c0ddd2edfee0386", "0b4c1bf8d48993f138d6e10c0c144e50acfff581" ], + "serverreq":true, + "clientreq":true + }, + { + "name": "org.scala-lang.plugins:scala-continuations-plugin_2.11.1:1.0.2", + "url" : "http://files.minecraftforge.net/maven/", + "checksums" : [ "1f7371605d4ba42aa26d3443440c0083c587b4e9", "1ea655dda4504ae0a367327e2340cd3beaee6c73" ], + "serverreq":true, + "clientreq":true + }, + { + "name": "org.scala-lang:scala-library:2.11.1", + "url" : "http://files.minecraftforge.net/maven/", + "checksums" : [ "0e11da23da3eabab9f4777b9220e60d44c1aab6a", "1e4df76e835201c6eabd43adca89ab11f225f134" ], + "serverreq":true, + "clientreq":true + }, + { + "name": "org.scala-lang:scala-parser-combinators_2.11:1.0.1", + "url" : "http://files.minecraftforge.net/maven/", + "checksums" : [ "f05d7345bf5a58924f2837c6c1f4d73a938e1ff0", "a1cbbcbde1dcc614f4253ed1aa0b320bc78d8f1d" ], + "serverreq":true, + "clientreq":true + }, + { + "name": "org.scala-lang:scala-reflect:2.11.1", + "url" : "http://files.minecraftforge.net/maven/", + "checksums" : [ "6580347e61cc7f8e802941e7fde40fa83b8badeb", "91ce0f0be20f4a536321724b4b3bbc6530ddcd88" ], + "serverreq":true, + "clientreq":true + }, + { + "name": "org.scala-lang:scala-swing_2.11:1.0.1", + "url" : "http://files.minecraftforge.net/maven/", + "checksums" : [ "b1cdd92bd47b1e1837139c1c53020e86bb9112ae", "d77152691dcf5bbdb00529af37aa7d3d887b3e63" ], + "serverreq":true, + "clientreq":true + }, + { + "name": "org.scala-lang:scala-xml_2.11:1.0.2", + "url" : "http://files.minecraftforge.net/maven/", + "checksums" : [ "7a80ec00aec122fba7cd4e0d4cdd87ff7e4cb6d0", "62736b01689d56b6d09a0164b7ef9da2b0b9633d" ], + "serverreq":true, + "clientreq":true + }, + { + "name": "net.sf.jopt-simple:jopt-simple:4.5", + "serverreq":true + }, + { + "name": "lzma:lzma:0.0.1", + "serverreq":true + }, + { + "name": "com.mojang:realms:1.3.5" + }, + { + "name": "org.apache.commons:commons-compress:1.8.1" + }, + { + "name": "org.apache.httpcomponents:httpclient:4.3.3" + }, + { + "name": "commons-logging:commons-logging:1.1.3" + }, + { + "name": "org.apache.httpcomponents:httpcore:4.3.2" + }, + { + "name": "java3d:vecmath:1.3.1" + }, + { + "name": "net.sf.trove4j:trove4j:3.0.3" + }, + { + "name": "com.ibm.icu:icu4j-core-mojang:51.2" + }, + { + "name": "com.paulscode:codecjorbis:20101023" + }, + { + "name": "com.paulscode:codecwav:20101023" + }, + { + "name": "com.paulscode:libraryjavasound:20101123" + }, + { + "name": "com.paulscode:librarylwjglopenal:20100824" + }, + { + "name": "com.paulscode:soundsystem:20120107" + }, + { + "name": "io.netty:netty-all:4.0.10.Final" + }, + { + "name": "com.google.guava:guava:16.0" + }, + { + "name": "org.apache.commons:commons-lang3:3.2.1" + }, + { + "name": "commons-io:commons-io:2.4" + }, + { + "name": "commons-codec:commons-codec:1.9" + }, + { + "name": "net.java.jinput:jinput:2.0.5" + }, + { + "name": "net.java.jutils:jutils:1.0.0" + }, + { + "name": "com.google.code.gson:gson:2.2.4" + }, + { + "name": "com.mojang:authlib:1.5.16" + }, + { + "name": "org.apache.logging.log4j:log4j-api:2.0-beta9" + }, + { + "name": "org.apache.logging.log4j:log4j-core:2.0-beta9" + }, + { + "name": "org.yaml:snakeyaml:1.9", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "commons-lang:commons-lang:2.6", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "org.avaje:ebean:2.7.3", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "jline:jline:2.6", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "net.md-5:SpecialSource:1.7-SNAPSHOT", + "url" : "https://raw.github.com/MinecraftPortCentral/mcpc-mvn-repo/master/snapshots", + "serverreq":true + }, + { + "name": "org.fusesource.jansi:jansi:1.8", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "net.sourceforge.argo:argo:2.25", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "com.googlecode.json-simple:json-simple:1.1", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "org.xerial:sqlite-jdbc:3.7.2", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "mysql:mysql-connector-java:5.1.14", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "javax.persistence:persistence-api:1.0.2", + "url" : "http://repo.maven.apache.org/maven2", + "serverreq":true + }, + { + "name": "org.lwjgl.lwjgl:lwjgl:2.9.1" + }, + { + "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1" + }, + { + "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1", + "natives": { + "linux": "natives-linux", + "windows": "natives-windows", + "osx": "natives-osx" + }, + "extract": { + "exclude": [ + "META-INF/" + ] + } + }, + { + "name": "net.java.jinput:jinput-platform:2.0.5", + "natives": { + "linux": "natives-linux", + "windows": "natives-windows", + "osx": "natives-osx" + }, + "extract": { + "exclude": [ + "META-INF/" + ] + } + }, + { + "name": "tv.twitch:twitch:5.16" + }, + { + "name": "tv.twitch:twitch-platform:5.16", + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux" + } + } + ], + "natives": { + "linux": "natives-linux", + "windows": "natives-windows-${arch}", + "osx": "natives-osx" + }, + "extract": { + "exclude": [ + "META-INF/" + ] + } + }, + { + "name": "tv.twitch:twitch-external-platform:4.5", + "rules": [ + { + "action": "allow", + "os": { + "name": "windows" + } + } + ], + "natives": { + "windows": "natives-windows-${arch}" + }, + "extract": { + "exclude": [ + "META-INF/" + ] + } + } + ], + "mainClass": "net.minecraft.launchwrapper.Launch" +} +} \ No newline at end of file diff --git a/jsons/1.7.10.json b/jsons/1.7.10.json new file mode 100644 index 0000000..baa7023 --- /dev/null +++ b/jsons/1.7.10.json @@ -0,0 +1,191 @@ +{ + "id": "@minecraft_version@-@project@@version@", + "time": "@timestamp@", + "releaseTime": "1960-01-01T00:00:00-0700", + "type": "release", + "minecraftArguments": "--version FML_DEV --tweakClass cpw.mods.fml.common.launcher.FMLTweaker", + "minimumLauncherVersion": 13, + "assets": "1.7.10", + "libraries": [ + { + "name": "net.minecraft:launchwrapper:1.11" + }, + { + "name": "org.ow2.asm:asm-debug-all:5.0.3", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "org.scala-lang:scala-library:2.10.2", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "org.scala-lang:scala-compiler:2.10.2", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "net.sf.jopt-simple:jopt-simple:4.5", + "children" : ["sources"], + "url" : "http://repo.maven.apache.org/maven2" + }, + { + "name": "lzma:lzma:0.0.1" + }, + { + "name": "com.mojang:realms:1.3.5" + }, + { + "name": "org.apache.commons:commons-compress:1.8.1" + }, + { + "name": "org.apache.httpcomponents:httpclient:4.3.3" + }, + { + "name": "commons-logging:commons-logging:1.1.3" + }, + { + "name": "org.apache.httpcomponents:httpcore:4.3.2" + }, + { + "name": "java3d:vecmath:1.3.1" + }, + { + "name": "net.sf.trove4j:trove4j:3.0.3" + }, + { + "name": "com.ibm.icu:icu4j-core-mojang:51.2" + }, + { + "name": "net.sf.jopt-simple:jopt-simple:4.5" + }, + { + "name": "com.paulscode:codecjorbis:20101023" + }, + { + "name": "com.paulscode:codecwav:20101023" + }, + { + "name": "com.paulscode:libraryjavasound:20101123" + }, + { + "name": "com.paulscode:librarylwjglopenal:20100824" + }, + { + "name": "com.paulscode:soundsystem:20120107" + }, + { + "name": "io.netty:netty-all:4.0.10.Final" + }, + { + "name": "com.google.guava:guava:16.0" + }, + { + "name": "org.apache.commons:commons-lang3:3.2.1" + }, + { + "name": "commons-io:commons-io:2.4" + }, + { + "name": "commons-codec:commons-codec:1.9" + }, + { + "name": "net.java.jinput:jinput:2.0.5" + }, + { + "name": "net.java.jutils:jutils:1.0.0" + }, + { + "name": "com.google.code.gson:gson:2.2.4" + }, + { + "name": "com.mojang:authlib:1.5.16" + }, + { + "name": "org.apache.logging.log4j:log4j-api:2.0-beta9" + }, + { + "name": "org.apache.logging.log4j:log4j-core:2.0-beta9" + }, + { + "name": "org.lwjgl.lwjgl:lwjgl:2.9.1" + }, + { + "name": "org.lwjgl.lwjgl:lwjgl_util:2.9.1" + }, + { + "name": "org.lwjgl.lwjgl:lwjgl-platform:2.9.1", + "natives": { + "linux": "natives-linux", + "windows": "natives-windows", + "osx": "natives-osx" + }, + "extract": { + "exclude": [ + "META-INF/" + ] + } + }, + { + "name": "net.java.jinput:jinput-platform:2.0.5", + "natives": { + "linux": "natives-linux", + "windows": "natives-windows", + "osx": "natives-osx" + }, + "extract": { + "exclude": [ + "META-INF/" + ] + } + }, + { + "name": "tv.twitch:twitch:5.16" + }, + { + "name": "tv.twitch:twitch-platform:5.16", + "rules": [ + { + "action": "allow" + }, + { + "action": "disallow", + "os": { + "name": "linux" + } + } + ], + "natives": { + "linux": "natives-linux", + "windows": "natives-windows-${arch}", + "osx": "natives-osx" + }, + "extract": { + "exclude": [ + "META-INF/" + ] + } + }, + { + "name": "tv.twitch:twitch-external-platform:4.5", + "rules": [ + { + "action": "allow", + "os": { + "name": "windows" + } + } + ], + "natives": { + "windows": "natives-windows-${arch}" + }, + "extract": { + "exclude": [ + "META-INF/" + ] + } + } + ], + "mainClass": "net.minecraft.launchwrapper.Launch" +} diff --git a/patches/cpw/mods/fml/common/FMLCommonHandler.java.patch b/patches/cpw/mods/fml/common/FMLCommonHandler.java.patch new file mode 100644 index 0000000..78d0b52 --- /dev/null +++ b/patches/cpw/mods/fml/common/FMLCommonHandler.java.patch @@ -0,0 +1,58 @@ +--- ../src-base/minecraft/cpw/mods/fml/common/FMLCommonHandler.java ++++ ../src-work/minecraft/cpw/mods/fml/common/FMLCommonHandler.java +@@ -37,6 +37,10 @@ + + import org.apache.logging.log4j.Level; + import org.apache.logging.log4j.Logger; ++import org.bukkit.Bukkit; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.entity.Player; ++import org.bukkit.event.player.PlayerChangedWorldEvent; + + import com.google.common.base.Joiner; + import com.google.common.base.Strings; +@@ -385,10 +389,11 @@ + { + return; + } +- if (handlerSet.contains(handler)) ++ if (handlerSet.contains(handler) || worldInfo.getDimension() != 0) // Cauldron - Only check FML data in main world + { + return; + } ++ // Cauldron - logic below should only be run for overworld as Forge/Vanilla only use 1 SaveHandler + handlerSet.add(handler); + handlerToCheck = new WeakReference(handler); // for confirmBackupLevelDatUse + Map additionalProperties = Maps.newHashMap(); +@@ -496,7 +501,12 @@ + + public String getModName() + { +- List modNames = Lists.newArrayListWithExpectedSize(3); ++ // Cauldron start ++ List modNames = Lists.newArrayListWithExpectedSize(6); ++ modNames.add("cauldron"); ++ modNames.add("craftbukkit"); ++ modNames.add("mcpc"); ++ // Cauldron end + modNames.add("fml"); + if (!noForge) + { +@@ -540,8 +550,17 @@ + bus().post(new InputEvent.KeyInputEvent()); + } + ++ // Cauldron start - wrapper to notify plugins for mods that bypass ServerConfigurationManager + public void firePlayerChangedDimensionEvent(EntityPlayer player, int fromDim, int toDim) + { ++ this.firePlayerChangedDimensionEvent(player, fromDim, toDim, player.worldObj.getWorld()); ++ } ++ ++ public void firePlayerChangedDimensionEvent(EntityPlayer player, int fromDim, int toDim, CraftWorld fromWorld) ++ { ++ PlayerChangedWorldEvent event = new PlayerChangedWorldEvent((Player) player.getBukkitEntity(), fromWorld); ++ Bukkit.getServer().getPluginManager().callEvent(event); ++ // Cauldron end + bus().post(new PlayerEvent.PlayerChangedDimensionEvent(player, fromDim, toDim)); + } + diff --git a/patches/cpw/mods/fml/common/asm/FMLSanityChecker.java.patch b/patches/cpw/mods/fml/common/asm/FMLSanityChecker.java.patch new file mode 100644 index 0000000..a7588fd --- /dev/null +++ b/patches/cpw/mods/fml/common/asm/FMLSanityChecker.java.patch @@ -0,0 +1,17 @@ +--- ../src-base/minecraft/cpw/mods/fml/common/asm/FMLSanityChecker.java ++++ ../src-work/minecraft/cpw/mods/fml/common/asm/FMLSanityChecker.java +@@ -164,10 +164,12 @@ + FMLRelaunchLog.severe("Technical information: ClientBrandRetriever was at %s, there were %d certificates for it", codeSource.getLocation(), certCount); + } + } +- if (!goodFML) ++ // Cauldron start - disable message ++ /*if (!goodFML) + { + FMLRelaunchLog.severe("FML appears to be missing any signature data. This is not a good thing"); +- } ++ }*/ ++ // Cauldron end + return null; + } + diff --git a/patches/cpw/mods/fml/common/asm/transformers/SideTransformer.java.patch b/patches/cpw/mods/fml/common/asm/transformers/SideTransformer.java.patch new file mode 100644 index 0000000..2334528 --- /dev/null +++ b/patches/cpw/mods/fml/common/asm/transformers/SideTransformer.java.patch @@ -0,0 +1,19 @@ +--- ../src-base/minecraft/cpw/mods/fml/common/asm/transformers/SideTransformer.java ++++ ../src-work/minecraft/cpw/mods/fml/common/asm/transformers/SideTransformer.java +@@ -32,6 +32,7 @@ + { + private static String SIDE = FMLLaunchHandler.side().name(); + private static final boolean DEBUG = false; ++ public static boolean allowInvalidSide = false; // Cauldron + @Override + public byte[] transform(String name, String transformedName, byte[] bytes) + { +@@ -41,7 +42,7 @@ + ClassReader classReader = new ClassReader(bytes); + classReader.accept(classNode, 0); + +- if (remove((List)classNode.visibleAnnotations, SIDE)) ++ if (remove((List)classNode.visibleAnnotations, SIDE) && !allowInvalidSide) // Cauldron + { + if (DEBUG) + { diff --git a/patches/cpw/mods/fml/common/event/FMLServerStartingEvent.java.patch b/patches/cpw/mods/fml/common/event/FMLServerStartingEvent.java.patch new file mode 100644 index 0000000..ef64a4c --- /dev/null +++ b/patches/cpw/mods/fml/common/event/FMLServerStartingEvent.java.patch @@ -0,0 +1,23 @@ +--- ../src-base/minecraft/cpw/mods/fml/common/event/FMLServerStartingEvent.java ++++ ../src-work/minecraft/cpw/mods/fml/common/event/FMLServerStartingEvent.java +@@ -16,6 +16,7 @@ + import net.minecraft.command.ICommand; + import net.minecraft.server.MinecraftServer; + import cpw.mods.fml.common.LoaderState.ModState; ++import org.bukkit.command.Command; // Cauldron + + public class FMLServerStartingEvent extends FMLStateEvent + { +@@ -43,4 +44,12 @@ + CommandHandler ch = (CommandHandler) getServer().getCommandManager(); + ch.registerCommand(command); + } ++ ++ // Cauldron start - used for mods to register a Bukkit command ++ public void registerServerCommand(String fallbackPrefix, Command command) ++ { ++ org.bukkit.command.SimpleCommandMap commandMap = getServer().server.getCommandMap(); ++ commandMap.register(fallbackPrefix, command); ++ } ++ // Cauldron end + } diff --git a/patches/cpw/mods/fml/common/network/handshake/ChannelRegistrationHandler.java.patch b/patches/cpw/mods/fml/common/network/handshake/ChannelRegistrationHandler.java.patch new file mode 100644 index 0000000..dce3768 --- /dev/null +++ b/patches/cpw/mods/fml/common/network/handshake/ChannelRegistrationHandler.java.patch @@ -0,0 +1,35 @@ +--- ../src-base/minecraft/cpw/mods/fml/common/network/handshake/ChannelRegistrationHandler.java ++++ ../src-work/minecraft/cpw/mods/fml/common/network/handshake/ChannelRegistrationHandler.java +@@ -2,6 +2,8 @@ + + import io.netty.channel.ChannelHandlerContext; + import io.netty.channel.SimpleChannelInboundHandler; ++ ++import java.io.UnsupportedEncodingException; + import java.util.Set; + import net.minecraft.network.NetworkManager; + import org.apache.logging.log4j.Level; +@@ -24,6 +26,23 @@ + msg.payload().readBytes(data); + String channels = new String(data,Charsets.UTF_8); + String[] split = channels.split("\0"); ++ // Cauldron start - register bukkit channels for players ++ NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).get(); ++ if (msg.channel().equals("REGISTER")) ++ { ++ for (String channel : split) ++ { ++ dispatcher.player.getBukkitEntity().addChannel(channel); ++ } ++ } ++ else ++ { ++ for (String channel : split) ++ { ++ dispatcher.player.getBukkitEntity().removeChannel(channel); ++ } ++ } ++ // Cauldron end + Set channelSet = ImmutableSet.copyOf(split); + FMLCommonHandler.instance().fireNetRegistrationEvent(manager, channelSet, msg.channel(), side); + } diff --git a/patches/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java.patch b/patches/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java.patch new file mode 100644 index 0000000..18ee8eb --- /dev/null +++ b/patches/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java.patch @@ -0,0 +1,45 @@ +--- ../src-base/minecraft/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java ++++ ../src-work/minecraft/cpw/mods/fml/common/network/handshake/NetworkDispatcher.java +@@ -72,7 +72,7 @@ + public static final AttributeKey IS_LOCAL = new AttributeKey("fml:isLocal"); + public final NetworkManager manager; + private final ServerConfigurationManager scm; +- private EntityPlayerMP player; ++ public EntityPlayerMP player; // Cauldron + private ConnectionState state; + private ConnectionType connectionType; + private final Side side; +@@ -202,7 +202,7 @@ + } + else + { +- FMLLog.info("Unexpected packet during modded negotiation - assuming vanilla or keepalives : %s", msg.getClass().getName()); ++ //FMLLog.info("Unexpected packet during modded negotiation - assuming vanilla or keepalives : %s", msg.getClass().getName()); // Cauldron - unneeded spam + } + return false; + } +@@ -287,6 +287,7 @@ + state = ConnectionState.HANDSHAKING; + } + String channelName = msg.func_149559_c(); ++ player.getBukkitEntity().addChannel(channelName); // Cauldron - register channel for bukkit player + if ("FML|HS".equals(channelName) || "REGISTER".equals(channelName) || "UNREGISTER".equals(channelName)) + { + FMLProxyPacket proxy = new FMLProxyPacket(msg); +@@ -308,6 +309,7 @@ + else if (NetworkRegistry.INSTANCE.hasChannel(channelName, Side.SERVER)) + { + FMLProxyPacket proxy = new FMLProxyPacket(msg); ++ serverHandler.getCraftServer().getMessenger().dispatchIncomingMessage(player.getBukkitEntity(), msg.func_149559_c(), msg.func_149558_e()); // pass msg to bukkit + proxy.setDispatcher(this); + context.fireChannelRead(proxy); + return true; +@@ -465,7 +467,7 @@ + // Stop the epic channel closed spam at close + if (!(cause instanceof ClosedChannelException)) + { +- FMLLog.log(Level.ERROR, cause, "NetworkDispatcher exception"); ++ //FMLLog.log(Level.ERROR, cause, "NetworkDispatcher exception"); // Cauldron - disable unneeded spam + } + super.exceptionCaught(ctx, cause); + } diff --git a/patches/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java.patch b/patches/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java.patch new file mode 100644 index 0000000..f708828 --- /dev/null +++ b/patches/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java.patch @@ -0,0 +1,51 @@ +--- ../src-base/minecraft/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java ++++ ../src-work/minecraft/cpw/mods/fml/common/network/internal/FMLNetworkHandler.java +@@ -47,6 +47,16 @@ + import cpw.mods.fml.common.registry.EntityRegistry.EntityRegistration; + import cpw.mods.fml.relauncher.Side; + import cpw.mods.fml.relauncher.SideOnly; ++//Cauldron start ++import net.minecraft.inventory.IInventory; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.tileentity.TileEntity; ++import org.bukkit.craftbukkit.entity.CraftPlayer; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.inventory.CraftInventory; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++import org.bukkit.event.inventory.InventoryType; ++// Cauldron end + + public class FMLNetworkHandler + { +@@ -75,6 +85,31 @@ + Container remoteGuiContainer = NetworkRegistry.INSTANCE.getRemoteGuiContainer(mc, entityPlayerMP, modGuiId, world, x, y, z); + if (remoteGuiContainer != null) + { ++ // Cauldron start - create bukkitView for passed container then fire open event. ++ if (entityPlayer != null) ++ { ++ if (remoteGuiContainer.getBukkitView() == null) ++ { ++ TileEntity te = entityPlayer.worldObj.getTileEntity(x, y, z); ++ if (te != null && te instanceof IInventory) ++ { ++ IInventory teInv = (IInventory)te; ++ CraftInventory inventory = new CraftInventory(teInv); ++ remoteGuiContainer.bukkitView = new CraftInventoryView(entityPlayer.getBukkitEntity(), inventory, remoteGuiContainer); ++ } ++ else ++ { ++ remoteGuiContainer.bukkitView = new CraftInventoryView(entityPlayer.getBukkitEntity(), MinecraftServer.getServer().server.createInventory(entityPlayer.getBukkitEntity(), InventoryType.CHEST), remoteGuiContainer); ++ } ++ ++ remoteGuiContainer = CraftEventFactory.callInventoryOpenEvent((EntityPlayerMP)entityPlayer, remoteGuiContainer, false); ++ if (remoteGuiContainer == null) ++ { ++ return; ++ } ++ } ++ } ++ // Cauldron end + entityPlayerMP.getNextWindowId(); + entityPlayerMP.closeContainer(); + int windowId = entityPlayerMP.currentWindowId; diff --git a/patches/cpw/mods/fml/common/network/internal/HandshakeCompletionHandler.java.patch b/patches/cpw/mods/fml/common/network/internal/HandshakeCompletionHandler.java.patch new file mode 100644 index 0000000..64edf7c --- /dev/null +++ b/patches/cpw/mods/fml/common/network/internal/HandshakeCompletionHandler.java.patch @@ -0,0 +1,18 @@ +--- ../src-base/minecraft/cpw/mods/fml/common/network/internal/HandshakeCompletionHandler.java ++++ ../src-work/minecraft/cpw/mods/fml/common/network/internal/HandshakeCompletionHandler.java +@@ -13,9 +13,15 @@ + @Override + protected void channelRead0(ChannelHandlerContext ctx, CompleteHandshake msg) throws Exception + { ++ // Cauldron start - attempt to fix race condition with attr being null ++ Object attr = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER); ++ if (attr != null) ++ { + NetworkDispatcher dispatcher = ctx.channel().attr(NetworkDispatcher.FML_DISPATCHER).getAndRemove(); + dispatcher.completeHandshake(msg.target); + } ++ // Cauldron end ++ } + + @Override + public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception diff --git a/patches/cpw/mods/fml/common/registry/EntityRegistry.java.patch b/patches/cpw/mods/fml/common/registry/EntityRegistry.java.patch new file mode 100644 index 0000000..5cf25ea --- /dev/null +++ b/patches/cpw/mods/fml/common/registry/EntityRegistry.java.patch @@ -0,0 +1,79 @@ +--- ../src-base/minecraft/cpw/mods/fml/common/registry/EntityRegistry.java ++++ ../src-work/minecraft/cpw/mods/fml/common/registry/EntityRegistry.java +@@ -41,6 +41,12 @@ + import cpw.mods.fml.common.ModContainer; + import cpw.mods.fml.common.network.internal.FMLMessage.EntitySpawnMessage; + ++// Cauldron start ++import net.minecraftforge.common.util.EnumHelper; ++import org.bukkit.craftbukkit.entity.CraftEntity; ++import org.bukkit.entity.EntityType; ++// Cauldron end ++ + public class EntityRegistry + { + public class EntityRegistration +@@ -118,6 +124,8 @@ + private ListMultimap entityRegistrations = ArrayListMultimap.create(); + private Map entityNames = Maps.newHashMap(); + private BiMap, EntityRegistration> entityClassRegistrations = HashBiMap.create(); ++ public static Map, String> entityTypeMap = Maps.newHashMap(); // Cauldron - used by CraftCustomEntity ++ public static Map> entityClassMap = Maps.newHashMap(); // Cauldron - used by CraftWorld + public static EntityRegistry instance() + { + return INSTANCE; +@@ -147,6 +155,7 @@ + public static void registerModEntity(Class entityClass, String entityName, int id, Object mod, int trackingRange, int updateFrequency, boolean sendsVelocityUpdates) + { + instance().doModEntityRegistration(entityClass, entityName, id, mod, trackingRange, updateFrequency, sendsVelocityUpdates); ++ registerBukkitType(entityClass, entityName); // Cauldron - register EntityType for Bukkit + } + + @SuppressWarnings("unchecked") +@@ -197,6 +206,7 @@ + } + id = instance().validateAndClaimId(id); + EntityList.addMapping(entityClass, entityName, id); ++ registerBukkitType(entityClass, entityName); // Cauldron - register EntityType for Bukkit + } + + private int validateAndClaimId(int id) +@@ -249,8 +259,38 @@ + } + instance().validateAndClaimId(id); + EntityList.addMapping(entityClass, entityName, id, backgroundEggColour, foregroundEggColour); ++ registerBukkitType(entityClass, entityName); // Cauldron - register EntityType for Bukkit + } + ++ // Cauldron start ++ private static void registerBukkitType(Class entityClass, String entityName) ++ { ++ ModContainer activeModContainer = Loader.instance().activeModContainer(); ++ String modId = "unknown"; ++ // fixup bad entity names from mods ++ if (entityName.contains(".")) ++ { ++ if ((entityName.indexOf(".") + 1) < entityName.length()) ++ entityName = entityName.substring(entityName.indexOf(".") + 1, entityName.length()); ++ } ++ entityName.replace("entity", ""); ++ if (entityName.startsWith("ent")) ++ entityName.replace("ent", ""); ++ entityName = entityName.replaceAll("[^A-Za-z0-9]", ""); // remove all non-digits/alphanumeric ++ if (activeModContainer != null) ++ modId = activeModContainer.getModId(); ++ entityName = modId + "-" + entityName; ++ entityTypeMap.put(entityClass, entityName); ++ entityClassMap.put(entityName, entityClass); ++ } ++ ++ // used by CraftCustomEntity ++ public static String getCustomEntityTypeName(Class entityClass) ++ { ++ return entityTypeMap.get(entityClass); ++ } ++ // Cauldron end ++ + public static void addSpawn(Class entityClass, int weightedProb, int min, int max, EnumCreatureType typeOfCreature, BiomeGenBase... biomes) + { + for (BiomeGenBase biome : biomes) diff --git a/patches/cpw/mods/fml/common/registry/GameData.java.patch b/patches/cpw/mods/fml/common/registry/GameData.java.patch new file mode 100644 index 0000000..0536ee0 --- /dev/null +++ b/patches/cpw/mods/fml/common/registry/GameData.java.patch @@ -0,0 +1,69 @@ +--- ../src-base/minecraft/cpw/mods/fml/common/registry/GameData.java ++++ ../src-work/minecraft/cpw/mods/fml/common/registry/GameData.java +@@ -14,7 +14,9 @@ + + import java.io.File; + import java.io.IOException; ++import java.util.ArrayList; + import java.util.BitSet; ++import java.util.Collections; + import java.util.HashMap; + import java.util.HashSet; + import java.util.Iterator; +@@ -1024,4 +1026,56 @@ + throw new RuntimeException("WHAT?"); + } + } ++ ++ // Cauldron start ++ public static void injectItemBukkitMaterials() ++ { ++ FMLControlledNamespacedRegistry itemRegistry = getItemRegistry(); ++ List ids = new ArrayList(); ++ ++ for (Item thing : itemRegistry.typeSafeIterable()) ++ { ++ ids.add(itemRegistry.getId(thing)); ++ } ++ ++ // sort by id ++ Collections.sort(ids); ++ ++ for (int id : ids) ++ { ++ Item item = itemRegistry.getRaw(id); ++ // inject item materials into Bukkit for FML ++ org.bukkit.Material material = org.bukkit.Material.addMaterial(id, itemRegistry.getNameForObject(item), false); ++ if (material != null) ++ { ++ FMLLog.info("Injected new Forge item material %s with ID %d.", material.name(), material.getId()); ++ } ++ } ++ } ++ ++ public static void injectBlockBukkitMaterials() ++ { ++ FMLControlledNamespacedRegistry blockRegistry = getBlockRegistry(); ++ List ids = new ArrayList(); ++ ++ for (Block block : blockRegistry.typeSafeIterable()) ++ { ++ ids.add(blockRegistry.getId(block)); ++ } ++ ++ // sort by id ++ Collections.sort(ids); ++ ++ for (int id : ids) ++ { ++ Block block = blockRegistry.getRaw(id); ++ // inject block materials into Bukkit for FML ++ org.bukkit.Material material = org.bukkit.Material.addMaterial(id, blockRegistry.getNameForObject(block), true); ++ if (material != null) ++ { ++ FMLLog.info("Injected new Forge block material %s with ID %d.", material.name(), material.getId()); ++ } ++ } ++ } ++ // Cauldron end + } diff --git a/patches/cpw/mods/fml/common/registry/GameRegistry.java.patch b/patches/cpw/mods/fml/common/registry/GameRegistry.java.patch new file mode 100644 index 0000000..86c77cd --- /dev/null +++ b/patches/cpw/mods/fml/common/registry/GameRegistry.java.patch @@ -0,0 +1,71 @@ +--- ../src-base/minecraft/cpw/mods/fml/common/registry/GameRegistry.java ++++ ../src-work/minecraft/cpw/mods/fml/common/registry/GameRegistry.java +@@ -53,6 +53,7 @@ + import cpw.mods.fml.common.LoaderException; + import cpw.mods.fml.common.LoaderState; + import cpw.mods.fml.common.ObfuscationReflectionHelper; ++import java.util.HashMap; // Cauldron + + public class GameRegistry + { +@@ -60,6 +61,10 @@ + private static Map worldGeneratorIndex = Maps.newHashMap(); + private static List fuelHandlers = Lists.newArrayList(); + private static List sortedGeneratorList; ++ // Cauldron start ++ private static Map configWorldGenCache = new HashMap(); ++ private static Map worldGenMap = new HashMap(); ++ // Cauldron end + + /** + * Register a world generator - something that inserts new block types into the world +@@ -70,12 +75,18 @@ + */ + public static void registerWorldGenerator(IWorldGenerator generator, int modGenerationWeight) + { ++ // Cauldron start - mod id's are not available during generateWorld so we must capture them here ++ String modId = Loader.instance().activeModContainer().getModId(); ++ modId = modId.replaceAll("[^A-Za-z0-9]", ""); // remove all non-digits/alphanumeric ++ modId.replace(" ", "_"); + worldGenerators.add(generator); + worldGeneratorIndex.put(generator, modGenerationWeight); + if (sortedGeneratorList != null) + { + sortedGeneratorList = null; + } ++ worldGenMap.put(generator.getClass().getName(), modId); ++ // Cauldron end + } + + /** +@@ -100,11 +111,27 @@ + long zSeed = fmlRandom.nextLong() >> 2 + 1L; + long chunkSeed = (xSeed * chunkX + zSeed * chunkZ) ^ worldSeed; + +- for (IWorldGenerator generator : sortedGeneratorList) ++ boolean before = ((net.minecraft.world.WorldServer) world).theChunkProviderServer.loadChunkOnProvideRequest; // Cauldron store value ++ ((net.minecraft.world.WorldServer) world).theChunkProviderServer.loadChunkOnProvideRequest = true; // Cauldron load chunks on provide requests ++ for (IWorldGenerator generator : worldGenerators) + { +- fmlRandom.setSeed(chunkSeed); +- generator.generate(fmlRandom, chunkX, chunkZ, world, chunkGenerator, chunkProvider); ++ // Cauldron start ++ if (!configWorldGenCache.containsKey(generator.getClass().getName())) ++ { ++ String modId = worldGenMap.get(generator.getClass().getName()); ++ String generatorName = ""; ++ generatorName = modId + "-" + generator.getClass().getSimpleName(); ++ boolean generatorEnabled = world.cauldronConfig.getBoolean("worldgen-" + generatorName, true); ++ configWorldGenCache.put(generator.getClass().getName(), generatorEnabled); ++ } ++ if (configWorldGenCache.get(generator.getClass().getName())) ++ { ++ fmlRandom.setSeed(chunkSeed); ++ generator.generate(fmlRandom, chunkX, chunkZ, world, chunkGenerator, chunkProvider); ++ } + } ++ ((net.minecraft.world.WorldServer)world).theChunkProviderServer.loadChunkOnProvideRequest = before; // reset ++ // Cauldron end + } + + private static void computeSortedGeneratorList() diff --git a/patches/cpw/mods/fml/relauncher/CoreModManager.java.patch b/patches/cpw/mods/fml/relauncher/CoreModManager.java.patch new file mode 100644 index 0000000..4111d3a --- /dev/null +++ b/patches/cpw/mods/fml/relauncher/CoreModManager.java.patch @@ -0,0 +1,47 @@ +--- ../src-base/minecraft/cpw/mods/fml/relauncher/CoreModManager.java ++++ ../src-work/minecraft/cpw/mods/fml/relauncher/CoreModManager.java +@@ -153,6 +153,9 @@ + + } + ++ // Cauldron - group output of @MCVersion warnings ++ private static List noVersionAnnotationCoreMods = new ArrayList(); ++ + public static void handleLaunch(File mcDir, LaunchClassLoader classLoader, FMLTweaker tweaker) + { + CoreModManager.mcDir = mcDir; +@@ -212,7 +215,19 @@ + loadCoreMod(classLoader, coreModClassName, null); + } + discoverCoreMods(mcDir, classLoader); +- ++ // Cauldron start - group output of @MCVersion warnings ++ if (!noVersionAnnotationCoreMods.isEmpty()) ++ { ++ FMLRelaunchLog ++ .warning("The following coremods do not have a @MCVersion annotation. They may cause problems if this is not the correct version of Minecraft for them."); ++ StringBuilder sb = new StringBuilder("Missing @MCVersion: "); ++ for (String className : noVersionAnnotationCoreMods) ++ { ++ sb.append(className).append(" "); ++ } ++ FMLRelaunchLog.warning(sb.toString()); ++ } ++ // Cauldron end + } + + private static void discoverCoreMods(File mcDir, LaunchClassLoader classLoader) +@@ -424,8 +439,11 @@ + MCVersion requiredMCVersion = coreModClazz.getAnnotation(IFMLLoadingPlugin.MCVersion.class); + if (!Arrays.asList(rootPlugins).contains(coreModClass) && (requiredMCVersion == null || Strings.isNullOrEmpty(requiredMCVersion.value()))) + { +- FMLRelaunchLog.log(Level.WARN, "The coremod %s does not have a MCVersion annotation, it may cause issues with this version of Minecraft", +- coreModClass); ++ // Cauldron start - group output of @MCVersion warnings ++ // FMLRelaunchLog.log(Level.WARN, "The coremod %s does not have a MCVersion annotation, it may cause issues with this version of Minecraft", ++ // coreModClass); ++ noVersionAnnotationCoreMods.add(coreModClass); ++ // Cauldron end + } + else if (requiredMCVersion != null && !FMLInjectionData.mccversion.equals(requiredMCVersion.value())) + { diff --git a/patches/net/minecraft/block/Block.java.patch b/patches/net/minecraft/block/Block.java.patch new file mode 100644 index 0000000..75c1970 --- /dev/null +++ b/patches/net/minecraft/block/Block.java.patch @@ -0,0 +1,52 @@ +--- ../src-base/minecraft/net/minecraft/block/Block.java ++++ ../src-work/minecraft/net/minecraft/block/Block.java +@@ -122,6 +122,7 @@ + private String unlocalizedName; + @SideOnly(Side.CLIENT) + protected IIcon blockIcon; ++ public boolean isForgeBlock; // Cauldron + private static final String __OBFID = "CL_00000199"; + + public final cpw.mods.fml.common.registry.RegistryDelegate delegate = +@@ -650,7 +651,7 @@ + + public void dropBlockAsItemWithChance(World p_149690_1_, int p_149690_2_, int p_149690_3_, int p_149690_4_, int p_149690_5_, float p_149690_6_, int p_149690_7_) + { +- if (!p_149690_1_.isRemote && !p_149690_1_.restoringBlockSnapshots) // do not drop items while restoring blockstates, prevents item dupe ++ if (!p_149690_1_.isRemote && (!p_149690_1_.restoringBlockSnapshots || !p_149690_1_.restoringBlockStates)) // do not drop items while restoring blockstates, prevents item dupe + { + ArrayList items = getDrops(p_149690_1_, p_149690_2_, p_149690_3_, p_149690_4_, p_149690_5_, p_149690_7_); + p_149690_6_ = ForgeEventFactory.fireBlockHarvesting(items, p_149690_1_, this, p_149690_2_, p_149690_3_, p_149690_4_, p_149690_5_, p_149690_7_, p_149690_6_, false, harvesters.get()); +@@ -667,7 +668,7 @@ + + protected void dropBlockAsItem(World p_149642_1_, int p_149642_2_, int p_149642_3_, int p_149642_4_, ItemStack p_149642_5_) + { +- if (!p_149642_1_.isRemote && p_149642_1_.getGameRules().getGameRuleBooleanValue("doTileDrops") && !p_149642_1_.restoringBlockSnapshots) // do not drop items while restoring blockstates, prevents item dupe ++ if (!p_149642_1_.isRemote && p_149642_1_.getGameRules().getGameRuleBooleanValue("doTileDrops") && (!p_149642_1_.restoringBlockSnapshots || !p_149642_1_.restoringBlockStates)) // do not drop items while restoring blockstates, prevents item dupe + { + if (captureDrops.get()) + { +@@ -1131,6 +1132,23 @@ + return this; + } + ++ // Spigot start ++ public static float range(float min, float value, float max) ++ { ++ if (value < min) ++ { ++ return min; ++ } ++ ++ if (value > max) ++ { ++ return max; ++ } ++ ++ return value; ++ } ++ // Spigot end ++ + @SideOnly(Side.CLIENT) + protected String getTextureName() + { diff --git a/patches/net/minecraft/block/BlockBasePressurePlate.java.patch b/patches/net/minecraft/block/BlockBasePressurePlate.java.patch new file mode 100644 index 0000000..ddfb36a --- /dev/null +++ b/patches/net/minecraft/block/BlockBasePressurePlate.java.patch @@ -0,0 +1,32 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockBasePressurePlate.java ++++ ../src-work/minecraft/net/minecraft/block/BlockBasePressurePlate.java +@@ -11,6 +11,8 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public abstract class BlockBasePressurePlate extends Block + { + private String field_150067_a; +@@ -122,7 +124,20 @@ + int i1 = this.func_150065_e(p_150062_1_, p_150062_2_, p_150062_3_, p_150062_4_); + boolean flag = p_150062_5_ > 0; + boolean flag1 = i1 > 0; ++ // CraftBukkit start - Interact Pressure Plate ++ org.bukkit.World bworld = p_150062_1_.getWorld(); ++ org.bukkit.plugin.PluginManager manager = p_150062_1_.getServer().getPluginManager(); + ++ if (flag != flag1) ++ { ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bworld.getBlockAt(p_150062_2_, p_150062_3_, p_150062_4_), p_150062_5_, i1); ++ manager.callEvent(eventRedstone); ++ flag1 = eventRedstone.getNewCurrent() > 0; ++ i1 = eventRedstone.getNewCurrent(); ++ } ++ ++ // CraftBukkit end ++ + if (p_150062_5_ != i1) + { + p_150062_1_.setBlockMetadataWithNotify(p_150062_2_, p_150062_3_, p_150062_4_, this.func_150066_d(i1), 2); diff --git a/patches/net/minecraft/block/BlockButton.java.patch b/patches/net/minecraft/block/BlockButton.java.patch new file mode 100644 index 0000000..bf1e5db --- /dev/null +++ b/patches/net/minecraft/block/BlockButton.java.patch @@ -0,0 +1,89 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockButton.java ++++ ../src-work/minecraft/net/minecraft/block/BlockButton.java +@@ -16,6 +16,10 @@ + + import net.minecraftforge.common.util.ForgeDirection; + import static net.minecraftforge.common.util.ForgeDirection.*; ++// CraftBukkit start ++import org.bukkit.event.block.BlockRedstoneEvent; ++import org.bukkit.event.entity.EntityInteractEvent; ++// CraftBukkit end + + public abstract class BlockButton extends Block + { +@@ -209,6 +213,19 @@ + } + else + { ++ // CraftBukkit start ++ org.bukkit.block.Block block = p_149727_1_.getWorld().getBlockAt(p_149727_2_, p_149727_3_, p_149727_4_); ++ int old = (k1 != 8) ? 15 : 0; ++ int current = (k1 == 8) ? 15 : 0; ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current); ++ p_149727_1_.getServer().getPluginManager().callEvent(eventRedstone); ++ ++ if ((eventRedstone.getNewCurrent() > 0) != (k1 == 8)) ++ { ++ return true; ++ } ++ ++ // CraftBukkit end + p_149727_1_.setBlockMetadataWithNotify(p_149727_2_, p_149727_3_, p_149727_4_, j1 + k1, 3); + p_149727_1_.markBlockRangeForRenderUpdate(p_149727_2_, p_149727_3_, p_149727_4_, p_149727_2_, p_149727_3_, p_149727_4_); + p_149727_1_.playSoundEffect((double)p_149727_2_ + 0.5D, (double)p_149727_3_ + 0.5D, (double)p_149727_4_ + 0.5D, "random.click", 0.3F, 0.6F); +@@ -262,6 +279,18 @@ + + if ((l & 8) != 0) + { ++ // CraftBukkit start ++ org.bukkit.block.Block block = p_149674_1_.getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_); ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 15, 0); ++ p_149674_1_.getServer().getPluginManager().callEvent(eventRedstone); ++ ++ if (eventRedstone.getNewCurrent() > 0) ++ { ++ return; ++ } ++ ++ // CraftBukkit end ++ + if (this.field_150047_a) + { + this.func_150046_n(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_); +@@ -309,6 +338,36 @@ + List list = p_150046_1_.getEntitiesWithinAABB(EntityArrow.class, AxisAlignedBB.getBoundingBox((double)p_150046_2_ + this.minX, (double)p_150046_3_ + this.minY, (double)p_150046_4_ + this.minZ, (double)p_150046_2_ + this.maxX, (double)p_150046_3_ + this.maxY, (double)p_150046_4_ + this.maxZ)); + boolean flag1 = !list.isEmpty(); + ++ // CraftBukkit start - Call interact event when arrows turn on wooden buttons ++ if (flag != flag1 && flag1) ++ { ++ org.bukkit.block.Block block = p_150046_1_.getWorld().getBlockAt(p_150046_2_, p_150046_3_, p_150046_4_); ++ boolean allowed = false; ++ ++ // If all of the events are cancelled block the button press, else allow ++ for (Object object : list) ++ { ++ if (object != null) ++ { ++ EntityInteractEvent event = new EntityInteractEvent(((Entity) object).getBukkitEntity(), block); ++ p_150046_1_.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ allowed = true; ++ break; ++ } ++ } ++ } ++ ++ if (!allowed) ++ { ++ return; ++ } ++ } ++ ++ // CraftBukkit end ++ + if (flag1 && !flag) + { + p_150046_1_.setBlockMetadataWithNotify(p_150046_2_, p_150046_3_, p_150046_4_, i1 | 8, 3); diff --git a/patches/net/minecraft/block/BlockCactus.java.patch b/patches/net/minecraft/block/BlockCactus.java.patch new file mode 100644 index 0000000..101c112 --- /dev/null +++ b/patches/net/minecraft/block/BlockCactus.java.patch @@ -0,0 +1,31 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockCactus.java ++++ ../src-work/minecraft/net/minecraft/block/BlockCactus.java +@@ -17,6 +17,8 @@ + import net.minecraftforge.common.util.ForgeDirection; + import net.minecraftforge.common.IPlantable; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class BlockCactus extends Block implements IPlantable + { + @SideOnly(Side.CLIENT) +@@ -47,9 +49,9 @@ + { + int i1 = p_149674_1_.getBlockMetadata(p_149674_2_, p_149674_3_, p_149674_4_); + +- if (i1 == 15) ++ if (i1 >= (byte) range(3, (p_149674_1_.growthOdds / p_149674_1_.getSpigotConfig().cactusModifier * 15) + 0.5F, 15)) // Spigot // Cauldron + { +- p_149674_1_.setBlock(p_149674_2_, p_149674_3_ + 1, p_149674_4_, this); ++ CraftEventFactory.handleBlockGrowEvent(p_149674_1_, p_149674_2_, p_149674_3_ + 1, p_149674_4_, this, 0); // CraftBukkit + p_149674_1_.setBlockMetadataWithNotify(p_149674_2_, p_149674_3_, p_149674_4_, 0, 4); + this.onNeighborBlockChange(p_149674_1_, p_149674_2_, p_149674_3_ + 1, p_149674_4_, this); + } +@@ -135,6 +137,7 @@ + + public void onEntityCollidedWithBlock(World p_149670_1_, int p_149670_2_, int p_149670_3_, int p_149670_4_, Entity p_149670_5_) + { ++ // Cauldron - moved CraftBukkit hook to func_145775_I() - doBlockCollisions + p_149670_5_.attackEntityFrom(DamageSource.cactus, 1.0F); + } + diff --git a/patches/net/minecraft/block/BlockCake.java.patch b/patches/net/minecraft/block/BlockCake.java.patch new file mode 100644 index 0000000..2e51ff8 --- /dev/null +++ b/patches/net/minecraft/block/BlockCake.java.patch @@ -0,0 +1,32 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockCake.java ++++ ../src-work/minecraft/net/minecraft/block/BlockCake.java +@@ -12,6 +12,10 @@ + import net.minecraft.util.IIcon; + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; ++// CraftBukkit start ++import net.minecraft.entity.player.EntityPlayerMP; ++import net.minecraft.network.play.server.S06PacketUpdateHealth; ++// CraftBukkit end + + public class BlockCake extends Block + { +@@ -104,7 +108,17 @@ + { + if (p_150036_5_.canEat(false)) + { +- p_150036_5_.getFoodStats().addStats(2, 0.1F); ++ // CraftBukkit start ++ int oldFoodLevel = p_150036_5_.getFoodStats().foodLevel; ++ org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(p_150036_5_, 2 + oldFoodLevel); ++ ++ if (!event.isCancelled()) ++ { ++ p_150036_5_.getFoodStats().addStats(event.getFoodLevel() - oldFoodLevel, 0.1F); ++ } ++ ++ ((EntityPlayerMP) p_150036_5_).playerNetServerHandler.sendPacket(new S06PacketUpdateHealth(((EntityPlayerMP) p_150036_5_).getBukkitEntity().getScaledHealth(), p_150036_5_.getFoodStats().foodLevel, p_150036_5_.getFoodStats().foodSaturationLevel)); ++ // CraftBukkit end + int l = p_150036_1_.getBlockMetadata(p_150036_2_, p_150036_3_, p_150036_4_) + 1; + + if (l >= 6) diff --git a/patches/net/minecraft/block/BlockCocoa.java.patch b/patches/net/minecraft/block/BlockCocoa.java.patch new file mode 100644 index 0000000..0bf8491 --- /dev/null +++ b/patches/net/minecraft/block/BlockCocoa.java.patch @@ -0,0 +1,12 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockCocoa.java ++++ ../src-work/minecraft/net/minecraft/block/BlockCocoa.java +@@ -51,7 +51,8 @@ + if (i1 < 2) + { + ++i1; +- p_149674_1_.setBlockMetadataWithNotify(p_149674_2_, p_149674_3_, p_149674_4_, i1 << 2 | getDirection(l), 2); ++ // CraftBukkit ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, this, i1 << 2 | getDirection(l)); + } + } + } diff --git a/patches/net/minecraft/block/BlockCommandBlock.java.patch b/patches/net/minecraft/block/BlockCommandBlock.java.patch new file mode 100644 index 0000000..39726f2 --- /dev/null +++ b/patches/net/minecraft/block/BlockCommandBlock.java.patch @@ -0,0 +1,34 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockCommandBlock.java ++++ ../src-work/minecraft/net/minecraft/block/BlockCommandBlock.java +@@ -10,6 +10,8 @@ + import net.minecraft.tileentity.TileEntityCommandBlock; + import net.minecraft.world.World; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockCommandBlock extends BlockContainer + { + private static final String __OBFID = "CL_00000219"; +@@ -31,13 +33,20 @@ + boolean flag = p_149695_1_.isBlockIndirectlyGettingPowered(p_149695_2_, p_149695_3_, p_149695_4_); + int l = p_149695_1_.getBlockMetadata(p_149695_2_, p_149695_3_, p_149695_4_); + boolean flag1 = (l & 1) != 0; ++ // CraftBukkit start ++ org.bukkit.block.Block bukkitBlock = p_149695_1_.getWorld().getBlockAt(p_149695_2_, p_149695_3_, p_149695_4_); ++ int old = flag1 ? 15 : 0; ++ int current = flag ? 15 : 0; ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, old, current); ++ p_149695_1_.getServer().getPluginManager().callEvent(eventRedstone); ++ // CraftBukkit end + +- if (flag && !flag1) ++ if (eventRedstone.getNewCurrent() > 0 && !(eventRedstone.getOldCurrent() > 0)) // CraftBukkit + { + p_149695_1_.setBlockMetadataWithNotify(p_149695_2_, p_149695_3_, p_149695_4_, l | 1, 4); + p_149695_1_.scheduleBlockUpdate(p_149695_2_, p_149695_3_, p_149695_4_, this, this.tickRate(p_149695_1_)); + } +- else if (!flag && flag1) ++ else if (!(eventRedstone.getNewCurrent() > 0) && eventRedstone.getOldCurrent() > 0) // CraftBukkit + { + p_149695_1_.setBlockMetadataWithNotify(p_149695_2_, p_149695_3_, p_149695_4_, l & -2, 4); + } diff --git a/patches/net/minecraft/block/BlockCrops.java.patch b/patches/net/minecraft/block/BlockCrops.java.patch new file mode 100644 index 0000000..4e2dd23 --- /dev/null +++ b/patches/net/minecraft/block/BlockCrops.java.patch @@ -0,0 +1,15 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockCrops.java ++++ ../src-work/minecraft/net/minecraft/block/BlockCrops.java +@@ -49,10 +49,9 @@ + { + float f = this.func_149864_n(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_); + +- if (p_149674_5_.nextInt((int)(25.0F / f) + 1) == 0) ++ if (p_149674_5_.nextInt((int)(p_149674_1_.growthOdds / p_149674_1_.getSpigotConfig().wheatModifier * (25.0F / f)) + 1) == 0) // Spigot // Cauldron + { +- ++l; +- p_149674_1_.setBlockMetadataWithNotify(p_149674_2_, p_149674_3_, p_149674_4_, l, 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, this, ++l); // CraftBukkit + } + } + } diff --git a/patches/net/minecraft/block/BlockDaylightDetector.java.patch b/patches/net/minecraft/block/BlockDaylightDetector.java.patch new file mode 100644 index 0000000..4106fcc --- /dev/null +++ b/patches/net/minecraft/block/BlockDaylightDetector.java.patch @@ -0,0 +1,10 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockDaylightDetector.java ++++ ../src-work/minecraft/net/minecraft/block/BlockDaylightDetector.java +@@ -73,6 +73,7 @@ + + if (l != i1) + { ++ i1 = org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(p_149957_1_, p_149957_2_, p_149957_3_, p_149957_4_, l, i1).getNewCurrent(); // CraftBukkit - Call BlockRedstoneEvent + p_149957_1_.setBlockMetadataWithNotify(p_149957_2_, p_149957_3_, p_149957_4_, i1, 3); + } + } diff --git a/patches/net/minecraft/block/BlockDispenser.java.patch b/patches/net/minecraft/block/BlockDispenser.java.patch new file mode 100644 index 0000000..c52cd2c --- /dev/null +++ b/patches/net/minecraft/block/BlockDispenser.java.patch @@ -0,0 +1,28 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockDispenser.java ++++ ../src-work/minecraft/net/minecraft/block/BlockDispenser.java +@@ -30,6 +30,7 @@ + { + public static final IRegistry dispenseBehaviorRegistry = new RegistryDefaulted(new BehaviorDefaultDispenseItem()); + protected Random field_149942_b = new Random(); ++ public static boolean eventFired = false; // CraftBukkit + @SideOnly(Side.CLIENT) + protected IIcon field_149944_M; + @SideOnly(Side.CLIENT) +@@ -124,7 +125,8 @@ + } + } + +- protected void func_149941_e(World p_149941_1_, int p_149941_2_, int p_149941_3_, int p_149941_4_) ++ // CraftBukkit - protected -> public ++ public void func_149941_e(World p_149941_1_, int p_149941_2_, int p_149941_3_, int p_149941_4_) + { + BlockSourceImpl blocksourceimpl = new BlockSourceImpl(p_149941_1_, p_149941_2_, p_149941_3_, p_149941_4_); + TileEntityDispenser tileentitydispenser = (TileEntityDispenser)blocksourceimpl.getBlockTileEntity(); +@@ -145,6 +147,7 @@ + if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider) + { + ItemStack itemstack1 = ibehaviordispenseitem.dispense(blocksourceimpl, itemstack); ++ eventFired = false; // CraftBukkit - reset event status + tileentitydispenser.setInventorySlotContents(l, itemstack1.stackSize == 0 ? null : itemstack1); + } + } diff --git a/patches/net/minecraft/block/BlockDoor.java.patch b/patches/net/minecraft/block/BlockDoor.java.patch new file mode 100644 index 0000000..1f0425a --- /dev/null +++ b/patches/net/minecraft/block/BlockDoor.java.patch @@ -0,0 +1,48 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockDoor.java ++++ ../src-work/minecraft/net/minecraft/block/BlockDoor.java +@@ -16,6 +16,8 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockDoor extends Block + { + @SideOnly(Side.CLIENT) +@@ -329,15 +331,32 @@ + { + this.dropBlockAsItem(p_149695_1_, p_149695_2_, p_149695_3_, p_149695_4_, l, 0); + } ++ ++ // CraftBukkit start + } +- else ++ else if (p_149695_5_.canProvidePower()) + { +- boolean flag1 = p_149695_1_.isBlockIndirectlyGettingPowered(p_149695_2_, p_149695_3_, p_149695_4_) || p_149695_1_.isBlockIndirectlyGettingPowered(p_149695_2_, p_149695_3_ + 1, p_149695_4_); ++ org.bukkit.World bworld = p_149695_1_.getWorld(); ++ org.bukkit.block.Block bukkitBlock = bworld.getBlockAt(p_149695_2_, p_149695_3_, p_149695_4_); ++ org.bukkit.block.Block blockTop = bworld.getBlockAt(p_149695_2_, p_149695_3_ + 1, p_149695_4_); ++ int power = bukkitBlock.getBlockPower(); ++ int powerTop = blockTop.getBlockPower(); + +- if ((flag1 || p_149695_5_.canProvidePower()) && p_149695_5_ != this) ++ if (powerTop > power) + { +- this.func_150014_a(p_149695_1_, p_149695_2_, p_149695_3_, p_149695_4_, flag1); ++ power = powerTop; + } ++ ++ int oldPower = (p_149695_1_.getBlockMetadata(p_149695_2_, p_149695_3_, p_149695_4_) & 4) > 0 ? 15 : 0; ++ ++ if (oldPower == 0 ^ power == 0) ++ { ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, oldPower, power); ++ p_149695_1_.getServer().getPluginManager().callEvent(eventRedstone); ++ this.func_150014_a(p_149695_1_, p_149695_2_, p_149695_3_, p_149695_4_, eventRedstone.getNewCurrent() > 0); ++ } ++ ++ // CraftBukkit end + } + } + else diff --git a/patches/net/minecraft/block/BlockDragonEgg.java.patch b/patches/net/minecraft/block/BlockDragonEgg.java.patch new file mode 100644 index 0000000..8aef0f7 --- /dev/null +++ b/patches/net/minecraft/block/BlockDragonEgg.java.patch @@ -0,0 +1,44 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockDragonEgg.java ++++ ../src-work/minecraft/net/minecraft/block/BlockDragonEgg.java +@@ -10,6 +10,8 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++import org.bukkit.event.block.BlockFromToEvent; // CraftBukkit ++ + public class BlockDragonEgg extends Block + { + private static final String __OBFID = "CL_00000232"; +@@ -43,7 +45,8 @@ + + if (!BlockFalling.fallInstantly && p_150018_1_.checkChunksExist(p_150018_2_ - b0, p_150018_3_ - b0, p_150018_4_ - b0, p_150018_2_ + b0, p_150018_3_ + b0, p_150018_4_ + b0)) + { +- EntityFallingBlock entityfallingblock = new EntityFallingBlock(p_150018_1_, (double)((float)p_150018_2_ + 0.5F), (double)((float)p_150018_3_ + 0.5F), (double)((float)p_150018_4_ + 0.5F), this); ++ // CraftBukkit - added data ++ EntityFallingBlock entityfallingblock = new EntityFallingBlock(p_150018_1_, (double)((float) p_150018_2_ + 0.5F), (double)((float) p_150018_3_ + 0.5F), (double)((float) p_150018_4_ + 0.5F), this, p_150018_1_.getBlockMetadata(p_150018_2_, p_150018_3_, p_150018_4_)); + p_150018_1_.spawnEntityInWorld(entityfallingblock); + } + else +@@ -86,6 +89,22 @@ + + if (p_150019_1_.getBlock(i1, j1, k1).blockMaterial == Material.air) + { ++ // CraftBukkit start ++ org.bukkit.block.Block from = p_150019_1_.getWorld().getBlockAt(p_150019_2_, p_150019_3_, p_150019_4_); ++ org.bukkit.block.Block to = p_150019_1_.getWorld().getBlockAt(i1, j1, k1); ++ BlockFromToEvent event = new BlockFromToEvent(from, to); ++ org.bukkit.Bukkit.getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ ++ i1 = event.getToBlock().getX(); ++ j1 = event.getToBlock().getY(); ++ k1 = event.getToBlock().getZ(); ++ // CraftBukkit end ++ + if (!p_150019_1_.isRemote) + { + p_150019_1_.setBlock(i1, j1, k1, this, p_150019_1_.getBlockMetadata(p_150019_2_, p_150019_3_, p_150019_4_), 2); diff --git a/patches/net/minecraft/block/BlockDropper.java.patch b/patches/net/minecraft/block/BlockDropper.java.patch new file mode 100644 index 0000000..5b1842d --- /dev/null +++ b/patches/net/minecraft/block/BlockDropper.java.patch @@ -0,0 +1,59 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockDropper.java ++++ ../src-work/minecraft/net/minecraft/block/BlockDropper.java +@@ -13,6 +13,11 @@ + import net.minecraft.tileentity.TileEntityHopper; + import net.minecraft.util.Facing; + import net.minecraft.world.World; ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.inventory.InventoryMoveItemEvent; ++import net.minecraft.inventory.InventoryLargeChest; ++// CraftBukkit end + + public class BlockDropper extends BlockDispenser + { +@@ -38,7 +43,7 @@ + return new TileEntityDropper(); + } + +- protected void func_149941_e(World p_149941_1_, int p_149941_2_, int p_149941_3_, int p_149941_4_) ++ public void func_149941_e(World p_149941_1_, int p_149941_2_, int p_149941_3_, int p_149941_4_) // CraftBukkit - protected -> public + { + BlockSourceImpl blocksourceimpl = new BlockSourceImpl(p_149941_1_, p_149941_2_, p_149941_3_, p_149941_4_); + TileEntityDispenser tileentitydispenser = (TileEntityDispenser)blocksourceimpl.getBlockTileEntity(); +@@ -60,10 +65,33 @@ + + if (iinventory != null) + { +- itemstack1 = TileEntityHopper.func_145889_a(iinventory, itemstack.copy().splitStack(1), Facing.oppositeSide[i1]); ++ // CraftBukkit start - Fire event when pushing items into other inventories ++ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(itemstack.copy().splitStack(1)); ++ org.bukkit.inventory.Inventory destinationInventory; + +- if (itemstack1 == null) ++ // Have to special case large chests as they work oddly ++ if (iinventory instanceof InventoryLargeChest) + { ++ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); ++ } ++ else ++ { ++ destinationInventory = iinventory.getOwner().getInventory(); ++ } ++ ++ InventoryMoveItemEvent event = new InventoryMoveItemEvent(tileentitydispenser.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true); ++ p_149941_1_.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ ++ itemstack1 = TileEntityHopper.func_145889_a(iinventory, CraftItemStack.asNMSCopy(event.getItem()), Facing.oppositeSide[i1]); ++ ++ if (event.getItem().equals(oitemstack) && itemstack1 == null) ++ { ++ // CraftBukkit end + itemstack1 = itemstack.copy(); + + if (--itemstack1.stackSize == 0) diff --git a/patches/net/minecraft/block/BlockDynamicLiquid.java.patch b/patches/net/minecraft/block/BlockDynamicLiquid.java.patch new file mode 100644 index 0000000..96360f0 --- /dev/null +++ b/patches/net/minecraft/block/BlockDynamicLiquid.java.patch @@ -0,0 +1,162 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockDynamicLiquid.java ++++ ../src-work/minecraft/net/minecraft/block/BlockDynamicLiquid.java +@@ -5,6 +5,11 @@ + import net.minecraft.init.Blocks; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.block.BlockFace; ++import org.bukkit.event.block.BlockFromToEvent; ++// CraftBukkit end ++ + public class BlockDynamicLiquid extends BlockLiquid + { + int field_149815_a; +@@ -37,6 +42,12 @@ + int i1 = this.tickRate(p_149674_1_); + int j1; + ++ // Cauldron - move CB edit to after variable initialization for coremod compatibility ++ // CraftBukkit start ++ org.bukkit.World bworld = p_149674_1_.getWorld(); ++ org.bukkit.Server server = p_149674_1_.getServer(); ++ org.bukkit.block.Block source = bworld == null ? null : bworld.getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_); ++ // CraftBukkit end + if (l > 0) + { + byte b1 = -100; +@@ -66,17 +77,22 @@ + } + } + +- if (this.field_149815_a >= 2 && this.blockMaterial == Material.water) ++ // Cauldron start - allow disabling infinite water sources ++ if(net.minecraft.server.MinecraftServer.getServer().cauldronConfig.infiniteWaterSource.getValue()) + { +- if (p_149674_1_.getBlock(p_149674_2_, p_149674_3_ - 1, p_149674_4_).getMaterial().isSolid()) ++ if (this.field_149815_a >= 2 && this.blockMaterial == Material.water) + { +- j1 = 0; ++ if (p_149674_1_.getBlock(p_149674_2_, p_149674_3_ - 1, p_149674_4_).getMaterial().isSolid()) ++ { ++ j1 = 0; ++ } ++ else if (p_149674_1_.getBlock(p_149674_2_, p_149674_3_ - 1, p_149674_4_).getMaterial() == this.blockMaterial && p_149674_1_.getBlockMetadata(p_149674_2_, p_149674_3_ - 1, p_149674_4_) == 0) ++ { ++ j1 = 0; ++ } + } +- else if (p_149674_1_.getBlock(p_149674_2_, p_149674_3_ - 1, p_149674_4_).getMaterial() == this.blockMaterial && p_149674_1_.getBlockMetadata(p_149674_2_, p_149674_3_ - 1, p_149674_4_) == 0) +- { +- j1 = 0; +- } + } ++ // Cauldron end + + if (this.blockMaterial == Material.lava && l < 8 && j1 < 8 && j1 > l && p_149674_5_.nextInt(4) != 0) + { +@@ -89,6 +105,13 @@ + { + this.func_149811_n(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_); + } ++ // Cauldron start - allow lava decaying at a 'natural' rate - see https://mojang.atlassian.net/browse/MC-4631 Lava decay fails to schedule block update ++ else if (net.minecraft.server.MinecraftServer.getServer().cauldronConfig.flowingLavaDecay.getValue()) ++ { ++ // Ensure that even if the flow decay was skipped, it will retry at the material's natural flow period. ++ p_149674_1_.scheduleBlockUpdate(p_149674_2_, p_149674_3_, p_149674_4_, this, this.tickRate(p_149674_1_)); ++ } ++ // Cauldron end + } + else + { +@@ -113,21 +136,34 @@ + + if (this.func_149809_q(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_)) + { +- if (this.blockMaterial == Material.lava && p_149674_1_.getBlock(p_149674_2_, p_149674_3_ - 1, p_149674_4_).getMaterial() == Material.water) ++ // CraftBukkit start - Send "down" to the server ++ BlockFromToEvent event = new BlockFromToEvent(source, BlockFace.DOWN); ++ ++ if (server != null) + { +- p_149674_1_.setBlock(p_149674_2_, p_149674_3_ - 1, p_149674_4_, Blocks.stone); +- this.func_149799_m(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_); +- return; ++ server.getPluginManager().callEvent(event); + } + +- if (l >= 8) ++ if (!event.isCancelled()) + { +- this.func_149813_h(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_, l); ++ if (this.blockMaterial == Material.lava && p_149674_1_.getBlock(p_149674_2_, p_149674_3_ - 1, p_149674_4_).getMaterial() == Material.water) ++ { ++ p_149674_1_.setBlock(p_149674_2_, p_149674_3_ - 1, p_149674_4_, Blocks.stone); ++ this.func_149799_m(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_); ++ return; ++ } ++ ++ if (l >= 8) ++ { ++ this.func_149813_h(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_, l); ++ } ++ else ++ { ++ this.func_149813_h(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_, l + 8); ++ } + } +- else +- { +- this.func_149813_h(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_, l + 8); +- } ++ ++ // CraftBukkit end + } + else if (l >= 0 && (l == 0 || this.func_149807_p(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_))) + { +@@ -144,25 +180,31 @@ + return; + } + +- if (aboolean[0]) +- { +- this.func_149813_h(p_149674_1_, p_149674_2_ - 1, p_149674_3_, p_149674_4_, j1); +- } ++ // CraftBukkit start - All four cardinal directions. Do not change the order! ++ BlockFace[] faces = new BlockFace[] { BlockFace.WEST, BlockFace.EAST, BlockFace.NORTH, BlockFace.SOUTH }; ++ int index = 0; + +- if (aboolean[1]) ++ for (BlockFace currentFace : faces) + { +- this.func_149813_h(p_149674_1_, p_149674_2_ + 1, p_149674_3_, p_149674_4_, j1); +- } ++ if (aboolean[index]) ++ { ++ BlockFromToEvent event = new BlockFromToEvent(source, currentFace); + +- if (aboolean[2]) +- { +- this.func_149813_h(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_ - 1, j1); +- } ++ if (server != null) ++ { ++ server.getPluginManager().callEvent(event); ++ } + +- if (aboolean[3]) +- { +- this.func_149813_h(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_ + 1, j1); ++ if (!event.isCancelled()) ++ { ++ this.func_149813_h(p_149674_1_, p_149674_2_ + currentFace.getModX(), p_149674_3_, p_149674_4_ + currentFace.getModZ(), j1); ++ } ++ } ++ ++ index++; + } ++ ++ // CraftBukkit end + } + } + diff --git a/patches/net/minecraft/block/BlockEndPortal.java.patch b/patches/net/minecraft/block/BlockEndPortal.java.patch new file mode 100644 index 0000000..90f7b51 --- /dev/null +++ b/patches/net/minecraft/block/BlockEndPortal.java.patch @@ -0,0 +1,22 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockEndPortal.java ++++ ../src-work/minecraft/net/minecraft/block/BlockEndPortal.java +@@ -15,6 +15,8 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++import org.bukkit.event.entity.EntityPortalEnterEvent; // CraftBukkit ++ + public class BlockEndPortal extends BlockContainer + { + public static boolean field_149948_a; +@@ -64,6 +66,10 @@ + { + if (p_149670_5_.ridingEntity == null && p_149670_5_.riddenByEntity == null && !p_149670_1_.isRemote) + { ++ // CraftBukkit start - Entity in portal ++ EntityPortalEnterEvent event = new EntityPortalEnterEvent(p_149670_5_.getBukkitEntity(), new org.bukkit.Location(p_149670_1_.getWorld(), p_149670_2_, p_149670_3_, p_149670_4_)); ++ p_149670_1_.getServer().getPluginManager().callEvent(event); ++ // CraftBukkit end + p_149670_5_.travelToDimension(1); + } + } diff --git a/patches/net/minecraft/block/BlockFarmland.java.patch b/patches/net/minecraft/block/BlockFarmland.java.patch new file mode 100644 index 0000000..d548dc6 --- /dev/null +++ b/patches/net/minecraft/block/BlockFarmland.java.patch @@ -0,0 +1,57 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockFarmland.java ++++ ../src-work/minecraft/net/minecraft/block/BlockFarmland.java +@@ -15,6 +15,11 @@ + import net.minecraftforge.common.IPlantable; + import net.minecraftforge.common.util.ForgeDirection; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityInteractEvent; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++// CraftBukkit end ++ + public class BlockFarmland extends Block + { + @SideOnly(Side.CLIENT) +@@ -64,6 +69,15 @@ + } + else if (!this.func_149822_e(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_)) + { ++ // CraftBukkit start ++ org.bukkit.block.Block block = p_149674_1_.getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_); ++ ++ if (CraftEventFactory.callBlockFadeEvent(block, Blocks.dirt).isCancelled()) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + p_149674_1_.setBlock(p_149674_2_, p_149674_3_, p_149674_4_, Blocks.dirt); + } + } +@@ -82,6 +96,26 @@ + return; + } + ++ // CraftBukkit start - Interact soil ++ // Cauldron start - validate data before sending event ++ org.bukkit.event.Cancellable cancellable = null; ++ ++ if (p_149746_5_ instanceof EntityPlayer) ++ { ++ cancellable = CraftEventFactory.callPlayerInteractEvent((EntityPlayer) p_149746_5_, org.bukkit.event.block.Action.PHYSICAL, p_149746_2_, p_149746_3_, p_149746_4_, -1, null); ++ } ++ else if (p_149746_1_ != null && p_149746_1_.getWorld() != null && p_149746_5_ != null) ++ { ++ cancellable = new EntityInteractEvent(p_149746_5_.getBukkitEntity(), p_149746_1_.getWorld().getBlockAt(p_149746_2_, p_149746_3_, p_149746_4_)); ++ p_149746_1_.getServer().getPluginManager().callEvent((EntityInteractEvent) cancellable); ++ } ++ ++ if (cancellable != null && cancellable.isCancelled()) ++ { ++ return; ++ } ++ // Cauldron end ++ // CraftBukkit end + p_149746_1_.setBlock(p_149746_2_, p_149746_3_, p_149746_4_, Blocks.dirt); + } + } diff --git a/patches/net/minecraft/block/BlockFire.java.patch b/patches/net/minecraft/block/BlockFire.java.patch new file mode 100644 index 0000000..a25bf69 --- /dev/null +++ b/patches/net/minecraft/block/BlockFire.java.patch @@ -0,0 +1,129 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockFire.java ++++ ../src-work/minecraft/net/minecraft/block/BlockFire.java +@@ -17,6 +17,11 @@ + import net.minecraft.world.WorldProviderEnd; + import net.minecraftforge.common.util.ForgeDirection; + import static net.minecraftforge.common.util.ForgeDirection.*; ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.block.BlockBurnEvent; ++import org.bukkit.event.block.BlockSpreadEvent; ++// CraftBukkit end + + public class BlockFire extends Block + { +@@ -105,12 +110,12 @@ + + if (!this.canPlaceBlockAt(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_)) + { +- p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_); ++ fireExtinguished(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_); // CraftBukkit - invalid place location + } + + if (!flag && p_149674_1_.isRaining() && (p_149674_1_.canLightningStrikeAt(p_149674_2_, p_149674_3_, p_149674_4_) || p_149674_1_.canLightningStrikeAt(p_149674_2_ - 1, p_149674_3_, p_149674_4_) || p_149674_1_.canLightningStrikeAt(p_149674_2_ + 1, p_149674_3_, p_149674_4_) || p_149674_1_.canLightningStrikeAt(p_149674_2_, p_149674_3_, p_149674_4_ - 1) || p_149674_1_.canLightningStrikeAt(p_149674_2_, p_149674_3_, p_149674_4_ + 1))) + { +- p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_); ++ fireExtinguished(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_); // CraftBukkit - extinguished by rain + } + else + { +@@ -127,12 +132,12 @@ + { + if (!World.doesBlockHaveSolidTopSurface(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_) || l > 3) + { +- p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_); ++ fireExtinguished(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_); // CraftBukkit - burn out of inflammable block + } + } + else if (!flag && !this.canCatchFire(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_, UP) && l == 15 && p_149674_5_.nextInt(4) == 0) + { +- p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_); ++ fireExtinguished(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_); // CraftBukkit - burn out + } + else + { +@@ -186,7 +191,29 @@ + k2 = 15; + } + +- p_149674_1_.setBlock(i1, k1, j1, this, k2, 3); ++ // CraftBukkit start - Call to stop spread of fire ++ if (p_149674_1_.getBlock(i1, k1, j1) != Blocks.fire) ++ { ++ if (CraftEventFactory.callBlockIgniteEvent(p_149674_1_, i1, k1, j1, p_149674_2_, p_149674_3_, p_149674_4_).isCancelled()) ++ { ++ continue; ++ } ++ ++ org.bukkit.Server server = p_149674_1_.getServer(); ++ org.bukkit.World bworld = p_149674_1_.getWorld(); ++ org.bukkit.block.BlockState blockState = bworld.getBlockAt(i1, k1, j1).getState(); ++ blockState.setTypeId(Block.getIdFromBlock(this)); ++ blockState.setData(new org.bukkit.material.MaterialData(Block.getIdFromBlock(this), (byte) k2)); ++ BlockSpreadEvent spreadEvent = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_), blockState); ++ server.getPluginManager().callEvent(spreadEvent); ++ ++ if (!spreadEvent.isCancelled()) ++ { ++ blockState.update(true); ++ } ++ } ++ ++ // CraftBukkit end + } + } + } +@@ -216,7 +243,18 @@ + if (p_149841_6_.nextInt(p_149841_5_) < j1) + { + boolean flag = p_149841_1_.getBlock(p_149841_2_, p_149841_3_, p_149841_4_) == Blocks.tnt; ++ // CraftBukkit start ++ org.bukkit.block.Block theBlock = p_149841_1_.getWorld().getBlockAt(p_149841_2_, p_149841_3_, p_149841_4_); ++ BlockBurnEvent event = new BlockBurnEvent(theBlock); ++ p_149841_1_.getServer().getPluginManager().callEvent(event); + ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ ++ // CraftBukkit end ++ + if (p_149841_6_.nextInt(p_149841_7_ + 10) < 5 && !p_149841_1_.canLightningStrikeAt(p_149841_2_, p_149841_3_, p_149841_4_)) + { + int k1 = p_149841_7_ + p_149841_6_.nextInt(5) / 4; +@@ -297,7 +335,7 @@ + { + if (!World.doesBlockHaveSolidTopSurface(p_149695_1_, p_149695_2_, p_149695_3_ - 1, p_149695_4_) && !this.canNeighborBurn(p_149695_1_, p_149695_2_, p_149695_3_, p_149695_4_)) + { +- p_149695_1_.setBlockToAir(p_149695_2_, p_149695_3_, p_149695_4_); ++ fireExtinguished(p_149695_1_, p_149695_2_, p_149695_3_, p_149695_4_); // CraftBukkit - fuel block gone + } + } + +@@ -307,7 +345,7 @@ + { + if (!World.doesBlockHaveSolidTopSurface(p_149726_1_, p_149726_2_, p_149726_3_ - 1, p_149726_4_) && !this.canNeighborBurn(p_149726_1_, p_149726_2_, p_149726_3_, p_149726_4_)) + { +- p_149726_1_.setBlockToAir(p_149726_2_, p_149726_3_, p_149726_4_); ++ fireExtinguished(p_149726_1_, p_149726_2_, p_149726_3_, p_149726_4_); // CraftBukkit - fuel block broke + } + else + { +@@ -398,6 +436,16 @@ + } + } + ++ // CraftBukkit start ++ private void fireExtinguished(World world, int x, int y, int z) ++ { ++ if (!CraftEventFactory.callBlockFadeEvent(world.getWorld().getBlockAt(x, y, z), Blocks.air).isCancelled()) ++ { ++ world.setBlockToAir(x, y, z); ++ } ++ } ++ // CraftBukkit end ++ + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister p_149651_1_) + { diff --git a/patches/net/minecraft/block/BlockGrass.java.patch b/patches/net/minecraft/block/BlockGrass.java.patch new file mode 100644 index 0000000..9759c5d --- /dev/null +++ b/patches/net/minecraft/block/BlockGrass.java.patch @@ -0,0 +1,64 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockGrass.java ++++ ../src-work/minecraft/net/minecraft/block/BlockGrass.java +@@ -15,6 +15,12 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import org.bukkit.block.BlockState; ++import org.bukkit.event.block.BlockSpreadEvent; ++import org.bukkit.event.block.BlockFadeEvent; ++// CraftBukkit end ++ + public class BlockGrass extends Block implements IGrowable + { + private static final Logger logger = LogManager.getLogger(); +@@ -45,11 +51,25 @@ + { + if (p_149674_1_.getBlockLightValue(p_149674_2_, p_149674_3_ + 1, p_149674_4_) < 4 && p_149674_1_.getBlockLightOpacity(p_149674_2_, p_149674_3_ + 1, p_149674_4_) > 2) + { +- p_149674_1_.setBlock(p_149674_2_, p_149674_3_, p_149674_4_, Blocks.dirt); ++ // CraftBukkit start ++ org.bukkit.World bworld = p_149674_1_.getWorld(); ++ BlockState blockState = bworld.getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_).getState(); ++ blockState.setTypeId(Block.getIdFromBlock(Blocks.dirt)); ++ BlockFadeEvent event = new BlockFadeEvent(blockState.getBlock(), blockState); ++ p_149674_1_.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ blockState.update(true); ++ } ++ ++ // CraftBukkit end + } + else if (p_149674_1_.getBlockLightValue(p_149674_2_, p_149674_3_ + 1, p_149674_4_) >= 9) + { +- for (int l = 0; l < 4; ++l) ++ int numGrowth = Math.min(4, Math.max(20, (int)(4 * 100F / p_149674_1_.growthOdds))); // Spigot ++ ++ for (int l = 0; l < numGrowth; ++l) // Spigot + { + int i1 = p_149674_2_ + p_149674_5_.nextInt(3) - 1; + int j1 = p_149674_3_ + p_149674_5_.nextInt(5) - 3; +@@ -58,7 +78,19 @@ + + if (p_149674_1_.getBlock(i1, j1, k1) == Blocks.dirt && p_149674_1_.getBlockMetadata(i1, j1, k1) == 0 && p_149674_1_.getBlockLightValue(i1, j1 + 1, k1) >= 4 && p_149674_1_.getBlockLightOpacity(i1, j1 + 1, k1) <= 2) + { +- p_149674_1_.setBlock(i1, j1, k1, Blocks.grass); ++ // CraftBukkit start ++ org.bukkit.World bworld = p_149674_1_.getWorld(); ++ BlockState blockState = bworld.getBlockAt(i1, j1, k1).getState(); ++ blockState.setTypeId(Block.getIdFromBlock(Blocks.grass)); ++ BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_), blockState); ++ p_149674_1_.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ blockState.update(true); ++ } ++ ++ // CraftBukkit end + } + } + } diff --git a/patches/net/minecraft/block/BlockHopper.java.patch b/patches/net/minecraft/block/BlockHopper.java.patch new file mode 100644 index 0000000..265bffe --- /dev/null +++ b/patches/net/minecraft/block/BlockHopper.java.patch @@ -0,0 +1,19 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockHopper.java ++++ ../src-work/minecraft/net/minecraft/block/BlockHopper.java +@@ -22,6 +22,7 @@ + import net.minecraft.util.IIcon; + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; ++import net.minecraft.inventory.IInventory; // CraftBukkit + + public class BlockHopper extends BlockContainer + { +@@ -210,7 +211,7 @@ + + public static int getDirectionFromMetadata(int p_149918_0_) + { +- return p_149918_0_ & 7; ++ return Math.min(p_149918_0_ & 7, 5); // CraftBukkit - Fix AIOOBE in callers + } + + public static boolean func_149917_c(int p_149917_0_) diff --git a/patches/net/minecraft/block/BlockIce.java.patch b/patches/net/minecraft/block/BlockIce.java.patch new file mode 100644 index 0000000..f710f5b --- /dev/null +++ b/patches/net/minecraft/block/BlockIce.java.patch @@ -0,0 +1,17 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockIce.java ++++ ../src-work/minecraft/net/minecraft/block/BlockIce.java +@@ -86,6 +86,14 @@ + { + if (p_149674_1_.getSavedLightValue(EnumSkyBlock.Block, p_149674_2_, p_149674_3_, p_149674_4_) > 11 - this.getLightOpacity()) + { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(p_149674_1_.getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_), Blocks.water).isCancelled()) ++ { ++ return; ++ } ++ ++ // CraftBukkit end ++ + if (p_149674_1_.provider.isHellWorld) + { + p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_); diff --git a/patches/net/minecraft/block/BlockJukebox.java.patch b/patches/net/minecraft/block/BlockJukebox.java.patch new file mode 100644 index 0000000..4080aec --- /dev/null +++ b/patches/net/minecraft/block/BlockJukebox.java.patch @@ -0,0 +1,26 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockJukebox.java ++++ ../src-work/minecraft/net/minecraft/block/BlockJukebox.java +@@ -163,8 +163,23 @@ + + public void func_145857_a(ItemStack p_145857_1_) + { ++ // CraftBukkit start - There can only be one ++ if (p_145857_1_ != null) ++ { ++ p_145857_1_.stackSize = 1; ++ } ++ ++ // CraftBukkit end + this.field_145858_a = p_145857_1_; + this.markDirty(); + } ++ ++ // Cauldron start ++ @Override ++ public boolean canUpdate() ++ { ++ return false; ++ } ++ // Cauldron end + } + } diff --git a/patches/net/minecraft/block/BlockLeaves.java.patch b/patches/net/minecraft/block/BlockLeaves.java.patch new file mode 100644 index 0000000..9e9d924 --- /dev/null +++ b/patches/net/minecraft/block/BlockLeaves.java.patch @@ -0,0 +1,28 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockLeaves.java ++++ ../src-work/minecraft/net/minecraft/block/BlockLeaves.java +@@ -18,6 +18,8 @@ + import net.minecraft.world.World; + import net.minecraftforge.common.IShearable; + ++import org.bukkit.event.block.LeavesDecayEvent; // CraftBukkit ++ + public abstract class BlockLeaves extends BlockLeavesBase implements IShearable + { + int[] field_150128_a; +@@ -222,6 +224,16 @@ + + private void removeLeaves(World p_150126_1_, int p_150126_2_, int p_150126_3_, int p_150126_4_) + { ++ // CraftBukkit start ++ LeavesDecayEvent event = new LeavesDecayEvent(p_150126_1_.getWorld().getBlockAt(p_150126_2_, p_150126_3_, p_150126_4_)); ++ p_150126_1_.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + this.dropBlockAsItem(p_150126_1_, p_150126_2_, p_150126_3_, p_150126_4_, p_150126_1_.getBlockMetadata(p_150126_2_, p_150126_3_, p_150126_4_), 0); + p_150126_1_.setBlockToAir(p_150126_2_, p_150126_3_, p_150126_4_); + } diff --git a/patches/net/minecraft/block/BlockLever.java.patch b/patches/net/minecraft/block/BlockLever.java.patch new file mode 100644 index 0000000..5e79d6a --- /dev/null +++ b/patches/net/minecraft/block/BlockLever.java.patch @@ -0,0 +1,31 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockLever.java ++++ ../src-work/minecraft/net/minecraft/block/BlockLever.java +@@ -13,6 +13,8 @@ + import net.minecraftforge.common.util.ForgeDirection; + import static net.minecraftforge.common.util.ForgeDirection.*; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockLever extends Block + { + private static final String __OBFID = "CL_00000264"; +@@ -270,6 +272,19 @@ + int i1 = p_149727_1_.getBlockMetadata(p_149727_2_, p_149727_3_, p_149727_4_); + int j1 = i1 & 7; + int k1 = 8 - (i1 & 8); ++ // CraftBukkit start - Interact Lever ++ org.bukkit.block.Block block = p_149727_1_.getWorld().getBlockAt(p_149727_2_, p_149727_3_, p_149727_4_); ++ int old = (k1 != 8) ? 15 : 0; ++ int current = (k1 == 8) ? 15 : 0; ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, old, current); ++ p_149727_1_.getServer().getPluginManager().callEvent(eventRedstone); ++ ++ if ((eventRedstone.getNewCurrent() > 0) != (k1 == 8)) ++ { ++ return true; ++ } ++ ++ // CraftBukkit end + p_149727_1_.setBlockMetadataWithNotify(p_149727_2_, p_149727_3_, p_149727_4_, j1 + k1, 3); + p_149727_1_.playSoundEffect((double)p_149727_2_ + 0.5D, (double)p_149727_3_ + 0.5D, (double)p_149727_4_ + 0.5D, "random.click", 0.3F, k1 > 0 ? 0.6F : 0.5F); + p_149727_1_.notifyBlocksOfNeighborChange(p_149727_2_, p_149727_3_, p_149727_4_, this); diff --git a/patches/net/minecraft/block/BlockMushroom.java.patch b/patches/net/minecraft/block/BlockMushroom.java.patch new file mode 100644 index 0000000..c494ff1 --- /dev/null +++ b/patches/net/minecraft/block/BlockMushroom.java.patch @@ -0,0 +1,60 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockMushroom.java ++++ ../src-work/minecraft/net/minecraft/block/BlockMushroom.java +@@ -6,6 +6,12 @@ + import net.minecraft.world.gen.feature.WorldGenBigMushroom; + import net.minecraftforge.common.util.ForgeDirection; + ++// CraftBukkit start ++import org.bukkit.block.BlockState; ++import org.bukkit.event.block.BlockSpreadEvent; ++import org.bukkit.TreeType; ++// CraftBukkit end ++ + public class BlockMushroom extends BlockBush implements IGrowable + { + private static final String __OBFID = "CL_00000272"; +@@ -19,7 +25,9 @@ + + public void updateTick(World p_149674_1_, int p_149674_2_, int p_149674_3_, int p_149674_4_, Random p_149674_5_) + { +- if (p_149674_5_.nextInt(25) == 0) ++ final int sourceX = p_149674_2_, sourceY = p_149674_3_, sourceZ = p_149674_4_; // CraftBukkit ++ ++ if (p_149674_5_.nextInt(Math.max(1, (int) p_149674_1_.growthOdds / p_149674_1_.getSpigotConfig().mushroomModifier * 25)) == 0) // Spigot // Cauldron + { + byte b0 = 4; + int l = 5; +@@ -66,7 +74,19 @@ + + if (p_149674_1_.isAirBlock(i1, j1, k1) && this.canBlockStay(p_149674_1_, i1, j1, k1)) + { +- p_149674_1_.setBlock(i1, j1, k1, this, 0, 2); ++ // CraftBukkit start ++ org.bukkit.World bworld = p_149674_1_.getWorld(); ++ BlockState blockState = bworld.getBlockAt(i1, j1, k1).getState(); ++ blockState.setTypeId(Block.getIdFromBlock(this)); // nms: this.id, 0, 2 ++ BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(sourceX, sourceY, sourceZ), blockState); ++ p_149674_1_.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ blockState.update(true); ++ } ++ ++ // CraftBukkit end + } + } + } +@@ -102,10 +122,12 @@ + + if (this == Blocks.brown_mushroom) + { ++ BlockSapling.treeType = TreeType.BROWN_MUSHROOM; // CraftBukkit + worldgenbigmushroom = new WorldGenBigMushroom(0); + } + else if (this == Blocks.red_mushroom) + { ++ BlockSapling.treeType = TreeType.RED_MUSHROOM; // CraftBukkit + worldgenbigmushroom = new WorldGenBigMushroom(1); + } + diff --git a/patches/net/minecraft/block/BlockMycelium.java.patch b/patches/net/minecraft/block/BlockMycelium.java.patch new file mode 100644 index 0000000..3aa46df --- /dev/null +++ b/patches/net/minecraft/block/BlockMycelium.java.patch @@ -0,0 +1,64 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockMycelium.java ++++ ../src-work/minecraft/net/minecraft/block/BlockMycelium.java +@@ -12,6 +12,12 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.block.BlockState; ++import org.bukkit.event.block.BlockFadeEvent; ++import org.bukkit.event.block.BlockSpreadEvent; ++// CraftBukkit end ++ + public class BlockMycelium extends Block + { + @SideOnly(Side.CLIENT) +@@ -39,11 +45,25 @@ + { + if (p_149674_1_.getBlockLightValue(p_149674_2_, p_149674_3_ + 1, p_149674_4_) < 4 && p_149674_1_.getBlockLightOpacity(p_149674_2_, p_149674_3_ + 1, p_149674_4_) > 2) + { +- p_149674_1_.setBlock(p_149674_2_, p_149674_3_, p_149674_4_, Blocks.dirt); ++ // CraftBukkit start ++ org.bukkit.World bworld = p_149674_1_.getWorld(); ++ BlockState blockState = bworld.getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_).getState(); ++ blockState.setTypeId(Block.getIdFromBlock(Blocks.dirt)); ++ BlockFadeEvent event = new BlockFadeEvent(blockState.getBlock(), blockState); ++ p_149674_1_.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ blockState.update(true); ++ } ++ ++ // CraftBukkit end + } + else if (p_149674_1_.getBlockLightValue(p_149674_2_, p_149674_3_ + 1, p_149674_4_) >= 9) + { +- for (int l = 0; l < 4; ++l) ++ int numGrowth = Math.min(4, Math.max(20, (int)(4 * 100F / p_149674_1_.growthOdds))); // Spigot ++ ++ for (int l = 0; l < numGrowth; ++l) // Spigot + { + int i1 = p_149674_2_ + p_149674_5_.nextInt(3) - 1; + int j1 = p_149674_3_ + p_149674_5_.nextInt(5) - 3; +@@ -52,7 +72,19 @@ + + if (p_149674_1_.getBlock(i1, j1, k1) == Blocks.dirt && p_149674_1_.getBlockMetadata(i1, j1, k1) == 0 && p_149674_1_.getBlockLightValue(i1, j1 + 1, k1) >= 4 && p_149674_1_.getBlockLightOpacity(i1, j1 + 1, k1) <= 2) + { +- p_149674_1_.setBlock(i1, j1, k1, this); ++ // CraftBukkit start ++ org.bukkit.World bworld = p_149674_1_.getWorld(); ++ BlockState blockState = bworld.getBlockAt(i1, j1, k1).getState(); ++ blockState.setTypeId(Block.getIdFromBlock(this)); ++ BlockSpreadEvent event = new BlockSpreadEvent(blockState.getBlock(), bworld.getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_), blockState); ++ p_149674_1_.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ blockState.update(true); ++ } ++ ++ // CraftBukkit end + } + } + } diff --git a/patches/net/minecraft/block/BlockNetherWart.java.patch b/patches/net/minecraft/block/BlockNetherWart.java.patch new file mode 100644 index 0000000..67b7fdd --- /dev/null +++ b/patches/net/minecraft/block/BlockNetherWart.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockNetherWart.java ++++ ../src-work/minecraft/net/minecraft/block/BlockNetherWart.java +@@ -45,7 +45,7 @@ + if (l < 3 && p_149674_5_.nextInt(10) == 0) + { + ++l; +- p_149674_1_.setBlockMetadataWithNotify(p_149674_2_, p_149674_3_, p_149674_4_, l, 2); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, this, l); // CraftBukkit + } + + super.updateTick(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, p_149674_5_); diff --git a/patches/net/minecraft/block/BlockNetherrack.java.patch b/patches/net/minecraft/block/BlockNetherrack.java.patch new file mode 100644 index 0000000..017cd12 --- /dev/null +++ b/patches/net/minecraft/block/BlockNetherrack.java.patch @@ -0,0 +1,32 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockNetherrack.java ++++ ../src-work/minecraft/net/minecraft/block/BlockNetherrack.java +@@ -4,6 +4,11 @@ + import net.minecraft.block.material.Material; + import net.minecraft.creativetab.CreativeTabs; + ++// CraftBukkit start ++import org.bukkit.event.block.BlockRedstoneEvent; ++import net.minecraft.world.World; ++// CraftBukkit end ++ + public class BlockNetherrack extends Block + { + private static final String __OBFID = "CL_00000275"; +@@ -18,4 +23,17 @@ + { + return MapColor.netherrackColor; + } ++ ++ // CraftBukkit start ++ public void doPhysics(World world, int i, int j, int k, int l) ++ { ++ if (Block.getBlockById(l) != null && Block.getBlockById(l).canProvidePower()) ++ { ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k); ++ int power = block.getBlockPower(); ++ BlockRedstoneEvent event = new BlockRedstoneEvent(block, power, power); ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/block/BlockPistonBase.java.patch b/patches/net/minecraft/block/BlockPistonBase.java.patch new file mode 100644 index 0000000..1f2b07d --- /dev/null +++ b/patches/net/minecraft/block/BlockPistonBase.java.patch @@ -0,0 +1,116 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockPistonBase.java ++++ ../src-work/minecraft/net/minecraft/block/BlockPistonBase.java +@@ -21,6 +21,12 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.block.CraftBlock; ++import org.bukkit.event.block.BlockPistonRetractEvent; ++import org.bukkit.event.block.BlockPistonExtendEvent; ++// CraftBukkit end ++ + public class BlockPistonBase extends Block + { + private final boolean isSticky; +@@ -128,13 +134,37 @@ + + if (flag && !isExtended(l)) + { +- if (canExtend(p_150078_1_, p_150078_2_, p_150078_3_, p_150078_4_, i1)) ++ // CraftBukkit start ++ int length = canExtend_IntCB(p_150078_1_, p_150078_2_, p_150078_3_, p_150078_4_, i1); ++ ++ if (length >= 0) + { ++ org.bukkit.block.Block block = p_150078_1_.getWorld().getBlockAt(p_150078_2_, p_150078_3_, p_150078_4_); ++ BlockPistonExtendEvent event = new BlockPistonExtendEvent(block, length, CraftBlock.notchToBlockFace(i1)); ++ p_150078_1_.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + p_150078_1_.addBlockEvent(p_150078_2_, p_150078_3_, p_150078_4_, this, 0, i1); + } + } + else if (!flag && isExtended(l)) + { ++ // CraftBukkit start ++ org.bukkit.block.Block block = p_150078_1_.getWorld().getBlockAt(p_150078_2_, p_150078_3_, p_150078_4_); ++ BlockPistonRetractEvent event = new BlockPistonRetractEvent(block, CraftBlock.notchToBlockFace(i1)); ++ p_150078_1_.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + p_150078_1_.setBlockMetadataWithNotify(p_150078_2_, p_150078_3_, p_150078_4_, i1, 2); + p_150078_1_.addBlockEvent(p_150078_2_, p_150078_3_, p_150078_4_, this, 1, i1); + } +@@ -297,6 +327,11 @@ + + public static int getPistonOrientation(int p_150076_0_) + { ++ if ((p_150076_0_ & 7) >= Facing.oppositeSide.length) ++ { ++ return 7; // CraftBukkit - check for AIOOB on piston data ++ } ++ + return p_150076_0_ & 7; + } + +@@ -366,7 +401,13 @@ + } + } + +- private static boolean canExtend(World p_150077_0_, int p_150077_1_, int p_150077_2_, int p_150077_3_, int p_150077_4_) ++ // Cauldron start - vanilla compatibility ++ private static boolean canExtend(World world, int i, int j, int k, int l) { ++ return canExtend_IntCB(world, i, j, k, l) >= 0; ++ } ++ // Cauldron end ++ ++ private static int canExtend_IntCB(World p_150077_0_, int p_150077_1_, int p_150077_2_, int p_150077_3_, int p_150077_4_) // CraftBukkit int -> boolean + { + int i1 = p_150077_1_ + Facing.offsetsXForSide[p_150077_4_]; + int j1 = p_150077_2_ + Facing.offsetsYForSide[p_150077_4_]; +@@ -379,7 +420,7 @@ + { + if (j1 <= 0 || j1 >= p_150077_0_.getHeight()) + { +- return false; ++ return -1; // CraftBukkit + } + + Block block = p_150077_0_.getBlock(i1, j1, k1); +@@ -388,14 +429,14 @@ + { + if (!canPushBlock(block, p_150077_0_, i1, j1, k1, true)) + { +- return false; ++ return -1; // CraftBukkit + } + + if (block.getMobilityFlag() != 1) + { + if (l1 == 12) + { +- return false; ++ return -1; // CraftBukkit + } + + i1 += Facing.offsetsXForSide[p_150077_4_]; +@@ -407,7 +448,7 @@ + } + } + +- return true; ++ return l1; // CraftBukkit + } + } + diff --git a/patches/net/minecraft/block/BlockPistonExtension.java.patch b/patches/net/minecraft/block/BlockPistonExtension.java.patch new file mode 100644 index 0000000..9fb7b66 --- /dev/null +++ b/patches/net/minecraft/block/BlockPistonExtension.java.patch @@ -0,0 +1,28 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockPistonExtension.java ++++ ../src-work/minecraft/net/minecraft/block/BlockPistonExtension.java +@@ -55,6 +55,12 @@ + public void breakBlock(World p_149749_1_, int p_149749_2_, int p_149749_3_, int p_149749_4_, Block p_149749_5_, int p_149749_6_) + { + super.breakBlock(p_149749_1_, p_149749_2_, p_149749_3_, p_149749_4_, p_149749_5_, p_149749_6_); ++ ++ if ((p_149749_6_ & 7) >= Facing.oppositeSide.length) ++ { ++ return; // CraftBukkit - fix a piston AIOOBE issue ++ } ++ + int i1 = Facing.oppositeSide[getDirectionMeta(p_149749_6_)]; + p_149749_2_ += Facing.offsetsXForSide[i1]; + p_149749_3_ += Facing.offsetsYForSide[i1]; +@@ -200,6 +206,12 @@ + public void onNeighborBlockChange(World p_149695_1_, int p_149695_2_, int p_149695_3_, int p_149695_4_, Block p_149695_5_) + { + int l = getDirectionMeta(p_149695_1_.getBlockMetadata(p_149695_2_, p_149695_3_, p_149695_4_)); ++ ++ if ((l & 7) >= Facing.oppositeSide.length) ++ { ++ return; // CraftBukkit - fix a piston AIOOBE issue ++ } ++ + Block block1 = p_149695_1_.getBlock(p_149695_2_ - Facing.offsetsXForSide[l], p_149695_3_ - Facing.offsetsYForSide[l], p_149695_4_ - Facing.offsetsZForSide[l]); + + if (block1 != Blocks.piston && block1 != Blocks.sticky_piston) diff --git a/patches/net/minecraft/block/BlockPortal.java.patch b/patches/net/minecraft/block/BlockPortal.java.patch new file mode 100644 index 0000000..392c626 --- /dev/null +++ b/patches/net/minecraft/block/BlockPortal.java.patch @@ -0,0 +1,383 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockPortal.java ++++ ../src-work/minecraft/net/minecraft/block/BlockPortal.java +@@ -14,6 +14,11 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.event.entity.EntityPortalEnterEvent; ++import org.bukkit.event.world.PortalCreateEvent; ++// CraftBukkit end ++ + public class BlockPortal extends BlockBreakable + { + public static final int[][] field_150001_a = new int[][] {new int[0], {3, 1}, {2, 0}}; +@@ -29,7 +34,7 @@ + { + super.updateTick(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, p_149674_5_); + +- if (p_149674_1_.provider.isSurfaceWorld() && p_149674_1_.getGameRules().getGameRuleBooleanValue("doMobSpawning") && p_149674_5_.nextInt(2000) < p_149674_1_.difficultySetting.getDifficultyId()) ++ if (p_149674_1_.getSpigotConfig().enableZombiePigmenPortalSpawns && p_149674_1_.provider.isSurfaceWorld() && p_149674_1_.getGameRules().getGameRuleBooleanValue("doMobSpawning") && p_149674_5_.nextInt(2000) < p_149674_1_.difficultySetting.getDifficultyId()) // Spigot // Cauldron + { + int l; + +@@ -104,13 +109,15 @@ + + if (size.func_150860_b() && size.field_150864_e == 0) + { +- size.func_150859_c(); +- return true; ++ // CraftBukkit start - return portalcreator ++ return size.CB_func_150859_c(); // Cauldron ++ //return true; + } + else if (size1.func_150860_b() && size1.field_150864_e == 0) + { +- size1.func_150859_c(); +- return true; ++ return size1.CB_func_150859_c(); // Cauldron ++ //return true; ++ // CraftBukkit end + } + else + { +@@ -181,6 +188,10 @@ + { + if (p_149670_5_.ridingEntity == null && p_149670_5_.riddenByEntity == null) + { ++ // CraftBukkit start - Entity in portal ++ EntityPortalEnterEvent event = new EntityPortalEnterEvent(p_149670_5_.getBukkitEntity(), new org.bukkit.Location(p_149670_1_.getWorld(), p_149670_2_, p_149670_3_, p_149670_4_)); ++ p_149670_1_.getServer().getPluginManager().callEvent(event); ++ // CraftBukkit end + p_149670_5_.setInPortal(); + } + } +@@ -239,175 +250,223 @@ + } + + public static class Size ++ { ++ private final World field_150867_a; ++ private final int field_150865_b; ++ private final int field_150866_c; ++ private final int field_150863_d; ++ private int field_150864_e = 0; ++ private ChunkCoordinates field_150861_f; ++ private int field_150862_g; ++ private int field_150868_h; ++ java.util.Collection blocks; // CraftBukkit ++ private static final String __OBFID = "CL_00000285"; ++ ++ public Size(World p_i45415_1_, int p_i45415_2_, int p_i45415_3_, int p_i45415_4_, int p_i45415_5_) + { +- private final World field_150867_a; +- private final int field_150865_b; +- private final int field_150866_c; +- private final int field_150863_d; +- private int field_150864_e = 0; +- private ChunkCoordinates field_150861_f; +- private int field_150862_g; +- private int field_150868_h; +- private static final String __OBFID = "CL_00000285"; ++ this.field_150867_a = p_i45415_1_; ++ this.field_150865_b = p_i45415_5_; ++ this.field_150863_d = BlockPortal.field_150001_a[p_i45415_5_][0]; ++ this.field_150866_c = BlockPortal.field_150001_a[p_i45415_5_][1]; + +- public Size(World p_i45415_1_, int p_i45415_2_, int p_i45415_3_, int p_i45415_4_, int p_i45415_5_) ++ for (int i1 = p_i45415_3_; p_i45415_3_ > i1 - 21 && p_i45415_3_ > 0 && this.func_150857_a(p_i45415_1_.getBlock(p_i45415_2_, p_i45415_3_ - 1, p_i45415_4_)); --p_i45415_3_) + { +- this.field_150867_a = p_i45415_1_; +- this.field_150865_b = p_i45415_5_; +- this.field_150863_d = BlockPortal.field_150001_a[p_i45415_5_][0]; +- this.field_150866_c = BlockPortal.field_150001_a[p_i45415_5_][1]; ++ ; ++ } + +- for (int i1 = p_i45415_3_; p_i45415_3_ > i1 - 21 && p_i45415_3_ > 0 && this.func_150857_a(p_i45415_1_.getBlock(p_i45415_2_, p_i45415_3_ - 1, p_i45415_4_)); --p_i45415_3_) ++ int j1 = this.func_150853_a(p_i45415_2_, p_i45415_3_, p_i45415_4_, this.field_150863_d) - 1; ++ ++ if (j1 >= 0) ++ { ++ this.field_150861_f = new ChunkCoordinates(p_i45415_2_ + j1 * Direction.offsetX[this.field_150863_d], p_i45415_3_, p_i45415_4_ + j1 * Direction.offsetZ[this.field_150863_d]); ++ this.field_150868_h = this.func_150853_a(this.field_150861_f.posX, this.field_150861_f.posY, this.field_150861_f.posZ, this.field_150866_c); ++ ++ if (this.field_150868_h < 2 || this.field_150868_h > 21) + { +- ; ++ this.field_150861_f = null; ++ this.field_150868_h = 0; + } ++ } + +- int j1 = this.func_150853_a(p_i45415_2_, p_i45415_3_, p_i45415_4_, this.field_150863_d) - 1; ++ if (this.field_150861_f != null) ++ { ++ this.field_150862_g = this.func_150858_a(); ++ } ++ } + +- if (j1 >= 0) +- { +- this.field_150861_f = new ChunkCoordinates(p_i45415_2_ + j1 * Direction.offsetX[this.field_150863_d], p_i45415_3_, p_i45415_4_ + j1 * Direction.offsetZ[this.field_150863_d]); +- this.field_150868_h = this.func_150853_a(this.field_150861_f.posX, this.field_150861_f.posY, this.field_150861_f.posZ, this.field_150866_c); ++ protected int func_150853_a(int p_150853_1_, int p_150853_2_, int p_150853_3_, int p_150853_4_) ++ { ++ int j1 = Direction.offsetX[p_150853_4_]; ++ int k1 = Direction.offsetZ[p_150853_4_]; ++ int i1; ++ Block block; + +- if (this.field_150868_h < 2 || this.field_150868_h > 21) +- { +- this.field_150861_f = null; +- this.field_150868_h = 0; +- } ++ for (i1 = 0; i1 < 22; ++i1) ++ { ++ block = this.field_150867_a.getBlock(p_150853_1_ + j1 * i1, p_150853_2_, p_150853_3_ + k1 * i1); ++ ++ if (!this.func_150857_a(block)) ++ { ++ break; + } + +- if (this.field_150861_f != null) ++ Block block1 = this.field_150867_a.getBlock(p_150853_1_ + j1 * i1, p_150853_2_ - 1, p_150853_3_ + k1 * i1); ++ ++ if (block1 != Blocks.obsidian) + { +- this.field_150862_g = this.func_150858_a(); ++ break; + } + } + +- protected int func_150853_a(int p_150853_1_, int p_150853_2_, int p_150853_3_, int p_150853_4_) ++ block = this.field_150867_a.getBlock(p_150853_1_ + j1 * i1, p_150853_2_, p_150853_3_ + k1 * i1); ++ return block == Blocks.obsidian ? i1 : 0; ++ } ++ ++ protected int func_150858_a() ++ { ++ this.blocks = new java.util.HashSet(); // CraftBukkit ++ org.bukkit.World bworld = this.field_150867_a.getWorld(); ++ int i; ++ int j; ++ int k; ++ int l; ++ label56: ++ ++ for (this.field_150862_g = 0; this.field_150862_g < 21; ++this.field_150862_g) + { +- int j1 = Direction.offsetX[p_150853_4_]; +- int k1 = Direction.offsetZ[p_150853_4_]; +- int i1; +- Block block; ++ i = this.field_150861_f.posY + this.field_150862_g; + +- for (i1 = 0; i1 < 22; ++i1) ++ for (j = 0; j < this.field_150868_h; ++j) + { +- block = this.field_150867_a.getBlock(p_150853_1_ + j1 * i1, p_150853_2_, p_150853_3_ + k1 * i1); ++ k = this.field_150861_f.posX + j * Direction.offsetX[BlockPortal.field_150001_a[this.field_150865_b][1]]; ++ l = this.field_150861_f.posZ + j * Direction.offsetZ[BlockPortal.field_150001_a[this.field_150865_b][1]]; ++ Block block = this.field_150867_a.getBlock(k, i, l); + + if (!this.func_150857_a(block)) + { +- break; ++ break label56; + } + +- Block block1 = this.field_150867_a.getBlock(p_150853_1_ + j1 * i1, p_150853_2_ - 1, p_150853_3_ + k1 * i1); +- +- if (block1 != Blocks.obsidian) ++ if (block == Blocks.portal) + { +- break; ++ ++this.field_150864_e; + } +- } + +- block = this.field_150867_a.getBlock(p_150853_1_ + j1 * i1, p_150853_2_, p_150853_3_ + k1 * i1); +- return block == Blocks.obsidian ? i1 : 0; +- } +- +- protected int func_150858_a() +- { +- int i; +- int j; +- int k; +- int l; +- label56: +- +- for (this.field_150862_g = 0; this.field_150862_g < 21; ++this.field_150862_g) +- { +- i = this.field_150861_f.posY + this.field_150862_g; +- +- for (j = 0; j < this.field_150868_h; ++j) ++ if (j == 0) + { +- k = this.field_150861_f.posX + j * Direction.offsetX[BlockPortal.field_150001_a[this.field_150865_b][1]]; +- l = this.field_150861_f.posZ + j * Direction.offsetZ[BlockPortal.field_150001_a[this.field_150865_b][1]]; +- Block block = this.field_150867_a.getBlock(k, i, l); ++ block = this.field_150867_a.getBlock(k + Direction.offsetX[BlockPortal.field_150001_a[this.field_150865_b][0]], i, l + Direction.offsetZ[BlockPortal.field_150001_a[this.field_150865_b][0]]); + +- if (!this.func_150857_a(block)) ++ if (block != Blocks.obsidian) + { + break label56; ++ // CraftBukkit start - add the block to our list + } +- +- if (block == Blocks.portal) ++ else + { +- ++this.field_150864_e; ++ blocks.add(bworld.getBlockAt(k + Direction.offsetX[BlockPortal.field_150001_a[this.field_150865_b][0]], i, l + Direction.offsetZ[BlockPortal.field_150001_a[this.field_150865_b][0]])); ++ // CraftBukkit end + } ++ } ++ else if (j == this.field_150868_h - 1) ++ { ++ block = this.field_150867_a.getBlock(k + Direction.offsetX[BlockPortal.field_150001_a[this.field_150865_b][1]], i, l + Direction.offsetZ[BlockPortal.field_150001_a[this.field_150865_b][1]]); + +- if (j == 0) ++ if (block != Blocks.obsidian) + { +- block = this.field_150867_a.getBlock(k + Direction.offsetX[BlockPortal.field_150001_a[this.field_150865_b][0]], i, l + Direction.offsetZ[BlockPortal.field_150001_a[this.field_150865_b][0]]); +- +- if (block != Blocks.obsidian) +- { +- break label56; +- } ++ break label56; ++ // CraftBukkit start - add the block to our list + } +- else if (j == this.field_150868_h - 1) ++ else + { +- block = this.field_150867_a.getBlock(k + Direction.offsetX[BlockPortal.field_150001_a[this.field_150865_b][1]], i, l + Direction.offsetZ[BlockPortal.field_150001_a[this.field_150865_b][1]]); +- +- if (block != Blocks.obsidian) +- { +- break label56; +- } ++ blocks.add(bworld.getBlockAt(k + Direction.offsetX[BlockPortal.field_150001_a[this.field_150865_b][1]], i, l + Direction.offsetZ[BlockPortal.field_150001_a[this.field_150865_b][1]])); ++ // CraftBukkit end + } + } + } ++ } + +- for (i = 0; i < this.field_150868_h; ++i) +- { +- j = this.field_150861_f.posX + i * Direction.offsetX[BlockPortal.field_150001_a[this.field_150865_b][1]]; +- k = this.field_150861_f.posY + this.field_150862_g; +- l = this.field_150861_f.posZ + i * Direction.offsetZ[BlockPortal.field_150001_a[this.field_150865_b][1]]; ++ for (i = 0; i < this.field_150868_h; ++i) ++ { ++ j = this.field_150861_f.posX + i * Direction.offsetX[BlockPortal.field_150001_a[this.field_150865_b][1]]; ++ k = this.field_150861_f.posY + this.field_150862_g; ++ l = this.field_150861_f.posZ + i * Direction.offsetZ[BlockPortal.field_150001_a[this.field_150865_b][1]]; + +- if (this.field_150867_a.getBlock(j, k, l) != Blocks.obsidian) +- { +- this.field_150862_g = 0; +- break; +- } +- } +- +- if (this.field_150862_g <= 21 && this.field_150862_g >= 3) ++ if (this.field_150867_a.getBlock(j, k, l) != Blocks.obsidian) + { +- return this.field_150862_g; +- } +- else +- { +- this.field_150861_f = null; +- this.field_150868_h = 0; + this.field_150862_g = 0; +- return 0; ++ break; + } + } + +- protected boolean func_150857_a(Block p_150857_1_) ++ if (this.field_150862_g <= 21 && this.field_150862_g >= 3) + { +- return p_150857_1_.blockMaterial == Material.air || p_150857_1_ == Blocks.fire || p_150857_1_ == Blocks.portal; ++ return this.field_150862_g; + } ++ else ++ { ++ this.field_150861_f = null; ++ this.field_150868_h = 0; ++ this.field_150862_g = 0; ++ return 0; ++ } ++ } + +- public boolean func_150860_b() ++ protected boolean func_150857_a(Block p_150857_1_) ++ { ++ return p_150857_1_.blockMaterial == Material.air || p_150857_1_ == Blocks.fire || p_150857_1_ == Blocks.portal; ++ } ++ ++ public boolean func_150860_b() ++ { ++ return this.field_150861_f != null && this.field_150868_h >= 2 && this.field_150868_h <= 21 && this.field_150862_g >= 3 && this.field_150862_g <= 21; ++ } ++ ++ // Cauldron start - vanilla compatibility ++ public void func_150859_c() ++ { ++ this.CB_func_150859_c(); ++ } ++ // Cauldron end ++ ++ public boolean CB_func_150859_c() ++ { ++ org.bukkit.World bworld = this.field_150867_a.getWorld(); ++ ++ // Copy below for loop ++ for (int i = 0; i < this.field_150868_h; ++i) + { +- return this.field_150861_f != null && this.field_150868_h >= 2 && this.field_150868_h <= 21 && this.field_150862_g >= 3 && this.field_150862_g <= 21; ++ int j = this.field_150861_f.posX + Direction.offsetX[this.field_150866_c] * i; ++ int k = this.field_150861_f.posZ + Direction.offsetZ[this.field_150866_c] * i; ++ ++ for (int l = 0; l < this.field_150862_g; ++l) ++ { ++ int i1 = this.field_150861_f.posY + l; ++ bworld.getBlockAt(j, i1, k); ++ } + } + +- public void func_150859_c() ++ PortalCreateEvent event = new PortalCreateEvent(blocks, bworld, PortalCreateEvent.CreateReason.FIRE); ++ this.field_150867_a.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) + { ++ return false; ++ } ++ // CraftBukkit end ++ + for (int i = 0; i < this.field_150868_h; ++i) + { + int j = this.field_150861_f.posX + Direction.offsetX[this.field_150866_c] * i; + int k = this.field_150861_f.posZ + Direction.offsetZ[this.field_150866_c] * i; +- ++ + for (int l = 0; l < this.field_150862_g; ++l) + { + int i1 = this.field_150861_f.posY + l; + this.field_150867_a.setBlock(j, i1, k, Blocks.portal, this.field_150865_b, 2); + } + } ++ ++ return true; // CraftBukkit + } + } + } diff --git a/patches/net/minecraft/block/BlockPressurePlate.java.patch b/patches/net/minecraft/block/BlockPressurePlate.java.patch new file mode 100644 index 0000000..fdae2f7 --- /dev/null +++ b/patches/net/minecraft/block/BlockPressurePlate.java.patch @@ -0,0 +1,47 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockPressurePlate.java ++++ ../src-work/minecraft/net/minecraft/block/BlockPressurePlate.java +@@ -8,6 +8,8 @@ + import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.world.World; + ++import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit ++ + public class BlockPressurePlate extends BlockBasePressurePlate + { + private BlockPressurePlate.Sensitivity field_150069_a; +@@ -54,8 +56,34 @@ + + while (iterator.hasNext()) + { +- Entity entity = (Entity)iterator.next(); ++ Entity entity = (Entity) iterator.next(); + ++ // CraftBukkit start - Call interact event when turning on a pressure plate ++ if (this.func_150060_c(p_150065_1_.getBlockMetadata(p_150065_2_, p_150065_3_, p_150065_4_)) == 0) ++ { ++ org.bukkit.World bworld = p_150065_1_.getWorld(); ++ org.bukkit.plugin.PluginManager manager = p_150065_1_.getServer().getPluginManager(); ++ org.bukkit.event.Cancellable cancellable; ++ ++ if (entity instanceof EntityPlayer) ++ { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityPlayer) entity, org.bukkit.event.block.Action.PHYSICAL, p_150065_2_, p_150065_3_, p_150065_4_, -1, null); ++ } ++ else ++ { ++ cancellable = new EntityInteractEvent(entity.getBukkitEntity(), bworld.getBlockAt(p_150065_2_, p_150065_3_, p_150065_4_)); ++ manager.callEvent((EntityInteractEvent) cancellable); ++ } ++ ++ // We only want to block turning the plate on if all events are cancelled ++ if (cancellable.isCancelled()) ++ { ++ continue; ++ } ++ } ++ ++ // CraftBukkit end ++ + if (!entity.doesEntityNotTriggerPressurePlate()) + { + return 15; diff --git a/patches/net/minecraft/block/BlockPressurePlateWeighted.java.patch b/patches/net/minecraft/block/BlockPressurePlateWeighted.java.patch new file mode 100644 index 0000000..7f8c979 --- /dev/null +++ b/patches/net/minecraft/block/BlockPressurePlateWeighted.java.patch @@ -0,0 +1,63 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockPressurePlateWeighted.java ++++ ../src-work/minecraft/net/minecraft/block/BlockPressurePlateWeighted.java +@@ -5,6 +5,12 @@ + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; + ++// CraftBukkit start ++import java.util.List; ++import net.minecraft.entity.player.EntityPlayer; ++import org.bukkit.event.entity.EntityInteractEvent; ++// CraftBukkit end ++ + public class BlockPressurePlateWeighted extends BlockBasePressurePlate + { + private final int field_150068_a; +@@ -18,18 +24,43 @@ + + protected int func_150065_e(World p_150065_1_, int p_150065_2_, int p_150065_3_, int p_150065_4_) + { +- int l = Math.min(p_150065_1_.getEntitiesWithinAABB(Entity.class, this.func_150061_a(p_150065_2_, p_150065_3_, p_150065_4_)).size(), this.field_150068_a); ++ // CraftBukkit start ++ int l = 0; ++ java.util.Iterator iterator = p_150065_1_.getEntitiesWithinAABB(Entity.class, this.func_150061_a(p_150065_2_, p_150065_3_, p_150065_4_)).iterator(); + +- if (l <= 0) ++ while (iterator.hasNext()) + { +- return 0; ++ Entity entity = (Entity) iterator.next(); ++ org.bukkit.event.Cancellable cancellable; ++ ++ if (entity instanceof EntityPlayer) ++ { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityPlayer) entity, org.bukkit.event.block.Action.PHYSICAL, p_150065_2_, p_150065_3_, p_150065_4_, -1, null); + } + else + { ++ cancellable = new EntityInteractEvent(entity.getBukkitEntity(), p_150065_1_.getWorld().getBlockAt(p_150065_2_, p_150065_3_, p_150065_4_)); ++ p_150065_1_.getServer().getPluginManager().callEvent((EntityInteractEvent) cancellable); ++ } ++ ++ // We only want to block turning the plate on if all events are cancelled ++ if (!cancellable.isCancelled()) ++ { ++ l++; ++ } ++ } ++ ++ l = Math.min(l, this.field_150068_a); ++ // CraftBukkit end ++ ++ if (l <= 0) ++ { ++ return 0; ++ } ++ + float f = (float)Math.min(this.field_150068_a, l) / (float)this.field_150068_a; + return MathHelper.ceiling_float_int(f * 15.0F); + } +- } + + protected int func_150060_c(int p_150060_1_) + { diff --git a/patches/net/minecraft/block/BlockPumpkin.java.patch b/patches/net/minecraft/block/BlockPumpkin.java.patch new file mode 100644 index 0000000..7ec5dfe --- /dev/null +++ b/patches/net/minecraft/block/BlockPumpkin.java.patch @@ -0,0 +1,126 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockPumpkin.java ++++ ../src-work/minecraft/net/minecraft/block/BlockPumpkin.java +@@ -14,6 +14,12 @@ + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.util.BlockStateListPopulator; ++import org.bukkit.event.block.BlockRedstoneEvent; ++import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; ++// CraftBukkit end ++ + public class BlockPumpkin extends BlockDirectional + { + private boolean field_149985_a; +@@ -45,15 +51,18 @@ + { + if (!p_149726_1_.isRemote) + { +- p_149726_1_.setBlock(p_149726_2_, p_149726_3_, p_149726_4_, getBlockById(0), 0, 2); +- p_149726_1_.setBlock(p_149726_2_, p_149726_3_ - 1, p_149726_4_, getBlockById(0), 0, 2); +- p_149726_1_.setBlock(p_149726_2_, p_149726_3_ - 2, p_149726_4_, getBlockById(0), 0, 2); ++ // CraftBukkit start - Use BlockStateListPopulator ++ BlockStateListPopulator blockList = new BlockStateListPopulator(p_149726_1_.getWorld()); ++ blockList.setTypeId(p_149726_2_, p_149726_3_, p_149726_4_, 0); ++ blockList.setTypeId(p_149726_2_, p_149726_3_ - 1, p_149726_4_, 0); ++ blockList.setTypeId(p_149726_2_, p_149726_3_ - 2, p_149726_4_, 0); + EntitySnowman entitysnowman = new EntitySnowman(p_149726_1_); +- entitysnowman.setLocationAndAngles((double)p_149726_2_ + 0.5D, (double)p_149726_3_ - 1.95D, (double)p_149726_4_ + 0.5D, 0.0F, 0.0F); +- p_149726_1_.spawnEntityInWorld(entitysnowman); +- p_149726_1_.notifyBlockChange(p_149726_2_, p_149726_3_, p_149726_4_, getBlockById(0)); +- p_149726_1_.notifyBlockChange(p_149726_2_, p_149726_3_ - 1, p_149726_4_, getBlockById(0)); +- p_149726_1_.notifyBlockChange(p_149726_2_, p_149726_3_ - 2, p_149726_4_, getBlockById(0)); ++ entitysnowman.setLocationAndAngles((double) p_149726_2_ + 0.5D, (double) p_149726_3_ - 1.95D, (double) p_149726_4_ + 0.5D, 0.0F, 0.0F); ++ ++ if (p_149726_1_.addEntity(entitysnowman, SpawnReason.BUILD_SNOWMAN)) ++ { ++ blockList.updateList(); ++ } + } + + for (int i1 = 0; i1 < 120; ++i1) +@@ -68,45 +77,38 @@ + + if (flag || flag1) + { +- p_149726_1_.setBlock(p_149726_2_, p_149726_3_, p_149726_4_, getBlockById(0), 0, 2); +- p_149726_1_.setBlock(p_149726_2_, p_149726_3_ - 1, p_149726_4_, getBlockById(0), 0, 2); +- p_149726_1_.setBlock(p_149726_2_, p_149726_3_ - 2, p_149726_4_, getBlockById(0), 0, 2); ++ // CraftBukkit start - Use BlockStateListPopulator ++ BlockStateListPopulator blockList = new BlockStateListPopulator(p_149726_1_.getWorld()); ++ blockList.setTypeId(p_149726_2_, p_149726_3_, p_149726_4_, 0); ++ blockList.setTypeId(p_149726_2_, p_149726_3_ - 1, p_149726_4_, 0); ++ blockList.setTypeId(p_149726_2_, p_149726_3_ - 2, p_149726_4_, 0); + + if (flag) + { +- p_149726_1_.setBlock(p_149726_2_ - 1, p_149726_3_ - 1, p_149726_4_, getBlockById(0), 0, 2); +- p_149726_1_.setBlock(p_149726_2_ + 1, p_149726_3_ - 1, p_149726_4_, getBlockById(0), 0, 2); ++ blockList.setTypeId(p_149726_2_ - 1, p_149726_3_ - 1, p_149726_4_, 0); ++ blockList.setTypeId(p_149726_2_ + 1, p_149726_3_ - 1, p_149726_4_, 0); + } + else + { +- p_149726_1_.setBlock(p_149726_2_, p_149726_3_ - 1, p_149726_4_ - 1, getBlockById(0), 0, 2); +- p_149726_1_.setBlock(p_149726_2_, p_149726_3_ - 1, p_149726_4_ + 1, getBlockById(0), 0, 2); ++ blockList.setTypeId(p_149726_2_, p_149726_3_ - 1, p_149726_4_ - 1, 0); ++ blockList.setTypeId(p_149726_2_, p_149726_3_ - 1, p_149726_4_ + 1, 0); + } + + EntityIronGolem entityirongolem = new EntityIronGolem(p_149726_1_); + entityirongolem.setPlayerCreated(true); +- entityirongolem.setLocationAndAngles((double)p_149726_2_ + 0.5D, (double)p_149726_3_ - 1.95D, (double)p_149726_4_ + 0.5D, 0.0F, 0.0F); +- p_149726_1_.spawnEntityInWorld(entityirongolem); ++ entityirongolem.setLocationAndAngles((double) p_149726_2_ + 0.5D, (double) p_149726_3_ - 1.95D, (double) p_149726_4_ + 0.5D, 0.0F, 0.0F); + +- for (int l = 0; l < 120; ++l) ++ if (p_149726_1_.addEntity(entityirongolem, SpawnReason.BUILD_IRONGOLEM)) + { +- p_149726_1_.spawnParticle("snowballpoof", (double)p_149726_2_ + p_149726_1_.rand.nextDouble(), (double)(p_149726_3_ - 2) + p_149726_1_.rand.nextDouble() * 3.9D, (double)p_149726_4_ + p_149726_1_.rand.nextDouble(), 0.0D, 0.0D, 0.0D); +- } ++ for (int i1 = 0; i1 < 120; ++i1) ++ { ++ p_149726_1_.spawnParticle("snowballpoof", (double) p_149726_2_ + p_149726_1_.rand.nextDouble(), (double)(p_149726_3_ - 2) + p_149726_1_.rand.nextDouble() * 3.9D, (double) p_149726_4_ + p_149726_1_.rand.nextDouble(), 0.0D, 0.0D, 0.0D); ++ } + +- p_149726_1_.notifyBlockChange(p_149726_2_, p_149726_3_, p_149726_4_, getBlockById(0)); +- p_149726_1_.notifyBlockChange(p_149726_2_, p_149726_3_ - 1, p_149726_4_, getBlockById(0)); +- p_149726_1_.notifyBlockChange(p_149726_2_, p_149726_3_ - 2, p_149726_4_, getBlockById(0)); +- +- if (flag) +- { +- p_149726_1_.notifyBlockChange(p_149726_2_ - 1, p_149726_3_ - 1, p_149726_4_, getBlockById(0)); +- p_149726_1_.notifyBlockChange(p_149726_2_ + 1, p_149726_3_ - 1, p_149726_4_, getBlockById(0)); ++ blockList.updateList(); + } +- else +- { +- p_149726_1_.notifyBlockChange(p_149726_2_, p_149726_3_ - 1, p_149726_4_ - 1, getBlockById(0)); +- p_149726_1_.notifyBlockChange(p_149726_2_, p_149726_3_ - 1, p_149726_4_ + 1, getBlockById(0)); +- } ++ ++ // CraftBukkit end + } + } + } +@@ -122,6 +124,19 @@ + p_149689_1_.setBlockMetadataWithNotify(p_149689_2_, p_149689_3_, p_149689_4_, l, 2); + } + ++ // CraftBukkit start ++ public void onNeighborBlockChange(World world, int i, int j, int k, Block block) ++ { ++ if (block != null && block.canProvidePower()) ++ { ++ org.bukkit.block.Block bukkitBlock = world.getWorld().getBlockAt(i, j, k); ++ int power = bukkitBlock.getBlockPower(); ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, power, power); ++ world.getServer().getPluginManager().callEvent(eventRedstone); ++ } ++ } ++ // CraftBukkit end ++ + @SideOnly(Side.CLIENT) + public void registerBlockIcons(IIconRegister p_149651_1_) + { diff --git a/patches/net/minecraft/block/BlockRailDetector.java.patch b/patches/net/minecraft/block/BlockRailDetector.java.patch new file mode 100644 index 0000000..0441e25 --- /dev/null +++ b/patches/net/minecraft/block/BlockRailDetector.java.patch @@ -0,0 +1,29 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockRailDetector.java ++++ ../src-work/minecraft/net/minecraft/block/BlockRailDetector.java +@@ -16,6 +16,8 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockRailDetector extends BlockRailBase + { + @SideOnly(Side.CLIENT) +@@ -86,6 +88,17 @@ + flag1 = true; + } + ++ // CraftBukkit start ++ if (flag != flag1) ++ { ++ org.bukkit.block.Block block = p_150054_1_.getWorld().getBlockAt(p_150054_2_, p_150054_3_, p_150054_4_); ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, flag ? 15 : 0, flag1 ? 15 : 0); ++ p_150054_1_.getServer().getPluginManager().callEvent(eventRedstone); ++ flag1 = eventRedstone.getNewCurrent() > 0; ++ } ++ ++ // CraftBukkit end ++ + if (flag1 && !flag) + { + p_150054_1_.setBlockMetadataWithNotify(p_150054_2_, p_150054_3_, p_150054_4_, p_150054_5_ | 8, 3); diff --git a/patches/net/minecraft/block/BlockRedstoneDiode.java.patch b/patches/net/minecraft/block/BlockRedstoneDiode.java.patch new file mode 100644 index 0000000..5dabe9b --- /dev/null +++ b/patches/net/minecraft/block/BlockRedstoneDiode.java.patch @@ -0,0 +1,43 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockRedstoneDiode.java ++++ ../src-work/minecraft/net/minecraft/block/BlockRedstoneDiode.java +@@ -13,6 +13,8 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public abstract class BlockRedstoneDiode extends BlockDirectional + { + protected final boolean isRepeaterPowered; +@@ -44,16 +46,30 @@ + { + int l = p_149674_1_.getBlockMetadata(p_149674_2_, p_149674_3_, p_149674_4_); + +- if (!this.func_149910_g(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, l)) ++ if (!this.func_149910_g((IBlockAccess) p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, l)) // CraftBukkit - Cast world to IBlockAccess to call the right method. + { + boolean flag = this.isGettingInput(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, l); + + if (this.isRepeaterPowered && !flag) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callRedstoneChange(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, 15, 0).getNewCurrent() != 0) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + p_149674_1_.setBlock(p_149674_2_, p_149674_3_, p_149674_4_, this.getBlockUnpowered(), l, 2); + } + else if (!this.isRepeaterPowered) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callRedstoneChange(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, 0, 15).getNewCurrent() != 15) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + p_149674_1_.setBlock(p_149674_2_, p_149674_3_, p_149674_4_, this.getBlockPowered(), l, 2); + + if (!flag) diff --git a/patches/net/minecraft/block/BlockRedstoneLight.java.patch b/patches/net/minecraft/block/BlockRedstoneLight.java.patch new file mode 100644 index 0000000..9103834 --- /dev/null +++ b/patches/net/minecraft/block/BlockRedstoneLight.java.patch @@ -0,0 +1,53 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockRedstoneLight.java ++++ ../src-work/minecraft/net/minecraft/block/BlockRedstoneLight.java +@@ -9,6 +9,8 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.world.World; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class BlockRedstoneLight extends Block + { + private final boolean field_150171_a; +@@ -35,6 +37,13 @@ + } + else if (!this.field_150171_a && p_149726_1_.isBlockIndirectlyGettingPowered(p_149726_2_, p_149726_3_, p_149726_4_)) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callRedstoneChange(p_149726_1_, p_149726_2_, p_149726_3_, p_149726_4_, 0, 15).getNewCurrent() != 15) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + p_149726_1_.setBlock(p_149726_2_, p_149726_3_, p_149726_4_, Blocks.lit_redstone_lamp, 0, 2); + } + } +@@ -50,6 +59,13 @@ + } + else if (!this.field_150171_a && p_149695_1_.isBlockIndirectlyGettingPowered(p_149695_2_, p_149695_3_, p_149695_4_)) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callRedstoneChange(p_149695_1_, p_149695_2_, p_149695_3_, p_149695_4_, 0, 15).getNewCurrent() != 15) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + p_149695_1_.setBlock(p_149695_2_, p_149695_3_, p_149695_4_, Blocks.lit_redstone_lamp, 0, 2); + } + } +@@ -59,6 +75,13 @@ + { + if (!p_149674_1_.isRemote && this.field_150171_a && !p_149674_1_.isBlockIndirectlyGettingPowered(p_149674_2_, p_149674_3_, p_149674_4_)) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callRedstoneChange(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, 15, 0).getNewCurrent() != 0) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + p_149674_1_.setBlock(p_149674_2_, p_149674_3_, p_149674_4_, Blocks.redstone_lamp, 0, 2); + } + } diff --git a/patches/net/minecraft/block/BlockRedstoneOre.java.patch b/patches/net/minecraft/block/BlockRedstoneOre.java.patch new file mode 100644 index 0000000..455b1d2 --- /dev/null +++ b/patches/net/minecraft/block/BlockRedstoneOre.java.patch @@ -0,0 +1,44 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockRedstoneOre.java ++++ ../src-work/minecraft/net/minecraft/block/BlockRedstoneOre.java +@@ -13,6 +13,8 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit ++ + public class BlockRedstoneOre extends Block + { + private boolean field_150187_a; +@@ -43,8 +45,30 @@ + + public void onEntityWalking(World p_149724_1_, int p_149724_2_, int p_149724_3_, int p_149724_4_, Entity p_149724_5_) + { +- this.func_150185_e(p_149724_1_, p_149724_2_, p_149724_3_, p_149724_4_); +- super.onEntityWalking(p_149724_1_, p_149724_2_, p_149724_3_, p_149724_4_, p_149724_5_); ++ // CraftBukkit start ++ if (p_149724_5_ instanceof EntityPlayer) ++ { ++ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityPlayer) p_149724_5_, org.bukkit.event.block.Action.PHYSICAL, p_149724_2_, p_149724_3_, p_149724_4_, -1, null); ++ ++ if (!event.isCancelled()) ++ { ++ this.func_150185_e(p_149724_1_, p_149724_2_, p_149724_3_, p_149724_4_); ++ super.onEntityWalking(p_149724_1_, p_149724_2_, p_149724_3_, p_149724_4_, p_149724_5_); ++ } ++ } ++ else ++ { ++ EntityInteractEvent event = new EntityInteractEvent(p_149724_5_.getBukkitEntity(), p_149724_1_.getWorld().getBlockAt(p_149724_2_, p_149724_3_, p_149724_4_)); ++ p_149724_1_.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ this.func_150185_e(p_149724_1_, p_149724_2_, p_149724_3_, p_149724_4_); ++ super.onEntityWalking(p_149724_1_, p_149724_2_, p_149724_3_, p_149724_4_, p_149724_5_); ++ } ++ } ++ ++ // CraftBukkit end + } + + public boolean onBlockActivated(World p_149727_1_, int p_149727_2_, int p_149727_3_, int p_149727_4_, EntityPlayer p_149727_5_, int p_149727_6_, float p_149727_7_, float p_149727_8_, float p_149727_9_) diff --git a/patches/net/minecraft/block/BlockRedstoneTorch.java.patch b/patches/net/minecraft/block/BlockRedstoneTorch.java.patch new file mode 100644 index 0000000..483680f --- /dev/null +++ b/patches/net/minecraft/block/BlockRedstoneTorch.java.patch @@ -0,0 +1,62 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockRedstoneTorch.java ++++ ../src-work/minecraft/net/minecraft/block/BlockRedstoneTorch.java +@@ -13,6 +13,8 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockRedstoneTorch extends BlockTorch + { + private boolean field_150113_a; +@@ -125,10 +127,30 @@ + list.remove(0); + } + ++ // CraftBukkit start ++ org.bukkit.plugin.PluginManager manager = p_149674_1_.getServer().getPluginManager(); ++ org.bukkit.block.Block block = p_149674_1_.getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_); ++ int oldCurrent = this.field_150113_a ? 15 : 0; ++ BlockRedstoneEvent event = new BlockRedstoneEvent(block, oldCurrent, oldCurrent); ++ // CraftBukkit end ++ + if (this.field_150113_a) + { + if (flag) + { ++ // CraftBukkit start ++ if (oldCurrent != 0) ++ { ++ event.setNewCurrent(0); ++ manager.callEvent(event); ++ ++ if (event.getNewCurrent() != 0) ++ { ++ return; ++ } ++ } ++ ++ // CraftBukkit end + p_149674_1_.setBlock(p_149674_2_, p_149674_3_, p_149674_4_, Blocks.unlit_redstone_torch, p_149674_1_.getBlockMetadata(p_149674_2_, p_149674_3_, p_149674_4_), 3); + + if (this.func_150111_a(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, true)) +@@ -147,6 +169,19 @@ + } + else if (!flag && !this.func_150111_a(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, false)) + { ++ // CraftBukkit start ++ if (oldCurrent != 15) ++ { ++ event.setNewCurrent(15); ++ manager.callEvent(event); ++ ++ if (event.getNewCurrent() != 15) ++ { ++ return; ++ } ++ } ++ ++ // CraftBukkit end + p_149674_1_.setBlock(p_149674_2_, p_149674_3_, p_149674_4_, Blocks.redstone_torch, p_149674_1_.getBlockMetadata(p_149674_2_, p_149674_3_, p_149674_4_), 3); + } + } diff --git a/patches/net/minecraft/block/BlockRedstoneWire.java.patch b/patches/net/minecraft/block/BlockRedstoneWire.java.patch new file mode 100644 index 0000000..6387aae --- /dev/null +++ b/patches/net/minecraft/block/BlockRedstoneWire.java.patch @@ -0,0 +1,39 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockRedstoneWire.java ++++ ../src-work/minecraft/net/minecraft/block/BlockRedstoneWire.java +@@ -18,6 +18,8 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockRedstoneWire extends Block + { + private boolean field_150181_a = true; +@@ -159,8 +161,17 @@ + i3 = l1; + } + ++ // CraftBukkit start + if (k1 != i3) + { ++ BlockRedstoneEvent event = new BlockRedstoneEvent(p_150175_1_.getWorld().getBlockAt(p_150175_2_, p_150175_3_, p_150175_4_), k1, i3); ++ p_150175_1_.getServer().getPluginManager().callEvent(event); ++ i3 = event.getNewCurrent(); ++ } ++ ++ // CraftBukkit end ++ if (k1 != i3) ++ { + p_150175_1_.setBlockMetadataWithNotify(p_150175_2_, p_150175_3_, p_150175_4_, i3, 2); + this.field_150179_b.add(new ChunkPosition(p_150175_2_, p_150175_3_, p_150175_4_)); + this.field_150179_b.add(new ChunkPosition(p_150175_2_ - 1, p_150175_3_, p_150175_4_)); +@@ -294,7 +305,8 @@ + } + } + +- private int func_150178_a(World p_150178_1_, int p_150178_2_, int p_150178_3_, int p_150178_4_, int p_150178_5_) ++ // CraftBukkit - private -> public ++ public int func_150178_a(World p_150178_1_, int p_150178_2_, int p_150178_3_, int p_150178_4_, int p_150178_5_) + { + if (p_150178_1_.getBlock(p_150178_2_, p_150178_3_, p_150178_4_) != this) + { diff --git a/patches/net/minecraft/block/BlockReed.java.patch b/patches/net/minecraft/block/BlockReed.java.patch new file mode 100644 index 0000000..bb17ea1 --- /dev/null +++ b/patches/net/minecraft/block/BlockReed.java.patch @@ -0,0 +1,14 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockReed.java ++++ ../src-work/minecraft/net/minecraft/block/BlockReed.java +@@ -44,9 +44,9 @@ + { + int i1 = p_149674_1_.getBlockMetadata(p_149674_2_, p_149674_3_, p_149674_4_); + +- if (i1 == 15) ++ if (i1 >= (byte) range(3, (p_149674_1_.growthOdds / p_149674_1_.getSpigotConfig().caneModifier * 15) + 0.5F, 15)) // Spigot // Cauldron + { +- p_149674_1_.setBlock(p_149674_2_, p_149674_3_ + 1, p_149674_4_, this); ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleBlockGrowEvent(p_149674_1_, p_149674_2_, p_149674_3_ + 1, p_149674_4_, this, 0); // CraftBukkit + p_149674_1_.setBlockMetadataWithNotify(p_149674_2_, p_149674_3_, p_149674_4_, 0, 4); + } + else diff --git a/patches/net/minecraft/block/BlockSapling.java.patch b/patches/net/minecraft/block/BlockSapling.java.patch new file mode 100644 index 0000000..897cf75 --- /dev/null +++ b/patches/net/minecraft/block/BlockSapling.java.patch @@ -0,0 +1,122 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockSapling.java ++++ ../src-work/minecraft/net/minecraft/block/BlockSapling.java +@@ -22,10 +22,18 @@ + import net.minecraft.world.gen.feature.WorldGenTrees; + import net.minecraft.world.gen.feature.WorldGenerator; + ++// CraftBukkit start ++import org.bukkit.Location; ++import org.bukkit.TreeType; ++import org.bukkit.block.BlockState; ++import org.bukkit.event.world.StructureGrowEvent; ++// CraftBukkit end ++ + public class BlockSapling extends BlockBush implements IGrowable + { + public static final String[] field_149882_a = new String[] {"oak", "spruce", "birch", "jungle", "acacia", "roofed_oak"}; + private static final IIcon[] field_149881_b = new IIcon[field_149882_a.length]; ++ public static TreeType treeType; // CraftBukkit + private static final String __OBFID = "CL_00000305"; + + protected BlockSapling() +@@ -41,9 +49,31 @@ + { + super.updateTick(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, p_149674_5_); + +- if (p_149674_1_.getBlockLightValue(p_149674_2_, p_149674_3_ + 1, p_149674_4_) >= 9 && p_149674_5_.nextInt(7) == 0) ++ if (p_149674_1_.getBlockLightValue(p_149674_2_, p_149674_3_ + 1, p_149674_4_) >= 9 && (p_149674_5_.nextInt(Math.max(2, (int)((p_149674_1_.growthOdds / p_149674_1_.getSpigotConfig().saplingModifier * 7) + 0.5F))) == 0)) // Spigot // Cauldron + { ++ // Cauldron start ++ p_149674_1_.captureTreeGeneration = true; + this.func_149879_c(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, p_149674_5_); ++ p_149674_1_.captureTreeGeneration = false; ++ if (p_149674_1_.capturedBlockStates.size() > 0) ++ { ++ TreeType treeType = BlockSapling.treeType; ++ BlockSapling.treeType = null; ++ Location location = new Location(p_149674_1_.getWorld(), p_149674_2_, p_149674_3_, p_149674_4_); ++ List blocks = (List) p_149674_1_.capturedBlockStates.clone(); ++ p_149674_1_.capturedBlockStates.clear(); ++ StructureGrowEvent event = null; ++ if (treeType != null) { ++ event = new StructureGrowEvent(location, treeType, false, null, blocks); ++ org.bukkit.Bukkit.getPluginManager().callEvent(event); ++ } ++ if (event == null || !event.isCancelled()) { ++ for (BlockState blockstate : blocks) { ++ blockstate.update(true); ++ } ++ } ++ } ++ //Cauldron end + } + } + } +@@ -73,7 +103,20 @@ + { + if (!net.minecraftforge.event.terraingen.TerrainGen.saplingGrowTree(p_149878_1_, p_149878_5_, p_149878_2_, p_149878_3_, p_149878_4_)) return; + int l = p_149878_1_.getBlockMetadata(p_149878_2_, p_149878_3_, p_149878_4_) & 7; +- Object object = p_149878_5_.nextInt(10) == 0 ? new WorldGenBigTree(true) : new WorldGenTrees(true); ++ // CraftBukkit start ++ Object object = null; ++ if (p_149878_5_.nextInt(10) == 0) ++ { ++ treeType = TreeType.BIG_TREE; // CraftBukkit ++ object = new WorldGenBigTree(true); ++ } ++ else ++ { ++ treeType = TreeType.TREE; // CraftBukkit ++ object = new WorldGenTrees(true); ++ } ++ // CraftBukkit end ++ + int i1 = 0; + int j1 = 0; + boolean flag = false; +@@ -84,6 +127,7 @@ + default: + break; + case 1: ++ treeType = TreeType.REDWOOD; // CraftBukkit + label78: + + for (i1 = 0; i1 >= -1; --i1) +@@ -108,6 +152,7 @@ + + break; + case 2: ++ treeType = TreeType.BIRCH; // CraftBukkit + object = new WorldGenForest(true, false); + break; + case 3: +@@ -119,6 +164,7 @@ + { + if (this.func_149880_a(p_149878_1_, p_149878_2_ + i1, p_149878_3_, p_149878_4_ + j1, 3) && this.func_149880_a(p_149878_1_, p_149878_2_ + i1 + 1, p_149878_3_, p_149878_4_ + j1, 3) && this.func_149880_a(p_149878_1_, p_149878_2_ + i1, p_149878_3_, p_149878_4_ + j1 + 1, 3) && this.func_149880_a(p_149878_1_, p_149878_2_ + i1 + 1, p_149878_3_, p_149878_4_ + j1 + 1, 3)) + { ++ treeType = TreeType.JUNGLE; // CraftBukkit + object = new WorldGenMegaJungle(true, 10, 20, 3, 3); + flag = true; + break label93; +@@ -130,11 +176,13 @@ + { + j1 = 0; + i1 = 0; ++ treeType = TreeType.SMALL_JUNGLE; // CraftBukkit + object = new WorldGenTrees(true, 4 + p_149878_5_.nextInt(7), 3, 3, false); + } + + break; + case 4: ++ treeType = TreeType.ACACIA; // CraftBukkit + object = new WorldGenSavannaTree(true); + break; + case 5: +@@ -147,6 +195,7 @@ + if (this.func_149880_a(p_149878_1_, p_149878_2_ + i1, p_149878_3_, p_149878_4_ + j1, 5) && this.func_149880_a(p_149878_1_, p_149878_2_ + i1 + 1, p_149878_3_, p_149878_4_ + j1, 5) && this.func_149880_a(p_149878_1_, p_149878_2_ + i1, p_149878_3_, p_149878_4_ + j1 + 1, 5) && this.func_149880_a(p_149878_1_, p_149878_2_ + i1 + 1, p_149878_3_, p_149878_4_ + j1 + 1, 5)) + { + object = new WorldGenCanopyTree(true); ++ treeType = TreeType.DARK_OAK; // CraftBukkit + flag = true; + break label108; + } diff --git a/patches/net/minecraft/block/BlockSign.java.patch b/patches/net/minecraft/block/BlockSign.java.patch new file mode 100644 index 0000000..5e0093b --- /dev/null +++ b/patches/net/minecraft/block/BlockSign.java.patch @@ -0,0 +1,29 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockSign.java ++++ ../src-work/minecraft/net/minecraft/block/BlockSign.java +@@ -14,6 +14,8 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockSign extends BlockContainer + { + private Class field_149968_a; +@@ -163,6 +165,17 @@ + } + + super.onNeighborBlockChange(p_149695_1_, p_149695_2_, p_149695_3_, p_149695_4_, p_149695_5_); ++ ++ // CraftBukkit start ++ if (p_149695_5_ != null && p_149695_5_.canProvidePower()) ++ { ++ org.bukkit.block.Block bukkitBlock = p_149695_1_.getWorld().getBlockAt(p_149695_2_, p_149695_3_, p_149695_4_); ++ int power = bukkitBlock.getBlockPower(); ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bukkitBlock, power, power); ++ p_149695_1_.getServer().getPluginManager().callEvent(eventRedstone); ++ } ++ ++ // CraftBukkit end + } + + @SideOnly(Side.CLIENT) diff --git a/patches/net/minecraft/block/BlockSkull.java.patch b/patches/net/minecraft/block/BlockSkull.java.patch new file mode 100644 index 0000000..a11ef00 --- /dev/null +++ b/patches/net/minecraft/block/BlockSkull.java.patch @@ -0,0 +1,156 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockSkull.java ++++ ../src-work/minecraft/net/minecraft/block/BlockSkull.java +@@ -27,6 +27,11 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.util.BlockStateListPopulator; ++import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; ++// CraftBukkit end ++ + public class BlockSkull extends BlockContainer + { + private static final String __OBFID = "CL_00000307"; +@@ -172,16 +177,18 @@ + { + if (p_149965_1_.getBlock(p_149965_2_, p_149965_3_ - 1, p_149965_4_ + l) == Blocks.soul_sand && p_149965_1_.getBlock(p_149965_2_, p_149965_3_ - 1, p_149965_4_ + l + 1) == Blocks.soul_sand && p_149965_1_.getBlock(p_149965_2_, p_149965_3_ - 2, p_149965_4_ + l + 1) == Blocks.soul_sand && p_149965_1_.getBlock(p_149965_2_, p_149965_3_ - 1, p_149965_4_ + l + 2) == Blocks.soul_sand && this.func_149966_a(p_149965_1_, p_149965_2_, p_149965_3_, p_149965_4_ + l, 1) && this.func_149966_a(p_149965_1_, p_149965_2_, p_149965_3_, p_149965_4_ + l + 1, 1) && this.func_149966_a(p_149965_1_, p_149965_2_, p_149965_3_, p_149965_4_ + l + 2, 1)) + { ++ // CraftBukkit start - Use BlockStateListPopulator ++ BlockStateListPopulator blockList = new BlockStateListPopulator(p_149965_1_.getWorld()); + p_149965_1_.setBlockMetadataWithNotify(p_149965_2_, p_149965_3_, p_149965_4_ + l, 8, 2); + p_149965_1_.setBlockMetadataWithNotify(p_149965_2_, p_149965_3_, p_149965_4_ + l + 1, 8, 2); + p_149965_1_.setBlockMetadataWithNotify(p_149965_2_, p_149965_3_, p_149965_4_ + l + 2, 8, 2); +- p_149965_1_.setBlock(p_149965_2_, p_149965_3_, p_149965_4_ + l, getBlockById(0), 0, 2); +- p_149965_1_.setBlock(p_149965_2_, p_149965_3_, p_149965_4_ + l + 1, getBlockById(0), 0, 2); +- p_149965_1_.setBlock(p_149965_2_, p_149965_3_, p_149965_4_ + l + 2, getBlockById(0), 0, 2); +- p_149965_1_.setBlock(p_149965_2_, p_149965_3_ - 1, p_149965_4_ + l, getBlockById(0), 0, 2); +- p_149965_1_.setBlock(p_149965_2_, p_149965_3_ - 1, p_149965_4_ + l + 1, getBlockById(0), 0, 2); +- p_149965_1_.setBlock(p_149965_2_, p_149965_3_ - 1, p_149965_4_ + l + 2, getBlockById(0), 0, 2); +- p_149965_1_.setBlock(p_149965_2_, p_149965_3_ - 2, p_149965_4_ + l + 1, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_, p_149965_3_, p_149965_4_ + l, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_, p_149965_3_, p_149965_4_ + l + 1, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_, p_149965_3_, p_149965_4_ + l + 2, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_, p_149965_3_ - 1, p_149965_4_ + l, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_, p_149965_3_ - 1, p_149965_4_ + l + 1, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_, p_149965_3_ - 1, p_149965_4_ + l + 2, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_, p_149965_3_ - 2, p_149965_4_ + l + 1, getBlockById(0), 0, 2); + + if (!p_149965_1_.isRemote) + { +@@ -190,18 +197,21 @@ + entitywither.renderYawOffset = 90.0F; + entitywither.func_82206_m(); + +- if (!p_149965_1_.isRemote) ++ if (p_149965_1_.addEntity(entitywither, SpawnReason.BUILD_WITHER)) + { +- iterator = p_149965_1_.getEntitiesWithinAABB(EntityPlayer.class, entitywither.boundingBox.expand(50.0D, 50.0D, 50.0D)).iterator(); +- +- while (iterator.hasNext()) ++ if (!p_149965_1_.isRemote) + { +- entityplayer = (EntityPlayer)iterator.next(); +- entityplayer.triggerAchievement(AchievementList.field_150963_I); ++ iterator = p_149965_1_.getEntitiesWithinAABB(EntityPlayer.class, entitywither.boundingBox.expand(50.0D, 50.0D, 50.0D)).iterator(); ++ ++ while (iterator.hasNext()) ++ { ++ entityplayer = (EntityPlayer) iterator.next(); ++ entityplayer.triggerAchievement(AchievementList.field_150963_I); ++ } + } +- } + +- p_149965_1_.spawnEntityInWorld(entitywither); ++ blockList.updateList(); ++ } + } + + for (i1 = 0; i1 < 120; ++i1) +@@ -209,13 +219,7 @@ + p_149965_1_.spawnParticle("snowballpoof", (double)p_149965_2_ + p_149965_1_.rand.nextDouble(), (double)(p_149965_3_ - 2) + p_149965_1_.rand.nextDouble() * 3.9D, (double)(p_149965_4_ + l + 1) + p_149965_1_.rand.nextDouble(), 0.0D, 0.0D, 0.0D); + } + +- p_149965_1_.notifyBlockChange(p_149965_2_, p_149965_3_, p_149965_4_ + l, getBlockById(0)); +- p_149965_1_.notifyBlockChange(p_149965_2_, p_149965_3_, p_149965_4_ + l + 1, getBlockById(0)); +- p_149965_1_.notifyBlockChange(p_149965_2_, p_149965_3_, p_149965_4_ + l + 2, getBlockById(0)); +- p_149965_1_.notifyBlockChange(p_149965_2_, p_149965_3_ - 1, p_149965_4_ + l, getBlockById(0)); +- p_149965_1_.notifyBlockChange(p_149965_2_, p_149965_3_ - 1, p_149965_4_ + l + 1, getBlockById(0)); +- p_149965_1_.notifyBlockChange(p_149965_2_, p_149965_3_ - 1, p_149965_4_ + l + 2, getBlockById(0)); +- p_149965_1_.notifyBlockChange(p_149965_2_, p_149965_3_ - 2, p_149965_4_ + l + 1, getBlockById(0)); ++ // CraftBukkit end + return; + } + } +@@ -224,16 +228,18 @@ + { + if (p_149965_1_.getBlock(p_149965_2_ + l, p_149965_3_ - 1, p_149965_4_) == Blocks.soul_sand && p_149965_1_.getBlock(p_149965_2_ + l + 1, p_149965_3_ - 1, p_149965_4_) == Blocks.soul_sand && p_149965_1_.getBlock(p_149965_2_ + l + 1, p_149965_3_ - 2, p_149965_4_) == Blocks.soul_sand && p_149965_1_.getBlock(p_149965_2_ + l + 2, p_149965_3_ - 1, p_149965_4_) == Blocks.soul_sand && this.func_149966_a(p_149965_1_, p_149965_2_ + l, p_149965_3_, p_149965_4_, 1) && this.func_149966_a(p_149965_1_, p_149965_2_ + l + 1, p_149965_3_, p_149965_4_, 1) && this.func_149966_a(p_149965_1_, p_149965_2_ + l + 2, p_149965_3_, p_149965_4_, 1)) + { ++ // CraftBukkit start - Use BlockStateListPopulator ++ BlockStateListPopulator blockList = new BlockStateListPopulator(p_149965_1_.getWorld()); + p_149965_1_.setBlockMetadataWithNotify(p_149965_2_ + l, p_149965_3_, p_149965_4_, 8, 2); + p_149965_1_.setBlockMetadataWithNotify(p_149965_2_ + l + 1, p_149965_3_, p_149965_4_, 8, 2); + p_149965_1_.setBlockMetadataWithNotify(p_149965_2_ + l + 2, p_149965_3_, p_149965_4_, 8, 2); +- p_149965_1_.setBlock(p_149965_2_ + l, p_149965_3_, p_149965_4_, getBlockById(0), 0, 2); +- p_149965_1_.setBlock(p_149965_2_ + l + 1, p_149965_3_, p_149965_4_, getBlockById(0), 0, 2); +- p_149965_1_.setBlock(p_149965_2_ + l + 2, p_149965_3_, p_149965_4_, getBlockById(0), 0, 2); +- p_149965_1_.setBlock(p_149965_2_ + l, p_149965_3_ - 1, p_149965_4_, getBlockById(0), 0, 2); +- p_149965_1_.setBlock(p_149965_2_ + l + 1, p_149965_3_ - 1, p_149965_4_, getBlockById(0), 0, 2); +- p_149965_1_.setBlock(p_149965_2_ + l + 2, p_149965_3_ - 1, p_149965_4_, getBlockById(0), 0, 2); +- p_149965_1_.setBlock(p_149965_2_ + l + 1, p_149965_3_ - 2, p_149965_4_, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_ + l, p_149965_3_, p_149965_4_, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_ + l + 1, p_149965_3_, p_149965_4_, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_ + l + 2, p_149965_3_, p_149965_4_, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_ + l, p_149965_3_ - 1, p_149965_4_, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_ + l + 1, p_149965_3_ - 1, p_149965_4_, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_ + l + 2, p_149965_3_ - 1, p_149965_4_, getBlockById(0), 0, 2); ++ blockList.setTypeAndData(p_149965_2_ + l + 1, p_149965_3_ - 2, p_149965_4_, getBlockById(0), 0, 2); + + if (!p_149965_1_.isRemote) + { +@@ -241,18 +247,21 @@ + entitywither.setLocationAndAngles((double)(p_149965_2_ + l) + 1.5D, (double)p_149965_3_ - 1.45D, (double)p_149965_4_ + 0.5D, 0.0F, 0.0F); + entitywither.func_82206_m(); + +- if (!p_149965_1_.isRemote) ++ if (p_149965_1_.addEntity(entitywither, SpawnReason.BUILD_WITHER)) + { +- iterator = p_149965_1_.getEntitiesWithinAABB(EntityPlayer.class, entitywither.boundingBox.expand(50.0D, 50.0D, 50.0D)).iterator(); +- +- while (iterator.hasNext()) ++ if (!p_149965_1_.isRemote) + { +- entityplayer = (EntityPlayer)iterator.next(); +- entityplayer.triggerAchievement(AchievementList.field_150963_I); ++ iterator = p_149965_1_.getEntitiesWithinAABB(EntityPlayer.class, entitywither.boundingBox.expand(50.0D, 50.0D, 50.0D)).iterator(); ++ ++ while (iterator.hasNext()) ++ { ++ entityplayer = (EntityPlayer) iterator.next(); ++ entityplayer.triggerAchievement(AchievementList.field_150963_I); ++ } + } +- } + +- p_149965_1_.spawnEntityInWorld(entitywither); ++ blockList.updateList(); ++ } + } + + for (i1 = 0; i1 < 120; ++i1) +@@ -260,13 +269,7 @@ + p_149965_1_.spawnParticle("snowballpoof", (double)(p_149965_2_ + l + 1) + p_149965_1_.rand.nextDouble(), (double)(p_149965_3_ - 2) + p_149965_1_.rand.nextDouble() * 3.9D, (double)p_149965_4_ + p_149965_1_.rand.nextDouble(), 0.0D, 0.0D, 0.0D); + } + +- p_149965_1_.notifyBlockChange(p_149965_2_ + l, p_149965_3_, p_149965_4_, getBlockById(0)); +- p_149965_1_.notifyBlockChange(p_149965_2_ + l + 1, p_149965_3_, p_149965_4_, getBlockById(0)); +- p_149965_1_.notifyBlockChange(p_149965_2_ + l + 2, p_149965_3_, p_149965_4_, getBlockById(0)); +- p_149965_1_.notifyBlockChange(p_149965_2_ + l, p_149965_3_ - 1, p_149965_4_, getBlockById(0)); +- p_149965_1_.notifyBlockChange(p_149965_2_ + l + 1, p_149965_3_ - 1, p_149965_4_, getBlockById(0)); +- p_149965_1_.notifyBlockChange(p_149965_2_ + l + 2, p_149965_3_ - 1, p_149965_4_, getBlockById(0)); +- p_149965_1_.notifyBlockChange(p_149965_2_ + l + 1, p_149965_3_ - 2, p_149965_4_, getBlockById(0)); ++ // CraftBukkit end + return; + } + } diff --git a/patches/net/minecraft/block/BlockSnow.java.patch b/patches/net/minecraft/block/BlockSnow.java.patch new file mode 100644 index 0000000..86c0ed8 --- /dev/null +++ b/patches/net/minecraft/block/BlockSnow.java.patch @@ -0,0 +1,17 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockSnow.java ++++ ../src-work/minecraft/net/minecraft/block/BlockSnow.java +@@ -114,6 +114,14 @@ + { + if (p_149674_1_.getSavedLightValue(EnumSkyBlock.Block, p_149674_2_, p_149674_3_, p_149674_4_) > 11) + { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockFadeEvent(p_149674_1_.getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_), Blocks.air).isCancelled()) ++ { ++ return; ++ } ++ ++ // CraftBukkit end ++ this.dropBlockAsItem(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, p_149674_1_.getBlockMetadata(p_149674_2_, p_149674_3_, p_149674_4_), 0); + p_149674_1_.setBlockToAir(p_149674_2_, p_149674_3_, p_149674_4_); + } + } diff --git a/patches/net/minecraft/block/BlockStaticLiquid.java.patch b/patches/net/minecraft/block/BlockStaticLiquid.java.patch new file mode 100644 index 0000000..8d27641 --- /dev/null +++ b/patches/net/minecraft/block/BlockStaticLiquid.java.patch @@ -0,0 +1,57 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockStaticLiquid.java ++++ ../src-work/minecraft/net/minecraft/block/BlockStaticLiquid.java +@@ -5,6 +5,8 @@ + import net.minecraft.init.Blocks; + import net.minecraft.world.World; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class BlockStaticLiquid extends BlockLiquid + { + private static final String __OBFID = "CL_00000315"; +@@ -43,6 +45,11 @@ + { + int l = p_149674_5_.nextInt(3); + int i1; ++ // CraftBukkit start - Prevent lava putting something on fire, remember igniter block coords ++ int x = p_149674_2_; ++ int y = p_149674_3_; ++ int z = p_149674_4_; ++ // CraftBukkit end + + for (i1 = 0; i1 < l; ++i1) + { +@@ -55,6 +62,16 @@ + { + if (this.isFlammable(p_149674_1_, p_149674_2_ - 1, p_149674_3_, p_149674_4_) || this.isFlammable(p_149674_1_, p_149674_2_ + 1, p_149674_3_, p_149674_4_) || this.isFlammable(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_ - 1) || this.isFlammable(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_ + 1) || this.isFlammable(p_149674_1_, p_149674_2_, p_149674_3_ - 1, p_149674_4_) || this.isFlammable(p_149674_1_, p_149674_2_, p_149674_3_ + 1, p_149674_4_)) + { ++ // CraftBukkit start - Prevent lava putting something on fire ++ if (p_149674_1_.getBlock(p_149674_2_, p_149674_3_, p_149674_4_) != Blocks.fire) ++ { ++ if (CraftEventFactory.callBlockIgniteEvent(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, x, y, z).isCancelled()) ++ { ++ continue; ++ } ++ } ++ ++ // CraftBukkit end + p_149674_1_.setBlock(p_149674_2_, p_149674_3_, p_149674_4_, Blocks.fire); + return; + } +@@ -77,6 +94,16 @@ + + if (p_149674_1_.isAirBlock(p_149674_2_, p_149674_3_ + 1, p_149674_4_) && this.isFlammable(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_)) + { ++ // CraftBukkit start - Prevent lava putting something on fire ++ if (p_149674_1_.getBlock(p_149674_2_, p_149674_3_ + 1, p_149674_4_) != Blocks.fire) ++ { ++ if (CraftEventFactory.callBlockIgniteEvent(p_149674_1_, p_149674_2_, p_149674_3_ + 1, p_149674_4_, x, y, z).isCancelled()) ++ { ++ continue; ++ } ++ } ++ ++ // CraftBukkit end + p_149674_1_.setBlock(p_149674_2_, p_149674_3_ + 1, p_149674_4_, Blocks.fire); + } + } diff --git a/patches/net/minecraft/block/BlockStem.java.patch b/patches/net/minecraft/block/BlockStem.java.patch new file mode 100644 index 0000000..41aed08 --- /dev/null +++ b/patches/net/minecraft/block/BlockStem.java.patch @@ -0,0 +1,37 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockStem.java ++++ ../src-work/minecraft/net/minecraft/block/BlockStem.java +@@ -17,6 +17,8 @@ + import net.minecraft.world.World; + import static net.minecraftforge.common.util.ForgeDirection.*; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class BlockStem extends BlockBush implements IGrowable + { + private final Block field_149877_a; +@@ -46,14 +48,14 @@ + { + float f = this.func_149875_n(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_); + +- if (p_149674_5_.nextInt((int)(25.0F / f) + 1) == 0) ++ if (p_149674_5_.nextInt((int)(p_149674_1_.growthOdds / (this == Blocks.pumpkin_stem ? p_149674_1_.getSpigotConfig().pumpkinModifier : p_149674_1_.spigotConfig.melonModifier) * (25.0F / f)) + 1) == 0) // Spigot // Cauldron + { + int l = p_149674_1_.getBlockMetadata(p_149674_2_, p_149674_3_, p_149674_4_); + + if (l < 7) + { + ++l; +- p_149674_1_.setBlockMetadataWithNotify(p_149674_2_, p_149674_3_, p_149674_4_, l, 2); ++ CraftEventFactory.handleBlockGrowEvent(p_149674_1_, p_149674_2_, p_149674_3_, p_149674_4_, this, l); // CraftBukkit + } + else + { +@@ -105,7 +107,7 @@ + + if (p_149674_1_.isAirBlock(j1, p_149674_3_, k1) && (block.canSustainPlant(p_149674_1_, j1, p_149674_3_ - 1, k1, UP, this) || block == Blocks.dirt || block == Blocks.grass)) + { +- p_149674_1_.setBlock(j1, p_149674_3_, k1, this.field_149877_a); ++ CraftEventFactory.handleBlockGrowEvent(p_149674_1_, j1, p_149674_3_, k1, this.field_149877_a, 0); // CraftBukkit + } + } + } diff --git a/patches/net/minecraft/block/BlockTrapDoor.java.patch b/patches/net/minecraft/block/BlockTrapDoor.java.patch new file mode 100644 index 0000000..d2418ce --- /dev/null +++ b/patches/net/minecraft/block/BlockTrapDoor.java.patch @@ -0,0 +1,32 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockTrapDoor.java ++++ ../src-work/minecraft/net/minecraft/block/BlockTrapDoor.java +@@ -13,6 +13,8 @@ + import net.minecraft.world.World; + import net.minecraftforge.common.util.ForgeDirection; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockTrapDoor extends Block + { + /** Set this to allow trapdoors to remain free-floating */ +@@ -176,6 +178,20 @@ + + if (flag || p_149695_5_.canProvidePower()) + { ++ // CraftBukkit start ++ org.bukkit.World bworld = p_149695_1_.getWorld(); ++ org.bukkit.block.Block bblock = bworld.getBlockAt(p_149695_2_, p_149695_3_, p_149695_4_); ++ int power = bblock.getBlockPower(); ++ int oldPower = (p_149695_1_.getBlockMetadata(p_149695_2_, p_149695_3_, p_149695_4_) & 4) > 0 ? 15 : 0; ++ ++ if (oldPower == 0 ^ power == 0 || p_149695_5_.canProvidePower()) ++ { ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(bblock, oldPower, power); ++ p_149695_1_.getServer().getPluginManager().callEvent(eventRedstone); ++ flag = eventRedstone.getNewCurrent() > 0; ++ } ++ ++ // CraftBukkit end + this.func_150120_a(p_149695_1_, p_149695_2_, p_149695_3_, p_149695_4_, flag); + } + } diff --git a/patches/net/minecraft/block/BlockTripWire.java.patch b/patches/net/minecraft/block/BlockTripWire.java.patch new file mode 100644 index 0000000..d3721ed --- /dev/null +++ b/patches/net/minecraft/block/BlockTripWire.java.patch @@ -0,0 +1,63 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockTripWire.java ++++ ../src-work/minecraft/net/minecraft/block/BlockTripWire.java +@@ -16,6 +16,8 @@ + import net.minecraft.world.IBlockAccess; + import net.minecraft.world.World; + ++import org.bukkit.event.entity.EntityInteractEvent; // CraftBukkit ++ + public class BlockTripWire extends Block + { + private static final String __OBFID = "CL_00000328"; +@@ -208,6 +210,51 @@ + } + } + ++ // CraftBukkit start - Call interact even when triggering connected tripwire ++ if (flag != flag1 && flag1 && (p_150140_1_.getBlockMetadata(p_150140_2_, p_150140_3_, p_150140_4_) & 4) == 4) ++ { ++ org.bukkit.World bworld = p_150140_1_.getWorld(); ++ org.bukkit.plugin.PluginManager manager = p_150140_1_.getServer().getPluginManager(); ++ org.bukkit.block.Block block = bworld.getBlockAt(p_150140_2_, p_150140_3_, p_150140_4_); ++ boolean allowed = false; ++ ++ // If all of the events are cancelled block the tripwire trigger, else allow ++ for (Object object : list) ++ { ++ if (object != null) ++ { ++ org.bukkit.event.Cancellable cancellable; ++ ++ if (object instanceof EntityPlayer) ++ { ++ cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent((EntityPlayer) object, org.bukkit.event.block.Action.PHYSICAL, p_150140_2_, p_150140_3_, p_150140_4_, -1, null); ++ } ++ else if (object instanceof Entity) ++ { ++ cancellable = new EntityInteractEvent(((Entity) object).getBukkitEntity(), block); ++ manager.callEvent((EntityInteractEvent) cancellable); ++ } ++ else ++ { ++ continue; ++ } ++ ++ if (!cancellable.isCancelled()) ++ { ++ allowed = true; ++ break; ++ } ++ } ++ } ++ ++ if (!allowed) ++ { ++ return; ++ } ++ } ++ ++ // CraftBukkit end ++ + if (flag1 && !flag) + { + l |= 1; diff --git a/patches/net/minecraft/block/BlockTripWireHook.java.patch b/patches/net/minecraft/block/BlockTripWireHook.java.patch new file mode 100644 index 0000000..f860cea --- /dev/null +++ b/patches/net/minecraft/block/BlockTripWireHook.java.patch @@ -0,0 +1,29 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockTripWireHook.java ++++ ../src-work/minecraft/net/minecraft/block/BlockTripWireHook.java +@@ -12,6 +12,8 @@ + import net.minecraftforge.common.util.ForgeDirection; + import static net.minecraftforge.common.util.ForgeDirection.*; + ++import org.bukkit.event.block.BlockRedstoneEvent; // CraftBukkit ++ + public class BlockTripWireHook extends Block + { + private static final String __OBFID = "CL_00000329"; +@@ -210,6 +212,17 @@ + this.func_150135_a(p_150136_1_, l2, p_150136_3_, i3, flag4, flag5, flag2, flag3); + } + ++ // CraftBukkit start ++ org.bukkit.block.Block block = p_150136_1_.getWorld().getBlockAt(p_150136_2_, p_150136_3_, p_150136_4_); ++ BlockRedstoneEvent eventRedstone = new BlockRedstoneEvent(block, 15, 0); ++ p_150136_1_.getServer().getPluginManager().callEvent(eventRedstone); ++ ++ if (eventRedstone.getNewCurrent() > 0) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + this.func_150135_a(p_150136_1_, p_150136_2_, p_150136_3_, p_150136_4_, flag4, flag5, flag2, flag3); + + if (!p_150136_5_) diff --git a/patches/net/minecraft/block/BlockVine.java.patch b/patches/net/minecraft/block/BlockVine.java.patch new file mode 100644 index 0000000..0eac4fe --- /dev/null +++ b/patches/net/minecraft/block/BlockVine.java.patch @@ -0,0 +1,77 @@ +--- ../src-base/minecraft/net/minecraft/block/BlockVine.java ++++ ../src-work/minecraft/net/minecraft/block/BlockVine.java +@@ -21,6 +21,8 @@ + import net.minecraftforge.common.ForgeHooks; + import net.minecraftforge.common.IShearable; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class BlockVine extends Block implements IShearable + { + private static final String __OBFID = "CL_00000330"; +@@ -268,7 +270,11 @@ + + if (j2 > 0) + { +- p_149674_1_.setBlock(p_149674_2_, p_149674_3_ + 1, p_149674_4_, this, j2, 2); ++ // CraftBukkit start - Call BlockSpreadEvent ++ org.bukkit.block.Block source = p_149674_1_.getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_); ++ org.bukkit.block.Block block = p_149674_1_.getWorld().getBlockAt(p_149674_2_, p_149674_3_ + 1, p_149674_4_); ++ CraftEventFactory.handleBlockSpreadEvent(block, source, this, l1); ++ // CraftBukkit end + } + } + } +@@ -290,27 +296,34 @@ + { + l1 = k1 + 1 & 3; + i2 = k1 + 3 & 3; ++ // CraftBukkit start - Call BlockSpreadEvent ++ org.bukkit.block.Block source = p_149674_1_.getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_); ++ org.bukkit.block.Block bukkitBlock = p_149674_1_.getWorld().getBlockAt(p_149674_2_ + Direction.offsetX[k1], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1]); + + if ((i1 & 1 << l1) != 0 && this.func_150093_a(p_149674_1_.getBlock(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[l1], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[l1]))) + { +- p_149674_1_.setBlock(p_149674_2_ + Direction.offsetX[k1], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1], this, 1 << l1, 2); ++ CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, 1 << l1); + } + else if ((i1 & 1 << i2) != 0 && this.func_150093_a(p_149674_1_.getBlock(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[i2], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[i2]))) + { +- p_149674_1_.setBlock(p_149674_2_ + Direction.offsetX[k1], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1], this, 1 << i2, 2); ++ CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, 1 << i2); + } + else if ((i1 & 1 << l1) != 0 && p_149674_1_.isAirBlock(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[l1], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[l1]) && this.func_150093_a(p_149674_1_.getBlock(p_149674_2_ + Direction.offsetX[l1], p_149674_3_, p_149674_4_ + Direction.offsetZ[l1]))) + { +- p_149674_1_.setBlock(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[l1], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[l1], this, 1 << (k1 + 2 & 3), 2); ++ bukkitBlock = p_149674_1_.getWorld().getBlockAt(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[l1], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[l1]); ++ CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, 1 << (k1 + 2 & 3)); + } + else if ((i1 & 1 << i2) != 0 && p_149674_1_.isAirBlock(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[i2], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[i2]) && this.func_150093_a(p_149674_1_.getBlock(p_149674_2_ + Direction.offsetX[i2], p_149674_3_, p_149674_4_ + Direction.offsetZ[i2]))) + { +- p_149674_1_.setBlock(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[i2], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[i2], this, 1 << (k1 + 2 & 3), 2); ++ bukkitBlock = p_149674_1_.getWorld().getBlockAt(p_149674_2_ + Direction.offsetX[k1] + Direction.offsetX[i2], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1] + Direction.offsetZ[i2]); ++ CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, 1 << (k1 + 2 & 3)); + } + else if (this.func_150093_a(p_149674_1_.getBlock(p_149674_2_ + Direction.offsetX[k1], p_149674_3_ + 1, p_149674_4_ + Direction.offsetZ[k1]))) + { +- p_149674_1_.setBlock(p_149674_2_ + Direction.offsetX[k1], p_149674_3_, p_149674_4_ + Direction.offsetZ[k1], this, 0, 2); ++ CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, 0); + } ++ ++ // CraftBukkit end + } + else if (block.blockMaterial.isOpaque() && block.renderAsNormalBlock()) + { +@@ -327,7 +340,11 @@ + + if (l1 > 0) + { +- p_149674_1_.setBlock(p_149674_2_, p_149674_3_ - 1, p_149674_4_, this, l1, 2); ++ // CraftBukkit start - Call BlockSpreadEvent ++ org.bukkit.block.Block source = p_149674_1_.getWorld().getBlockAt(p_149674_2_, p_149674_3_, p_149674_4_); ++ org.bukkit.block.Block bukkitBlock = p_149674_1_.getWorld().getBlockAt(p_149674_2_, p_149674_3_ - 1, p_149674_4_); ++ CraftEventFactory.handleBlockSpreadEvent(bukkitBlock, source, this, l1); ++ // CraftBukkit end + } + } + else if (block == this) diff --git a/patches/net/minecraft/client/Minecraft.java.patch b/patches/net/minecraft/client/Minecraft.java.patch new file mode 100644 index 0000000..9134545 --- /dev/null +++ b/patches/net/minecraft/client/Minecraft.java.patch @@ -0,0 +1,26 @@ +--- ../src-base/minecraft/net/minecraft/client/Minecraft.java ++++ ../src-work/minecraft/net/minecraft/client/Minecraft.java +@@ -148,6 +148,7 @@ + import net.minecraft.util.Timer; + import net.minecraft.util.Util; + import net.minecraft.world.EnumDifficulty; ++import net.minecraft.world.MinecraftException; + import net.minecraft.world.WorldProviderEnd; + import net.minecraft.world.WorldProviderHell; + import net.minecraft.world.WorldSettings; +@@ -2644,7 +2645,14 @@ + + if (integratedserver != null) + { +- integratedserver.stopServer(); ++ try ++ { ++ integratedserver.stopServer(); ++ } ++ catch (MinecraftException e) ++ { ++ e.printStackTrace(); ++ } + } + } + } diff --git a/patches/net/minecraft/command/CommandHandler.java.patch b/patches/net/minecraft/command/CommandHandler.java.patch new file mode 100644 index 0000000..a5f91b0 --- /dev/null +++ b/patches/net/minecraft/command/CommandHandler.java.patch @@ -0,0 +1,74 @@ +--- ../src-base/minecraft/net/minecraft/command/CommandHandler.java ++++ ../src-work/minecraft/net/minecraft/command/CommandHandler.java +@@ -16,6 +16,11 @@ + + import net.minecraftforge.common.MinecraftForge; + import net.minecraftforge.event.CommandEvent; ++// Cauldron start ++import org.bukkit.craftbukkit.command.CraftSimpleCommandMap; ++import org.bukkit.craftbukkit.command.ModCustomCommand; ++import cpw.mods.fml.common.FMLCommonHandler; ++// Cauldron end + + public class CommandHandler implements ICommandManager + { +@@ -48,7 +53,7 @@ + throw new CommandNotFoundException(); + } + +- if (icommand.canCommandSenderUseCommand(p_71556_1_)) ++ if (true || icommand.canCommandSenderUseCommand(p_71556_1_)) // Cauldron start - disable check for permissions since we handle it on Bukkit side + { + CommandEvent event = new CommandEvent(icommand, p_71556_1_, astring); + if (MinecraftForge.EVENT_BUS.post(event)) +@@ -134,11 +139,30 @@ + + public ICommand registerCommand(ICommand p_71560_1_) + { +- List list = p_71560_1_.getCommandAliases(); +- this.commandMap.put(p_71560_1_.getCommandName(), p_71560_1_); +- this.commandSet.add(p_71560_1_); ++ // Cauldron start - register commands with permission nodes, defaulting to class name ++ return registerCommand(p_71560_1_, p_71560_1_.getClass().getName()); ++ } + ++ public ICommand registerCommand(String permissionGroup, ICommand par1ICommand) ++ { ++ return registerCommand(par1ICommand, permissionGroup + "." + par1ICommand.getCommandName()); ++ } ++ ++ public ICommand registerCommand(ICommand par1ICommand, String permissionNode) ++ { ++ List list = par1ICommand.getCommandAliases(); ++ this.commandMap.put(par1ICommand.getCommandName(), par1ICommand); ++ this.commandSet.add(par1ICommand); ++ // register vanilla commands with Bukkit to support permissions. ++ CraftSimpleCommandMap commandMap = FMLCommonHandler.instance().getMinecraftServerInstance().server.getCraftCommandMap(); ++ ModCustomCommand customCommand = new ModCustomCommand(par1ICommand.getCommandName()); ++ customCommand.setPermission(permissionNode); + if (list != null) ++ customCommand.setAliases(list); ++ commandMap.register(par1ICommand.getCommandName(), customCommand); ++ LogManager.getLogger().info("Registered command " + par1ICommand.getCommandName() + " with permission node " + permissionNode); ++ ++ if (list != null) + { + Iterator iterator = list.iterator(); + +@@ -149,13 +173,14 @@ + + if (icommand1 == null || !icommand1.getCommandName().equals(s)) + { +- this.commandMap.put(s, p_71560_1_); ++ this.commandMap.put(s, par1ICommand); + } + } + } + +- return p_71560_1_; ++ return par1ICommand; + } ++ // Cauldron end + + private static String[] dropFirstString(String[] p_71559_0_) + { diff --git a/patches/net/minecraft/command/PlayerSelector.java.patch b/patches/net/minecraft/command/PlayerSelector.java.patch new file mode 100644 index 0000000..b9a88e1 --- /dev/null +++ b/patches/net/minecraft/command/PlayerSelector.java.patch @@ -0,0 +1,24 @@ +--- ../src-base/minecraft/net/minecraft/command/PlayerSelector.java ++++ ../src-work/minecraft/net/minecraft/command/PlayerSelector.java +@@ -7,6 +7,7 @@ + import java.util.Map; + import java.util.regex.Matcher; + import java.util.regex.Pattern; ++import net.minecraft.command.server.CommandBlockLogic; + import net.minecraft.entity.player.EntityPlayerMP; + import net.minecraft.server.MinecraftServer; + import net.minecraft.util.ChunkCoordinates; +@@ -51,6 +52,13 @@ + + public static EntityPlayerMP[] matchPlayers(ICommandSender p_82380_0_, String p_82380_1_) + { ++ // CraftBukkit start ++ if (!(p_82380_0_ instanceof CommandBlockLogic)) ++ { ++ return null; ++ } ++ ++ // CraftBukkit end + Matcher matcher = tokenPattern.matcher(p_82380_1_); + + if (matcher.matches()) diff --git a/patches/net/minecraft/command/ServerCommandManager.java.patch b/patches/net/minecraft/command/ServerCommandManager.java.patch new file mode 100644 index 0000000..93d575e --- /dev/null +++ b/patches/net/minecraft/command/ServerCommandManager.java.patch @@ -0,0 +1,76 @@ +--- ../src-base/minecraft/net/minecraft/command/ServerCommandManager.java ++++ ../src-work/minecraft/net/minecraft/command/ServerCommandManager.java +@@ -39,8 +39,16 @@ + { + private static final String __OBFID = "CL_00000922"; + ++ // Cauldron start - moved commands to it's own method to be executed further in server startup + changed to registerVanillaCommand + public ServerCommandManager() + { ++ CommandBase.setAdminCommander(this); ++ } ++ ++ public void registerVanillaCommands() ++ { ++ // Cauldron - do not register vanilla commands replaced by Bukkit ++ /* + this.registerCommand(new CommandTime()); + this.registerCommand(new CommandGameMode()); + this.registerCommand(new CommandDifficulty()); +@@ -56,7 +64,6 @@ + this.registerCommand(new CommandEmote()); + this.registerCommand(new CommandShowSeed()); + this.registerCommand(new CommandHelp()); +- this.registerCommand(new CommandDebug()); + this.registerCommand(new CommandMessage()); + this.registerCommand(new CommandBroadcast()); + this.registerCommand(new CommandSetSpawnpoint()); +@@ -64,17 +71,23 @@ + this.registerCommand(new CommandGameRule()); + this.registerCommand(new CommandClearInventory()); + this.registerCommand(new CommandTestFor()); +- this.registerCommand(new CommandSpreadPlayers()); +- this.registerCommand(new CommandPlaySound()); +- this.registerCommand(new CommandScoreboard()); +- this.registerCommand(new CommandAchievement()); +- this.registerCommand(new CommandSummon()); +- this.registerCommand(new CommandSetBlock()); +- this.registerCommand(new CommandTestForBlock()); +- this.registerCommand(new CommandMessageRaw()); ++ */ ++ // Cauldron start - add permission nodes for rest of vanilla commands ++ this.registerCommand("vanilla.command", new CommandDebug()); ++ this.registerCommand("vanilla.command", new CommandSpreadPlayers()); ++ this.registerCommand("vanilla.command", new CommandPlaySound()); ++ this.registerCommand("vanilla.command", new CommandScoreboard()); ++ this.registerCommand("vanilla.command", new CommandAchievement()); ++ this.registerCommand("vanilla.command", new CommandSummon()); ++ this.registerCommand("vanilla.command", new CommandSetBlock()); ++ this.registerCommand("vanilla.command", new CommandTestForBlock()); ++ this.registerCommand("vanilla.command", new CommandMessageRaw()); ++ this.registerCommand("vanilla.command", new CommandNetstat()); ++ // Cauldron end + + if (MinecraftServer.getServer().isDedicatedServer()) + { ++ /* + this.registerCommand(new CommandOp()); + this.registerCommand(new CommandDeOp()); + this.registerCommand(new CommandStop()); +@@ -90,7 +103,7 @@ + this.registerCommand(new CommandListPlayers()); + this.registerCommand(new CommandWhitelist()); + this.registerCommand(new CommandSetPlayerTimeout()); +- this.registerCommand(new CommandNetstat()); ++ */ + } + else + { +@@ -98,6 +111,7 @@ + } + + CommandBase.setAdminCommander(this); ++ // Cauldron end + } + + public void func_152372_a(ICommandSender p_152372_1_, ICommand p_152372_2_, int p_152372_3_, String p_152372_4_, Object ... p_152372_5_) diff --git a/patches/net/minecraft/command/server/CommandBlockLogic.java.patch b/patches/net/minecraft/command/server/CommandBlockLogic.java.patch new file mode 100644 index 0000000..e80fed8 --- /dev/null +++ b/patches/net/minecraft/command/server/CommandBlockLogic.java.patch @@ -0,0 +1,212 @@ +--- ../src-base/minecraft/net/minecraft/command/server/CommandBlockLogic.java ++++ ../src-work/minecraft/net/minecraft/command/server/CommandBlockLogic.java +@@ -9,18 +9,30 @@ + import net.minecraft.command.ICommandSender; + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.server.MinecraftServer; ++import net.minecraft.tileentity.TileEntityCommandBlockListener; + import net.minecraft.util.ChatComponentText; + import net.minecraft.util.IChatComponent; + import net.minecraft.world.World; + ++// CraftBukkit start ++import java.util.ArrayList; ++import org.apache.logging.log4j.Level; ++import org.bukkit.craftbukkit.command.VanillaCommandWrapper; ++import com.google.common.base.Joiner; ++import net.minecraft.command.PlayerSelector; ++import net.minecraft.entity.EntityMinecartCommandBlockListener; ++import net.minecraft.entity.player.EntityPlayerMP; ++// CraftBukkit end ++ + public abstract class CommandBlockLogic implements ICommandSender + { + private static final SimpleDateFormat field_145766_a = new SimpleDateFormat("HH:mm:ss"); + private int field_145764_b; + private boolean field_145765_c = true; + private IChatComponent field_145762_d = null; +- private String field_145763_e = ""; ++ public String field_145763_e = ""; // CraftBukkit - private -> public + private String field_145761_f = "@"; ++ protected org.bukkit.command.CommandSender sender; // CraftBukkit - add sender; + private static final String __OBFID = "CL_00000128"; + + public int func_145760_g() +@@ -94,8 +106,143 @@ + + if (minecraftserver != null && minecraftserver.isCommandBlockEnabled()) + { +- ICommandManager icommandmanager = minecraftserver.getCommandManager(); +- this.field_145764_b = icommandmanager.executeCommand(this, this.field_145763_e); ++ // CraftBukkit start - Handle command block commands using Bukkit dispatcher ++ org.bukkit.command.SimpleCommandMap commandMap = minecraftserver.server.getCommandMap(); ++ Joiner joiner = Joiner.on(" "); ++ String command = this.field_145763_e; ++ ++ if (this.field_145763_e.startsWith("/")) ++ { ++ command = this.field_145763_e.substring(1); ++ } ++ ++ String[] args = command.split(" "); ++ ArrayList commands = new ArrayList(); ++ ++ // Block disallowed commands ++ if (args[0].equalsIgnoreCase("stop") || args[0].equalsIgnoreCase("kick") || args[0].equalsIgnoreCase("op") || ++ args[0].equalsIgnoreCase("deop") || args[0].equalsIgnoreCase("ban") || args[0].equalsIgnoreCase("ban-ip") || ++ args[0].equalsIgnoreCase("pardon") || args[0].equalsIgnoreCase("pardon-ip") || args[0].equalsIgnoreCase("reload")) ++ { ++ this.field_145764_b = 0; ++ return; ++ } ++ ++ // If the world has no players don't run ++ if (this.getEntityWorld().playerEntities.isEmpty()) ++ { ++ this.field_145764_b = 0; ++ return; ++ } ++ ++ // Handle vanilla commands; ++ if (minecraftserver.server.getCommandBlockOverride(args[0])) ++ { ++ org.bukkit.command.Command commandBlockCommand = commandMap.getCommand("minecraft:" + args[0]); ++ ++ if (commandBlockCommand instanceof VanillaCommandWrapper) ++ { ++ this.field_145764_b = ((VanillaCommandWrapper) commandBlockCommand).dispatchVanillaCommandBlock(this, this.field_145763_e); ++ return; ++ } ++ } ++ ++ // Make sure this is a valid command ++ if (commandMap.getCommand(args[0]) == null) ++ { ++ // Cauldron start - execute command using the vanilla command manager if it isn't in the bukkit command map ++ net.minecraft.command.ICommandManager icommandmanager = minecraftserver.getCommandManager(); ++ icommandmanager.executeCommand(this, this.field_145763_e); ++ return; ++ // Cauldron end ++ } ++ ++ // testfor command requires special handling ++ if (args[0].equalsIgnoreCase("testfor")) ++ { ++ if (args.length < 2) ++ { ++ this.field_145764_b = 0; ++ return; ++ } ++ ++ EntityPlayerMP[] players = PlayerSelector.matchPlayers(this, args[1]); ++ ++ if (players != null && players.length > 0) ++ { ++ this.field_145764_b = players.length; ++ return; ++ } ++ else ++ { ++ EntityPlayerMP player = MinecraftServer.getServer().getConfigurationManager().func_152612_a(args[1]); ++ ++ if (player == null) ++ { ++ this.field_145764_b = 0; ++ return; ++ } ++ else ++ { ++ this.field_145764_b = 1; ++ return; ++ } ++ } ++ } ++ ++ commands.add(args); ++ // Find positions of command block syntax, if any ++ ArrayList newCommands = new ArrayList(); ++ ++ for (int i = 0; i < args.length; i++) ++ { ++ if (PlayerSelector.hasArguments(args[i])) ++ { ++ for (int j = 0; j < commands.size(); j++) ++ { ++ newCommands.addAll(this.buildCommands(commands.get(j), i)); ++ } ++ ++ ArrayList temp = commands; ++ commands = newCommands; ++ newCommands = temp; ++ newCommands.clear(); ++ } ++ } ++ ++ int completed = 0; ++ ++ // Now dispatch all of the commands we ended up with ++ for (int i = 0; i < commands.size(); i++) ++ { ++ try ++ { ++ if (commandMap.dispatch(sender, joiner.join(java.util.Arrays.asList(commands.get(i))))) ++ { ++ completed++; ++ } ++ } ++ catch (Throwable exception) ++ { ++ if (this instanceof TileEntityCommandBlockListener) ++ { ++ TileEntityCommandBlockListener listener = (TileEntityCommandBlockListener) this; ++ MinecraftServer.getLogger().log(Level.WARN, String.format("CommandBlock at (%d,%d,%d) failed to handle command", listener.getPlayerCoordinates().posX, listener.getPlayerCoordinates().posY, listener.getPlayerCoordinates().posZ), exception); ++ } ++ else if (this instanceof EntityMinecartCommandBlockListener) ++ { ++ EntityMinecartCommandBlockListener listener = (EntityMinecartCommandBlockListener) this; ++ MinecraftServer.getLogger().log(Level.WARN, String.format("MinecartCommandBlock at (%d,%d,%d) failed to handle command", listener.getPlayerCoordinates().posX, listener.getPlayerCoordinates().posY, listener.getPlayerCoordinates().posZ), exception); ++ } ++ else ++ { ++ MinecraftServer.getLogger().log(Level.WARN, String.format("Unknown CommandBlock failed to handle command"), exception); ++ } ++ } ++ } ++ ++ this.field_145764_b = completed; ++ // CraftBukkit end + } + else + { +@@ -103,6 +250,31 @@ + } + } + ++ // CraftBukkit start ++ private ArrayList buildCommands(String[] args, int pos) ++ { ++ ArrayList commands = new ArrayList(); ++ EntityPlayerMP[] players = PlayerSelector.matchPlayers(this, args[pos]); ++ ++ if (players != null) ++ { ++ for (EntityPlayerMP player : players) ++ { ++ if (player.worldObj != this.getEntityWorld()) ++ { ++ continue; ++ } ++ ++ String[] command = args.clone(); ++ command[pos] = player.getCommandSenderName(); ++ commands.add(command); ++ } ++ } ++ ++ return commands; ++ } ++ // CraftBukkit end ++ + public String getCommandSenderName() + { + return this.field_145761_f; diff --git a/patches/net/minecraft/dispenser/BehaviorDefaultDispenseItem.java.patch b/patches/net/minecraft/dispenser/BehaviorDefaultDispenseItem.java.patch new file mode 100644 index 0000000..4222be5 --- /dev/null +++ b/patches/net/minecraft/dispenser/BehaviorDefaultDispenseItem.java.patch @@ -0,0 +1,101 @@ +--- ../src-base/minecraft/net/minecraft/dispenser/BehaviorDefaultDispenseItem.java ++++ ../src-work/minecraft/net/minecraft/dispenser/BehaviorDefaultDispenseItem.java +@@ -6,6 +6,11 @@ + import net.minecraft.util.EnumFacing; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.block.BlockDispenseEvent; ++// CraftBukkit end ++ + public class BehaviorDefaultDispenseItem implements IBehaviorDispenseItem + { + private static final String __OBFID = "CL_00001195"; +@@ -23,10 +28,17 @@ + EnumFacing enumfacing = BlockDispenser.func_149937_b(p_82487_1_.getBlockMetadata()); + IPosition iposition = BlockDispenser.func_149939_a(p_82487_1_); + ItemStack itemstack1 = p_82487_2_.splitStack(1); +- doDispense(p_82487_1_.getWorld(), itemstack1, 6, enumfacing, iposition); ++ // CraftBukkit start ++ if (!doDispense(p_82487_1_.getWorld(), itemstack1, 6, enumfacing, p_82487_1_)) ++ { ++ p_82487_2_.stackSize++; ++ } ++ ++ // CraftBukkit end + return p_82487_2_; + } + ++ // Cauldron start - vanilla compatibility + public static void doDispense(World p_82486_0_, ItemStack p_82486_1_, int p_82486_2_, EnumFacing p_82486_3_, IPosition p_82486_4_) + { + double d0 = p_82486_4_.getX(); +@@ -42,7 +54,67 @@ + entityitem.motionZ += p_82486_0_.rand.nextGaussian() * 0.007499999832361937D * (double)p_82486_2_; + p_82486_0_.spawnEntityInWorld(entityitem); + } ++ // Cauldron end + ++ // CraftBukkit start - void -> boolean return, IPosition -> ISourceBlock last argument ++ public static boolean doDispense(World world, ItemStack itemstack, int i, EnumFacing enumfacing, IBlockSource iblocksource) ++ { ++ IPosition iposition = BlockDispenser.func_149939_a(iblocksource); ++ // CraftBukkit end ++ double d0 = iposition.getX(); ++ double d1 = iposition.getY(); ++ double d2 = iposition.getZ(); ++ EntityItem entityitem = new EntityItem(world, d0, d1 - 0.3D, d2, itemstack); ++ double d3 = world.rand.nextDouble() * 0.1D + 0.2D; ++ entityitem.motionX = (double) enumfacing.getFrontOffsetX() * d3; ++ entityitem.motionY = 0.20000000298023224D; ++ entityitem.motionZ = (double) enumfacing.getFrontOffsetZ() * d3; ++ entityitem.motionX += world.rand.nextGaussian() * 0.007499999832361937D * (double) i; ++ entityitem.motionY += world.rand.nextGaussian() * 0.007499999832361937D * (double) i; ++ entityitem.motionZ += world.rand.nextGaussian() * 0.007499999832361937D * (double) i; ++ // CraftBukkit start ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(iblocksource.getXInt(), iblocksource.getYInt(), iblocksource.getZInt()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack); ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(entityitem.motionX, entityitem.motionY, entityitem.motionZ)); ++ ++ if (!BlockDispenser.eventFired) ++ { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) ++ { ++ return false; ++ } ++ ++ entityitem.setEntityItemStack(CraftItemStack.asNMSCopy(event.getItem())); ++ entityitem.motionX = event.getVelocity().getX(); ++ entityitem.motionY = event.getVelocity().getY(); ++ entityitem.motionZ = event.getVelocity().getZ(); ++ ++ if (!event.getItem().equals(craftItem)) ++ { ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); ++ ++ if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem.getClass() != BehaviorDefaultDispenseItem.class) ++ { ++ ibehaviordispenseitem.dispense(iblocksource, eventStack); ++ } ++ else ++ { ++ world.spawnEntityInWorld(entityitem); ++ } ++ ++ return false; ++ } ++ ++ world.spawnEntityInWorld(entityitem); ++ return true; ++ // CraftBukkit end ++ } ++ + protected void playDispenseSound(IBlockSource p_82485_1_) + { + p_82485_1_.getWorld().playAuxSFX(1000, p_82485_1_.getXInt(), p_82485_1_.getYInt(), p_82485_1_.getZInt(), 0); diff --git a/patches/net/minecraft/dispenser/BehaviorProjectileDispense.java.patch b/patches/net/minecraft/dispenser/BehaviorProjectileDispense.java.patch new file mode 100644 index 0000000..8c44a01 --- /dev/null +++ b/patches/net/minecraft/dispenser/BehaviorProjectileDispense.java.patch @@ -0,0 +1,59 @@ +--- ../src-base/minecraft/net/minecraft/dispenser/BehaviorProjectileDispense.java ++++ ../src-work/minecraft/net/minecraft/dispenser/BehaviorProjectileDispense.java +@@ -7,6 +7,12 @@ + import net.minecraft.util.EnumFacing; + import net.minecraft.world.World; + ++// CraftBukkit start ++import net.minecraft.tileentity.TileEntityDispenser; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.block.BlockDispenseEvent; ++// CraftBukkit end ++ + public abstract class BehaviorProjectileDispense extends BehaviorDefaultDispenseItem + { + private static final String __OBFID = "CL_00001394"; +@@ -17,9 +23,42 @@ + IPosition iposition = BlockDispenser.func_149939_a(p_82487_1_); + EnumFacing enumfacing = BlockDispenser.func_149937_b(p_82487_1_.getBlockMetadata()); + IProjectile iprojectile = this.getProjectileEntity(world, iposition); ++ // CraftBukkit start ++ ItemStack itemstack1 = p_82487_2_.splitStack(1); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(p_82487_1_.getXInt(), p_82487_1_.getYInt(), p_82487_1_.getZInt()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector((double) enumfacing.getFrontOffsetX(), (double)((float) enumfacing.getFrontOffsetY() + 0.1F), (double) enumfacing.getFrontOffsetZ())); ++ ++ if (!BlockDispenser.eventFired) ++ { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) ++ { ++ p_82487_2_.stackSize++; ++ return p_82487_2_; ++ } ++ ++ if (!event.getItem().equals(craftItem)) ++ { ++ p_82487_2_.stackSize++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); ++ ++ if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem != this) ++ { ++ ibehaviordispenseitem.dispense(p_82487_1_, eventStack); ++ return p_82487_2_; ++ } ++ } ++ + iprojectile.setThrowableHeading((double)enumfacing.getFrontOffsetX(), (double)((float)enumfacing.getFrontOffsetY() + 0.1F), (double)enumfacing.getFrontOffsetZ(), this.func_82500_b(), this.func_82498_a()); ++ ((Entity) iprojectile).projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource((TileEntityDispenser) p_82487_1_.getBlockTileEntity()); ++ // CraftBukkit end + world.spawnEntityInWorld((Entity)iprojectile); +- p_82487_2_.splitStack(1); ++ // p_82487_2_.splitStack(1); // CraftBukkit - Handled during event processing + return p_82487_2_; + } + diff --git a/patches/net/minecraft/enchantment/Enchantment.java.patch b/patches/net/minecraft/enchantment/Enchantment.java.patch new file mode 100644 index 0000000..0bb4011 --- /dev/null +++ b/patches/net/minecraft/enchantment/Enchantment.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/enchantment/Enchantment.java ++++ ../src-work/minecraft/net/minecraft/enchantment/Enchantment.java +@@ -56,6 +56,8 @@ + { + enchantmentsList[p_i1926_1_] = this; + } ++ ++ org.bukkit.enchantments.Enchantment.registerEnchantment(new org.bukkit.craftbukkit.enchantments.CraftEnchantment(this)); // CraftBukkit + } + + public int getWeight() diff --git a/patches/net/minecraft/entity/Entity.java.patch b/patches/net/minecraft/entity/Entity.java.patch new file mode 100644 index 0000000..2eb1107 --- /dev/null +++ b/patches/net/minecraft/entity/Entity.java.patch @@ -0,0 +1,775 @@ +--- ../src-base/minecraft/net/minecraft/entity/Entity.java ++++ ../src-work/minecraft/net/minecraft/entity/Entity.java +@@ -45,13 +45,51 @@ + import net.minecraft.world.Explosion; + import net.minecraft.world.World; + import net.minecraft.world.WorldServer; ++import net.minecraftforge.cauldron.CauldronHooks; + import net.minecraftforge.common.IExtendedEntityProperties; + import net.minecraftforge.common.MinecraftForge; + import net.minecraftforge.event.entity.EntityEvent; + import net.minecraftforge.fluids.IFluidBlock; + ++// CraftBukkit start ++import net.minecraft.entity.passive.EntityTameable; ++import net.minecraft.entity.player.EntityPlayerMP; ++import org.bukkit.Bukkit; ++import org.bukkit.Location; ++import org.bukkit.Server; ++import org.bukkit.TravelAgent; ++import org.bukkit.block.BlockFace; ++import org.bukkit.entity.Hanging; ++import org.bukkit.entity.LivingEntity; ++import org.bukkit.entity.Painting; ++import org.bukkit.entity.Vehicle; ++import org.spigotmc.CustomTimingsHandler; // Spigot ++import org.bukkit.event.entity.EntityCombustByEntityEvent; ++import org.bukkit.event.painting.PaintingBreakByEntityEvent; ++import org.bukkit.event.vehicle.VehicleBlockCollisionEvent; ++import org.bukkit.event.vehicle.VehicleEnterEvent; ++import org.bukkit.event.vehicle.VehicleExitEvent; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.craftbukkit.entity.CraftEntity; ++import org.bukkit.craftbukkit.entity.CraftPlayer; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityCombustEvent; ++import org.bukkit.event.entity.EntityPortalEvent; ++import org.bukkit.event.hanging.HangingBreakByEntityEvent; ++import org.bukkit.plugin.PluginManager; ++// CraftBukkit end ++import net.minecraft.world.Teleporter; // Cauldron ++ + public abstract class Entity + { ++ // CraftBukkit start ++ private static final int CURRENT_LEVEL = 2; ++ static boolean isLevelAtLeast(NBTTagCompound tag, int level) ++ { ++ return tag.hasKey("Bukkit.updateLevel") && tag.getInteger("Bukkit.updateLevel") >= level; ++ } ++ // CraftBukkit end ++ + private static int nextEntityID; + private int entityId; + public double renderDistanceWeight; +@@ -100,12 +138,12 @@ + protected Random rand; + public int ticksExisted; + public int fireResistance; +- private int fire; +- protected boolean inWater; ++ public int fire; // CraftBukkit - private -> public ++ public boolean inWater; // Spigot - protected -> public + public int hurtResistantTime; + private boolean firstUpdate; + protected boolean isImmuneToFire; +- protected DataWatcher dataWatcher; ++ public DataWatcher dataWatcher; // CraftBukkit - protected -> public + private double entityRiderPitchDelta; + private double entityRiderYawDelta; + public boolean addedToChunk; +@@ -126,8 +164,10 @@ + public int dimension; + protected int teleportDirection; + private boolean invulnerable; +- protected UUID entityUniqueID; ++ public UUID entityUniqueID; // CraftBukkit - protected -> public + public Entity.EnumEntitySize myEntitySize; ++ public boolean valid; // CraftBukkit ++ public org.bukkit.projectiles.ProjectileSource projectileSource; // CraftBukkit - For projectiles only + private static final String __OBFID = "CL_00001533"; + /** Forge: Used to store custom data for each entity. */ + private NBTTagCompound customEntityData; +@@ -135,7 +175,16 @@ + public ArrayList capturedDrops = new ArrayList(); + private UUID persistentID; + ++ // Spigot start ++ public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getEntityTimings(this); // Spigot ++ public final byte activationType = org.spigotmc.ActivationRange.initializeEntityActivationType(this); ++ public final boolean defaultActivationState; ++ public long activatedTick = 0; ++ public boolean fromMobSpawner; ++ public void inactiveTick() { } ++ // Spigot end + protected HashMap extendedProperties; ++ public String spawnReason; // Cauldron - used to handle CraftBukkit's SpawnReason with CustomSpawners + + public int getEntityId() + { +@@ -159,7 +208,7 @@ + this.rand = new Random(); + this.fireResistance = 1; + this.firstUpdate = true; +- this.entityUniqueID = UUID.randomUUID(); ++ this.entityUniqueID = new UUID(rand.nextLong(), rand.nextLong()); // Spigot + this.myEntitySize = Entity.EnumEntitySize.SIZE_2; + this.worldObj = p_i1582_1_; + this.setPosition(0.0D, 0.0D, 0.0D); +@@ -167,8 +216,15 @@ + if (p_i1582_1_ != null) + { + this.dimension = p_i1582_1_.provider.dimensionId; ++ // Spigot start ++ this.defaultActivationState = org.spigotmc.ActivationRange.initializeEntityActivationState(this, p_i1582_1_.getSpigotConfig()); // Cauldron + } ++ else ++ { ++ this.defaultActivationState = false; ++ } + ++ // Spigot end + this.dataWatcher = new DataWatcher(this); + this.dataWatcher.addObject(0, Byte.valueOf((byte)0)); + this.dataWatcher.addObject(1, Short.valueOf((short)300)); +@@ -277,6 +333,41 @@ + + protected void setRotation(float p_70101_1_, float p_70101_2_) + { ++ // CraftBukkit start - yaw was sometimes set to NaN, so we need to set it back to 0 ++ if (Float.isNaN(p_70101_1_)) ++ { ++ p_70101_1_ = 0; ++ } ++ ++ if ((p_70101_1_ == Float.POSITIVE_INFINITY) || (p_70101_1_ == Float.NEGATIVE_INFINITY)) ++ { ++ if (this instanceof EntityPlayerMP) ++ { ++ this.worldObj.getServer().getLogger().warning(((CraftPlayer) this.getBukkitEntity()).getName() + " was caught trying to crash the server with an invalid yaw"); ++ ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope"); ++ } ++ ++ p_70101_1_ = 0; ++ } ++ ++ // pitch was sometimes set to NaN, so we need to set it back to 0. ++ if (Float.isNaN(p_70101_2_)) ++ { ++ p_70101_2_ = 0; ++ } ++ ++ if ((p_70101_2_ == Float.POSITIVE_INFINITY) || (p_70101_2_ == Float.NEGATIVE_INFINITY)) ++ { ++ if (this instanceof EntityPlayerMP) ++ { ++ this.worldObj.getServer().getLogger().warning(((CraftPlayer) this.getBukkitEntity()).getName() + " was caught trying to crash the server with an invalid pitch"); ++ ((CraftPlayer) this.getBukkitEntity()).kickPlayer("Nope"); ++ } ++ ++ p_70101_2_ = 0; ++ } ++ ++ // CraftBukkit end + this.rotationYaw = p_70101_1_ % 360.0F; + this.rotationPitch = p_70101_2_ % 360.0F; + } +@@ -343,7 +434,7 @@ + + if (this.inPortal) + { +- if (minecraftserver.getAllowNether()) ++ if (true || minecraftserver.getAllowNether()) // CraftBukkit + { + if (this.ridingEntity == null && this.portalCounter++ >= i) + { +@@ -457,7 +548,35 @@ + { + if (!this.isImmuneToFire) + { +- this.attackEntityFrom(DamageSource.lava, 4.0F); ++ // CraftBukkit start - Fallen in lava TODO: this event spams! ++ this.attackEntityFrom(DamageSource.lava, 4); ++ ++ if (this instanceof EntityLivingBase) ++ { ++ if (this.fire <= 0) ++ { ++ // not on fire yet ++ // TODO: shouldn't be sending null for the block. ++ org.bukkit.block.Block damager = null; // ((WorldServer) this.l).getWorld().getBlockAt(i, j, k); ++ org.bukkit.entity.Entity damagee = this.getBukkitEntity(); ++ EntityCombustEvent combustEvent = new org.bukkit.event.entity.EntityCombustByBlockEvent(damager, damagee, 15); ++ this.worldObj.getServer().getPluginManager().callEvent(combustEvent); ++ ++ if (!combustEvent.isCancelled()) ++ { ++ this.setFire(combustEvent.getDuration()); ++ } ++ } ++ else ++ { ++ // This will be called every single tick the entity is in lava, so don't throw an event ++ this.setFire(15); ++ } ++ ++ return; ++ } ++ ++ // CraftBukkit end - we also don't throw an event unless the object in lava is living, to save on some event calls + this.setFire(15); + } + } +@@ -492,6 +611,30 @@ + + public void moveEntity(double p_70091_1_, double p_70091_3_, double p_70091_5_) + { ++ // CraftBukkit start - Don't do anything if we aren't moving ++ // We need to do this regardless of whether or not we are moving thanks to portals ++ try ++ { ++ this.func_145775_I(); ++ } ++ catch (Throwable throwable) ++ { ++ CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Checking entity block collision"); ++ CrashReportCategory crashreportcategory = crashreport.makeCategory("Entity being checked for collision"); ++ this.addEntityCrashInfo(crashreportcategory); ++ throw new ReportedException(crashreport); ++ } ++ ++ // Check if we're moving ++ if (p_70091_1_ == 0 && p_70091_3_ == 0 && p_70091_5_ == 0 && this.ridingEntity == null && this.riddenByEntity == null) ++ { ++ return; ++ } ++ ++ // CraftBukkit end ++ if (!CauldronHooks.checkEntitySpeed(this, p_70091_1_, p_70091_3_, p_70091_5_)) return; // Check for entities violating the speed limit ++ org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.startTiming(); // Spigot ++ + if (this.noClip) + { + this.boundingBox.offset(p_70091_1_, p_70091_3_, p_70091_5_); +@@ -756,6 +899,35 @@ + d10 = this.posY - d4; + d11 = this.posZ - d5; + ++ // CraftBukkit start ++ if ((this.isCollidedHorizontally) && (this.getBukkitEntity() instanceof Vehicle)) ++ { ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ org.bukkit.block.Block block = this.worldObj.getWorld().getBlockAt(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY - (double) this.yOffset), MathHelper.floor_double(this.posZ)); ++ ++ if (d6 > p_70091_1_) ++ { ++ block = block.getRelative(BlockFace.EAST); ++ } ++ else if (d6 < p_70091_1_) ++ { ++ block = block.getRelative(BlockFace.WEST); ++ } ++ else if (d8 > p_70091_5_) ++ { ++ block = block.getRelative(BlockFace.SOUTH); ++ } ++ else if (d8 < p_70091_5_) ++ { ++ block = block.getRelative(BlockFace.NORTH); ++ } ++ ++ VehicleBlockCollisionEvent event = new VehicleBlockCollisionEvent(vehicle, block); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ } ++ ++ // CraftBukkit end ++ + if (this.canTriggerWalking() && !flag && this.ridingEntity == null) + { + int j1 = MathHelper.floor_double(this.posX); +@@ -798,6 +970,8 @@ + } + } + ++ // CraftBukkit start - Move to the top of the method ++ /* + try + { + this.func_145775_I(); +@@ -809,7 +983,8 @@ + this.addEntityCrashInfo(crashreportcategory); + throw new ReportedException(crashreport); + } +- ++ */ ++ // CraftBukkit end + boolean flag2 = this.isWet(); + + if (this.worldObj.func_147470_e(this.boundingBox.contract(0.001D, 0.001D, 0.001D))) +@@ -820,8 +995,20 @@ + { + ++this.fire; + +- if (this.fire == 0) ++ // CraftBukkit start - Not on fire yet ++ if (this.fire <= 0) // Only throw events on the first combust, otherwise it spams + { ++ EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity(), 8); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ this.setFire(event.getDuration()); ++ } ++ } ++ else ++ { ++ // CraftBukkit end + this.setFire(8); + } + } +@@ -839,6 +1026,8 @@ + + this.worldObj.theProfiler.endSection(); + } ++ ++ org.bukkit.craftbukkit.SpigotTimings.entityMoveTimer.stopTiming(); // Spigot + } + + protected String getSwimSound() +@@ -867,7 +1056,11 @@ + + try + { ++ // Cauldron start - damage hook for custom blocks ++ CraftEventFactory.blockDamage = this.worldObj.getWorld().getBlockAt(k1, l1, i2); + block.onEntityCollidedWithBlock(this.worldObj, k1, l1, i2, this); ++ CraftEventFactory.blockDamage = null; ++ // Cauldron end + } + catch (Throwable throwable) + { +@@ -928,6 +1121,7 @@ + return null; + } + ++ // Cauldron start - vanilla compatibility + protected void dealFireDamage(int p_70081_1_) + { + if (!this.isImmuneToFire) +@@ -935,7 +1129,16 @@ + this.attackEntityFrom(DamageSource.inFire, (float)p_70081_1_); + } + } ++ // Cauldron end + ++ protected void dealFireDamage(float par1) // CraftBukkit signature change ++ { ++ if (!this.isImmuneToFire) ++ { ++ this.attackEntityFrom(DamageSource.inFire, (float)par1); ++ } ++ } ++ + public final boolean isImmuneToFire() + { + return this.isImmuneToFire; +@@ -1184,6 +1387,8 @@ + + public void onCollideWithPlayer(EntityPlayer p_70100_1_) {} + ++ int numCollisions = 0; // Spigot ++ + public void applyEntityCollision(Entity p_70108_1_) + { + if (p_70108_1_.riddenByEntity != this && p_70108_1_.ridingEntity != this) +@@ -1310,6 +1515,20 @@ + { + p_70109_1_.setTag("Pos", this.newDoubleNBTList(new double[] {this.posX, this.posY + (double)this.ySize, this.posZ})); + p_70109_1_.setTag("Motion", this.newDoubleNBTList(new double[] {this.motionX, this.motionY, this.motionZ})); ++ ++ // CraftBukkit start - Checking for NaN pitch/yaw and resetting to zero ++ // TODO: make sure this is the best way to address this. ++ if (Float.isNaN(this.rotationYaw)) ++ { ++ this.rotationYaw = 0; ++ } ++ ++ if (Float.isNaN(this.rotationPitch)) ++ { ++ this.rotationPitch = 0; ++ } ++ ++ // CraftBukkit end + p_70109_1_.setTag("Rotation", this.newFloatNBTList(new float[] {this.rotationYaw, this.rotationPitch})); + p_70109_1_.setFloat("FallDistance", this.fallDistance); + p_70109_1_.setShort("Fire", (short)this.fire); +@@ -1320,6 +1539,12 @@ + p_70109_1_.setInteger("PortalCooldown", this.timeUntilPortal); + p_70109_1_.setLong("UUIDMost", this.getUniqueID().getMostSignificantBits()); + p_70109_1_.setLong("UUIDLeast", this.getUniqueID().getLeastSignificantBits()); ++ // CraftBukkit start ++ p_70109_1_.setLong("WorldUUIDLeast", this.worldObj.getSaveHandler().getUUID().getLeastSignificantBits()); ++ p_70109_1_.setLong("WorldUUIDMost", this.worldObj.getSaveHandler().getUUID().getMostSignificantBits()); ++ p_70109_1_.setInteger("Bukkit.updateLevel", CURRENT_LEVEL); ++ p_70109_1_.setInteger("Spigot.ticksLived", this.ticksExisted); ++ // CraftBukkit end + if (customEntityData != null) + { + p_70109_1_.setTag("ForgeData", customEntityData); +@@ -1370,7 +1595,7 @@ + this.motionX = nbttaglist1.func_150309_d(0); + this.motionY = nbttaglist1.func_150309_d(1); + this.motionZ = nbttaglist1.func_150309_d(2); +- ++ /* CraftBukkit start - Moved section down + if (Math.abs(this.motionX) > 10.0D) + { + this.motionX = 0.0D; +@@ -1385,7 +1610,7 @@ + { + this.motionZ = 0.0D; + } +- ++ // CraftBukkit end */ + this.prevPosX = this.lastTickPosX = this.posX = nbttaglist.func_150309_d(0); + this.prevPosY = this.lastTickPosY = this.posY = nbttaglist.func_150309_d(1); + this.prevPosZ = this.lastTickPosZ = this.posZ = nbttaglist.func_150309_d(2); +@@ -1436,6 +1661,76 @@ + { + this.setPosition(this.posX, this.posY, this.posZ); + } ++ ++ // CraftBukkit start ++ if (this instanceof EntityLivingBase) ++ { ++ EntityLivingBase entity = (EntityLivingBase) this; ++ this.ticksExisted = p_70020_1_.getInteger("Spigot.ticksLived"); ++ ++ // Reset the persistence for tamed animals ++ if (entity instanceof EntityTameable && !isLevelAtLeast(p_70020_1_, 2) && !p_70020_1_.getBoolean("PersistenceRequired")) ++ { ++ EntityLiving entityliving = (EntityLiving) entity; ++ entityliving.persistenceRequired = !entityliving.canDespawn(); ++ } ++ } ++ ++ // CraftBukkit end ++ ++ // CraftBukkit start - Exempt Vehicles from notch's sanity check ++ if (!(this.getBukkitEntity() instanceof Vehicle)) ++ { ++ if (Math.abs(this.motionX) > 10.0D) ++ { ++ this.motionX = 0.0D; ++ } ++ ++ if (Math.abs(this.motionY) > 10.0D) ++ { ++ this.motionY = 0.0D; ++ } ++ ++ if (Math.abs(this.motionZ) > 10.0D) ++ { ++ this.motionZ = 0.0D; ++ } ++ } ++ ++ // CraftBukkit end ++ ++ // CraftBukkit start - Reset world ++ if (this instanceof EntityPlayerMP) ++ { ++ Server server = Bukkit.getServer(); ++ org.bukkit.World bworld = null; ++ // TODO: Remove World related checks, replaced with WorldUID. ++ String worldName = p_70020_1_.getString("World"); ++ ++ if (p_70020_1_.hasKey("WorldUUIDMost") && p_70020_1_.hasKey("WorldUUIDLeast")) ++ { ++ UUID uid = new UUID(p_70020_1_.getLong("WorldUUIDMost"), p_70020_1_.getLong("WorldUUIDLeast")); ++ bworld = server.getWorld(uid); ++ } ++ else ++ { ++ bworld = server.getWorld(worldName); ++ } ++ ++ if (bworld == null) ++ { ++ EntityPlayerMP entityPlayer = (EntityPlayerMP) this; ++ // Cauldron start - use CraftBukkit's fallback world code if no valid world is found. ++ entityPlayer.setWorld(MinecraftServer.getServer().worldServerForDimension(entityPlayer.dimension)); ++ } ++ else ++ { ++ this.setWorld(((CraftWorld) bworld).getHandle()); ++ // Cauldron end ++ } ++ } ++ ++ // CraftBukkit end + } + catch (Throwable throwable) + { +@@ -1653,6 +1948,31 @@ + + public void mountEntity(Entity p_70078_1_) + { ++ // CraftBukkit start ++ this.setPassengerOf(p_70078_1_); ++ } ++ ++ protected CraftEntity bukkitEntity; ++ ++ public CraftEntity getBukkitEntity() ++ { ++ if (this.bukkitEntity == null) ++ { ++ this.bukkitEntity = CraftEntity.getEntity(this.worldObj.getServer(), this); ++ } ++ ++ return this.bukkitEntity; ++ } ++ ++ public void setPassengerOf(Entity p_70078_1_) ++ { ++ // mountEntity(null) doesn't really fly for overloaded methods, ++ // so this method is needed ++ Entity originalVehicle = this.ridingEntity; ++ Entity originalPassenger = this.ridingEntity == null ? null : this.ridingEntity.riddenByEntity; ++ PluginManager pluginManager = Bukkit.getPluginManager(); ++ this.getBukkitEntity(); // make sure bukkitEntity is initialised ++ // CraftBukkit end + this.entityRiderPitchDelta = 0.0D; + this.entityRiderYawDelta = 0.0D; + +@@ -1660,6 +1980,20 @@ + { + if (this.ridingEntity != null) + { ++ // CraftBukkit start ++ if ((this.bukkitEntity instanceof LivingEntity) && (this.ridingEntity.getBukkitEntity() instanceof Vehicle)) ++ { ++ VehicleExitEvent event = new VehicleExitEvent((Vehicle) this.ridingEntity.getBukkitEntity(), (LivingEntity) this.bukkitEntity); ++ pluginManager.callEvent(event); ++ ++ if (event.isCancelled() || this.ridingEntity != originalVehicle) ++ { ++ return; ++ } ++ } ++ ++ // CraftBukkit end ++ pluginManager.callEvent(new org.spigotmc.event.entity.EntityDismountEvent(this.getBukkitEntity(), this.ridingEntity.getBukkitEntity())); // Spigot + this.setLocationAndAngles(this.ridingEntity.posX, this.ridingEntity.boundingBox.minY + (double)this.ridingEntity.height, this.ridingEntity.posZ, this.rotationYaw, this.rotationPitch); + this.ridingEntity.riddenByEntity = null; + } +@@ -1668,22 +2002,61 @@ + } + else + { +- if (this.ridingEntity != null) ++ // CraftBukkit start ++ if ((this.bukkitEntity instanceof LivingEntity) && (p_70078_1_.getBukkitEntity() instanceof Vehicle) && p_70078_1_.worldObj.chunkExists((int) p_70078_1_.posX >> 4, (int) p_70078_1_.posZ >> 4)) + { +- this.ridingEntity.riddenByEntity = null; +- } ++ // It's possible to move from one vehicle to another. We need to check if they're already in a vehicle, and fire an exit event if they are. ++ VehicleExitEvent exitEvent = null; + +- if (p_70078_1_ != null) +- { +- for (Entity entity1 = p_70078_1_.ridingEntity; entity1 != null; entity1 = entity1.ridingEntity) ++ if (this.ridingEntity != null && this.ridingEntity.getBukkitEntity() instanceof Vehicle) + { +- if (entity1 == this) ++ exitEvent = new VehicleExitEvent((Vehicle) this.ridingEntity.getBukkitEntity(), (LivingEntity) this.bukkitEntity); ++ pluginManager.callEvent(exitEvent); ++ ++ if (exitEvent.isCancelled() || this.ridingEntity != originalVehicle || (this.ridingEntity != null && this.ridingEntity.riddenByEntity != originalPassenger)) + { + return; + } + } ++ ++ VehicleEnterEvent event = new VehicleEnterEvent((Vehicle) p_70078_1_.getBukkitEntity(), this.bukkitEntity); ++ pluginManager.callEvent(event); ++ ++ // If a plugin messes with the vehicle or the vehicle's passenger ++ if (event.isCancelled() || this.ridingEntity != originalVehicle || (this.ridingEntity != null && this.ridingEntity.riddenByEntity != originalPassenger)) ++ { ++ // If we only cancelled the enterevent then we need to put the player in a decent position. ++ if (exitEvent != null && this.ridingEntity == originalVehicle && this.ridingEntity != null && this.ridingEntity.riddenByEntity == originalPassenger) ++ { ++ this.setLocationAndAngles(this.ridingEntity.posX, this.ridingEntity.boundingBox.minY + (double) this.ridingEntity.height, this.ridingEntity.posZ, this.rotationYaw, this.rotationPitch); ++ this.ridingEntity.riddenByEntity = null; ++ this.ridingEntity = null; ++ } ++ ++ return; ++ } + } + ++ // CraftBukkit end ++ // Spigot Start ++ if (p_70078_1_.worldObj.chunkExists((int) p_70078_1_.posX >> 4, (int) p_70078_1_.posZ >> 4)) ++ { ++ org.spigotmc.event.entity.EntityMountEvent event = new org.spigotmc.event.entity.EntityMountEvent(this.getBukkitEntity(), p_70078_1_.getBukkitEntity()); ++ pluginManager.callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ } ++ ++ // Spigot End ++ ++ if (this.ridingEntity != null) ++ { ++ this.ridingEntity.riddenByEntity = null; ++ } ++ + this.ridingEntity = p_70078_1_; + p_70078_1_.riddenByEntity = this; + } +@@ -1860,12 +2233,59 @@ + + public void onStruckByLightning(EntityLightningBolt p_70077_1_) + { +- this.dealFireDamage(5); ++ // CraftBukkit start ++ final org.bukkit.entity.Entity thisBukkitEntity = this.getBukkitEntity(); ++ if (thisBukkitEntity == null) return; // Cauldron - skip mod entities with no wrapper (TODO: create a wrapper) ++ if (p_70077_1_ == null) return; // Cauldron - skip null entities, see #392 ++ final org.bukkit.entity.Entity stormBukkitEntity = p_70077_1_.getBukkitEntity(); ++ if (stormBukkitEntity == null) return; // Cauldron - skip mod entities with no wrapper (TODO: create a wrapper) ++ final PluginManager pluginManager = Bukkit.getPluginManager(); ++ ++ if (thisBukkitEntity instanceof Hanging) ++ { ++ HangingBreakByEntityEvent hangingEvent = new HangingBreakByEntityEvent((Hanging) thisBukkitEntity, stormBukkitEntity); ++ PaintingBreakByEntityEvent paintingEvent = null; ++ ++ if (thisBukkitEntity instanceof Painting) { ++ paintingEvent = new PaintingBreakByEntityEvent((Painting) thisBukkitEntity, stormBukkitEntity); ++ } ++ ++ pluginManager.callEvent(hangingEvent); ++ ++ if (paintingEvent != null) { ++ paintingEvent.setCancelled(hangingEvent.isCancelled()); ++ pluginManager.callEvent(paintingEvent); ++ } ++ ++ if (hangingEvent.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) { ++ return; ++ } ++ } ++ ++ if (this.isImmuneToFire) { ++ return; ++ } ++ CraftEventFactory.entityDamage = p_70077_1_; ++ if (!this.attackEntityFrom(DamageSource.inFire, 5.0F)) { ++ CraftEventFactory.entityDamage = null; ++ return; ++ } ++ ++ // CraftBukkit end + ++this.fire; + + if (this.fire == 0) + { +- this.setFire(8); ++ // CraftBukkit start - Call a combust event when lightning strikes ++ EntityCombustByEntityEvent entityCombustEvent = new EntityCombustByEntityEvent(stormBukkitEntity, thisBukkitEntity, 8); ++ pluginManager.callEvent(entityCombustEvent); ++ ++ if (!entityCombustEvent.isCancelled()) ++ { ++ this.setFire(entityCombustEvent.getDuration()); ++ } ++ ++ // CraftBukkit end + } + } + +@@ -2038,36 +2458,62 @@ + { + this.worldObj.theProfiler.startSection("changeDimension"); + MinecraftServer minecraftserver = MinecraftServer.getServer(); +- int j = this.dimension; +- WorldServer worldserver = minecraftserver.worldServerForDimension(j); +- WorldServer worldserver1 = minecraftserver.worldServerForDimension(p_71027_1_); +- this.dimension = p_71027_1_; ++ // CraftBukkit start - Move logic into new function "teleportToLocation" ++ // int j = this.dimension; ++ // Cauldron start - Allow Forge hotloading on teleport ++ WorldServer exitWorld = minecraftserver.worldServerForDimension(p_71027_1_); + +- if (j == 1 && p_71027_1_ == 1) ++ Location enter = this.getBukkitEntity().getLocation(); ++ Location exit = exitWorld != null ? minecraftserver.getConfigurationManager().calculateTarget(enter, minecraftserver.worldServerForDimension(p_71027_1_)) : null; ++ boolean useTravelAgent = exitWorld != null && !(this.dimension == 1 && exitWorld.dimension == 1); // don't use agent for custom worlds or return from THE_END ++ // Cauldron start - check if teleporter is instance of TravelAgent before attempting to cast to it ++ Teleporter teleporter = exit != null ? ((CraftWorld) exit.getWorld()).getHandle().getDefaultTeleporter() : null; ++ TravelAgent agent = (teleporter != null && teleporter instanceof TravelAgent) ? (TravelAgent)teleporter : org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT; // return arbitrary TA to compensate for implementation dependent plugins ++ // Cauldron end ++ EntityPortalEvent event = new EntityPortalEvent(this.getBukkitEntity(), enter, exit, agent); ++ event.useTravelAgent(useTravelAgent); ++ event.getEntity().getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled() || event.getTo() == null || !this.isEntityAlive()) + { +- worldserver1 = minecraftserver.worldServerForDimension(0); +- this.dimension = 0; ++ return; + } + ++ exit = event.useTravelAgent() ? event.getPortalTravelAgent().findOrCreate(event.getTo()) : event.getTo(); ++ this.teleportTo(exit, true); ++ } ++ } ++ ++ public void teleportTo(Location exit, boolean portal) ++ { ++ if (true) ++ { ++ WorldServer worldserver = ((CraftWorld) this.getBukkitEntity().getLocation().getWorld()).getHandle(); ++ WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle(); ++ int i = worldserver1.dimension; ++ // CraftBukkit end ++ this.dimension = i; + this.worldObj.removeEntity(this); + this.isDead = false; + this.worldObj.theProfiler.startSection("reposition"); +- minecraftserver.getConfigurationManager().transferEntityToWorld(this, j, worldserver, worldserver1); ++ // CraftBukkit start - Ensure chunks are loaded in case TravelAgent is not used which would initially cause chunks to load during find/create ++ // minecraftserver.getPlayerList().a(this, j, worldserver, worldserver1); ++ boolean before = worldserver1.theChunkProviderServer.loadChunkOnProvideRequest; // Cauldron start - load chunks on provide request ++ worldserver1.theChunkProviderServer.loadChunkOnProvideRequest = true; ++ worldserver1.func_73046_m().getConfigurationManager().repositionEntity(this, exit, portal); ++ worldserver1.theChunkProviderServer.loadChunkOnProvideRequest = before; // Cauldron end ++ // CraftBukkit end + this.worldObj.theProfiler.endStartSection("reloading"); + Entity entity = EntityList.createEntityByName(EntityList.getEntityString(this), worldserver1); + + if (entity != null) + { + entity.copyDataFrom(this, true); +- +- if (j == 1 && p_71027_1_ == 1) +- { +- ChunkCoordinates chunkcoordinates = worldserver1.getSpawnPoint(); +- chunkcoordinates.posY = this.worldObj.getTopSolidOrLiquidBlock(chunkcoordinates.posX, chunkcoordinates.posZ); +- entity.setLocationAndAngles((double)chunkcoordinates.posX, (double)chunkcoordinates.posY, (double)chunkcoordinates.posZ, entity.rotationYaw, entity.rotationPitch); +- } +- + worldserver1.spawnEntityInWorld(entity); ++ // CraftBukkit start - Forward the CraftEntity to the new entity ++ this.getBukkitEntity().setHandle(entity); ++ entity.bukkitEntity = this.getBukkitEntity(); ++ // CraftBukkit end + } + + this.isDead = true; +@@ -2077,7 +2523,6 @@ + this.worldObj.theProfiler.endSection(); + } + } +- + public float func_145772_a(Explosion p_145772_1_, World p_145772_2_, int p_145772_3_, int p_145772_4_, int p_145772_5_, Block p_145772_6_) + { + return p_145772_6_.getExplosionResistance(this, p_145772_2_, p_145772_3_, p_145772_4_, p_145772_5_, posX, posY + getEyeHeight(), posZ); diff --git a/patches/net/minecraft/entity/EntityAgeable.java.patch b/patches/net/minecraft/entity/EntityAgeable.java.patch new file mode 100644 index 0000000..a620cac --- /dev/null +++ b/patches/net/minecraft/entity/EntityAgeable.java.patch @@ -0,0 +1,80 @@ +--- ../src-base/minecraft/net/minecraft/entity/EntityAgeable.java ++++ ../src-work/minecraft/net/minecraft/entity/EntityAgeable.java +@@ -10,6 +10,36 @@ + { + private float field_98056_d = -1.0F; + private float field_98057_e; ++ public boolean ageLocked = false; // CraftBukkit ++ ++ // Spigot start ++ @Override ++ public void inactiveTick() ++ { ++ super.inactiveTick(); ++ ++ if (this.worldObj.isRemote || this.ageLocked) ++ { ++ // CraftBukkit ++ this.setScaleForAge(this.isChild()); ++ } ++ else ++ { ++ int i = this.getGrowingAge(); ++ ++ if (i < 0) ++ { ++ ++i; ++ this.setGrowingAge(i); ++ } ++ else if (i > 0) ++ { ++ --i; ++ this.setGrowingAge(i); ++ } ++ } ++ } ++ // Spigot end + private static final String __OBFID = "CL_00001530"; + + public EntityAgeable(World p_i1578_1_) +@@ -37,7 +67,7 @@ + { + entityageable.setGrowingAge(-24000); + entityageable.setLocationAndAngles(this.posX, this.posY, this.posZ, 0.0F, 0.0F); +- this.worldObj.spawnEntityInWorld(entityageable); ++ this.worldObj.addEntity(entityageable, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // CraftBukkit + + if (itemstack.hasDisplayName()) + { +@@ -48,7 +78,7 @@ + { + --itemstack.stackSize; + +- if (itemstack.stackSize <= 0) ++ if (itemstack.stackSize == 0) // CraftBukkit - allow less than 0 stacks as "infinite" + { + p_70085_1_.inventory.setInventorySlotContents(p_70085_1_.inventory.currentItem, (ItemStack)null); + } +@@ -99,19 +129,21 @@ + { + super.writeEntityToNBT(p_70014_1_); + p_70014_1_.setInteger("Age", this.getGrowingAge()); ++ p_70014_1_.setBoolean("AgeLocked", this.ageLocked); // CraftBukkit + } + + public void readEntityFromNBT(NBTTagCompound p_70037_1_) + { + super.readEntityFromNBT(p_70037_1_); + this.setGrowingAge(p_70037_1_.getInteger("Age")); ++ this.ageLocked = p_70037_1_.getBoolean("AgeLocked"); // CraftBukkit + } + + public void onLivingUpdate() + { + super.onLivingUpdate(); + +- if (this.worldObj.isRemote) ++ if (this.worldObj.isRemote || this.ageLocked) // CraftBukkit + { + this.setScaleForAge(this.isChild()); + } diff --git a/patches/net/minecraft/entity/EntityCreature.java.patch b/patches/net/minecraft/entity/EntityCreature.java.patch new file mode 100644 index 0000000..d44004c --- /dev/null +++ b/patches/net/minecraft/entity/EntityCreature.java.patch @@ -0,0 +1,105 @@ +--- ../src-base/minecraft/net/minecraft/entity/EntityCreature.java ++++ ../src-work/minecraft/net/minecraft/entity/EntityCreature.java +@@ -13,12 +13,18 @@ + import net.minecraft.util.Vec3; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.entity.CraftEntity; ++import org.bukkit.event.entity.EntityTargetEvent; ++import org.bukkit.event.entity.EntityUnleashEvent; ++// CraftBukkit end ++ + public abstract class EntityCreature extends EntityLiving + { + public static final UUID field_110179_h = UUID.fromString("E199AD21-BA8A-4C53-8D13-6182D5C69D3A"); + public static final AttributeModifier field_110181_i = (new AttributeModifier(field_110179_h, "Fleeing speed bonus", 2.0D, 2)).setSaved(false); +- private PathEntity pathToEntity; +- protected Entity entityToAttack; ++ public PathEntity pathToEntity; // CraftBukkit - private -> public ++ public Entity entityToAttack; // CraftBukkit - protected -> public + protected boolean hasAttacked; + protected int fleeingTick; + private ChunkCoordinates homePosition = new ChunkCoordinates(0, 0, 0); +@@ -52,8 +58,29 @@ + + if (this.entityToAttack == null) + { +- this.entityToAttack = this.findPlayerToAttack(); ++ // CraftBukkit start ++ Entity target = this.findPlayerToAttack(); + ++ if (target != null) ++ { ++ EntityTargetEvent event = new EntityTargetEvent(this.getBukkitEntity(), target.getBukkitEntity(), EntityTargetEvent.TargetReason.CLOSEST_PLAYER); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ if (event.getTarget() == null) ++ { ++ this.entityToAttack = null; ++ } ++ else ++ { ++ this.entityToAttack = ((CraftEntity) event.getTarget()).getHandle(); ++ } ++ } ++ } ++ ++ // CraftBukkit end ++ + if (this.entityToAttack != null) + { + this.pathToEntity = this.worldObj.getPathEntityToEntity(this, this.entityToAttack, f4, true, false, false, true); +@@ -70,7 +97,23 @@ + } + else + { +- this.entityToAttack = null; ++ // CraftBukkit start ++ EntityTargetEvent event = new EntityTargetEvent(this.getBukkitEntity(), null, EntityTargetEvent.TargetReason.TARGET_DIED); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ if (event.getTarget() == null) ++ { ++ this.entityToAttack = null; ++ } ++ else ++ { ++ this.entityToAttack = ((CraftEntity) event.getTarget()).getHandle(); ++ } ++ } ++ ++ // CraftBukkit end + } + + if (this.entityToAttack instanceof EntityPlayerMP && ((EntityPlayerMP)this.entityToAttack).theItemInWorldManager.isCreative()) +@@ -122,7 +165,8 @@ + double d1 = vec3.xCoord - this.posX; + double d2 = vec3.zCoord - this.posZ; + double d3 = vec3.yCoord - (double)i; +- float f1 = (float)(Math.atan2(d2, d1) * 180.0D / Math.PI) - 90.0F; ++ // CraftBukkit - Math -> TrigMath ++ float f1 = (float)(org.bukkit.craftbukkit.TrigMath.atan2(d2, d1) * 180.0D / Math.PI) - 90.0F; + float f2 = MathHelper.wrapAngleTo180_float(f1 - this.rotationYaw); + this.moveForward = (float)this.getEntityAttribute(SharedMonsterAttributes.movementSpeed).getAttributeValue(); + +@@ -303,6 +347,7 @@ + { + if (f > 10.0F) + { ++ this.worldObj.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE)); // CraftBukkit + this.clearLeashed(true, true); + } + +@@ -335,6 +380,7 @@ + + if (f > 10.0F) + { ++ this.worldObj.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), EntityUnleashEvent.UnleashReason.DISTANCE)); // CraftBukkit + this.clearLeashed(true, true); + } + } diff --git a/patches/net/minecraft/entity/EntityHanging.java.patch b/patches/net/minecraft/entity/EntityHanging.java.patch new file mode 100644 index 0000000..7e5ae4e --- /dev/null +++ b/patches/net/minecraft/entity/EntityHanging.java.patch @@ -0,0 +1,119 @@ +--- ../src-base/minecraft/net/minecraft/entity/EntityHanging.java ++++ ../src-work/minecraft/net/minecraft/entity/EntityHanging.java +@@ -10,6 +10,14 @@ + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; + ++// CraftBukkit start ++import net.minecraft.entity.item.EntityPainting; ++import org.bukkit.entity.Hanging; ++import org.bukkit.entity.Painting; ++import org.bukkit.event.hanging.HangingBreakEvent; ++import org.bukkit.event.painting.PaintingBreakEvent; ++// CraftBukkit end ++ + public abstract class EntityHanging extends Entity + { + private int tickCounter1; +@@ -125,6 +133,38 @@ + + if (!this.isDead && !this.onValidSurface()) + { ++ // CraftBukkit start ++ Material material = this.worldObj.getBlock((int) this.posX, (int) this.posY, (int) this.posZ).getMaterial(); ++ HangingBreakEvent.RemoveCause cause; ++ ++ if (!material.equals(Material.air)) ++ { ++ // TODO: This feels insufficient to catch 100% of suffocation cases ++ cause = HangingBreakEvent.RemoveCause.OBSTRUCTION; ++ } ++ else ++ { ++ cause = HangingBreakEvent.RemoveCause.PHYSICS; ++ } ++ ++ HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), cause); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ PaintingBreakEvent paintingEvent = null; ++ ++ if (this instanceof EntityPainting) ++ { ++ // Fire old painting event until it can be removed ++ paintingEvent = new PaintingBreakEvent((Painting) this.getBukkitEntity(), PaintingBreakEvent.RemoveCause.valueOf(cause.name())); ++ paintingEvent.setCancelled(event.isCancelled()); ++ this.worldObj.getServer().getPluginManager().callEvent(paintingEvent); ++ } ++ ++ if (isDead || event.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + this.setDead(); + this.onBroken((Entity)null); + } +@@ -233,6 +273,39 @@ + { + if (!this.isDead && !this.worldObj.isRemote) + { ++ // CraftBukkit start ++ HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.DEFAULT); ++ PaintingBreakEvent paintingEvent = null; ++ ++ if (p_70097_1_.getEntity() != null) ++ { ++ event = new org.bukkit.event.hanging.HangingBreakByEntityEvent((Hanging) this.getBukkitEntity(), p_70097_1_.getEntity() == null ? null : p_70097_1_.getEntity().getBukkitEntity()); ++ ++ if (this instanceof EntityPainting) ++ { ++ // Fire old painting event until it can be removed ++ paintingEvent = new org.bukkit.event.painting.PaintingBreakByEntityEvent((Painting) this.getBukkitEntity(), p_70097_1_.getEntity() == null ? null : p_70097_1_.getEntity().getBukkitEntity()); ++ } ++ } ++ else if (p_70097_1_.isExplosion()) ++ { ++ event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.EXPLOSION); ++ } ++ ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (paintingEvent != null) ++ { ++ paintingEvent.setCancelled(event.isCancelled()); ++ this.worldObj.getServer().getPluginManager().callEvent(paintingEvent); ++ } ++ ++ if (this.isDead || event.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) ++ { ++ return true; ++ } ++ ++ // CraftBukkit end + this.setDead(); + this.setBeenAttacked(); + this.onBroken(p_70097_1_.getEntity()); +@@ -246,6 +319,22 @@ + { + if (!this.worldObj.isRemote && !this.isDead && p_70091_1_ * p_70091_1_ + p_70091_3_ * p_70091_3_ + p_70091_5_ * p_70091_5_ > 0.0D) + { ++ if (this.isDead) ++ { ++ return; // CraftBukkit ++ } ++ ++ // CraftBukkit start ++ // TODO - Does this need its own cause? Seems to only be triggered by pistons ++ HangingBreakEvent event = new HangingBreakEvent((Hanging) this.getBukkitEntity(), HangingBreakEvent.RemoveCause.PHYSICS); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (this.isDead || event.isCancelled()) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + this.setDead(); + this.onBroken((Entity)null); + } diff --git a/patches/net/minecraft/entity/EntityLeashKnot.java.patch b/patches/net/minecraft/entity/EntityLeashKnot.java.patch new file mode 100644 index 0000000..bcab608 --- /dev/null +++ b/patches/net/minecraft/entity/EntityLeashKnot.java.patch @@ -0,0 +1,74 @@ +--- ../src-base/minecraft/net/minecraft/entity/EntityLeashKnot.java ++++ ../src-work/minecraft/net/minecraft/entity/EntityLeashKnot.java +@@ -11,6 +11,12 @@ + import net.minecraft.util.AxisAlignedBB; + import net.minecraft.world.World; + ++ // CraftBukkit start ++import net.minecraft.entity.player.EntityPlayerMP; ++import net.minecraft.network.play.server.S1BPacketEntityAttach; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++// CraftBukkit end ++ + public class EntityLeashKnot extends EntityHanging + { + private static final String __OBFID = "CL_00001548"; +@@ -84,6 +90,14 @@ + + if (entityliving.getLeashed() && entityliving.getLeashedToEntity() == p_130002_1_) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callPlayerLeashEntityEvent(entityliving, this, p_130002_1_).isCancelled()) ++ { ++ ((EntityPlayerMP) p_130002_1_).playerNetServerHandler.sendPacket(new S1BPacketEntityAttach(1, entityliving, entityliving.getLeashedToEntity())); ++ continue; ++ } ++ ++ // CraftBukkit end + entityliving.setLeashedToEntity(this, true); + flag = true; + } +@@ -93,9 +107,12 @@ + + if (!this.worldObj.isRemote && !flag) + { +- this.setDead(); ++ // CraftBukkit start - Move below ++ //this.setDead(); ++ boolean die = true; + +- if (p_130002_1_.capabilities.isCreativeMode) ++ // CraftBukkit end ++ if (true || p_130002_1_.capabilities.isCreativeMode) // CraftBukkit - Process for non-creative as well + { + d0 = 7.0D; + list = this.worldObj.getEntitiesWithinAABB(EntityLiving.class, AxisAlignedBB.getBoundingBox(this.posX - d0, this.posY - d0, this.posZ - d0, this.posX + d0, this.posY + d0, this.posZ + d0)); +@@ -110,11 +127,27 @@ + + if (entityliving.getLeashed() && entityliving.getLeashedToEntity() == this) + { +- entityliving.clearLeashed(true, false); ++ // CraftBukkit start ++ if (CraftEventFactory.callPlayerUnleashEntityEvent(entityliving, p_130002_1_).isCancelled()) ++ { ++ die = false; ++ continue; ++ } ++ ++ entityliving.clearLeashed(true, !p_130002_1_.capabilities.isCreativeMode); // false -> survival mode boolean ++ // CraftBukkit end + } + } + } + } ++ ++ // CraftBukkit start ++ if (die) ++ { ++ this.setDead(); ++ } ++ ++ // CraftBukkit end + } + + return true; diff --git a/patches/net/minecraft/entity/EntityLiving.java.patch b/patches/net/minecraft/entity/EntityLiving.java.patch new file mode 100644 index 0000000..ce5ad09 --- /dev/null +++ b/patches/net/minecraft/entity/EntityLiving.java.patch @@ -0,0 +1,162 @@ +--- ../src-base/minecraft/net/minecraft/entity/EntityLiving.java ++++ ../src-work/minecraft/net/minecraft/entity/EntityLiving.java +@@ -38,6 +38,13 @@ + import cpw.mods.fml.common.eventhandler.Event.Result; + import net.minecraftforge.event.ForgeEventFactory; + ++// CraftBukkit start ++import net.minecraft.entity.player.EntityPlayerMP; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityUnleashEvent; ++import org.bukkit.event.entity.EntityUnleashEvent.UnleashReason; ++// CraftBukkit end ++ + public abstract class EntityLiving extends EntityLivingBase + { + public int livingSoundTime; +@@ -52,9 +59,9 @@ + private EntityLivingBase attackTarget; + private EntitySenses senses; + private ItemStack[] equipment = new ItemStack[5]; +- protected float[] equipmentDropChances = new float[5]; +- private boolean canPickUpLoot; +- private boolean persistenceRequired; ++ public float[] equipmentDropChances = new float[5]; // CraftBukkit - protected -> public ++ public boolean canPickUpLoot; // CraftBukkit - private -> public ++ public boolean persistenceRequired; // CraftBukkit - private -> public + protected float defaultPitch; + private Entity currentTarget; + protected int numTicksToChaseTarget; +@@ -311,9 +318,23 @@ + public void readEntityFromNBT(NBTTagCompound p_70037_1_) + { + super.readEntityFromNBT(p_70037_1_); +- this.setCanPickUpLoot(p_70037_1_.getBoolean("CanPickUpLoot")); +- this.persistenceRequired = p_70037_1_.getBoolean("PersistenceRequired"); ++ // CraftBukkit start - If looting or persistence is false only use it if it was set after we started using it ++ boolean data = p_70037_1_.getBoolean("CanPickUpLoot"); + ++ if (isLevelAtLeast(p_70037_1_, 1) || data) ++ { ++ this.canPickUpLoot = data; ++ } ++ ++ data = p_70037_1_.getBoolean("PersistenceRequired"); ++ ++ if (isLevelAtLeast(p_70037_1_, 1) || data) ++ { ++ this.persistenceRequired = data; ++ } ++ ++ // CraftBukkit end ++ + if (p_70037_1_.hasKey("CustomName", 8) && p_70037_1_.getString("CustomName").length() > 0) + { + this.setCustomNameTag(p_70037_1_.getString("CustomName")); +@@ -521,15 +542,36 @@ + this.entityAge = 0; + } + } ++ // Cauldron start - Force despawn of entity if a player isn't near ++ else if (this.worldObj.cauldronConfig.entityDespawnImmediate && this.canDespawn()) ++ { ++ this.despawn("No Player : Immediate"); ++ } ++ // Cauldron end + } + } + ++ // Cauldron start ++ private void despawn(String reason) { ++ this.setDead(); ++ net.minecraftforge.cauldron.CauldronHooks.logEntityDespawn(this, reason); ++ } ++ // Cauldron end ++ + protected void updateAITasks() + { + ++this.entityAge; + this.worldObj.theProfiler.startSection("checkDespawn"); + this.despawnEntity(); + this.worldObj.theProfiler.endSection(); ++ ++ // Spigot Start ++ if (this.fromMobSpawner) ++ { ++ return; ++ } ++ ++ // Spigot End + this.worldObj.theProfiler.startSection("sensing"); + this.senses.clearSensingCache(); + this.worldObj.theProfiler.endSection(); +@@ -1005,6 +1047,14 @@ + { + if (this.getLeashed() && this.getLeashedToEntity() == p_130002_1_) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callPlayerUnleashEntityEvent(this, p_130002_1_).isCancelled()) ++ { ++ ((EntityPlayerMP) p_130002_1_).playerNetServerHandler.sendPacket(new S1BPacketEntityAttach(1, this, this.getLeashedToEntity())); ++ return false; ++ } ++ ++ // CraftBukkit end + this.clearLeashed(true, !p_130002_1_.capabilities.isCreativeMode); + return true; + } +@@ -1016,6 +1066,14 @@ + { + if (!(this instanceof EntityTameable) || !((EntityTameable)this).isTamed()) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callPlayerLeashEntityEvent(this, p_130002_1_, p_130002_1_).isCancelled()) ++ { ++ ((EntityPlayerMP) p_130002_1_).playerNetServerHandler.sendPacket(new S1BPacketEntityAttach(1, this, this.getLeashedToEntity())); ++ return false; ++ } ++ ++ // CraftBukkit end + this.setLeashedToEntity(p_130002_1_, true); + --itemstack.stackSize; + return true; +@@ -1023,6 +1081,14 @@ + + if (((EntityTameable)this).func_152114_e(p_130002_1_)) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callPlayerLeashEntityEvent(this, p_130002_1_, p_130002_1_).isCancelled()) ++ { ++ ((EntityPlayerMP) p_130002_1_).playerNetServerHandler.sendPacket(new S1BPacketEntityAttach(1, this, this.getLeashedToEntity())); ++ return false; ++ } ++ ++ // CraftBukkit end + this.setLeashedToEntity(p_130002_1_, true); + --itemstack.stackSize; + return true; +@@ -1049,6 +1115,7 @@ + { + if (this.leashedToEntity == null || this.leashedToEntity.isDead) + { ++ this.worldObj.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.HOLDER_GONE)); // CraftBukkit + this.clearLeashed(true, true); + } + } +@@ -1136,10 +1203,16 @@ + } + else + { ++ this.worldObj.getServer().getPluginManager().callEvent(new EntityUnleashEvent(this.getBukkitEntity(), UnleashReason.UNKNOWN)); // CraftBukkit + this.clearLeashed(false, true); + } + } + + this.field_110170_bx = null; + } ++ ++ public boolean canDespawn_CB() ++ { ++ return this.canDespawn(); ++ } + } diff --git a/patches/net/minecraft/entity/EntityLivingBase.java.patch b/patches/net/minecraft/entity/EntityLivingBase.java.patch new file mode 100644 index 0000000..c4f3d54 --- /dev/null +++ b/patches/net/minecraft/entity/EntityLivingBase.java.patch @@ -0,0 +1,657 @@ +--- ../src-base/minecraft/net/minecraft/entity/EntityLivingBase.java ++++ ../src-work/minecraft/net/minecraft/entity/EntityLivingBase.java +@@ -50,14 +50,28 @@ + import net.minecraft.world.World; + import net.minecraft.world.WorldServer; + import net.minecraftforge.common.ForgeHooks; ++import net.minecraftforge.common.ISpecialArmor.ArmorProperties; + ++// CraftBukkit start ++import net.minecraft.nbt.NBTTagInt; ++import net.minecraft.network.play.server.S28PacketEffect; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityDamageEvent; ++import org.bukkit.event.entity.EntityDamageEvent.DamageModifier; ++import org.bukkit.event.entity.EntityRegainHealthEvent; ++// CraftBukkit end ++import org.bukkit.craftbukkit.SpigotTimings; // Spigot ++import org.bukkit.craftbukkit.inventory.CraftItemStack; // Cauldron ++ ++import com.google.common.base.Function; ++ + public abstract class EntityLivingBase extends Entity + { + private static final UUID sprintingSpeedBoostModifierUUID = UUID.fromString("662A6B8D-DA3E-4C1C-8813-96EA6097278D"); + private static final AttributeModifier sprintingSpeedBoostModifier = (new AttributeModifier(sprintingSpeedBoostModifierUUID, "Sprinting speed boost", 0.30000001192092896D, 2)).setSaved(false); + private BaseAttributeMap attributeMap; +- private final CombatTracker _combatTracker = new CombatTracker(this); +- private final HashMap activePotionsMap = new HashMap(); ++ public CombatTracker _combatTracker = new CombatTracker(this); // CraftBukkit - private -> public, remove final ++ public final HashMap activePotionsMap = new HashMap(); // CraftBukkit - protected -> public + private final ItemStack[] previousEquipment = new ItemStack[5]; + public boolean isSwingInProgress; + public int swingProgressInt; +@@ -83,7 +97,7 @@ + public float rotationYawHead; + public float prevRotationYawHead; + public float jumpMovementFactor = 0.02F; +- protected EntityPlayer attackingPlayer; ++ public EntityPlayer attackingPlayer; // CraftBukkit - protected -> public + protected int recentlyHit; + protected boolean dead; + protected int entityAge; +@@ -93,7 +107,7 @@ + protected float field_70763_ax; + protected float field_70741_aB; + protected int scoreValue; +- protected float lastDamage; ++ public float lastDamage; // CraftBukkit - protected -> public + protected boolean isJumping; + public float moveStrafing; + public float moveForward; +@@ -104,21 +118,26 @@ + protected double newPosZ; + protected double newRotationYaw; + protected double newRotationPitch; +- private boolean potionsNeedUpdate = true; +- private EntityLivingBase entityLivingToAttack; ++ public boolean potionsNeedUpdate = true; // CraftBukkit - private -> public ++ public EntityLivingBase entityLivingToAttack; // CraftBukkit - private -> public + private int revengeTimer; + private EntityLivingBase lastAttacker; + private int lastAttackerTime; + private float landMovementFactor; + private int jumpTicks; + private float field_110151_bq; ++ // CraftBukkit start ++ public int expToDrop; ++ public int maxAirTicks = 300; ++ // CraftBukkit end + private static final String __OBFID = "CL_00001549"; + + public EntityLivingBase(World p_i1594_1_) + { + super(p_i1594_1_); + this.applyEntityAttributes(); +- this.setHealth(this.getMaxHealth()); ++ // CraftBukkit - this.setHealth(getMaxHealth()) inlined and simplified to skip the instanceof check for EntityPlayer, as getBukkitEntity() is not initialized in constructor ++ this.dataWatcher.updateObject(6, (float) this.getEntityAttribute(SharedMonsterAttributes.maxHealth).getAttributeValue()); + this.preventEntitySpawning = true; + this.field_70770_ap = (float)(Math.random() + 1.0D) * 0.01F; + this.setPosition(this.posX, this.posY, this.posZ); +@@ -173,7 +192,18 @@ + } + else if (!this.worldObj.isRemote && this.fallDistance > 3.0F) + { +- this.worldObj.playAuxSFX(2006, i, j, k, MathHelper.ceiling_float_int(this.fallDistance - 3.0F)); ++ // CraftBukkit start - supply player as argument in particles for visibility API to work ++ if (this instanceof EntityPlayerMP) ++ { ++ this.worldObj.playAuxSFXAtEntity((EntityPlayer) this, 2006, i, j, k, MathHelper.ceiling_float_int(this.fallDistance - 3.0F)); ++ ((EntityPlayerMP) this).playerNetServerHandler.sendPacket(new S28PacketEffect(2006, i, j, k, MathHelper ++ .ceiling_float_int(this.fallDistance - 3.0F), false)); ++ } ++ else ++ { ++ this.worldObj.playAuxSFX(2006, i, j, k, MathHelper.ceiling_float_int(this.fallDistance - 3.0F)); ++ } ++ // CraftBukkit end + } + + block.onFallenUpon(this.worldObj, i, j, k, this, this.fallDistance); +@@ -234,7 +264,12 @@ + } + else + { +- this.setAir(300); ++ // CraftBukkit start - Only set if needed to work around a DataWatcher inefficiency ++ if (this.getAir() != 300) ++ { ++ this.setAir(maxAirTicks); ++ } ++ // CraftBukkit end + } + + if (this.isEntityAlive() && this.isWet()) +@@ -299,6 +334,22 @@ + this.worldObj.theProfiler.endSection(); + } + ++ // CraftBukkit start ++ public int getExpReward() ++ { ++ int exp = this.getExperiencePoints(this.attackingPlayer); ++ ++ if (!this.worldObj.isRemote && (this.recentlyHit > 0 || this.isPlayer()) && this.func_146066_aG()) ++ { ++ return exp; ++ } ++ else ++ { ++ return 0; ++ } ++ } ++ // CraftBukkit end ++ + public boolean isChild() + { + return false; +@@ -308,22 +359,21 @@ + { + ++this.deathTime; + +- if (this.deathTime == 20) ++ if (this.deathTime >= 20 && !this.isDead) // CraftBukkit - (this.deathTicks == 20) -> (this.deathTicks >= 20 && !this.dead) + { + int i; ++ // CraftBukkit start - Update getExpReward() above if the removed if() changes! ++ i = this.expToDrop; + +- if (!this.worldObj.isRemote && (this.recentlyHit > 0 || this.isPlayer()) && this.func_146066_aG() && this.worldObj.getGameRules().getGameRuleBooleanValue("doMobLoot")) ++ while (i > 0) + { +- i = this.getExperiencePoints(this.attackingPlayer); +- +- while (i > 0) +- { +- int j = EntityXPOrb.getXPSplit(i); +- i -= j; +- this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, j)); +- } ++ int j = EntityXPOrb.getXPSplit(i); ++ i -= j; ++ this.worldObj.spawnEntityInWorld(new EntityXPOrb(this.worldObj, this.posX, this.posY, this.posZ, j)); + } + ++ this.expToDrop = 0; ++ // CraftBukkit end + this.setDead(); + + for (i = 0; i < 20; ++i) +@@ -485,6 +535,22 @@ + } + } + ++ // CraftBukkit start ++ if (p_70037_1_.hasKey("Bukkit.MaxHealth")) ++ { ++ NBTBase nbtbase = p_70037_1_.getTag("Bukkit.MaxHealth"); ++ ++ if (nbtbase.getId() == 5) ++ { ++ this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue((double) ((NBTTagFloat) nbtbase).func_150291_c()); ++ } ++ else if (nbtbase.getId() == 3) ++ { ++ this.getEntityAttribute(SharedMonsterAttributes.maxHealth).setBaseValue((double) ((NBTTagInt) nbtbase).func_150287_d()); ++ } ++ } ++ // CraftBukkit end ++ + if (p_70037_1_.hasKey("HealF", 99)) + { + this.setHealth(p_70037_1_.getFloat("HealF")); +@@ -614,12 +680,14 @@ + + public boolean isPotionActive(int p_82165_1_) + { +- return this.activePotionsMap.containsKey(Integer.valueOf(p_82165_1_)); ++ // CraftBukkit - Add size check for efficiency ++ return this.activePotionsMap.size() != 0 && this.activePotionsMap.containsKey(Integer.valueOf(p_82165_1_)); + } + + public boolean isPotionActive(Potion p_70644_1_) + { +- return this.activePotionsMap.containsKey(Integer.valueOf(p_70644_1_.id)); ++ // CraftBukkit - Add size check for efficiency ++ return this.activePotionsMap.size() != 0 && this.activePotionsMap.containsKey(Integer.valueOf(p_70644_1_.id)); + } + + public PotionEffect getActivePotionEffect(Potion p_70660_1_) +@@ -710,25 +778,66 @@ + } + } + ++ // CraftBukkit start - Delegate so we can handle providing a reason for health being regained + public void heal(float p_70691_1_) + { ++ heal(p_70691_1_, EntityRegainHealthEvent.RegainReason.CUSTOM); ++ } ++ ++ public void heal(float p_70691_1_, EntityRegainHealthEvent.RegainReason regainReason) ++ { + p_70691_1_ = net.minecraftforge.event.ForgeEventFactory.onLivingHeal(this, p_70691_1_); + if (p_70691_1_ <= 0) return; + float f1 = this.getHealth(); + + if (f1 > 0.0F) + { +- this.setHealth(f1 + p_70691_1_); ++ EntityRegainHealthEvent event = new EntityRegainHealthEvent(this.getBukkitEntity(), p_70691_1_, regainReason); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ this.setHealth((float) (this.getHealth() + event.getAmount())); ++ } + } + } + + public final float getHealth() + { ++ // CraftBukkit start - Use unscaled health ++ if (this instanceof EntityPlayerMP) ++ { ++ return (float) ((EntityPlayerMP) this).getBukkitEntity().getHealth(); ++ } ++ // CraftBukkit end + return this.dataWatcher.getWatchableObjectFloat(6); + } + + public void setHealth(float p_70606_1_) + { ++ // CraftBukkit start - Handle scaled health ++ if (this instanceof EntityPlayerMP) ++ { ++ org.bukkit.craftbukkit.entity.CraftPlayer player = ((EntityPlayerMP) this).getBukkitEntity(); ++ ++ // Squeeze ++ if (p_70606_1_ < 0.0F) ++ { ++ player.setRealHealth(0.0D); ++ } ++ else if (p_70606_1_ > player.getMaxHealth()) ++ { ++ player.setRealHealth(player.getMaxHealth()); ++ } ++ else ++ { ++ player.setRealHealth(p_70606_1_); ++ } ++ ++ this.dataWatcher.updateObject(6, Float.valueOf(player.getScaledHealth())); ++ return; ++ } ++ // CraftBukkit end + this.dataWatcher.updateObject(6, Float.valueOf(MathHelper.clamp_float(p_70606_1_, 0.0F, this.getMaxHealth()))); + } + +@@ -757,7 +866,8 @@ + } + else + { +- if ((p_70097_1_ == DamageSource.anvil || p_70097_1_ == DamageSource.fallingBlock) && this.getEquipmentInSlot(4) != null) ++ // CraftBukkit - Moved into damageEntity_CB(DamageSource, float) ++ if (false && (p_70097_1_ == DamageSource.anvil || p_70097_1_ == DamageSource.fallingBlock) && this.getEquipmentInSlot(4) != null) + { + this.getEquipmentInSlot(4).damageItem((int)(p_70097_2_ * 4.0F + this.rand.nextFloat() * p_70097_2_ * 2.0F), this); + p_70097_2_ *= 0.75F; +@@ -773,16 +883,27 @@ + return false; + } + +- this.damageEntity(p_70097_1_, p_70097_2_ - this.lastDamage); ++ // CraftBukkit start ++ if (!this.damageEntity_CB(p_70097_1_, p_70097_2_ - this.lastDamage)) ++ { ++ return false; ++ } ++ // CraftBukkit end + this.lastDamage = p_70097_2_; + flag = false; + } + else + { ++ // CraftBukkit start ++ float previousHealth = this.getHealth(); ++ if (!this.damageEntity_CB(p_70097_1_, p_70097_2_)) ++ { ++ return false; ++ } + this.lastDamage = p_70097_2_; +- this.prevHealth = this.getHealth(); ++ this.prevHealth = previousHealth; + this.hurtResistantTime = this.maxHurtResistantTime; +- this.damageEntity(p_70097_1_, p_70097_2_); ++ // CraftBukkit end + this.hurtTime = this.maxHurtTime = 10; + } + +@@ -938,6 +1059,22 @@ + + if (!ForgeHooks.onLivingDrops(this, p_70645_1_, capturedDrops, i, recentlyHit > 0, j)) + { ++ // Cauldron start - capture drops for plugins then fire event ++ if (this.capturedDrops.size() > 0) ++ { ++ java.util.List loot = new java.util.ArrayList(); ++ for (EntityItem item : capturedDrops) ++ { ++ loot.add(CraftItemStack.asCraftMirror(item.getEntityItem())); ++ } ++ CraftEventFactory.callEntityDeathEvent(this, loot); ++ } ++ else ++ { ++ CraftEventFactory.callEntityDeathEvent(this); ++ } ++ // Cauldron end ++ + for (EntityItem item : capturedDrops) + { + worldObj.spawnEntityInWorld(item); +@@ -1010,8 +1147,17 @@ + + if (i > 0) + { ++ // CraftBukkit start ++ if (!this.attackEntityFrom(DamageSource.fall, (float) i)) ++ { ++ return; ++ } ++ } ++ // CraftBukkit end ++ if (i > 0) ++ { + this.playSound(this.func_146067_o(i), 1.0F, 1.0F); +- this.attackEntityFrom(DamageSource.fall, (float)i); ++ // this.attackEntityFrom(DamageSource.fall, (float)i); // CraftBukkit - moved up + int j = MathHelper.floor_double(this.posX); + int k = MathHelper.floor_double(this.posY - 0.20000000298023224D - (double)this.yOffset); + int l = MathHelper.floor_double(this.posZ); +@@ -1065,7 +1211,7 @@ + { + int i = 25 - this.getTotalArmorValue(); + float f1 = p_70655_2_ * (float)i; +- this.damageArmor(p_70655_2_); ++ // this.damageArmor(p_70655_2_); // CraftBukkit - Moved into damageEntity_CB(DamageSource, float) + p_70655_2_ = f1 / 25.0F; + } + +@@ -1089,7 +1235,8 @@ + int j; + float f1; + +- if (this.isPotionActive(Potion.resistance) && p_70672_1_ != DamageSource.outOfWorld) ++ // CraftBukkit - Moved to damageEntity_CB(DamageSource, float) ++ if (false && this.isPotionActive(Potion.resistance) && p_70672_1_ != DamageSource.outOfWorld) + { + i = (this.getActivePotionEffect(Potion.resistance).getAmplifier() + 1) * 5; + j = 25 - i; +@@ -1122,26 +1269,156 @@ + } + } + ++ // Cauldron start - vanilla compatibility + protected void damageEntity(DamageSource p_70665_1_, float p_70665_2_) + { ++ this.damageEntity_CB(p_70665_1_, p_70665_2_); ++ } ++ ++ // Cauldron end ++ ++ // CraftBukkit start ++ protected boolean damageEntity_CB(final DamageSource damagesource, float f) ++ { // void -> boolean, add final + if (!this.isEntityInvulnerable()) + { +- p_70665_2_ = ForgeHooks.onLivingHurt(this, p_70665_1_, p_70665_2_); +- if (p_70665_2_ <= 0) return; +- p_70665_2_ = this.applyArmorCalculations(p_70665_1_, p_70665_2_); +- p_70665_2_ = this.applyPotionDamageCalculations(p_70665_1_, p_70665_2_); +- float f1 = p_70665_2_; +- p_70665_2_ = Math.max(p_70665_2_ - this.getAbsorptionAmount(), 0.0F); +- this.setAbsorptionAmount(this.getAbsorptionAmount() - (f1 - p_70665_2_)); ++ final boolean human = this instanceof EntityPlayer; ++ float originalDamage = f; ++ // Cauldron start - apply forge damage hook ++ f = ForgeHooks.onLivingHurt(this, damagesource, f); ++ if (f <= 0) return false; ++ // Cauldron end ++ Function hardHat = new Function() { ++ @Override ++ public Double apply(Double f) ++ { ++ if ((damagesource == DamageSource.anvil || damagesource == DamageSource.fallingBlock) ++ && EntityLivingBase.this.getEquipmentInSlot(4) != null) ++ { ++ return -(f - (f * 0.75F)); ++ } ++ return -0.0; ++ } ++ }; + +- if (p_70665_2_ != 0.0F) ++ float hardHatModifier = hardHat.apply((double) f).floatValue(); ++ f += hardHatModifier; ++ ++ Function blocking = new Function() { ++ @Override ++ public Double apply(Double f) ++ { ++ if (human) ++ { ++ if (!damagesource.isUnblockable() && ((EntityPlayer) EntityLivingBase.this).isBlocking() && f > 0.0F) ++ { ++ return -(f - ((1.0F + f) * 0.5F)); ++ } ++ } ++ return -0.0; ++ } ++ }; ++ float blockingModifier = blocking.apply((double) f).floatValue(); ++ f += blockingModifier; ++ ++ Function armor = new Function() { ++ @Override ++ public Double apply(Double f) ++ { ++ // Cauldron start - apply forge armor hook ++ if (human) ++ { ++ return -(f - ArmorProperties.ApplyArmor(EntityLivingBase.this, ((EntityPlayer) EntityLivingBase.this).inventory.armorInventory, ++ damagesource, f.floatValue())); ++ } ++ // Cauldron end ++ return -(f - EntityLivingBase.this.applyArmorCalculations(damagesource, f.floatValue())); ++ } ++ }; ++ float armorModifier = armor.apply((double) f).floatValue(); ++ f += armorModifier; ++ ++ Function resistance = new Function() { ++ @Override ++ public Double apply(Double f) ++ { ++ if (!damagesource.isDamageAbsolute() && EntityLivingBase.this.isPotionActive(Potion.resistance) && damagesource != DamageSource.outOfWorld) ++ { ++ int i = (EntityLivingBase.this.getActivePotionEffect(Potion.resistance).getAmplifier() + 1) * 5; ++ int j = 25 - i; ++ float f1 = f.floatValue() * (float) j; ++ return -(f - (f1 / 25.0F)); ++ } ++ return -0.0; ++ } ++ }; ++ float resistanceModifier = resistance.apply((double) f).floatValue(); ++ f += resistanceModifier; ++ ++ Function magic = new Function() { ++ @Override ++ public Double apply(Double f) ++ { ++ return -(f - EntityLivingBase.this.applyPotionDamageCalculations(damagesource, f.floatValue())); ++ } ++ }; ++ float magicModifier = magic.apply((double) f).floatValue(); ++ f += magicModifier; ++ ++ Function absorption = new Function() { ++ @Override ++ public Double apply(Double f) ++ { ++ return -(Math.max(f - Math.max(f - EntityLivingBase.this.getAbsorptionAmount(), 0.0F), 0.0F)); ++ } ++ }; ++ float absorptionModifier = absorption.apply((double) f).floatValue(); ++ ++ EntityDamageEvent event = CraftEventFactory.handleLivingEntityDamageEvent(this, damagesource, originalDamage, hardHatModifier, blockingModifier, ++ armorModifier, resistanceModifier, magicModifier, absorptionModifier, hardHat, blocking, armor, resistance, magic, absorption); ++ if (event.isCancelled()) + { ++ return false; ++ } ++ ++ f = (float) event.getFinalDamage(); ++ ++ // Apply damage to helmet ++ if ((damagesource == DamageSource.anvil || damagesource == DamageSource.fallingBlock) && this.getEquipmentInSlot(4) != null) ++ { ++ this.getEquipmentInSlot(4).damageItem((int) (event.getDamage() * 4.0F + this.rand.nextFloat() * event.getDamage() * 2.0F), this); ++ } ++ ++ // Apply damage to armor ++ if (!damagesource.isUnblockable()) ++ { ++ float armorDamage = (float) (event.getDamage() + event.getDamage(DamageModifier.BLOCKING) + event.getDamage(DamageModifier.HARD_HAT)); ++ this.damageArmor(armorDamage); ++ } ++ ++ absorptionModifier = (float) -event.getDamage(DamageModifier.ABSORPTION); ++ this.setAbsorptionAmount(Math.max(this.getAbsorptionAmount() - absorptionModifier, 0.0F)); ++ if (f != 0.0F) ++ { ++ if (human) ++ { ++ ((EntityPlayer) this).addExhaustion(damagesource.getHungerDamage()); ++ } ++ // CraftBukkit end + float f2 = this.getHealth(); +- this.setHealth(f2 - p_70665_2_); +- this.func_110142_aN().func_94547_a(p_70665_1_, f2, p_70665_2_); +- this.setAbsorptionAmount(this.getAbsorptionAmount() - p_70665_2_); ++ this.setHealth(f2 - f); ++ this.func_110142_aN().func_94547_a(damagesource, f2, f); ++ // CraftBukkit start ++ if (human) ++ { ++ return true; ++ } ++ // CraftBukkit end ++ this.setAbsorptionAmount(this.getAbsorptionAmount() - f); + } ++ return true; // CraftBukkit + } ++ return false; // CraftBukkit + } + + public CombatTracker func_110142_aN() +@@ -1558,6 +1835,7 @@ + public void onUpdate() + { + if (ForgeHooks.onLivingUpdate(this)) return; ++ SpigotTimings.timerEntityBaseTick.startTiming(); // Spigot + super.onUpdate(); + + if (!this.worldObj.isRemote) +@@ -1608,7 +1886,9 @@ + } + } + ++ SpigotTimings.timerEntityBaseTick.stopTiming(); // Spigot + this.onLivingUpdate(); ++ SpigotTimings.timerEntityTickRest.startTiming(); // Spigot + double d0 = this.posX - this.prevPosX; + double d1 = this.posZ - this.prevPosZ; + float f = (float)(d0 * d0 + d1 * d1); +@@ -1621,7 +1901,8 @@ + { + f3 = 1.0F; + f2 = (float)Math.sqrt((double)f) * 3.0F; +- f1 = (float)Math.atan2(d1, d0) * 180.0F / (float)Math.PI - 90.0F; ++ // CraftBukkit - Math -> TrigMath ++ f1 = (float) org.bukkit.craftbukkit.TrigMath.atan2(d1, d0) * 180.0F / (float)Math.PI - 90.0F; + } + + if (this.swingProgress > 0.0F) +@@ -1682,6 +1963,7 @@ + + this.worldObj.theProfiler.endSection(); + this.field_70764_aw += f2; ++ SpigotTimings.timerEntityTickRest.stopTiming(); // Spigot + } + + protected float func_110146_f(float p_110146_1_, float p_110146_2_) +@@ -1757,6 +2039,7 @@ + this.motionZ = 0.0D; + } + ++ SpigotTimings.timerEntityAI.startTiming(); // Spigot + this.worldObj.theProfiler.startSection("ai"); + + if (this.isMovementBlocked()) +@@ -1783,6 +2066,7 @@ + } + } + ++ SpigotTimings.timerEntityAI.stopTiming(); // Spigot + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("jump"); + +@@ -1811,13 +2095,17 @@ + this.moveStrafing *= 0.98F; + this.moveForward *= 0.98F; + this.randomYawVelocity *= 0.9F; ++ SpigotTimings.timerEntityAIMove.startTiming(); // Spigot + this.moveEntityWithHeading(this.moveStrafing, this.moveForward); ++ SpigotTimings.timerEntityAIMove.stopTiming(); // Spigot + this.worldObj.theProfiler.endSection(); + this.worldObj.theProfiler.startSection("push"); + + if (!this.worldObj.isRemote) + { ++ SpigotTimings.timerEntityAICollision.startTiming(); // Spigot + this.collideWithNearbyEntities(); ++ SpigotTimings.timerEntityAICollision.stopTiming(); // Spigot + } + + this.worldObj.theProfiler.endSection(); +@@ -1829,17 +2117,36 @@ + { + List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); + +- if (list != null && !list.isEmpty()) ++ if (this.canBeCollidedWith() && list != null && !list.isEmpty()) // Spigot: Add this.canBeCollidedWith() condition + { ++ numCollisions -= worldObj.getSpigotConfig().maxCollisionsPerEntity; // Spigot // Cauldron ++ + for (int i = 0; i < list.size(); ++i) + { +- Entity entity = (Entity)list.get(i); ++ if (numCollisions > worldObj.getSpigotConfig().maxCollisionsPerEntity) // Cauldron ++ { ++ break; // Spigot ++ } + ++ Entity entity = (Entity) list.get(i); ++ ++ // TODO better check now? ++ // CraftBukkit start - Only handle mob (non-player) collisions ++ // every other tick ++ if (entity instanceof EntityLivingBase && !(this instanceof EntityPlayerMP) && this.ticksExisted % 2 == 0) ++ { ++ continue; ++ } ++ // CraftBukkit end ++ + if (entity.canBePushed()) + { ++ entity.numCollisions++; // Spigot ++ numCollisions++; // Spigot + this.collideWithEntity(entity); + } + } ++ numCollisions = 0; // Spigot + } + } + diff --git a/patches/net/minecraft/entity/EntityMinecartCommandBlock.java.patch b/patches/net/minecraft/entity/EntityMinecartCommandBlock.java.patch new file mode 100644 index 0000000..af78d15 --- /dev/null +++ b/patches/net/minecraft/entity/EntityMinecartCommandBlock.java.patch @@ -0,0 +1,39 @@ +--- ../src-base/minecraft/net/minecraft/entity/EntityMinecartCommandBlock.java ++++ ../src-work/minecraft/net/minecraft/entity/EntityMinecartCommandBlock.java +@@ -16,33 +16,9 @@ + + public class EntityMinecartCommandBlock extends EntityMinecart + { +- private final CommandBlockLogic field_145824_a = new CommandBlockLogic() +- { +- private static final String __OBFID = "CL_00001673"; +- public void func_145756_e() +- { +- EntityMinecartCommandBlock.this.getDataWatcher().updateObject(23, this.func_145753_i()); +- EntityMinecartCommandBlock.this.getDataWatcher().updateObject(24, IChatComponent.Serializer.func_150696_a(this.func_145749_h())); +- } +- @SideOnly(Side.CLIENT) +- public int func_145751_f() +- { +- return 1; +- } +- @SideOnly(Side.CLIENT) +- public void func_145757_a(ByteBuf p_145757_1_) +- { +- p_145757_1_.writeInt(EntityMinecartCommandBlock.this.getEntityId()); +- } +- public ChunkCoordinates getPlayerCoordinates() +- { +- return new ChunkCoordinates(MathHelper.floor_double(EntityMinecartCommandBlock.this.posX), MathHelper.floor_double(EntityMinecartCommandBlock.this.posY + 0.5D), MathHelper.floor_double(EntityMinecartCommandBlock.this.posZ)); +- } +- public World getEntityWorld() +- { +- return EntityMinecartCommandBlock.this.worldObj; +- } +- }; ++ private final EntityMinecartCommandBlockListener field_145824_a_CB= new EntityMinecartCommandBlockListener(this); // CraftBukkit ++ private final CommandBlockLogic field_145824_a = field_145824_a_CB; // Cauldron ++ + private int field_145823_b = 0; + private static final String __OBFID = "CL_00001672"; + diff --git a/patches/net/minecraft/entity/EntityTracker.java.patch b/patches/net/minecraft/entity/EntityTracker.java.patch new file mode 100644 index 0000000..7381990 --- /dev/null +++ b/patches/net/minecraft/entity/EntityTracker.java.patch @@ -0,0 +1,27 @@ +--- ../src-base/minecraft/net/minecraft/entity/EntityTracker.java ++++ ../src-work/minecraft/net/minecraft/entity/EntityTracker.java +@@ -38,6 +38,7 @@ + import net.minecraft.world.chunk.Chunk; + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; ++import net.minecraft.server.MinecraftServer; // Spigot + + import cpw.mods.fml.common.registry.EntityRegistry; + +@@ -46,7 +47,7 @@ + private static final Logger logger = LogManager.getLogger(); + private final WorldServer theWorld; + private Set trackedEntities = new HashSet(); +- private IntHashMap trackedEntityIDs = new IntHashMap(); ++ public IntHashMap trackedEntityIDs = new IntHashMap(); // CraftBukkit - private -> public + private int entityViewDistance; + private static final String __OBFID = "CL_00001431"; + +@@ -184,6 +185,7 @@ + + public void addEntityToTracker(Entity p_72785_1_, int p_72785_2_, final int p_72785_3_, boolean p_72785_4_) + { ++ p_72785_2_ = org.spigotmc.TrackingRange.getEntityTrackingRange(p_72785_1_, p_72785_2_); // Spigot + if (p_72785_2_ > this.entityViewDistance) + { + p_72785_2_ = this.entityViewDistance; diff --git a/patches/net/minecraft/entity/EntityTrackerEntry.java.patch b/patches/net/minecraft/entity/EntityTrackerEntry.java.patch new file mode 100644 index 0000000..1963f94 --- /dev/null +++ b/patches/net/minecraft/entity/EntityTrackerEntry.java.patch @@ -0,0 +1,216 @@ +--- ../src-base/minecraft/net/minecraft/entity/EntityTrackerEntry.java ++++ ../src-work/minecraft/net/minecraft/entity/EntityTrackerEntry.java +@@ -56,9 +56,15 @@ + import net.minecraft.world.storage.MapData; + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; ++import net.minecraft.server.MinecraftServer; // Spigot + + import cpw.mods.fml.common.network.internal.FMLNetworkHandler; + ++// CraftBukkit start ++import org.bukkit.entity.Player; ++import org.bukkit.event.player.PlayerVelocityEvent; ++// CraftBukkit end ++ + public class EntityTrackerEntry + { + private static final Logger logger = LogManager.getLogger(); +@@ -131,15 +137,15 @@ + this.func_151259_a(new S1BPacketEntityAttach(0, this.myEntity, this.myEntity.ridingEntity)); + } + +- if (this.myEntity instanceof EntityItemFrame && this.ticks % 10 == 0) ++ if (this.myEntity instanceof EntityItemFrame /*&& this.ticks % 10 == 0*/) // CraftBukkit - Moved below, should always enter this block + { + EntityItemFrame entityitemframe = (EntityItemFrame)this.myEntity; + ItemStack itemstack = entityitemframe.getDisplayedItem(); + +- if (itemstack != null && itemstack.getItem() instanceof ItemMap) ++ if (this.ticks % 10 == 0 && itemstack != null && itemstack.getItem() instanceof ItemMap) // CraftBukkit - Moved this.m % 10 logic here so item frames do not enter the other blocks + { + MapData mapdata = Items.filled_map.getMapData(itemstack, this.myEntity.worldObj); +- Iterator iterator = p_73122_1_.iterator(); ++ Iterator iterator = this.trackingPlayers.iterator(); // CraftBukkit + + while (iterator.hasNext()) + { +@@ -177,6 +183,22 @@ + boolean flag = Math.abs(j1) >= 4 || Math.abs(k1) >= 4 || Math.abs(l1) >= 4 || this.ticks % 60 == 0; + boolean flag1 = Math.abs(l - this.lastYaw) >= 4 || Math.abs(i1 - this.lastPitch) >= 4; + ++ // CraftBukkit start - Code moved from below ++ if (flag) ++ { ++ this.lastScaledXPosition = i; ++ this.lastScaledYPosition = j; ++ this.lastScaledZPosition = k; ++ } ++ ++ if (flag1) ++ { ++ this.lastYaw = l; ++ this.lastPitch = i1; ++ } ++ ++ // CraftBukkit end ++ + if (this.ticks > 0 || this.myEntity instanceof EntityArrow) + { + if (j1 >= -128 && j1 < 128 && k1 >= -128 && k1 < 128 && l1 >= -128 && l1 < 128 && this.ticksSinceLastForcedTeleport <= 400 && !this.ridingEntity) +@@ -197,7 +219,15 @@ + else + { + this.ticksSinceLastForcedTeleport = 0; +- object = new S18PacketEntityTeleport(this.myEntity.getEntityId(), i, j, k, (byte)l, (byte)i1); ++ ++ // CraftBukkit start - Refresh list of who can see a player before sending teleport packet ++ if (this.myEntity instanceof EntityPlayerMP) ++ { ++ this.sendEventsToPlayers(new java.util.ArrayList(this.trackingPlayers)); ++ } ++ ++ // CraftBukkit end ++ object = new S18PacketEntityTeleport(this.myEntity.getEntityId(), i, j, k, (byte) l, (byte) i1); + } + } + +@@ -224,7 +254,7 @@ + } + + this.sendMetadataToAllAssociatedPlayers(); +- ++ /* CraftBukkit start - Code moved up + if (flag) + { + this.lastScaledXPosition = i; +@@ -237,7 +267,7 @@ + this.lastYaw = l; + this.lastPitch = i1; + } +- ++ // CraftBukkit end */ + this.ridingEntity = false; + } + else +@@ -275,7 +305,32 @@ + + if (this.myEntity.velocityChanged) + { +- this.func_151261_b(new S12PacketEntityVelocity(this.myEntity)); ++ // CraftBukkit start - Create PlayerVelocity event ++ boolean cancelled = false; ++ ++ if (this.myEntity instanceof EntityPlayerMP) ++ { ++ Player player = (Player) this.myEntity.getBukkitEntity(); ++ org.bukkit.util.Vector velocity = player.getVelocity(); ++ PlayerVelocityEvent event = new PlayerVelocityEvent(player, velocity); ++ this.myEntity.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ cancelled = true; ++ } ++ else if (!velocity.equals(event.getVelocity())) ++ { ++ player.setVelocity(velocity); ++ } ++ } ++ ++ if (!cancelled) ++ { ++ this.func_151261_b((Packet)(new S12PacketEntityVelocity(this.myEntity))); ++ } ++ ++ // CraftBukkit end + this.myEntity.velocityChanged = false; + } + } +@@ -296,6 +351,13 @@ + + if (!set.isEmpty()) + { ++ // CraftBukkit start - Send scaled max health ++ if (this.myEntity instanceof EntityPlayerMP) ++ { ++ ((EntityPlayerMP) this.myEntity).getBukkitEntity().injectScaledMaxHealth(set, false); ++ } ++ ++ // CraftBukkit end + this.func_151261_b(new S20PacketEntityProperties(this.myEntity.getEntityId(), set)); + } + +@@ -353,6 +415,19 @@ + + if (d0 >= (double)(-this.blocksDistanceThreshold) && d0 <= (double)this.blocksDistanceThreshold && d1 >= (double)(-this.blocksDistanceThreshold) && d1 <= (double)this.blocksDistanceThreshold) + { ++ // CraftBukkit start ++ if (this.myEntity instanceof EntityPlayerMP) ++ { ++ Player player = ((EntityPlayerMP) this.myEntity).getBukkitEntity(); ++ ++ if (!p_73117_1_.getBukkitEntity().canSee(player)) ++ { ++ return; ++ } ++ } ++ // CraftBukkit end ++ ++ p_73117_1_.destroyedItemsNetCache.remove(Integer.valueOf(this.myEntity.getEntityId())); + if (!this.trackingPlayers.contains(p_73117_1_) && (this.isPlayerWatchingThisChunk(p_73117_1_) || this.myEntity.forceSpawn)) + { + this.trackingPlayers.add(p_73117_1_); +@@ -369,6 +444,13 @@ + ServersideAttributeMap serversideattributemap = (ServersideAttributeMap)((EntityLivingBase)this.myEntity).getAttributeMap(); + Collection collection = serversideattributemap.getWatchedAttributes(); + ++ // CraftBukkit start - If sending own attributes send scaled health instead of current maximum health ++ if (this.myEntity.getEntityId() == p_73117_1_.getEntityId()) ++ { ++ ((EntityPlayerMP) this.myEntity).getBukkitEntity().injectScaledMaxHealth(collection, false); ++ } ++ ++ // CraftBukkit end + if (!collection.isEmpty()) + { + p_73117_1_.playerNetServerHandler.sendPacket(new S20PacketEntityProperties(this.myEntity.getEntityId(), collection)); +@@ -397,6 +479,14 @@ + p_73117_1_.playerNetServerHandler.sendPacket(new S1BPacketEntityAttach(0, this.myEntity, this.myEntity.ridingEntity)); + } + ++ // CraftBukkit start ++ if (this.myEntity.riddenByEntity != null) ++ { ++ p_73117_1_.playerNetServerHandler.sendPacket(new S1BPacketEntityAttach(0, this.myEntity.riddenByEntity, this.myEntity)); ++ } ++ ++ // CraftBukkit end ++ + if (this.myEntity instanceof EntityLiving && ((EntityLiving)this.myEntity).getLeashedToEntity() != null) + { + p_73117_1_.playerNetServerHandler.sendPacket(new S1BPacketEntityAttach(1, this.myEntity, ((EntityLiving)this.myEntity).getLeashedToEntity())); +@@ -425,6 +515,11 @@ + } + } + ++ // CraftBukkit start - Fix for nonsensical head yaw ++ this.lastHeadMotion = MathHelper.floor_float(this.myEntity.getRotationYawHead() * 256.0F / 360.0F); // tracker.ao() should be getHeadRotation ++ this.func_151259_a(new S19PacketEntityHeadLook(this.myEntity, (byte) lastHeadMotion)); ++ // CraftBukkit end ++ + if (this.myEntity instanceof EntityLivingBase) + { + EntityLivingBase entitylivingbase = (EntityLivingBase)this.myEntity; +@@ -465,7 +560,10 @@ + { + if (this.myEntity.isDead) + { +- logger.warn("Fetching addPacket for removed entity"); ++ // CraftBukkit start - Remove useless error spam, just return ++ // logger.warn("Fetching addPacket for removed entity"); ++ return null; ++ // CraftBukkit end + } + + Packet pkt = FMLNetworkHandler.getEntitySpawningPacket(this.myEntity); diff --git a/patches/net/minecraft/entity/ai/EntityAIArrowAttack.java.patch b/patches/net/minecraft/entity/ai/EntityAIArrowAttack.java.patch new file mode 100644 index 0000000..868a77c --- /dev/null +++ b/patches/net/minecraft/entity/ai/EntityAIArrowAttack.java.patch @@ -0,0 +1,25 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityAIArrowAttack.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityAIArrowAttack.java +@@ -5,6 +5,11 @@ + import net.minecraft.entity.IRangedAttackMob; + import net.minecraft.util.MathHelper; + ++// CraftBukkit start ++import net.minecraft.entity.Entity; ++import org.bukkit.event.entity.EntityTargetEvent; ++// CraftBukkit end ++ + public class EntityAIArrowAttack extends EntityAIBase + { + private final EntityLiving entityHost; +@@ -67,6 +72,10 @@ + + public void resetTask() + { ++ // CraftBukkit start ++ EntityTargetEvent.TargetReason reason = this.attackTarget.isEntityAlive() ? EntityTargetEvent.TargetReason.FORGOT_TARGET : EntityTargetEvent.TargetReason.TARGET_DIED; ++ org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetEvent((Entity) rangedAttackEntityHost, null, reason); ++ // CraftBukkit end + this.attackTarget = null; + this.field_75318_f = 0; + this.rangedAttackTime = -1; diff --git a/patches/net/minecraft/entity/ai/EntityAIAttackOnCollide.java.patch b/patches/net/minecraft/entity/ai/EntityAIAttackOnCollide.java.patch new file mode 100644 index 0000000..5487dde --- /dev/null +++ b/patches/net/minecraft/entity/ai/EntityAIAttackOnCollide.java.patch @@ -0,0 +1,30 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityAIAttackOnCollide.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityAIAttackOnCollide.java +@@ -7,6 +7,11 @@ + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; + ++// CraftBukkit start ++import net.minecraft.entity.Entity; ++import org.bukkit.event.entity.EntityTargetEvent; ++// CraftBukkit end ++ + public class EntityAIAttackOnCollide extends EntityAIBase + { + World worldObj; +@@ -73,6 +78,15 @@ + public boolean continueExecuting() + { + EntityLivingBase entitylivingbase = this.attacker.getAttackTarget(); ++ // CraftBukkit start ++ EntityTargetEvent.TargetReason reason = this.attacker.getAttackTarget() == null ? EntityTargetEvent.TargetReason.FORGOT_TARGET : EntityTargetEvent.TargetReason.TARGET_DIED; ++ ++ if (this.attacker.getAttackTarget() == null || (this.attacker.getAttackTarget() != null && !this.attacker.getAttackTarget().isEntityAlive())) ++ { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetEvent(attacker, null, reason); ++ } ++ ++ // CraftBukkit end + return entitylivingbase == null ? false : (!entitylivingbase.isEntityAlive() ? false : (!this.longMemory ? !this.attacker.getNavigator().noPath() : this.attacker.isWithinHomeDistance(MathHelper.floor_double(entitylivingbase.posX), MathHelper.floor_double(entitylivingbase.posY), MathHelper.floor_double(entitylivingbase.posZ)))); + } + diff --git a/patches/net/minecraft/entity/ai/EntityAIBreakDoor.java.patch b/patches/net/minecraft/entity/ai/EntityAIBreakDoor.java.patch new file mode 100644 index 0000000..e921440 --- /dev/null +++ b/patches/net/minecraft/entity/ai/EntityAIBreakDoor.java.patch @@ -0,0 +1,17 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityAIBreakDoor.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityAIBreakDoor.java +@@ -58,6 +58,14 @@ + + if (this.breakingTime == 240 && this.theEntity.worldObj.difficultySetting == EnumDifficulty.HARD) + { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callEntityBreakDoorEvent(this.theEntity, this.entityPosX, this.entityPosY, this.entityPosZ).isCancelled()) ++ { ++ this.updateTask(); ++ return; ++ } ++ ++ // CraftBukkit end + this.theEntity.worldObj.setBlockToAir(this.entityPosX, this.entityPosY, this.entityPosZ); + this.theEntity.worldObj.playAuxSFX(1012, this.entityPosX, this.entityPosY, this.entityPosZ, 0); + this.theEntity.worldObj.playAuxSFX(2001, this.entityPosX, this.entityPosY, this.entityPosZ, Block.getIdFromBlock(this.field_151504_e)); diff --git a/patches/net/minecraft/entity/ai/EntityAIEatGrass.java.patch b/patches/net/minecraft/entity/ai/EntityAIEatGrass.java.patch new file mode 100644 index 0000000..c242e3d --- /dev/null +++ b/patches/net/minecraft/entity/ai/EntityAIEatGrass.java.patch @@ -0,0 +1,34 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityAIEatGrass.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityAIEatGrass.java +@@ -6,6 +6,11 @@ + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.Material; ++// CraftBukkit end ++ + public class EntityAIEatGrass extends EntityAIBase + { + private EntityLiving field_151500_b; +@@ -69,7 +74,8 @@ + + if (this.field_151501_c.getBlock(i, j, k) == Blocks.tallgrass) + { +- if (this.field_151501_c.getGameRules().getGameRuleBooleanValue("mobGriefing")) ++ // CraftBukkit ++ if (!CraftEventFactory.callEntityChangeBlockEvent(this.field_151500_b, this.field_151500_b.worldObj.getWorld().getBlockAt(i, j, k), Material.AIR, !this.field_151501_c.getGameRules().getGameRuleBooleanValue("mobGriefing")).isCancelled()) + { + this.field_151501_c.func_147480_a(i, j, k, false); + } +@@ -78,7 +84,8 @@ + } + else if (this.field_151501_c.getBlock(i, j - 1, k) == Blocks.grass) + { +- if (this.field_151501_c.getGameRules().getGameRuleBooleanValue("mobGriefing")) ++ // CraftBukkit ++ if (!CraftEventFactory.callEntityChangeBlockEvent(this.field_151500_b, this.field_151500_b.worldObj.getWorld().getBlockAt(i, j - 1, k), Material.DIRT, !this.field_151501_c.getGameRules().getGameRuleBooleanValue("mobGriefing")).isCancelled()) + { + this.field_151501_c.playAuxSFX(2001, i, j - 1, k, Block.getIdFromBlock(Blocks.grass)); + this.field_151501_c.setBlock(i, j - 1, k, Blocks.dirt, 0, 2); diff --git a/patches/net/minecraft/entity/ai/EntityAIMate.java.patch b/patches/net/minecraft/entity/ai/EntityAIMate.java.patch new file mode 100644 index 0000000..8890571 --- /dev/null +++ b/patches/net/minecraft/entity/ai/EntityAIMate.java.patch @@ -0,0 +1,42 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityAIMate.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityAIMate.java +@@ -4,6 +4,7 @@ + import java.util.List; + import java.util.Random; + import net.minecraft.entity.EntityAgeable; ++import net.minecraft.entity.EntityLiving; + import net.minecraft.entity.item.EntityXPOrb; + import net.minecraft.entity.passive.EntityAnimal; + import net.minecraft.entity.passive.EntityCow; +@@ -12,6 +13,8 @@ + import net.minecraft.stats.StatList; + import net.minecraft.world.World; + ++import net.minecraft.entity.passive.EntityTameable; // CraftBukkit ++ + public class EntityAIMate extends EntityAIBase + { + private EntityAnimal theAnimal; +@@ -93,6 +96,13 @@ + + if (entityageable != null) + { ++ // CraftBukkit start - set persistence for tame animals ++ if (entityageable instanceof EntityTameable && ((EntityTameable) entityageable).isTamed()) ++ { ++ ((EntityLiving)entityageable).persistenceRequired = true; // Cauldron - fix illegal access error. SS bug? ++ } ++ ++ // CraftBukkit end + EntityPlayer entityplayer = this.theAnimal.func_146083_cb(); + + if (entityplayer == null && this.targetMate.func_146083_cb() != null) +@@ -116,7 +126,7 @@ + this.targetMate.resetInLove(); + entityageable.setGrowingAge(-24000); + entityageable.setLocationAndAngles(this.theAnimal.posX, this.theAnimal.posY, this.theAnimal.posZ, 0.0F, 0.0F); +- this.theWorld.spawnEntityInWorld(entityageable); ++ this.theWorld.addEntity(entityageable, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason + Random random = this.theAnimal.getRNG(); + + for (int i = 0; i < 7; ++i) diff --git a/patches/net/minecraft/entity/ai/EntityAIPanic.java.patch b/patches/net/minecraft/entity/ai/EntityAIPanic.java.patch new file mode 100644 index 0000000..aef9450 --- /dev/null +++ b/patches/net/minecraft/entity/ai/EntityAIPanic.java.patch @@ -0,0 +1,26 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityAIPanic.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityAIPanic.java +@@ -3,6 +3,8 @@ + import net.minecraft.entity.EntityCreature; + import net.minecraft.util.Vec3; + ++import net.minecraft.entity.EntityLivingBase; // CraftBukkit ++ + public class EntityAIPanic extends EntityAIBase + { + private EntityCreature theEntityCreature; +@@ -50,6 +52,14 @@ + + public boolean continueExecuting() + { ++ // CraftBukkit start - introduce a temporary timeout hack until this is fixed properly ++ if ((this.theEntityCreature.ticksExisted - this.theEntityCreature.func_142015_aE()) > 100) ++ { ++ this.theEntityCreature.setRevengeTarget((EntityLivingBase) null); ++ return false; ++ } ++ ++ // CraftBukkit end + return !this.theEntityCreature.getNavigator().noPath(); + } + } diff --git a/patches/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java.patch b/patches/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java.patch new file mode 100644 index 0000000..36c0c25 --- /dev/null +++ b/patches/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java.patch @@ -0,0 +1,35 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityAIRunAroundLikeCrazy.java +@@ -64,7 +64,8 @@ + int i = this.horseHost.getTemper(); + int j = this.horseHost.getMaxTemper(); + +- if (j > 0 && this.horseHost.getRNG().nextInt(j) < i) ++ // CraftBukkit ++ if (j > 0 && this.horseHost.getRNG().nextInt(j) < i && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this.horseHost, (EntityPlayer) this.horseHost.riddenByEntity).isCancelled() && this.horseHost.riddenByEntity instanceof EntityPlayer) + { + this.horseHost.setTamedBy((EntityPlayer)this.horseHost.riddenByEntity); + this.horseHost.worldObj.setEntityState(this.horseHost, (byte)7); +@@ -74,8 +75,20 @@ + this.horseHost.increaseTemper(5); + } + +- this.horseHost.riddenByEntity.mountEntity((Entity)null); +- this.horseHost.riddenByEntity = null; ++ // CraftBukkit start - Handle dismounting to account for VehicleExitEvent being fired. ++ if (this.horseHost.riddenByEntity != null) ++ { ++ this.horseHost.riddenByEntity.mountEntity((Entity) null); ++ ++ // If the entity still has a passenger, then a plugin cancelled the event. ++ if (this.horseHost.riddenByEntity != null) ++ { ++ return; ++ } ++ } ++ ++ // this.entity.passenger = null; ++ // CraftBukkit end + this.horseHost.makeHorseRearWithSound(); + this.horseHost.worldObj.setEntityState(this.horseHost, (byte)6); + } diff --git a/patches/net/minecraft/entity/ai/EntityAISit.java.patch b/patches/net/minecraft/entity/ai/EntityAISit.java.patch new file mode 100644 index 0000000..cfb4697 --- /dev/null +++ b/patches/net/minecraft/entity/ai/EntityAISit.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityAISit.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityAISit.java +@@ -19,7 +19,7 @@ + { + if (!this.theEntity.isTamed()) + { +- return false; ++ return this.isSitting && this.theEntity.getAttackTarget() == null; // CraftBukkit - Allow sitting for wild animals + } + else if (this.theEntity.isInWater()) + { diff --git a/patches/net/minecraft/entity/ai/EntityAITarget.java.patch b/patches/net/minecraft/entity/ai/EntityAITarget.java.patch new file mode 100644 index 0000000..da6c042 --- /dev/null +++ b/patches/net/minecraft/entity/ai/EntityAITarget.java.patch @@ -0,0 +1,66 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityAITarget.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityAITarget.java +@@ -12,6 +12,11 @@ + import net.minecraft.util.MathHelper; + import org.apache.commons.lang3.StringUtils; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.entity.CraftEntity; ++import org.bukkit.event.entity.EntityTargetEvent; ++// CraftBukkit end ++ + public abstract class EntityAITarget extends EntityAIBase + { + protected EntityCreature taskOwner; +@@ -156,6 +161,51 @@ + } + } + ++ // CraftBukkit start - Check all the different target goals for the reason, default to RANDOM_TARGET ++ EntityTargetEvent.TargetReason reason = EntityTargetEvent.TargetReason.RANDOM_TARGET; ++ ++ if (this instanceof EntityAIDefendVillage) ++ { ++ reason = EntityTargetEvent.TargetReason.DEFEND_VILLAGE; ++ } ++ else if (this instanceof EntityAIHurtByTarget) ++ { ++ reason = EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY; ++ } ++ else if (this instanceof EntityAINearestAttackableTarget) ++ { ++ if (p_75296_1_ instanceof EntityPlayer) ++ { ++ reason = EntityTargetEvent.TargetReason.CLOSEST_PLAYER; ++ } ++ } ++ else if (this instanceof EntityAIOwnerHurtByTarget) ++ { ++ reason = EntityTargetEvent.TargetReason.TARGET_ATTACKED_OWNER; ++ } ++ else if (this instanceof EntityAIOwnerHurtTarget) ++ { ++ reason = EntityTargetEvent.TargetReason.OWNER_ATTACKED_TARGET; ++ } ++ ++ org.bukkit.event.entity.EntityTargetLivingEntityEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetLivingEvent(this.taskOwner, p_75296_1_, reason); ++ ++ if (event.isCancelled() || event.getTarget() == null) ++ { ++ this.taskOwner.setAttackTarget(null); ++ return false; ++ } ++ else if (p_75296_1_.getBukkitEntity() != event.getTarget()) ++ { ++ this.taskOwner.setAttackTarget((EntityLivingBase)((CraftEntity) event.getTarget()).getHandle()); ++ } ++ ++ if (this.taskOwner instanceof EntityCreature) ++ { ++ ((EntityCreature) this.taskOwner).entityToAttack = ((CraftEntity) event.getTarget()).getHandle(); ++ } ++ ++ // CraftBukkit end + return true; + } + } diff --git a/patches/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch b/patches/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch new file mode 100644 index 0000000..7da3ed5 --- /dev/null +++ b/patches/net/minecraft/entity/ai/EntityAIVillagerMate.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityAIVillagerMate.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityAIVillagerMate.java +@@ -119,7 +119,7 @@ + this.villagerObj.setGrowingAge(6000); + entityvillager.setGrowingAge(-24000); + entityvillager.setLocationAndAngles(this.villagerObj.posX, this.villagerObj.posY, this.villagerObj.posZ, 0.0F, 0.0F); +- this.worldObj.spawnEntityInWorld(entityvillager); ++ this.worldObj.addEntity(entityvillager, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.BREEDING); // CraftBukkit - added SpawnReason + this.worldObj.setEntityState(entityvillager, (byte)12); + } + } diff --git a/patches/net/minecraft/entity/ai/EntityLookHelper.java.patch b/patches/net/minecraft/entity/ai/EntityLookHelper.java.patch new file mode 100644 index 0000000..856003a --- /dev/null +++ b/patches/net/minecraft/entity/ai/EntityLookHelper.java.patch @@ -0,0 +1,24 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityLookHelper.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityLookHelper.java +@@ -5,6 +5,8 @@ + import net.minecraft.entity.EntityLivingBase; + import net.minecraft.util.MathHelper; + ++import org.bukkit.craftbukkit.TrigMath; // CraftBukkit ++ + public class EntityLookHelper + { + private EntityLiving entity; +@@ -61,8 +63,10 @@ + double d1 = this.posY - (this.entity.posY + (double)this.entity.getEyeHeight()); + double d2 = this.posZ - this.entity.posZ; + double d3 = (double)MathHelper.sqrt_double(d0 * d0 + d2 * d2); +- float f = (float)(Math.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F; +- float f1 = (float)(-(Math.atan2(d1, d3) * 180.0D / Math.PI)); ++ // CraftBukkit start - Math -> TrigMath ++ float f = (float)(TrigMath.atan2(d2, d0) * 180.0D / Math.PI) - 90.0F; ++ float f1 = (float)(-(TrigMath.atan2(d1, d3) * 180.0D / Math.PI)); ++ // CraftBukkit end + this.entity.rotationPitch = this.updateRotation(this.entity.rotationPitch, f1, this.deltaLookPitch); + this.entity.rotationYawHead = this.updateRotation(this.entity.rotationYawHead, f, this.deltaLookYaw); + } diff --git a/patches/net/minecraft/entity/ai/EntityMoveHelper.java.patch b/patches/net/minecraft/entity/ai/EntityMoveHelper.java.patch new file mode 100644 index 0000000..467bcd6 --- /dev/null +++ b/patches/net/minecraft/entity/ai/EntityMoveHelper.java.patch @@ -0,0 +1,12 @@ +--- ../src-base/minecraft/net/minecraft/entity/ai/EntityMoveHelper.java ++++ ../src-work/minecraft/net/minecraft/entity/ai/EntityMoveHelper.java +@@ -56,7 +56,8 @@ + + if (d3 >= 2.500000277905201E-7D) + { +- float f = (float)(Math.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F; ++ // CraftBukkit - Math -> TrigMath ++ float f = (float)(org.bukkit.craftbukkit.TrigMath.atan2(d1, d0) * 180.0D / Math.PI) - 90.0F; + this.entity.rotationYaw = this.limitAngle(this.entity.rotationYaw, f, 30.0F); + this.entity.setAIMoveSpeed((float)(this.speed * this.entity.getEntityAttribute(SharedMonsterAttributes.movementSpeed).getAttributeValue())); + diff --git a/patches/net/minecraft/entity/boss/EntityDragon.java.patch b/patches/net/minecraft/entity/boss/EntityDragon.java.patch new file mode 100644 index 0000000..781ef89 --- /dev/null +++ b/patches/net/minecraft/entity/boss/EntityDragon.java.patch @@ -0,0 +1,258 @@ +--- ../src-base/minecraft/net/minecraft/entity/boss/EntityDragon.java ++++ ../src-work/minecraft/net/minecraft/entity/boss/EntityDragon.java +@@ -22,6 +22,19 @@ + import net.minecraft.world.Explosion; + import net.minecraft.world.World; + ++// CraftBukkit start ++import net.minecraft.entity.player.EntityPlayerMP; ++import net.minecraft.network.play.server.S23PacketBlockChange; ++import org.bukkit.block.BlockState; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.util.BlockStateListPopulator; ++import org.bukkit.event.entity.EntityCreatePortalEvent; ++import org.bukkit.event.entity.EntityExplodeEvent; ++import org.bukkit.event.entity.EntityRegainHealthEvent; ++import org.bukkit.event.entity.EntityTargetEvent; ++import org.bukkit.Bukkit; ++// CraftBukkit end ++ + public class EntityDragon extends EntityLiving implements IBossDisplayData, IEntityMultiPart, IMob + { + public double targetX; +@@ -44,6 +57,7 @@ + private Entity target; + public int deathTicks; + public EntityEnderCrystal healingEnderCrystal; ++ private Explosion explosionSource = new Explosion(null, this, Double.NaN, Double.NaN, Double.NaN, Float.NaN); // CraftBukkit - reusable source for CraftTNTPrimed.getSource() + private static final String __OBFID = "CL_00001659"; + + public EntityDragon(World p_i1700_1_) +@@ -355,14 +369,25 @@ + { + if (!this.worldObj.isRemote) + { +- this.attackEntityFromPart(this.dragonPartHead, DamageSource.setExplosionSource((Explosion)null), 10.0F); ++ CraftEventFactory.entityDamage = this.healingEnderCrystal; // CraftBukkit ++ this.attackEntityFromPart(this.dragonPartHead, DamageSource.setExplosionSource((Explosion) null), 10.0F); ++ CraftEventFactory.entityDamage = null; // CraftBukkit + } + + this.healingEnderCrystal = null; + } + else if (this.ticksExisted % 10 == 0 && this.getHealth() < this.getMaxHealth()) + { +- this.setHealth(this.getHealth() + 1.0F); ++ // CraftBukkit start ++ EntityRegainHealthEvent event = new EntityRegainHealthEvent(this.getBukkitEntity(), 1.0D, EntityRegainHealthEvent.RegainReason.ENDER_CRYSTAL); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ this.setHealth((float)(this.getHealth() + event.getAmount())); ++ } ++ ++ // CraftBukkit end + } + } + +@@ -429,7 +454,24 @@ + + if (this.rand.nextInt(2) == 0 && !this.worldObj.playerEntities.isEmpty()) + { +- this.target = (Entity)this.worldObj.playerEntities.get(this.rand.nextInt(this.worldObj.playerEntities.size())); ++ // CraftBukkit start ++ Entity target = (Entity) this.worldObj.playerEntities.get(this.rand.nextInt(this.worldObj.playerEntities.size())); ++ EntityTargetEvent event = new EntityTargetEvent(this.getBukkitEntity(), target.getBukkitEntity(), EntityTargetEvent.TargetReason.RANDOM_TARGET); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ if (event.getTarget() == null) ++ { ++ this.target = null; ++ } ++ else ++ { ++ this.target = ((org.bukkit.craftbukkit.entity.CraftEntity) event.getTarget()).getHandle(); ++ } ++ } ++ ++ // CraftBukkit end + } + else + { +@@ -468,6 +510,10 @@ + int j1 = MathHelper.floor_double(p_70972_1_.maxZ); + boolean flag = false; + boolean flag1 = false; ++ // CraftBukkit start - Create a list to hold all the destroyed blocks ++ List destroyedBlocks = new java.util.ArrayList(); ++ org.bukkit.craftbukkit.CraftWorld craftWorld = this.worldObj.getWorld(); ++ // CraftBukkit end + + for (int k1 = i; k1 <= l; ++k1) + { +@@ -481,7 +527,11 @@ + { + if (block.canEntityDestroy(worldObj, k1, l1, i2, this) && this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) + { +- flag1 = this.worldObj.setBlockToAir(k1, l1, i2) || flag1; ++ // CraftBukkit start - Add blocks to list rather than destroying them ++ // flag1 = this.world.setAir(k1, l1, i2) || flag1; ++ flag1 = true; ++ destroyedBlocks.add(craftWorld.getBlockAt(k1, l1, i2)); ++ // CraftBukkit end + } + else + { +@@ -494,6 +544,52 @@ + + if (flag1) + { ++ // CraftBukkit start - Set off an EntityExplodeEvent for the dragon exploding all these blocks ++ org.bukkit.entity.Entity bukkitEntity = this.getBukkitEntity(); ++ EntityExplodeEvent event = new EntityExplodeEvent(bukkitEntity, bukkitEntity.getLocation(), destroyedBlocks, 0F); ++ Bukkit.getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ // This flag literally means 'Dragon hit something hard' (Obsidian, White Stone or Bedrock) and will cause the dragon to slow down. ++ // We should consider adding an event extension for it, or perhaps returning true if the event is cancelled. ++ return flag; ++ } ++ else if (event.getYield() == 0F) ++ { ++ // Yield zero ==> no drops ++ for (org.bukkit.block.Block block : event.blockList()) ++ { ++ this.worldObj.setBlockToAir(block.getX(), block.getY(), block.getZ()); ++ } ++ } ++ else ++ { ++ for (org.bukkit.block.Block block : event.blockList()) ++ { ++ org.bukkit.Material blockId = block.getType(); ++ ++ if (blockId == org.bukkit.Material.AIR) ++ { ++ continue; ++ } ++ ++ int blockX = block.getX(); ++ int blockY = block.getY(); ++ int blockZ = block.getZ(); ++ Block nmsBlock = org.bukkit.craftbukkit.util.CraftMagicNumbers.getBlock(blockId); ++ ++ if (nmsBlock.canDropFromExplosion(explosionSource)) ++ { ++ nmsBlock.dropBlockAsItemWithChance(this.worldObj, blockX, blockY, blockZ, block.getData(), event.getYield(), 0); ++ } ++ ++ nmsBlock.onBlockDestroyedByExplosion(worldObj, blockX, blockY, blockZ, explosionSource); ++ this.worldObj.setBlockToAir(blockX, blockY, blockZ); ++ } ++ } ++ ++ // CraftBukkit end + double d1 = p_70972_1_.minX + (p_70972_1_.maxX - p_70972_1_.minX) * (double)this.rand.nextFloat(); + double d2 = p_70972_1_.minY + (p_70972_1_.maxY - p_70972_1_.minY) * (double)this.rand.nextFloat(); + double d0 = p_70972_1_.minZ + (p_70972_1_.maxZ - p_70972_1_.minZ) * (double)this.rand.nextFloat(); +@@ -531,13 +627,18 @@ + return false; + } + +- protected boolean func_82195_e(DamageSource p_82195_1_, float p_82195_2_) ++ public boolean func_82195_e(DamageSource p_82195_1_, float p_82195_2_) // CraftBukkit - protected -> public + { + return super.attackEntityFrom(p_82195_1_, p_82195_2_); + } + + protected void onDeathUpdate() + { ++ if (this.isDead) ++ { ++ return; // CraftBukkit - can't kill what's already dead ++ } ++ + ++this.deathTicks; + + if (this.deathTicks >= 180 && this.deathTicks <= 200) +@@ -555,7 +656,7 @@ + { + if (this.deathTicks > 150 && this.deathTicks % 5 == 0) + { +- i = 1000; ++ i = this.expToDrop / 12; // CraftBukkit - drop experience as dragon falls from sky. use experience drop from death event. This is now set in getExpReward() + + while (i > 0) + { +@@ -576,7 +677,7 @@ + + if (this.deathTicks == 200 && !this.worldObj.isRemote) + { +- i = 2000; ++ i = this.expToDrop - (10 * this.expToDrop / 12); // CraftBukkit - drop the remaining experience + + while (i > 0) + { +@@ -595,6 +696,8 @@ + byte b0 = 64; + BlockEndPortal.field_149948_a = true; + byte b1 = 4; ++ // CraftBukkit start - Replace any "this.world" in the following with just "world"! ++ BlockStateListPopulator world = new BlockStateListPopulator(this.worldObj.getWorld()); + + for (int k = b0 - 1; k <= b0 + 32; ++k) + { +@@ -641,6 +744,35 @@ + this.worldObj.setBlock(p_70975_1_, b0 + 2, p_70975_2_ + 1, Blocks.torch); + this.worldObj.setBlock(p_70975_1_, b0 + 3, p_70975_2_, Blocks.bedrock); + this.worldObj.setBlock(p_70975_1_, b0 + 4, p_70975_2_, Blocks.dragon_egg); ++ EntityCreatePortalEvent event = new EntityCreatePortalEvent((org.bukkit.entity.LivingEntity) this.getBukkitEntity(), java.util.Collections.unmodifiableList(world.getList()), org.bukkit.PortalType.ENDER); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ for (BlockState state : event.getBlocks()) ++ { ++ state.update(true); ++ } ++ } ++ else ++ { ++ for (BlockState state : event.getBlocks()) ++ { ++ S23PacketBlockChange packet = new S23PacketBlockChange(state.getX(), state.getY(), state.getZ(), this.worldObj); ++ ++ for (Iterator it = this.worldObj.playerEntities.iterator(); it.hasNext();) ++ { ++ EntityPlayer entity = (EntityPlayer) it.next(); ++ ++ if (entity instanceof EntityPlayerMP) ++ { ++ ((EntityPlayerMP) entity).playerNetServerHandler.sendPacket(packet); ++ } ++ } ++ } ++ } ++ ++ // CraftBukkit end + BlockEndPortal.field_149948_a = false; + } + +@@ -675,4 +807,13 @@ + { + return 5.0F; + } ++ ++ // CraftBukkit start ++ public int getExpReward() ++ { ++ // This value is equal to the amount of experience dropped while falling from the sky (10 * 1000) ++ // plus what is dropped when the dragon hits the ground (2000) ++ return 12000; ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/entity/boss/EntityWither.java.patch b/patches/net/minecraft/entity/boss/EntityWither.java.patch new file mode 100644 index 0000000..62083a2 --- /dev/null +++ b/patches/net/minecraft/entity/boss/EntityWither.java.patch @@ -0,0 +1,57 @@ +--- ../src-base/minecraft/net/minecraft/entity/boss/EntityWither.java ++++ ../src-work/minecraft/net/minecraft/entity/boss/EntityWither.java +@@ -34,6 +34,11 @@ + import net.minecraft.world.EnumDifficulty; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.ExplosionPrimeEvent; ++// CraftBukkit end ++ + public class EntityWither extends EntityMob implements IBossDisplayData, IRangedAttackMob + { + private float[] field_82220_d = new float[2]; +@@ -228,15 +233,25 @@ + + if (i <= 0) + { +- this.worldObj.newExplosion(this, this.posX, this.posY + (double)this.getEyeHeight(), this.posZ, 7.0F, false, this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); +- this.worldObj.playBroadcastSound(1013, (int)this.posX, (int)this.posY, (int)this.posZ, 0); ++ // CraftBukkit start ++ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 7.0F, false); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ this.worldObj.newExplosion(this, this.posX, this.posY + (double) this.getEyeHeight(), this.posZ, event.getRadius(), event.getFire(), this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); ++ } ++ ++ // CraftBukkit end ++ this.worldObj.newExplosion(this, this.posX, this.posY + (double) this.getEyeHeight(), this.posZ, 7.0F, false, this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); ++ this.worldObj.playBroadcastSound(1013, (int) this.posX, (int) this.posY, (int) this.posZ, 0); + } + + this.func_82215_s(i); + + if (this.ticksExisted % 10 == 0) + { +- this.heal(10.0F); ++ this.heal(10.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.WITHER_SPAWN); // CraftBukkit + } + } + else +@@ -349,6 +364,13 @@ + + if (!block.isAir(worldObj, j2, k, l) && block.canEntityDestroy(worldObj, j2, k, l, this)) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callEntityChangeBlockEvent(this, j2, k, l, Blocks.air, 0).isCancelled()) ++ { ++ continue; ++ } ++ ++ // CraftBukkit end + flag = this.worldObj.func_147480_a(j2, k, l, true) || flag; + } + } diff --git a/patches/net/minecraft/entity/effect/EntityLightningBolt.java.patch b/patches/net/minecraft/entity/effect/EntityLightningBolt.java.patch new file mode 100644 index 0000000..7d54c84 --- /dev/null +++ b/patches/net/minecraft/entity/effect/EntityLightningBolt.java.patch @@ -0,0 +1,100 @@ +--- ../src-base/minecraft/net/minecraft/entity/effect/EntityLightningBolt.java ++++ ../src-work/minecraft/net/minecraft/entity/effect/EntityLightningBolt.java +@@ -10,6 +10,8 @@ + import net.minecraft.world.EnumDifficulty; + import net.minecraft.world.World; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class EntityLightningBolt extends EntityWeatherEffect + { + private int lightningState; +@@ -17,15 +19,25 @@ + private int boltLivingTime; + private static final String __OBFID = "CL_00001666"; + ++ // CraftBukkit start ++ public boolean isEffect = false; ++ + public EntityLightningBolt(World p_i1703_1_, double p_i1703_2_, double p_i1703_4_, double p_i1703_6_) + { ++ this(p_i1703_1_, p_i1703_2_, p_i1703_4_, p_i1703_6_, false); ++ } ++ ++ public EntityLightningBolt(World p_i1703_1_, double p_i1703_2_, double p_i1703_4_, double p_i1703_6_, boolean isEffect) ++ { + super(p_i1703_1_); ++ this.isEffect = isEffect; ++ // CraftBukkit end + this.setLocationAndAngles(p_i1703_2_, p_i1703_4_, p_i1703_6_, 0.0F, 0.0F); + this.lightningState = 2; + this.boltVertex = this.rand.nextLong(); + this.boltLivingTime = this.rand.nextInt(3) + 1; + +- if (!p_i1703_1_.isRemote && p_i1703_1_.getGameRules().getGameRuleBooleanValue("doFireTick") && (p_i1703_1_.difficultySetting == EnumDifficulty.NORMAL || p_i1703_1_.difficultySetting == EnumDifficulty.HARD) && p_i1703_1_.doChunksNearChunkExist(MathHelper.floor_double(p_i1703_2_), MathHelper.floor_double(p_i1703_4_), MathHelper.floor_double(p_i1703_6_), 10)) ++ if (!isEffect && !p_i1703_1_.isRemote && p_i1703_1_.getGameRules().getGameRuleBooleanValue("doFireTick") && (p_i1703_1_.difficultySetting == EnumDifficulty.NORMAL || p_i1703_1_.difficultySetting == EnumDifficulty.HARD) && p_i1703_1_.doChunksNearChunkExist(MathHelper.floor_double(p_i1703_2_), MathHelper.floor_double(p_i1703_4_), MathHelper.floor_double(p_i1703_6_), 10)) // CraftBukkit + { + int i = MathHelper.floor_double(p_i1703_2_); + int j = MathHelper.floor_double(p_i1703_4_); +@@ -33,7 +45,13 @@ + + if (p_i1703_1_.getBlock(i, j, k).getMaterial() == Material.air && Blocks.fire.canPlaceBlockAt(p_i1703_1_, i, j, k)) + { +- p_i1703_1_.setBlock(i, j, k, Blocks.fire); ++ // CraftBukkit start ++ if (!CraftEventFactory.callBlockIgniteEvent(p_i1703_1_, i, j, k, this).isCancelled()) ++ { ++ p_i1703_1_.setBlock(i, j, k, Blocks.fire); ++ } ++ ++ // CraftBukkit end + } + + for (i = 0; i < 4; ++i) +@@ -44,7 +62,13 @@ + + if (p_i1703_1_.getBlock(j, k, l).getMaterial() == Material.air && Blocks.fire.canPlaceBlockAt(p_i1703_1_, j, k, l)) + { +- p_i1703_1_.setBlock(j, k, l, Blocks.fire); ++ // CraftBukkit start ++ if (!CraftEventFactory.callBlockIgniteEvent(p_i1703_1_, j, k, l, this).isCancelled()) ++ { ++ p_i1703_1_.setBlock(j, k, l, Blocks.fire); ++ } ++ ++ // CraftBukkit end + } + } + } +@@ -74,7 +98,8 @@ + this.lightningState = 1; + this.boltVertex = this.rand.nextLong(); + +- if (!this.worldObj.isRemote && this.worldObj.getGameRules().getGameRuleBooleanValue("doFireTick") && this.worldObj.doChunksNearChunkExist(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ), 10)) ++ // CraftBukkit ++ if (!isEffect && !this.worldObj.isRemote && this.worldObj.getGameRules().getGameRuleBooleanValue("doFireTick") && this.worldObj.doChunksNearChunkExist(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ), 10)) + { + int i = MathHelper.floor_double(this.posX); + int j = MathHelper.floor_double(this.posY); +@@ -82,13 +107,19 @@ + + if (this.worldObj.getBlock(i, j, k).getMaterial() == Material.air && Blocks.fire.canPlaceBlockAt(this.worldObj, i, j, k)) + { +- this.worldObj.setBlock(i, j, k, Blocks.fire); ++ // CraftBukkit start ++ if (!CraftEventFactory.callBlockIgniteEvent(worldObj, i, j, k, this).isCancelled()) ++ { ++ this.worldObj.setBlock(i, j, k, Blocks.fire); ++ } ++ ++ // CraftBukkit end + } + } + } + } + +- if (this.lightningState >= 0) ++ if (this.lightningState >= 0 && !this.isEffect) // CraftBukkit - add !this.isEffect + { + if (this.worldObj.isRemote) + { diff --git a/patches/net/minecraft/entity/item/EntityBoat.java.patch b/patches/net/minecraft/entity/item/EntityBoat.java.patch new file mode 100644 index 0000000..b2b026a --- /dev/null +++ b/patches/net/minecraft/entity/item/EntityBoat.java.patch @@ -0,0 +1,239 @@ +--- ../src-base/minecraft/net/minecraft/entity/item/EntityBoat.java ++++ ../src-work/minecraft/net/minecraft/entity/item/EntityBoat.java +@@ -17,6 +17,16 @@ + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.Location; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.entity.Vehicle; ++import org.bukkit.event.vehicle.VehicleDamageEvent; ++import org.bukkit.event.vehicle.VehicleDestroyEvent; ++import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; ++import org.bukkit.event.vehicle.VehicleMoveEvent; ++// CraftBukkit end ++ + public class EntityBoat extends Entity + { + private boolean isBoatEmpty; +@@ -35,6 +45,32 @@ + private double velocityZ; + private static final String __OBFID = "CL_00001667"; + ++ // CraftBukkit start ++ public double maxSpeed = 0.4D; ++ public double occupiedDeceleration = 0.2D; ++ public double unoccupiedDeceleration = -1; ++ public boolean landBoats = false; ++ ++ @Override ++ ++ /** ++ * Applies a velocity to each of the entities pushing them away from each other. Args: entity ++ */ ++ public void applyEntityCollision(Entity entity) ++ { ++ org.bukkit.entity.Entity hitEntity = (entity == null) ? null : entity.getBukkitEntity(); ++ VehicleEntityCollisionEvent event = new VehicleEntityCollisionEvent((Vehicle) this.getBukkitEntity(), hitEntity); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ ++ super.applyEntityCollision(entity); ++ } ++ // CraftBukkit end ++ + public EntityBoat(World p_i1704_1_) + { + super(p_i1704_1_); +@@ -82,6 +118,7 @@ + this.prevPosX = p_i1705_2_; + this.prevPosY = p_i1705_4_; + this.prevPosZ = p_i1705_6_; ++ this.worldObj.getServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleCreateEvent((Vehicle) this.getBukkitEntity())); // CraftBukkit + } + + public double getMountedYOffset() +@@ -97,6 +134,19 @@ + } + else if (!this.worldObj.isRemote && !this.isDead) + { ++ // CraftBukkit start ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ org.bukkit.entity.Entity attacker = (p_70097_1_.getEntity() == null) ? null : p_70097_1_.getEntity().getBukkitEntity(); ++ VehicleDamageEvent event = new VehicleDamageEvent(vehicle, attacker, (double) p_70097_2_); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return true; ++ } ++ ++ // f = event.getDamage(); // TODO Why don't we do this? ++ // CraftBukkit end + this.setForwardDirection(-this.getForwardDirection()); + this.setTimeSinceHit(10); + this.setDamageTaken(this.getDamageTaken() + p_70097_2_ * 10.0F); +@@ -105,6 +155,18 @@ + + if (flag || this.getDamageTaken() > 40.0F) + { ++ // CraftBukkit start ++ VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, attacker); ++ this.worldObj.getServer().getPluginManager().callEvent(destroyEvent); ++ ++ if (destroyEvent.isCancelled()) ++ { ++ this.setDamageTaken(40F); // Maximize damage so this doesn't get triggered again right away ++ return true; ++ } ++ ++ // CraftBukkit end ++ + if (this.riddenByEntity != null) + { + this.riddenByEntity.mountEntity(this); +@@ -181,6 +243,13 @@ + + public void onUpdate() + { ++ // CraftBukkit start ++ double prevX = this.posX; ++ double prevY = this.posY; ++ double prevZ = this.posZ; ++ float prevYaw = this.rotationYaw; ++ float prevPitch = this.rotationPitch; ++ // CraftBukkit end + super.onUpdate(); + + if (this.getTimeSinceHit() > 0) +@@ -303,7 +372,25 @@ + this.motionX += -Math.sin((double)(f * (float)Math.PI / 180.0F)) * this.speedMultiplier * (double)entitylivingbase.moveForward * 0.05000000074505806D; + this.motionZ += Math.cos((double)(f * (float)Math.PI / 180.0F)) * this.speedMultiplier * (double)entitylivingbase.moveForward * 0.05000000074505806D; + } ++ // CraftBukkit start - Support unoccupied deceleration ++ else if (unoccupiedDeceleration >= 0) ++ { ++ this.motionX *= unoccupiedDeceleration; ++ this.motionZ *= unoccupiedDeceleration; + ++ // Kill lingering speed ++ if (motionX <= 0.00001) ++ { ++ motionX = 0; ++ } ++ ++ if (motionZ <= 0.00001) ++ { ++ motionZ = 0; ++ } ++ } ++ ++ // CraftBukkit end + d2 = Math.sqrt(this.motionX * this.motionX + this.motionZ * this.motionZ); + + if (d2 > 0.35D) +@@ -347,18 +434,32 @@ + + if (block == Blocks.snow_layer) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callEntityChangeBlockEvent(this, i1, k, j, Blocks.air, 0).isCancelled()) ++ { ++ continue; ++ } ++ ++ // CraftBukkit end + this.worldObj.setBlockToAir(i1, k, j); + this.isCollidedHorizontally = false; + } + else if (block == Blocks.waterlily) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callEntityChangeBlockEvent(this, i1, k, j, Blocks.air, 0).isCancelled()) ++ { ++ continue; ++ } ++ ++ // CraftBukkit end + this.worldObj.func_147480_a(i1, k, j, true); + this.isCollidedHorizontally = false; + } + } + } + +- if (this.onGround) ++ if (this.onGround && !this.landBoats) // CraftBukkit + { + this.motionX *= 0.5D; + this.motionY *= 0.5D; +@@ -371,17 +472,27 @@ + { + if (!this.worldObj.isRemote && !this.isDead) + { +- this.setDead(); ++ // CraftBukkit start ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, null); ++ this.worldObj.getServer().getPluginManager().callEvent(destroyEvent); + +- for (l = 0; l < 3; ++l) ++ if (!destroyEvent.isCancelled()) + { +- this.func_145778_a(Item.getItemFromBlock(Blocks.planks), 1, 0.0F); +- } ++ this.setDead(); + +- for (l = 0; l < 2; ++l) +- { +- this.func_145778_a(Items.stick, 1, 0.0F); ++ for (l = 0; l < 3; ++l) ++ { ++ this.func_145778_a(Item.getItemFromBlock(Blocks.planks), 1, 0.0F); ++ } ++ ++ for (l = 0; l < 2; ++l) ++ { ++ this.func_145778_a(Items.stick, 1, 0.0F); ++ } + } ++ ++ // CraftBukkit end + } + } + else +@@ -415,7 +526,22 @@ + + this.rotationYaw = (float)((double)this.rotationYaw + d7); + this.setRotation(this.rotationYaw, this.rotationPitch); ++ // CraftBukkit start ++ org.bukkit.Server server = this.worldObj.getServer(); ++ org.bukkit.World bworld = this.worldObj.getWorld(); ++ Location from = new Location(bworld, prevX, prevY, prevZ, prevYaw, prevPitch); ++ Location to = new Location(bworld, this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ server.getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle)); + ++ if (!from.equals(to)) ++ { ++ VehicleMoveEvent event = new VehicleMoveEvent(vehicle, from, to); ++ server.getPluginManager().callEvent(event); ++ } ++ ++ // CraftBukkit end ++ + if (!this.worldObj.isRemote) + { + List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, this.boundingBox.expand(0.20000000298023224D, 0.0D, 0.20000000298023224D)); +@@ -435,6 +561,7 @@ + + if (this.riddenByEntity != null && this.riddenByEntity.isDead) + { ++ this.riddenByEntity.ridingEntity = null; // CraftBukkit + this.riddenByEntity = null; + } + } diff --git a/patches/net/minecraft/entity/item/EntityEnderCrystal.java.patch b/patches/net/minecraft/entity/item/EntityEnderCrystal.java.patch new file mode 100644 index 0000000..33daf81 --- /dev/null +++ b/patches/net/minecraft/entity/item/EntityEnderCrystal.java.patch @@ -0,0 +1,49 @@ +--- ../src-base/minecraft/net/minecraft/entity/item/EntityEnderCrystal.java ++++ ../src-work/minecraft/net/minecraft/entity/item/EntityEnderCrystal.java +@@ -10,6 +10,8 @@ + import net.minecraft.world.World; + import net.minecraft.world.WorldProviderEnd; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class EntityEnderCrystal extends Entity + { + public int innerRotation; +@@ -56,7 +58,13 @@ + + if (this.worldObj.provider instanceof WorldProviderEnd && this.worldObj.getBlock(i, j, k) != Blocks.fire) + { +- this.worldObj.setBlock(i, j, k, Blocks.fire); ++ // CraftBukkit start ++ if (!CraftEventFactory.callBlockIgniteEvent(this.worldObj, i, j, k, this).isCancelled()) ++ { ++ this.worldObj.setBlock(i, j, k, Blocks.fire); ++ } ++ ++ // CraftBukkit end + } + } + +@@ -85,6 +93,13 @@ + { + if (!this.isDead && !this.worldObj.isRemote) + { ++ // CraftBukkit start - All non-living entities need this ++ if (CraftEventFactory.handleNonLivingEntityDamageEvent(this, p_70097_1_, p_70097_2_)) ++ { ++ return false; ++ } ++ ++ // CraftBukkit end + this.health = 0; + + if (this.health <= 0) +@@ -93,7 +108,7 @@ + + if (!this.worldObj.isRemote) + { +- this.worldObj.createExplosion((Entity)null, this.posX, this.posY, this.posZ, 6.0F, true); ++ this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, 6.0F, true); // CraftBukkit - (Entity) null -> this + } + } + } diff --git a/patches/net/minecraft/entity/item/EntityEnderPearl.java.patch b/patches/net/minecraft/entity/item/EntityEnderPearl.java.patch new file mode 100644 index 0000000..113f501 --- /dev/null +++ b/patches/net/minecraft/entity/item/EntityEnderPearl.java.patch @@ -0,0 +1,56 @@ +--- ../src-base/minecraft/net/minecraft/entity/item/EntityEnderPearl.java ++++ ../src-work/minecraft/net/minecraft/entity/item/EntityEnderPearl.java +@@ -12,6 +12,12 @@ + import net.minecraftforge.common.MinecraftForge; + import net.minecraftforge.event.entity.living.EnderTeleportEvent; + ++// CraftBukkit start ++import org.bukkit.Bukkit; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.player.PlayerTeleportEvent; ++// CraftBukkit end ++ + public class EntityEnderPearl extends EntityThrowable + { + private static final String __OBFID = "CL_00001725"; +@@ -52,18 +58,31 @@ + + if (entityplayermp.playerNetServerHandler.func_147362_b().isChannelOpen() && entityplayermp.worldObj == this.worldObj) + { +- EnderTeleportEvent event = new EnderTeleportEvent(entityplayermp, this.posX, this.posY, this.posZ, 5.0F); +- if (!MinecraftForge.EVENT_BUS.post(event)) +- { // Don't indent to lower patch size +- if (this.getThrower().isRiding()) +- { +- this.getThrower().mountEntity((Entity)null); ++ EnderTeleportEvent event = new EnderTeleportEvent(entityplayermp, this.posX, this.posY, this.posZ, 5); ++ // Cauldron start - invert condition; return if cancelled otherwise fall through to CB event ++ if (MinecraftForge.EVENT_BUS.post(event)){ ++ this.setDead(); ++ return; + } ++ // Cauldron end ++ // CraftBukkit start ++ org.bukkit.craftbukkit.entity.CraftPlayer player = entityplayermp.getBukkitEntity(); ++ org.bukkit.Location location = getBukkitEntity().getLocation(); ++ location.setPitch(player.getLocation().getPitch()); ++ location.setYaw(player.getLocation().getYaw()); ++ PlayerTeleportEvent teleEvent = new PlayerTeleportEvent(player, player.getLocation(), location, PlayerTeleportEvent.TeleportCause.ENDER_PEARL); ++ Bukkit.getPluginManager().callEvent(teleEvent); + +- this.getThrower().setPositionAndUpdate(event.targetX, event.targetY, event.targetZ); +- this.getThrower().fallDistance = 0.0F; +- this.getThrower().attackEntityFrom(DamageSource.fall, event.attackDamage); ++ if (!teleEvent.isCancelled() && !entityplayermp.playerNetServerHandler.isDisconnected()) ++ { ++ entityplayermp.playerNetServerHandler.teleport(teleEvent.getTo()); ++ this.getThrower().fallDistance = 0.0F; ++ CraftEventFactory.entityDamage = this; ++ this.getThrower().attackEntityFrom(DamageSource.fall, 5.0F); ++ CraftEventFactory.entityDamage = null; + } ++ ++ // CraftBukkit end + } + } + diff --git a/patches/net/minecraft/entity/item/EntityExpBottle.java.patch b/patches/net/minecraft/entity/item/EntityExpBottle.java.patch new file mode 100644 index 0000000..bcf22d0 --- /dev/null +++ b/patches/net/minecraft/entity/item/EntityExpBottle.java.patch @@ -0,0 +1,24 @@ +--- ../src-base/minecraft/net/minecraft/entity/item/EntityExpBottle.java ++++ ../src-work/minecraft/net/minecraft/entity/item/EntityExpBottle.java +@@ -43,9 +43,20 @@ + { + if (!this.worldObj.isRemote) + { +- this.worldObj.playAuxSFX(2002, (int)Math.round(this.posX), (int)Math.round(this.posY), (int)Math.round(this.posZ), 0); ++ // CraftBukkit moved after event ++ //this.worldObj.playAuxSFX(2002, (int)Math.round(this.posX), (int)Math.round(this.posY), (int)Math.round(this.posZ), 0); + int i = 3 + this.worldObj.rand.nextInt(5) + this.worldObj.rand.nextInt(5); ++ // CraftBukkit start ++ org.bukkit.event.entity.ExpBottleEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callExpBottleEvent(this, i); ++ i = event.getExperience(); + ++ if (event.getShowEffect()) ++ { ++ this.worldObj.playAuxSFX(2002, (int) Math.round(this.posX), (int) Math.round(this.posY), (int) Math.round(this.posZ), 0); ++ } ++ ++ // CraftBukkit end ++ + while (i > 0) + { + int j = EntityXPOrb.getXPSplit(i); diff --git a/patches/net/minecraft/entity/item/EntityFallingBlock.java.patch b/patches/net/minecraft/entity/item/EntityFallingBlock.java.patch new file mode 100644 index 0000000..b2d2850 --- /dev/null +++ b/patches/net/minecraft/entity/item/EntityFallingBlock.java.patch @@ -0,0 +1,57 @@ +--- ../src-base/minecraft/net/minecraft/entity/item/EntityFallingBlock.java ++++ ../src-work/minecraft/net/minecraft/entity/item/EntityFallingBlock.java +@@ -19,9 +19,11 @@ + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class EntityFallingBlock extends Entity + { +- private Block field_145811_e; ++ public Block field_145811_e; // CraftBukkit - private -> public + public int field_145814_a; + public int field_145812_b; + public boolean field_145813_c; +@@ -103,7 +105,8 @@ + + if (this.field_145812_b == 1) + { +- if (this.worldObj.getBlock(i, j, k) != this.field_145811_e) ++ // CraftBukkit - compare data and call event ++ if (this.field_145812_b != 1 || this.worldObj.getBlock(i, j, k) != this.field_145811_e || this.worldObj.getBlockMetadata(i, j, k) != this.field_145814_a || CraftEventFactory.callEntityChangeBlockEvent(this, i, j, k, Blocks.air, 0).isCancelled()) + { + this.setDead(); + return; +@@ -122,8 +125,17 @@ + { + this.setDead(); + +- if (!this.field_145808_f && this.worldObj.canPlaceEntityOnSide(this.field_145811_e, i, j, k, true, 1, (Entity)null, (ItemStack)null) && !BlockFalling.func_149831_e(this.worldObj, i, j - 1, k) && this.worldObj.setBlock(i, j, k, this.field_145811_e, this.field_145814_a, 3)) ++ // CraftBukkit start ++ if (!this.field_145808_f && this.worldObj.canPlaceEntityOnSide(this.field_145811_e, i, j, k, true, 1, (Entity) null, (ItemStack) null) && !BlockFalling.func_149831_e(this.worldObj, i, j - 1, k) /* mimic the false conditions of setTypeIdAndData */ && i >= -30000000 && k >= -30000000 && i < 30000000 && k < 30000000 && j > 0 && j < 256 && !(this.worldObj.getBlock(i, j, k) == this.field_145811_e && this.worldObj.getBlockMetadata(i, j, k) == this.field_145814_a)) + { ++ if (CraftEventFactory.callEntityChangeBlockEvent(this, i, j, k, this.field_145811_e, this.field_145814_a).isCancelled()) ++ { ++ return; ++ } ++ ++ this.worldObj.setBlock(i, j, k, this.field_145811_e, this.field_145814_a, 3); ++ // CraftBukkit end ++ + if (this.field_145811_e instanceof BlockFalling) + { + ((BlockFalling)this.field_145811_e).func_149828_a(this.worldObj, i, j, k, this.field_145814_a); +@@ -189,8 +201,10 @@ + + while (iterator.hasNext()) + { +- Entity entity = (Entity)iterator.next(); +- entity.attackEntityFrom(damagesource, (float)Math.min(MathHelper.floor_float((float)i * this.field_145816_i), this.field_145815_h)); ++ Entity entity = (Entity) iterator.next(); ++ CraftEventFactory.entityDamage = this; // CraftBukkit ++ entity.attackEntityFrom(damagesource,(float) Math.min(MathHelper.floor_float((float) i * this.field_145816_i), this.field_145815_h)); ++ CraftEventFactory.entityDamage = null; // CraftBukkit + } + + if (flag && (double)this.rand.nextFloat() < 0.05000000074505806D + (double)i * 0.05D) diff --git a/patches/net/minecraft/entity/item/EntityFireworkRocket.java.patch b/patches/net/minecraft/entity/item/EntityFireworkRocket.java.patch new file mode 100644 index 0000000..f0ce86b --- /dev/null +++ b/patches/net/minecraft/entity/item/EntityFireworkRocket.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/entity/item/EntityFireworkRocket.java ++++ ../src-work/minecraft/net/minecraft/entity/item/EntityFireworkRocket.java +@@ -11,7 +11,7 @@ + public class EntityFireworkRocket extends Entity + { + private int fireworkAge; +- private int lifetime; ++ public int lifetime; // CraftBukkit - private -> public + private static final String __OBFID = "CL_00001718"; + + public EntityFireworkRocket(World p_i1762_1_) diff --git a/patches/net/minecraft/entity/item/EntityItem.java.patch b/patches/net/minecraft/entity/item/EntityItem.java.patch new file mode 100644 index 0000000..02441af --- /dev/null +++ b/patches/net/minecraft/entity/item/EntityItem.java.patch @@ -0,0 +1,280 @@ +--- ../src-base/minecraft/net/minecraft/entity/item/EntityItem.java ++++ ../src-work/minecraft/net/minecraft/entity/item/EntityItem.java +@@ -22,6 +22,11 @@ + import cpw.mods.fml.common.FMLCommonHandler; + import cpw.mods.fml.common.eventhandler.Event.Result; + ++// CraftBukkit start ++import org.bukkit.event.player.PlayerPickupItemEvent; ++import net.minecraft.server.MinecraftServer; ++// CraftBukkit end ++ + public class EntityItem extends Entity + { + private static final Logger logger = LogManager.getLogger(); +@@ -31,6 +36,7 @@ + private String field_145801_f; + private String field_145802_g; + public float hoverStart; ++ private int lastTick = MinecraftServer.currentTick; // CraftBukkit + private static final String __OBFID = "CL_00001669"; + + /** +@@ -55,6 +61,15 @@ + public EntityItem(World p_i1710_1_, double p_i1710_2_, double p_i1710_4_, double p_i1710_6_, ItemStack p_i1710_8_) + { + this(p_i1710_1_, p_i1710_2_, p_i1710_4_, p_i1710_6_); ++ ++ // CraftBukkit start - Can't set null items in the datawatcher ++ if (p_i1710_8_ == null || p_i1710_8_.getItem() == null) ++ { ++ return; ++ } ++ ++ // CraftBukkit end ++ + this.setEntityItemStack(p_i1710_8_); + this.lifespan = (p_i1710_8_.getItem() == null ? 6000 : p_i1710_8_.getItem().getEntityLifespan(p_i1710_8_, p_i1710_1_)); + } +@@ -89,93 +104,102 @@ + } + } + +- if (this.getEntityItem() == null) +- { +- this.setDead(); ++ super.onUpdate(); ++ // CraftBukkit start - Use wall time for pickup and despawn timers ++ int elapsedTicks = MinecraftServer.currentTick - this.lastTick; ++ this.delayBeforeCanPickup -= elapsedTicks; ++ this.age += elapsedTicks; ++ this.lastTick = MinecraftServer.currentTick; ++ // CraftBukkit end ++ ++ boolean forceUpdate = this.ticksExisted > 0 && this.ticksExisted % 25 == 0; // Cauldron - optimize item tick updates ++ this.prevPosX = this.posX; ++ this.prevPosY = this.posY; ++ this.prevPosZ = this.posZ; ++ this.motionY -= 0.03999999910593033D; ++ // Cauldron start - if forced ++ if (forceUpdate || noClip) { ++ this.noClip = this.func_145771_j(this.posX, (this.boundingBox.minY + this.boundingBox.maxY) / 2.0D, this.posZ); + } +- else +- { +- super.onUpdate(); ++ // Cauldron end ++ this.moveEntity(this.motionX, this.motionY, this.motionZ); ++ boolean flag = (int)this.prevPosX != (int)this.posX || (int)this.prevPosY != (int)this.posY || (int)this.prevPosZ != (int)this.posZ; + +- if (this.delayBeforeCanPickup > 0) ++ if ((flag && this.ticksExisted % 5 == 0) || forceUpdate) // Cauldron - if forced ++ { ++ if (this.worldObj.getBlock(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)).getMaterial() == Material.lava) + { +- --this.delayBeforeCanPickup; ++ this.motionY = 0.20000000298023224D; ++ this.motionX = (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F); ++ this.motionZ = (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F); ++ this.playSound("random.fizz", 0.4F, 2.0F + this.rand.nextFloat() * 0.4F); + } + +- this.prevPosX = this.posX; +- this.prevPosY = this.posY; +- this.prevPosZ = this.posZ; +- this.motionY -= 0.03999999910593033D; +- this.noClip = this.func_145771_j(this.posX, (this.boundingBox.minY + this.boundingBox.maxY) / 2.0D, this.posZ); +- this.moveEntity(this.motionX, this.motionY, this.motionZ); +- boolean flag = (int)this.prevPosX != (int)this.posX || (int)this.prevPosY != (int)this.posY || (int)this.prevPosZ != (int)this.posZ; +- +- if (flag || this.ticksExisted % 25 == 0) ++ if (forceUpdate && !this.worldObj.isRemote) // Cauldron - if forced + { +- if (this.worldObj.getBlock(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.posY), MathHelper.floor_double(this.posZ)).getMaterial() == Material.lava) +- { +- this.motionY = 0.20000000298023224D; +- this.motionX = (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F); +- this.motionZ = (double)((this.rand.nextFloat() - this.rand.nextFloat()) * 0.2F); +- this.playSound("random.fizz", 0.4F, 2.0F + this.rand.nextFloat() * 0.4F); +- } +- +- if (!this.worldObj.isRemote) +- { +- this.searchForOtherItemsNearby(); +- } ++ this.searchForOtherItemsNearby(); + } ++ } + +- float f = 0.98F; ++ float f = 0.98F; + +- if (this.onGround) +- { +- f = this.worldObj.getBlock(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)).slipperiness * 0.98F; +- } ++ if (this.onGround) ++ { ++ f = this.worldObj.getBlock(MathHelper.floor_double(this.posX), MathHelper.floor_double(this.boundingBox.minY) - 1, MathHelper.floor_double(this.posZ)).slipperiness * 0.98F; ++ } + +- this.motionX *= (double)f; +- this.motionY *= 0.9800000190734863D; +- this.motionZ *= (double)f; ++ this.motionX *= (double)f; ++ this.motionY *= 0.9800000190734863D; ++ this.motionZ *= (double)f; + +- if (this.onGround) +- { +- this.motionY *= -0.5D; +- } ++ if (this.onGround) ++ { ++ this.motionY *= -0.5D; ++ } + +- ++this.age; ++ // ++this.age; // CraftBukkit - Moved up (base age on wall time) + +- ItemStack item = getDataWatcher().getWatchableObjectItemStack(10); +- +- if (!this.worldObj.isRemote && this.age >= lifespan) ++ ItemStack item = getDataWatcher().getWatchableObjectItemStack(10); ++ ++ if (!this.worldObj.isRemote && this.age >= lifespan - 1) // Cauldron adjust for age being off by one when it is first dropped ++ { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callItemDespawnEvent(this).isCancelled()) + { +- if (item != null) +- { +- ItemExpireEvent event = new ItemExpireEvent(this, (item.getItem() == null ? 6000 : item.getItem().getEntityLifespan(item, worldObj))); +- if (MinecraftForge.EVENT_BUS.post(event)) +- { +- lifespan += event.extraLife; +- } +- else +- { +- this.setDead(); +- } ++ this.age = 0; ++ return; ++ } ++ // CraftBukkit end ++ if (item != null) ++ { ++ ItemExpireEvent event = new ItemExpireEvent(this, (item.getItem() == null ? this.worldObj.getSpigotConfig().itemDespawnRate : item.getItem().getEntityLifespan(item, worldObj))); // Spigot // Cauldron ++ if (MinecraftForge.EVENT_BUS.post(event)) ++ { ++ lifespan += event.extraLife; + } + else + { + this.setDead(); + } + } +- +- if (item != null && item.stackSize <= 0) ++ else + { + this.setDead(); + } + } ++ ++ if (item != null && item.stackSize <= 0) ++ { ++ this.setDead(); ++ } + } + + private void searchForOtherItemsNearby() + { +- Iterator iterator = this.worldObj.getEntitiesWithinAABB(EntityItem.class, this.boundingBox.expand(0.5D, 0.0D, 0.5D)).iterator(); ++ // Spigot start ++ double radius = worldObj.getSpigotConfig().itemMerge; // Cauldron ++ Iterator iterator = this.worldObj.getEntitiesWithinAABB(EntityItem.class, this.boundingBox.expand(radius, radius, radius)).iterator(); ++ // Spigot end + + while (iterator.hasNext()) + { +@@ -225,11 +249,13 @@ + } + else + { +- itemstack1.stackSize += itemstack.stackSize; +- p_70289_1_.delayBeforeCanPickup = Math.max(p_70289_1_.delayBeforeCanPickup, this.delayBeforeCanPickup); +- p_70289_1_.age = Math.min(p_70289_1_.age, this.age); +- p_70289_1_.setEntityItemStack(itemstack1); +- this.setDead(); ++ // Spigot start ++ itemstack.stackSize += itemstack1.stackSize; ++ this.delayBeforeCanPickup = Math.max(p_70289_1_.delayBeforeCanPickup, this.delayBeforeCanPickup); ++ this.age = Math.min(p_70289_1_.age, this.age); ++ this.setEntityItemStack(itemstack); ++ p_70289_1_.setDead(); ++ // Spigot end + return true; + } + } +@@ -316,8 +342,27 @@ + } + + NBTTagCompound nbttagcompound1 = p_70037_1_.getCompoundTag("Item"); +- this.setEntityItemStack(ItemStack.loadItemStackFromNBT(nbttagcompound1)); + ++ // CraftBukkit start ++ if (nbttagcompound1 != null) ++ { ++ ItemStack itemstack = ItemStack.loadItemStackFromNBT(nbttagcompound1); ++ ++ if (itemstack != null) ++ { ++ this.setEntityItemStack(itemstack); ++ } ++ else ++ { ++ this.setDead(); ++ } ++ } ++ else ++ { ++ this.setDead(); ++ } ++ ++ // CraftBukkit end + ItemStack item = getDataWatcher().getWatchableObjectItemStack(10); + + if (item == null || item.stackSize <= 0) +@@ -350,6 +395,31 @@ + ItemStack itemstack = this.getEntityItem(); + int i = itemstack.stackSize; + ++ // CraftBukkit start ++ int canHold = p_70100_1_.inventory.canHold(itemstack); ++ int remaining = itemstack.stackSize - canHold; ++ ++ if (this.delayBeforeCanPickup <= 0 && canHold > 0) ++ { ++ itemstack.stackSize = canHold; ++ // Cauldron start - rename to cbEvent to fix naming collision ++ PlayerPickupItemEvent cbEvent = new PlayerPickupItemEvent((org.bukkit.entity.Player) p_70100_1_.getBukkitEntity(), (org.bukkit.entity.Item) this.getBukkitEntity(), remaining); ++ //cbEvent.setCancelled(!par1EntityPlayer.canPickUpLoot); TODO ++ this.worldObj.getServer().getPluginManager().callEvent(cbEvent); ++ itemstack.stackSize = canHold + remaining; ++ ++ if (cbEvent.isCancelled()) ++ { ++ return; ++ } ++ // Cauldron end ++ ++ // Possibly < 0; fix here so we do not have to modify code below ++ this.delayBeforeCanPickup = 0; ++ } ++ ++ // CraftBukkit end ++ + if (this.delayBeforeCanPickup <= 0 && (this.field_145802_g == null || lifespan - this.age <= 200 || this.field_145802_g.equals(p_70100_1_.getCommandSenderName())) && (event.getResult() == Result.ALLOW || i <= 0 || p_70100_1_.inventory.addItemStackToInventory(itemstack))) + { + if (itemstack.getItem() == Item.getItemFromBlock(Blocks.log)) diff --git a/patches/net/minecraft/entity/item/EntityItemFrame.java.patch b/patches/net/minecraft/entity/item/EntityItemFrame.java.patch new file mode 100644 index 0000000..a862230 --- /dev/null +++ b/patches/net/minecraft/entity/item/EntityItemFrame.java.patch @@ -0,0 +1,16 @@ +--- ../src-base/minecraft/net/minecraft/entity/item/EntityItemFrame.java ++++ ../src-work/minecraft/net/minecraft/entity/item/EntityItemFrame.java +@@ -45,6 +45,13 @@ + { + if (!this.worldObj.isRemote) + { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.handleNonLivingEntityDamageEvent(this, p_70097_1_, p_70097_2_) || this.isDead) ++ { ++ return true; ++ } ++ // CraftBukkit end ++ + this.func_146065_b(p_70097_1_.getEntity(), false); + this.setDisplayedItem((ItemStack)null); + } diff --git a/patches/net/minecraft/entity/item/EntityMinecart.java.patch b/patches/net/minecraft/entity/item/EntityMinecart.java.patch new file mode 100644 index 0000000..d082841 --- /dev/null +++ b/patches/net/minecraft/entity/item/EntityMinecart.java.patch @@ -0,0 +1,234 @@ +--- ../src-base/minecraft/net/minecraft/entity/item/EntityMinecart.java ++++ ../src-work/minecraft/net/minecraft/entity/item/EntityMinecart.java +@@ -28,6 +28,15 @@ + import net.minecraftforge.event.entity.minecart.MinecartCollisionEvent; + import net.minecraftforge.event.entity.minecart.MinecartUpdateEvent; + ++// CraftBukkit start ++import org.bukkit.Location; ++import org.bukkit.entity.Vehicle; ++import org.bukkit.event.vehicle.VehicleDamageEvent; ++import org.bukkit.event.vehicle.VehicleDestroyEvent; ++import org.bukkit.event.vehicle.VehicleEntityCollisionEvent; ++import org.bukkit.util.Vector; ++// CraftBukkit end ++ + public abstract class EntityMinecart extends Entity + { + private boolean isInReverse; +@@ -47,6 +56,17 @@ + private double velocityZ; + private static final String __OBFID = "CL_00001670"; + ++ // CraftBukkit start ++ public boolean slowWhenEmpty = true; ++ private double derailedX = 0.5D; ++ private double derailedY = 0.5D; ++ private double derailedZ = 0.5D; ++ private double flyingX = 0.95D; ++ private double flyingY = 0.95D; ++ private double flyingZ = 0.95D; ++ public double maxSpeed = 0.4D; ++ // CraftBukkit end ++ + /* Forge: Minecart Compatibility Layer Integration. */ + public static float defaultMaxSpeedAirLateral = 0.4f; + public static float defaultMaxSpeedAirVertical = -1f; +@@ -138,6 +158,7 @@ + this.prevPosX = p_i1713_2_; + this.prevPosY = p_i1713_4_; + this.prevPosZ = p_i1713_6_; ++ this.worldObj.getServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleCreateEvent((Vehicle) this.getBukkitEntity())); // CraftBukkit + } + + public double getMountedYOffset() +@@ -155,6 +176,19 @@ + } + else + { ++ // CraftBukkit start ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ org.bukkit.entity.Entity passenger = (p_70097_1_.getEntity() == null) ? null : p_70097_1_.getEntity().getBukkitEntity(); ++ VehicleDamageEvent event = new VehicleDamageEvent(vehicle, passenger, p_70097_2_); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return true; ++ } ++ ++ p_70097_2_ = (float) event.getDamage(); ++ // CraftBukkit end + this.setRollingDirection(-this.getRollingDirection()); + this.setRollingAmplitude(10); + this.setBeenAttacked(); +@@ -168,6 +202,18 @@ + this.riddenByEntity.mountEntity(this); + } + ++ // CraftBukkit start ++ VehicleDestroyEvent destroyEvent = new VehicleDestroyEvent(vehicle, passenger); ++ this.worldObj.getServer().getPluginManager().callEvent(destroyEvent); ++ ++ if (destroyEvent.isCancelled()) ++ { ++ this.setDamage(40); // Maximize damage so this doesn't ++ // get triggered again right away ++ return true; ++ } ++ // CraftBukkit end ++ + if (flag && !this.hasCustomInventoryName()) + { + this.setDead(); +@@ -220,6 +266,14 @@ + + public void onUpdate() + { ++ // CraftBukkit start ++ double prevX = this.posX; ++ double prevY = this.posY; ++ double prevZ = this.posZ; ++ float prevYaw = this.rotationYaw; ++ float prevPitch = this.rotationPitch; ++ // CraftBukkit end ++ + if (this.getRollingAmplitude() > 0) + { + this.setRollingAmplitude(this.getRollingAmplitude() - 1); +@@ -245,7 +299,7 @@ + + if (this.inPortal) + { +- if (minecraftserver.getAllowNether()) ++ if (true || minecraftserver.getAllowNether()) // CraftBukkit - multi-world should still allow teleport even if default vanilla nether disabled + { + if (this.ridingEntity == null && this.portalCounter++ >= i) + { +@@ -324,7 +378,7 @@ + --i; + } + +- double d0 = 0.4D; ++ double d0 = this.maxSpeed; // CraftBukkit + double d2 = 0.0078125D; + Block block = this.worldObj.getBlock(l, i, i1); + +@@ -368,7 +422,18 @@ + } + + this.setRotation(this.rotationYaw, this.rotationPitch); ++ // CraftBukkit start ++ org.bukkit.World bworld = this.worldObj.getWorld(); ++ Location from = new Location(bworld, prevX, prevY, prevZ, prevYaw, prevPitch); ++ Location to = new Location(bworld, this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ this.worldObj.getServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleUpdateEvent(vehicle)); + ++ if (!from.equals(to)) ++ { ++ this.worldObj.getServer().getPluginManager().callEvent(new org.bukkit.event.vehicle.VehicleMoveEvent(vehicle, from, to)); ++ } ++ // CraftBukkit end + AxisAlignedBB box; + if (getCollisionHandler() != null) + { +@@ -445,18 +510,22 @@ + + if (this.onGround) + { +- this.motionX *= 0.5D; +- this.motionY *= 0.5D; +- this.motionZ *= 0.5D; ++ // CraftBukkit start ++ this.motionX *= this.derailedX; ++ this.motionY *= this.derailedY; ++ this.motionZ *= this.derailedZ; ++ // CraftBukkit end + } + + this.moveEntity(this.motionX, moveY, this.motionZ); + + if (!this.onGround) + { ++ // CraftBukkit start // Cauldron - CB changed to flyingX but Forge changed to getDragAir() - prefer Forge in this case + this.motionX *= getDragAir(); + this.motionY *= getDragAir(); + this.motionZ *= getDragAir(); ++ // CraftBukkit end + } + } + +@@ -678,7 +747,7 @@ + + protected void applyDrag() + { +- if (this.riddenByEntity != null) ++ if (this.riddenByEntity != null || !this.slowWhenEmpty) // CraftBukkit + { + this.motionX *= 0.996999979019165D; + this.motionY *= 0.0D; +@@ -866,6 +935,18 @@ + { + if (p_70108_1_ != this.riddenByEntity) + { ++ // CraftBukkit start ++ Vehicle vehicle = (Vehicle) this.getBukkitEntity(); ++ org.bukkit.entity.Entity hitEntity = (p_70108_1_ == null) ? null : p_70108_1_.getBukkitEntity(); ++ VehicleEntityCollisionEvent collisionEvent = new VehicleEntityCollisionEvent(vehicle, hitEntity); ++ this.worldObj.getServer().getPluginManager().callEvent(collisionEvent); ++ ++ if (collisionEvent.isCancelled()) ++ { ++ return; ++ } ++ // CraftBukkit end ++ + if (p_70108_1_ instanceof EntityLivingBase && !(p_70108_1_ instanceof EntityPlayer) && !(p_70108_1_ instanceof EntityIronGolem) && canBeRidden() && this.motionX * this.motionX + this.motionZ * this.motionZ > 0.01D && this.riddenByEntity == null && p_70108_1_.ridingEntity == null) + { + p_70108_1_.mountEntity(this); +@@ -875,7 +956,8 @@ + double d1 = p_70108_1_.posZ - this.posZ; + double d2 = d0 * d0 + d1 * d1; + +- if (d2 >= 9.999999747378752E-5D) ++ // CraftBukkit - collision ++ if (d2 >= 9.999999747378752E-5D && !collisionEvent.isCollisionCancelled()) + { + d2 = (double)MathHelper.sqrt_double(d2); + d0 /= d2; +@@ -1089,6 +1171,34 @@ + { + return this.entityName; + } ++ ++ // CraftBukkit start - Methods for getting and setting flying and derailed ++ // velocity modifiers ++ public Vector getFlyingVelocityMod() ++ { ++ return new Vector(flyingX, flyingY, flyingZ); ++ } ++ ++ public void setFlyingVelocityMod(Vector flying) ++ { ++ flyingX = flying.getX(); ++ flyingY = flying.getY(); ++ flyingZ = flying.getZ(); ++ } ++ ++ public Vector getDerailedVelocityMod() ++ { ++ return new Vector(derailedX, derailedY, derailedZ); ++ } ++ ++ public void setDerailedVelocityMod(Vector derailed) ++ { ++ derailedX = derailed.getX(); ++ derailedY = derailed.getY(); ++ derailedZ = derailed.getZ(); ++ } ++ // CraftBukkit end ++ + /* =================================== FORGE START ===========================================*/ + /** + * Moved to allow overrides. diff --git a/patches/net/minecraft/entity/item/EntityMinecartContainer.java.patch b/patches/net/minecraft/entity/item/EntityMinecartContainer.java.patch new file mode 100644 index 0000000..0827277 --- /dev/null +++ b/patches/net/minecraft/entity/item/EntityMinecartContainer.java.patch @@ -0,0 +1,78 @@ +--- ../src-base/minecraft/net/minecraft/entity/item/EntityMinecartContainer.java ++++ ../src-work/minecraft/net/minecraft/entity/item/EntityMinecartContainer.java +@@ -9,12 +9,61 @@ + import net.minecraft.util.DamageSource; + import net.minecraft.world.World; + ++// CraftBukkit start ++import java.util.List; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++import org.bukkit.inventory.InventoryHolder; ++// CraftBukkit end ++ + public abstract class EntityMinecartContainer extends EntityMinecart implements IInventory + { + private ItemStack[] minecartContainerItems = new ItemStack[36]; + private boolean dropContentsWhenDead = true; + private static final String __OBFID = "CL_00001674"; + ++ // CraftBukkit start ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() ++ { ++ return this.minecartContainerItems; ++ } ++ ++ public void onOpen(CraftHumanEntity who) ++ { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) ++ { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() ++ { ++ return transaction; ++ } ++ ++ public InventoryHolder getOwner() ++ { ++ org.bukkit.entity.Entity cart = getBukkitEntity(); ++ ++ if (cart instanceof InventoryHolder) ++ { ++ return (InventoryHolder) cart; ++ } ++ ++ return null; ++ } ++ ++ public void setMaxStackSize(int size) ++ { ++ maxStack = size; ++ } ++ // CraftBukkit end ++ + public EntityMinecartContainer(World p_i1716_1_) + { + super(p_i1716_1_); +@@ -147,6 +196,13 @@ + + public void travelToDimension(int p_71027_1_) + { ++ // Spigot Start ++ for (HumanEntity human : new java.util.ArrayList(transaction)) ++ { ++ human.closeInventory(); ++ } ++ ++ // Spigot End + this.dropContentsWhenDead = false; + super.travelToDimension(p_71027_1_); + } diff --git a/patches/net/minecraft/entity/item/EntityPainting.java.patch b/patches/net/minecraft/entity/item/EntityPainting.java.patch new file mode 100644 index 0000000..b9c5842 --- /dev/null +++ b/patches/net/minecraft/entity/item/EntityPainting.java.patch @@ -0,0 +1,10 @@ +--- ../src-base/minecraft/net/minecraft/entity/item/EntityPainting.java ++++ ../src-work/minecraft/net/minecraft/entity/item/EntityPainting.java +@@ -19,6 +19,7 @@ + public EntityPainting(World p_i1599_1_) + { + super(p_i1599_1_); ++ this.art = EntityPainting.EnumArt.values()[this.rand.nextInt(EntityPainting.EnumArt.values().length)]; // CraftBukkit - generate a non-null painting + } + + public EntityPainting(World p_i1600_1_, int p_i1600_2_, int p_i1600_3_, int p_i1600_4_, int p_i1600_5_) diff --git a/patches/net/minecraft/entity/item/EntityTNTPrimed.java.patch b/patches/net/minecraft/entity/item/EntityTNTPrimed.java.patch new file mode 100644 index 0000000..de44908 --- /dev/null +++ b/patches/net/minecraft/entity/item/EntityTNTPrimed.java.patch @@ -0,0 +1,57 @@ +--- ../src-base/minecraft/net/minecraft/entity/item/EntityTNTPrimed.java ++++ ../src-work/minecraft/net/minecraft/entity/item/EntityTNTPrimed.java +@@ -7,11 +7,15 @@ + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.world.World; + ++import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit ++ + public class EntityTNTPrimed extends Entity + { + public int fuse; + private EntityLivingBase tntPlacedBy; + private static final String __OBFID = "CL_00001681"; ++ public float yield = 4; // CraftBukkit ++ public boolean isIncendiary = false; // CraftBukkit + + public EntityTNTPrimed(World p_i1729_1_) + { +@@ -68,12 +72,14 @@ + + if (this.fuse-- <= 0) + { +- this.setDead(); +- ++ // CraftBukkit start - Need to reverse the order of the explosion and the entity death so we have a location for the event + if (!this.worldObj.isRemote) + { + this.explode(); + } ++ ++ this.setDead(); ++ // CraftBukkit end + } + else + { +@@ -83,8 +89,19 @@ + + private void explode() + { +- float f = 4.0F; +- this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, f, true); ++ // CraftBukkit start ++ // float f = 4.0F; ++ org.bukkit.craftbukkit.CraftServer server = this.worldObj.getServer(); ++ ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) org.bukkit.craftbukkit.entity.CraftEntity.getEntity(server, this)); ++ server.getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ // give 'this' instead of (Entity) null so we know what causes the damage ++ this.worldObj.newExplosion(this, this.posX, this.posY, this.posZ, event.getRadius(), event.getFire(), true); ++ } ++ ++ // CraftBukkit end + } + + protected void writeEntityToNBT(NBTTagCompound p_70014_1_) diff --git a/patches/net/minecraft/entity/item/EntityXPOrb.java.patch b/patches/net/minecraft/entity/item/EntityXPOrb.java.patch new file mode 100644 index 0000000..5aeae47 --- /dev/null +++ b/patches/net/minecraft/entity/item/EntityXPOrb.java.patch @@ -0,0 +1,158 @@ +--- ../src-base/minecraft/net/minecraft/entity/item/EntityXPOrb.java ++++ ../src-work/minecraft/net/minecraft/entity/item/EntityXPOrb.java +@@ -12,13 +12,18 @@ + import net.minecraftforge.common.MinecraftForge; + import net.minecraftforge.event.entity.player.PlayerPickupXpEvent; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityTargetEvent; ++// CraftBukkit end ++ + public class EntityXPOrb extends Entity + { + public int xpColor; + public int xpOrbAge; + public int field_70532_c; + private int xpOrbHealth = 5; +- public int xpValue; ++ public int xpValue; // CraftBukkit - private -> public + private EntityPlayer closestPlayer; + private int xpTargetColor; + private static final String __OBFID = "CL_00001544"; +@@ -115,18 +120,27 @@ + + if (this.closestPlayer != null) + { +- double d1 = (this.closestPlayer.posX - this.posX) / d0; +- double d2 = (this.closestPlayer.posY + (double)this.closestPlayer.getEyeHeight() - this.posY) / d0; +- double d3 = (this.closestPlayer.posZ - this.posZ) / d0; +- double d4 = Math.sqrt(d1 * d1 + d2 * d2 + d3 * d3); +- double d5 = 1.0D - d4; ++ // CraftBukkit start ++ EntityTargetEvent event = CraftEventFactory.callEntityTargetEvent(this, closestPlayer, EntityTargetEvent.TargetReason.CLOSEST_PLAYER); ++ Entity target = event.getTarget() == null ? null : ((org.bukkit.craftbukkit.entity.CraftEntity) event.getTarget()).getHandle(); + +- if (d5 > 0.0D) ++ if (!event.isCancelled() && target != null) + { +- d5 *= d5; +- this.motionX += d1 / d4 * d5 * 0.1D; +- this.motionY += d2 / d4 * d5 * 0.1D; +- this.motionZ += d3 / d4 * d5 * 0.1D; ++ double d1 = (target.posX - this.posX) / d0; ++ double d2 = (target.posY + (double) target.getEyeHeight() - this.posY) / d0; ++ double d3 = (target.posZ - this.posZ) / d0; ++ double d4 = Math.sqrt(d1 * d1 + d2 * d2 + d3 * d3); ++ double d5 = 1.0D - d4; ++ ++ if (d5 > 0.0D) ++ { ++ d5 *= d5; ++ this.motionX += d1 / d4 * d5 * 0.1D; ++ this.motionY += d2 / d4 * d5 * 0.1D; ++ this.motionZ += d3 / d4 * d5 * 0.1D; ++ } ++ ++ // CraftBukkit end + } + } + +@@ -210,7 +224,7 @@ + p_70100_1_.xpCooldown = 2; + this.worldObj.playSoundAtEntity(p_70100_1_, "random.orb", 0.1F, 0.5F * ((this.rand.nextFloat() - this.rand.nextFloat()) * 0.7F + 1.8F)); + p_70100_1_.onItemPickup(this, 1); +- p_70100_1_.addExperience(this.xpValue); ++ p_70100_1_.addExperience(CraftEventFactory.callPlayerExpChangeEvent(p_70100_1_, this.xpValue).getAmount()); + this.setDead(); + } + } +@@ -229,6 +243,88 @@ + + public static int getXPSplit(int p_70527_0_) + { ++ // CraftBukkit start ++ if (p_70527_0_ > 162670129) ++ { ++ return p_70527_0_ - 100000; ++ } ++ ++ if (p_70527_0_ > 81335063) ++ { ++ return 81335063; ++ } ++ ++ if (p_70527_0_ > 40667527) ++ { ++ return 40667527; ++ } ++ ++ if (p_70527_0_ > 20333759) ++ { ++ return 20333759; ++ } ++ ++ if (p_70527_0_ > 10166857) ++ { ++ return 10166857; ++ } ++ ++ if (p_70527_0_ > 5083423) ++ { ++ return 5083423; ++ } ++ ++ if (p_70527_0_ > 2541701) ++ { ++ return 2541701; ++ } ++ ++ if (p_70527_0_ > 1270849) ++ { ++ return 1270849; ++ } ++ ++ if (p_70527_0_ > 635413) ++ { ++ return 635413; ++ } ++ ++ if (p_70527_0_ > 317701) ++ { ++ return 317701; ++ } ++ ++ if (p_70527_0_ > 158849) ++ { ++ return 158849; ++ } ++ ++ if (p_70527_0_ > 79423) ++ { ++ return 79423; ++ } ++ ++ if (p_70527_0_ > 39709) ++ { ++ return 39709; ++ } ++ ++ if (p_70527_0_ > 19853) ++ { ++ return 19853; ++ } ++ ++ if (p_70527_0_ > 9923) ++ { ++ return 9923; ++ } ++ ++ if (p_70527_0_ > 4957) ++ { ++ return 4957; ++ } ++ ++ // CraftBukkit end + return p_70527_0_ >= 2477 ? 2477 : (p_70527_0_ >= 1237 ? 1237 : (p_70527_0_ >= 617 ? 617 : (p_70527_0_ >= 307 ? 307 : (p_70527_0_ >= 149 ? 149 : (p_70527_0_ >= 73 ? 73 : (p_70527_0_ >= 37 ? 37 : (p_70527_0_ >= 17 ? 17 : (p_70527_0_ >= 7 ? 7 : (p_70527_0_ >= 3 ? 3 : 1))))))))); + } + diff --git a/patches/net/minecraft/entity/monster/EntityCreeper.java.patch b/patches/net/minecraft/entity/monster/EntityCreeper.java.patch new file mode 100644 index 0000000..c4c0d3a --- /dev/null +++ b/patches/net/minecraft/entity/monster/EntityCreeper.java.patch @@ -0,0 +1,78 @@ +--- ../src-base/minecraft/net/minecraft/entity/monster/EntityCreeper.java ++++ ../src-work/minecraft/net/minecraft/entity/monster/EntityCreeper.java +@@ -23,6 +23,11 @@ + import net.minecraft.util.DamageSource; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.ExplosionPrimeEvent; ++// CraftBukkit end ++ + public class EntityCreeper extends EntityMob + { + private int lastActiveTime; +@@ -207,9 +212,35 @@ + public void onStruckByLightning(EntityLightningBolt p_70077_1_) + { + super.onStruckByLightning(p_70077_1_); +- this.dataWatcher.updateObject(17, Byte.valueOf((byte)1)); ++ ++ // Cauldron start ++ if (p_70077_1_ != null) ++ { ++ // CraftBukkit start ++ if (CraftEventFactory.callCreeperPowerEvent(this, p_70077_1_, org.bukkit.event.entity.CreeperPowerEvent.PowerCause.LIGHTNING).isCancelled()) ++ { ++ return; ++ } ++ } ++ // Cauldron end ++ ++ this.setPowered(true); + } + ++ public void setPowered(boolean powered) ++ { ++ if (!powered) ++ { ++ this.dataWatcher.updateObject(17, Byte.valueOf((byte) 0)); ++ } ++ else ++ { ++ this.dataWatcher.updateObject(17, Byte.valueOf((byte) 1)); ++ } ++ ++ // CraftBukkit end ++ } ++ + protected boolean interact(EntityPlayer p_70085_1_) + { + ItemStack itemstack = p_70085_1_.inventory.getCurrentItem(); +@@ -235,17 +266,22 @@ + if (!this.worldObj.isRemote) + { + boolean flag = this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing"); ++ // CraftBukkit start ++ float radius = this.getPowered() ? 6.0F : 3.0F; ++ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), radius, false); ++ this.worldObj.getServer().getPluginManager().callEvent(event); + +- if (this.getPowered()) ++ if (!event.isCancelled()) + { +- this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)(this.explosionRadius * 2), flag); ++ this.worldObj.newExplosion(this, this.posX, this.posY, this.posZ, event.getRadius(), event.getFire(), flag); ++ this.setDead(); + } + else + { +- this.worldObj.createExplosion(this, this.posX, this.posY, this.posZ, (float)this.explosionRadius, flag); ++ this.timeSinceIgnited = 0; + } + +- this.setDead(); ++ // CraftBukkit end + } + } + diff --git a/patches/net/minecraft/entity/monster/EntityEnderman.java.patch b/patches/net/minecraft/entity/monster/EntityEnderman.java.patch new file mode 100644 index 0000000..ebc90de --- /dev/null +++ b/patches/net/minecraft/entity/monster/EntityEnderman.java.patch @@ -0,0 +1,72 @@ +--- ../src-base/minecraft/net/minecraft/entity/monster/EntityEnderman.java ++++ ../src-work/minecraft/net/minecraft/entity/monster/EntityEnderman.java +@@ -24,6 +24,12 @@ + import net.minecraftforge.common.MinecraftForge; + import net.minecraftforge.event.entity.living.EnderTeleportEvent; + ++// CraftBukkit start ++import org.bukkit.Location; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityTeleportEvent; ++// CraftBukkit end ++ + public class EntityEnderman extends EntityMob + { + private static final UUID attackingSpeedBoostModifierUUID = UUID.fromString("020E0DFB-87AE-4653-9556-831010E291A0"); +@@ -161,9 +167,15 @@ + + if (EntityEnderman.getCarriable(block)) + { +- this.func_146081_a(block); +- this.setCarryingData(this.worldObj.getBlockMetadata(k, i, j)); +- this.worldObj.setBlock(k, i, j, Blocks.air); ++ // CraftBukkit start - Pickup event ++ if (this.worldObj.getWorld() == null || !CraftEventFactory.callEntityChangeBlockEvent(this, this.worldObj.getWorld().getBlockAt(i, j, k), org.bukkit.Material.AIR).isCancelled()) // Cauldron ++ { ++ this.func_146081_a(block); ++ this.setCarryingData(this.worldObj.getBlockMetadata(i, j, k)); ++ this.worldObj.setBlock(i, j, k, Blocks.air); ++ } ++ ++ // CraftBukkit end + } + } + } +@@ -177,8 +189,14 @@ + + if (block.getMaterial() == Material.air && block1.getMaterial() != Material.air && block1.renderAsNormalBlock()) + { +- this.worldObj.setBlock(k, i, j, this.func_146080_bZ(), this.getCarryingData(), 3); +- this.func_146081_a(Blocks.air); ++ // CraftBukkit start - Place event ++ if (!CraftEventFactory.callEntityChangeBlockEvent(this, i, j, k, this.func_146080_bZ(), this.getCarryingData()).isCancelled()) ++ { ++ this.worldObj.setBlock(i, j, k, this.func_146080_bZ(), this.getCarryingData(), 3); ++ this.func_146081_a(Blocks.air); ++ } ++ ++ // CraftBukkit end + } + } + } +@@ -306,8 +324,19 @@ + + if (flag1) + { +- this.setPosition(this.posX, this.posY, this.posZ); ++ // CraftBukkit start - Teleport event ++ EntityTeleportEvent teleport = new EntityTeleportEvent(this.getBukkitEntity(), new Location(this.worldObj.getWorld(), d3, d4, d5), new Location(this.worldObj.getWorld(), this.posX, this.posY, this.posZ)); ++ this.worldObj.getServer().getPluginManager().callEvent(teleport); + ++ if (teleport.isCancelled()) ++ { ++ return false; ++ } ++ ++ Location to = teleport.getTo(); ++ this.setPosition(to.getX(), to.getY(), to.getZ()); ++ // CraftBukkit end ++ + if (this.worldObj.getCollidingBoundingBoxes(this, this.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(this.boundingBox)) + { + flag = true; diff --git a/patches/net/minecraft/entity/monster/EntityGhast.java.patch b/patches/net/minecraft/entity/monster/EntityGhast.java.patch new file mode 100644 index 0000000..d0662ae --- /dev/null +++ b/patches/net/minecraft/entity/monster/EntityGhast.java.patch @@ -0,0 +1,77 @@ +--- ../src-base/minecraft/net/minecraft/entity/monster/EntityGhast.java ++++ ../src-work/minecraft/net/minecraft/entity/monster/EntityGhast.java +@@ -18,6 +18,11 @@ + import net.minecraft.world.EnumDifficulty; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.entity.CraftEntity; ++import org.bukkit.event.entity.EntityTargetEvent; ++// CraftBukkit end ++ + public class EntityGhast extends EntityFlying implements IMob + { + public int courseChangeCooldown; +@@ -117,13 +122,50 @@ + + if (this.targetedEntity != null && this.targetedEntity.isDead) + { +- this.targetedEntity = null; ++ // CraftBukkit start ++ EntityTargetEvent event = new EntityTargetEvent(this.getBukkitEntity(), null, EntityTargetEvent.TargetReason.TARGET_DIED); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ if (event.getTarget() == null) ++ { ++ this.targetedEntity = null; ++ } ++ else ++ { ++ this.targetedEntity = ((CraftEntity) event.getTarget()).getHandle(); ++ } ++ } ++ ++ // CraftBukkit end + } + + if (this.targetedEntity == null || this.aggroCooldown-- <= 0) + { +- this.targetedEntity = this.worldObj.getClosestVulnerablePlayerToEntity(this, 100.0D); ++ // CraftBukkit start ++ Entity target = this.worldObj.getClosestVulnerablePlayerToEntity(this, 100.0D); + ++ if (target != null) ++ { ++ EntityTargetEvent event = new EntityTargetEvent(this.getBukkitEntity(), target.getBukkitEntity(), EntityTargetEvent.TargetReason.CLOSEST_PLAYER); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ if (event.getTarget() == null) ++ { ++ this.targetedEntity = null; ++ } ++ else ++ { ++ this.targetedEntity = ((CraftEntity) event.getTarget()).getHandle(); ++ } ++ } ++ } ++ ++ // CraftBukkit end ++ + if (this.targetedEntity != null) + { + this.aggroCooldown = 20; +@@ -152,7 +194,8 @@ + { + this.worldObj.playAuxSFXAtEntity((EntityPlayer)null, 1008, (int)this.posX, (int)this.posY, (int)this.posZ, 0); + EntityLargeFireball entitylargefireball = new EntityLargeFireball(this.worldObj, this, d5, d6, d7); +- entitylargefireball.field_92057_e = this.explosionStrength; ++ // CraftBukkit - set bukkitYield when setting explosionpower ++ entitylargefireball.bukkitYield = entitylargefireball.field_92057_e = this.explosionStrength; + double d8 = 4.0D; + Vec3 vec3 = this.getLook(1.0F); + entitylargefireball.posX = this.posX + vec3.xCoord * d8; diff --git a/patches/net/minecraft/entity/monster/EntityMob.java.patch b/patches/net/minecraft/entity/monster/EntityMob.java.patch new file mode 100644 index 0000000..0cb0f12 --- /dev/null +++ b/patches/net/minecraft/entity/monster/EntityMob.java.patch @@ -0,0 +1,40 @@ +--- ../src-base/minecraft/net/minecraft/entity/monster/EntityMob.java ++++ ../src-work/minecraft/net/minecraft/entity/monster/EntityMob.java +@@ -1,5 +1,6 @@ + package net.minecraft.entity.monster; + ++import org.bukkit.event.entity.EntityTargetEvent; // CraftBukkit + import net.minecraft.enchantment.EnchantmentHelper; + import net.minecraft.entity.Entity; + import net.minecraft.entity.EntityCreature; +@@ -75,7 +76,29 @@ + { + if (entity != this) + { +- this.entityToAttack = entity; ++ // CraftBukkit start - We still need to call events for entities without goals ++ if (entity != this.entityToAttack && (this instanceof EntityBlaze || this instanceof EntityEnderman || this instanceof EntitySpider || this instanceof EntityGiantZombie || this instanceof EntitySilverfish)) ++ { ++ EntityTargetEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTargetEvent(this, entity, EntityTargetEvent.TargetReason.TARGET_ATTACKED_ENTITY); ++ ++ if (!event.isCancelled()) ++ { ++ if (event.getTarget() == null) ++ { ++ this.entityToAttack = null; ++ } ++ else ++ { ++ this.entityToAttack = ((org.bukkit.craftbukkit.entity.CraftEntity) event.getTarget()).getHandle(); ++ } ++ } ++ } ++ else ++ { ++ this.entityToAttack = entity; ++ } ++ ++ // CraftBukkit end + } + + return true; diff --git a/patches/net/minecraft/entity/monster/EntityPigZombie.java.patch b/patches/net/minecraft/entity/monster/EntityPigZombie.java.patch new file mode 100644 index 0000000..d712abb --- /dev/null +++ b/patches/net/minecraft/entity/monster/EntityPigZombie.java.patch @@ -0,0 +1,42 @@ +--- ../src-base/minecraft/net/minecraft/entity/monster/EntityPigZombie.java ++++ ../src-work/minecraft/net/minecraft/entity/monster/EntityPigZombie.java +@@ -15,11 +15,13 @@ + import net.minecraft.world.EnumDifficulty; + import net.minecraft.world.World; + ++import org.bukkit.event.entity.EntityTargetEvent; // CraftBukkit ++ + public class EntityPigZombie extends EntityZombie + { + private static final UUID field_110189_bq = UUID.fromString("49455A49-7EC5-45BA-B886-3B90B23A1718"); + private static final AttributeModifier field_110190_br = (new AttributeModifier(field_110189_bq, "Attacking speed boost", 0.45D, 0)).setSaved(false); +- private int angerLevel; ++ public int angerLevel; // CraftBukkit - private -> public + private int randomSoundDelay; + private Entity field_110191_bu; + private static final String __OBFID = "CL_00001693"; +@@ -122,6 +124,24 @@ + + private void becomeAngryAt(Entity p_70835_1_) + { ++ // CraftBukkit start ++ org.bukkit.entity.Entity bukkitTarget = p_70835_1_ == null ? null : p_70835_1_.getBukkitEntity(); ++ EntityTargetEvent event = new EntityTargetEvent(this.getBukkitEntity(), bukkitTarget, EntityTargetEvent.TargetReason.PIG_ZOMBIE_TARGET); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ ++ if (event.getTarget() == null) ++ { ++ this.entityToAttack = null; ++ return; ++ } ++ ++ p_70835_1_ = ((org.bukkit.craftbukkit.entity.CraftEntity) event.getTarget()).getHandle(); ++ // CraftBukkit end + this.entityToAttack = p_70835_1_; + this.angerLevel = 400 + this.rand.nextInt(400); + this.randomSoundDelay = this.rand.nextInt(40); diff --git a/patches/net/minecraft/entity/monster/EntitySilverfish.java.patch b/patches/net/minecraft/entity/monster/EntitySilverfish.java.patch new file mode 100644 index 0000000..59d7184 --- /dev/null +++ b/patches/net/minecraft/entity/monster/EntitySilverfish.java.patch @@ -0,0 +1,39 @@ +--- ../src-base/minecraft/net/minecraft/entity/monster/EntitySilverfish.java ++++ ../src-work/minecraft/net/minecraft/entity/monster/EntitySilverfish.java +@@ -15,6 +15,8 @@ + import net.minecraft.world.World; + import org.apache.commons.lang3.tuple.ImmutablePair; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class EntitySilverfish extends EntityMob + { + private int allySummonCooldown; +@@ -132,6 +134,13 @@ + { + if (this.worldObj.getBlock(i + i1, j + l, k + j1) == Blocks.monster_egg) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callEntityChangeBlockEvent(this, i + i1, j + l, k + j1, Blocks.air, 0).isCancelled()) ++ { ++ continue; ++ } ++ ++ // CraftBukkit end + if (!this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")) + { + int k1 = this.worldObj.getBlockMetadata(i + i1, j + l, k + j1); +@@ -168,6 +177,13 @@ + + if (BlockSilverfish.func_150196_a(block)) + { ++ // CraftBukkit start ++ if (CraftEventFactory.callEntityChangeBlockEvent(this, i + Facing.offsetsXForSide[l1], j + Facing.offsetsYForSide[l1], k + Facing.offsetsZForSide[l1], Blocks.monster_egg, Block.getIdFromBlock(BlockSilverfish.getBlockById(i1))).isCancelled()) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + this.worldObj.setBlock(i + Facing.offsetsXForSide[l1], j + Facing.offsetsYForSide[l1], k + Facing.offsetsZForSide[l1], Blocks.monster_egg, BlockSilverfish.func_150195_a(block, i1), 3); + this.spawnExplosionParticle(); + this.setDead(); diff --git a/patches/net/minecraft/entity/monster/EntitySkeleton.java.patch b/patches/net/minecraft/entity/monster/EntitySkeleton.java.patch new file mode 100644 index 0000000..383d7fb --- /dev/null +++ b/patches/net/minecraft/entity/monster/EntitySkeleton.java.patch @@ -0,0 +1,54 @@ +--- ../src-base/minecraft/net/minecraft/entity/monster/EntitySkeleton.java ++++ ../src-work/minecraft/net/minecraft/entity/monster/EntitySkeleton.java +@@ -36,6 +36,8 @@ + import net.minecraft.world.World; + import net.minecraft.world.WorldProviderHell; + ++import org.bukkit.event.entity.EntityCombustEvent; // CraftBukkit ++ + public class EntitySkeleton extends EntityMob implements IRangedAttackMob + { + private EntityAIArrowAttack aiArrowAttack = new EntityAIArrowAttack(this, 1.0D, 20, 60, 15.0F); +@@ -148,7 +150,16 @@ + + if (flag) + { +- this.setFire(8); ++ // CraftBukkit start ++ EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity(), 8); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ this.setFire(event.getDuration()); ++ } ++ ++ // CraftBukkit end + } + } + } +@@ -312,8 +323,23 @@ + entityarrow.setFire(100); + } + ++ // CraftBukkit start ++ org.bukkit.event.entity.EntityShootBowEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(this, this.getHeldItem(), entityarrow, 0.8F); ++ ++ if (event.isCancelled()) ++ { ++ event.getProjectile().remove(); ++ return; ++ } ++ ++ if (event.getProjectile() == entityarrow.getBukkitEntity()) ++ { ++ worldObj.spawnEntityInWorld(entityarrow); ++ } ++ ++ // CraftBukkit end + this.playSound("random.bow", 1.0F, 1.0F / (this.getRNG().nextFloat() * 0.4F + 0.8F)); +- this.worldObj.spawnEntityInWorld(entityarrow); ++ // this.worldObj.spawnEntityInWorld(entityarrow); // CraftBukkit - moved up + } + + public int getSkeletonType() diff --git a/patches/net/minecraft/entity/monster/EntitySlime.java.patch b/patches/net/minecraft/entity/monster/EntitySlime.java.patch new file mode 100644 index 0000000..fb20188 --- /dev/null +++ b/patches/net/minecraft/entity/monster/EntitySlime.java.patch @@ -0,0 +1,94 @@ +--- ../src-base/minecraft/net/minecraft/entity/monster/EntitySlime.java ++++ ../src-work/minecraft/net/minecraft/entity/monster/EntitySlime.java +@@ -14,12 +14,21 @@ + import net.minecraft.world.biome.BiomeGenBase; + import net.minecraft.world.chunk.Chunk; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.entity.CraftEntity; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityTargetEvent; ++import org.bukkit.event.entity.SlimeSplitEvent; ++import net.minecraft.entity.Entity; ++// CraftBukkit end ++ + public class EntitySlime extends EntityLiving implements IMob + { + public float squishAmount; + public float squishFactor; + public float prevSquishFactor; + private int slimeJumpDelay; ++ private Entity lastTarget; // CraftBukkit + private static final String __OBFID = "CL_00001698"; + + public EntitySlime(World p_i1742_1_) +@@ -37,7 +46,7 @@ + this.dataWatcher.addObject(16, new Byte((byte)1)); + } + +- protected void setSlimeSize(int p_70799_1_) ++ public void setSlimeSize(int p_70799_1_) // CraftBukkit - protected -> public + { + this.dataWatcher.updateObject(16, new Byte((byte)p_70799_1_)); + this.setSize(0.6F * (float)p_70799_1_, 0.6F * (float)p_70799_1_); +@@ -131,8 +140,27 @@ + protected void updateEntityActionState() + { + this.despawnEntity(); +- EntityPlayer entityplayer = this.worldObj.getClosestVulnerablePlayerToEntity(this, 16.0D); ++ // CraftBukkit start ++ Entity entityplayer = this.worldObj.getClosestVulnerablePlayerToEntity(this, 16.0D); // EntityPlayer -> Entity ++ EntityTargetEvent event = null; + ++ if (entityplayer != null && !entityplayer.equals(lastTarget)) ++ { ++ event = CraftEventFactory.callEntityTargetEvent(this, entityplayer, EntityTargetEvent.TargetReason.CLOSEST_PLAYER); ++ } ++ else if (lastTarget != null && entityplayer == null) ++ { ++ event = CraftEventFactory.callEntityTargetEvent(this, entityplayer, EntityTargetEvent.TargetReason.FORGOT_TARGET); ++ } ++ ++ if (event != null && !event.isCancelled()) ++ { ++ entityplayer = event.getTarget() == null ? null : ((CraftEntity) event.getTarget()).getHandle(); ++ } ++ ++ this.lastTarget = entityplayer; ++ // CraftBukkit end ++ + if (entityplayer != null) + { + this.faceEntity(entityplayer, 10.0F, 20.0F); +@@ -190,7 +218,22 @@ + if (!this.worldObj.isRemote && i > 1 && this.getHealth() <= 0.0F) + { + int j = 2 + this.rand.nextInt(3); ++ // CraftBukkit start ++ SlimeSplitEvent event = new SlimeSplitEvent((org.bukkit.entity.Slime) this.getBukkitEntity(), j); ++ this.worldObj.getServer().getPluginManager().callEvent(event); + ++ if (!event.isCancelled() && event.getCount() > 0) ++ { ++ j = event.getCount(); ++ } ++ else ++ { ++ super.setDead(); ++ return; ++ } ++ ++ // CraftBukkit end ++ + for (int k = 0; k < j; ++k) + { + float f = ((float)(k % 2) - 0.5F) * (float)i / 4.0F; +@@ -198,7 +241,7 @@ + EntitySlime entityslime = this.createInstance(); + entityslime.setSlimeSize(i / 2); + entityslime.setLocationAndAngles(this.posX + (double)f, this.posY + 0.5D, this.posZ + (double)f1, this.rand.nextFloat() * 360.0F, 0.0F); +- this.worldObj.spawnEntityInWorld(entityslime); ++ this.worldObj.addEntity(entityslime, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SLIME_SPLIT); // CraftBukkit - SpawnReason + } + } + diff --git a/patches/net/minecraft/entity/monster/EntitySnowman.java.patch b/patches/net/minecraft/entity/monster/EntitySnowman.java.patch new file mode 100644 index 0000000..5aad01e --- /dev/null +++ b/patches/net/minecraft/entity/monster/EntitySnowman.java.patch @@ -0,0 +1,44 @@ +--- ../src-base/minecraft/net/minecraft/entity/monster/EntitySnowman.java ++++ ../src-work/minecraft/net/minecraft/entity/monster/EntitySnowman.java +@@ -19,6 +19,12 @@ + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import org.bukkit.event.block.EntityBlockFormEvent; ++// CraftBukkit end ++ + public class EntitySnowman extends EntityGolem implements IRangedAttackMob + { + private static final String __OBFID = "CL_00001650"; +@@ -61,7 +67,7 @@ + + if (this.worldObj.getBiomeGenForCoords(i, k).getFloatTemperature(i, j, k) > 1.0F) + { +- this.attackEntityFrom(DamageSource.onFire, 1.0F); ++ this.attackEntityFrom(CraftEventFactory.MELTING, 1.0F); // CraftBukkit - DamageSource.BURN -> CraftEventFactory.MELTING + } + + for (int l = 0; l < 4; ++l) +@@ -72,7 +78,18 @@ + + if (this.worldObj.getBlock(i, j, k).getMaterial() == Material.air && this.worldObj.getBiomeGenForCoords(i, k).getFloatTemperature(i, j, k) < 0.8F && Blocks.snow_layer.canPlaceBlockAt(this.worldObj, i, j, k)) + { +- this.worldObj.setBlock(i, j, k, Blocks.snow_layer); ++ // CraftBukkit start ++ org.bukkit.block.BlockState blockState = this.worldObj.getWorld().getBlockAt(i, j, k).getState(); ++ blockState.setType(CraftMagicNumbers.getMaterial(Blocks.snow_layer)); ++ EntityBlockFormEvent event = new EntityBlockFormEvent(this.getBukkitEntity(), blockState.getBlock(), blockState); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ blockState.update(true); ++ } ++ ++ // CraftBukkit end + } + } + } diff --git a/patches/net/minecraft/entity/monster/EntitySpider.java.patch b/patches/net/minecraft/entity/monster/EntitySpider.java.patch new file mode 100644 index 0000000..19bfbf8 --- /dev/null +++ b/patches/net/minecraft/entity/monster/EntitySpider.java.patch @@ -0,0 +1,38 @@ +--- ../src-base/minecraft/net/minecraft/entity/monster/EntitySpider.java ++++ ../src-work/minecraft/net/minecraft/entity/monster/EntitySpider.java +@@ -14,6 +14,8 @@ + import net.minecraft.world.EnumDifficulty; + import net.minecraft.world.World; + ++import org.bukkit.event.entity.EntityTargetEvent; // CraftBukkit ++ + public class EntitySpider extends EntityMob + { + private static final String __OBFID = "CL_00001699"; +@@ -88,7 +90,25 @@ + + if (f1 > 0.5F && this.rand.nextInt(100) == 0) + { +- this.entityToAttack = null; ++ // CraftBukkit start ++ EntityTargetEvent event = new EntityTargetEvent(this.getBukkitEntity(), null, EntityTargetEvent.TargetReason.FORGOT_TARGET); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ if (event.getTarget() == null) ++ { ++ this.entityToAttack = null; ++ } ++ else ++ { ++ this.entityToAttack = ((org.bukkit.craftbukkit.entity.CraftEntity) event.getTarget()).getHandle(); ++ } ++ ++ return; ++ } ++ ++ // CraftBukkit end + } + else + { diff --git a/patches/net/minecraft/entity/monster/EntityZombie.java.patch b/patches/net/minecraft/entity/monster/EntityZombie.java.patch new file mode 100644 index 0000000..9c7bbb5 --- /dev/null +++ b/patches/net/minecraft/entity/monster/EntityZombie.java.patch @@ -0,0 +1,109 @@ +--- ../src-base/minecraft/net/minecraft/entity/monster/EntityZombie.java ++++ ../src-work/minecraft/net/minecraft/entity/monster/EntityZombie.java +@@ -46,6 +46,13 @@ + import net.minecraftforge.event.ForgeEventFactory; + import net.minecraftforge.event.entity.living.ZombieEvent.SummonAidEvent; + ++//CraftBukkit start ++import net.minecraft.server.MinecraftServer; ++import org.bukkit.craftbukkit.entity.CraftLivingEntity; ++import org.bukkit.event.entity.EntityCombustByEntityEvent; ++import org.bukkit.event.entity.EntityCombustEvent; ++//CraftBukkit end ++ + public class EntityZombie extends EntityMob + { + protected static final IAttribute field_110186_bp = (new RangedAttribute("zombie.spawnReinforcements", 0.0D, 0.0D, 1.0D)).setDescription("Spawn Reinforcements Chance"); +@@ -56,6 +63,7 @@ + private boolean field_146076_bu = false; + private float field_146074_bv = -1.0F; + private float field_146073_bw; ++ private int lastTick = MinecraftServer.currentTick; // CraftBukkit + private static final String __OBFID = "CL_00001702"; + + public EntityZombie(World p_i1745_1_) +@@ -64,7 +72,12 @@ + this.getNavigator().setBreakDoors(true); + this.tasks.addTask(0, new EntityAISwimming(this)); + this.tasks.addTask(2, new EntityAIAttackOnCollide(this, EntityPlayer.class, 1.0D, false)); +- this.tasks.addTask(4, new EntityAIAttackOnCollide(this, EntityVillager.class, 1.0D, true)); ++ ++ if (p_i1745_1_.getSpigotConfig().zombieAggressiveTowardsVillager) // Cauldron ++ { ++ this.tasks.addTask(4, new EntityAIAttackOnCollide(this, EntityVillager.class, 1.0D, true)); // Spigot ++ } ++ + this.tasks.addTask(5, new EntityAIMoveTowardsRestriction(this, 1.0D)); + this.tasks.addTask(6, new EntityAIMoveThroughVillage(this, 1.0D, false)); + this.tasks.addTask(7, new EntityAIWander(this, 1.0D)); +@@ -72,7 +85,12 @@ + this.tasks.addTask(8, new EntityAILookIdle(this)); + this.targetTasks.addTask(1, new EntityAIHurtByTarget(this, true)); + this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityPlayer.class, 0, true)); +- this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityVillager.class, 0, false)); ++ ++ if (p_i1745_1_.getSpigotConfig().zombieAggressiveTowardsVillager) // Cauldron ++ { ++ this.targetTasks.addTask(2, new EntityAINearestAttackableTarget(this, EntityVillager.class, 0, false)); // Spigot ++ } ++ + this.setSize(0.6F, 1.8F); + } + +@@ -204,7 +222,16 @@ + + if (flag) + { +- this.setFire(8); ++ // CraftBukkit start ++ EntityCombustEvent event = new EntityCombustEvent(this.getBukkitEntity(), 8); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ this.setFire(event.getDuration()); ++ } ++ ++ // CraftBukkit end + } + } + } +@@ -272,7 +299,7 @@ + + if (this.worldObj.checkNoEntityCollision(entityzombie.boundingBox) && this.worldObj.getCollidingBoundingBoxes(entityzombie, entityzombie.boundingBox).isEmpty() && !this.worldObj.isAnyLiquid(entityzombie.boundingBox)) + { +- this.worldObj.spawnEntityInWorld(entityzombie); ++ this.worldObj.addEntity(entityzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.REINFORCEMENTS); // CraftBukkit + if (entitylivingbase != null) entityzombie.setAttackTarget(entitylivingbase); + entityzombie.onSpawnWithEgg((IEntityLivingData)null); + this.getEntityAttribute(field_110186_bp).applyModifier(new AttributeModifier("Zombie reinforcement caller charge", -0.05000000074505806D, 0)); +@@ -292,6 +319,11 @@ + if (!this.worldObj.isRemote && this.isConverting()) + { + int i = this.getConversionTimeBoost(); ++ // CraftBukkit start - Use wall time instead of ticks for villager conversion ++ int elapsedTicks = MinecraftServer.currentTick - this.lastTick; ++ this.lastTick = MinecraftServer.currentTick; ++ i *= elapsedTicks; ++ // CraftBukkit end + this.conversionTime -= i; + + if (this.conversionTime <= 0) +@@ -313,7 +345,16 @@ + + if (this.getHeldItem() == null && this.isBurning() && this.rand.nextFloat() < (float)i * 0.3F) + { +- p_70652_1_.setFire(2 * i); ++ // CraftBukkit start ++ EntityCombustByEntityEvent event = new EntityCombustByEntityEvent(this.getBukkitEntity(), p_70652_1_.getBukkitEntity(), 2 * i); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ p_70652_1_.setFire(event.getDuration()); ++ } ++ ++ // CraftBukkit end + } + } + diff --git a/patches/net/minecraft/entity/passive/EntityCow.java.patch b/patches/net/minecraft/entity/passive/EntityCow.java.patch new file mode 100644 index 0000000..2852437 --- /dev/null +++ b/patches/net/minecraft/entity/passive/EntityCow.java.patch @@ -0,0 +1,42 @@ +--- ../src-base/minecraft/net/minecraft/entity/passive/EntityCow.java ++++ ../src-work/minecraft/net/minecraft/entity/passive/EntityCow.java +@@ -17,6 +17,11 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++// CraftBukkit end ++ + public class EntityCow extends EntityAnimal + { + private static final String __OBFID = "CL_00001640"; +@@ -109,15 +114,25 @@ + + if (itemstack != null && itemstack.getItem() == Items.bucket && !p_70085_1_.capabilities.isCreativeMode) + { ++ // CraftBukkit start - Got milk? ++ org.bukkit.Location loc = this.getBukkitEntity().getLocation(); ++ org.bukkit.event.player.PlayerBucketFillEvent event = CraftEventFactory.callPlayerBucketFillEvent(p_70085_1_, loc.getBlockX(), loc.getBlockY(), loc.getBlockZ(), -1, itemstack, Items.milk_bucket); ++ ++ if (event.isCancelled()) ++ { ++ return false; ++ } ++ + if (itemstack.stackSize-- == 1) + { +- p_70085_1_.inventory.setInventorySlotContents(p_70085_1_.inventory.currentItem, new ItemStack(Items.milk_bucket)); ++ p_70085_1_.inventory.setInventorySlotContents(p_70085_1_.inventory.currentItem, CraftItemStack.asNMSCopy(event.getItemStack())); + } + else if (!p_70085_1_.inventory.addItemStackToInventory(new ItemStack(Items.milk_bucket))) + { +- p_70085_1_.dropPlayerItemWithRandomChoice(new ItemStack(Items.milk_bucket, 1, 0), false); ++ p_70085_1_.dropPlayerItemWithRandomChoice(CraftItemStack.asNMSCopy(event.getItemStack()), false); + } + ++ // CraftBukkit end + return true; + } + else diff --git a/patches/net/minecraft/entity/passive/EntityHorse.java.patch b/patches/net/minecraft/entity/passive/EntityHorse.java.patch new file mode 100644 index 0000000..22a4a79 --- /dev/null +++ b/patches/net/minecraft/entity/passive/EntityHorse.java.patch @@ -0,0 +1,134 @@ +--- ../src-base/minecraft/net/minecraft/entity/passive/EntityHorse.java ++++ ../src-work/minecraft/net/minecraft/entity/passive/EntityHorse.java +@@ -50,7 +50,7 @@ + return p_82704_1_ instanceof EntityHorse && ((EntityHorse)p_82704_1_).func_110205_ce(); + } + }; +- private static final IAttribute horseJumpStrength = (new RangedAttribute("horse.jumpStrength", 0.7D, 0.0D, 2.0D)).setDescription("Jump Strength").setShouldWatch(true); ++ public static final IAttribute horseJumpStrength = (new RangedAttribute("horse.jumpStrength", 0.7D, 0.0D, 2.0D)).setDescription("Jump Strength").setShouldWatch(true); // CraftBukkit - private -> public + private static final String[] horseArmorTextures = new String[] {null, "textures/entity/horse/armor/horse_armor_iron.png", "textures/entity/horse/armor/horse_armor_gold.png", "textures/entity/horse/armor/horse_armor_diamond.png"}; + private static final String[] field_110273_bx = new String[] {"", "meo", "goo", "dio"}; + private static final int[] armorValues = new int[] {0, 5, 7, 11}; +@@ -64,7 +64,7 @@ + public int field_110278_bp; + public int field_110279_bq; + protected boolean horseJumping; +- private AnimalChest horseChest; ++ public AnimalChest horseChest; // CraftBukkit - private -> public + private boolean hasReproduced; + protected int temper; + protected float jumpPower; +@@ -78,6 +78,7 @@ + private int field_110285_bP; + private String field_110286_bQ; + private String[] field_110280_bR = new String[3]; ++ public int maxDomestication = 100; // CraftBukkit - store max domestication value + private static final String __OBFID = "CL_00001641"; + + public EntityHorse(World p_i1685_1_) +@@ -403,13 +404,13 @@ + private int func_110225_cC() + { + int i = this.getHorseType(); +- return this.isChested() && (i == 1 || i == 2) ? 17 : 2; ++ return this.isChested() /* && (i == 1 || i == 2) */ ? 17 : 2; // CraftBukkit - Remove type check + } + +- private void func_110226_cD() ++ public void func_110226_cD() // CraftBukkit - private -> public + { + AnimalChest animalchest = this.horseChest; +- this.horseChest = new AnimalChest("HorseChest", this.func_110225_cC()); ++ this.horseChest = new AnimalChest("HorseChest", this.func_110225_cC(), this); // CraftBukkit - add this horse + this.horseChest.func_110133_a(this.getCommandSenderName()); + + if (animalchest != null) +@@ -950,12 +951,25 @@ + { + super.onDeath(p_70645_1_); + ++ /* CraftBukkit start - Handle chest dropping in dropFewItems below + if (!this.worldObj.isRemote) + { + this.dropChestItems(); + } ++ // CraftBukkit end */ + } + ++ // CraftBukkit start - Add method ++ protected void dropFewItems(boolean flag, int i) { ++ super.dropFewItems(flag, i); ++ ++ // Moved from die method above ++ if (!this.worldObj.isRemote) { ++ this.dropChestItems(); ++ } ++ } ++ // CraftBukkit end ++ + public void onLivingUpdate() + { + if (this.rand.nextInt(200) == 0) +@@ -1278,6 +1292,7 @@ + p_70014_1_.setInteger("Temper", this.getTemper()); + p_70014_1_.setBoolean("Tame", this.isTame()); + p_70014_1_.setString("OwnerUUID", this.func_152119_ch()); ++ p_70014_1_.setInteger("Bukkit.MaxDomestication", this.maxDomestication); // CraftBukkit + + if (this.isChested()) + { +@@ -1327,6 +1342,13 @@ + this.func_152120_b(p_70037_1_.getString("OwnerUUID")); + } + ++ // CraftBukkit start ++ if (p_70037_1_.hasKey("Bukkit.MaxDomestication")) ++ { ++ this.maxDomestication = p_70037_1_.getInteger("Bukkit.MaxDomestication"); ++ } ++ ++ // CraftBukkit end + IAttributeInstance iattributeinstance = this.getAttributeMap().getAttributeInstanceByName("Speed"); + + if (iattributeinstance != null) +@@ -1566,24 +1588,33 @@ + { + if (this.isHorseSaddled()) + { ++ // CraftBukkit start - fire HorseJumpEvent, use event power + if (p_110206_1_ < 0) + { + p_110206_1_ = 0; + } +- else +- { +- this.field_110294_bI = true; +- this.makeHorseRear(); +- } + ++ float power; ++ + if (p_110206_1_ >= 90) + { +- this.jumpPower = 1.0F; ++ power = 1.0F; + } + else + { +- this.jumpPower = 0.4F + 0.4F * (float)p_110206_1_ / 90.0F; ++ power = 0.4F + 0.4F * (float)p_110206_1_ / 90.0F; + } ++ ++ org.bukkit.event.entity.HorseJumpEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callHorseJumpEvent(this, power); ++ ++ if (!event.isCancelled()) ++ { ++ this.field_110294_bI = true; ++ this.makeHorseRear(); ++ this.jumpPower = event.getPower(); ++ } ++ ++ // CraftBukkit end + } + } + diff --git a/patches/net/minecraft/entity/passive/EntityMooshroom.java.patch b/patches/net/minecraft/entity/passive/EntityMooshroom.java.patch new file mode 100644 index 0000000..787b01a --- /dev/null +++ b/patches/net/minecraft/entity/passive/EntityMooshroom.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/entity/passive/EntityMooshroom.java ++++ ../src-work/minecraft/net/minecraft/entity/passive/EntityMooshroom.java +@@ -12,6 +12,8 @@ + import net.minecraft.world.World; + import net.minecraftforge.common.IShearable; + ++import org.bukkit.event.player.PlayerShearEntityEvent; // CraftBukkit ++ + public class EntityMooshroom extends EntityCow implements IShearable + { + private static final String __OBFID = "CL_00001645"; diff --git a/patches/net/minecraft/entity/passive/EntityOcelot.java.patch b/patches/net/minecraft/entity/passive/EntityOcelot.java.patch new file mode 100644 index 0000000..4f679f9 --- /dev/null +++ b/patches/net/minecraft/entity/passive/EntityOcelot.java.patch @@ -0,0 +1,21 @@ +--- ../src-base/minecraft/net/minecraft/entity/passive/EntityOcelot.java ++++ ../src-work/minecraft/net/minecraft/entity/passive/EntityOcelot.java +@@ -89,7 +89,7 @@ + + protected boolean canDespawn() + { +- return !this.isTamed() && this.ticksExisted > 2400; ++ return !this.isTamed(); // CraftBukkit + } + + public boolean isAIEnabled() +@@ -188,7 +188,8 @@ + + if (!this.worldObj.isRemote) + { +- if (this.rand.nextInt(3) == 0) ++ // CraftBukkit - added event call and isCancelled check ++ if (this.rand.nextInt(3) == 0 && !org.bukkit.craftbukkit.event.CraftEventFactory.callEntityTameEvent(this, p_70085_1_).isCancelled()) + { + this.setTamed(true); + this.setTameSkin(1 + this.worldObj.rand.nextInt(3)); diff --git a/patches/net/minecraft/entity/passive/EntityPig.java.patch b/patches/net/minecraft/entity/passive/EntityPig.java.patch new file mode 100644 index 0000000..f0e0780 --- /dev/null +++ b/patches/net/minecraft/entity/passive/EntityPig.java.patch @@ -0,0 +1,36 @@ +--- ../src-base/minecraft/net/minecraft/entity/passive/EntityPig.java ++++ ../src-work/minecraft/net/minecraft/entity/passive/EntityPig.java +@@ -22,6 +22,8 @@ + import net.minecraft.stats.AchievementList; + import net.minecraft.world.World; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class EntityPig extends EntityAnimal + { + private final EntityAIControlledByPlayer aiControlledByPlayer; +@@ -171,9 +173,23 @@ + if (!this.worldObj.isRemote) + { + EntityPigZombie entitypigzombie = new EntityPigZombie(this.worldObj); ++ ++ // Cauldron start ++ if (p_70077_1_ != null) ++ { ++ // CraftBukkit start ++ if (CraftEventFactory.callPigZapEvent(this, p_70077_1_, entitypigzombie).isCancelled()) ++ { ++ return; ++ } ++ ++ // CraftBukkit end ++ } ++ // Cauldron end + entitypigzombie.setCurrentItemOrArmor(0, new ItemStack(Items.golden_sword)); + entitypigzombie.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); +- this.worldObj.spawnEntityInWorld(entitypigzombie); ++ // CraftBukkit - added a reason for spawning this creature ++ this.worldObj.addEntity(entitypigzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.LIGHTNING); + this.setDead(); + } + } diff --git a/patches/net/minecraft/entity/passive/EntitySheep.java.patch b/patches/net/minecraft/entity/passive/EntitySheep.java.patch new file mode 100644 index 0000000..916146e --- /dev/null +++ b/patches/net/minecraft/entity/passive/EntitySheep.java.patch @@ -0,0 +1,42 @@ +--- ../src-base/minecraft/net/minecraft/entity/passive/EntitySheep.java ++++ ../src-work/minecraft/net/minecraft/entity/passive/EntitySheep.java +@@ -32,6 +32,12 @@ + import net.minecraft.world.World; + import net.minecraftforge.common.IShearable; + ++// CraftBukkit start ++import net.minecraft.inventory.InventoryCraftResult; ++import org.bukkit.event.entity.SheepRegrowWoolEvent; ++import org.bukkit.event.player.PlayerShearEntityEvent; ++// CraftBukkit end ++ + public class EntitySheep extends EntityAnimal implements IShearable + { + private final InventoryCrafting field_90016_e = new InventoryCrafting(new Container() +@@ -63,6 +69,7 @@ + this.tasks.addTask(8, new EntityAILookIdle(this)); + this.field_90016_e.setInventorySlotContents(0, new ItemStack(Items.dye, 1, 0)); + this.field_90016_e.setInventorySlotContents(1, new ItemStack(Items.dye, 1, 0)); ++ this.field_90016_e.resultInventory = new InventoryCraftResult(); // CraftBukkit - add result slot for event + } + + protected boolean isAIEnabled() +@@ -231,8 +238,17 @@ + + public void eatGrassBonus() + { +- this.setSheared(false); ++ // CraftBukkit start ++ SheepRegrowWoolEvent event = new SheepRegrowWoolEvent((org.bukkit.entity.Sheep) this.getBukkitEntity()); ++ this.worldObj.getServer().getPluginManager().callEvent(event); + ++ if (!event.isCancelled()) ++ { ++ this.setSheared(false); ++ } ++ ++ // CraftBukkit end ++ + if (this.isChild()) + { + this.addGrowth(60); diff --git a/patches/net/minecraft/entity/passive/EntitySquid.java.patch b/patches/net/minecraft/entity/passive/EntitySquid.java.patch new file mode 100644 index 0000000..2436cc8 --- /dev/null +++ b/patches/net/minecraft/entity/passive/EntitySquid.java.patch @@ -0,0 +1,39 @@ +--- ../src-base/minecraft/net/minecraft/entity/passive/EntitySquid.java ++++ ../src-work/minecraft/net/minecraft/entity/passive/EntitySquid.java +@@ -8,6 +8,8 @@ + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; + ++import org.bukkit.craftbukkit.TrigMath; // CraftBukkit ++ + public class EntitySquid extends EntityWaterMob + { + public float squidPitch; +@@ -79,10 +81,12 @@ + } + } + ++ /* CraftBukkit start - Delegate to Entity to use existing inWater value + public boolean isInWater() + { + return this.worldObj.handleMaterialAcceleration(this.boundingBox.expand(0.0D, -0.6000000238418579D, 0.0D), Material.water, this); + } ++ // CraftBukkit end */ + + public void onLivingUpdate() + { +@@ -137,10 +141,12 @@ + } + + f = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); +- this.renderYawOffset += (-((float)Math.atan2(this.motionX, this.motionZ)) * 180.0F / (float)Math.PI - this.renderYawOffset) * 0.1F; ++ // CraftBukkit - Math -> TrigMath ++ this.renderYawOffset += (-((float) TrigMath.atan2(this.motionX, this.motionZ)) * 180.0F / (float)Math.PI - this.renderYawOffset) * 0.1F; + this.rotationYaw = this.renderYawOffset; + this.squidYaw += (float)Math.PI * this.field_70871_bB * 1.5F; +- this.squidPitch += (-((float)Math.atan2((double)f, this.motionY)) * 180.0F / (float)Math.PI - this.squidPitch) * 0.1F; ++ // CraftBukkit - Math -> TrigMath ++ this.squidPitch += (-((float) TrigMath.atan2((double) f, this.motionY)) * 180.0F / (float)Math.PI - this.squidPitch) * 0.1F; + } + else + { diff --git a/patches/net/minecraft/entity/passive/EntityWolf.java.patch b/patches/net/minecraft/entity/passive/EntityWolf.java.patch new file mode 100644 index 0000000..f3419a2 --- /dev/null +++ b/patches/net/minecraft/entity/passive/EntityWolf.java.patch @@ -0,0 +1,21 @@ +--- ../src-base/minecraft/net/minecraft/entity/passive/EntityWolf.java ++++ ../src-work/minecraft/net/minecraft/entity/passive/EntityWolf.java +@@ -139,7 +139,8 @@ + + protected String getLivingSound() + { +- return this.isAngry() ? "mob.wolf.growl" : (this.rand.nextInt(3) == 0 ? (this.isTamed() && this.dataWatcher.getWatchableObjectFloat(18) < 10.0F ? "mob.wolf.whine" : "mob.wolf.panting") : "mob.wolf.bark"); ++ // CraftBukkit - (getFloat(18) < 10) -> (getFloat(18) < this.getMaxHealth() / 2) ++ return this.isAngry() ? "mob.wolf.growl" : (this.rand.nextInt(3) == 0 ? (this.isTamed() && this.dataWatcher.getWatchableObjectFloat(18) < (this.getMaxHealth() / 2) ? "mob.wolf.whine" : "mob.wolf.panting") : "mob.wolf.bark"); + } + + protected String getHurtSound() +@@ -527,7 +528,7 @@ + + protected boolean canDespawn() + { +- return !this.isTamed() && this.ticksExisted > 2400; ++ return !this.isTamed(); // CraftBukkit + } + + public boolean func_142018_a(EntityLivingBase p_142018_1_, EntityLivingBase p_142018_2_) diff --git a/patches/net/minecraft/entity/player/EntityPlayer.java.patch b/patches/net/minecraft/entity/player/EntityPlayer.java.patch new file mode 100644 index 0000000..adf0e59 --- /dev/null +++ b/patches/net/minecraft/entity/player/EntityPlayer.java.patch @@ -0,0 +1,484 @@ +--- ../src-base/minecraft/net/minecraft/entity/player/EntityPlayer.java ++++ ../src-work/minecraft/net/minecraft/entity/player/EntityPlayer.java +@@ -92,6 +92,22 @@ + import net.minecraftforge.event.entity.player.PlayerFlyableFallEvent; + import net.minecraftforge.event.entity.player.PlayerSleepInBedEvent; + ++// CraftBukkit start ++import net.minecraft.network.play.server.S2FPacketSetSlot; ++ ++import org.bukkit.Bukkit; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.craftbukkit.entity.CraftItem; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.entity.Player; ++import org.bukkit.event.entity.EntityCombustByEntityEvent; ++import org.bukkit.event.inventory.InventoryCloseEvent; ++import org.bukkit.event.player.PlayerBedEnterEvent; ++import org.bukkit.event.player.PlayerBedLeaveEvent; ++import org.bukkit.event.player.PlayerDropItemEvent; ++import org.bukkit.event.player.PlayerItemConsumeEvent; ++// CraftBukkit end ++ + public abstract class EntityPlayer extends EntityLivingBase implements ICommandSender + { + public static final String PERSISTED_NBT_TAG = "PlayerPersisted"; +@@ -102,7 +118,7 @@ + private InventoryEnderChest theInventoryEnderChest = new InventoryEnderChest(); + public Container inventoryContainer; + public Container openContainer; +- protected FoodStats foodStats = new FoodStats(); ++ protected FoodStats foodStats = new FoodStats(this); // CraftBukkit - add this argument + protected int flyToggleTimer; + public float prevCameraYaw; + public float cameraYaw; +@@ -113,9 +129,19 @@ + public double field_71094_bP; + public double field_71095_bQ; + public double field_71085_bR; +- protected boolean sleeping; ++ // CraftBukkit start ++ public boolean sleeping; // protected -> public ++ public boolean fauxSleeping; ++ public String spawnWorld = ""; ++ ++ @Override ++ public CraftHumanEntity getBukkitEntity() ++ { ++ return (CraftHumanEntity) super.getBukkitEntity(); ++ } ++ // CraftBukkit end + public ChunkCoordinates playerLocation; +- private int sleepTimer; ++ public int sleepTimer; // CraftBukkit - private -> public + public float field_71079_bU; + @SideOnly(Side.CLIENT) + public float field_71082_cx; +@@ -124,6 +150,7 @@ + private boolean spawnForced; + private ChunkCoordinates startMinecartRidingCoordinate; + public PlayerCapabilities capabilities = new PlayerCapabilities(); ++ public int oldLevel = -1; // CraftBukkit + public int experienceLevel; + public int experienceTotal; + public float experience; +@@ -416,6 +443,42 @@ + { + this.updateItemUse(this.itemInUse, 16); + int i = this.itemInUse.stackSize; ++ // CraftBukkit start ++ org.bukkit.inventory.ItemStack craftItem = CraftItemStack.asBukkitCopy(this.itemInUse); ++ PlayerItemConsumeEvent event = new PlayerItemConsumeEvent((Player) this.getBukkitEntity(), craftItem); ++ worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ // Update client ++ if (this instanceof EntityPlayerMP) ++ { ++ ((EntityPlayerMP) this).playerNetServerHandler.sendPacket(new S2FPacketSetSlot((byte) 0, openContainer.getSlotFromInventory( ++ (IInventory) this.inventory, this.inventory.currentItem).slotIndex, this.itemInUse)); ++ // Spigot Start ++ ((EntityPlayerMP) this).getBukkitEntity().updateInventory(); ++ ((EntityPlayerMP) this).getBukkitEntity().updateScaledHealth(); ++ // Spigot End ++ } ++ ++ return; ++ } ++ ++ // Plugin modified the item, process it but don't remove it ++ if (!craftItem.equals(event.getItem())) ++ { ++ CraftItemStack.asNMSCopy(event.getItem()).onFoodEaten(this.worldObj, this); ++ ++ // Update client ++ if (this instanceof EntityPlayerMP) ++ { ++ ((EntityPlayerMP) this).playerNetServerHandler.sendPacket(new S2FPacketSetSlot((byte) 0, openContainer.getSlotFromInventory( ++ (IInventory) this.inventory, this.inventory.currentItem).slotIndex, this.itemInUse)); ++ } ++ ++ return; ++ } ++ // CraftBukkit end + ItemStack itemstack = this.itemInUse.onFoodEaten(this.worldObj, this); + + itemstack = ForgeEventFactory.onItemUseFinish(this, itemInUse, itemInUseCount, itemstack); +@@ -452,6 +515,7 @@ + return this.getHealth() <= 0.0F || this.isPlayerSleeping(); + } + ++ // CraftBukkit - protected -> public + public void closeScreen() + { + this.openContainer = this.inventoryContainer; +@@ -459,23 +523,40 @@ + + public void mountEntity(Entity p_70078_1_) + { ++ // CraftBukkit start - mirror Entity mount changes ++ this.setPassengerOf(p_70078_1_); ++ } ++ ++ public void setPassengerOf(Entity p_70078_1_) ++ { ++ // CraftBukkit end + if (this.ridingEntity != null && p_70078_1_ == null) + { +- if (!this.worldObj.isRemote) +- { +- this.dismountEntity(this.ridingEntity); +- } ++ worldObj.getServer().getPluginManager() ++ .callEvent(new org.spigotmc.event.entity.EntityDismountEvent(this.getBukkitEntity(), this.ridingEntity.getBukkitEntity())); // Spigot ++ // CraftBukkit start - use parent method instead to correctly fire ++ // VehicleExitEvent ++ Entity originalVehicle = this.ridingEntity; ++ // First statement moved down, second statement handled in parent ++ // method. ++ /* ++ * if (!this.world.isStatic) { this.l(this.vehicle); } ++ * ++ * if (this.vehicle != null) { this.vehicle.passenger = null; } ++ * ++ * this.vehicle = null; ++ */ ++ super.setPassengerOf(p_70078_1_); + +- if (this.ridingEntity != null) ++ if (!this.worldObj.isRemote && this.ridingEntity == null) + { +- this.ridingEntity.riddenByEntity = null; ++ this.dismountEntity(originalVehicle); + } +- +- this.ridingEntity = null; ++ // CraftBukkit end + } + else + { +- super.mountEntity(p_70078_1_); ++ super.setPassengerOf(p_70078_1_); // CraftBukkit - call new parent + } + } + +@@ -532,7 +613,8 @@ + + if (this.worldObj.difficultySetting == EnumDifficulty.PEACEFUL && this.getHealth() < this.getMaxHealth() && this.worldObj.getGameRules().getGameRuleBooleanValue("naturalRegeneration") && this.ticksExisted % 20 * 12 == 0) + { +- this.heal(1.0F); ++ // CraftBukkit - added regain reason of "REGEN" for filtering purposes. ++ this.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.REGEN); + } + + this.inventory.decrementAnimations(); +@@ -554,7 +636,8 @@ + + this.setAIMoveSpeed((float)iattributeinstance.getAttributeValue()); + float f = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionZ * this.motionZ); +- float f1 = (float)Math.atan(-this.motionY * 0.20000000298023224D) * 15.0F; ++ // CraftBukkit - Math -> TrigMath ++ float f1 = (float) org.bukkit.craftbukkit.TrigMath.atan(-this.motionY * 0.20000000298023224D) * 15.0F; + + if (f > 0.1F) + { +@@ -589,7 +672,7 @@ + + List list = this.worldObj.getEntitiesWithinAABBExcludingEntity(this, axisalignedbb); + +- if (list != null) ++ if (list != null && this.canBeCollidedWith()) // Spigot: this.canBeCollidedWith() condition + { + for (int i = 0; i < list.size(); ++i) + { +@@ -687,12 +770,14 @@ + public void addToPlayerScore(Entity p_70084_1_, int p_70084_2_) + { + this.addScore(p_70084_2_); +- Collection collection = this.getWorldScoreboard().func_96520_a(IScoreObjectiveCriteria.totalKillCount); ++ // CraftBukkit - Get our scores instead ++ Collection collection = this.worldObj.getServer().getScoreboardManager().getScoreboardScores(IScoreObjectiveCriteria.totalKillCount, this.getCommandSenderName(), new java.util.ArrayList()); + + if (p_70084_1_ instanceof EntityPlayer) + { + this.addStat(StatList.playerKillsStat, 1); +- collection.addAll(this.getWorldScoreboard().func_96520_a(IScoreObjectiveCriteria.playerKillCount)); ++ // CraftBukkit - Get our scores instead ++ this.worldObj.getServer().getScoreboardManager().getScoreboardScores(IScoreObjectiveCriteria.playerKillCount, this.getCommandSenderName(), collection); + } + else + { +@@ -703,8 +788,7 @@ + + while (iterator.hasNext()) + { +- ScoreObjective scoreobjective = (ScoreObjective)iterator.next(); +- Score score = this.getWorldScoreboard().func_96529_a(this.getCommandSenderName(), scoreobjective); ++ Score score = (Score) iterator.next(); // CraftBukkit - Use our scores instead + score.func_96648_a(); + } + } +@@ -777,6 +861,19 @@ + entityitem.motionZ += Math.sin((double)f1) * (double)f; + } + ++ // CraftBukkit start ++ Player player = (Player) this.getBukkitEntity(); ++ CraftItem drop = new CraftItem(this.worldObj.getServer(), entityitem); ++ PlayerDropItemEvent event = new PlayerDropItemEvent(player, drop); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ player.getInventory().addItem(drop.getItemStack()); ++ return null; ++ } ++ // CraftBukkit end ++ + this.joinEntityItemWithWorld(entityitem); + this.addStat(StatList.dropStat, 1); + return entityitem; +@@ -881,6 +978,15 @@ + this.wakeUpPlayer(true, true, false); + } + ++ // CraftBukkit start ++ this.spawnWorld = p_70037_1_.getString("SpawnWorld"); ++ ++ if ("".equals(spawnWorld)) ++ { ++ this.spawnWorld = this.worldObj.getServer().getWorlds().get(0).getName(); ++ } ++ // CraftBukkit end ++ + if (p_70037_1_.hasKey("SpawnX", 99) && p_70037_1_.hasKey("SpawnY", 99) && p_70037_1_.hasKey("SpawnZ", 99)) + { + this.spawnChunk = new ChunkCoordinates(p_70037_1_.getInteger("SpawnX"), p_70037_1_.getInteger("SpawnY"), p_70037_1_.getInteger("SpawnZ")); +@@ -925,6 +1031,7 @@ + p_70014_1_.setInteger("SpawnY", this.spawnChunk.posY); + p_70014_1_.setInteger("SpawnZ", this.spawnChunk.posZ); + p_70014_1_.setBoolean("SpawnForced", this.spawnForced); ++ p_70014_1_.setString("SpawnWorld", spawnWorld); // CraftBukkit - fixes bed spawns for multiworld worlds + } + + NBTTagList spawnlist = new NBTTagList(); +@@ -1003,7 +1110,7 @@ + { + if (this.worldObj.difficultySetting == EnumDifficulty.PEACEFUL) + { +- p_70097_2_ = 0.0F; ++ return false; // CraftBukkit - p_70097_2_ = 0.0F; -> return false + } + + if (this.worldObj.difficultySetting == EnumDifficulty.EASY) +@@ -1017,7 +1124,7 @@ + } + } + +- if (p_70097_2_ == 0.0F) ++ if (false && p_70097_2_ == 0.0F) // CraftBukkit - Don't filter out 0 damage + { + return false; + } +@@ -1039,9 +1146,40 @@ + + public boolean canAttackPlayer(EntityPlayer p_96122_1_) + { +- Team team = this.getTeam(); +- Team team1 = p_96122_1_.getTeam(); +- return team == null ? true : (!team.isSameTeam(team1) ? true : team.getAllowFriendlyFire()); ++ // CraftBukkit start - Change to check OTHER player's scoreboard team ++ // according to API ++ // To summarize this method's logic, it's "Can parameter hurt this" ++ org.bukkit.scoreboard.Team team; ++ ++ if (p_96122_1_ instanceof EntityPlayerMP) ++ { ++ EntityPlayerMP thatPlayer = (EntityPlayerMP) p_96122_1_; ++ team = thatPlayer.getBukkitEntity().getScoreboard().getPlayerTeam(thatPlayer.getBukkitEntity()); ++ ++ if (team == null || team.allowFriendlyFire()) ++ { ++ return true; ++ } ++ } ++ else ++ { ++ // This should never be called, but is implemented anyway ++ org.bukkit.OfflinePlayer thisPlayer = p_96122_1_.worldObj.getServer().getOfflinePlayer(p_96122_1_.getCommandSenderName()); ++ team = p_96122_1_.worldObj.getServer().getScoreboardManager().getMainScoreboard().getPlayerTeam(thisPlayer); ++ ++ if (team == null || team.allowFriendlyFire()) ++ { ++ return true; ++ } ++ } ++ ++ if (this instanceof EntityPlayerMP) ++ { ++ return !team.hasPlayer(((EntityPlayerMP) this).getBukkitEntity()); ++ } ++ ++ return !team.hasPlayer(this.worldObj.getServer().getOfflinePlayer(this.getCommandSenderName())); ++ // CraftBukkit end + } + + protected void damageArmor(float p_70675_1_) +@@ -1073,19 +1211,34 @@ + return (float)i / (float)this.inventory.armorInventory.length; + } + ++ // Cauldron start - vanilla compatibility + protected void damageEntity(DamageSource p_70665_1_, float p_70665_2_) + { ++ this.damageEntity_CB(p_70665_1_, p_70665_2_); ++ } ++ // Cauldron end ++ ++ // CraftBukkit start ++ protected boolean damageEntity_CB(DamageSource p_70665_1_, float p_70665_2_) // void ++ // -> ++ // boolean ++ { ++ if (true) ++ { ++ return super.damageEntity_CB(p_70665_1_, p_70665_2_); ++ } ++ // CraftBukkit end + if (!this.isEntityInvulnerable()) + { + p_70665_2_ = ForgeHooks.onLivingHurt(this, p_70665_1_, p_70665_2_); +- if (p_70665_2_ <= 0) return; ++ if (p_70665_2_ <= 0) return false; + if (!p_70665_1_.isUnblockable() && this.isBlocking() && p_70665_2_ > 0.0F) + { + p_70665_2_ = (1.0F + p_70665_2_) * 0.5F; + } + + p_70665_2_ = ArmorProperties.ApplyArmor(this, inventory.armorInventory, p_70665_1_, p_70665_2_); +- if (p_70665_2_ <= 0) return; ++ if (p_70665_2_ <= 0) return false; + p_70665_2_ = this.applyPotionDamageCalculations(p_70665_1_, p_70665_2_); + float f1 = p_70665_2_; + p_70665_2_ = Math.max(p_70665_2_ - this.getAbsorptionAmount(), 0.0F); +@@ -1099,6 +1252,7 @@ + this.func_110142_aN().func_94547_a(p_70665_1_, f2, p_70665_2_); + } + } ++ return false; + } + + public void func_146101_a(TileEntityFurnace p_146101_1_) {} +@@ -1134,7 +1288,8 @@ + + if (itemstack.interactWithEntity(this, (EntityLivingBase)p_70998_1_)) + { +- if (itemstack.stackSize <= 0 && !this.capabilities.isCreativeMode) ++ // CraftBukkit - bypass infinite items; <= 0 -> == 0 ++ if (itemstack.stackSize == 0 && !this.capabilities.isCreativeMode) + { + this.destroyCurrentEquippedItem(); + } +@@ -1281,7 +1436,8 @@ + { + itemstack.hitEntity((EntityLivingBase)object, this); + +- if (itemstack.stackSize <= 0) ++ // CraftBukkit - bypass infinite items; <= 0 -> == 0 ++ if (itemstack.stackSize == 0) + { + this.destroyCurrentEquippedItem(); + } +@@ -1293,7 +1449,17 @@ + + if (j > 0) + { +- p_71059_1_.setFire(j * 4); ++ // CraftBukkit start - Call a combust event when ++ // somebody hits with a fire enchanted item ++ EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), p_71059_1_.getBukkitEntity(), ++ j * 4); ++ org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); ++ ++ if (!combustEvent.isCancelled()) ++ { ++ p_71059_1_.setFire(combustEvent.getDuration()); ++ } ++ // CraftBukkit end + } + } + +@@ -1322,6 +1488,10 @@ + + if (this.openContainer != null) + { ++ // CraftBukkit start ++ InventoryCloseEvent event = new InventoryCloseEvent(this.openContainer.getBukkitView()); ++ if (this.openContainer.getBukkitView() != null) Bukkit.getServer().getPluginManager().callEvent(event); // Cauldron - allow vanilla mods to bypass ++ // CraftBukkit end + this.openContainer.onContainerClosed(this); + } + } +@@ -1381,6 +1551,20 @@ + this.mountEntity((Entity)null); + } + ++ // CraftBukkit start ++ if (this.getBukkitEntity() instanceof Player) ++ { ++ Player player = (Player) this.getBukkitEntity(); ++ org.bukkit.block.Block bed = this.worldObj.getWorld().getBlockAt(p_71018_1_, p_71018_2_, p_71018_3_); ++ PlayerBedEnterEvent cbEvent = new PlayerBedEnterEvent(player, bed); ++ this.worldObj.getServer().getPluginManager().callEvent(cbEvent); ++ ++ if (cbEvent.isCancelled()) ++ { ++ return EntityPlayer.EnumStatus.OTHER_PROBLEM; ++ } ++ } ++ // CraftBukkit end + this.setSize(0.2F, 0.2F); + this.yOffset = 0.2F; + +@@ -1476,6 +1660,26 @@ + this.worldObj.updateAllPlayersSleepingFlag(); + } + ++ // CraftBukkit start ++ if (this.getBukkitEntity() instanceof Player) ++ { ++ Player player = (Player) this.getBukkitEntity(); ++ org.bukkit.block.Block bed; ++ ++ if (chunkcoordinates != null) ++ { ++ bed = this.worldObj.getWorld().getBlockAt(chunkcoordinates.posX, chunkcoordinates.posY, chunkcoordinates.posZ); ++ } ++ else ++ { ++ bed = this.worldObj.getWorld().getBlockAt(player.getLocation()); ++ } ++ ++ PlayerBedLeaveEvent event = new PlayerBedLeaveEvent(player, bed); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ } ++ // CraftBukkit end ++ + if (p_70999_1_) + { + this.sleepTimer = 0; +@@ -1606,11 +1810,13 @@ + { + this.spawnChunk = new ChunkCoordinates(p_71063_1_); + this.spawnForced = p_71063_2_; ++ this.spawnWorld = this.worldObj.worldInfo.getWorldName(); // CraftBukkit + } + else + { + this.spawnChunk = null; + this.spawnForced = false; ++ this.spawnWorld = ""; // CraftBukkit + } + } + diff --git a/patches/net/minecraft/entity/player/EntityPlayerMP.java.patch b/patches/net/minecraft/entity/player/EntityPlayerMP.java.patch new file mode 100644 index 0000000..5f889d7 --- /dev/null +++ b/patches/net/minecraft/entity/player/EntityPlayerMP.java.patch @@ -0,0 +1,822 @@ +--- ../src-base/minecraft/net/minecraft/entity/player/EntityPlayerMP.java ++++ ../src-work/minecraft/net/minecraft/entity/player/EntityPlayerMP.java +@@ -2,6 +2,7 @@ + + import com.google.common.collect.Sets; + import com.mojang.authlib.GameProfile; ++ + import io.netty.buffer.Unpooled; + import java.io.IOException; + import java.util.ArrayList; +@@ -83,6 +84,7 @@ + import net.minecraft.tileentity.TileEntityFurnace; + import net.minecraft.tileentity.TileEntityHopper; + import net.minecraft.tileentity.TileEntitySign; ++import net.minecraft.util.ChatComponentTranslation; + import net.minecraft.util.ChunkCoordinates; + import net.minecraft.util.DamageSource; + import net.minecraft.util.EntityDamageSource; +@@ -106,24 +108,38 @@ + import net.minecraftforge.event.entity.player.PlayerDropsEvent; + import net.minecraftforge.event.world.ChunkWatchEvent; + ++// CraftBukkit start ++import net.minecraft.util.CombatTracker; ++import net.minecraft.util.FoodStats; ++import net.minecraft.world.World; ++import org.bukkit.Bukkit; ++import org.bukkit.WeatherType; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.craftbukkit.entity.CraftPlayer; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.inventory.InventoryType; ++import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; ++// CraftBukkit end ++ + public class EntityPlayerMP extends EntityPlayer implements ICrafting + { + private static final Logger logger = LogManager.getLogger(); +- private String translator = "en_US"; ++ public String translator = "en_US"; // CraftBukkit - private -> public + public NetHandlerPlayServer playerNetServerHandler; + public final MinecraftServer mcServer; + public final ItemInWorldManager theItemInWorldManager; + public double managedPosX; + public double managedPosZ; + public final List loadedChunks = new LinkedList(); +- private final List destroyedItemsNetCache = new LinkedList(); ++ public final List destroyedItemsNetCache = new LinkedList(); + private final StatisticsFile field_147103_bO; + private float field_130068_bO = Float.MIN_VALUE; + private float lastHealth = -1.0E8F; + private int lastFoodLevel = -99999999; + private boolean wasHungry = true; +- private int lastExperience = -99999999; +- private int field_147101_bU = 60; ++ public int lastExperience = -99999999; // CraftBukkit - private -> public ++ public int field_147101_bU = 60; // CraftBukkit - private -> public + private EntityPlayer.EnumChatVisibility chatVisibility; + private boolean chatColours = true; + private long field_143005_bX = System.currentTimeMillis(); +@@ -131,6 +147,39 @@ + public boolean isChangingQuantityOnly; + public int ping; + public boolean playerConqueredTheEnd; ++ // CraftBukkit start ++ public String displayName; ++ public String listName; ++ public org.bukkit.Location compassTarget; ++ public int newExp = 0; ++ public int newLevel = 0; ++ public int newTotalExp = 0; ++ public boolean keepLevel = false; ++ public double maxHealthCache; ++ // CraftBukkit end ++ // Spigot start ++ public boolean collidesWithEntities = true; ++ ++ @Override ++ ++ /** ++ * Returns true if other Entities should be prevented from moving through this Entity. ++ */ ++ public boolean canBeCollidedWith() ++ { ++ return this.collidesWithEntities && super.canBeCollidedWith(); ++ } ++ ++ @Override ++ ++ /** ++ * Returns true if this entity should push and be pushed by other entities when colliding. ++ */ ++ public boolean canBePushed() ++ { ++ return this.collidesWithEntities && super.canBePushed(); ++ } ++ // Spigot end + private static final String __OBFID = "CL_00001440"; + + public EntityPlayerMP(MinecraftServer p_i45285_1_, WorldServer p_i45285_2_, GameProfile p_i45285_3_, ItemInWorldManager p_i45285_4_) +@@ -153,6 +202,13 @@ + { + this.setPosition(this.posX, this.posY + 1.0D, this.posZ); + } ++ ++ // CraftBukkit start ++ this.displayName = this.getCommandSenderName(); ++ this.listName = this.getCommandSenderName(); ++ // this.canPickUpLoot = true; TODO ++ this.maxHealthCache = this.getMaxHealth(); ++ // CraftBukkit end + } + + public void readEntityFromNBT(NBTTagCompound p_70037_1_) +@@ -170,14 +226,57 @@ + this.theItemInWorldManager.setGameType(WorldSettings.GameType.getByID(p_70037_1_.getInteger("playerGameType"))); + } + } ++ ++ this.getBukkitEntity().readExtraData(p_70037_1_); // CraftBukkit + } + + public void writeEntityToNBT(NBTTagCompound p_70014_1_) + { + super.writeEntityToNBT(p_70014_1_); + p_70014_1_.setInteger("playerGameType", this.theItemInWorldManager.getGameType().getID()); ++ this.getBukkitEntity().setExtraData(p_70014_1_); // CraftBukkit + } + ++ // CraftBukkit start - World fallback code, either respawn location or global spawn ++ ++ /** ++ * Sets the reference to the World object. ++ */ ++ public void setWorld(World world) ++ { ++ super.setWorld(world); ++ ++ if (world == null) ++ { ++ this.isDead = false; ++ ChunkCoordinates position = null; ++ ++ if (this.spawnWorld != null && !this.spawnWorld.equals("")) ++ { ++ CraftWorld cworld = (CraftWorld) Bukkit.getServer().getWorld(this.spawnWorld); ++ ++ if (cworld != null && this.getBedLocation() != null) ++ { ++ world = cworld.getHandle(); ++ position = EntityPlayer.verifyRespawnCoordinates(cworld.getHandle(), this.getBedLocation(), false); ++ } ++ } ++ ++ if (world == null || position == null) ++ { ++ world = ((CraftWorld) Bukkit.getServer().getWorlds().get(0)).getHandle(); ++ position = world.getSpawnPoint(); ++ } ++ ++ this.worldObj = world; ++ this.setPosition(position.posX + 0.5, position.posY, position.posZ + 0.5); ++ } ++ ++ this.dimension = ((WorldServer) this.worldObj).provider.dimensionId; ++ this.theItemInWorldManager.setWorld((WorldServer) world); ++ } ++ // CraftBukkit end ++ + public void addExperienceLevel(int p_82242_1_) + { + super.addExperienceLevel(p_82242_1_); +@@ -240,7 +339,7 @@ + ArrayList arraylist1 = new ArrayList(); + Chunk chunk; + +- while (iterator1.hasNext() && arraylist.size() < S26PacketMapChunkBulk.func_149258_c()) ++ while (iterator1.hasNext() && arraylist.size() < this.worldObj.getSpigotConfig().maxBulkChunk) // Spigot // Cauldron + { + ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair)iterator1.next(); + +@@ -253,8 +352,7 @@ + if (chunk.func_150802_k()) + { + arraylist.add(chunk); +- arraylist1.addAll(((WorldServer)this.worldObj).func_147486_a(chunkcoordintpair.chunkXPos * 16, 0, chunkcoordintpair.chunkZPos * 16, chunkcoordintpair.chunkXPos * 16 + 15, 256, chunkcoordintpair.chunkZPos * 16 + 15)); +- //BugFix: 16 makes it load an extra chunk, which isn't associated with a player, which makes it not unload unless a player walks near it. ++ arraylist1.addAll(chunk.chunkTileEntityMap.values()); // CraftBukkit - Get tile entities directly from the chunk instead of the world + iterator1.remove(); + } + } +@@ -309,9 +407,10 @@ + } + } + ++ // CraftBukkit - Optionally scale health + if (this.getHealth() != this.lastHealth || this.lastFoodLevel != this.foodStats.getFoodLevel() || this.foodStats.getSaturationLevel() == 0.0F != this.wasHungry) + { +- this.playerNetServerHandler.sendPacket(new S06PacketUpdateHealth(this.getHealth(), this.foodStats.getFoodLevel(), this.foodStats.getSaturationLevel())); ++ this.playerNetServerHandler.sendPacket(new S06PacketUpdateHealth(this.getBukkitEntity().getScaledHealth(), this.foodStats.getFoodLevel(), this.foodStats.getSaturationLevel())); + this.lastHealth = this.getHealth(); + this.lastFoodLevel = this.foodStats.getFoodLevel(); + this.wasHungry = this.foodStats.getSaturationLevel() == 0.0F; +@@ -320,16 +419,18 @@ + if (this.getHealth() + this.getAbsorptionAmount() != this.field_130068_bO) + { + this.field_130068_bO = this.getHealth() + this.getAbsorptionAmount(); +- Collection collection = this.getWorldScoreboard().func_96520_a(IScoreObjectiveCriteria.health); +- Iterator iterator = collection.iterator(); ++ // CraftBukkit - Update ALL the scores! ++ this.worldObj.getServer().getScoreboardManager().updateAllScoresForList(IScoreObjectiveCriteria.health, this.getCommandSenderName(), com.google.common.collect.ImmutableList.of(this)); ++ } + +- while (iterator.hasNext()) +- { +- ScoreObjective scoreobjective = (ScoreObjective)iterator.next(); +- this.getWorldScoreboard().func_96529_a(this.getCommandSenderName(), scoreobjective).func_96651_a(Arrays.asList(new EntityPlayer[] {this})); +- } ++ // CraftBukkit start - Force max health updates ++ if (this.maxHealthCache != this.getMaxHealth()) ++ { ++ this.getBukkitEntity().updateScaledHealth(); + } + ++ // CraftBukkit end ++ + if (this.experienceTotal != this.lastExperience) + { + this.lastExperience = this.experienceTotal; +@@ -340,6 +441,20 @@ + { + this.func_147098_j(); + } ++ ++ // CraftBukkit start ++ if (this.oldLevel == -1) ++ { ++ this.oldLevel = this.experienceLevel; ++ } ++ ++ if (this.oldLevel != this.experienceLevel) ++ { ++ CraftEventFactory.callPlayerLevelChangeEvent(this.worldObj.getServer().getPlayer((EntityPlayerMP) this), this.oldLevel, this.experienceLevel); ++ this.oldLevel = this.experienceLevel; ++ } ++ ++ // CraftBukkit end + } + catch (Throwable throwable) + { +@@ -402,34 +517,74 @@ + + public void onDeath(DamageSource p_70645_1_) + { +- if (ForgeHooks.onLivingDeath(this, p_70645_1_)) return; +- this.mcServer.getConfigurationManager().sendChatMsg(this.func_110142_aN().func_151521_b()); ++ // CraftBukkit start ++ if (this.isDead || ForgeHooks.onLivingDeath(this, p_70645_1_)) // Cauldron - call Forge hook ++ { ++ return; ++ } + +- if (!this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory")) ++ java.util.List loot = new java.util.ArrayList(); ++ boolean keepInventory = this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory"); ++ ++ if (!keepInventory) + { ++ // Cauldron start - rework CraftBukkit logic to support Forge better + captureDrops = true; + capturedDrops.clear(); +- + this.inventory.dropAllItems(); ++ for (int i = 0; i < capturedDrops.size(); ++i) ++ { ++ if (capturedDrops.get(i) != null) ++ { ++ loot.add(CraftItemStack.asCraftMirror(capturedDrops.get(i).getEntityItem())); ++ } ++ } ++ // Cauldron end ++ } + ++ IChatComponent chatmessage = this.func_110142_aN().func_151521_b(); ++ String deathmessage = chatmessage.getUnformattedText(); ++ org.bukkit.event.entity.PlayerDeathEvent event = CraftEventFactory.callPlayerDeathEvent(this, loot, deathmessage); ++ String deathMessage = event.getDeathMessage(); ++ ++ if (deathMessage != null && deathMessage.length() > 0) ++ { ++ if (deathMessage.equals(deathmessage)) ++ { ++ this.mcServer.getConfigurationManager().sendChatMsg(chatmessage); ++ } ++ else ++ { ++ this.mcServer.getConfigurationManager().sendMessage(org.bukkit.craftbukkit.util.CraftChatMessage.fromString(deathMessage)); ++ } ++ } ++ ++ if (!keepInventory) ++ { ++ // Cauldron start - rework CraftBukkit logic to support Forge better ++ this.inventory.clearInventory(null, -1); // CraftBukkit - we clean the player's inventory after the EntityDeathEvent is called so plugins can get the exact state of the inventory. + captureDrops = false; +- PlayerDropsEvent event = new PlayerDropsEvent(this, p_70645_1_, capturedDrops, recentlyHit > 0); +- if (!MinecraftForge.EVENT_BUS.post(event)) ++ PlayerDropsEvent forgeEvent = new PlayerDropsEvent(this, p_70645_1_, capturedDrops, recentlyHit > 0); ++ ++ if (!MinecraftForge.EVENT_BUS.post(forgeEvent)) + { + for (EntityItem item : capturedDrops) + { + joinEntityItemWithWorld(item); + } + } ++ // Cauldron end + } + +- Collection collection = this.worldObj.getScoreboard().func_96520_a(IScoreObjectiveCriteria.deathCount); ++ this.closeScreen(); ++ // CraftBukkit end ++ // CraftBukkit - Get our scores instead ++ Collection collection = this.worldObj.getServer().getScoreboardManager().getScoreboardScores(IScoreObjectiveCriteria.deathCount, this.getCommandSenderName(), new java.util.ArrayList()); + Iterator iterator = collection.iterator(); + + while (iterator.hasNext()) + { +- ScoreObjective scoreobjective = (ScoreObjective)iterator.next(); +- Score score = this.getWorldScoreboard().func_96529_a(this.getCommandSenderName(), scoreobjective); ++ Score score = (Score) iterator.next(); // CraftBukkit - Use our scores instead + score.func_96648_a(); + } + +@@ -495,7 +650,8 @@ + + public boolean canAttackPlayer(EntityPlayer p_96122_1_) + { +- return !this.mcServer.isPVPEnabled() ? false : super.canAttackPlayer(p_96122_1_); ++ // CraftBukkit - this.mcServer.isPVPEnabled() -> this.world.pvpMode ++ return !this.worldObj.pvpMode ? false : super.canAttackPlayer(p_96122_1_); + } + + public void travelToDimension(int p_71027_1_) +@@ -526,7 +682,10 @@ + this.triggerAchievement(AchievementList.portal); + } + +- this.mcServer.getConfigurationManager().transferPlayerToDimension(this, p_71027_1_); ++ // CraftBukkit start ++ TeleportCause cause = (this.dimension == 1 || p_71027_1_ == 1) ? TeleportCause.END_PORTAL : TeleportCause.NETHER_PORTAL; ++ this.mcServer.getConfigurationManager().transferPlayerToDimension(this, p_71027_1_, cause); // Cauldron ++ // CraftBukkit end + this.lastExperience = -1; + this.lastHealth = -1.0F; + this.lastFoodLevel = -1; +@@ -569,6 +728,11 @@ + + public void wakeUpPlayer(boolean p_70999_1_, boolean p_70999_2_, boolean p_70999_3_) + { ++ if (this.fauxSleeping && !this.sleeping) ++ { ++ return; // CraftBukkit - Can't leave bed if not in one! ++ } ++ + if (this.isPlayerSleeping()) + { + this.getServerForPlayer().getEntityTracker().func_151248_b(this, new S0BPacketAnimation(this, 2)); +@@ -584,11 +748,27 @@ + + public void mountEntity(Entity p_70078_1_) + { +- super.mountEntity(p_70078_1_); +- this.playerNetServerHandler.sendPacket(new S1BPacketEntityAttach(0, this, this.ridingEntity)); +- this.playerNetServerHandler.setPlayerLocation(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); ++ // CraftBukkit start ++ this.setPassengerOf(p_70078_1_); + } + ++ public void setPassengerOf(Entity entity) ++ { ++ // mount(null) doesn't really fly for overloaded methods, ++ // so this method is needed ++ Entity currentVehicle = this.ridingEntity; ++ super.setPassengerOf(entity); ++ ++ // Check if the vehicle actually changed. ++ if (currentVehicle != this.ridingEntity) ++ { ++ this.playerNetServerHandler.sendPacket(new S1BPacketEntityAttach(0, this, this.ridingEntity)); ++ this.playerNetServerHandler.setPlayerLocation(this.posX, this.posY, this.posZ, this.rotationYaw, this.rotationPitch); ++ } ++ ++ // CraftBukkit end ++ } ++ + protected void updateFallState(double p_70064_1_, boolean p_70064_3_) {} + + public void handleFalling(double p_71122_1_, boolean p_71122_3_) +@@ -610,29 +790,64 @@ + this.currentWindowId = this.currentWindowId % 100 + 1; + } + ++ // CraftBukkit start - change signature from void to int ++ public int nextContainerCounter() ++ { ++ this.currentWindowId = this.currentWindowId % 100 + 1; ++ return this.currentWindowId; ++ } ++ // CraftBukkit end ++ + public void displayGUIWorkbench(int p_71058_1_, int p_71058_2_, int p_71058_3_) + { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerWorkbench(this.inventory, this.worldObj, p_71058_1_, p_71058_2_, p_71058_3_)); ++ ++ if (container == null) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 1, "Crafting", 9, true)); +- this.openContainer = new ContainerWorkbench(this.inventory, this.worldObj, p_71058_1_, p_71058_2_, p_71058_3_); ++ this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters(this); + } + + public void displayGUIEnchantment(int p_71002_1_, int p_71002_2_, int p_71002_3_, String p_71002_4_) + { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerEnchantment(this.inventory, this.worldObj, p_71002_1_, p_71002_2_, p_71002_3_)); ++ ++ if (container == null) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 4, p_71002_4_ == null ? "" : p_71002_4_, 9, p_71002_4_ != null)); +- this.openContainer = new ContainerEnchantment(this.inventory, this.worldObj, p_71002_1_, p_71002_2_, p_71002_3_); ++ this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters(this); + } + + public void displayGUIAnvil(int p_82244_1_, int p_82244_2_, int p_82244_3_) + { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerRepair(this.inventory, this.worldObj, p_82244_1_, p_82244_2_, p_82244_3_, this)); ++ ++ if (container == null) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 8, "Repairing", 9, true)); +- this.openContainer = new ContainerRepair(this.inventory, this.worldObj, p_82244_1_, p_82244_2_, p_82244_3_, this); ++ this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters(this); + } +@@ -644,71 +859,150 @@ + this.closeScreen(); + } + ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerChest(this.inventory, p_71007_1_)); ++ ++ if (container == null) ++ { ++ p_71007_1_.closeInventory(); // Cauldron - prevent chest from being stuck in open state on clients ++ return; ++ } ++ ++ // CraftBukkit end + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 0, p_71007_1_.getInventoryName(), p_71007_1_.getSizeInventory(), p_71007_1_.hasCustomInventoryName())); +- this.openContainer = new ContainerChest(this.inventory, p_71007_1_); ++ this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters(this); + } + + public void func_146093_a(TileEntityHopper p_146093_1_) + { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerHopper(this.inventory, p_146093_1_)); ++ ++ if (container == null) ++ { ++ p_146093_1_.closeInventory(); // Cauldron - prevent chest from being stuck in open state on clients ++ return; ++ } ++ ++ // CraftBukkit end + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 9, p_146093_1_.getInventoryName(), p_146093_1_.getSizeInventory(), p_146093_1_.hasCustomInventoryName())); +- this.openContainer = new ContainerHopper(this.inventory, p_146093_1_); ++ this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters(this); + } + + public void displayGUIHopperMinecart(EntityMinecartHopper p_96125_1_) + { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerHopper(this.inventory, p_96125_1_)); ++ ++ if (container == null) ++ { ++ p_96125_1_.closeInventory(); // Cauldron - prevent chest from being stuck in open state on clients ++ return; ++ } ++ ++ // CraftBukkit end + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 9, p_96125_1_.getInventoryName(), p_96125_1_.getSizeInventory(), p_96125_1_.hasCustomInventoryName())); +- this.openContainer = new ContainerHopper(this.inventory, p_96125_1_); ++ this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters(this); + } + + public void func_146101_a(TileEntityFurnace p_146101_1_) + { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerFurnace(this.inventory, p_146101_1_)); ++ ++ if (container == null) ++ { ++ p_146101_1_.closeInventory(); // Cauldron - prevent chests from being stuck in open state on clients ++ return; ++ } ++ ++ // CraftBukkit end + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 2, p_146101_1_.getInventoryName(), p_146101_1_.getSizeInventory(), p_146101_1_.hasCustomInventoryName())); +- this.openContainer = new ContainerFurnace(this.inventory, p_146101_1_); ++ this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters(this); + } + + public void func_146102_a(TileEntityDispenser p_146102_1_) + { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerDispenser(this.inventory, p_146102_1_)); ++ ++ if (container == null) ++ { ++ p_146102_1_.closeInventory(); // Cauldron - prevent chests from being stuck in open state on clients ++ return; ++ } ++ ++ // CraftBukkit end + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, p_146102_1_ instanceof TileEntityDropper ? 10 : 3, p_146102_1_.getInventoryName(), p_146102_1_.getSizeInventory(), p_146102_1_.hasCustomInventoryName())); +- this.openContainer = new ContainerDispenser(this.inventory, p_146102_1_); ++ this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters(this); + } + + public void func_146098_a(TileEntityBrewingStand p_146098_1_) + { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerBrewingStand(this.inventory, p_146098_1_)); ++ ++ if (container == null) ++ { ++ p_146098_1_.closeInventory(); // Cauldron - prevent chests from being stuck in open state on clients ++ return; ++ } ++ ++ // CraftBukkit end + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 5, p_146098_1_.getInventoryName(), p_146098_1_.getSizeInventory(), p_146098_1_.hasCustomInventoryName())); +- this.openContainer = new ContainerBrewingStand(this.inventory, p_146098_1_); ++ this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters(this); + } + + public void func_146104_a(TileEntityBeacon p_146104_1_) + { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerBeacon(this.inventory, p_146104_1_)); ++ ++ if (container == null) ++ { ++ p_146104_1_.closeInventory(); // Cauldron - prevent chests from being stuck in open state on clients ++ return; ++ } ++ ++ // CraftBukkit end + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 7, p_146104_1_.getInventoryName(), p_146104_1_.getSizeInventory(), p_146104_1_.hasCustomInventoryName())); +- this.openContainer = new ContainerBeacon(this.inventory, p_146104_1_); ++ this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters(this); + } + + public void displayGUIMerchant(IMerchant p_71030_1_, String p_71030_2_) + { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerMerchant(this.inventory, p_71030_1_, this.worldObj)); ++ ++ if (container == null) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + this.getNextWindowId(); +- this.openContainer = new ContainerMerchant(this.inventory, p_71030_1_, this.worldObj); ++ this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters(this); + InventoryMerchant inventorymerchant = ((ContainerMerchant)this.openContainer).getMerchantInventory(); +@@ -725,7 +1019,7 @@ + merchantrecipelist.func_151391_a(packetbuffer); + this.playerNetServerHandler.sendPacket(new S3FPacketCustomPayload("MC|TrList", packetbuffer)); + } +- catch (IOException ioexception) ++ catch (Exception ioexception) // CraftBukkit - IOException -> Exception + { + logger.error("Couldn\'t send trade list", ioexception); + } +@@ -738,6 +1032,17 @@ + + public void displayGUIHorse(EntityHorse p_110298_1_, IInventory p_110298_2_) + { ++ // CraftBukkit start - Inventory open hook ++ Container container = CraftEventFactory.callInventoryOpenEvent(this, new ContainerHorseInventory(this.inventory, p_110298_2_, p_110298_1_)); ++ ++ if (container == null) ++ { ++ p_110298_2_.closeInventory(); // Cauldron - prevent chests from being stuck in open state on clients ++ return; ++ } ++ ++ // CraftBukkit end ++ + if (this.openContainer != this.inventoryContainer) + { + this.closeScreen(); +@@ -745,7 +1050,7 @@ + + this.getNextWindowId(); + this.playerNetServerHandler.sendPacket(new S2DPacketOpenWindow(this.currentWindowId, 11, p_110298_2_.getInventoryName(), p_110298_2_.getSizeInventory(), p_110298_2_.hasCustomInventoryName(), p_110298_1_.getEntityId())); +- this.openContainer = new ContainerHorseInventory(this.inventory, p_110298_2_, p_110298_1_); ++ this.openContainer = container; // CraftBukkit - Use container we passed to event + this.openContainer.windowId = this.currentWindowId; + this.openContainer.addCraftingToCrafters(this); + } +@@ -770,6 +1075,15 @@ + { + this.playerNetServerHandler.sendPacket(new S30PacketWindowItems(p_71110_1_.windowId, p_71110_2_)); + this.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(-1, -1, this.inventory.getItemStack())); ++ ++ if (p_71110_1_.getBukkitView() == null) return; // Cauldron - allow vanilla mods to bypass ++ // CraftBukkit start - Send a Set Slot to update the crafting result slot ++ if (java.util.EnumSet.of(InventoryType.CRAFTING, InventoryType.WORKBENCH).contains(p_71110_1_.getBukkitView().getType())) ++ { ++ this.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(p_71110_1_.windowId, 0, p_71110_1_.getSlot(0).getStack())); ++ } ++ ++ // CraftBukkit end + } + + public void sendProgressBarUpdate(Container p_71112_1_, int p_71112_2_, int p_71112_3_) +@@ -779,6 +1093,7 @@ + + public void closeScreen() + { ++ CraftEventFactory.handleInventoryCloseEvent(this); // CraftBukkit + this.playerNetServerHandler.sendPacket(new S2EPacketCloseWindow(this.openContainer.windowId)); + this.closeContainer(); + } +@@ -853,8 +1168,19 @@ + public void setPlayerHealthUpdated() + { + this.lastHealth = -1.0E8F; ++ this.lastExperience = -1; // CraftBukkit - Added to reset + } + ++ // CraftBukkit start - Support multi-line messages ++ public void sendMessage(IChatComponent[] ichatcomponent) ++ { ++ for (IChatComponent component : ichatcomponent) ++ { ++ this.addChatComponentMessage(component); ++ } ++ } ++ // CraftBukkit end ++ + public void addChatComponentMessage(IChatComponent p_146105_1_) + { + this.playerNetServerHandler.sendPacket(new S02PacketChat(p_146105_1_)); +@@ -1037,6 +1363,114 @@ + return this.field_143005_bX; + } + ++ // CraftBukkit start ++ public long timeOffset = 0; ++ public boolean relativeTime = true; ++ ++ public long getPlayerTime() ++ { ++ if (this.relativeTime) ++ { ++ // Adds timeOffset to the current server time. ++ return this.worldObj.getWorldTime() + this.timeOffset; ++ } ++ else ++ { ++ // Adds timeOffset to the beginning of this day. ++ return this.worldObj.getWorldTime() - (this.worldObj.getWorldTime() % 24000) + this.timeOffset; ++ } ++ } ++ ++ public WeatherType weather = null; ++ ++ public WeatherType getPlayerWeather() ++ { ++ return this.weather; ++ } ++ ++ public void setPlayerWeather(WeatherType type, boolean plugin) ++ { ++ if (!plugin && this.weather != null) ++ { ++ return; ++ } ++ ++ if (plugin) ++ { ++ this.weather = type; ++ } ++ ++ if (type == WeatherType.DOWNFALL) ++ { ++ this.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(2, 0)); ++ // this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(7, this.world.j(1.0F))); ++ // this.playerConnection.sendPacket(new PacketPlayOutGameStateChange(8, this.world.h(1.0F))); ++ } ++ else ++ { ++ this.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(1, 0)); ++ } ++ } ++ ++ public void resetPlayerWeather() ++ { ++ this.weather = null; ++ this.setPlayerWeather(this.worldObj.getWorldInfo().isRaining() ? WeatherType.DOWNFALL : WeatherType.CLEAR, false); ++ } ++ ++ @Override ++ public String toString() ++ { ++ return super.toString() + "(" + this.getCommandSenderName() + " at " + this.posX + "," + this.posY + "," + this.posZ + ")"; ++ } ++ ++ public void reset() ++ { ++ float exp = 0; ++ boolean keepInventory = this.worldObj.getGameRules().getGameRuleBooleanValue("keepInventory"); ++ ++ if (this.keepLevel || keepInventory) ++ { ++ exp = this.experience; ++ this.newTotalExp = this.experienceTotal; ++ this.newLevel = this.experienceLevel; ++ } ++ ++ this.setHealth(this.getMaxHealth()); ++ this.fire = 0; ++ this.fallDistance = 0; ++ this.foodStats = new FoodStats(this); ++ this.experienceLevel = this.newLevel; ++ this.experienceTotal = this.newTotalExp; ++ this.experience = 0; ++ this.deathTime = 0; ++ this.clearActivePotions(); // Should be remapped: removeAllEffects should be remapped to this. ++ super.potionsNeedUpdate = true; // Cauldron - change to super to temporarily workaround remapping bug with SpecialSource ++ this.openContainer = this.inventoryContainer; ++ this.attackingPlayer = null; ++ this.entityLivingToAttack = null; ++ this._combatTracker = new CombatTracker(this); ++ this.lastExperience = -1; ++ ++ if (this.keepLevel || keepInventory) ++ { ++ this.experience = exp; ++ } ++ else ++ { ++ this.addExperience(this.newExp); ++ } ++ ++ this.keepLevel = false; ++ } ++ ++ @Override ++ public CraftPlayer getBukkitEntity() ++ { ++ return (CraftPlayer) super.getBukkitEntity(); ++ } ++ // CraftBukkit end ++ + /* ===================================== FORGE START =====================================*/ + /** + * Returns the default eye height of the player diff --git a/patches/net/minecraft/entity/player/InventoryPlayer.java.patch b/patches/net/minecraft/entity/player/InventoryPlayer.java.patch new file mode 100644 index 0000000..8e73044 --- /dev/null +++ b/patches/net/minecraft/entity/player/InventoryPlayer.java.patch @@ -0,0 +1,140 @@ +--- ../src-base/minecraft/net/minecraft/entity/player/InventoryPlayer.java ++++ ../src-work/minecraft/net/minecraft/entity/player/InventoryPlayer.java +@@ -2,7 +2,9 @@ + + import cpw.mods.fml.relauncher.Side; + import cpw.mods.fml.relauncher.SideOnly; ++ + import java.util.concurrent.Callable; ++ + import net.minecraft.block.Block; + import net.minecraft.crash.CrashReport; + import net.minecraft.crash.CrashReportCategory; +@@ -13,7 +15,13 @@ + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.nbt.NBTTagList; + import net.minecraft.util.ReportedException; ++// CraftBukkit start ++import java.util.List; + ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class InventoryPlayer implements IInventory + { + public ItemStack[] mainInventory = new ItemStack[36]; +@@ -25,7 +33,46 @@ + private ItemStack itemStack; + public boolean inventoryChanged; + private static final String __OBFID = "CL_00001709"; ++ // CraftBukkit start ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; + ++ public ItemStack[] getContents() ++ { ++ return this.mainInventory; ++ } ++ ++ public ItemStack[] getArmorContents() ++ { ++ return this.armorInventory; ++ } ++ ++ public void onOpen(CraftHumanEntity who) ++ { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) ++ { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() ++ { ++ return transaction; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() ++ { ++ return this.player.getBukkitEntity(); ++ } ++ ++ public void setMaxStackSize(int size) ++ { ++ maxStack = size; ++ } ++ // CraftBukkit end ++ + public InventoryPlayer(EntityPlayer p_i1750_1_) + { + this.player = p_i1750_1_; +@@ -81,6 +128,34 @@ + return -1; + } + ++ // CraftBukkit start - Watch method above! :D ++ public int canHold(ItemStack itemstack) ++ { ++ int remains = itemstack.stackSize; ++ ++ for (int i = 0; i < this.mainInventory.length; ++i) ++ { ++ if (this.mainInventory[i] == null) ++ { ++ return itemstack.stackSize; ++ } ++ ++ // Taken from firstPartial(ItemStack) ++ if (this.mainInventory[i] != null && this.mainInventory[i].getItem() == itemstack.getItem() && this.mainInventory[i].isStackable() && this.mainInventory[i].stackSize < this.mainInventory[i].getMaxStackSize() && this.mainInventory[i].stackSize < this.getInventoryStackLimit() && (!this.mainInventory[i].getHasSubtypes() || this.mainInventory[i].getItemDamage() == itemstack.getItemDamage()) && ItemStack.areItemStackTagsEqual(this.mainInventory[i], itemstack)) ++ { ++ remains -= (this.mainInventory[i].getMaxStackSize() < this.getInventoryStackLimit() ? this.mainInventory[i].getMaxStackSize() : this.getInventoryStackLimit()) - this.mainInventory[i].stackSize; ++ } ++ ++ if (remains <= 0) ++ { ++ return itemstack.stackSize; ++ } ++ } ++ ++ return itemstack.stackSize - remains; ++ } ++ // CraftBukkit end ++ + public int getFirstEmptyStack() + { + for (int i = 0; i < this.mainInventory.length; ++i) +@@ -658,7 +733,7 @@ + if (this.mainInventory[i] != null) + { + this.player.func_146097_a(this.mainInventory[i], true, false); +- this.mainInventory[i] = null; ++ //this.mainInventory[i] = null; // Cauldron - we clear this in EntityPlayerMP.onDeath after PlayerDeathEvent + } + } + +@@ -667,7 +742,7 @@ + if (this.armorInventory[i] != null) + { + this.player.func_146097_a(this.armorInventory[i], true, false); +- this.armorInventory[i] = null; ++ //this.armorInventory[i] = null; // Cauldron - we clear this in EntityPlayerMP.onDeath after PlayerDeathEvent + } + } + } +@@ -684,6 +759,13 @@ + + public ItemStack getItemStack() + { ++ // CraftBukkit start ++ if (this.itemStack != null && this.itemStack.stackSize == 0) ++ { ++ this.setItemStack(null); ++ } ++ ++ // CraftBukkit end + return this.itemStack; + } + diff --git a/patches/net/minecraft/entity/player/PlayerCapabilities.java.patch b/patches/net/minecraft/entity/player/PlayerCapabilities.java.patch new file mode 100644 index 0000000..d67f84c --- /dev/null +++ b/patches/net/minecraft/entity/player/PlayerCapabilities.java.patch @@ -0,0 +1,13 @@ +--- ../src-base/minecraft/net/minecraft/entity/player/PlayerCapabilities.java ++++ ../src-work/minecraft/net/minecraft/entity/player/PlayerCapabilities.java +@@ -11,8 +11,8 @@ + public boolean allowFlying; + public boolean isCreativeMode; + public boolean allowEdit = true; +- private float flySpeed = 0.05F; +- private float walkSpeed = 0.1F; ++ public float flySpeed = 0.05F; // CraftBukkit private -> public ++ public float walkSpeed = 0.1F; // CraftBukkit private -> public + private static final String __OBFID = "CL_00001708"; + + public void writeCapabilitiesToNBT(NBTTagCompound p_75091_1_) diff --git a/patches/net/minecraft/entity/projectile/EntityArrow.java.patch b/patches/net/minecraft/entity/projectile/EntityArrow.java.patch new file mode 100644 index 0000000..c12e33d --- /dev/null +++ b/patches/net/minecraft/entity/projectile/EntityArrow.java.patch @@ -0,0 +1,141 @@ +--- ../src-base/minecraft/net/minecraft/entity/projectile/EntityArrow.java ++++ ../src-work/minecraft/net/minecraft/entity/projectile/EntityArrow.java +@@ -23,6 +23,13 @@ + import net.minecraft.util.Vec3; + import net.minecraft.world.World; + ++// CraftBukkit start ++import net.minecraft.entity.item.EntityItem; ++import org.bukkit.entity.LivingEntity; ++import org.bukkit.event.entity.EntityCombustByEntityEvent; ++import org.bukkit.event.player.PlayerPickupItemEvent; ++// CraftBukkit end ++ + public class EntityArrow extends Entity implements IProjectile + { + private int field_145791_d = -1; +@@ -30,14 +37,14 @@ + private int field_145789_f = -1; + private Block field_145790_g; + private int inData; +- private boolean inGround; ++ public boolean inGround = false; // Spigot - private -> public + public int canBePickedUp; + public int arrowShake; + public Entity shootingEntity; + private int ticksInGround; + private int ticksInAir; + private double damage = 2.0D; +- private int knockbackStrength; ++ public int knockbackStrength; // CraftBukkit - private -> public + private static final String __OBFID = "CL_00001715"; + + public EntityArrow(World p_i1753_1_) +@@ -61,6 +68,7 @@ + super(p_i1755_1_); + this.renderDistanceWeight = 10.0D; + this.shootingEntity = p_i1755_2_; ++ this.projectileSource = (LivingEntity) p_i1755_2_.getBukkitEntity(); // CraftBukkit + + if (p_i1755_2_ instanceof EntityPlayer) + { +@@ -91,6 +99,7 @@ + super(p_i1756_1_); + this.renderDistanceWeight = 10.0D; + this.shootingEntity = p_i1756_2_; ++ this.projectileSource = (LivingEntity) p_i1756_2_.getBukkitEntity(); // CraftBukkit + + if (p_i1756_2_ instanceof EntityPlayer) + { +@@ -199,7 +208,7 @@ + { + ++this.ticksInGround; + +- if (this.ticksInGround == 1200) ++ if (this.ticksInGround == worldObj.getSpigotConfig().arrowDespawnRate) // Spigot // Cauldron + { + this.setDead(); + } +@@ -246,7 +255,7 @@ + + if (movingobjectposition1 != null) + { +- double d1 = vec31.distanceTo(movingobjectposition1.hitVec); ++ double d1 = vec31.squareDistanceTo(movingobjectposition1.hitVec); // CraftBukkit - distance efficiency + + if (d1 < d0 || d0 == 0.0D) + { +@@ -277,6 +286,8 @@ + + if (movingobjectposition != null) + { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this); // CraftBukkit - Call event ++ + if (movingobjectposition.entityHit != null) + { + f2 = MathHelper.sqrt_double(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ); +@@ -298,13 +309,23 @@ + damagesource = DamageSource.causeArrowDamage(this, this.shootingEntity); + } + +- if (this.isBurning() && !(movingobjectposition.entityHit instanceof EntityEnderman)) ++ // CraftBukkit start - Moved damage call ++ if (movingobjectposition.entityHit.attackEntityFrom(damagesource, k)) + { +- movingobjectposition.entityHit.setFire(5); +- } ++ if (this.isBurning() && !(movingobjectposition.entityHit instanceof EntityEnderman) && (!(movingobjectposition.entityHit instanceof EntityPlayerMP) || !(this.shootingEntity instanceof EntityPlayerMP) || this.worldObj.pvpMode)) // CraftBukkit - abide by pvp setting if destination is a player ++ { ++ EntityCombustByEntityEvent combustEvent = new EntityCombustByEntityEvent(this.getBukkitEntity(), entity.getBukkitEntity(), 5); ++ org.bukkit.Bukkit.getPluginManager().callEvent(combustEvent); + +- if (movingobjectposition.entityHit.attackEntityFrom(damagesource, (float)k)) +- { ++ if (!combustEvent.isCancelled()) ++ { ++ movingobjectposition.entityHit.setFire(combustEvent.getDuration()); ++ } ++ ++ // CraftBukkit end ++ } ++ ++ // if (movingobjectposition.entityHit.attackEntityFrom(damagesource, (float)k)) { // CraftBukkit - moved up + if (movingobjectposition.entityHit instanceof EntityLivingBase) + { + EntityLivingBase entitylivingbase = (EntityLivingBase)movingobjectposition.entityHit; +@@ -487,6 +508,23 @@ + { + if (!this.worldObj.isRemote && this.inGround && this.arrowShake <= 0) + { ++ // CraftBukkit start ++ ItemStack itemstack = new ItemStack(Items.arrow); ++ ++ if (this.canBePickedUp == 1 && p_70100_1_.inventory.canHold(itemstack) > 0) ++ { ++ EntityItem item = new EntityItem(this.worldObj, this.posX, this.posY, this.posZ, itemstack); ++ PlayerPickupItemEvent event = new PlayerPickupItemEvent((org.bukkit.entity.Player) p_70100_1_.getBukkitEntity(), new org.bukkit.craftbukkit.entity.CraftItem(this.worldObj.getServer(), this, item), 0); ++ // event.setCancelled(!entityplayer.canPickUpLoot); TODO ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ } ++ ++ // CraftBukkit end + boolean flag = this.canBePickedUp == 1 || this.canBePickedUp == 2 && p_70100_1_.capabilities.isCreativeMode; + + if (this.canBePickedUp == 1 && !p_70100_1_.inventory.addItemStackToInventory(new ItemStack(Items.arrow, 1))) +@@ -553,4 +591,11 @@ + byte b0 = this.dataWatcher.getWatchableObjectByte(16); + return (b0 & 1) != 0; + } ++ ++ // CraftBukkit start ++ public boolean isInGround() ++ { ++ return inGround; ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/entity/projectile/EntityEgg.java.patch b/patches/net/minecraft/entity/projectile/EntityEgg.java.patch new file mode 100644 index 0000000..a4d1760 --- /dev/null +++ b/patches/net/minecraft/entity/projectile/EntityEgg.java.patch @@ -0,0 +1,73 @@ +--- ../src-base/minecraft/net/minecraft/entity/projectile/EntityEgg.java ++++ ../src-work/minecraft/net/minecraft/entity/projectile/EntityEgg.java +@@ -6,6 +6,15 @@ + import net.minecraft.util.MovingObjectPosition; + import net.minecraft.world.World; + ++// CraftBukkit start ++import net.minecraft.entity.player.EntityPlayerMP; ++import org.bukkit.entity.Ageable; ++import org.bukkit.entity.EntityType; ++import org.bukkit.entity.Player; ++import org.bukkit.event.player.PlayerEggThrowEvent; ++import net.minecraft.entity.Entity; ++// CraftBukkit end ++ + public class EntityEgg extends EntityThrowable + { + private static final String __OBFID = "CL_00001724"; +@@ -32,24 +41,43 @@ + p_70184_1_.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.getThrower()), 0.0F); + } + +- if (!this.worldObj.isRemote && this.rand.nextInt(8) == 0) ++ // CraftBukkit start ++ boolean hatching = !this.worldObj.isRemote && this.rand.nextInt(8) == 0; ++ int numHatching = (this.rand.nextInt(32) == 0) ? 4 : 1; ++ ++ if (!hatching) + { +- byte b0 = 1; ++ numHatching = 0; ++ } + +- if (this.rand.nextInt(32) == 0) +- { +- b0 = 4; +- } ++ EntityType hatchingType = EntityType.CHICKEN; ++ Entity shooter = this.getThrower(); + +- for (int i = 0; i < b0; ++i) ++ if (shooter instanceof EntityPlayerMP) ++ { ++ Player player = (shooter == null) ? null : (Player) shooter.getBukkitEntity(); ++ PlayerEggThrowEvent event = new PlayerEggThrowEvent(player, (org.bukkit.entity.Egg) this.getBukkitEntity(), hatching, (byte) numHatching, hatchingType); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ hatching = event.isHatching(); ++ numHatching = event.getNumHatches(); ++ hatchingType = event.getHatchingType(); ++ } ++ ++ if (hatching) ++ { ++ for (int k = 0; k < numHatching; k++) + { +- EntityChicken entitychicken = new EntityChicken(this.worldObj); +- entitychicken.setGrowingAge(-24000); +- entitychicken.setLocationAndAngles(this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F); +- this.worldObj.spawnEntityInWorld(entitychicken); ++ org.bukkit.entity.Entity entity = worldObj.getWorld().spawn(new org.bukkit.Location(worldObj.getWorld(), this.posX, this.posY, this.posZ, this.rotationYaw, 0.0F), hatchingType.getEntityClass(), org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.EGG); ++ ++ if (entity instanceof Ageable) ++ { ++ ((Ageable) entity).setBaby(); ++ } + } + } + ++ // CraftBukkit end ++ + for (int j = 0; j < 8; ++j) + { + this.worldObj.spawnParticle("snowballpoof", this.posX, this.posY, this.posZ, 0.0D, 0.0D, 0.0D); diff --git a/patches/net/minecraft/entity/projectile/EntityFireball.java.patch b/patches/net/minecraft/entity/projectile/EntityFireball.java.patch new file mode 100644 index 0000000..4ea87ad --- /dev/null +++ b/patches/net/minecraft/entity/projectile/EntityFireball.java.patch @@ -0,0 +1,122 @@ +--- ../src-base/minecraft/net/minecraft/entity/projectile/EntityFireball.java ++++ ../src-work/minecraft/net/minecraft/entity/projectile/EntityFireball.java +@@ -3,6 +3,7 @@ + import cpw.mods.fml.relauncher.Side; + import cpw.mods.fml.relauncher.SideOnly; + import java.util.List; ++ + import net.minecraft.block.Block; + import net.minecraft.entity.Entity; + import net.minecraft.entity.EntityLivingBase; +@@ -15,6 +16,8 @@ + import net.minecraft.util.Vec3; + import net.minecraft.world.World; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public abstract class EntityFireball extends Entity + { + private int field_145795_e = -1; +@@ -28,6 +31,8 @@ + public double accelerationX; + public double accelerationY; + public double accelerationZ; ++ public float bukkitYield = 1; // CraftBukkit ++ public boolean isIncendiary = true; // CraftBukkit + private static final String __OBFID = "CL_00001717"; + + public EntityFireball(World p_i1759_1_) +@@ -62,11 +67,19 @@ + { + super(p_i1761_1_); + this.shootingEntity = p_i1761_2_; ++ this.projectileSource = (org.bukkit.entity.LivingEntity) p_i1761_2_.getBukkitEntity(); // CraftBukkit + this.setSize(1.0F, 1.0F); + this.setLocationAndAngles(p_i1761_2_.posX, p_i1761_2_.posY, p_i1761_2_.posZ, p_i1761_2_.rotationYaw, p_i1761_2_.rotationPitch); + this.setPosition(this.posX, this.posY, this.posZ); + this.yOffset = 0.0F; + this.motionX = this.motionY = this.motionZ = 0.0D; ++ // CraftBukkit start - Added setDirection method ++ this.setDirection(p_i1761_3_, p_i1761_5_, p_i1761_7_); ++ } ++ ++ public void setDirection(double p_i1761_3_, double p_i1761_5_, double p_i1761_7_) ++ { ++ // CraftBukkit end + p_i1761_3_ += this.rand.nextGaussian() * 0.4D; + p_i1761_5_ += this.rand.nextGaussian() * 0.4D; + p_i1761_7_ += this.rand.nextGaussian() * 0.4D; +@@ -140,7 +153,7 @@ + + if (movingobjectposition1 != null) + { +- double d1 = vec3.distanceTo(movingobjectposition1.hitVec); ++ double d1 = vec3.squareDistanceTo(movingobjectposition1.hitVec); // CraftBukkit - distance efficiency + + if (d1 < d0 || d0 == 0.0D) + { +@@ -159,6 +172,14 @@ + if (movingobjectposition != null) + { + this.onImpact(movingobjectposition); ++ ++ // CraftBukkit start ++ if (this.isDead) ++ { ++ CraftEventFactory.callProjectileHitEvent(this); ++ } ++ ++ // CraftBukkit end + } + + this.posX += this.motionX; +@@ -227,6 +248,8 @@ + p_70014_1_.setShort("zTile", (short)this.field_145794_g); + p_70014_1_.setByte("inTile", (byte)Block.getIdFromBlock(this.field_145796_h)); + p_70014_1_.setByte("inGround", (byte)(this.inGround ? 1 : 0)); ++ // CraftBukkit - Fix direction being mismapped to invalid variables ++ p_70014_1_.setTag("power", this.newDoubleNBTList(new double[] { this.accelerationX, this.accelerationY, this.accelerationZ})); + p_70014_1_.setTag("direction", this.newDoubleNBTList(new double[] {this.motionX, this.motionY, this.motionZ})); + } + +@@ -238,8 +261,17 @@ + this.field_145796_h = Block.getBlockById(p_70037_1_.getByte("inTile") & 255); + this.inGround = p_70037_1_.getByte("inGround") == 1; + +- if (p_70037_1_.hasKey("direction", 9)) ++ // CraftBukkit start - direction -> power ++ if (p_70037_1_.hasKey("power", 9)) + { ++ NBTTagList nbttaglist = p_70037_1_.getTagList("power", 6); ++ this.accelerationX = nbttaglist.func_150309_d(0); ++ this.accelerationY = nbttaglist.func_150309_d(1); ++ this.accelerationZ = nbttaglist.func_150309_d(2); ++ // CraftBukkit end ++ } ++ else if (p_70037_1_.hasKey("direction", 9)) ++ { + NBTTagList nbttaglist = p_70037_1_.getTagList("direction", 6); + this.motionX = nbttaglist.func_150309_d(0); + this.motionY = nbttaglist.func_150309_d(1); +@@ -273,6 +305,13 @@ + + if (p_70097_1_.getEntity() != null) + { ++ // CraftBukkit start ++ if (CraftEventFactory.handleNonLivingEntityDamageEvent(this, p_70097_1_, p_70097_2_)) ++ { ++ return false; ++ } ++ ++ // CraftBukkit end + Vec3 vec3 = p_70097_1_.getEntity().getLookVec(); + + if (vec3 != null) +@@ -288,6 +327,7 @@ + if (p_70097_1_.getEntity() instanceof EntityLivingBase) + { + this.shootingEntity = (EntityLivingBase)p_70097_1_.getEntity(); ++ this.projectileSource = (org.bukkit.projectiles.ProjectileSource) this.shootingEntity.getBukkitEntity(); // CraftBukkit + } + + return true; diff --git a/patches/net/minecraft/entity/projectile/EntityFishHook.java.patch b/patches/net/minecraft/entity/projectile/EntityFishHook.java.patch new file mode 100644 index 0000000..09da7c4 --- /dev/null +++ b/patches/net/minecraft/entity/projectile/EntityFishHook.java.patch @@ -0,0 +1,119 @@ +--- ../src-base/minecraft/net/minecraft/entity/projectile/EntityFishHook.java ++++ ../src-work/minecraft/net/minecraft/entity/projectile/EntityFishHook.java +@@ -27,6 +27,12 @@ + import net.minecraft.world.World; + import net.minecraft.world.WorldServer; + ++// CraftBukkit start ++import org.bukkit.entity.Player; ++import org.bukkit.entity.Fish; ++import org.bukkit.event.player.PlayerFishEvent; ++// CraftBukkit end ++ + public class EntityFishHook extends Entity + { + public static final List field_146039_d = Arrays.asList(new WeightedRandomFishable[] {(new WeightedRandomFishable(new ItemStack(Items.leather_boots), 10)).func_150709_a(0.9F), new WeightedRandomFishable(new ItemStack(Items.leather), 10), new WeightedRandomFishable(new ItemStack(Items.bone), 10), new WeightedRandomFishable(new ItemStack(Items.potionitem), 10), new WeightedRandomFishable(new ItemStack(Items.string), 5), (new WeightedRandomFishable(new ItemStack(Items.fishing_rod), 2)).func_150709_a(0.9F), new WeightedRandomFishable(new ItemStack(Items.bowl), 10), new WeightedRandomFishable(new ItemStack(Items.stick), 5), new WeightedRandomFishable(new ItemStack(Items.dye, 10, 0), 1), new WeightedRandomFishable(new ItemStack(Blocks.tripwire_hook), 10), new WeightedRandomFishable(new ItemStack(Items.rotten_flesh), 10)}); +@@ -258,7 +264,7 @@ + + if (movingobjectposition1 != null) + { +- d2 = vec31.distanceTo(movingobjectposition1.hitVec); ++ d2 = vec31.squareDistanceTo(movingobjectposition1.hitVec); // CraftBukkit - distance efficiency + + if (d2 < d0 || d0 == 0.0D) + { +@@ -276,6 +282,8 @@ + + if (movingobjectposition != null) + { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this); // Craftbukkit - Call event ++ + if (movingobjectposition.entityHit != null) + { + if (movingobjectposition.entityHit.attackEntityFrom(DamageSource.causeThrownDamage(this, this.field_146042_b), 0.0F)) +@@ -509,6 +517,18 @@ + + if (this.field_146043_c != null) + { ++ // CraftBukkit start ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.field_146042_b.getBukkitEntity(), this.field_146043_c.getBukkitEntity(), (Fish) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_ENTITY); ++ this.worldObj.getServer().getPluginManager().callEvent(playerFishEvent); ++ ++ if (playerFishEvent.isCancelled()) ++ { ++ this.setDead(); ++ this.field_146042_b.fishEntity = null; ++ return 0; ++ } ++ ++ // CraftBukkit end + double d0 = this.field_146042_b.posX - this.posX; + double d2 = this.field_146042_b.posY - this.posY; + double d4 = this.field_146042_b.posZ - this.posZ; +@@ -522,6 +542,19 @@ + else if (this.field_146045_ax > 0) + { + EntityItem entityitem = new EntityItem(this.worldObj, this.posX, this.posY, this.posZ, this.func_146033_f()); ++ // CraftBukkit start ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.field_146042_b.getBukkitEntity(), entityitem.getBukkitEntity(), (Fish) this.getBukkitEntity(), PlayerFishEvent.State.CAUGHT_FISH); ++ playerFishEvent.setExpToDrop(this.rand.nextInt(6) + 1); ++ this.worldObj.getServer().getPluginManager().callEvent(playerFishEvent); ++ ++ if (playerFishEvent.isCancelled()) ++ { ++ this.setDead(); ++ this.field_146042_b.fishEntity = null; ++ return 0; ++ } ++ ++ // CraftBukkit end + double d1 = this.field_146042_b.posX - this.posX; + double d3 = this.field_146042_b.posY - this.posY; + double d5 = this.field_146042_b.posZ - this.posZ; +@@ -531,15 +564,36 @@ + entityitem.motionY = d3 * d9 + (double)MathHelper.sqrt_double(d7) * 0.08D; + entityitem.motionZ = d5 * d9; + this.worldObj.spawnEntityInWorld(entityitem); +- this.field_146042_b.worldObj.spawnEntityInWorld(new EntityXPOrb(this.field_146042_b.worldObj, this.field_146042_b.posX, this.field_146042_b.posY + 0.5D, this.field_146042_b.posZ + 0.5D, this.rand.nextInt(6) + 1)); ++ // CraftBukkit - this.random.nextInt(6) + 1 -> playerFishEvent.getExpToDrop() ++ this.field_146042_b.worldObj.spawnEntityInWorld(new EntityXPOrb(this.field_146042_b.worldObj, this.field_146042_b.posX, this.field_146042_b.posY + 0.5D, this.field_146042_b.posZ + 0.5D, playerFishEvent.getExpToDrop())); + b0 = 1; + } + + if (this.field_146051_au) + { ++ // CraftBukkit start ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.field_146042_b.getBukkitEntity(), null, (Fish) this.getBukkitEntity(), PlayerFishEvent.State.IN_GROUND); ++ this.worldObj.getServer().getPluginManager().callEvent(playerFishEvent); ++ ++ if (playerFishEvent.isCancelled()) ++ { ++ this.setDead(); ++ this.field_146042_b.fishEntity = null; ++ return 0; ++ } ++ ++ // CraftBukkit end + b0 = 2; + } + ++ // CraftBukkit start ++ if (b0 == 0) ++ { ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((Player) this.field_146042_b.getBukkitEntity(), null, (Fish) this.getBukkitEntity(), PlayerFishEvent.State.FAILED_ATTEMPT); ++ this.worldObj.getServer().getPluginManager().callEvent(playerFishEvent); ++ } ++ ++ // CraftBukkit end + this.setDead(); + this.field_146042_b.fishEntity = null; + return b0; +@@ -580,7 +634,7 @@ + { + float f3 = f - f2; + this.field_146042_b.addStat(StatList.fishCaughtStat, 1); +- return ((WeightedRandomFishable)WeightedRandom.getRandomItem(this.rand, field_146036_f)).func_150708_a(this.rand); ++ return ((WeightedRandomFishable) WeightedRandom.getRandomItem(this.rand, EntityFishHook.field_146036_f)).func_150708_a(this.rand); // CraftBukkit - fix static reference to fish list + } + } + } diff --git a/patches/net/minecraft/entity/projectile/EntityLargeFireball.java.patch b/patches/net/minecraft/entity/projectile/EntityLargeFireball.java.patch new file mode 100644 index 0000000..b948d35 --- /dev/null +++ b/patches/net/minecraft/entity/projectile/EntityLargeFireball.java.patch @@ -0,0 +1,40 @@ +--- ../src-base/minecraft/net/minecraft/entity/projectile/EntityLargeFireball.java ++++ ../src-work/minecraft/net/minecraft/entity/projectile/EntityLargeFireball.java +@@ -9,6 +9,8 @@ + import net.minecraft.util.MovingObjectPosition; + import net.minecraft.world.World; + ++import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit ++ + public class EntityLargeFireball extends EntityFireball + { + public int field_92057_e = 1; +@@ -39,7 +41,17 @@ + p_70227_1_.entityHit.attackEntityFrom(DamageSource.causeFireballDamage(this, this.shootingEntity), 6.0F); + } + +- this.worldObj.newExplosion((Entity)null, this.posX, this.posY, this.posZ, (float)this.field_92057_e, true, this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); ++ // CraftBukkit start ++ ExplosionPrimeEvent event = new ExplosionPrimeEvent((org.bukkit.entity.Explosive) org.bukkit.craftbukkit.entity.CraftEntity.getEntity(this.worldObj.getServer(), this)); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ // give 'this' instead of (Entity) null so we know what causes the damage ++ this.worldObj.newExplosion(this, this.posX, this.posY, this.posZ, event.getRadius(), event.getFire(), this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); ++ } ++ ++ // CraftBukkit end + this.setDead(); + } + } +@@ -56,7 +68,8 @@ + + if (p_70037_1_.hasKey("ExplosionPower", 99)) + { +- this.field_92057_e = p_70037_1_.getInteger("ExplosionPower"); ++ // CraftBukkit - set bukkitYield when setting explosionpower ++ this.bukkitYield = this.field_92057_e = p_70037_1_.getInteger("ExplosionPower"); + } + } + } diff --git a/patches/net/minecraft/entity/projectile/EntityPotion.java.patch b/patches/net/minecraft/entity/projectile/EntityPotion.java.patch new file mode 100644 index 0000000..98d96f7 --- /dev/null +++ b/patches/net/minecraft/entity/projectile/EntityPotion.java.patch @@ -0,0 +1,89 @@ +--- ../src-base/minecraft/net/minecraft/entity/projectile/EntityPotion.java ++++ ../src-work/minecraft/net/minecraft/entity/projectile/EntityPotion.java +@@ -14,9 +14,16 @@ + import net.minecraft.util.MovingObjectPosition; + import net.minecraft.world.World; + ++// CraftBukkit start ++import java.util.HashMap; ++import net.minecraft.entity.player.EntityPlayerMP; ++import org.bukkit.craftbukkit.entity.CraftLivingEntity; ++import org.bukkit.entity.LivingEntity; ++// CraftBukkit end ++ + public class EntityPotion extends EntityThrowable + { +- private ItemStack potionDamage; ++ public ItemStack potionDamage; // CraftBukkit private --> public + private static final String __OBFID = "CL_00001727"; + + public EntityPotion(World p_i1788_1_) +@@ -88,14 +95,16 @@ + { + List list = Items.potionitem.getEffects(this.potionDamage); + +- if (list != null && !list.isEmpty()) ++ if (true || list != null && !list.isEmpty()) // CraftBukkit - Call event even if no effects to apply + { + AxisAlignedBB axisalignedbb = this.boundingBox.expand(4.0D, 2.0D, 4.0D); + List list1 = this.worldObj.getEntitiesWithinAABB(EntityLivingBase.class, axisalignedbb); + +- if (list1 != null && !list1.isEmpty()) ++ if (list1 != null) // CraftBukkit - Run code even if there are no entities around + { + Iterator iterator = list1.iterator(); ++ // CraftBukkit ++ HashMap affected = new HashMap(); + + while (iterator.hasNext()) + { +@@ -111,6 +120,25 @@ + d1 = 1.0D; + } + ++ // CraftBukkit start ++ affected.put((LivingEntity) entitylivingbase.getBukkitEntity(), d1); ++ } ++ } ++ ++ org.bukkit.event.entity.PotionSplashEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPotionSplashEvent(this, affected); ++ ++ if (!event.isCancelled() && list != null && !list.isEmpty()) // do not process effects if there are no effects to process ++ { ++ for (LivingEntity victim : event.getAffectedEntities()) ++ { ++ if (!(victim instanceof CraftLivingEntity)) ++ { ++ continue; ++ } ++ ++ EntityLivingBase entitylivingbase = ((CraftLivingEntity) victim).getHandle(); ++ double d1 = event.getIntensity(victim); ++ // CraftBukkit end + Iterator iterator1 = list.iterator(); + + while (iterator1.hasNext()) +@@ -118,9 +146,22 @@ + PotionEffect potioneffect = (PotionEffect)iterator1.next(); + int i = potioneffect.getPotionID(); + ++ // CraftBukkit start - Abide by PVP settings - for players only! ++ if (!this.worldObj.pvpMode && this.getThrower() instanceof EntityPlayerMP && entitylivingbase instanceof EntityPlayerMP && entitylivingbase != this.getThrower()) ++ { ++ // Block SLOWER_MOVEMENT, SLOWER_DIG, HARM, BLINDNESS, HUNGER, WEAKNESS and POISON potions ++ if (i == 2 || i == 4 || i == 7 || i == 15 || i == 17 || i == 18 || i == 19) ++ { ++ continue; ++ } ++ } ++ ++ // CraftBukkit end ++ + if (Potion.potionTypes[i].isInstant()) + { +- Potion.potionTypes[i].affectEntity(this.getThrower(), entitylivingbase, potioneffect.getAmplifier(), d1); ++ // CraftBukkit - Added 'this' ++ Potion.potionTypes[i].applyInstantEffect(this.getThrower(), entitylivingbase, potioneffect.getAmplifier(), d1, this); + } + else + { diff --git a/patches/net/minecraft/entity/projectile/EntitySmallFireball.java.patch b/patches/net/minecraft/entity/projectile/EntitySmallFireball.java.patch new file mode 100644 index 0000000..bebfed8 --- /dev/null +++ b/patches/net/minecraft/entity/projectile/EntitySmallFireball.java.patch @@ -0,0 +1,44 @@ +--- ../src-base/minecraft/net/minecraft/entity/projectile/EntitySmallFireball.java ++++ ../src-work/minecraft/net/minecraft/entity/projectile/EntitySmallFireball.java +@@ -6,6 +6,8 @@ + import net.minecraft.util.MovingObjectPosition; + import net.minecraft.world.World; + ++import org.bukkit.event.entity.EntityCombustByEntityEvent; // CraftBukkit ++ + public class EntitySmallFireball extends EntityFireball + { + private static final String __OBFID = "CL_00001721"; +@@ -36,7 +38,16 @@ + { + if (!p_70227_1_.entityHit.isImmuneToFire() && p_70227_1_.entityHit.attackEntityFrom(DamageSource.causeFireballDamage(this, this.shootingEntity), 5.0F)) + { +- p_70227_1_.entityHit.setFire(5); ++ // CraftBukkit start - Entity damage by entity event + combust event ++ EntityCombustByEntityEvent event = new EntityCombustByEntityEvent((org.bukkit.entity.Projectile) this.getBukkitEntity(), p_70227_1_.entityHit.getBukkitEntity(), 5); ++ p_70227_1_.entityHit.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ p_70227_1_.entityHit.setFire(event.getDuration()); ++ } ++ ++ // CraftBukkit end + } + } + else +@@ -68,7 +79,13 @@ + + if (this.worldObj.isAirBlock(i, j, k)) + { +- this.worldObj.setBlock(i, j, k, Blocks.fire); ++ // CraftBukkit start ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(worldObj, i, j, k, this).isCancelled()) ++ { ++ this.worldObj.setBlock(i, j, k, Blocks.fire); ++ } ++ ++ // CraftBukkit end + } + } + diff --git a/patches/net/minecraft/entity/projectile/EntityThrowable.java.patch b/patches/net/minecraft/entity/projectile/EntityThrowable.java.patch new file mode 100644 index 0000000..6905edb --- /dev/null +++ b/patches/net/minecraft/entity/projectile/EntityThrowable.java.patch @@ -0,0 +1,45 @@ +--- ../src-base/minecraft/net/minecraft/entity/projectile/EntityThrowable.java ++++ ../src-work/minecraft/net/minecraft/entity/projectile/EntityThrowable.java +@@ -24,8 +24,8 @@ + private Block field_145785_f; + protected boolean inGround; + public int throwableShake; +- private EntityLivingBase thrower; +- private String throwerName; ++ public EntityLivingBase thrower; // CraftBukkit - private -> public ++ public String throwerName; // CraftBukkit - private -> public + private int ticksInGround; + private int ticksInAir; + private static final String __OBFID = "CL_00001723"; +@@ -50,6 +50,7 @@ + { + super(p_i1777_1_); + this.thrower = p_i1777_2_; ++ this.projectileSource = (org.bukkit.entity.LivingEntity) p_i1777_2_.getBukkitEntity(); // CraftBukkit + this.setSize(0.25F, 0.25F); + this.setLocationAndAngles(p_i1777_2_.posX, p_i1777_2_.posY + (double)p_i1777_2_.getEyeHeight(), p_i1777_2_.posZ, p_i1777_2_.rotationYaw, p_i1777_2_.rotationPitch); + this.posX -= (double)(MathHelper.cos(this.rotationYaw / 180.0F * (float)Math.PI) * 0.16F); +@@ -187,7 +188,7 @@ + + if (movingobjectposition1 != null) + { +- double d1 = vec3.distanceTo(movingobjectposition1.hitVec); ++ double d1 = vec3.squareDistanceTo(movingobjectposition1.hitVec); // CraftBukkit - distance efficiency + + if (d1 < d0 || d0 == 0.0D) + { +@@ -213,6 +214,14 @@ + else + { + this.onImpact(movingobjectposition); ++ ++ // CraftBukkit start ++ if (this.isDead) ++ { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callProjectileHitEvent(this); ++ } ++ ++ // CraftBukkit end + } + } + diff --git a/patches/net/minecraft/entity/projectile/EntityWitherSkull.java.patch b/patches/net/minecraft/entity/projectile/EntityWitherSkull.java.patch new file mode 100644 index 0000000..cb1d4fd --- /dev/null +++ b/patches/net/minecraft/entity/projectile/EntityWitherSkull.java.patch @@ -0,0 +1,38 @@ +--- ../src-base/minecraft/net/minecraft/entity/projectile/EntityWitherSkull.java ++++ ../src-work/minecraft/net/minecraft/entity/projectile/EntityWitherSkull.java +@@ -13,6 +13,8 @@ + import net.minecraft.world.Explosion; + import net.minecraft.world.World; + ++import org.bukkit.event.entity.ExplosionPrimeEvent; // CraftBukkit ++ + public class EntityWitherSkull extends EntityFireball + { + private static final String __OBFID = "CL_00001728"; +@@ -68,7 +70,7 @@ + { + if (p_70227_1_.entityHit.attackEntityFrom(DamageSource.causeMobDamage(this.shootingEntity), 8.0F) && !p_70227_1_.entityHit.isEntityAlive()) + { +- this.shootingEntity.heal(5.0F); ++ this.shootingEntity.heal(5.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.WITHER); // CraftBukkit + } + } + else +@@ -96,7 +98,16 @@ + } + } + +- this.worldObj.newExplosion(this, this.posX, this.posY, this.posZ, 1.0F, false, this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); ++ // CraftBukkit start ++ ExplosionPrimeEvent event = new ExplosionPrimeEvent(this.getBukkitEntity(), 1.0F, false); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ this.worldObj.newExplosion(this, this.posX, this.posY, this.posZ, event.getRadius(), event.getFire(), this.worldObj.getGameRules().getGameRuleBooleanValue("mobGriefing")); ++ } ++ ++ // CraftBukkit end + this.setDead(); + } + } diff --git a/patches/net/minecraft/init/Bootstrap.java.patch b/patches/net/minecraft/init/Bootstrap.java.patch new file mode 100644 index 0000000..42d25de --- /dev/null +++ b/patches/net/minecraft/init/Bootstrap.java.patch @@ -0,0 +1,454 @@ +--- ../src-base/minecraft/net/minecraft/init/Bootstrap.java ++++ ../src-work/minecraft/net/minecraft/init/Bootstrap.java +@@ -1,6 +1,7 @@ + package net.minecraft.init; + + import java.util.Random; ++ + import net.minecraft.block.Block; + import net.minecraft.block.BlockDispenser; + import net.minecraft.block.BlockFire; +@@ -34,6 +35,11 @@ + import net.minecraft.util.EnumFacing; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.block.BlockDispenseEvent; ++// CraftBukkit end ++ + public class Bootstrap + { + private static boolean field_151355_a = false; +@@ -116,14 +122,48 @@ + double d0 = p_82487_1_.getX() + (double)enumfacing.getFrontOffsetX(); + double d1 = (double)((float)p_82487_1_.getYInt() + 0.2F); + double d2 = p_82487_1_.getZ() + (double)enumfacing.getFrontOffsetZ(); +- Entity entity = ItemMonsterPlacer.spawnCreature(p_82487_1_.getWorld(), p_82487_2_.getItemDamage(), d0, d1, d2); ++ // CraftBukkit start ++ World world = p_82487_1_.getWorld(); ++ ItemStack itemstack1 = p_82487_2_.splitStack(1); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(p_82487_1_.getXInt(), p_82487_1_.getYInt(), p_82487_1_.getZInt()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1, d2)); + ++ if (!BlockDispenser.eventFired) ++ { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) ++ { ++ p_82487_2_.stackSize++; ++ return p_82487_2_; ++ } ++ ++ if (!event.getItem().equals(craftItem)) ++ { ++ p_82487_2_.stackSize++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); ++ ++ if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem != this) ++ { ++ ibehaviordispenseitem.dispense(p_82487_1_, eventStack); ++ return p_82487_2_; ++ } ++ } ++ ++ itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); ++ Entity entity = ItemMonsterPlacer.spawnCreature(p_82487_1_.getWorld(), p_82487_2_.getItemDamage(), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); ++ + if (entity instanceof EntityLivingBase && p_82487_2_.hasDisplayName()) + { +- ((EntityLiving)entity).setCustomNameTag(p_82487_2_.getDisplayName()); ++ ((EntityLiving) entity).setCustomNameTag(p_82487_2_.getDisplayName()); + } + +- p_82487_2_.splitStack(1); ++ // p_82487_2_.splitStack(1); // Handled during event processing ++ // CraftBukkit end + return p_82487_2_; + } + }); +@@ -136,9 +176,43 @@ + double d0 = p_82487_1_.getX() + (double)enumfacing.getFrontOffsetX(); + double d1 = (double)((float)p_82487_1_.getYInt() + 0.2F); + double d2 = p_82487_1_.getZ() + (double)enumfacing.getFrontOffsetZ(); +- EntityFireworkRocket entityfireworkrocket = new EntityFireworkRocket(p_82487_1_.getWorld(), d0, d1, d2, p_82487_2_); ++ // CraftBukkit start ++ World world = p_82487_1_.getWorld(); ++ ItemStack itemstack1 = p_82487_2_.splitStack(1); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(p_82487_1_.getXInt(), p_82487_1_.getYInt(), p_82487_1_.getZInt()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1, d2)); ++ ++ if (!BlockDispenser.eventFired) ++ { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) ++ { ++ p_82487_2_.stackSize++; ++ return p_82487_2_; ++ } ++ ++ if (!event.getItem().equals(craftItem)) ++ { ++ p_82487_2_.stackSize++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); ++ ++ if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem != this) ++ { ++ ibehaviordispenseitem.dispense(p_82487_1_, eventStack); ++ return p_82487_2_; ++ } ++ } ++ ++ itemstack1 = CraftItemStack.asNMSCopy(event.getItem()); ++ EntityFireworkRocket entityfireworkrocket = new EntityFireworkRocket(p_82487_1_.getWorld(), event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), itemstack1); + p_82487_1_.getWorld().spawnEntityInWorld(entityfireworkrocket); +- p_82487_2_.splitStack(1); ++ // p_82487_2_.splitStack(1); // Handled during event processing ++ // CraftBukkit end + return p_82487_2_; + } + protected void playDispenseSound(IBlockSource p_82485_1_) +@@ -161,8 +235,42 @@ + double d3 = random.nextGaussian() * 0.05D + (double)enumfacing.getFrontOffsetX(); + double d4 = random.nextGaussian() * 0.05D + (double)enumfacing.getFrontOffsetY(); + double d5 = random.nextGaussian() * 0.05D + (double)enumfacing.getFrontOffsetZ(); +- world.spawnEntityInWorld(new EntitySmallFireball(world, d0, d1, d2, d3, d4, d5)); +- p_82487_2_.splitStack(1); ++ // CraftBukkit start ++ ItemStack itemstack1 = p_82487_2_.splitStack(1); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(p_82487_1_.getXInt(), p_82487_1_.getYInt(), p_82487_1_.getZInt()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d3, d4, d5)); ++ ++ if (!BlockDispenser.eventFired) ++ { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) ++ { ++ p_82487_2_.stackSize++; ++ return p_82487_2_; ++ } ++ ++ if (!event.getItem().equals(craftItem)) ++ { ++ p_82487_2_.stackSize++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); ++ ++ if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem != this) ++ { ++ ibehaviordispenseitem.dispense(p_82487_1_, eventStack); ++ return p_82487_2_; ++ } ++ } ++ ++ EntitySmallFireball entitysmallfireball = new EntitySmallFireball(world, d0, d1, d2, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); ++ entitysmallfireball.projectileSource = new org.bukkit.craftbukkit.projectiles.CraftBlockProjectileSource((TileEntityDispenser) p_82487_1_.getBlockTileEntity()); ++ world.spawnEntityInWorld(entitysmallfireball); ++ // p_82487_2_.splitStack(1); // Handled during event processing ++ // CraftBukkit end + return p_82487_2_; + } + protected void playDispenseSound(IBlockSource p_82485_1_) +@@ -201,9 +309,41 @@ + d3 = 0.0D; + } + +- EntityBoat entityboat = new EntityBoat(world, d0, d1 + d3, d2); ++ // CraftBukkit start ++ ItemStack itemstack1 = p_82487_2_.splitStack(1); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(p_82487_1_.getXInt(), p_82487_1_.getYInt(), p_82487_1_.getZInt()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(d0, d1 + d3, d2)); ++ ++ if (!BlockDispenser.eventFired) ++ { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) ++ { ++ p_82487_2_.stackSize++; ++ return p_82487_2_; ++ } ++ ++ if (!event.getItem().equals(craftItem)) ++ { ++ p_82487_2_.stackSize++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); ++ ++ if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem != this) ++ { ++ ibehaviordispenseitem.dispense(p_82487_1_, eventStack); ++ return p_82487_2_; ++ } ++ } ++ ++ EntityBoat entityboat = new EntityBoat(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ()); ++ // CraftBukkit end + world.spawnEntityInWorld(entityboat); +- p_82487_2_.splitStack(1); ++ // p_82487_2_.splitStack(1); // CraftBukkit - handled during event processing + return p_82487_2_; + } + protected void playDispenseSound(IBlockSource p_82485_1_) +@@ -217,16 +357,67 @@ + private static final String __OBFID = "CL_00001399"; + public ItemStack dispenseStack(IBlockSource p_82487_1_, ItemStack p_82487_2_) + { +- ItemBucket itembucket = (ItemBucket)p_82487_2_.getItem(); ++ ItemBucket itembucket = (ItemBucket) p_82487_2_.getItem(); + int i = p_82487_1_.getXInt(); + int j = p_82487_1_.getYInt(); + int k = p_82487_1_.getZInt(); + EnumFacing enumfacing = BlockDispenser.func_149937_b(p_82487_1_.getBlockMetadata()); ++ // CraftBukkit start ++ World world = p_82487_1_.getWorld(); ++ int x = i + enumfacing.getFrontOffsetX(); ++ int y = j + enumfacing.getFrontOffsetY(); ++ int z = k + enumfacing.getFrontOffsetZ(); + ++ if (world.isAirBlock(x, y, z) || !world.getBlock(x, y, z).getMaterial().isSolid()) ++ { ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(i, j, k); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(p_82487_2_); ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(x, y, z)); ++ ++ if (!BlockDispenser.eventFired) ++ { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) ++ { ++ return p_82487_2_; ++ } ++ ++ if (!event.getItem().equals(craftItem)) ++ { ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); ++ ++ if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem != this) ++ { ++ ibehaviordispenseitem.dispense(p_82487_1_, eventStack); ++ return p_82487_2_; ++ } ++ } ++ ++ itembucket = (ItemBucket) CraftItemStack.asNMSCopy(event.getItem()).getItem(); ++ } ++ ++ // CraftBukkit end ++ + if (itembucket.tryPlaceContainedLiquid(p_82487_1_.getWorld(), i + enumfacing.getFrontOffsetX(), j + enumfacing.getFrontOffsetY(), k + enumfacing.getFrontOffsetZ())) + { +- p_82487_2_.func_150996_a(Items.bucket); +- p_82487_2_.stackSize = 1; ++ // CraftBukkit start - Handle stacked buckets ++ Item item = Items.bucket; ++ ++ if (--p_82487_2_.stackSize == 0) ++ { ++ p_82487_2_.func_150996_a(Items.bucket); ++ p_82487_2_.stackSize = 1; ++ } ++ else if (((TileEntityDispenser) p_82487_1_.getBlockTileEntity()).func_146019_a(new ItemStack(item)) < 0) ++ { ++ this.field_150841_b.dispense(p_82487_1_, new ItemStack(item)); ++ } ++ ++ // CraftBukkit end + return p_82487_2_; + } + else +@@ -266,6 +457,36 @@ + item = Items.lava_bucket; + } + ++ // CraftBukkit start ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(p_82487_1_.getXInt(), p_82487_1_.getYInt(), p_82487_1_.getZInt()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(p_82487_2_); ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(i, j, k)); ++ ++ if (!BlockDispenser.eventFired) ++ { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) ++ { ++ return p_82487_2_; ++ } ++ ++ if (!event.getItem().equals(craftItem)) ++ { ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); ++ ++ if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem != this) ++ { ++ ibehaviordispenseitem.dispense(p_82487_1_, eventStack); ++ return p_82487_2_; ++ } ++ } ++ ++ // CraftBukkit end ++ + world.setBlockToAir(i, j, k); + + if (--p_82487_2_.stackSize == 0) +@@ -292,16 +513,51 @@ + int i = p_82487_1_.getXInt() + enumfacing.getFrontOffsetX(); + int j = p_82487_1_.getYInt() + enumfacing.getFrontOffsetY(); + int k = p_82487_1_.getZInt() + enumfacing.getFrontOffsetZ(); ++ // CraftBukkit start ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(p_82487_1_.getXInt(), p_82487_1_.getYInt(), p_82487_1_.getZInt()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(p_82487_2_); ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); + +- if (world.isAirBlock(i, j, k)) ++ if (!BlockDispenser.eventFired) + { +- world.setBlock(i, j, k, Blocks.fire); ++ world.getServer().getPluginManager().callEvent(event); ++ } + +- if (p_82487_2_.attemptDamageItem(1, world.rand)) ++ if (event.isCancelled()) ++ { ++ return p_82487_2_; ++ } ++ ++ if (!event.getItem().equals(craftItem)) ++ { ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); ++ ++ if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem != this) + { +- p_82487_2_.stackSize = 0; ++ ibehaviordispenseitem.dispense(p_82487_1_, eventStack); ++ return p_82487_2_; + } + } ++ ++ // CraftBukkit end ++ ++ if (world.isAirBlock(i, j, k)) ++ { ++ // CraftBukkit start - Ignition by dispensing flint and steel ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(world, i, j, k, p_82487_1_.getXInt(), p_82487_1_.getYInt(), p_82487_1_.getZInt()).isCancelled()) ++ { ++ world.setBlock(i, j, k, Blocks.fire); ++ ++ if (p_82487_2_.attemptDamageItem(1, world.rand)) ++ { ++ p_82487_2_.stackSize = 0; ++ } ++ } ++ ++ // CraftBukkit end ++ } + else if (world.getBlock(i, j, k) == Blocks.tnt) + { + Blocks.tnt.onBlockDestroyedByPlayer(world, i, j, k, 1); +@@ -339,7 +595,36 @@ + int i = p_82487_1_.getXInt() + enumfacing.getFrontOffsetX(); + int j = p_82487_1_.getYInt() + enumfacing.getFrontOffsetY(); + int k = p_82487_1_.getZInt() + enumfacing.getFrontOffsetZ(); ++ // CraftBukkit start ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(p_82487_1_.getXInt(), p_82487_1_.getYInt(), p_82487_1_.getZInt()); ++ CraftItemStack craftItem = CraftItemStack.asNewCraftStack(p_82487_2_.getItem()); ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(0, 0, 0)); + ++ if (!BlockDispenser.eventFired) ++ { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) ++ { ++ return p_82487_2_; ++ } ++ ++ if (!event.getItem().equals(craftItem)) ++ { ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); ++ ++ if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem != this) ++ { ++ ibehaviordispenseitem.dispense(p_82487_1_, eventStack); ++ return p_82487_2_; ++ } ++ } ++ ++ // CraftBukkit end ++ + if (ItemDye.func_150919_a(p_82487_2_, world, i, j, k)) + { + if (!world.isRemote) +@@ -381,9 +666,41 @@ + int i = p_82487_1_.getXInt() + enumfacing.getFrontOffsetX(); + int j = p_82487_1_.getYInt() + enumfacing.getFrontOffsetY(); + int k = p_82487_1_.getZInt() + enumfacing.getFrontOffsetZ(); +- EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, (double)((float)i + 0.5F), (double)((float)j + 0.5F), (double)((float)k + 0.5F), (EntityLivingBase)null); ++ // CraftBukkit start ++ ItemStack itemstack1 = p_82487_2_.splitStack(1); ++ org.bukkit.block.Block block = world.getWorld().getBlockAt(p_82487_1_.getXInt(), p_82487_1_.getYInt(), p_82487_1_.getZInt()); ++ CraftItemStack craftItem = CraftItemStack.asCraftMirror(itemstack1); ++ BlockDispenseEvent event = new BlockDispenseEvent(block, craftItem.clone(), new org.bukkit.util.Vector(i + 0.5, j + 0.5, k + 0.5)); ++ ++ if (!BlockDispenser.eventFired) ++ { ++ world.getServer().getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) ++ { ++ p_82487_2_.stackSize++; ++ return p_82487_2_; ++ } ++ ++ if (!event.getItem().equals(craftItem)) ++ { ++ p_82487_2_.stackSize++; ++ // Chain to handler for new item ++ ItemStack eventStack = CraftItemStack.asNMSCopy(event.getItem()); ++ IBehaviorDispenseItem ibehaviordispenseitem = (IBehaviorDispenseItem) BlockDispenser.dispenseBehaviorRegistry.getObject(eventStack.getItem()); ++ ++ if (ibehaviordispenseitem != IBehaviorDispenseItem.itemDispenseBehaviorProvider && ibehaviordispenseitem != this) ++ { ++ ibehaviordispenseitem.dispense(p_82487_1_, eventStack); ++ return p_82487_2_; ++ } ++ } ++ ++ EntityTNTPrimed entitytntprimed = new EntityTNTPrimed(world, event.getVelocity().getX(), event.getVelocity().getY(), event.getVelocity().getZ(), (EntityLivingBase) null); ++ // CraftBukkit end + world.spawnEntityInWorld(entitytntprimed); +- --p_82487_2_.stackSize; ++ // --p_82487_2_.stackSize; // CraftBukkit - handled above + return p_82487_2_; + } + }); diff --git a/patches/net/minecraft/inventory/AnimalChest.java.patch b/patches/net/minecraft/inventory/AnimalChest.java.patch new file mode 100644 index 0000000..7972403 --- /dev/null +++ b/patches/net/minecraft/inventory/AnimalChest.java.patch @@ -0,0 +1,83 @@ +--- ../src-base/minecraft/net/minecraft/inventory/AnimalChest.java ++++ ../src-work/minecraft/net/minecraft/inventory/AnimalChest.java +@@ -3,6 +3,14 @@ + import cpw.mods.fml.relauncher.Side; + import cpw.mods.fml.relauncher.SideOnly; + ++// CraftBukkit start ++import java.util.List; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++import net.minecraft.entity.passive.EntityHorse; ++import net.minecraft.item.ItemStack; ++// CraftBukkit end ++ + public class AnimalChest extends InventoryBasic + { + private static final String __OBFID = "CL_00001731"; +@@ -12,6 +20,65 @@ + super(p_i1796_1_, false, p_i1796_2_); + } + ++ // CraftBukkit start ++ public List transaction = new java.util.ArrayList(); ++ private EntityHorse horse; ++ private int maxStack = MAX_STACK; ++ ++ public AnimalChest(String s, int i, EntityHorse horse) ++ { ++ this(s, i); ++ this.horse = horse; ++ } ++ ++ @Override ++ public ItemStack[] getContents() ++ { ++ return this.inventoryContents; ++ } ++ ++ @Override ++ public void onOpen(CraftHumanEntity who) ++ { ++ transaction.add(who); ++ } ++ ++ @Override ++ public void onClose(CraftHumanEntity who) ++ { ++ transaction.remove(who); ++ } ++ ++ @Override ++ public List getViewers() ++ { ++ return transaction; ++ } ++ ++ @Override ++ public org.bukkit.inventory.InventoryHolder getOwner() ++ { ++ return (org.bukkit.entity.Horse) this.horse.getBukkitEntity(); ++ } ++ ++ @Override ++ public void setMaxStackSize(int size) ++ { ++ maxStack = size; ++ } ++ ++ @Override ++ ++ /** ++ * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't ++ * this more of a set than a get?* ++ */ ++ public int getInventoryStackLimit() ++ { ++ return maxStack; ++ } ++ // CraftBukkit end ++ + @SideOnly(Side.CLIENT) + public AnimalChest(String p_i1797_1_, boolean p_i1797_2_, int p_i1797_3_) + { diff --git a/patches/net/minecraft/inventory/Container.java.patch b/patches/net/minecraft/inventory/Container.java.patch new file mode 100644 index 0000000..2cfc727 --- /dev/null +++ b/patches/net/minecraft/inventory/Container.java.patch @@ -0,0 +1,186 @@ +--- ../src-base/minecraft/net/minecraft/inventory/Container.java ++++ ../src-work/minecraft/net/minecraft/inventory/Container.java +@@ -13,6 +13,17 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.util.MathHelper; + ++// CraftBukkit start ++import java.util.HashMap; ++import java.util.Map; ++import net.minecraft.entity.player.EntityPlayerMP; ++import org.bukkit.craftbukkit.inventory.CraftInventory; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.Event.Result; ++import org.bukkit.event.inventory.InventoryDragEvent; ++import org.bukkit.inventory.InventoryView; ++// CraftBukkit end ++ + public abstract class Container + { + public List inventoryItemStacks = new ArrayList(); +@@ -21,12 +32,52 @@ + @SideOnly(Side.CLIENT) + private short transactionID; + private int field_94535_f = -1; +- private int field_94536_g; ++ public int field_94536_g; // CraftBukkit - private -> public + private final Set field_94537_h = new HashSet(); ++ public InventoryView bukkitView = null; // Cauldron ++ + protected List crafters = new ArrayList(); + private Set playerList = new HashSet(); + private static final String __OBFID = "CL_00001730"; + ++ // CraftBukkit start ++ public boolean checkReachable = true; ++ public InventoryView getBukkitView() { return bukkitView; } // Cauldron ++ public void transferTo(Container other, org.bukkit.craftbukkit.entity.CraftHumanEntity player) ++ { ++ InventoryView source = this.getBukkitView(), destination = other.getBukkitView(); ++ // Cauldron start - add null checks to skip modded inventories with no Bukkit wrappers, and ++ // catch AbstractMethodErrors for modded IInventory's with no onClose() ++ if (source != null) { ++ try { ++ ((CraftInventory) source.getTopInventory()).getInventory().onClose(player); ++ } catch (AbstractMethodError ex) { ++ // modded ++ } ++ ++ try { ++ ((CraftInventory) source.getBottomInventory()).getInventory().onClose(player); ++ } catch (AbstractMethodError ex) { ++ // modded ++ } ++ } ++ if (destination != null) { ++ try { ++ ((CraftInventory) destination.getTopInventory()).getInventory().onOpen(player); ++ } catch (AbstractMethodError ex) { ++ // modded ++ } ++ ++ try { ++ ((CraftInventory) destination.getBottomInventory()).getInventory().onOpen(player); ++ } catch (AbstractMethodError ex) { ++ // modded ++ } ++ } ++ // Cauldron end ++ } ++ // CraftBukkit end ++ + protected Slot addSlotToContainer(Slot p_75146_1_) + { + p_75146_1_.slotNumber = this.inventorySlots.size(); +@@ -39,7 +90,11 @@ + { + if (this.crafters.contains(p_75132_1_)) + { +- throw new IllegalArgumentException("Listener already listening"); ++ // Cauldron start - As we do not create a new player object on respawn, we need to update the client with changes if listener already exists ++ //throw new IllegalArgumentException("Listener already listening"); ++ p_75132_1_.sendContainerAndContentsToPlayer(this, this.getInventory()); ++ this.detectAndSendChanges(); ++ // Cauldron end + } + else + { +@@ -109,6 +164,10 @@ + + public Slot getSlot(int p_75139_1_) + { ++ // Cauldron start - vanilla compatibility. fixes NPE with ProjectRed's Item Stock Keeper ++ if (p_75139_1_ < 0 || p_75139_1_ >= this.inventorySlots.size()) ++ return null; ++ // Cauldron end + return (Slot)this.inventorySlots.get(p_75139_1_); + } + +@@ -168,6 +227,7 @@ + itemstack3 = inventoryplayer.getItemStack().copy(); + i1 = inventoryplayer.getItemStack().stackSize; + Iterator iterator = this.field_94537_h.iterator(); ++ Map draggedSlots = new HashMap(); // CraftBukkit - Store slots from drag in map (raw slot id -> new stack) + + while (iterator.hasNext()) + { +@@ -190,18 +250,55 @@ + } + + i1 -= itemstack1.stackSize - j1; +- slot1.putStack(itemstack1); ++ draggedSlots.put(slot1.slotNumber, itemstack1); // CraftBukkit - Put in map instead of setting + } + } + +- itemstack3.stackSize = i1; ++ // CraftBukkit start - InventoryDragEvent ++ InventoryView view = getBukkitView(); ++ org.bukkit.inventory.ItemStack newcursor = CraftItemStack.asCraftMirror(itemstack3); ++ newcursor.setAmount(i1); ++ Map eventmap = new HashMap(); + +- if (itemstack3.stackSize <= 0) ++ for (Map.Entry ditem : draggedSlots.entrySet()) + { +- itemstack3 = null; ++ eventmap.put(ditem.getKey(), CraftItemStack.asBukkitCopy(ditem.getValue())); + } + +- inventoryplayer.setItemStack(itemstack3); ++ // It's essential that we set the cursor to the new value here to prevent item duplication if a plugin closes the inventory. ++ ItemStack oldCursor = inventoryplayer.getItemStack(); ++ inventoryplayer.setItemStack(CraftItemStack.asNMSCopy(newcursor)); ++ InventoryDragEvent event = new InventoryDragEvent(view, (newcursor.getType() != org.bukkit.Material.AIR ? newcursor : null), CraftItemStack.asBukkitCopy(oldCursor), this.field_94535_f == i1, eventmap); // Should be dragButton ++ p_75144_4_.worldObj.getServer().getPluginManager().callEvent(event); ++ // Whether or not a change was made to the inventory that requires an update. ++ boolean needsUpdate = event.getResult() != Result.DEFAULT; ++ ++ if (event.getResult() != Result.DENY) ++ { ++ for (Map.Entry dslot : draggedSlots.entrySet()) ++ { ++ view.setItem(dslot.getKey(), CraftItemStack.asBukkitCopy(dslot.getValue())); ++ } ++ ++ // The only time the carried item will be set to null is if the inventory is closed by the server. ++ // If the inventory is closed by the server, then the cursor items are dropped. This is why we change the cursor early. ++ if (inventoryplayer.getItemStack() != null) ++ { ++ inventoryplayer.setItemStack(CraftItemStack.asNMSCopy(event.getCursor())); ++ needsUpdate = true; ++ } ++ } ++ else ++ { ++ inventoryplayer.setItemStack(oldCursor); ++ } ++ ++ if (needsUpdate && p_75144_4_ instanceof EntityPlayerMP) ++ { ++ ((EntityPlayerMP) p_75144_4_).sendContainerToPlayer(this); ++ } ++ ++ // CraftBukkit end + } + + this.func_94533_d(); +@@ -235,10 +332,17 @@ + + if (p_75144_2_ == 1) + { +- p_75144_4_.dropPlayerItemWithRandomChoice(inventoryplayer.getItemStack().splitStack(1), true); ++ // CraftBukkit start - Store a reference ++ ItemStack itemstack4 = inventoryplayer.getItemStack(); + + if (inventoryplayer.getItemStack().stackSize == 0) + { ++ p_75144_4_.dropPlayerItemWithRandomChoice(inventoryplayer.getItemStack().splitStack(1), true); ++ } ++ ++ if (itemstack4.stackSize == 0) ++ { ++ // CraftBukkit end + inventoryplayer.setItemStack((ItemStack)null); + } + } diff --git a/patches/net/minecraft/inventory/ContainerBeacon.java.patch b/patches/net/minecraft/inventory/ContainerBeacon.java.patch new file mode 100644 index 0000000..edb50c4 --- /dev/null +++ b/patches/net/minecraft/inventory/ContainerBeacon.java.patch @@ -0,0 +1,62 @@ +--- ../src-base/minecraft/net/minecraft/inventory/ContainerBeacon.java ++++ ../src-work/minecraft/net/minecraft/inventory/ContainerBeacon.java +@@ -8,6 +8,8 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.tileentity.TileEntityBeacon; + ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit ++ + public class ContainerBeacon extends Container + { + private TileEntityBeacon tileBeacon; +@@ -15,10 +17,15 @@ + private int field_82865_g; + private int field_82867_h; + private int field_82868_i; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private InventoryPlayer player; ++ // CraftBukkit end + private static final String __OBFID = "CL_00001735"; + + public ContainerBeacon(InventoryPlayer p_i1802_1_, TileEntityBeacon p_i1802_2_) + { ++ player = p_i1802_1_; // CraftBukkit + this.tileBeacon = p_i1802_2_; + this.addSlotToContainer(this.beaconSlot = new ContainerBeacon.BeaconSlot(p_i1802_2_, 0, 136, 110)); + byte b0 = 36; +@@ -77,6 +84,13 @@ + + public boolean canInteractWith(EntityPlayer p_75145_1_) + { ++ // CraftBukkit start ++ if (!this.checkReachable) ++ { ++ return true; ++ } ++ // CraftBukkit end ++ + return this.tileBeacon.isUseableByPlayer(p_75145_1_); + } + +@@ -145,6 +159,20 @@ + return itemstack; + } + ++ // CraftBukkit start ++ public CraftInventoryView getBukkitView() ++ { ++ if (bukkitEntity != null) ++ { ++ return bukkitEntity; ++ } ++ ++ org.bukkit.craftbukkit.inventory.CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryBeacon(this.tileBeacon); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end ++ + class BeaconSlot extends Slot + { + private static final String __OBFID = "CL_00001736"; diff --git a/patches/net/minecraft/inventory/ContainerBrewingStand.java.patch b/patches/net/minecraft/inventory/ContainerBrewingStand.java.patch new file mode 100644 index 0000000..0aa2974 --- /dev/null +++ b/patches/net/minecraft/inventory/ContainerBrewingStand.java.patch @@ -0,0 +1,63 @@ +--- ../src-base/minecraft/net/minecraft/inventory/ContainerBrewingStand.java ++++ ../src-work/minecraft/net/minecraft/inventory/ContainerBrewingStand.java +@@ -10,15 +10,25 @@ + import net.minecraft.stats.AchievementList; + import net.minecraft.tileentity.TileEntityBrewingStand; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftInventoryBrewer; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerBrewingStand extends Container + { + private TileEntityBrewingStand tileBrewingStand; + private final Slot theSlot; + private int brewTime; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private InventoryPlayer player; ++ // CraftBukkit end + private static final String __OBFID = "CL_00001737"; + + public ContainerBrewingStand(InventoryPlayer p_i1805_1_, TileEntityBrewingStand p_i1805_2_) + { ++ this.player = p_i1805_1_; // CraftBukkit + this.tileBrewingStand = p_i1805_2_; + this.addSlotToContainer(new ContainerBrewingStand.Potion(p_i1805_1_.player, p_i1805_2_, 0, 56, 46)); + this.addSlotToContainer(new ContainerBrewingStand.Potion(p_i1805_1_.player, p_i1805_2_, 1, 79, 53)); +@@ -74,6 +84,13 @@ + + public boolean canInteractWith(EntityPlayer p_75145_1_) + { ++ // CraftBukkit start ++ if (!this.checkReachable) ++ { ++ return true; ++ } ++ // CraftBukkit end ++ + return this.tileBrewingStand.isUseableByPlayer(p_75145_1_); + } + +@@ -152,6 +169,20 @@ + return itemstack; + } + ++ // CraftBukkit start ++ public CraftInventoryView getBukkitView() ++ { ++ if (bukkitEntity != null) ++ { ++ return bukkitEntity; ++ } ++ ++ CraftInventoryBrewer inventory = new CraftInventoryBrewer(this.tileBrewingStand); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end ++ + class Ingredient extends Slot + { + private static final String __OBFID = "CL_00001738"; diff --git a/patches/net/minecraft/inventory/ContainerChest.java.patch b/patches/net/minecraft/inventory/ContainerChest.java.patch new file mode 100644 index 0000000..1db5e5c --- /dev/null +++ b/patches/net/minecraft/inventory/ContainerChest.java.patch @@ -0,0 +1,77 @@ +--- ../src-base/minecraft/net/minecraft/inventory/ContainerChest.java ++++ ../src-work/minecraft/net/minecraft/inventory/ContainerChest.java +@@ -3,10 +3,46 @@ + import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.item.ItemStack; + ++// CraftBukkit start ++import net.minecraft.entity.player.InventoryPlayer; ++import org.bukkit.craftbukkit.inventory.CraftInventory; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerChest extends Container + { +- private IInventory lowerChestInventory; ++ public IInventory lowerChestInventory; // CraftBukkit - private->public + private int numRows; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private InventoryPlayer player; ++ ++ public CraftInventoryView getBukkitView() ++ { ++ if (bukkitEntity != null || player == null) // Cauldron ++ { ++ return bukkitEntity; ++ } ++ ++ CraftInventory inventory; ++ ++ if (this.lowerChestInventory instanceof InventoryPlayer) ++ { ++ inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryPlayer((InventoryPlayer) this.lowerChestInventory); ++ } ++ else if (this.lowerChestInventory instanceof InventoryLargeChest) ++ { ++ inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) this.lowerChestInventory); ++ } ++ else ++ { ++ inventory = new CraftInventory(this.lowerChestInventory); ++ } ++ ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + private static final String __OBFID = "CL_00001742"; + + public ContainerChest(IInventory p_i1806_1_, IInventory p_i1806_2_) +@@ -15,6 +51,12 @@ + this.numRows = p_i1806_2_.getSizeInventory() / 9; + p_i1806_2_.openInventory(); + int i = (this.numRows - 4) * 18; ++ // CraftBukkit start - Save player ++ if (p_i1806_1_ instanceof InventoryPlayer) // Cauldron - make sure it is an InventoryPlayer before casting ++ { ++ this.player = (InventoryPlayer) p_i1806_1_; ++ } ++ // CraftBukkit end + int j; + int k; + +@@ -42,6 +84,13 @@ + + public boolean canInteractWith(EntityPlayer p_75145_1_) + { ++ // CraftBukkit start ++ if (!this.checkReachable) ++ { ++ return true; ++ } ++ // CraftBukkit end ++ + return this.lowerChestInventory.isUseableByPlayer(p_75145_1_); + } + diff --git a/patches/net/minecraft/inventory/ContainerDispenser.java.patch b/patches/net/minecraft/inventory/ContainerDispenser.java.patch new file mode 100644 index 0000000..e1578ab --- /dev/null +++ b/patches/net/minecraft/inventory/ContainerDispenser.java.patch @@ -0,0 +1,65 @@ +--- ../src-base/minecraft/net/minecraft/inventory/ContainerDispenser.java ++++ ../src-work/minecraft/net/minecraft/inventory/ContainerDispenser.java +@@ -4,14 +4,28 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.tileentity.TileEntityDispenser; + ++// CraftBukkit start ++import net.minecraft.entity.player.InventoryPlayer; ++import org.bukkit.craftbukkit.inventory.CraftInventory; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerDispenser extends Container + { +- private TileEntityDispenser tileDispenser; ++ public TileEntityDispenser tileDispenser; // CraftBukkit - private -> public ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private InventoryPlayer player; ++ // CraftBukkit end + private static final String __OBFID = "CL_00001763"; + + public ContainerDispenser(IInventory p_i1825_1_, TileEntityDispenser p_i1825_2_) + { + this.tileDispenser = p_i1825_2_; ++ // CraftBukkit start - Save player ++ // TODO: Should we check to make sure it really is an InventoryPlayer? ++ this.player = (InventoryPlayer)p_i1825_1_; ++ // CraftBukkit end + int i; + int j; + +@@ -39,6 +53,13 @@ + + public boolean canInteractWith(EntityPlayer p_75145_1_) + { ++ // CraftBukkit start ++ if (!this.checkReachable) ++ { ++ return true; ++ } ++ // CraftBukkit end ++ + return this.tileDispenser.isUseableByPlayer(p_75145_1_); + } + +@@ -83,4 +104,18 @@ + + return itemstack; + } ++ ++ // CraftBukkit start ++ public CraftInventoryView getBukkitView() ++ { ++ if (bukkitEntity != null) ++ { ++ return bukkitEntity; ++ } ++ ++ CraftInventory inventory = new CraftInventory(this.tileDispenser); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/inventory/ContainerEnchantment.java.patch b/patches/net/minecraft/inventory/ContainerEnchantment.java.patch new file mode 100644 index 0000000..a838cdf --- /dev/null +++ b/patches/net/minecraft/inventory/ContainerEnchantment.java.patch @@ -0,0 +1,208 @@ +--- ../src-base/minecraft/net/minecraft/inventory/ContainerEnchantment.java ++++ ../src-work/minecraft/net/minecraft/inventory/ContainerEnchantment.java +@@ -4,6 +4,8 @@ + import cpw.mods.fml.relauncher.SideOnly; + import java.util.List; + import java.util.Random; ++ ++import net.minecraft.enchantment.Enchantment; + import net.minecraft.enchantment.EnchantmentData; + import net.minecraft.enchantment.EnchantmentHelper; + import net.minecraft.entity.player.EntityPlayer; +@@ -14,21 +16,22 @@ + import net.minecraft.world.World; + import net.minecraftforge.common.ForgeHooks; + ++// CraftBukkit start ++import java.util.Map; ++ ++import org.bukkit.craftbukkit.inventory.CraftInventoryEnchanting; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.enchantment.EnchantItemEvent; ++import org.bukkit.event.enchantment.PrepareItemEnchantEvent; ++import org.bukkit.entity.Player; ++// CraftBukkit end ++ + public class ContainerEnchantment extends Container + { +- public IInventory tableInventory = new InventoryBasic("Enchant", true, 1) +- { +- private static final String __OBFID = "CL_00001746"; +- public int getInventoryStackLimit() +- { +- return 1; +- } +- public void markDirty() +- { +- super.markDirty(); +- ContainerEnchantment.this.onCraftMatrixChanged(this); +- } +- }; ++ // CraftBukkit - make type specific (changed from IInventory) ++ public ContainerEnchantTableInventory tableInventory_CB = new ContainerEnchantTableInventory(this, "Enchant", true, 1); // CraftBukkit ++ public IInventory tableInventory = tableInventory_CB; + private World worldPointer; + private int posX; + private int posY; +@@ -36,6 +39,10 @@ + private Random rand = new Random(); + public long nameSeed; + public int[] enchantLevels = new int[3]; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private Player player; ++ // CraftBukkit end + private static final String __OBFID = "CL_00001745"; + + public ContainerEnchantment(InventoryPlayer p_i1811_1_, World p_i1811_2_, int p_i1811_3_, int p_i1811_4_, int p_i1811_5_) +@@ -66,6 +73,11 @@ + { + this.addSlotToContainer(new Slot(p_i1811_1_, l, 8 + l * 18, 142)); + } ++ ++ // CraftBukkit start ++ player = (Player) p_i1811_1_.player.getBukkitEntity(); ++ tableInventory_CB.player = player; // Cauldron ++ // CraftBukkit end + } + + public void addCraftingToCrafters(ICrafting p_75132_1_) +@@ -109,7 +121,7 @@ + ItemStack itemstack = p_75130_1_.getStackInSlot(0); + int i; + +- if (itemstack != null && itemstack.isItemEnchantable()) ++ if (itemstack != null) // CraftBukkit - relax condition + { + this.nameSeed = this.rand.nextLong(); + +@@ -144,6 +156,23 @@ + this.enchantLevels[j] = EnchantmentHelper.calcItemStackEnchantability(this.rand, j, (int)power, itemstack); + } + ++ // CraftBukkit start ++ CraftItemStack item = CraftItemStack.asCraftMirror(itemstack); ++ PrepareItemEnchantEvent event = new PrepareItemEnchantEvent(player, this.getBukkitView(), this.worldPointer.getWorld().getBlockAt(this.posX, this.posY, this.posZ), item, this.enchantLevels, i); ++ event.setCancelled(!itemstack.isItemEnchantable()); ++ if (this.getBukkitView() != null) this.worldPointer.getServer().getPluginManager().callEvent(event); // Cauldron - allow vanilla mods to byp ++ ++ if (event.isCancelled()) ++ { ++ for (i = 0; i < 3; ++i) ++ { ++ this.enchantLevels[i] = 0; ++ } ++ ++ return; ++ } ++ ++ // CraftBukkit end + this.detectAndSendChanges(); + } + } +@@ -170,32 +199,64 @@ + + if (list != null) + { +- p_75140_1_.addExperienceLevel(-this.enchantLevels[p_75140_2_]); ++ // CraftBukkit start ++ Map enchants = new java.util.HashMap(); + +- if (flag) ++ for (Object obj : list) + { +- itemstack.func_150996_a(Items.enchanted_book); ++ EnchantmentData instance = (EnchantmentData) obj; ++ enchants.put(org.bukkit.enchantments.Enchantment.getById(instance.enchantmentobj.effectId), instance.enchantmentLevel); + } + +- int j = flag && list.size() > 1 ? this.rand.nextInt(list.size()) : -1; ++ CraftItemStack item = CraftItemStack.asCraftMirror(itemstack); ++ EnchantItemEvent event = new EnchantItemEvent((Player) p_75140_1_.getBukkitEntity(), this.getBukkitView(), this.worldPointer.getWorld().getBlockAt(this.posX, this.posY, this.posZ), item, this.enchantLevels[p_75140_2_], enchants, p_75140_2_); ++ if (this.getBukkitView() != null) this.worldPointer.getServer().getPluginManager().callEvent(event); // Cauldron - allow vanilla mods to bypass ++ int level = event.getExpLevelCost(); + +- for (int k = 0; k < list.size(); ++k) ++ if (event.isCancelled() || (level > p_75140_1_.experienceLevel && !p_75140_1_.capabilities.isCreativeMode) || enchants.isEmpty()) + { +- EnchantmentData enchantmentdata = (EnchantmentData)list.get(k); ++ return false; ++ } + +- if (!flag || k != j) ++ boolean applied = !flag; ++ ++ for (Map.Entry entry : event.getEnchantsToAdd().entrySet()) ++ { ++ try + { + if (flag) + { +- Items.enchanted_book.addEnchantment(itemstack, enchantmentdata); ++ int enchantId = entry.getKey().getId(); ++ ++ if (Enchantment.enchantmentsList[enchantId] == null) ++ { ++ continue; ++ } ++ ++ EnchantmentData enchantment = new EnchantmentData(enchantId, entry.getValue()); ++ Items.enchanted_book.addEnchantment(itemstack, enchantment); ++ applied = true; ++ itemstack.func_150996_a(Items.enchanted_book); ++ break; + } + else + { +- itemstack.addEnchantment(enchantmentdata.enchantmentobj, enchantmentdata.enchantmentLevel); ++ item.addEnchantment(entry.getKey(), entry.getValue()); + } + } ++ catch (IllegalArgumentException e) ++ { ++ /* Just swallow invalid enchantments */ ++ } + } + ++ // Only down level if we've applied the enchantments ++ if (applied) ++ { ++ p_75140_1_.addExperienceLevel(-level); ++ } ++ ++ // CraftBukkit end + this.onCraftMatrixChanged(this.tableInventory); + } + } +@@ -225,6 +286,11 @@ + + public boolean canInteractWith(EntityPlayer p_75145_1_) + { ++ if (!this.checkReachable) ++ { ++ return true; // CraftBukkit ++ } ++ + return this.worldPointer.getBlock(this.posX, this.posY, this.posZ) != Blocks.enchanting_table ? false : p_75145_1_.getDistanceSq((double)this.posX + 0.5D, (double)this.posY + 0.5D, (double)this.posZ + 0.5D) <= 64.0D; + } + +@@ -283,4 +349,18 @@ + + return itemstack; + } ++ ++ // CraftBukkit start ++ public CraftInventoryView getBukkitView() ++ { ++ if (bukkitEntity != null) ++ { ++ return bukkitEntity; ++ } ++ ++ CraftInventoryEnchanting inventory = new CraftInventoryEnchanting(this.tableInventory_CB); ++ bukkitEntity = new CraftInventoryView(this.player, inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/inventory/ContainerFurnace.java.patch b/patches/net/minecraft/inventory/ContainerFurnace.java.patch new file mode 100644 index 0000000..c11416a --- /dev/null +++ b/patches/net/minecraft/inventory/ContainerFurnace.java.patch @@ -0,0 +1,57 @@ +--- ../src-base/minecraft/net/minecraft/inventory/ContainerFurnace.java ++++ ../src-work/minecraft/net/minecraft/inventory/ContainerFurnace.java +@@ -8,12 +8,34 @@ + import net.minecraft.item.crafting.FurnaceRecipes; + import net.minecraft.tileentity.TileEntityFurnace; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftInventoryFurnace; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerFurnace extends Container + { + private TileEntityFurnace tileFurnace; + private int lastCookTime; + private int lastBurnTime; + private int lastItemBurnTime; ++ ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private InventoryPlayer player; ++ ++ public CraftInventoryView getBukkitView() ++ { ++ if (bukkitEntity != null) ++ { ++ return bukkitEntity; ++ } ++ ++ CraftInventoryFurnace inventory = new CraftInventoryFurnace(this.tileFurnace); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + private static final String __OBFID = "CL_00001748"; + + public ContainerFurnace(InventoryPlayer p_i1812_1_, TileEntityFurnace p_i1812_2_) +@@ -22,6 +44,7 @@ + this.addSlotToContainer(new Slot(p_i1812_2_, 0, 56, 17)); + this.addSlotToContainer(new Slot(p_i1812_2_, 1, 56, 53)); + this.addSlotToContainer(new SlotFurnace(p_i1812_1_.player, p_i1812_2_, 2, 116, 35)); ++ this.player = p_i1812_1_; // CraftBukkit - save player + int i; + + for (i = 0; i < 3; ++i) +@@ -96,6 +119,11 @@ + + public boolean canInteractWith(EntityPlayer p_75145_1_) + { ++ if (!this.checkReachable) ++ { ++ return true; // CraftBukkit ++ } ++ + return this.tileFurnace.isUseableByPlayer(p_75145_1_); + } + diff --git a/patches/net/minecraft/inventory/ContainerHopper.java.patch b/patches/net/minecraft/inventory/ContainerHopper.java.patch new file mode 100644 index 0000000..46638ae --- /dev/null +++ b/patches/net/minecraft/inventory/ContainerHopper.java.patch @@ -0,0 +1,51 @@ +--- ../src-base/minecraft/net/minecraft/inventory/ContainerHopper.java ++++ ../src-work/minecraft/net/minecraft/inventory/ContainerHopper.java +@@ -4,13 +4,36 @@ + import net.minecraft.entity.player.InventoryPlayer; + import net.minecraft.item.ItemStack; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftInventory; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerHopper extends Container + { + private final IInventory field_94538_a; + private static final String __OBFID = "CL_00001750"; + ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private InventoryPlayer player; ++ ++ public CraftInventoryView getBukkitView() ++ { ++ if (bukkitEntity != null) ++ { ++ return bukkitEntity; ++ } ++ ++ CraftInventory inventory = new CraftInventory(this.field_94538_a); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end ++ + public ContainerHopper(InventoryPlayer p_i1814_1_, IInventory p_i1814_2_) + { ++ this.player = p_i1814_1_; // CraftBukkit - save player + this.field_94538_a = p_i1814_2_; + p_i1814_2_.openInventory(); + byte b0 = 51; +@@ -37,6 +60,11 @@ + + public boolean canInteractWith(EntityPlayer p_75145_1_) + { ++ if (!this.checkReachable) ++ { ++ return true; // CraftBukkit ++ } ++ + return this.field_94538_a.isUseableByPlayer(p_75145_1_); + } + diff --git a/patches/net/minecraft/inventory/ContainerMerchant.java.patch b/patches/net/minecraft/inventory/ContainerMerchant.java.patch new file mode 100644 index 0000000..a2b2828 --- /dev/null +++ b/patches/net/minecraft/inventory/ContainerMerchant.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/inventory/ContainerMerchant.java ++++ ../src-work/minecraft/net/minecraft/inventory/ContainerMerchant.java +@@ -8,6 +8,8 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.world.World; + ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit ++ + public class ContainerMerchant extends Container + { + private IMerchant theMerchant; diff --git a/patches/net/minecraft/inventory/ContainerPlayer.java.patch b/patches/net/minecraft/inventory/ContainerPlayer.java.patch new file mode 100644 index 0000000..eb3b6dc --- /dev/null +++ b/patches/net/minecraft/inventory/ContainerPlayer.java.patch @@ -0,0 +1,82 @@ +--- ../src-base/minecraft/net/minecraft/inventory/ContainerPlayer.java ++++ ../src-work/minecraft/net/minecraft/inventory/ContainerPlayer.java +@@ -12,18 +12,33 @@ + import net.minecraft.item.crafting.CraftingManager; + import net.minecraft.util.IIcon; + ++// CraftBukkit start ++import net.minecraft.entity.player.EntityPlayerMP; ++import net.minecraft.network.play.server.S2FPacketSetSlot; ++import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerPlayer extends Container + { + public InventoryCrafting craftMatrix = new InventoryCrafting(this, 2, 2); + public IInventory craftResult = new InventoryCraftResult(); + public boolean isLocalWorld; + private final EntityPlayer thePlayer; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private InventoryPlayer player; ++ // CraftBukkit end + private static final String __OBFID = "CL_00001754"; + + public ContainerPlayer(final InventoryPlayer p_i1819_1_, boolean p_i1819_2_, EntityPlayer p_i1819_3_) + { + this.isLocalWorld = p_i1819_2_; + this.thePlayer = p_i1819_3_; ++ this.craftResult = new InventoryCraftResult(); // CraftBukkit - moved to before InventoryCrafting construction ++ this.craftMatrix = new InventoryCrafting(this, 2, 2, p_i1819_1_.player); // CraftBukkit - pass player ++ this.craftMatrix.resultInventory = this.craftResult; // CraftBukkit - let InventoryCrafting know about its result slot ++ this.player = p_i1819_1_; // CraftBukkit - save player + this.addSlotToContainer(new SlotCrafting(p_i1819_1_.player, this.craftMatrix, this.craftResult, 0, 144, 36)); + int i; + int j; +@@ -72,12 +87,24 @@ + this.addSlotToContainer(new Slot(p_i1819_1_, i, 8 + i * 18, 142)); + } + +- this.onCraftMatrixChanged(this.craftMatrix); ++ // this.onCraftMatrixChanged(this.craftMatrix); // CraftBukkit - unneeded since it just sets result slot to empty + } + + public void onCraftMatrixChanged(IInventory p_75130_1_) + { +- this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.thePlayer.worldObj)); ++ // CraftBukkit start (Note: the following line would cause an error if called during construction) ++ CraftingManager.getInstance().lastCraftView = getBukkitView(); ++ ItemStack craftResult = CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.thePlayer.worldObj); ++ this.craftResult.setInventorySlotContents(0, craftResult); ++ ++ if (super.crafters.size() < 1) ++ { ++ return; ++ } ++ ++ EntityPlayerMP player = (EntityPlayerMP) super.crafters.get(0); // TODO: Is this _always_ correct? Seems like it. ++ player.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(player.openContainer.windowId, 0, craftResult)); ++ // CraftBukkit end + } + + public void onContainerClosed(EntityPlayer p_75134_1_) +@@ -187,4 +214,18 @@ + { + return p_94530_2_.inventory != this.craftResult && super.func_94530_a(p_94530_1_, p_94530_2_); + } ++ ++ // CraftBukkit start ++ public CraftInventoryView getBukkitView() ++ { ++ if (bukkitEntity != null) ++ { ++ return bukkitEntity; ++ } ++ ++ CraftInventoryCrafting inventory = new CraftInventoryCrafting(this.craftMatrix, this.craftResult); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/inventory/ContainerRepair.java.patch b/patches/net/minecraft/inventory/ContainerRepair.java.patch new file mode 100644 index 0000000..00b9737 --- /dev/null +++ b/patches/net/minecraft/inventory/ContainerRepair.java.patch @@ -0,0 +1,71 @@ +--- ../src-base/minecraft/net/minecraft/inventory/ContainerRepair.java ++++ ../src-work/minecraft/net/minecraft/inventory/ContainerRepair.java +@@ -17,19 +17,13 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; // CraftBukkit ++ + public class ContainerRepair extends Container + { + private static final Logger logger = LogManager.getLogger(); + private IInventory outputSlot = new InventoryCraftResult(); +- private IInventory inputSlots = new InventoryBasic("Repair", true, 2) +- { +- private static final String __OBFID = "CL_00001733"; +- public void markDirty() +- { +- super.markDirty(); +- ContainerRepair.this.onCraftMatrixChanged(this); +- } +- }; ++ private IInventory inputSlots = new ContainerRepairInventory(this, "Repair", true, 2); + private World theWorld; + private int field_82861_i; + private int field_82858_j; +@@ -39,9 +33,14 @@ + private String repairedItemName; + private final EntityPlayer thePlayer; + private static final String __OBFID = "CL_00001732"; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private InventoryPlayer player; + + public ContainerRepair(InventoryPlayer p_i1800_1_, final World p_i1800_2_, final int p_i1800_3_, final int p_i1800_4_, final int p_i1800_5_, EntityPlayer p_i1800_6_) + { ++ this.player = p_i1800_1_; ++ // CraftBukkit end + this.theWorld = p_i1800_2_; + this.field_82861_i = p_i1800_3_; + this.field_82858_j = p_i1800_4_; +@@ -461,6 +460,11 @@ + + public boolean canInteractWith(EntityPlayer p_75145_1_) + { ++ if (!this.checkReachable) ++ { ++ return true; // CraftBukkit ++ } ++ + return this.theWorld.getBlock(this.field_82861_i, this.field_82858_j, this.field_82859_k) != Blocks.anvil ? false : p_75145_1_.getDistanceSq((double)this.field_82861_i + 0.5D, (double)this.field_82858_j + 0.5D, (double)this.field_82859_k + 0.5D) <= 64.0D; + } + +@@ -535,4 +539,18 @@ + + this.updateRepairOutput(); + } ++ ++ // CraftBukkit start ++ public CraftInventoryView getBukkitView() ++ { ++ if (bukkitEntity != null) ++ { ++ return bukkitEntity; ++ } ++ ++ org.bukkit.craftbukkit.inventory.CraftInventory inventory = new org.bukkit.craftbukkit.inventory.CraftInventoryAnvil(this.inputSlots, this.outputSlot); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/inventory/ContainerWorkbench.java.patch b/patches/net/minecraft/inventory/ContainerWorkbench.java.patch new file mode 100644 index 0000000..d54c87f --- /dev/null +++ b/patches/net/minecraft/inventory/ContainerWorkbench.java.patch @@ -0,0 +1,92 @@ +--- ../src-base/minecraft/net/minecraft/inventory/ContainerWorkbench.java ++++ ../src-work/minecraft/net/minecraft/inventory/ContainerWorkbench.java +@@ -7,18 +7,35 @@ + import net.minecraft.item.crafting.CraftingManager; + import net.minecraft.world.World; + ++// CraftBukkit start ++import net.minecraft.entity.player.EntityPlayerMP; ++import net.minecraft.network.play.server.S2FPacketSetSlot; ++import org.bukkit.craftbukkit.inventory.CraftInventoryCrafting; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++// CraftBukkit end ++ + public class ContainerWorkbench extends Container + { +- public InventoryCrafting craftMatrix = new InventoryCrafting(this, 3, 3); +- public IInventory craftResult = new InventoryCraftResult(); ++ public InventoryCrafting craftMatrix; // CraftBukkit - move initialization into constructor ++ public IInventory craftResult; // CraftBukkit - move initialization into constructor + private World worldObj; + private int posX; + private int posY; + private int posZ; ++ // CraftBukkit start ++ private CraftInventoryView bukkitEntity = null; ++ private InventoryPlayer player; ++ // CraftBukkit end + private static final String __OBFID = "CL_00001744"; + + public ContainerWorkbench(InventoryPlayer p_i1808_1_, World p_i1808_2_, int p_i1808_3_, int p_i1808_4_, int p_i1808_5_) + { ++ // CraftBukkit start - Switched order of IInventory construction and stored player ++ this.craftResult = new InventoryCraftResult(); ++ this.craftMatrix = new InventoryCrafting(this, 3, 3, p_i1808_1_.player); // CraftBukkit - pass player ++ this.craftMatrix.resultInventory = this.craftResult; ++ this.player = p_i1808_1_; ++ // CraftBukkit end + this.worldObj = p_i1808_2_; + this.posX = p_i1808_3_; + this.posY = p_i1808_4_; +@@ -53,7 +70,19 @@ + + public void onCraftMatrixChanged(IInventory p_75130_1_) + { +- this.craftResult.setInventorySlotContents(0, CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.worldObj)); ++ // CraftBukkit start ++ CraftingManager.getInstance().lastCraftView = getBukkitView(); ++ ItemStack craftResult = CraftingManager.getInstance().findMatchingRecipe(this.craftMatrix, this.worldObj); ++ this.craftResult.setInventorySlotContents(0, craftResult); ++ ++ if (super.crafters.size() < 1) ++ { ++ return; ++ } ++ ++ EntityPlayerMP player = (EntityPlayerMP) super.crafters.get(0); // TODO: Is this _always_ correct? Seems like it. ++ player.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(player.openContainer.windowId, 0, craftResult)); ++ // CraftBukkit end + } + + public void onContainerClosed(EntityPlayer p_75134_1_) +@@ -76,6 +105,11 @@ + + public boolean canInteractWith(EntityPlayer p_75145_1_) + { ++ if (!this.checkReachable) ++ { ++ return true; // CraftBukkit ++ } ++ + return this.worldObj.getBlock(this.posX, this.posY, this.posZ) != Blocks.crafting_table ? false : p_75145_1_.getDistanceSq((double)this.posX + 0.5D, (double)this.posY + 0.5D, (double)this.posZ + 0.5D) <= 64.0D; + } + +@@ -141,4 +175,18 @@ + { + return p_94530_2_.inventory != this.craftResult && super.func_94530_a(p_94530_1_, p_94530_2_); + } ++ ++ // CraftBukkit start ++ public CraftInventoryView getBukkitView() ++ { ++ if (bukkitEntity != null) ++ { ++ return bukkitEntity; ++ } ++ ++ CraftInventoryCrafting inventory = new CraftInventoryCrafting(this.craftMatrix, this.craftResult); ++ bukkitEntity = new CraftInventoryView(this.player.player.getBukkitEntity(), inventory, this); ++ return bukkitEntity; ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/inventory/IInventory.java.patch b/patches/net/minecraft/inventory/IInventory.java.patch new file mode 100644 index 0000000..cd33ce3 --- /dev/null +++ b/patches/net/minecraft/inventory/IInventory.java.patch @@ -0,0 +1,32 @@ +--- ../src-base/minecraft/net/minecraft/inventory/IInventory.java ++++ ../src-work/minecraft/net/minecraft/inventory/IInventory.java +@@ -3,6 +3,8 @@ + import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.item.ItemStack; + ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; // CraftBukkit ++ + public interface IInventory + { + int getSizeInventory(); +@@ -30,4 +32,20 @@ + void closeInventory(); + + boolean isItemValidForSlot(int p_94041_1_, ItemStack p_94041_2_); ++ ++ // CraftBukkit start ++ ItemStack[] getContents(); ++ ++ void onOpen(CraftHumanEntity who); ++ ++ void onClose(CraftHumanEntity who); ++ ++ java.util.List getViewers(); ++ ++ org.bukkit.inventory.InventoryHolder getOwner(); ++ ++ void setMaxStackSize(int size); ++ ++ int MAX_STACK = 64; ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/inventory/InventoryBasic.java.patch b/patches/net/minecraft/inventory/InventoryBasic.java.patch new file mode 100644 index 0000000..9a76868 --- /dev/null +++ b/patches/net/minecraft/inventory/InventoryBasic.java.patch @@ -0,0 +1,57 @@ +--- ../src-base/minecraft/net/minecraft/inventory/InventoryBasic.java ++++ ../src-work/minecraft/net/minecraft/inventory/InventoryBasic.java +@@ -2,6 +2,11 @@ + + import java.util.ArrayList; + import java.util.List; ++ ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++import org.bukkit.inventory.InventoryHolder; ++ + import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.item.ItemStack; + +@@ -9,7 +14,7 @@ + { + private String inventoryTitle; + private int slotsCount; +- private ItemStack[] inventoryContents; ++ protected ItemStack[] inventoryContents; // CraftBukkit - protected + private List field_70480_d; + private boolean field_94051_e; + private static final String __OBFID = "CL_00001514"; +@@ -150,4 +155,33 @@ + { + return true; + } ++ ++ // Cauldron start ++ @Override ++ public ItemStack[] getContents() ++ { ++ return null; ++ } ++ ++ @Override ++ public void onOpen(CraftHumanEntity who) {} ++ ++ @Override ++ public void onClose(CraftHumanEntity who) {} ++ ++ @Override ++ public List getViewers() ++ { ++ return null; ++ } ++ ++ @Override ++ public InventoryHolder getOwner() ++ { ++ return null; ++ } ++ ++ @Override ++ public void setMaxStackSize(int size) {} ++ // Cauldron end + } diff --git a/patches/net/minecraft/inventory/InventoryCraftResult.java.patch b/patches/net/minecraft/inventory/InventoryCraftResult.java.patch new file mode 100644 index 0000000..1d17965 --- /dev/null +++ b/patches/net/minecraft/inventory/InventoryCraftResult.java.patch @@ -0,0 +1,53 @@ +--- ../src-base/minecraft/net/minecraft/inventory/InventoryCraftResult.java ++++ ../src-work/minecraft/net/minecraft/inventory/InventoryCraftResult.java +@@ -2,10 +2,41 @@ + + import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.item.ItemStack; ++// CraftBukkit start ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end + + public class InventoryCraftResult implements IInventory + { + private ItemStack[] stackResult = new ItemStack[1]; ++ ++ // CraftBukkit start ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() ++ { ++ return this.stackResult; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() ++ { ++ return null; // Result slots don't get an owner ++ } ++ ++ // Don't need a transaction; the InventoryCrafting keeps track of it for us ++ public void onOpen(CraftHumanEntity who) {} ++ public void onClose(CraftHumanEntity who) {} ++ public java.util.List getViewers() ++ { ++ return new java.util.ArrayList(); ++ } ++ ++ public void setMaxStackSize(int size) ++ { ++ maxStack = size; ++ } ++ // CraftBukkit end + private static final String __OBFID = "CL_00001760"; + + public int getSizeInventory() +@@ -63,7 +94,7 @@ + + public int getInventoryStackLimit() + { +- return 64; ++ return maxStack; // CraftBukkit + } + + public void markDirty() {} diff --git a/patches/net/minecraft/inventory/InventoryCrafting.java.patch b/patches/net/minecraft/inventory/InventoryCrafting.java.patch new file mode 100644 index 0000000..fd0f85d --- /dev/null +++ b/patches/net/minecraft/inventory/InventoryCrafting.java.patch @@ -0,0 +1,81 @@ +--- ../src-base/minecraft/net/minecraft/inventory/InventoryCrafting.java ++++ ../src-work/minecraft/net/minecraft/inventory/InventoryCrafting.java +@@ -3,11 +3,69 @@ + import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.item.ItemStack; + ++// CraftBukkit start ++import java.util.List; ++import net.minecraft.item.crafting.IRecipe; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++import org.bukkit.event.inventory.InventoryType; ++// CraftBukkit end ++ + public class InventoryCrafting implements IInventory + { + private ItemStack[] stackList; + private int inventoryWidth; + private Container eventHandler; ++ // CraftBukkit start ++ public List transaction = new java.util.ArrayList(); ++ public IRecipe currentRecipe; ++ public IInventory resultInventory; ++ private EntityPlayer owner; ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() ++ { ++ return this.stackList; ++ } ++ ++ public void onOpen(CraftHumanEntity who) ++ { ++ transaction.add(who); ++ } ++ ++ public InventoryType getInvType() ++ { ++ return stackList.length == 4 ? InventoryType.CRAFTING : InventoryType.WORKBENCH; ++ } ++ ++ public void onClose(CraftHumanEntity who) ++ { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() ++ { ++ return transaction; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() ++ { ++ if (owner == null) return null; // Cauldron ++ return owner.getBukkitEntity(); ++ } ++ ++ public void setMaxStackSize(int size) ++ { ++ maxStack = size; ++ resultInventory.setMaxStackSize(size); ++ } ++ ++ public InventoryCrafting(Container container, int i, int j, EntityPlayer player) ++ { ++ this(container, i, j); ++ this.owner = player; ++ } ++ // CraftBukkit end + private static final String __OBFID = "CL_00001743"; + + public InventoryCrafting(Container p_i1807_1_, int p_i1807_2_, int p_i1807_3_) +@@ -105,7 +163,7 @@ + + public int getInventoryStackLimit() + { +- return 64; ++ return maxStack; // CraftBukkit + } + + public void markDirty() {} diff --git a/patches/net/minecraft/inventory/InventoryEnderChest.java.patch b/patches/net/minecraft/inventory/InventoryEnderChest.java.patch new file mode 100644 index 0000000..c145959 --- /dev/null +++ b/patches/net/minecraft/inventory/InventoryEnderChest.java.patch @@ -0,0 +1,64 @@ +--- ../src-base/minecraft/net/minecraft/inventory/InventoryEnderChest.java ++++ ../src-work/minecraft/net/minecraft/inventory/InventoryEnderChest.java +@@ -6,9 +6,61 @@ + import net.minecraft.nbt.NBTTagList; + import net.minecraft.tileentity.TileEntityEnderChest; + ++// CraftBukkit start ++import java.util.List; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ ++ + public class InventoryEnderChest extends InventoryBasic + { + private TileEntityEnderChest associatedChest; ++ ++ // CraftBukkit start ++ public List transaction = new java.util.ArrayList(); ++ public org.bukkit.entity.Player player; ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() ++ { ++ return this.inventoryContents; ++ } ++ ++ public void onOpen(CraftHumanEntity who) ++ { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) ++ { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() ++ { ++ return transaction; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() ++ { ++ return this.player; ++ } ++ ++ public void setMaxStackSize(int size) ++ { ++ maxStack = size; ++ } ++ ++ /** ++ * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't ++ * this more of a set than a get?* ++ */ ++ public int getInventoryStackLimit() ++ { ++ return maxStack; ++ } ++ // CraftBukkit end + private static final String __OBFID = "CL_00001759"; + + public InventoryEnderChest() diff --git a/patches/net/minecraft/inventory/InventoryLargeChest.java.patch b/patches/net/minecraft/inventory/InventoryLargeChest.java.patch new file mode 100644 index 0000000..875ad96 --- /dev/null +++ b/patches/net/minecraft/inventory/InventoryLargeChest.java.patch @@ -0,0 +1,76 @@ +--- ../src-base/minecraft/net/minecraft/inventory/InventoryLargeChest.java ++++ ../src-work/minecraft/net/minecraft/inventory/InventoryLargeChest.java +@@ -3,11 +3,62 @@ + import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.item.ItemStack; + ++// CraftBukkit start ++import java.util.List; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class InventoryLargeChest implements IInventory + { + private String name; +- private IInventory upperChest; +- private IInventory lowerChest; ++ public IInventory upperChest; // CraftBukkit - private -> public ++ public IInventory lowerChest; // CraftBukkit - private -> public ++ // CraftBukkit start ++ public List transaction = new java.util.ArrayList(); ++ ++ public ItemStack[] getContents() ++ { ++ ItemStack[] result = new ItemStack[this.getSizeInventory()]; ++ ++ for (int i = 0; i < result.length; i++) ++ { ++ result[i] = this.getStackInSlot(i); ++ } ++ ++ return result; ++ } ++ ++ public void onOpen(CraftHumanEntity who) ++ { ++ this.upperChest.onOpen(who); ++ this.lowerChest.onOpen(who); ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) ++ { ++ this.upperChest.onClose(who); ++ this.lowerChest.onClose(who); ++ transaction.remove(who); ++ } ++ ++ public List getViewers() ++ { ++ return transaction; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() ++ { ++ return null; // This method won't be called since CraftInventoryDoubleChest doesn't defer to here ++ } ++ ++ public void setMaxStackSize(int size) ++ { ++ this.upperChest.setMaxStackSize(size); ++ this.lowerChest.setMaxStackSize(size); ++ } ++ // CraftBukkit end + private static final String __OBFID = "CL_00001507"; + + public InventoryLargeChest(String p_i1559_1_, IInventory p_i1559_2_, IInventory p_i1559_3_) +@@ -77,7 +128,7 @@ + + public int getInventoryStackLimit() + { +- return this.upperChest.getInventoryStackLimit(); ++ return Math.min(this.upperChest.getInventoryStackLimit(), this.lowerChest.getInventoryStackLimit()); // CraftBukkit - check both sides + } + + public void markDirty() diff --git a/patches/net/minecraft/inventory/InventoryMerchant.java.patch b/patches/net/minecraft/inventory/InventoryMerchant.java.patch new file mode 100644 index 0000000..e22abf0 --- /dev/null +++ b/patches/net/minecraft/inventory/InventoryMerchant.java.patch @@ -0,0 +1,65 @@ +--- ../src-base/minecraft/net/minecraft/inventory/InventoryMerchant.java ++++ ../src-work/minecraft/net/minecraft/inventory/InventoryMerchant.java +@@ -6,6 +6,12 @@ + import net.minecraft.village.MerchantRecipe; + import net.minecraft.village.MerchantRecipeList; + ++// CraftBukkit start ++import java.util.List; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class InventoryMerchant implements IInventory + { + private final IMerchant theMerchant; +@@ -13,6 +19,40 @@ + private final EntityPlayer thePlayer; + private MerchantRecipe currentRecipe; + private int currentRecipeIndex; ++ // CraftBukkit start ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() ++ { ++ return this.theInventory; ++ } ++ ++ public void onOpen(CraftHumanEntity who) ++ { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) ++ { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() ++ { ++ return transaction; ++ } ++ ++ public void setMaxStackSize(int i) ++ { ++ maxStack = i; ++ } ++ ++ public org.bukkit.inventory.InventoryHolder getOwner() ++ { ++ return thePlayer.getBukkitEntity(); ++ } ++ // CraftBukkit end + private static final String __OBFID = "CL_00001756"; + + public InventoryMerchant(EntityPlayer p_i1820_1_, IMerchant p_i1820_2_) +@@ -124,7 +164,7 @@ + + public int getInventoryStackLimit() + { +- return 64; ++ return maxStack; // CraftBukkit + } + + public boolean isUseableByPlayer(EntityPlayer p_70300_1_) diff --git a/patches/net/minecraft/inventory/Slot.java.patch b/patches/net/minecraft/inventory/Slot.java.patch new file mode 100644 index 0000000..221d1b8 --- /dev/null +++ b/patches/net/minecraft/inventory/Slot.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/inventory/Slot.java ++++ ../src-work/minecraft/net/minecraft/inventory/Slot.java +@@ -10,7 +10,7 @@ + + public class Slot + { +- private final int slotIndex; ++ public final int slotIndex; // CraftBukkit - private -> public + public final IInventory inventory; + public int slotNumber; + public int xDisplayPosition; diff --git a/patches/net/minecraft/inventory/SlotFurnace.java.patch b/patches/net/minecraft/inventory/SlotFurnace.java.patch new file mode 100644 index 0000000..9c36934 --- /dev/null +++ b/patches/net/minecraft/inventory/SlotFurnace.java.patch @@ -0,0 +1,36 @@ +--- ../src-base/minecraft/net/minecraft/inventory/SlotFurnace.java ++++ ../src-work/minecraft/net/minecraft/inventory/SlotFurnace.java +@@ -9,6 +9,12 @@ + import net.minecraft.stats.AchievementList; + import net.minecraft.util.MathHelper; + ++// CraftBukkit start ++import net.minecraft.tileentity.TileEntityFurnace; ++import org.bukkit.entity.Player; ++import org.bukkit.event.inventory.FurnaceExtractEvent; ++// CraftBukkit end ++ + public class SlotFurnace extends Slot + { + private EntityPlayer thePlayer; +@@ -74,6 +80,20 @@ + i = j; + } + ++ // Cauldron start - validate inventory before attempting to cast it ++ if (this.inventory instanceof TileEntityFurnace) ++ { ++ // CraftBukkit start ++ Player player = (Player) thePlayer.getBukkitEntity(); ++ TileEntityFurnace furnace = ((TileEntityFurnace) this.inventory); ++ org.bukkit.block.Block block = thePlayer.worldObj.getWorld().getBlockAt(furnace.xCoord, furnace.yCoord, furnace.zCoord); ++ FurnaceExtractEvent event = new FurnaceExtractEvent(player, block, org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(p_75208_1_.getItem()), p_75208_1_.stackSize, i); ++ thePlayer.worldObj.getServer().getPluginManager().callEvent(event); ++ i = event.getExpToDrop(); ++ // CraftBukkit end ++ } ++ // Cauldron end ++ + while (i > 0) + { + j = EntityXPOrb.getXPSplit(i); diff --git a/patches/net/minecraft/item/Item.java.patch b/patches/net/minecraft/item/Item.java.patch new file mode 100644 index 0000000..d504e19 --- /dev/null +++ b/patches/net/minecraft/item/Item.java.patch @@ -0,0 +1,38 @@ +--- ../src-base/minecraft/net/minecraft/item/Item.java ++++ ../src-work/minecraft/net/minecraft/item/Item.java +@@ -54,6 +54,7 @@ + import net.minecraft.util.WeightedRandomChestContent; + import net.minecraft.world.World; + import net.minecraftforge.common.ChestGenHooks; ++import net.minecraftforge.common.DimensionManager; // Cauldron + import net.minecraftforge.common.util.EnumHelper; + + public class Item +@@ -402,6 +403,12 @@ + { + object = (new ItemDoublePlant(Blocks.double_plant, Blocks.double_plant, BlockDoublePlant.field_149892_a)).setUnlocalizedName("doublePlant"); + } ++ // CraftBukkit start - allow certain blocks to retain data ++ else if (block == Blocks.mob_spawner || block == Blocks.brown_mushroom_block || block == Blocks.red_mushroom_block) ++ { ++ object = new ItemColored(block, true); ++ } ++ // CraftBukkit end + else + { + if (hashset.contains(block)) +@@ -923,7 +930,13 @@ + */ + public int getEntityLifespan(ItemStack itemStack, World world) + { +- return 6000; ++ // Cauldron start - fixes MFR proxy worlds used with grinder/slaughterhouse ++ if (world == null) ++ { ++ return 6000; ++ } ++ return world.getSpigotConfig().itemDespawnRate; // Spigot ++ // Cauldron end + } + + /** diff --git a/patches/net/minecraft/item/ItemBoat.java.patch b/patches/net/minecraft/item/ItemBoat.java.patch new file mode 100644 index 0000000..0e0f669 --- /dev/null +++ b/patches/net/minecraft/item/ItemBoat.java.patch @@ -0,0 +1,19 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemBoat.java ++++ ../src-work/minecraft/net/minecraft/item/ItemBoat.java +@@ -80,7 +80,16 @@ + i = movingobjectposition.blockX; + int j = movingobjectposition.blockY; + int k = movingobjectposition.blockZ; ++ // CraftBukkit start - Boat placement ++ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(p_77659_3_, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK, i, j, k, movingobjectposition.sideHit, p_77659_1_); + ++ if (event.isCancelled()) ++ { ++ return p_77659_1_; ++ } ++ ++ // CraftBukkit end ++ + if (p_77659_2_.getBlock(i, j, k) == Blocks.snow_layer) + { + --j; diff --git a/patches/net/minecraft/item/ItemBow.java.patch b/patches/net/minecraft/item/ItemBow.java.patch new file mode 100644 index 0000000..17c9d5e --- /dev/null +++ b/patches/net/minecraft/item/ItemBow.java.patch @@ -0,0 +1,33 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemBow.java ++++ ../src-work/minecraft/net/minecraft/item/ItemBow.java +@@ -84,6 +84,21 @@ + entityarrow.setFire(100); + } + ++ // CraftBukkit start ++ org.bukkit.event.entity.EntityShootBowEvent cbEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callEntityShootBowEvent(p_77615_3_, p_77615_1_, entityarrow, f); ++ ++ if (cbEvent.isCancelled()) ++ { ++ cbEvent.getProjectile().remove(); ++ return; ++ } ++ ++ if (cbEvent.getProjectile() == entityarrow.getBukkitEntity()) ++ { ++ p_77615_2_.spawnEntityInWorld(entityarrow); ++ } ++ ++ // CraftBukkit end + p_77615_1_.damageItem(1, p_77615_3_); + p_77615_2_.playSoundAtEntity(p_77615_3_, "random.bow", 1.0F, 1.0F / (itemRand.nextFloat() * 0.4F + 1.2F) + f * 0.5F); + +@@ -98,7 +113,7 @@ + + if (!p_77615_2_.isRemote) + { +- p_77615_2_.spawnEntityInWorld(entityarrow); ++ // p_77615_2_.spawnEntityInWorld(entityarrow); // CraftBukkit - moved up + } + } + } diff --git a/patches/net/minecraft/item/ItemBucket.java.patch b/patches/net/minecraft/item/ItemBucket.java.patch new file mode 100644 index 0000000..6c70ce0 --- /dev/null +++ b/patches/net/minecraft/item/ItemBucket.java.patch @@ -0,0 +1,133 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemBucket.java ++++ ../src-work/minecraft/net/minecraft/item/ItemBucket.java +@@ -12,6 +12,13 @@ + import net.minecraftforge.common.MinecraftForge; + import net.minecraftforge.event.entity.player.FillBucketEvent; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.event.player.PlayerBucketEmptyEvent; ++import org.bukkit.event.player.PlayerBucketFillEvent; ++// CraftBukkit end ++ + public class ItemBucket extends Item + { + private Block isFull; +@@ -83,23 +90,52 @@ + + if (material == Material.water && l == 0) + { ++ // CraftBukkit start ++ PlayerBucketFillEvent cbEvent = CraftEventFactory.callPlayerBucketFillEvent(p_77659_3_, i, j, k, -1, p_77659_1_, Items.water_bucket); ++ ++ if (cbEvent.isCancelled()) ++ { ++ return p_77659_1_; ++ } ++ ++ // CraftBukkit end + p_77659_2_.setBlockToAir(i, j, k); +- return this.func_150910_a(p_77659_1_, p_77659_3_, Items.water_bucket); ++ return this.func_150910_a(p_77659_1_, p_77659_3_, Items.water_bucket, cbEvent.getItemStack()); // CraftBukkit - added Event stack + } + + if (material == Material.lava && l == 0) + { ++ // CraftBukkit start ++ PlayerBucketFillEvent cbEvent = CraftEventFactory.callPlayerBucketFillEvent(p_77659_3_, i, j, k, -1, p_77659_1_, Items.lava_bucket); ++ ++ if (cbEvent.isCancelled()) ++ { ++ return p_77659_1_; ++ } ++ ++ // CraftBukkit end + p_77659_2_.setBlockToAir(i, j, k); +- return this.func_150910_a(p_77659_1_, p_77659_3_, Items.lava_bucket); ++ return this.func_150910_a(p_77659_1_, p_77659_3_, Items.lava_bucket, cbEvent.getItemStack()); // CraftBukkit - added Event stack + } + } + else + { + if (this.isFull == Blocks.air) + { +- return new ItemStack(Items.bucket); ++ // CraftBukkit start ++ PlayerBucketEmptyEvent cbEvent = CraftEventFactory.callPlayerBucketEmptyEvent(p_77659_3_, i, j, k, movingobjectposition.sideHit, p_77659_1_); ++ ++ if (cbEvent.isCancelled()) ++ { ++ return p_77659_1_; ++ } ++ ++ return CraftItemStack.asNMSCopy(cbEvent.getItemStack()); + } + ++ int clickedX = i, clickedY = j, clickedZ = k; ++ // CraftBukkit end ++ + if (movingobjectposition.sideHit == 0) + { + --j; +@@ -135,9 +171,19 @@ + return p_77659_1_; + } + ++ // CraftBukkit start ++ PlayerBucketEmptyEvent cbEvent = CraftEventFactory.callPlayerBucketEmptyEvent(p_77659_3_, clickedX, clickedY, clickedZ, movingobjectposition.sideHit, p_77659_1_); ++ ++ if (cbEvent.isCancelled()) ++ { ++ return p_77659_1_; ++ } ++ ++ // CraftBukkit end ++ + if (this.tryPlaceContainedLiquid(p_77659_2_, i, j, k) && !p_77659_3_.capabilities.isCreativeMode) + { +- return new ItemStack(Items.bucket); ++ return CraftItemStack.asNMSCopy(cbEvent.getItemStack()); // CraftBukkit + } + } + } +@@ -146,24 +192,32 @@ + } + } + ++ // Cauldron start - vanilla compatibility + private ItemStack func_150910_a(ItemStack p_150910_1_, EntityPlayer p_150910_2_, Item p_150910_3_) + { +- if (p_150910_2_.capabilities.isCreativeMode) ++ return this.func_150910_a(p_150910_1_, p_150910_2_, p_150910_3_, null); ++ } ++ // Cauldron end ++ ++ // CraftBukkit - added ob.ItemStack result - TODO: Is this... the right way to handle this? ++ private ItemStack func_150910_a(ItemStack itemstack, EntityPlayer entityplayer, Item item, org.bukkit.inventory.ItemStack result) ++ { ++ if (entityplayer.capabilities.isCreativeMode) + { +- return p_150910_1_; ++ return itemstack; + } +- else if (--p_150910_1_.stackSize <= 0) ++ else if (--itemstack.stackSize <= 0) + { +- return new ItemStack(p_150910_3_); ++ return CraftItemStack.asNMSCopy(result); // CraftBukkit + } + else + { +- if (!p_150910_2_.inventory.addItemStackToInventory(new ItemStack(p_150910_3_))) ++ if (!entityplayer.inventory.addItemStackToInventory(CraftItemStack.asNMSCopy(result))) // CraftBukkit + { +- p_150910_2_.dropPlayerItemWithRandomChoice(new ItemStack(p_150910_3_, 1, 0), false); ++ entityplayer.dropPlayerItemWithRandomChoice(CraftItemStack.asNMSCopy(result), false); // CraftBukkit + } + +- return p_150910_1_; ++ return itemstack; + } + } + diff --git a/patches/net/minecraft/item/ItemDye.java.patch b/patches/net/minecraft/item/ItemDye.java.patch new file mode 100644 index 0000000..ef52624 --- /dev/null +++ b/patches/net/minecraft/item/ItemDye.java.patch @@ -0,0 +1,30 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemDye.java ++++ ../src-work/minecraft/net/minecraft/item/ItemDye.java +@@ -23,6 +23,8 @@ + import net.minecraftforge.common.util.FakePlayerFactory; + import net.minecraftforge.event.entity.player.BonemealEvent; + ++import org.bukkit.event.entity.SheepDyeWoolEvent; // CraftBukkit ++ + public class ItemDye extends Item + { + public static final String[] field_150923_a = new String[] {"black", "red", "green", "brown", "blue", "purple", "cyan", "silver", "gray", "pink", "lime", "yellow", "lightBlue", "magenta", "orange", "white"}; +@@ -220,6 +222,18 @@ + + if (!entitysheep.getSheared() && entitysheep.getFleeceColor() != i) + { ++ // CraftBukkit start ++ byte bColor = (byte) i; ++ SheepDyeWoolEvent event = new SheepDyeWoolEvent((org.bukkit.entity.Sheep) entitysheep.getBukkitEntity(), org.bukkit.DyeColor.getByData(bColor)); ++ entitysheep.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return false; ++ } ++ ++ i = (byte) event.getColor().getWoolData(); ++ // CraftBukkit end + entitysheep.setFleeceColor(i); + --p_111207_1_.stackSize; + } diff --git a/patches/net/minecraft/item/ItemEmptyMap.java.patch b/patches/net/minecraft/item/ItemEmptyMap.java.patch new file mode 100644 index 0000000..b72e669 --- /dev/null +++ b/patches/net/minecraft/item/ItemEmptyMap.java.patch @@ -0,0 +1,10 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemEmptyMap.java ++++ ../src-work/minecraft/net/minecraft/item/ItemEmptyMap.java +@@ -27,6 +27,7 @@ + mapdata.zCenter = (int)(Math.round(p_77659_3_.posZ / (double)i) * (long)i); + mapdata.dimension = p_77659_2_.provider.dimensionId; + mapdata.markDirty(); ++ org.bukkit.craftbukkit.event.CraftEventFactory.callEvent(new org.bukkit.event.server.MapInitializeEvent(mapdata.mapView)); // CraftBukkit + --p_77659_1_.stackSize; + + if (p_77659_1_.stackSize <= 0) diff --git a/patches/net/minecraft/item/ItemFireball.java.patch b/patches/net/minecraft/item/ItemFireball.java.patch new file mode 100644 index 0000000..f2043a7 --- /dev/null +++ b/patches/net/minecraft/item/ItemFireball.java.patch @@ -0,0 +1,21 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemFireball.java ++++ ../src-work/minecraft/net/minecraft/item/ItemFireball.java +@@ -61,6 +61,18 @@ + { + if (p_77648_3_.getBlock(p_77648_4_, p_77648_5_, p_77648_6_).getMaterial() == Material.air) + { ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(p_77648_3_, p_77648_4_, p_77648_5_, p_77648_6_, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FIREBALL, p_77648_2_).isCancelled()) ++ { ++ if (!p_77648_2_.capabilities.isCreativeMode) ++ { ++ --p_77648_1_.stackSize; ++ } ++ ++ return false; ++ } ++ ++ // CraftBukkit end + p_77648_3_.playSoundEffect((double)p_77648_4_ + 0.5D, (double)p_77648_5_ + 0.5D, (double)p_77648_6_ + 0.5D, "fire.ignite", 1.0F, itemRand.nextFloat() * 0.4F + 0.8F); + p_77648_3_.setBlock(p_77648_4_, p_77648_5_, p_77648_6_, Blocks.fire); + } diff --git a/patches/net/minecraft/item/ItemFishingRod.java.patch b/patches/net/minecraft/item/ItemFishingRod.java.patch new file mode 100644 index 0000000..dc5ce58 --- /dev/null +++ b/patches/net/minecraft/item/ItemFishingRod.java.patch @@ -0,0 +1,35 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemFishingRod.java ++++ ../src-work/minecraft/net/minecraft/item/ItemFishingRod.java +@@ -9,6 +9,8 @@ + import net.minecraft.util.IIcon; + import net.minecraft.world.World; + ++import org.bukkit.event.player.PlayerFishEvent; // CraftBukkit ++ + public class ItemFishingRod extends Item + { + @SideOnly(Side.CLIENT) +@@ -44,11 +46,22 @@ + } + else + { ++ // CraftBukkit start ++ EntityFishHook hook = new EntityFishHook(p_77659_2_, p_77659_3_); ++ PlayerFishEvent playerFishEvent = new PlayerFishEvent((org.bukkit.entity.Player) p_77659_3_.getBukkitEntity(), null, (org.bukkit.entity.Fish) hook.getBukkitEntity(), PlayerFishEvent.State.FISHING); ++ p_77659_2_.getServer().getPluginManager().callEvent(playerFishEvent); ++ ++ if (playerFishEvent.isCancelled()) ++ { ++ return p_77659_1_; ++ } ++ ++ // CraftBukkit end + p_77659_2_.playSoundAtEntity(p_77659_3_, "random.bow", 0.5F, 0.4F / (itemRand.nextFloat() * 0.4F + 0.8F)); + + if (!p_77659_2_.isRemote) + { +- p_77659_2_.spawnEntityInWorld(new EntityFishHook(p_77659_2_, p_77659_3_)); ++ p_77659_2_.spawnEntityInWorld(hook); // CraftBukkit - moved creation up + } + + p_77659_3_.swingItem(); diff --git a/patches/net/minecraft/item/ItemFlintAndSteel.java.patch b/patches/net/minecraft/item/ItemFlintAndSteel.java.patch new file mode 100644 index 0000000..971c0e4 --- /dev/null +++ b/patches/net/minecraft/item/ItemFlintAndSteel.java.patch @@ -0,0 +1,51 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemFlintAndSteel.java ++++ ../src-work/minecraft/net/minecraft/item/ItemFlintAndSteel.java +@@ -6,6 +6,11 @@ + import net.minecraft.init.Blocks; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.block.CraftBlockState; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++// CraftBukkit end ++ + public class ItemFlintAndSteel extends Item + { + private static final String __OBFID = "CL_00000035"; +@@ -19,6 +24,8 @@ + + public boolean onItemUse(ItemStack p_77648_1_, EntityPlayer p_77648_2_, World p_77648_3_, int p_77648_4_, int p_77648_5_, int p_77648_6_, int p_77648_7_, float p_77648_8_, float p_77648_9_, float p_77648_10_) + { ++ int clickedX = p_77648_4_, clickedY = p_77648_5_, clickedZ = p_77648_6_; // CraftBukkit ++ + if (p_77648_7_ == 0) + { + --p_77648_5_; +@@ -57,8 +64,27 @@ + { + if (p_77648_3_.isAirBlock(p_77648_4_, p_77648_5_, p_77648_6_)) + { ++ // CraftBukkit start - Store the clicked block ++ if (CraftEventFactory.callBlockIgniteEvent(p_77648_3_, p_77648_4_, p_77648_5_, p_77648_6_, org.bukkit.event.block.BlockIgniteEvent.IgniteCause.FLINT_AND_STEEL, p_77648_2_).isCancelled()) ++ { ++ p_77648_1_.damageItem(1, p_77648_2_); ++ return false; ++ } ++ ++ CraftBlockState blockState = CraftBlockState.getBlockState(p_77648_3_, p_77648_4_, p_77648_5_, p_77648_6_); ++ // CraftBukkit end + p_77648_3_.playSoundEffect((double)p_77648_4_ + 0.5D, (double)p_77648_5_ + 0.5D, (double)p_77648_6_ + 0.5D, "fire.ignite", 1.0F, itemRand.nextFloat() * 0.4F + 0.8F); + p_77648_3_.setBlock(p_77648_4_, p_77648_5_, p_77648_6_, Blocks.fire); ++ // CraftBukkit start ++ org.bukkit.event.block.BlockPlaceEvent placeEvent = CraftEventFactory.callBlockPlaceEvent(p_77648_3_, p_77648_2_, blockState, clickedX, clickedY, clickedZ); ++ ++ if (placeEvent.isCancelled() || !placeEvent.canBuild()) ++ { ++ placeEvent.getBlockPlaced().setTypeIdAndData(0, (byte) 0, false); ++ return false; ++ } ++ ++ // CraftBukkit end + } + + p_77648_1_.damageItem(1, p_77648_2_); diff --git a/patches/net/minecraft/item/ItemHangingEntity.java.patch b/patches/net/minecraft/item/ItemHangingEntity.java.patch new file mode 100644 index 0000000..284e620 --- /dev/null +++ b/patches/net/minecraft/item/ItemHangingEntity.java.patch @@ -0,0 +1,44 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemHangingEntity.java ++++ ../src-work/minecraft/net/minecraft/item/ItemHangingEntity.java +@@ -8,6 +8,12 @@ + import net.minecraft.util.Direction; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.entity.Player; ++import org.bukkit.event.hanging.HangingPlaceEvent; ++import org.bukkit.event.painting.PaintingPlaceEvent; ++// CraftBukkit end ++ + public class ItemHangingEntity extends Item + { + private final Class hangingEntityClass; +@@ -44,6 +50,28 @@ + { + if (!p_77648_3_.isRemote) + { ++ // CraftBukkit start ++ Player who = (p_77648_2_ == null) ? null : (Player) p_77648_2_.getBukkitEntity(); ++ org.bukkit.block.Block blockClicked = p_77648_3_.getWorld().getBlockAt(p_77648_4_, p_77648_5_, p_77648_6_); ++ org.bukkit.block.BlockFace blockFace = org.bukkit.craftbukkit.block.CraftBlock.notchToBlockFace(p_77648_7_); ++ HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) entityhanging.getBukkitEntity(), who, blockClicked, blockFace); ++ p_77648_3_.getServer().getPluginManager().callEvent(event); ++ PaintingPlaceEvent paintingEvent = null; ++ ++ if (entityhanging instanceof EntityPainting) ++ { ++ // Fire old painting event until it can be removed ++ paintingEvent = new PaintingPlaceEvent((org.bukkit.entity.Painting) entityhanging.getBukkitEntity(), who, blockClicked, blockFace); ++ paintingEvent.setCancelled(event.isCancelled()); ++ p_77648_3_.getServer().getPluginManager().callEvent(paintingEvent); ++ } ++ ++ if (event.isCancelled() || (paintingEvent != null && paintingEvent.isCancelled())) ++ { ++ return false; ++ } ++ ++ // CraftBukkit end + p_77648_3_.spawnEntityInWorld(entityhanging); + } + diff --git a/patches/net/minecraft/item/ItemLead.java.patch b/patches/net/minecraft/item/ItemLead.java.patch new file mode 100644 index 0000000..864b756 --- /dev/null +++ b/patches/net/minecraft/item/ItemLead.java.patch @@ -0,0 +1,38 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemLead.java ++++ ../src-work/minecraft/net/minecraft/item/ItemLead.java +@@ -10,6 +10,8 @@ + import net.minecraft.util.AxisAlignedBB; + import net.minecraft.world.World; + ++import org.bukkit.event.hanging.HangingPlaceEvent; // CraftBukkit ++ + public class ItemLead extends Item + { + private static final String __OBFID = "CL_00000045"; +@@ -61,8 +63,26 @@ + if (entityleashknot == null) + { + entityleashknot = EntityLeashKnot.func_110129_a(p_150909_1_, p_150909_2_, p_150909_3_, p_150909_4_); ++ // CraftBukkit start ++ HangingPlaceEvent event = new HangingPlaceEvent((org.bukkit.entity.Hanging) entityleashknot.getBukkitEntity(), p_150909_0_ != null ? (org.bukkit.entity.Player) p_150909_0_.getBukkitEntity() : null, p_150909_1_.getWorld().getBlockAt(p_150909_2_, p_150909_3_, p_150909_4_), org.bukkit.block.BlockFace.SELF); ++ p_150909_1_.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ entityleashknot.setDead(); ++ return false; ++ } ++ ++ // CraftBukkit end + } + ++ // CraftBukkit start ++ if (org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerLeashEntityEvent(entityliving, entityleashknot, p_150909_0_).isCancelled()) ++ { ++ continue; ++ } ++ ++ // CraftBukkit end + entityliving.setLeashedToEntity(entityleashknot, true); + flag = true; + } diff --git a/patches/net/minecraft/item/ItemLilyPad.java.patch b/patches/net/minecraft/item/ItemLilyPad.java.patch new file mode 100644 index 0000000..818195c --- /dev/null +++ b/patches/net/minecraft/item/ItemLilyPad.java.patch @@ -0,0 +1,36 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemLilyPad.java ++++ ../src-work/minecraft/net/minecraft/item/ItemLilyPad.java +@@ -48,7 +48,17 @@ + { + // special case for handling block placement with water lilies + net.minecraftforge.common.util.BlockSnapshot blocksnapshot = net.minecraftforge.common.util.BlockSnapshot.getBlockSnapshot(p_77659_2_, i, j + 1, k); ++ // Cauldron start - special case for handling block placement with water lilies ++ org.bukkit.block.BlockState blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(p_77659_2_, i, j + 1, k); + p_77659_2_.setBlock(i, j + 1, k, Blocks.waterlily); ++ org.bukkit.event.block.BlockPlaceEvent placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(p_77659_2_, ++ p_77659_3_, blockstate, i, j, k); ++ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) ++ { ++ blockstate.update(true, false); ++ return p_77659_1_; ++ } ++ // Cauldron end + if (net.minecraftforge.event.ForgeEventFactory.onPlayerBlockPlace(p_77659_3_, blocksnapshot, net.minecraftforge.common.util.ForgeDirection.UP).isCanceled()) + { + blocksnapshot.restore(true, false); +@@ -66,6 +76,15 @@ + } + } + ++ // Cauldron start ++ public boolean onItemUse(ItemStack par1ItemStack, EntityPlayer par2EntityPlayer, World par3World, int par4, int par5, int par6, int par7, float par8, ++ float par9, float par10) ++ { ++ cpw.mods.fml.relauncher.FMLRelaunchLog.info("onItemUse par1ItemStack = " + par1ItemStack); ++ return super.onItemUse(par1ItemStack, par2EntityPlayer, par3World, par4, par5, par6, par7, par8, par9, par10); ++ } ++ // Cauldron end ++ + @SideOnly(Side.CLIENT) + public int getColorFromItemStack(ItemStack p_82790_1_, int p_82790_2_) + { diff --git a/patches/net/minecraft/item/ItemMap.java.patch b/patches/net/minecraft/item/ItemMap.java.patch new file mode 100644 index 0000000..fc882d1 --- /dev/null +++ b/patches/net/minecraft/item/ItemMap.java.patch @@ -0,0 +1,36 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemMap.java ++++ ../src-work/minecraft/net/minecraft/item/ItemMap.java +@@ -19,6 +19,11 @@ + import net.minecraft.world.chunk.Chunk; + import net.minecraft.world.storage.MapData; + ++// CraftBukkit start ++import org.bukkit.Bukkit; ++import org.bukkit.event.server.MapInitializeEvent; ++// CraftBukkit end ++ + public class ItemMap extends ItemMapBase + { + private static final String __OBFID = "CL_00000047"; +@@ -60,6 +65,10 @@ + mapdata.dimension = p_77873_2_.provider.dimensionId; + mapdata.markDirty(); + p_77873_2_.setItemData(s, mapdata); ++ // CraftBukkit start ++ MapInitializeEvent event = new MapInitializeEvent(mapdata.mapView); ++ Bukkit.getServer().getPluginManager().callEvent(event); ++ // CraftBukkit end + } + + return mapdata; +@@ -279,6 +288,10 @@ + mapdata1.dimension = mapdata.dimension; + mapdata1.markDirty(); + p_77622_2_.setItemData("map_" + p_77622_1_.getItemDamage(), mapdata1); ++ // CraftBukkit start ++ MapInitializeEvent event = new MapInitializeEvent(mapdata1.mapView); ++ Bukkit.getServer().getPluginManager().callEvent(event); ++ // CraftBukkit end + } + } + diff --git a/patches/net/minecraft/item/ItemMinecart.java.patch b/patches/net/minecraft/item/ItemMinecart.java.patch new file mode 100644 index 0000000..f29389b --- /dev/null +++ b/patches/net/minecraft/item/ItemMinecart.java.patch @@ -0,0 +1,18 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemMinecart.java ++++ ../src-work/minecraft/net/minecraft/item/ItemMinecart.java +@@ -79,6 +79,15 @@ + { + if (!p_77648_3_.isRemote) + { ++ // CraftBukkit start - Minecarts ++ org.bukkit.event.player.PlayerInteractEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerInteractEvent(p_77648_2_, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK, p_77648_4_, p_77648_5_, p_77648_6_, p_77648_7_, p_77648_1_); ++ ++ if (event.isCancelled()) ++ { ++ return false; ++ } ++ ++ // CraftBukkit end + EntityMinecart entityminecart = EntityMinecart.createMinecart(p_77648_3_, (double)((float)p_77648_4_ + 0.5F), (double)((float)p_77648_5_ + 0.5F), (double)((float)p_77648_6_ + 0.5F), this.minecartType); + + if (p_77648_1_.hasDisplayName()) diff --git a/patches/net/minecraft/item/ItemMonsterPlacer.java.patch b/patches/net/minecraft/item/ItemMonsterPlacer.java.patch new file mode 100644 index 0000000..b312855 --- /dev/null +++ b/patches/net/minecraft/item/ItemMonsterPlacer.java.patch @@ -0,0 +1,20 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemMonsterPlacer.java ++++ ../src-work/minecraft/net/minecraft/item/ItemMonsterPlacer.java +@@ -55,7 +55,7 @@ + + public boolean onItemUse(ItemStack p_77648_1_, EntityPlayer p_77648_2_, World p_77648_3_, int p_77648_4_, int p_77648_5_, int p_77648_6_, int p_77648_7_, float p_77648_8_, float p_77648_9_, float p_77648_10_) + { +- if (p_77648_3_.isRemote) ++ if (p_77648_3_.isRemote || p_77648_1_.getItemDamage() == 48 || p_77648_1_.getItemDamage() == 49 || p_77648_1_.getItemDamage() == 63 || p_77648_1_.getItemDamage() == 64) // CraftBukkit + { + return true; + } +@@ -168,7 +168,7 @@ + entityliving.rotationYawHead = entityliving.rotationYaw; + entityliving.renderYawOffset = entityliving.rotationYaw; + entityliving.onSpawnWithEgg((IEntityLivingData)null); +- p_77840_0_.spawnEntityInWorld(entity); ++ p_77840_0_.addEntity(entity, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.SPAWNER_EGG); // CraftBukkit + entityliving.playLivingSound(); + } + } diff --git a/patches/net/minecraft/item/ItemShears.java.patch b/patches/net/minecraft/item/ItemShears.java.patch new file mode 100644 index 0000000..51fa182 --- /dev/null +++ b/patches/net/minecraft/item/ItemShears.java.patch @@ -0,0 +1,28 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemShears.java ++++ ../src-work/minecraft/net/minecraft/item/ItemShears.java +@@ -3,6 +3,8 @@ + import java.util.ArrayList; + import java.util.Random; + ++import org.bukkit.event.player.PlayerShearEntityEvent; ++ + import net.minecraft.block.Block; + import net.minecraft.block.material.Material; + import net.minecraft.creativetab.CreativeTabs; +@@ -61,6 +63,16 @@ + IShearable target = (IShearable)entity; + if (target.isShearable(itemstack, entity.worldObj, (int)entity.posX, (int)entity.posY, (int)entity.posZ)) + { ++ // Cauldron start ++ PlayerShearEntityEvent event = new PlayerShearEntityEvent((org.bukkit.entity.Player) player.getBukkitEntity(), entity.getBukkitEntity()); ++ player.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return false; ++ } ++ ++ // Cauldron end + ArrayList drops = target.onSheared(itemstack, entity.worldObj, (int)entity.posX, (int)entity.posY, (int)entity.posZ, + EnchantmentHelper.getEnchantmentLevel(Enchantment.fortune.effectId, itemstack)); + diff --git a/patches/net/minecraft/item/ItemStack.java.patch b/patches/net/minecraft/item/ItemStack.java.patch new file mode 100644 index 0000000..b1fdb77 --- /dev/null +++ b/patches/net/minecraft/item/ItemStack.java.patch @@ -0,0 +1,227 @@ +--- ../src-base/minecraft/net/minecraft/item/ItemStack.java ++++ ../src-work/minecraft/net/minecraft/item/ItemStack.java +@@ -35,6 +35,20 @@ + import net.minecraft.world.World; + import net.minecraftforge.event.ForgeEventFactory; + ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; // CraftBukkit ++import net.minecraft.entity.player.EntityPlayerMP; // Spigot ++// Cauldron start ++import net.minecraft.block.BlockSapling; ++import net.minecraft.block.BlockMushroom; ++ ++import org.bukkit.Location; ++import org.bukkit.TreeType; ++import org.bukkit.block.BlockState; ++import org.bukkit.craftbukkit.block.CraftBlockState; ++import org.bukkit.entity.Player; ++import org.bukkit.event.world.StructureGrowEvent; ++// Cauldron end ++ + public final class ItemStack + { + public static final DecimalFormat field_111284_a = new DecimalFormat("#.###"); +@@ -43,7 +57,12 @@ + private Item field_151002_e; + public NBTTagCompound stackTagCompound; + int itemDamage; +- private EntityItemFrame itemFrame; ++ // Cauldron - due to a bug in Gson(https://code.google.com/p/google-gson/issues/detail?id=440), a stackoverflow ++ // can occur when gson attempts to resolve a field of a class that points to itself. ++ // As a temporary workaround, we will prevent serialization for this object until the bug is fixed. ++ // This fixes EE3's serialization of ItemStack. ++ private transient EntityItemFrame itemFrame; ++ public static EntityPlayer currentPlayer; // Cauldron - reference to current player calling onItemUse + private static final String __OBFID = "CL_00000043"; + + private cpw.mods.fml.common.registry.RegistryDelegate delegate; +@@ -126,12 +145,120 @@ + public boolean tryPlaceItemIntoWorld(EntityPlayer p_77943_1_, World p_77943_2_, int p_77943_3_, int p_77943_4_, int p_77943_5_, int p_77943_6_, float p_77943_7_, float p_77943_8_, float p_77943_9_) + { + if (!p_77943_2_.isRemote) return net.minecraftforge.common.ForgeHooks.onPlaceItemIntoWorld(this, p_77943_1_, p_77943_2_, p_77943_3_, p_77943_4_, p_77943_5_, p_77943_6_, p_77943_7_, p_77943_8_, p_77943_9_); ++ // Cauldron start - handle all placement events here ++ int meta = this.getItemDamage(); ++ int size = this.stackSize; ++ NBTTagCompound nbt = null; ++ if (this.getTagCompound() != null) ++ { ++ nbt = (NBTTagCompound) this.getTagCompound().copy(); ++ } ++ ++ if (!(this.getItem() instanceof ItemBucket)) // if not bucket ++ { ++ p_77943_2_.captureBlockStates = true; ++ if (this.getItem() instanceof ItemDye && this.getItemDamage() == 15) ++ { ++ Block block = p_77943_2_.getBlock(p_77943_3_, p_77943_4_, p_77943_5_); ++ if (block != null && (block instanceof BlockSapling || block instanceof BlockMushroom)) ++ { ++ p_77943_2_.captureTreeGeneration = true; ++ } ++ } ++ } ++ currentPlayer = p_77943_1_; + boolean flag = this.getItem().onItemUse(this, p_77943_1_, p_77943_2_, p_77943_3_, p_77943_4_, p_77943_5_, p_77943_6_, p_77943_7_, p_77943_8_, p_77943_9_); ++ p_77943_2_.captureBlockStates = false; ++ currentPlayer = null; ++ if (flag && p_77943_2_.captureTreeGeneration && p_77943_2_.capturedBlockStates.size() > 0) ++ { ++ p_77943_2_.captureTreeGeneration = false; ++ Location location = new Location(p_77943_2_.getWorld(), p_77943_3_, p_77943_4_, p_77943_5_); ++ TreeType treeType = BlockSapling.treeType; ++ BlockSapling.treeType = null; ++ List blocks = (List) p_77943_2_.capturedBlockStates.clone(); ++ p_77943_2_.capturedBlockStates.clear(); ++ StructureGrowEvent event = null; ++ if (treeType != null) ++ { ++ event = new StructureGrowEvent(location, treeType, false, (Player) p_77943_1_.getBukkitEntity(), blocks); ++ org.bukkit.Bukkit.getPluginManager().callEvent(event); ++ } ++ if (event == null || !event.isCancelled()) ++ { ++ for (BlockState blockstate : blocks) ++ { ++ blockstate.update(true); ++ } ++ } + ++ return flag; ++ } ++ p_77943_2_.captureTreeGeneration = false; ++ + if (flag) + { +- p_77943_1_.addStat(StatList.objectUseStats[Item.getIdFromItem(this.field_151002_e)], 1); ++ org.bukkit.event.block.BlockPlaceEvent placeEvent = null; ++ List blockstates = (List) p_77943_2_.capturedBlockStates.clone(); ++ p_77943_2_.capturedBlockStates.clear(); ++ if (blockstates.size() > 1) ++ { ++ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockMultiPlaceEvent(p_77943_2_, p_77943_1_, blockstates, p_77943_3_, ++ p_77943_4_, p_77943_5_); ++ } ++ else if (blockstates.size() == 1) ++ { ++ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(p_77943_2_, p_77943_1_, blockstates.get(0), p_77943_3_, ++ p_77943_4_, p_77943_5_); ++ } ++ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) ++ { ++ flag = false; // cancel placement ++ // revert back all captured blocks ++ for (BlockState blockstate : blockstates) ++ { ++ p_77943_2_.restoringBlockStates = true; ++ blockstate.update(true, false); // restore blockstate ++ p_77943_2_.restoringBlockStates = false; ++ } ++ // make sure to restore stack after cancel ++ this.setItemDamage(meta); ++ this.stackSize = size; ++ if (nbt != null) ++ { ++ this.setTagCompound(nbt); ++ } ++ } ++ else ++ { ++ // drop items ++ for (int i = 0; i < p_77943_2_.capturedItems.size(); i++) ++ { ++ p_77943_2_.spawnEntityInWorld(p_77943_2_.capturedItems.get(i)); ++ } ++ ++ for (BlockState blockstate : blockstates) ++ { ++ int x = blockstate.getX(); ++ int y = blockstate.getY(); ++ int z = blockstate.getZ(); ++ int metadata = p_77943_2_.getBlockMetadata(x, y, z); ++ int updateFlag = ((CraftBlockState) blockstate).getFlag(); ++ Block oldBlock = CraftMagicNumbers.getBlock(blockstate.getTypeId()); ++ Block newBlock = p_77943_2_.getBlock(x, y, z); ++ if (newBlock != null && !(newBlock.hasTileEntity(metadata))) ++ { // Containers get placed automatically ++ newBlock.onBlockAdded(p_77943_2_, x, y, z); ++ } ++ ++ p_77943_2_.markAndNotifyBlock(x, y, z, null, oldBlock, newBlock, updateFlag); ++ } ++ p_77943_1_.addStat(StatList.objectUseStats[Item.getIdFromItem(this.field_151002_e)], 1); ++ } + } ++ p_77943_2_.capturedBlockStates.clear(); ++ p_77943_2_.capturedItems.clear(); ++ // Cauldron end + + return flag; + } +@@ -227,8 +354,22 @@ + return getItem().getMaxDamage(this); + } + ++ // Spigot start ++ ++ /** ++ * Attempts to damage the ItemStack with par1 amount of damage, If the ItemStack has the Unbreaking enchantment ++ * there is a chance for each point of damage to be negated. Returns true if it takes more damage than ++ * getMaxDamage(). Returns false otherwise or if the ItemStack can't be damaged or if all points of damage are ++ * negated. ++ */ + public boolean attemptDamageItem(int p_96631_1_, Random p_96631_2_) + { ++ return isDamaged(p_96631_1_, p_96631_2_, null); ++ } ++ ++ public boolean isDamaged(int p_96631_1_, Random p_96631_2_, EntityLivingBase entitylivingbase) ++ { ++ // Spigot end + if (!this.isItemStackDamageable()) + { + return false; +@@ -250,6 +391,23 @@ + + p_96631_1_ -= k; + ++ // Spigot start ++ if (entitylivingbase instanceof EntityPlayerMP) ++ { ++ org.bukkit.craftbukkit.inventory.CraftItemStack item = org.bukkit.craftbukkit.inventory.CraftItemStack.asCraftMirror(this); ++ org.bukkit.event.player.PlayerItemDamageEvent event = new org.bukkit.event.player.PlayerItemDamageEvent( ++ (org.bukkit.entity.Player) entitylivingbase.getBukkitEntity(), item, p_96631_1_); ++ org.bukkit.Bukkit.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return false; ++ } ++ ++ p_96631_1_ = event.getDamage(); ++ } ++ // Spigot end ++ + if (p_96631_1_ <= 0) + { + return false; +@@ -288,6 +446,12 @@ + this.stackSize = 0; + } + ++ // CraftBukkit start - Check for item breaking ++ if (this.stackSize == 0 && p_77972_2_ instanceof EntityPlayer) ++ { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callPlayerItemBreakEvent((EntityPlayer) p_77972_2_, this); ++ } ++ // CraftBukkit end + this.itemDamage = 0; + } + } +@@ -419,6 +583,7 @@ + + public void setTagCompound(NBTTagCompound p_77982_1_) + { ++ // Cauldron - do not alter name of compound. Fixes Ars Magica 2 Spellbooks + this.stackTagCompound = p_77982_1_; + } + diff --git a/patches/net/minecraft/item/crafting/CraftingManager.java.patch b/patches/net/minecraft/item/crafting/CraftingManager.java.patch new file mode 100644 index 0000000..7b34355 --- /dev/null +++ b/patches/net/minecraft/item/crafting/CraftingManager.java.patch @@ -0,0 +1,104 @@ +--- ../src-base/minecraft/net/minecraft/item/crafting/CraftingManager.java ++++ ../src-work/minecraft/net/minecraft/item/crafting/CraftingManager.java +@@ -13,10 +13,17 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.world.World; + ++import org.bukkit.craftbukkit.event.CraftEventFactory; // CraftBukkit ++ + public class CraftingManager + { + private static final CraftingManager instance = new CraftingManager(); +- private List recipes = new ArrayList(); ++ // CraftBukkit start ++ /** A list of all the recipes added */ ++ public List recipes = new ArrayList(); // private -> public ++ public IRecipe lastRecipe; ++ public org.bukkit.inventory.InventoryView lastCraftView; ++ // CraftBukkit end + private static final String __OBFID = "CL_00000090"; + + public static final CraftingManager getInstance() +@@ -24,7 +31,8 @@ + return instance; + } + +- private CraftingManager() ++ // CraftBukkit - private -> public ++ public CraftingManager() + { + (new RecipesTools()).addRecipes(this); + (new RecipesWeapons()).addRecipes(this); +@@ -152,6 +160,23 @@ + this.addShapelessRecipe(new ItemStack(Items.fire_charge, 3), new Object[] {Items.gunpowder, Items.blaze_powder, new ItemStack(Items.coal, 1, 1)}); + this.addRecipe(new ItemStack(Blocks.daylight_detector), new Object[] {"GGG", "QQQ", "WWW", 'G', Blocks.glass, 'Q', Items.quartz, 'W', Blocks.wooden_slab}); + this.addRecipe(new ItemStack(Blocks.hopper), new Object[] {"I I", "ICI", " I ", 'I', Items.iron_ingot, 'C', Blocks.chest}); ++ /*Collections.sort(this.recipes, new Comparator() // CraftBukkit - moved below ++ { ++ private static final String __OBFID = "CL_00000091"; ++ public int compare(IRecipe par1IRecipe, IRecipe par2IRecipe) ++ { ++ return par1IRecipe instanceof ShapelessRecipes && par2IRecipe instanceof ShapedRecipes ? 1 : (par2IRecipe instanceof ShapelessRecipes && par1IRecipe instanceof ShapedRecipes ? -1 : (par2IRecipe.getRecipeSize() < par1IRecipe.getRecipeSize() ? -1 : (par2IRecipe.getRecipeSize() > par1IRecipe.getRecipeSize() ? 1 : 0))); ++ } ++ public int compare(Object par1Obj, Object par2Obj) ++ { ++ return this.compare((IRecipe)par1Obj, (IRecipe)par2Obj); ++ } ++ });*/ ++ this.sort(); // CraftBukkit - call new sort method ++ } ++ ++ public void sort() ++ { + Collections.sort(this.recipes, new Comparator() + { + private static final String __OBFID = "CL_00000091"; +@@ -312,7 +337,22 @@ + i1 = 0; + } + +- return new ItemStack(itemstack.getItem(), 1, i1); ++ // Cauldron start - vanilla compatibility ++ if (p_82787_1_.resultInventory == null) ++ { ++ return new ItemStack(itemstack.getItem(), 1, i1); ++ } ++ // Cauldron end ++ // CraftBukkit start - Construct a dummy repair recipe ++ ItemStack result = new ItemStack(itemstack.getItem(), 1, i1); ++ List ingredients = new ArrayList(); ++ ingredients.add(itemstack.copy()); ++ ingredients.add(itemstack1.copy()); ++ ShapelessRecipes recipe = new ShapelessRecipes(result.copy(), ingredients); ++ p_82787_1_.currentRecipe = recipe; ++ result = CraftEventFactory.callPreCraftEvent(p_82787_1_, result, lastCraftView, true); ++ return result; ++ // CraftBukkit end + } + else + { +@@ -320,12 +360,23 @@ + { + IRecipe irecipe = (IRecipe)this.recipes.get(j); + +- if (irecipe.matches(p_82787_1_, p_82787_2_)) ++ if (irecipe.matches(p_82787_1_, p_82787_2_) && p_82787_1_.resultInventory != null) // Cauldron - add null check for vanilla compatibility + { ++ // CraftBukkit start - INVENTORY_PRE_CRAFT event ++ p_82787_1_.currentRecipe = irecipe; ++ ItemStack result = irecipe.getCraftingResult(p_82787_1_); ++ return CraftEventFactory.callPreCraftEvent(p_82787_1_, result, lastCraftView, false); ++ // CraftBukkit end ++ } ++ // Cauldron start - vanilla ++ else if (irecipe.matches(p_82787_1_, p_82787_2_)) ++ { + return irecipe.getCraftingResult(p_82787_1_); + } ++ // Cauldron end + } + ++ p_82787_1_.currentRecipe = null; // CraftBukkit - Clear recipe when no recipe is found + return null; + } + } diff --git a/patches/net/minecraft/item/crafting/FurnaceRecipes.java.patch b/patches/net/minecraft/item/crafting/FurnaceRecipes.java.patch new file mode 100644 index 0000000..df5135d --- /dev/null +++ b/patches/net/minecraft/item/crafting/FurnaceRecipes.java.patch @@ -0,0 +1,62 @@ +--- ../src-base/minecraft/net/minecraft/item/crafting/FurnaceRecipes.java ++++ ../src-work/minecraft/net/minecraft/item/crafting/FurnaceRecipes.java +@@ -14,8 +14,9 @@ + public class FurnaceRecipes + { + private static final FurnaceRecipes smeltingBase = new FurnaceRecipes(); +- private Map smeltingList = new HashMap(); ++ public Map smeltingList = new HashMap(); // CraftBukkit - private -> public + private Map experienceList = new HashMap(); ++ public Map customRecipes = new HashMap(); // CraftBukkit + private static final String __OBFID = "CL_00000085"; + + public static FurnaceRecipes smelting() +@@ -23,7 +24,7 @@ + return smeltingBase; + } + +- private FurnaceRecipes() ++ public FurnaceRecipes() // CraftBukkit - private -> public + { + this.func_151393_a(Blocks.iron_ore, new ItemStack(Items.iron_ingot), 0.7F); + this.func_151393_a(Blocks.gold_ore, new ItemStack(Items.gold_ingot), 1.0F); +@@ -76,16 +77,37 @@ + this.experienceList.put(p_151394_2_, Float.valueOf(p_151394_3_)); + } + ++ // CraftBukkit start ++ public void registerRecipe(ItemStack itemstack, ItemStack itemstack1) ++ { ++ this.customRecipes.put(itemstack, itemstack1); ++ } ++ // CraftBukkit end ++ + public ItemStack getSmeltingResult(ItemStack p_151395_1_) + { +- Iterator iterator = this.smeltingList.entrySet().iterator(); ++ // CraftBukkit start ++ boolean vanilla = false; ++ Iterator iterator = this.customRecipes.entrySet().iterator(); ++ // CraftBukkit end + Entry entry; + + do + { + if (!iterator.hasNext()) + { +- return null; ++ // CraftBukkit start ++ if (!vanilla) ++ { ++ iterator = this.smeltingList.entrySet().iterator(); ++ vanilla = true; ++ } ++ else ++ { ++ return null; ++ } ++ ++ // CraftBukkit end + } + + entry = (Entry)iterator.next(); diff --git a/patches/net/minecraft/item/crafting/IRecipe.java.patch b/patches/net/minecraft/item/crafting/IRecipe.java.patch new file mode 100644 index 0000000..285ab14 --- /dev/null +++ b/patches/net/minecraft/item/crafting/IRecipe.java.patch @@ -0,0 +1,9 @@ +--- ../src-base/minecraft/net/minecraft/item/crafting/IRecipe.java ++++ ../src-work/minecraft/net/minecraft/item/crafting/IRecipe.java +@@ -13,4 +13,6 @@ + int getRecipeSize(); + + ItemStack getRecipeOutput(); ++ ++ org.bukkit.inventory.Recipe toBukkitRecipe(); // CraftBukkit + } diff --git a/patches/net/minecraft/item/crafting/RecipeBookCloning.java.patch b/patches/net/minecraft/item/crafting/RecipeBookCloning.java.patch new file mode 100644 index 0000000..a0f3299 --- /dev/null +++ b/patches/net/minecraft/item/crafting/RecipeBookCloning.java.patch @@ -0,0 +1,21 @@ +--- ../src-base/minecraft/net/minecraft/item/crafting/RecipeBookCloning.java ++++ ../src-work/minecraft/net/minecraft/item/crafting/RecipeBookCloning.java +@@ -6,10 +6,17 @@ + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.world.World; + +-public class RecipeBookCloning implements IRecipe ++public class RecipeBookCloning extends ShapelessRecipes implements IRecipe // CraftBukkit - added extends + { + private static final String __OBFID = "CL_00000081"; + ++ // CraftBukkit start - Delegate to new parent class ++ public RecipeBookCloning() ++ { ++ super(new ItemStack(Items.written_book, 0, -1), java.util.Arrays.asList(new ItemStack(Items.writable_book, 0, 0))); ++ } ++ // CraftBukkit end ++ + public boolean matches(InventoryCrafting p_77569_1_, World p_77569_2_) + { + int i = 0; diff --git a/patches/net/minecraft/item/crafting/RecipeFireworks.java.patch b/patches/net/minecraft/item/crafting/RecipeFireworks.java.patch new file mode 100644 index 0000000..eb6d629 --- /dev/null +++ b/patches/net/minecraft/item/crafting/RecipeFireworks.java.patch @@ -0,0 +1,22 @@ +--- ../src-base/minecraft/net/minecraft/item/crafting/RecipeFireworks.java ++++ ../src-work/minecraft/net/minecraft/item/crafting/RecipeFireworks.java +@@ -9,11 +9,18 @@ + import net.minecraft.nbt.NBTTagList; + import net.minecraft.world.World; + +-public class RecipeFireworks implements IRecipe ++public class RecipeFireworks extends ShapelessRecipes implements IRecipe // CraftBukkit - added extends + { + private ItemStack field_92102_a; + private static final String __OBFID = "CL_00000083"; + ++ // CraftBukkit start - Delegate to new parent class with bogus info ++ public RecipeFireworks() ++ { ++ super(new ItemStack(Items.fireworks, 0, 0), java.util.Arrays.asList(new ItemStack(Items.gunpowder, 0, 5))); ++ } ++ // CraftBukkit end ++ + public boolean matches(InventoryCrafting p_77569_1_, World p_77569_2_) + { + this.field_92102_a = null; diff --git a/patches/net/minecraft/item/crafting/RecipesArmorDyes.java.patch b/patches/net/minecraft/item/crafting/RecipesArmorDyes.java.patch new file mode 100644 index 0000000..b069d80 --- /dev/null +++ b/patches/net/minecraft/item/crafting/RecipesArmorDyes.java.patch @@ -0,0 +1,21 @@ +--- ../src-base/minecraft/net/minecraft/item/crafting/RecipesArmorDyes.java ++++ ../src-work/minecraft/net/minecraft/item/crafting/RecipesArmorDyes.java +@@ -9,10 +9,17 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.world.World; + +-public class RecipesArmorDyes implements IRecipe ++public class RecipesArmorDyes extends ShapelessRecipes implements IRecipe // CraftBukkit - added extends + { + private static final String __OBFID = "CL_00000079"; + ++ // CraftBukkit start - Delegate to new parent class with bogus info ++ public RecipesArmorDyes() ++ { ++ super(new ItemStack(Items.leather_helmet, 0, 0), java.util.Arrays.asList(new ItemStack(Items.dye, 0, 5))); ++ } ++ // CraftBukkit end ++ + public boolean matches(InventoryCrafting p_77569_1_, World p_77569_2_) + { + ItemStack itemstack = null; diff --git a/patches/net/minecraft/item/crafting/RecipesMapCloning.java.patch b/patches/net/minecraft/item/crafting/RecipesMapCloning.java.patch new file mode 100644 index 0000000..70c8e8e --- /dev/null +++ b/patches/net/minecraft/item/crafting/RecipesMapCloning.java.patch @@ -0,0 +1,21 @@ +--- ../src-base/minecraft/net/minecraft/item/crafting/RecipesMapCloning.java ++++ ../src-work/minecraft/net/minecraft/item/crafting/RecipesMapCloning.java +@@ -5,10 +5,17 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.world.World; + +-public class RecipesMapCloning implements IRecipe ++public class RecipesMapCloning extends ShapelessRecipes implements IRecipe // CraftBukkit - added extends + { + private static final String __OBFID = "CL_00000087"; + ++ // CraftBukkit start - Delegate to new parent class ++ public RecipesMapCloning() ++ { ++ super(new ItemStack(Items.filled_map, 0, -1), java.util.Arrays.asList(new ItemStack(Items.map, 0, 0))); ++ } ++ // CraftBukkit end ++ + public boolean matches(InventoryCrafting p_77569_1_, World p_77569_2_) + { + int i = 0; diff --git a/patches/net/minecraft/item/crafting/ShapedRecipes.java.patch b/patches/net/minecraft/item/crafting/ShapedRecipes.java.patch new file mode 100644 index 0000000..e1baadf --- /dev/null +++ b/patches/net/minecraft/item/crafting/ShapedRecipes.java.patch @@ -0,0 +1,92 @@ +--- ../src-base/minecraft/net/minecraft/item/crafting/ShapedRecipes.java ++++ ../src-work/minecraft/net/minecraft/item/crafting/ShapedRecipes.java +@@ -5,6 +5,11 @@ + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftShapedRecipe; ++// CraftBukkit end ++ + public class ShapedRecipes implements IRecipe + { + public final int recipeWidth; +@@ -22,6 +27,77 @@ + this.recipeOutput = p_i1917_4_; + } + ++ // CraftBukkit start ++ public org.bukkit.inventory.ShapedRecipe toBukkitRecipe() ++ { ++ CraftItemStack result = CraftItemStack.asCraftMirror(this.recipeOutput); ++ CraftShapedRecipe recipe = new CraftShapedRecipe(result, this); ++ ++ switch (this.recipeHeight) ++ { ++ case 1: ++ switch (this.recipeWidth) ++ { ++ case 1: ++ recipe.shape("a"); ++ break; ++ case 2: ++ recipe.shape("ab"); ++ break; ++ case 3: ++ recipe.shape("abc"); ++ break; ++ } ++ ++ break; ++ case 2: ++ switch (this.recipeWidth) ++ { ++ case 1: ++ recipe.shape("a", "b"); ++ break; ++ case 2: ++ recipe.shape("ab", "cd"); ++ break; ++ case 3: ++ recipe.shape("abc", "def"); ++ break; ++ } ++ ++ break; ++ case 3: ++ switch (this.recipeWidth) ++ { ++ case 1: ++ recipe.shape("a", "b", "c"); ++ break; ++ case 2: ++ recipe.shape("ab", "cd", "ef"); ++ break; ++ case 3: ++ recipe.shape("abc", "def", "ghi"); ++ break; ++ } ++ ++ break; ++ } ++ ++ char c = 'a'; ++ ++ for (ItemStack stack : this.recipeItems) ++ { ++ if (stack != null) ++ { ++ recipe.setIngredient(c, org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(stack.getItem()), stack.getItemDamage()); ++ } ++ ++ c++; ++ } ++ ++ return recipe; ++ } ++ // CraftBukkit end ++ + public ItemStack getRecipeOutput() + { + return this.recipeOutput; diff --git a/patches/net/minecraft/item/crafting/ShapelessRecipes.java.patch b/patches/net/minecraft/item/crafting/ShapelessRecipes.java.patch new file mode 100644 index 0000000..874586f --- /dev/null +++ b/patches/net/minecraft/item/crafting/ShapelessRecipes.java.patch @@ -0,0 +1,40 @@ +--- ../src-base/minecraft/net/minecraft/item/crafting/ShapelessRecipes.java ++++ ../src-work/minecraft/net/minecraft/item/crafting/ShapelessRecipes.java +@@ -7,6 +7,11 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.world.World; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.inventory.CraftShapelessRecipe; ++// CraftBukkit end ++ + public class ShapelessRecipes implements IRecipe + { + private final ItemStack recipeOutput; +@@ -19,6 +24,25 @@ + this.recipeItems = p_i1918_2_; + } + ++ // CraftBukkit start ++ @SuppressWarnings("unchecked") ++ public org.bukkit.inventory.ShapelessRecipe toBukkitRecipe() ++ { ++ CraftItemStack result = CraftItemStack.asCraftMirror(this.recipeOutput); ++ CraftShapelessRecipe recipe = new CraftShapelessRecipe(result, this); ++ ++ for (ItemStack stack : (List) this.recipeItems) ++ { ++ if (stack != null) ++ { ++ recipe.addIngredient(org.bukkit.craftbukkit.util.CraftMagicNumbers.getMaterial(stack.getItem()), stack.getItemDamage()); ++ } ++ } ++ ++ return recipe; ++ } ++ // CraftBukkit end ++ + public ItemStack getRecipeOutput() + { + return this.recipeOutput; diff --git a/patches/net/minecraft/network/NetHandlerPlayServer.java.patch b/patches/net/minecraft/network/NetHandlerPlayServer.java.patch new file mode 100644 index 0000000..5e24391 --- /dev/null +++ b/patches/net/minecraft/network/NetHandlerPlayServer.java.patch @@ -0,0 +1,1940 @@ +--- ../src-base/minecraft/net/minecraft/network/NetHandlerPlayServer.java ++++ ../src-work/minecraft/net/minecraft/network/NetHandlerPlayServer.java +@@ -13,6 +13,7 @@ + import java.util.Iterator; + import java.util.Random; + import java.util.concurrent.Callable; ++import net.minecraft.block.Block; + import net.minecraft.block.material.Material; + import net.minecraft.command.server.CommandBlockLogic; + import net.minecraft.crash.CrashReport; +@@ -32,6 +33,7 @@ + import net.minecraft.inventory.ContainerMerchant; + import net.minecraft.inventory.ContainerRepair; + import net.minecraft.inventory.Slot; ++import net.minecraft.item.Item; + import net.minecraft.item.ItemEditableBook; + import net.minecraft.item.ItemStack; + import net.minecraft.item.ItemWritableBook; +@@ -61,6 +63,7 @@ + import net.minecraft.network.play.server.S00PacketKeepAlive; + import net.minecraft.network.play.server.S02PacketChat; + import net.minecraft.network.play.server.S08PacketPlayerPosLook; ++import net.minecraft.network.play.server.S1CPacketEntityMetadata; + import net.minecraft.network.play.server.S23PacketBlockChange; + import net.minecraft.network.play.server.S2FPacketSetSlot; + import net.minecraft.network.play.server.S32PacketConfirmTransaction; +@@ -81,19 +84,75 @@ + import net.minecraft.util.IChatComponent; + import net.minecraft.util.IntHashMap; + import net.minecraft.util.ReportedException; ++import net.minecraft.world.World; + import net.minecraft.world.WorldServer; + import org.apache.commons.lang3.StringUtils; + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++import net.minecraftforge.cauldron.CauldronUtils; + import net.minecraftforge.common.ForgeHooks; + import net.minecraftforge.common.MinecraftForge; +-import cpw.mods.fml.common.eventhandler.Event; + import net.minecraftforge.event.ForgeEventFactory; + import net.minecraftforge.event.ServerChatEvent; + import net.minecraftforge.event.entity.player.PlayerInteractEvent; +-import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; + ++// CraftBukkit start ++import java.io.UnsupportedEncodingException; ++import java.util.concurrent.ExecutionException; ++import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; ++import java.util.HashSet; ++ ++import net.minecraft.entity.EntityLiving; ++import net.minecraft.init.Blocks; ++import net.minecraft.network.play.server.S05PacketSpawnPosition; ++import net.minecraft.network.play.server.S09PacketHeldItemChange; ++import net.minecraft.network.play.server.S1BPacketEntityAttach; ++import net.minecraft.network.play.server.S33PacketUpdateSign; ++import net.minecraft.util.MathHelper; ++import net.minecraft.util.MovingObjectPosition; ++import net.minecraft.util.Vec3; ++ ++import org.bukkit.craftbukkit.entity.CraftPlayer; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.craftbukkit.util.CraftChatMessage; ++import org.bukkit.craftbukkit.util.LazyPlayerSet; ++import org.bukkit.craftbukkit.util.Waitable; ++ ++import org.bukkit.Location; ++import org.bukkit.entity.Player; ++import org.bukkit.event.Event; ++import org.bukkit.event.block.Action; ++import org.bukkit.event.block.SignChangeEvent; ++import org.bukkit.event.inventory.ClickType; ++import org.bukkit.event.inventory.CraftItemEvent; ++import org.bukkit.event.inventory.InventoryAction; ++import org.bukkit.event.inventory.InventoryClickEvent; ++import org.bukkit.event.inventory.InventoryCreativeEvent; ++import org.bukkit.event.inventory.InventoryType.SlotType; ++import org.bukkit.event.player.AsyncPlayerChatEvent; ++import org.bukkit.event.player.PlayerAnimationEvent; ++import org.bukkit.event.player.PlayerChatEvent; ++import org.bukkit.event.player.PlayerCommandPreprocessEvent; ++import org.bukkit.event.player.PlayerInteractEntityEvent; ++import org.bukkit.event.player.PlayerItemHeldEvent; ++import org.bukkit.event.player.PlayerKickEvent; ++import org.bukkit.event.player.PlayerMoveEvent; ++import org.bukkit.event.player.PlayerTeleportEvent; ++import org.bukkit.event.player.PlayerToggleFlightEvent; ++import org.bukkit.event.player.PlayerToggleSneakEvent; ++import org.bukkit.event.player.PlayerToggleSprintEvent; ++import org.bukkit.inventory.CraftingInventory; ++import org.bukkit.inventory.InventoryView; ++import org.bukkit.util.NumberConversions; ++// CraftBukkit end ++// Cauldron start ++import org.bukkit.craftbukkit.CraftServer; ++import org.bukkit.event.inventory.InventoryType; ++// Cauldron end ++ + public class NetHandlerPlayServer implements INetHandlerPlayServer + { + private static final Logger logger = LogManager.getLogger(); +@@ -107,13 +166,12 @@ + private long field_147379_i; + private static Random field_147376_j = new Random(); + private long field_147377_k; +- private int chatSpamThresholdCount; ++ private volatile int chatSpamThresholdCount; // Cauldron - set to volatile to fix multithreaded issues ++ private static final AtomicIntegerFieldUpdater chatSpamField = AtomicIntegerFieldUpdater.newUpdater(NetHandlerPlayServer.class, CauldronUtils.deobfuscatedEnvironment() ? "chatSpamThresholdCount" : "fiel" + "d_147374_l"); // CraftBukkit - multithreaded field + private int field_147375_m; + private IntHashMap field_147372_n = new IntHashMap(); +- private double lastPosX; +- private double lastPosY; +- private double lastPosZ; +- private boolean hasMoved = true; ++ public boolean hasMoved = true; // CraftBukkit - private -> public ++ private boolean processedDisconnect; // CraftBukkit - added + private static final String __OBFID = "CL_00001452"; + + public NetHandlerPlayServer(MinecraftServer p_i1530_1_, NetworkManager p_i1530_2_, EntityPlayerMP p_i1530_3_) +@@ -123,8 +181,41 @@ + p_i1530_2_.setNetHandler(this); + this.playerEntity = p_i1530_3_; + p_i1530_3_.playerNetServerHandler = this; ++ // CraftBukkit start ++ this.server = p_i1530_1_.server; + } + ++ private final org.bukkit.craftbukkit.CraftServer server; ++ private int lastTick = MinecraftServer.currentTick; ++ private int lastDropTick = MinecraftServer.currentTick; ++ private int dropCount = 0; ++ private static final int SURVIVAL_PLACE_DISTANCE_SQUARED = 6 * 6; ++ private static final int CREATIVE_PLACE_DISTANCE_SQUARED = 7 * 7; ++ ++ private double lastPosX = Double.MAX_VALUE; ++ private double lastPosY = Double.MAX_VALUE; ++ private double lastPosZ = Double.MAX_VALUE; ++ private float lastPitch = Float.MAX_VALUE; ++ private float lastYaw = Float.MAX_VALUE; ++ private boolean justTeleported = false; ++ ++ // For the PacketPlayOutBlockPlace hack :( ++ Long lastPacket; ++ ++ // Store the last block right clicked and what type it was ++ private Item lastMaterial; ++ ++ // Cauldron - rename getPlayer -> getPlayerB() to disambiguate with FML's getPlayer() method of the same name (below) ++ // Plugins calling this method will be remapped appropriately, but CraftBukkit code should be updated ++ public CraftPlayer getPlayerB() ++ { ++ return (this.playerEntity == null) ? null : (CraftPlayer) this.playerEntity.getBukkitEntity(); ++ } ++ ++ private final static HashSet invalidItems = new HashSet(java.util.Arrays.asList(8, 9, 10, 11, 26, 34, 36, 43, 51, 52, 55, 59, 60, 62, 63, ++ 64, 68, 71, 74, 75, 83, 90, 92, 93, 94, 104, 105, 115, 117, 118, 119, 125, 127, 132, 137, 140, 141, 142, 144)); // TODO: Check after every update. ++ // CraftBukkit end ++ + public void onNetworkTick() + { + this.field_147366_g = false; +@@ -139,10 +230,16 @@ + this.sendPacket(new S00PacketKeepAlive(this.field_147378_h)); + } + ++ // CraftBukkit start ++ for (int spam; (spam = this.chatSpamThresholdCount) > 0 && !chatSpamField.compareAndSet(this, spam, spam - 1);) ; ++ ++ /* Use thread-safe field access instead + if (this.chatSpamThresholdCount > 0) + { + --this.chatSpamThresholdCount; + } ++ */ ++ // CraftBukkit end + + if (this.field_147375_m > 0) + { +@@ -162,6 +259,24 @@ + + public void kickPlayerFromServer(String p_147360_1_) + { ++ // CraftBukkit start ++ String leaveMessage = EnumChatFormatting.YELLOW + this.playerEntity.getCommandSenderName() + " left the game."; ++ PlayerKickEvent event = new PlayerKickEvent(this.server.getPlayer(this.playerEntity), p_147360_1_, leaveMessage); ++ ++ if (this.server.getServer().isServerRunning()) ++ { ++ this.server.getPluginManager().callEvent(event); ++ } ++ ++ if (event.isCancelled()) ++ { ++ // Do not kick the player ++ return; ++ } ++ ++ // Send the possibly modified leave message ++ p_147360_1_ = event.getReason(); ++ // CraftBukkit end + final ChatComponentText chatcomponenttext = new ChatComponentText(p_147360_1_); + this.netManager.scheduleOutboundPacket(new S40PacketDisconnect(chatcomponenttext), new GenericFutureListener[] {new GenericFutureListener() + { +@@ -170,8 +285,8 @@ + { + NetHandlerPlayServer.this.netManager.closeChannel(chatcomponenttext); + } +- } +- }); ++ }}); ++ this.onDisconnect(chatcomponenttext); // CraftBukkit - Process quit immediately + this.netManager.disableAutoRead(); + } + +@@ -182,6 +297,15 @@ + + public void processPlayer(C03PacketPlayer p_147347_1_) + { ++ // CraftBukkit start - Check for NaN ++ if (Double.isNaN(p_147347_1_.field_149479_a) || Double.isNaN(p_147347_1_.field_149477_b) || Double.isNaN(p_147347_1_.field_149478_c) ++ || Double.isNaN(p_147347_1_.field_149475_d)) ++ { ++ logger.warn(playerEntity.getCommandSenderName() + " was caught trying to crash the server with an invalid position."); ++ getPlayerB().kickPlayer("Nope!"); ++ return; ++ } ++ // CraftBukkit end + WorldServer worldserver = this.serverController.worldServerForDimension(this.playerEntity.dimension); + this.field_147366_g = true; + +@@ -199,8 +323,78 @@ + } + } + +- if (this.hasMoved) ++ // CraftBukkit start ++ Player player = this.getPlayerB(); ++ Location from = new Location(player.getWorld(), lastPosX, lastPosY, lastPosZ, lastYaw, lastPitch); // Get the Players previous Event location. ++ Location to = player.getLocation().clone(); // Start off the To location as the Players current location. ++ ++ // If the packet contains movement information then we update the To location with the correct XYZ. ++ if (p_147347_1_.field_149480_h && !(p_147347_1_.field_149480_h && p_147347_1_.field_149477_b == -999.0D && p_147347_1_.field_149475_d == -999.0D)) + { ++ to.setX(p_147347_1_.field_149479_a); ++ to.setY(p_147347_1_.field_149477_b); ++ to.setZ(p_147347_1_.field_149478_c); ++ } ++ ++ // If the packet contains look information then we update the To location with the correct Yaw & Pitch. ++ if (p_147347_1_.field_149481_i) ++ { ++ to.setYaw(p_147347_1_.field_149476_e); ++ to.setPitch(p_147347_1_.field_149473_f); ++ } ++ ++ // Prevent 40 event-calls for less than a single pixel of movement >.> ++ double delta = Math.pow(this.lastPosX - to.getX(), 2) + Math.pow(this.lastPosY - to.getY(), 2) + Math.pow(this.lastPosZ - to.getZ(), 2); ++ float deltaAngle = Math.abs(this.lastYaw - to.getYaw()) + Math.abs(this.lastPitch - to.getPitch()); ++ ++ if ((delta > 1f / 256 || deltaAngle > 10f) && (this.hasMoved && !this.playerEntity.isDead)) ++ { ++ this.lastPosX = to.getX(); ++ this.lastPosY = to.getY(); ++ this.lastPosZ = to.getZ(); ++ this.lastYaw = to.getYaw(); ++ this.lastPitch = to.getPitch(); ++ ++ // Skip the first time we do this ++ if (hasMoved) // Spigot - Better Check! ++ { ++ PlayerMoveEvent event = new PlayerMoveEvent(player, from, to); ++ this.server.getPluginManager().callEvent(event); ++ ++ // If the event is cancelled we move the player back to their old location. ++ if (event.isCancelled()) ++ { ++ this.playerEntity.playerNetServerHandler.sendPacket(new S08PacketPlayerPosLook(from.getX(), from.getY() + 1.6200000047683716D, from ++ .getZ(), from.getYaw(), from.getPitch(), false)); ++ return; ++ } ++ ++ /* If a Plugin has changed the To destination then we teleport the Player ++ there to avoid any 'Moved wrongly' or 'Moved too quickly' errors. ++ We only do this if the Event was not cancelled. */ ++ if (!to.equals(event.getTo()) && !event.isCancelled()) ++ { ++ this.playerEntity.getBukkitEntity().teleport(event.getTo(), PlayerTeleportEvent.TeleportCause.UNKNOWN); ++ return; ++ } ++ ++ /* Check to see if the Players Location has some how changed during the call of the event. ++ This can happen due to a plugin teleporting the player instead of using .setTo() */ ++ if (!from.equals(this.getPlayerB().getLocation()) && this.justTeleported) ++ { ++ this.justTeleported = false; ++ return; ++ } ++ } ++ else ++ { ++ hasMoved = true; // Spigot - Better Check! ++ } ++ } ++ ++ if (this.hasMoved && !this.playerEntity.isDead) ++ { ++ // CraftBukkit end + double d1; + double d2; + double d3; +@@ -318,7 +512,7 @@ + double d9 = Math.max(Math.abs(d6), Math.abs(this.playerEntity.motionZ)); + double d10 = d7 * d7 + d8 * d8 + d9 * d9; + +- if (d10 > 100.0D && (!this.serverController.isSinglePlayer() || !this.serverController.getServerOwner().equals(this.playerEntity.getCommandSenderName()))) ++ if (d10 > 100.0D && this.hasMoved && (!this.serverController.isSinglePlayer() || !this.serverController.getServerOwner().equals(this.playerEntity.getCommandSenderName()))) // CraftBukkit - Added this.checkMovement condition to solve this check being triggered by teleports + { + logger.warn(this.playerEntity.getCommandSenderName() + " moved too quickly! " + d4 + "," + d5 + "," + d6 + " (" + d7 + ", " + d8 + ", " + d9 + ")"); + this.setPlayerLocation(this.lastPosX, this.lastPosY, this.lastPosZ, this.playerEntity.rotationYaw, this.playerEntity.rotationPitch); +@@ -413,21 +607,85 @@ + + public void setPlayerLocation(double p_147364_1_, double p_147364_3_, double p_147364_5_, float p_147364_7_, float p_147364_8_) + { ++ // CraftBukkit start - Delegate to teleport(Location) ++ Player player = this.getPlayerB(); ++ Location from = player.getLocation(); ++ Location to = new Location(this.getPlayerB().getWorld(), p_147364_1_, p_147364_3_, p_147364_5_, p_147364_7_, p_147364_8_); ++ PlayerTeleportEvent event = new PlayerTeleportEvent(player, from, to, PlayerTeleportEvent.TeleportCause.UNKNOWN); ++ this.server.getPluginManager().callEvent(event); ++ from = event.getFrom(); ++ to = event.isCancelled() ? from : event.getTo(); ++ this.teleport(to); ++ } ++ ++ public void teleport(Location dest) ++ { ++ double d0, d1, d2; ++ float f, f1; ++ d0 = dest.getX(); ++ d1 = dest.getY(); ++ d2 = dest.getZ(); ++ f = dest.getYaw(); ++ f1 = dest.getPitch(); ++ ++ // TODO: make sure this is the best way to address this. ++ if (Float.isNaN(f)) ++ { ++ f = 0; ++ } ++ ++ if (Float.isNaN(f1)) ++ { ++ f1 = 0; ++ } ++ ++ this.lastPosX = d0; ++ this.lastPosY = d1; ++ this.lastPosZ = d2; ++ this.lastYaw = f; ++ this.lastPitch = f1; ++ this.justTeleported = true; ++ // CraftBukkit end + this.hasMoved = false; +- this.lastPosX = p_147364_1_; +- this.lastPosY = p_147364_3_; +- this.lastPosZ = p_147364_5_; +- this.playerEntity.setPositionAndRotation(p_147364_1_, p_147364_3_, p_147364_5_, p_147364_7_, p_147364_8_); +- this.playerEntity.playerNetServerHandler.sendPacket(new S08PacketPlayerPosLook(p_147364_1_, p_147364_3_ + 1.6200000047683716D, p_147364_5_, p_147364_7_, p_147364_8_, false)); ++ this.lastPosX = d0; ++ this.lastPosY = d1; ++ this.lastPosZ = d2; ++ this.playerEntity.setPositionAndRotation(d0, d1, d2, f, f1); ++ this.playerEntity.playerNetServerHandler.sendPacket(new S08PacketPlayerPosLook(d0, d1 + 1.6200000047683716D, d2, f, f1, false)); + } + + public void processPlayerDigging(C07PacketPlayerDigging p_147345_1_) + { ++ if (this.playerEntity.isDead) ++ { ++ return; // CraftBukkit ++ } ++ + WorldServer worldserver = this.serverController.worldServerForDimension(this.playerEntity.dimension); + this.playerEntity.func_143004_u(); + + if (p_147345_1_.func_149506_g() == 4) + { ++ // CraftBukkit start ++ // If the ticks aren't the same then the count starts from 0 and we update the lastDropTick. ++ if (this.lastDropTick != MinecraftServer.currentTick) ++ { ++ this.dropCount = 0; ++ this.lastDropTick = MinecraftServer.currentTick; ++ } ++ else ++ { ++ // Else we increment the drop count and check the amount. ++ this.dropCount++; ++ ++ if (this.dropCount >= 20) ++ { ++ this.logger.warn(this.playerEntity.getCommandSenderName() + " dropped their items too quickly!"); ++ this.kickPlayerFromServer("You dropped your items too quickly (Hacking?)"); ++ return; ++ } ++ } ++ // CraftBukkit end + this.playerEntity.dropOneItem(false); + } + else if (p_147345_1_.func_149506_g() == 3) +@@ -490,7 +748,17 @@ + } + else + { ++ // CraftBukkit start ++ CraftEventFactory.callPlayerInteractEvent(this.playerEntity, Action.LEFT_CLICK_BLOCK, i, j, k, p_147345_1_.func_149501_f(), this.playerEntity.inventory.getCurrentItem()); + this.playerEntity.playerNetServerHandler.sendPacket(new S23PacketBlockChange(i, j, k, worldserver)); ++ // Update any tile entity data for this block ++ TileEntity tileentity = worldserver.getTileEntity(i, j, k); ++ ++ if (tileentity != null) ++ { ++ this.playerEntity.playerNetServerHandler.sendPacket(tileentity.getDescriptionPacket()); ++ } ++ // CraftBukkit end + } + } + else if (p_147345_1_.func_149506_g() == 2) +@@ -517,6 +785,39 @@ + public void processPlayerBlockPlacement(C08PacketPlayerBlockPlacement p_147346_1_) + { + WorldServer worldserver = this.serverController.worldServerForDimension(this.playerEntity.dimension); ++ // CraftBukkit start ++ if (this.playerEntity.isDead) ++ { ++ return; ++ } ++ ++ // This is a horrible hack needed because the client sends 2 packets on 'right mouse click' ++ // aimed at a block. We shouldn't need to get the second packet if the data is handled ++ // but we cannot know what the client will do, so we might still get it ++ // ++ // If the time between packets is small enough, and the 'signature' similar, we discard the ++ // second one. This sadly has to remain until Mojang makes their packets saner. :( ++ // -- Grum ++ if (p_147346_1_.func_149568_f() == 255) ++ { ++ if (p_147346_1_.func_149574_g() != null && p_147346_1_.func_149574_g().getItem() == this.lastMaterial && this.lastPacket != null ++ && p_147346_1_.timestamp - this.lastPacket < 100) ++ { ++ this.lastPacket = null; ++ return; ++ } ++ } ++ else ++ { ++ this.lastMaterial = p_147346_1_.func_149574_g() == null ? null : p_147346_1_.func_149574_g().getItem(); ++ this.lastPacket = p_147346_1_.timestamp; ++ } ++ ++ // CraftBukkit - if rightclick decremented the item, always send the update packet. */ ++ // this is not here for CraftBukkit's own functionality; rather it is to fix ++ // a notch bug where the item doesn't update correctly. ++ boolean always = false; ++ // CraftBukkit end + ItemStack itemstack = this.playerEntity.inventory.getCurrentItem(); + boolean flag = false; + boolean placeResult = true; +@@ -533,11 +834,21 @@ + return; + } + +- PlayerInteractEvent event = ForgeEventFactory.onPlayerInteract(playerEntity, PlayerInteractEvent.Action.RIGHT_CLICK_AIR, 0, 0, 0, -1, worldserver); +- if (event.useItem != Event.Result.DENY) ++ PlayerInteractEvent forgeEvent = ForgeEventFactory.onPlayerInteract(playerEntity, PlayerInteractEvent.Action.RIGHT_CLICK_AIR, 0, 0, 0, -1, ++ worldserver); // Cauldron - rename event ++ // CraftBukkit start ++ int itemstackAmount = itemstack.stackSize; ++ org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(this.playerEntity, Action.RIGHT_CLICK_AIR, itemstack); ++ ++ if (forgeEvent.useItem != cpw.mods.fml.common.eventhandler.Event.Result.DENY && event.useItemInHand() != Event.Result.DENY) + { + this.playerEntity.theItemInWorldManager.tryUseItem(this.playerEntity, worldserver, itemstack); + } ++ // CraftBukkit - notch decrements the counter by 1 in the above method with food, ++ // snowballs and so forth, but he does it in a place that doesn't cause the ++ // inventory update packet to get sent ++ always = (itemstack.stackSize != itemstackAmount); ++ // CraftBukkit end + } + else if (p_147346_1_.func_149571_d() >= this.serverController.getBuildLimit() - 1 && (p_147346_1_.func_149568_f() == 1 || p_147346_1_.func_149571_d() >= this.serverController.getBuildLimit())) + { +@@ -548,17 +859,24 @@ + } + else + { +- double dist = playerEntity.theItemInWorldManager.getBlockReachDistance() + 1; +- dist *= dist; +- if (this.hasMoved && this.playerEntity.getDistanceSq((double)i + 0.5D, (double)j + 0.5D, (double)k + 0.5D) < dist && !this.serverController.isBlockProtected(worldserver, i, j, k, this.playerEntity)) ++ // CraftBukkit start - Check if we can actually do something over this large a distance ++ Location eyeLoc = this.getPlayerB().getEyeLocation(); ++ double reachDistance = NumberConversions.square(eyeLoc.getX() - i) + NumberConversions.square(eyeLoc.getY() - j) ++ + NumberConversions.square(eyeLoc.getZ() - k); ++ ++ if (reachDistance > (this.getPlayerB().getGameMode() == org.bukkit.GameMode.CREATIVE ? CREATIVE_PLACE_DISTANCE_SQUARED : SURVIVAL_PLACE_DISTANCE_SQUARED)) + { +- // record block place result so we can update client itemstack size if place event was cancelled. +- if (!this.playerEntity.theItemInWorldManager.activateBlockOrUseItem(this.playerEntity, worldserver, itemstack, i, j, k, l, p_147346_1_.func_149573_h(), p_147346_1_.func_149569_i(), p_147346_1_.func_149575_j())) +- { +- placeResult = false; +- } ++ return; + } + ++ // Cauldron start - record place result so we can update client inventory slot if place event is cancelled. Fixes stacksize client-side bug ++ if (!this.playerEntity.theItemInWorldManager.activateBlockOrUseItem(this.playerEntity, worldserver, itemstack, i, j, k, l, ++ p_147346_1_.func_149573_h(), p_147346_1_.func_149569_i(), p_147346_1_.func_149575_j())) ++ { ++ always = true; ++ } ++ // Cauldron end ++ // CraftBukkit end + flag = true; + } + +@@ -612,10 +930,17 @@ + this.playerEntity.isChangingQuantityOnly = true; + this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem] = ItemStack.copyItemStack(this.playerEntity.inventory.mainInventory[this.playerEntity.inventory.currentItem]); + Slot slot = this.playerEntity.openContainer.getSlotFromInventory(this.playerEntity.inventory, this.playerEntity.inventory.currentItem); ++ // Cauldron start - abort if no slot, fixes RP2 timer crash block place - see #181 ++ if (slot == null) ++ { ++ this.playerEntity.isChangingQuantityOnly = false; // set flag to false or it will cause inventory to glitch on death ++ return; ++ } ++ // Cauldron end + this.playerEntity.openContainer.detectAndSendChanges(); + this.playerEntity.isChangingQuantityOnly = false; + +- if (!ItemStack.areItemStacksEqual(this.playerEntity.inventory.getCurrentItem(), p_147346_1_.func_149574_g()) || !placeResult) // force client itemstack update if place event was cancelled ++ if (!ItemStack.areItemStacksEqual(this.playerEntity.inventory.getCurrentItem(), p_147346_1_.func_149574_g()) || always) // Cauldron - always is needed to update client itemstack if placement is cancelled + { + this.sendPacket(new S2FPacketSetSlot(this.playerEntity.openContainer.windowId, slot.slotNumber, this.playerEntity.inventory.getCurrentItem())); + } +@@ -624,14 +949,34 @@ + + public void onDisconnect(IChatComponent p_147231_1_) + { +- logger.info(this.playerEntity.getCommandSenderName() + " lost connection: " + p_147231_1_); ++ // CraftBukkit start - Rarely it would send a disconnect line twice ++ if (this.processedDisconnect) ++ { ++ return; ++ } ++ else ++ { ++ this.processedDisconnect = true; ++ } ++ // CraftBukkit end ++ logger.info(this.playerEntity.getCommandSenderName() + " lost connection: " + p_147231_1_.getUnformattedText()); // CraftBukkit - Don't toString the component + this.serverController.func_147132_au(); +- ChatComponentTranslation chatcomponenttranslation = new ChatComponentTranslation("multiplayer.player.left", new Object[] {this.playerEntity.func_145748_c_()}); +- chatcomponenttranslation.getChatStyle().setColor(EnumChatFormatting.YELLOW); +- this.serverController.getConfigurationManager().sendChatMsg(chatcomponenttranslation); ++ // CraftBukkit start - Replace vanilla quit message handling with our own. ++ /* ++ ChatMessage chatcomponenttranslation = new ChatMessage("multiplayer.player.left", new Object[] { this.player.getScoreboardDisplayName()}); ++ ++ chatcomponenttranslation.b().setColor(EnumChatFormat.YELLOW); ++ this.minecraftServer.getPlayerList().sendMessage(chatcomponenttranslation); ++ */ + this.playerEntity.mountEntityAndWakeUp(); +- this.serverController.getConfigurationManager().playerLoggedOut(this.playerEntity); ++ String quitMessage = this.serverController.getConfigurationManager().disconnect(this.playerEntity); + ++ if ((quitMessage != null) && (quitMessage.length() > 0)) ++ { ++ this.serverController.getConfigurationManager().sendMessage(CraftChatMessage.fromString(quitMessage)); ++ } ++ // CraftBukkit end ++ + if (this.serverController.isSinglePlayer() && this.playerEntity.getCommandSenderName().equals(this.serverController.getServerOwner())) + { + logger.info("Stopping singleplayer server as player logged out"); +@@ -657,6 +1002,18 @@ + } + } + ++ // CraftBukkit start ++ if (p_147359_1_ == null) ++ { ++ return; ++ } ++ else if (p_147359_1_ instanceof S05PacketSpawnPosition) ++ { ++ S05PacketSpawnPosition packet6 = (S05PacketSpawnPosition) p_147359_1_; ++ this.playerEntity.compassTarget = new Location(this.getPlayerB().getWorld(), packet6.field_149364_a, packet6.field_149362_b, packet6.field_149363_c); ++ } ++ // CraftBukkit end ++ + try + { + this.netManager.scheduleOutboundPacket(p_147359_1_, new GenericFutureListener[0]); +@@ -679,20 +1036,37 @@ + + public void processHeldItemChange(C09PacketHeldItemChange p_147355_1_) + { ++ // CraftBukkit start ++ if (this.playerEntity.isDead) ++ { ++ return; ++ } ++ + if (p_147355_1_.func_149614_c() >= 0 && p_147355_1_.func_149614_c() < InventoryPlayer.getHotbarSize()) + { ++ PlayerItemHeldEvent event = new PlayerItemHeldEvent(this.getPlayerB(), this.playerEntity.inventory.currentItem, p_147355_1_.func_149614_c()); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ this.sendPacket(new S09PacketHeldItemChange(this.playerEntity.inventory.currentItem)); ++ this.playerEntity.func_143004_u(); ++ return; ++ } ++ // CraftBukkit end + this.playerEntity.inventory.currentItem = p_147355_1_.func_149614_c(); + this.playerEntity.func_143004_u(); + } + else + { + logger.warn(this.playerEntity.getCommandSenderName() + " tried to set an invalid carried item"); ++ this.kickPlayerFromServer("Nope!"); // CraftBukkit + } + } + + public void processChatMessage(C01PacketChatMessage p_147354_1_) + { +- if (this.playerEntity.func_147096_v() == EntityPlayer.EnumChatVisibility.HIDDEN) ++ if (this.playerEntity.isDead || this.playerEntity.func_147096_v() == EntityPlayer.EnumChatVisibility.HIDDEN) // CraftBukkit - dead men tell no tales + { + ChatComponentTranslation chatcomponenttranslation = new ChatComponentTranslation("chat.cannotSend", new Object[0]); + chatcomponenttranslation.getChatStyle().setColor(EnumChatFormatting.RED); +@@ -708,51 +1082,385 @@ + { + if (!ChatAllowedCharacters.isAllowedCharacter(s.charAt(i))) + { +- this.kickPlayerFromServer("Illegal characters in chat"); ++ // CraftBukkit start - threadsafety ++ if (p_147354_1_.hasPriority()) ++ { ++ Waitable waitable = new Waitable() { ++ @Override ++ protected Object evaluate() ++ { ++ NetHandlerPlayServer.this.kickPlayerFromServer("Illegal characters in chat"); ++ return null; ++ } ++ }; ++ this.serverController.processQueue.add(waitable); ++ ++ try ++ { ++ waitable.get(); ++ } ++ catch (InterruptedException e) ++ { ++ Thread.currentThread().interrupt(); ++ } ++ catch (ExecutionException e) ++ { ++ throw new RuntimeException(e); ++ } ++ } ++ else ++ { ++ this.kickPlayerFromServer("Illegal characters in chat"); ++ } ++ // CraftBukkit end + return; + } + } + +- if (s.startsWith("/")) ++ // CraftBukkit start ++ if (!p_147354_1_.hasPriority()) + { +- this.handleSlashCommand(s); ++ try ++ { ++ this.serverController.server.playerCommandState = true; ++ this.handleSlashCommand(s); ++ } ++ finally ++ { ++ this.serverController.server.playerCommandState = false; ++ } + } +- else ++ else if (s.isEmpty()) + { +- ChatComponentTranslation chatcomponenttranslation1 = new ChatComponentTranslation("chat.type.text", new Object[] {this.playerEntity.func_145748_c_(), ForgeHooks.newChatWithLinks(s)}); // Fixes chat links +- chatcomponenttranslation1 = ForgeHooks.onServerChatEvent(this, s, chatcomponenttranslation1); +- if (chatcomponenttranslation1 == null) return; +- this.serverController.getConfigurationManager().sendChatMsgImpl(chatcomponenttranslation1, false); ++ logger.warn(this.playerEntity.getCommandSenderName() + " tried to send an empty message"); + } ++ else if (getPlayerB().isConversing()) ++ { ++ getPlayerB().acceptConversationInput(s); ++ } ++ else if (this.playerEntity.func_147096_v() == EntityPlayer.EnumChatVisibility.SYSTEM) // Re-add "Command Only" flag check ++ { ++ ChatComponentTranslation chatcomponenttranslation = new ChatComponentTranslation("chat.cannotSend", new Object[0]); ++ chatcomponenttranslation.getChatStyle().setColor(EnumChatFormatting.RED); ++ this.sendPacket(new S02PacketChat(chatcomponenttranslation)); ++ } ++ else if (true) ++ { ++ this.chat(s, true); ++ // CraftBukkit end - the below is for reference. :) ++ } + +- this.chatSpamThresholdCount += 20; ++ // CraftBukkit start - replaced with thread safe throttle ++ // this.chatSpamThresholdCount += 20; ++ if (chatSpamField.addAndGet(this, 20) > 200 && !this.serverController.getConfigurationManager().func_152596_g(this.playerEntity.getGameProfile())) ++ { ++ if (p_147354_1_.hasPriority()) ++ { ++ Waitable waitable = new Waitable() { ++ @Override ++ protected Object evaluate() ++ { ++ NetHandlerPlayServer.this.kickPlayerFromServer("disconnect.spam"); ++ return null; ++ } ++ }; ++ this.serverController.processQueue.add(waitable); + +- if (this.chatSpamThresholdCount > 200 && !this.serverController.getConfigurationManager().func_152596_g(this.playerEntity.getGameProfile())) ++ try ++ { ++ waitable.get(); ++ } ++ catch (InterruptedException e) ++ { ++ Thread.currentThread().interrupt(); ++ } ++ catch (ExecutionException e) ++ { ++ throw new RuntimeException(e); ++ } ++ } ++ else ++ { ++ this.kickPlayerFromServer("disconnect.spam"); ++ } ++ ++ // CraftBukkit end ++ } ++ } ++ } ++ ++ // CraftBukkit start ++ public void chat(String s, boolean async) ++ { ++ if (s.isEmpty() || this.playerEntity.func_147096_v() == EntityPlayer.EnumChatVisibility.HIDDEN) ++ { ++ return; ++ } ++ ++ if (!async && s.startsWith("/")) ++ { ++ this.handleSlashCommand(s); ++ } ++ else if (this.playerEntity.func_147096_v() == EntityPlayer.EnumChatVisibility.SYSTEM) ++ { ++ // Do nothing, this is coming from a plugin ++ } ++ else ++ { ++ // Cauldron start - handle Forge event ++ ChatComponentTranslation chatcomponenttranslation1 = new ChatComponentTranslation("chat.type.text", new Object[] { ++ this.playerEntity.func_145748_c_(), s }); ++ chatcomponenttranslation1 = ForgeHooks.onServerChatEvent(this, s, chatcomponenttranslation1); ++ ++ if (chatcomponenttranslation1 != null ++ && chatcomponenttranslation1.getFormatArgs()[chatcomponenttranslation1.getFormatArgs().length - 1] instanceof String) + { +- this.kickPlayerFromServer("disconnect.spam"); ++ // use event message from Forge ++ s = (String) chatcomponenttranslation1.getFormatArgs()[chatcomponenttranslation1.getFormatArgs().length - 1]; + } ++ // Cauldron end ++ Player player = this.getPlayerB(); ++ AsyncPlayerChatEvent event = new AsyncPlayerChatEvent(async, player, s, new LazyPlayerSet()); // Cauldron - pass changed message if any from Forge ++ event.setCancelled(chatcomponenttranslation1 == null); // Cauldron - pre-cancel event if forge event was cancelled ++ this.server.getPluginManager().callEvent(event); ++ if (PlayerChatEvent.getHandlerList().getRegisteredListeners().length != 0) ++ { ++ // Evil plugins still listening to deprecated event ++ final PlayerChatEvent queueEvent = new PlayerChatEvent(player, event.getMessage(), event.getFormat(), event.getRecipients()); ++ queueEvent.setCancelled(event.isCancelled()); ++ Waitable waitable = new Waitable() { ++ @Override ++ protected Object evaluate() ++ { ++ org.bukkit.Bukkit.getPluginManager().callEvent(queueEvent); ++ ++ if (queueEvent.isCancelled()) ++ { ++ return null; ++ } ++ ++ String message = String.format(queueEvent.getFormat(), queueEvent.getPlayer().getDisplayName(), queueEvent.getMessage()); ++ NetHandlerPlayServer.this.serverController.console.sendMessage(message); ++ if (((LazyPlayerSet) queueEvent.getRecipients()).isLazy()) ++ { ++ for (Object recipient : serverController.getConfigurationManager().playerEntityList) ++ { ++ ((EntityPlayerMP) recipient).sendMessage(CraftChatMessage.fromString(message)); ++ } ++ } ++ else ++ { ++ for (Player player : queueEvent.getRecipients()) ++ { ++ player.sendMessage(message); ++ } ++ } ++ ++ return null; ++ } ++ }; ++ ++ if (async) ++ { ++ serverController.processQueue.add(waitable); ++ } ++ else ++ { ++ waitable.run(); ++ } ++ ++ try ++ { ++ waitable.get(); ++ } ++ catch (InterruptedException e) ++ { ++ Thread.currentThread().interrupt(); // This is proper habit for java. If we aren't handling it, pass it on! ++ } ++ catch (ExecutionException e) ++ { ++ throw new RuntimeException("Exception processing chat event", e.getCause()); ++ } ++ } ++ else ++ { ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ ++ s = String.format(event.getFormat(), event.getPlayer().getDisplayName(), event.getMessage()); ++ serverController.console.sendMessage(s); ++ if (((LazyPlayerSet) event.getRecipients()).isLazy()) ++ { ++ for (Object recipient : serverController.getConfigurationManager().playerEntityList) ++ { ++ for (IChatComponent component : CraftChatMessage.fromString(s)) ++ { ++ ((EntityPlayerMP) recipient).sendMessage(CraftChatMessage.fromString(s)); ++ } ++ } ++ } ++ else ++ { ++ for (Player recipient : event.getRecipients()) ++ { ++ recipient.sendMessage(s); ++ } ++ } ++ } + } + } ++ // CraftBukkit end + + private void handleSlashCommand(String p_147361_1_) + { +- this.serverController.getCommandManager().executeCommand(this.playerEntity, p_147361_1_); ++ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.startTiming(); // Spigot ++ // CraftBukkit start ++ CraftPlayer player = this.getPlayerB(); ++ PlayerCommandPreprocessEvent event = new PlayerCommandPreprocessEvent(player, p_147361_1_, new LazyPlayerSet()); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot ++ return; ++ } ++ ++ try ++ { ++ // Spigot Start ++ if (org.spigotmc.SpigotConfig.logCommands) ++ { ++ this.logger.info(event.getPlayer().getName() + " issued server command: " + event.getMessage()); // CraftBukkit ++ } ++ ++ // Spigot end ++ // Cauldron start - handle bukkit/vanilla commands ++ int space = event.getMessage().indexOf(" "); ++ // if bukkit command exists then execute it over vanilla ++ if (this.server.getCommandMap().getCommand(event.getMessage().substring(1, space != -1 ? space : event.getMessage().length())) != null) ++ { ++ this.server.dispatchCommand(event.getPlayer(), event.getMessage().substring(1)); ++ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot ++ return; ++ } ++ else ++ // process vanilla command ++ { ++ this.server.dispatchVanillaCommand(event.getPlayer(), event.getMessage().substring(1)); ++ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot ++ return; ++ } ++ } ++ catch (org.bukkit.command.CommandException ex) ++ { ++ player.sendMessage(org.bukkit.ChatColor.RED + "An internal error occurred while attempting to perform this command"); ++ java.util.logging.Logger.getLogger(NetHandlerPlayServer.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); ++ org.bukkit.craftbukkit.SpigotTimings.playerCommandTimer.stopTiming(); // Spigot ++ return; ++ } ++ ++ // this.serverController.getCommandManager().executeCommand(this.playerEntity, p_147361_1_); ++ // CraftBukkit end + } + + public void processAnimation(C0APacketAnimation p_147350_1_) + { ++ if (this.playerEntity.isDead) ++ { ++ return; // CraftBukkit ++ } ++ + this.playerEntity.func_143004_u(); + + if (p_147350_1_.func_149421_d() == 1) + { ++ // CraftBukkit start - Raytrace to look for 'rogue armswings' ++ float f = 1.0F; ++ float f1 = this.playerEntity.prevRotationPitch + (this.playerEntity.rotationPitch - this.playerEntity.prevRotationPitch) * f; ++ float f2 = this.playerEntity.prevRotationYaw + (this.playerEntity.rotationYaw - this.playerEntity.prevRotationYaw) * f; ++ double d0 = this.playerEntity.prevPosX + (this.playerEntity.posX - this.playerEntity.prevPosX) * (double) f; ++ double d1 = this.playerEntity.prevPosY + (this.playerEntity.posY - this.playerEntity.prevPosY) * (double) f + 1.62D ++ - (double) this.playerEntity.yOffset; ++ double d2 = this.playerEntity.prevPosZ + (this.playerEntity.posZ - this.playerEntity.prevPosZ) * (double) f; ++ Vec3 vec3 = Vec3.createVectorHelper(d0, d1, d2); ++ float f3 = MathHelper.cos(-f2 * 0.017453292F - (float) Math.PI); ++ float f4 = MathHelper.sin(-f2 * 0.017453292F - (float) Math.PI); ++ float f5 = -MathHelper.cos(-f1 * 0.017453292F); ++ float f6 = MathHelper.sin(-f1 * 0.017453292F); ++ float f7 = f4 * f5; ++ float f8 = f3 * f5; ++ double d3 = 5.0D; ++ Vec3 vec31 = vec3.addVector((double) f7 * d3, (double) f6 * d3, (double) f8 * d3); ++ MovingObjectPosition movingobjectposition = this.playerEntity.worldObj.rayTraceBlocks(vec3, vec31, true); ++ boolean valid = false; ++ ++ if (movingobjectposition == null || movingobjectposition.typeOfHit != MovingObjectPosition.MovingObjectType.BLOCK) ++ { ++ valid = true; ++ } ++ else ++ { ++ Block block = this.playerEntity.worldObj.getBlock(movingobjectposition.blockX, movingobjectposition.blockY, movingobjectposition.blockZ); ++ ++ if (!block.isOpaqueCube()) // Should be isBreakable? ++ { ++ valid = true; ++ } ++ } ++ ++ if (valid) ++ { ++ CraftEventFactory.callPlayerInteractEvent(this.playerEntity, Action.LEFT_CLICK_AIR, this.playerEntity.inventory.getCurrentItem()); ++ } ++ ++ // Arm swing animation ++ PlayerAnimationEvent event = new PlayerAnimationEvent(this.getPlayerB()); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ // CraftBukkit end + this.playerEntity.swingItem(); + } + } + + public void processEntityAction(C0BPacketEntityAction p_147357_1_) + { ++ // CraftBukkit start ++ if (this.playerEntity.isDead) ++ { ++ return; ++ } ++ + this.playerEntity.func_143004_u(); + ++ if (p_147357_1_.func_149513_d() == 1 || p_147357_1_.func_149513_d() == 2) ++ { ++ PlayerToggleSneakEvent event = new PlayerToggleSneakEvent(this.getPlayerB(), p_147357_1_.func_149513_d() == 1); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ } ++ ++ if (p_147357_1_.func_149513_d() == 4 || p_147357_1_.func_149513_d() == 5) ++ { ++ PlayerToggleSprintEvent event = new PlayerToggleSprintEvent(this.getPlayerB(), p_147357_1_.func_149513_d() == 4); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ } ++ // CraftBukkit end ++ + if (p_147357_1_.func_149513_d() == 1) + { + this.playerEntity.setSneaking(true); +@@ -772,7 +1480,7 @@ + else if (p_147357_1_.func_149513_d() == 3) + { + this.playerEntity.wakeUpPlayer(false, true, true); +- this.hasMoved = false; ++ // this.hasMoved = false; // CraftBukkit - this is handled in teleport + } + else if (p_147357_1_.func_149513_d() == 6) + { +@@ -789,8 +1497,20 @@ + + public void processUseEntity(C02PacketUseEntity p_147340_1_) + { ++ if (this.playerEntity.isDead) ++ { ++ return; // CraftBukkit ++ } ++ + WorldServer worldserver = this.serverController.worldServerForDimension(this.playerEntity.dimension); +- Entity entity = p_147340_1_.func_149564_a(worldserver); ++ Entity entity = p_147340_1_.func_149564_a((World) worldserver); ++ // Spigot Start ++ if (entity == playerEntity) ++ { ++ kickPlayerFromServer("Cannot interact with self!"); ++ return; ++ } ++ // Spigot End + this.playerEntity.func_143004_u(); + + if (entity != null) +@@ -805,9 +1525,53 @@ + + if (this.playerEntity.getDistanceSqToEntity(entity) < d0) + { ++ ItemStack itemInHand = this.playerEntity.inventory.getCurrentItem(); // CraftBukkit ++ + if (p_147340_1_.func_149565_c() == C02PacketUseEntity.Action.INTERACT) + { ++ // CraftBukkit start ++ boolean triggerTagUpdate = itemInHand != null && itemInHand.getItem() == Items.name_tag && entity instanceof EntityLiving; ++ boolean triggerChestUpdate = itemInHand != null && itemInHand.getItem() == Item.getItemFromBlock(Blocks.chest) ++ && entity instanceof EntityHorse; ++ boolean triggerLeashUpdate = itemInHand != null && itemInHand.getItem() == Items.lead && entity instanceof EntityLiving; ++ PlayerInteractEntityEvent event = new PlayerInteractEntityEvent((Player) this.getPlayerB(), entity.getBukkitEntity()); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (triggerLeashUpdate ++ && (event.isCancelled() || this.playerEntity.inventory.getCurrentItem() == null || this.playerEntity.inventory.getCurrentItem() ++ .getItem() != Items.lead)) ++ { ++ // Refresh the current leash state ++ this.sendPacket(new S1BPacketEntityAttach(1, entity, ((EntityLiving) entity).getLeashedToEntity())); ++ } ++ ++ if (triggerTagUpdate ++ && (event.isCancelled() || this.playerEntity.inventory.getCurrentItem() == null || this.playerEntity.inventory.getCurrentItem() ++ .getItem() != Items.name_tag)) ++ { ++ // Refresh the current entity metadata ++ this.sendPacket(new S1CPacketEntityMetadata(entity.getEntityId(), entity.dataWatcher, true)); ++ } ++ ++ if (triggerChestUpdate ++ && (event.isCancelled() || this.playerEntity.inventory.getCurrentItem() == null || this.playerEntity.inventory.getCurrentItem() ++ .getItem() != Item.getItemFromBlock(Blocks.chest))) ++ { ++ this.sendPacket(new S1CPacketEntityMetadata(entity.getEntityId(), entity.dataWatcher, true)); ++ } ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ // CraftBukkit end + this.playerEntity.interactWith(entity); ++ // CraftBukkit start ++ if (itemInHand != null && itemInHand.stackSize <= -1) ++ { ++ this.playerEntity.sendContainerToPlayer(this.playerEntity.openContainer); ++ } ++ // CraftBukkit end + } + else if (p_147340_1_.func_149565_c() == C02PacketUseEntity.Action.ATTACK) + { +@@ -819,6 +1583,13 @@ + } + + this.playerEntity.attackTargetEntityWithCurrentItem(entity); ++ ++ // CraftBukkit start ++ if (itemInHand != null && itemInHand.stackSize <= -1) ++ { ++ this.playerEntity.sendContainerToPlayer(this.playerEntity.openContainer); ++ } ++ // CraftBukkit end + } + } + } +@@ -834,8 +1605,19 @@ + case 1: + if (this.playerEntity.playerConqueredTheEnd) + { +- this.playerEntity = this.serverController.getConfigurationManager().respawnPlayer(this.playerEntity, 0, true); ++ // Cauldron start ++ if (this.playerEntity.dimension == -1) // coming from end ++ { ++ // We really should be calling transferPlayerToDimension since the player is coming in contact with a portal. ++ this.serverController.getConfigurationManager().respawnPlayer(this.playerEntity, 0, true); // set flag to indicate player is leaving end. + } ++ else ++ // not coming from end ++ { ++ this.playerEntity = this.serverController.getConfigurationManager().respawnPlayer(this.playerEntity, 0, false); ++ } ++ // Cauldron end ++ } + else if (this.playerEntity.getServerForPlayer().getWorldInfo().isHardcoreModeEnabled()) + { + if (this.serverController.isSinglePlayer() && this.playerEntity.getCommandSenderName().equals(this.serverController.getServerOwner())) +@@ -871,17 +1653,461 @@ + + public void processCloseWindow(C0DPacketCloseWindow p_147356_1_) + { ++ if (this.playerEntity.isDead) ++ { ++ return; // CraftBukkit ++ } ++ ++ // Cauldron start - vanilla compatibility ++ try ++ { ++ if (this.playerEntity.openContainer.getBukkitView() != null) ++ { ++ CraftEventFactory.handleInventoryCloseEvent(this.playerEntity); // CraftBukkit ++ } ++ } ++ catch (AbstractMethodError e) ++ { ++ // do nothing ++ } ++ // Cauldron end + this.playerEntity.closeContainer(); + } + + public void processClickWindow(C0EPacketClickWindow p_147351_1_) + { ++ if (this.playerEntity.isDead) ++ { ++ return; // CraftBukkit ++ } ++ + this.playerEntity.func_143004_u(); + + if (this.playerEntity.openContainer.windowId == p_147351_1_.func_149548_c() && this.playerEntity.openContainer.isPlayerNotUsingContainer(this.playerEntity)) + { +- ItemStack itemstack = this.playerEntity.openContainer.slotClick(p_147351_1_.func_149544_d(), p_147351_1_.func_149543_e(), p_147351_1_.func_149542_h(), this.playerEntity); ++ // CraftBukkit start - Call InventoryClickEvent ++ if (p_147351_1_.func_149544_d() < -1 && p_147351_1_.func_149544_d() != -999) ++ { ++ return; ++ } + ++ InventoryView inventory = this.playerEntity.openContainer.getBukkitView(); ++ SlotType type = CraftInventoryView.getSlotType(inventory, p_147351_1_.func_149544_d()); ++ InventoryClickEvent event = null; ++ ClickType click = ClickType.UNKNOWN; ++ InventoryAction action = InventoryAction.UNKNOWN; ++ ItemStack itemstack = null; ++ ++ // Cauldron start - some containers such as NEI's Creative Container does not have a view at this point so we need to create one ++ if (inventory == null) ++ { ++ inventory = new CraftInventoryView(this.playerEntity.getBukkitEntity(), MinecraftServer.getServer().server.createInventory( ++ this.playerEntity.getBukkitEntity(), InventoryType.CHEST), this.playerEntity.openContainer); ++ this.playerEntity.openContainer.bukkitView = inventory; ++ } ++ // Cauldron end ++ ++ if (p_147351_1_.func_149544_d() == -1) ++ { ++ type = SlotType.OUTSIDE; // override ++ click = p_147351_1_.func_149543_e() == 0 ? ClickType.WINDOW_BORDER_LEFT : ClickType.WINDOW_BORDER_RIGHT; ++ action = InventoryAction.NOTHING; ++ } ++ else if (p_147351_1_.func_149542_h() == 0) ++ { ++ if (p_147351_1_.func_149543_e() == 0) ++ { ++ click = ClickType.LEFT; ++ } ++ else if (p_147351_1_.func_149543_e() == 1) ++ { ++ click = ClickType.RIGHT; ++ } ++ ++ if (p_147351_1_.func_149543_e() == 0 || p_147351_1_.func_149543_e() == 1) ++ { ++ action = InventoryAction.NOTHING; // Don't want to repeat ourselves ++ ++ if (p_147351_1_.func_149544_d() == -999) ++ { ++ if (playerEntity.inventory.getItemStack() != null) ++ { ++ action = p_147351_1_.func_149543_e() == 0 ? InventoryAction.DROP_ALL_CURSOR : InventoryAction.DROP_ONE_CURSOR; ++ } ++ } ++ else ++ { ++ Slot slot = this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()); ++ ++ if (slot != null) ++ { ++ ItemStack clickedItem = slot.getStack(); ++ ItemStack cursor = playerEntity.inventory.getItemStack(); ++ ++ if (clickedItem == null) ++ { ++ if (cursor != null) ++ { ++ action = p_147351_1_.func_149543_e() == 0 ? InventoryAction.PLACE_ALL : InventoryAction.PLACE_ONE; ++ } ++ } ++ else if (slot.canTakeStack(playerEntity)) // Should be Slot.isPlayerAllowed ++ { ++ if (cursor == null) ++ { ++ action = p_147351_1_.func_149543_e() == 0 ? InventoryAction.PICKUP_ALL : InventoryAction.PICKUP_HALF; ++ } ++ else if (slot.isItemValid(cursor)) // Should be Slot.isItemAllowed ++ { ++ if (clickedItem.isItemEqual(cursor) && ItemStack.areItemStackTagsEqual(clickedItem, cursor)) ++ { ++ int toPlace = p_147351_1_.func_149543_e() == 0 ? cursor.stackSize : 1; ++ toPlace = Math.min(toPlace, clickedItem.getMaxStackSize() - clickedItem.stackSize); ++ toPlace = Math.min(toPlace, slot.inventory.getInventoryStackLimit() - clickedItem.stackSize); ++ ++ if (toPlace == 1) ++ { ++ action = InventoryAction.PLACE_ONE; ++ } ++ else if (toPlace == cursor.stackSize) ++ { ++ action = InventoryAction.PLACE_ALL; ++ } ++ else if (toPlace < 0) ++ { ++ action = toPlace != -1 ? InventoryAction.PICKUP_SOME : InventoryAction.PICKUP_ONE; // this happens with oversized stacks ++ } ++ else if (toPlace != 0) ++ { ++ action = InventoryAction.PLACE_SOME; ++ } ++ } ++ else if (cursor.stackSize <= slot.getSlotStackLimit()) // Should be Slot.getMaxStackSize() ++ { ++ action = InventoryAction.SWAP_WITH_CURSOR; ++ } ++ } ++ else if (cursor.getItem() == clickedItem.getItem() ++ && (!cursor.getHasSubtypes() || cursor.getItemDamage() == clickedItem.getItemDamage()) ++ && ItemStack.areItemStackTagsEqual(cursor, clickedItem)) ++ { ++ if (clickedItem.stackSize >= 0) ++ { ++ if (clickedItem.stackSize + cursor.stackSize <= cursor.getMaxStackSize()) ++ { ++ // As of 1.5, this is result slots only ++ action = InventoryAction.PICKUP_ALL; ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++ } ++ else if (p_147351_1_.func_149542_h() == 1) ++ { ++ if (p_147351_1_.func_149543_e() == 0) ++ { ++ click = ClickType.SHIFT_LEFT; ++ } ++ else if (p_147351_1_.func_149543_e() == 1) ++ { ++ click = ClickType.SHIFT_RIGHT; ++ } ++ ++ if (p_147351_1_.func_149543_e() == 0 || p_147351_1_.func_149543_e() == 1) ++ { ++ if (p_147351_1_.func_149544_d() < 0) ++ { ++ action = InventoryAction.NOTHING; ++ } ++ else ++ { ++ Slot slot = this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()); ++ ++ if (slot != null && slot.canTakeStack(this.playerEntity) && slot.getHasStack()) // Should be Slot.hasItem() ++ { ++ action = InventoryAction.MOVE_TO_OTHER_INVENTORY; ++ } ++ else ++ { ++ action = InventoryAction.NOTHING; ++ } ++ } ++ } ++ } ++ else if (p_147351_1_.func_149542_h() == 2) ++ { ++ if (p_147351_1_.func_149543_e() >= 0 && p_147351_1_.func_149543_e() < 9) ++ { ++ click = ClickType.NUMBER_KEY; ++ Slot clickedSlot = this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()); ++ ++ if (clickedSlot.canTakeStack(playerEntity)) ++ { ++ ItemStack hotbar = this.playerEntity.inventory.getStackInSlot(p_147351_1_.func_149543_e()); ++ boolean canCleanSwap = hotbar == null || (clickedSlot.inventory == playerEntity.inventory && clickedSlot.isItemValid(hotbar)); // the slot will accept the hotbar item ++ ++ if (clickedSlot.getHasStack()) ++ { ++ if (canCleanSwap) ++ { ++ action = InventoryAction.HOTBAR_SWAP; ++ } ++ else ++ { ++ int firstEmptySlot = playerEntity.inventory.getFirstEmptyStack(); // Should be Inventory.firstEmpty() ++ ++ if (firstEmptySlot > -1) ++ { ++ action = InventoryAction.HOTBAR_MOVE_AND_READD; ++ } ++ else ++ { ++ action = InventoryAction.NOTHING; // This is not sane! Mojang: You should test for other slots of same type ++ } ++ } ++ } ++ else if (!clickedSlot.getHasStack() && hotbar != null && clickedSlot.isItemValid(hotbar)) ++ { ++ action = InventoryAction.HOTBAR_SWAP; ++ } ++ else ++ { ++ action = InventoryAction.NOTHING; ++ } ++ } ++ else ++ { ++ action = InventoryAction.NOTHING; ++ } ++ ++ // Special constructor for number key ++ event = new InventoryClickEvent(inventory, type, p_147351_1_.func_149544_d(), click, action, p_147351_1_.func_149543_e()); ++ } ++ } ++ else if (p_147351_1_.func_149542_h() == 3) ++ { ++ if (p_147351_1_.func_149543_e() == 2) ++ { ++ click = ClickType.MIDDLE; ++ ++ if (p_147351_1_.func_149544_d() == -999) ++ { ++ action = InventoryAction.NOTHING; ++ } ++ else ++ { ++ Slot slot = this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()); ++ ++ if (slot != null && slot.getHasStack() && playerEntity.capabilities.isCreativeMode && playerEntity.inventory.getItemStack() == null) ++ { ++ action = InventoryAction.CLONE_STACK; ++ } ++ else ++ { ++ action = InventoryAction.NOTHING; ++ } ++ } ++ } ++ else ++ { ++ click = ClickType.UNKNOWN; ++ action = InventoryAction.UNKNOWN; ++ } ++ } ++ else if (p_147351_1_.func_149542_h() == 4) ++ { ++ if (p_147351_1_.func_149544_d() >= 0) ++ { ++ if (p_147351_1_.func_149543_e() == 0) ++ { ++ click = ClickType.DROP; ++ Slot slot = this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()); ++ ++ if (slot != null && slot.getHasStack() && slot.canTakeStack(playerEntity) && slot.getStack() != null ++ && slot.getStack().getItem() != Item.getItemFromBlock(Blocks.air)) ++ { ++ action = InventoryAction.DROP_ONE_SLOT; ++ } ++ else ++ { ++ action = InventoryAction.NOTHING; ++ } ++ } ++ else if (p_147351_1_.func_149543_e() == 1) ++ { ++ click = ClickType.CONTROL_DROP; ++ Slot slot = this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()); ++ ++ if (slot != null && slot.getHasStack() && slot.canTakeStack(playerEntity) && slot.getStack() != null ++ && slot.getStack().getItem() != Item.getItemFromBlock(Blocks.air)) ++ { ++ action = InventoryAction.DROP_ALL_SLOT; ++ } ++ else ++ { ++ action = InventoryAction.NOTHING; ++ } ++ } ++ } ++ else ++ { ++ // Sane default (because this happens when they are holding nothing. Don't ask why.) ++ click = ClickType.LEFT; ++ ++ if (p_147351_1_.func_149543_e() == 1) ++ { ++ click = ClickType.RIGHT; ++ } ++ ++ action = InventoryAction.NOTHING; ++ } ++ } ++ else if (p_147351_1_.func_149542_h() == 5) ++ { ++ itemstack = this.playerEntity.openContainer.slotClick(p_147351_1_.func_149544_d(), p_147351_1_.func_149543_e(), 5, this.playerEntity); ++ } ++ else if (p_147351_1_.func_149542_h() == 6) ++ { ++ click = ClickType.DOUBLE_CLICK; ++ action = InventoryAction.NOTHING; ++ ++ if (p_147351_1_.func_149544_d() >= 0 && this.playerEntity.inventory.getItemStack() != null) ++ { ++ ItemStack cursor = this.playerEntity.inventory.getItemStack(); ++ action = InventoryAction.NOTHING; ++ ++ // Quick check for if we have any of the item ++ // Cauldron start - can't call getContents() on modded IInventory; CB-added method ++ try ++ { ++ if (inventory.getTopInventory().contains(org.bukkit.Material.getMaterial(Item.getIdFromItem(cursor.getItem()))) ++ || inventory.getBottomInventory().contains(org.bukkit.Material.getMaterial(Item.getIdFromItem(cursor.getItem())))) ++ { ++ action = InventoryAction.COLLECT_TO_CURSOR; ++ } ++ } ++ catch (AbstractMethodError ex) ++ { ++ // nothing we can do ++ } ++ // Cauldron end ++ } ++ } ++ ++ // TODO check on updates ++ ++ if (p_147351_1_.func_149542_h() != 5) ++ { ++ if (click == ClickType.NUMBER_KEY) ++ { ++ event = new InventoryClickEvent(inventory, type, p_147351_1_.func_149544_d(), click, action, p_147351_1_.func_149543_e()); ++ } ++ else ++ { ++ event = new InventoryClickEvent(inventory, type, p_147351_1_.func_149544_d(), click, action); ++ } ++ ++ org.bukkit.inventory.Inventory top = inventory.getTopInventory(); ++ ++ if (p_147351_1_.func_149544_d() == 0 && top instanceof CraftingInventory) ++ { ++ // Cauldron start - vanilla compatibility (mod recipes) ++ org.bukkit.inventory.Recipe recipe = null; ++ try ++ { ++ recipe = ((CraftingInventory) top).getRecipe(); ++ } ++ catch (AbstractMethodError e) ++ { ++ // do nothing ++ } ++ // Cauldron end ++ ++ if (recipe != null) ++ { ++ if (click == ClickType.NUMBER_KEY) ++ { ++ event = new CraftItemEvent(recipe, inventory, type, p_147351_1_.func_149544_d(), click, action, p_147351_1_.func_149543_e()); ++ } ++ else ++ { ++ event = new CraftItemEvent(recipe, inventory, type, p_147351_1_.func_149544_d(), click, action); ++ } ++ } ++ } ++ ++ server.getPluginManager().callEvent(event); ++ ++ switch (event.getResult()) ++ { ++ case ALLOW: ++ case DEFAULT: ++ itemstack = this.playerEntity.openContainer.slotClick(p_147351_1_.func_149544_d(), p_147351_1_.func_149543_e(), ++ p_147351_1_.func_149542_h(), this.playerEntity); ++ break; ++ case DENY: ++ /* Needs enum constructor in InventoryAction ++ if (action.modifiesOtherSlots()) { ++ } else { ++ if (action.modifiesCursor()) { ++ this.player.playerConnection.sendPacket(new Packet103SetSlot(-1, -1, this.player.inventory.getCarried())); ++ } ++ if (action.modifiesClicked()) { ++ this.player.playerConnection.sendPacket(new Packet103SetSlot(this.player.activeContainer.windowId, packet102windowclick.slot, this.player.activeContainer.getSlot(packet102windowclick.slot).getItem())); ++ } ++ }*/ ++ switch (action) ++ { ++ // Modified other slots ++ case PICKUP_ALL: ++ case MOVE_TO_OTHER_INVENTORY: ++ case HOTBAR_MOVE_AND_READD: ++ case HOTBAR_SWAP: ++ case COLLECT_TO_CURSOR: ++ case UNKNOWN: ++ this.playerEntity.sendContainerToPlayer(this.playerEntity.openContainer); ++ break; ++ ++ // Modified cursor and clicked ++ case PICKUP_SOME: ++ case PICKUP_HALF: ++ case PICKUP_ONE: ++ case PLACE_ALL: ++ case PLACE_SOME: ++ case PLACE_ONE: ++ case SWAP_WITH_CURSOR: ++ this.playerEntity.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(-1, -1, this.playerEntity.inventory.getItemStack())); ++ this.playerEntity.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(this.playerEntity.openContainer.windowId, p_147351_1_ ++ .func_149544_d(), this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()).getStack())); ++ break; ++ ++ // Modified clicked only ++ case DROP_ALL_SLOT: ++ case DROP_ONE_SLOT: ++ this.playerEntity.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(this.playerEntity.openContainer.windowId, p_147351_1_ ++ .func_149544_d(), this.playerEntity.openContainer.getSlot(p_147351_1_.func_149544_d()).getStack())); ++ break; ++ ++ // Modified cursor only ++ case DROP_ALL_CURSOR: ++ case DROP_ONE_CURSOR: ++ case CLONE_STACK: ++ this.playerEntity.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(-1, -1, this.playerEntity.inventory.getItemStack())); ++ break; ++ ++ // Nothing ++ case NOTHING: ++ break; ++ } ++ ++ return; ++ } ++ } ++ // CraftBukkit end ++ + if (ItemStack.areItemStacksEqual(p_147351_1_.func_149546_g(), itemstack)) + { + this.playerEntity.playerNetServerHandler.sendPacket(new S32PacketConfirmTransaction(p_147351_1_.func_149548_c(), p_147351_1_.func_149547_f(), true)); +@@ -903,6 +2129,12 @@ + } + + this.playerEntity.sendContainerAndContentsToPlayer(this.playerEntity.openContainer, arraylist); ++ // CraftBukkit start - Send a Set Slot to update the crafting result slot ++ if (type == SlotType.RESULT && itemstack != null) ++ { ++ this.playerEntity.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(this.playerEntity.openContainer.windowId, 0, itemstack)); ++ } ++ // CraftBukkit end + } + } + } +@@ -925,9 +2157,61 @@ + boolean flag = p_147344_1_.func_149627_c() < 0; + ItemStack itemstack = p_147344_1_.func_149625_d(); + boolean flag1 = p_147344_1_.func_149627_c() >= 1 && p_147344_1_.func_149627_c() < 36 + InventoryPlayer.getHotbarSize(); +- boolean flag2 = itemstack == null || itemstack.getItem() != null; ++ // CraftBukkit - Add invalidItems check ++ boolean flag2 = itemstack == null || itemstack.getItem() != null && !invalidItems.contains(Item.getIdFromItem(itemstack.getItem())); + boolean flag3 = itemstack == null || itemstack.getItemDamage() >= 0 && itemstack.stackSize <= 64 && itemstack.stackSize > 0; ++ // CraftBukkit start - Call click event ++ if (flag ++ || (flag1 && !ItemStack.areItemStacksEqual(this.playerEntity.inventoryContainer.getSlot(p_147344_1_.func_149627_c()).getStack(), ++ p_147344_1_.func_149625_d()))) // Insist on valid slot ++ { ++ org.bukkit.entity.HumanEntity player = this.playerEntity.getBukkitEntity(); ++ InventoryView inventory = new CraftInventoryView(player, player.getInventory(), this.playerEntity.inventoryContainer); ++ org.bukkit.inventory.ItemStack item = CraftItemStack.asBukkitCopy(p_147344_1_.func_149625_d()); // Should be packet107setcreativeslot.newitem ++ SlotType type = SlotType.QUICKBAR; + ++ if (flag) ++ { ++ type = SlotType.OUTSIDE; ++ } ++ else if (p_147344_1_.func_149627_c() < 36) ++ { ++ if (p_147344_1_.func_149627_c() >= 5 && p_147344_1_.func_149627_c() < 9) ++ { ++ type = SlotType.ARMOR; ++ } ++ else ++ { ++ type = SlotType.CONTAINER; ++ } ++ } ++ ++ InventoryCreativeEvent event = new InventoryCreativeEvent(inventory, type, flag ? -999 : p_147344_1_.func_149627_c(), item); ++ server.getPluginManager().callEvent(event); ++ itemstack = CraftItemStack.asNMSCopy(event.getCursor()); ++ ++ switch (event.getResult()) ++ { ++ case ALLOW: ++ // Plugin cleared the id / stacksize checks ++ flag2 = flag3 = true; ++ break; ++ case DEFAULT: ++ break; ++ case DENY: ++ // Reset the slot ++ if (p_147344_1_.func_149627_c() >= 0) ++ { ++ this.playerEntity.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(this.playerEntity.inventoryContainer.windowId, p_147344_1_ ++ .func_149627_c(), this.playerEntity.inventoryContainer.getSlot(p_147344_1_.func_149627_c()).getStack())); ++ this.playerEntity.playerNetServerHandler.sendPacket(new S2FPacketSetSlot(-1, -1, null)); ++ } ++ ++ return; ++ } ++ } ++ // CraftBukkit end ++ + if (flag1 && flag2 && flag3) + { + if (itemstack == null) +@@ -956,6 +2240,11 @@ + + public void processConfirmTransaction(C0FPacketConfirmTransaction p_147339_1_) + { ++ if (this.playerEntity.isDead) ++ { ++ return; // CraftBukkit ++ } ++ + Short oshort = (Short)this.field_147372_n.lookup(this.playerEntity.openContainer.windowId); + + if (oshort != null && p_147339_1_.func_149533_d() == oshort.shortValue() && this.playerEntity.openContainer.windowId == p_147339_1_.func_149532_c() && !this.playerEntity.openContainer.isPlayerNotUsingContainer(this.playerEntity)) +@@ -966,6 +2255,11 @@ + + public void processUpdateSign(C12PacketUpdateSign p_147343_1_) + { ++ if (this.playerEntity.isDead) ++ { ++ return; // CraftBukkit ++ } ++ + this.playerEntity.func_143004_u(); + WorldServer worldserver = this.serverController.worldServerForDimension(this.playerEntity.dimension); + +@@ -980,6 +2274,7 @@ + if (!tileentitysign.func_145914_a() || tileentitysign.func_145911_b() != this.playerEntity) + { + this.serverController.logWarning("Player " + this.playerEntity.getCommandSenderName() + " just tried to change non-editable sign"); ++ this.sendPacket(new S33PacketUpdateSign(p_147343_1_.func_149588_c(), p_147343_1_.func_149586_d(), p_147343_1_.func_149585_e(), tileentitysign.signText)); // CraftBukkit + return; + } + } +@@ -990,6 +2285,7 @@ + for (j = 0; j < 4; ++j) + { + boolean flag = true; ++ p_147343_1_.func_149589_f()[j] = p_147343_1_.func_149589_f()[j].replaceAll("\uF700", "").replaceAll("\uF701", ""); // Spigot - Mac OSX sends weird chars + + if (p_147343_1_.func_149589_f()[j].length() > 15) + { +@@ -1018,7 +2314,29 @@ + int k = p_147343_1_.func_149586_d(); + i = p_147343_1_.func_149585_e(); + TileEntitySign tileentitysign1 = (TileEntitySign)tileentity; +- System.arraycopy(p_147343_1_.func_149589_f(), 0, tileentitysign1.signText, 0, 4); ++ // CraftBukkit start ++ Player player = this.server.getPlayer(this.playerEntity); ++ SignChangeEvent event = new SignChangeEvent((org.bukkit.craftbukkit.block.CraftBlock) player.getWorld().getBlockAt(j, k, i), ++ this.server.getPlayer(this.playerEntity), p_147343_1_.func_149589_f()); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ for (int l = 0; l < 4; ++l) ++ { ++ tileentitysign1.signText[l] = event.getLine(l); ++ ++ if (tileentitysign1.signText[l] == null) ++ { ++ tileentitysign1.signText[l] = ""; ++ } ++ } ++ ++ tileentitysign1.field_145916_j = false; ++ } ++ ++ // System.arraycopy(p_147343_1_.func_149589_f(), 0, tileentitysign1.signText, 0, 4); ++ // CraftBukkit end + tileentitysign1.markDirty(); + worldserver.markBlockForUpdate(j, k, i); + } +@@ -1041,7 +2359,22 @@ + + public void processPlayerAbilities(C13PacketPlayerAbilities p_147348_1_) + { +- this.playerEntity.capabilities.isFlying = p_147348_1_.func_149488_d() && this.playerEntity.capabilities.allowFlying; ++ // CraftBukkit start - d() should be isFlying() ++ if (this.playerEntity.capabilities.allowFlying && this.playerEntity.capabilities.isFlying != p_147348_1_.func_149488_d()) ++ { ++ PlayerToggleFlightEvent event = new PlayerToggleFlightEvent(this.server.getPlayer(this.playerEntity), p_147348_1_.func_149488_d()); ++ this.server.getPluginManager().callEvent(event); ++ ++ if (!event.isCancelled()) ++ { ++ this.playerEntity.capabilities.isFlying = p_147348_1_.func_149488_d(); // Actually set the player's flying status ++ } ++ else ++ { ++ this.playerEntity.sendPlayerAbilities(); // Tell the player their ability was reverted ++ } ++ } ++ // CraftBukkit end + } + + public void processTabComplete(C14PacketTabComplete p_147341_1_) +@@ -1068,7 +2401,12 @@ + PacketBuffer packetbuffer; + ItemStack itemstack; + ItemStack itemstack1; +- ++ // CraftBukkit start - Ignore empty payloads ++ if (p_147349_1_.field_149560_b <= 0) ++ { ++ return; ++ } ++ // CraftBukkit end + if ("MC|BEdit".equals(p_147349_1_.func_149559_c())) + { + packetbuffer = new PacketBuffer(Unpooled.wrappedBuffer(p_147349_1_.func_149558_e())); +@@ -1093,16 +2431,18 @@ + + if (itemstack.getItem() == Items.writable_book && itemstack.getItem() == itemstack1.getItem()) + { +- itemstack1.setTagInfo("pages", itemstack.getTagCompound().getTagList("pages", 8)); ++ CraftEventFactory.handleEditBookEvent(playerEntity, itemstack); // CraftBukkit + } + + return; + } + } +- catch (Exception exception4) ++ // CraftBukkit start ++ catch (Throwable throwable) + { +- logger.error("Couldn\'t handle book info", exception4); +- return; ++ logger.error("Couldn\'t handle book info", throwable); ++ this.kickPlayerFromServer("Invalid book data!"); ++ // CraftBukkit end + } + finally + { +@@ -1135,19 +2475,18 @@ + { + if (itemstack.getItem() == Items.written_book && itemstack1.getItem() == Items.writable_book) + { +- itemstack1.setTagInfo("author", new NBTTagString(this.playerEntity.getCommandSenderName())); +- itemstack1.setTagInfo("title", new NBTTagString(itemstack.getTagCompound().getString("title"))); +- itemstack1.setTagInfo("pages", itemstack.getTagCompound().getTagList("pages", 8)); +- itemstack1.func_150996_a(Items.written_book); ++ CraftEventFactory.handleEditBookEvent(playerEntity, itemstack); // CraftBukkit + } + + return; + } + } +- catch (Exception exception3) ++ // CraftBukkit start ++ catch (Throwable exception1) + { +- logger.error("Couldn\'t sign book", exception3); +- return; ++ logger.error("Couldn\'t sign book", exception1); ++ this.kickPlayerFromServer("Invalid book data!"); ++ // CraftBukkit end + } + finally + { +@@ -1174,9 +2513,12 @@ + ((ContainerMerchant)container).setCurrentRecipeIndex(i); + } + } +- catch (Exception exception2) ++ // CraftBukkit start ++ catch (Throwable exception2) + { + logger.error("Couldn\'t select trade", exception2); ++ this.kickPlayerFromServer("Invalid trade data!"); ++ // CraftBukkit end + } + } + else if ("MC|AdvCdm".equals(p_147349_1_.func_149559_c())) +@@ -1222,9 +2564,12 @@ + this.playerEntity.addChatMessage(new ChatComponentTranslation("advMode.setCommand.success", new Object[] {s1})); + } + } +- catch (Exception exception1) ++ // CraftBukkit start ++ catch (Throwable exception3) + { +- logger.error("Couldn\'t set command block", exception1); ++ logger.error("Couldn\'t set command block", exception3); ++ this.kickPlayerFromServer("Invalid CommandBlock data!"); ++ // CraftBukkit end + } + finally + { +@@ -1257,9 +2602,12 @@ + tileentitybeacon.markDirty(); + } + } +- catch (Exception exception) ++ // CraftBukkit start ++ catch (Throwable exception4) + { +- logger.error("Couldn\'t set beacon", exception); ++ logger.error("Couldn\'t set beacon", exception4); ++ this.kickPlayerFromServer("Invalid beacon data!"); ++ // CraftBukkit end + } + } + } +@@ -1281,6 +2629,13 @@ + containerrepair.updateItemName(""); + } + } ++ // CraftBukkit start ++ // Cauldron - bukkit registration moved to FML's ChannelRegistrationHandler ++ else ++ { ++ server.getMessenger().dispatchIncomingMessage(playerEntity.getBukkitEntity(), p_147349_1_.func_149559_c(), p_147349_1_.func_149558_e()); ++ } ++ // CraftBukkit end + } + } + +@@ -1292,6 +2647,21 @@ + } + } + ++ // CraftBukkit start - Add "isDisconnected" method ++ public final boolean isDisconnected() ++ { ++ return !this.netManager.channel().config().isAutoRead(); ++ } ++ ++ // CraftBukkit end ++ ++ // Cauldron start ++ public CraftServer getCraftServer() ++ { ++ return this.server; ++ } ++ // Cauldron end ++ + static final class SwitchEnumState + { + static final int[] field_151290_a = new int[C16PacketClientStatus.EnumState.values().length]; diff --git a/patches/net/minecraft/network/NetworkManager.java.patch b/patches/net/minecraft/network/NetworkManager.java.patch new file mode 100644 index 0000000..da3f586 --- /dev/null +++ b/patches/net/minecraft/network/NetworkManager.java.patch @@ -0,0 +1,102 @@ +--- ../src-base/minecraft/net/minecraft/network/NetworkManager.java ++++ ../src-work/minecraft/net/minecraft/network/NetworkManager.java +@@ -25,6 +25,8 @@ + import java.net.InetAddress; + import java.net.SocketAddress; + import java.util.Queue; ++import java.util.UUID; ++ + import javax.crypto.SecretKey; + import net.minecraft.util.ChatComponentTranslation; + import net.minecraft.util.CryptManager; +@@ -38,6 +40,8 @@ + import org.apache.logging.log4j.Logger; + import org.apache.logging.log4j.Marker; + import org.apache.logging.log4j.MarkerManager; ++import com.mojang.authlib.properties.Property; ++import com.google.common.collect.ImmutableSet; // Spigot + + public class NetworkManager extends SimpleChannelInboundHandler + { +@@ -54,13 +58,32 @@ + private final Queue receivedPacketsQueue = Queues.newConcurrentLinkedQueue(); + private final Queue outboundPacketsQueue = Queues.newConcurrentLinkedQueue(); + private Channel channel; +- private SocketAddress socketAddress; ++ // Spigot start ++ public SocketAddress socketAddress; ++ public Property[] spoofedProfile; ++ public UUID spoofedUUID; ++ // Spigot end + private INetHandler netHandler; + private EnumConnectionState connectionState; + private IChatComponent terminationReason; + private boolean field_152463_r; + private static final String __OBFID = "CL_00001240"; + ++ // Spigot Start ++ public static final AttributeKey protocolVersion = new AttributeKey("protocol_version"); ++ public static final ImmutableSet SUPPORTED_VERSIONS = ImmutableSet.of(4, 5); ++ public static final int CURRENT_VERSION = 5; ++ public static int getVersion(Channel attr) ++ { ++ Integer ver = attr.attr( protocolVersion ).get(); ++ return ( ver != null ) ? ver : CURRENT_VERSION; ++ } ++ public int getVersion() ++ { ++ return getVersion( this.channel ); ++ } ++ // Spigot End ++ + public NetworkManager(boolean p_i45147_1_) + { + this.isClientSide = p_i45147_1_; +@@ -71,6 +94,7 @@ + super.channelActive(p_channelActive_1_); + this.channel = p_channelActive_1_.channel(); + this.socketAddress = this.channel.remoteAddress(); ++ this.field_152463_r = false; // Spigot + this.setConnectionState(EnumConnectionState.HANDSHAKING); + } + +@@ -208,7 +232,15 @@ + { + for (int i = 1000; !this.receivedPacketsQueue.isEmpty() && i >= 0; --i) + { +- Packet packet = (Packet)this.receivedPacketsQueue.poll(); ++ Packet packet = (Packet) this.receivedPacketsQueue.poll(); ++ ++ // CraftBukkit start ++ if (!this.isChannelOpen() || !this.channel.config().isAutoRead()) // Should be isConnected ++ { ++ continue; ++ } ++ ++ // CraftBukkit end + packet.processPacket(this.netHandler); + } + +@@ -225,6 +257,8 @@ + + public void closeChannel(IChatComponent p_150718_1_) + { ++ this.field_152463_r = false; // Spigot ++ + if (this.channel.isOpen()) + { + this.channel.close(); +@@ -322,6 +356,13 @@ + return channel; + } + ++ // Spigot Start ++ public SocketAddress getRawAddress() ++ { ++ return this.channel.remoteAddress(); ++ } ++ // Spigot End ++ + static class InboundHandlerTuplePacketListener + { + private final Packet field_150774_a; diff --git a/patches/net/minecraft/network/NetworkSystem.java.patch b/patches/net/minecraft/network/NetworkSystem.java.patch new file mode 100644 index 0000000..e799ed3 --- /dev/null +++ b/patches/net/minecraft/network/NetworkSystem.java.patch @@ -0,0 +1,17 @@ +--- ../src-base/minecraft/net/minecraft/network/NetworkSystem.java ++++ ../src-work/minecraft/net/minecraft/network/NetworkSystem.java +@@ -139,6 +139,14 @@ + + synchronized (this.networkManagers) + { ++ // Spigot Start ++ // This prevents players from 'gaming' the server, and strategically relogging to increase their position in the tick order ++ if (org.spigotmc.SpigotConfig.playerShuffle > 0 && MinecraftServer.currentTick % org.spigotmc.SpigotConfig.playerShuffle == 0) ++ { ++ Collections.shuffle(this.networkManagers); ++ } ++ ++ // Spigot End + Iterator iterator = this.networkManagers.iterator(); + + while (iterator.hasNext()) diff --git a/patches/net/minecraft/network/Packet.java.patch b/patches/net/minecraft/network/Packet.java.patch new file mode 100644 index 0000000..6ff6cbb --- /dev/null +++ b/patches/net/minecraft/network/Packet.java.patch @@ -0,0 +1,10 @@ +--- ../src-base/minecraft/net/minecraft/network/Packet.java ++++ ../src-work/minecraft/net/minecraft/network/Packet.java +@@ -9,6 +9,7 @@ + public abstract class Packet + { + private static final Logger logger = LogManager.getLogger(); ++ public final long timestamp = System.currentTimeMillis(); // CraftBukkit + private static final String __OBFID = "CL_00001272"; + + public static Packet generatePacket(BiMap p_148839_0_, int p_148839_1_) diff --git a/patches/net/minecraft/network/PacketBuffer.java.patch b/patches/net/minecraft/network/PacketBuffer.java.patch new file mode 100644 index 0000000..5dcea93 --- /dev/null +++ b/patches/net/minecraft/network/PacketBuffer.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/network/PacketBuffer.java ++++ ../src-work/minecraft/net/minecraft/network/PacketBuffer.java +@@ -98,7 +98,7 @@ + + public void writeItemStackToBuffer(ItemStack p_150788_1_) throws IOException + { +- if (p_150788_1_ == null) ++ if (p_150788_1_ == null || p_150788_1_.getItem() == null) // CraftBukkit - NPE fix itemstack.getItem() + { + this.writeShort(-1); + } diff --git a/patches/net/minecraft/network/handshake/client/C00Handshake.java.patch b/patches/net/minecraft/network/handshake/client/C00Handshake.java.patch new file mode 100644 index 0000000..13d9eb5 --- /dev/null +++ b/patches/net/minecraft/network/handshake/client/C00Handshake.java.patch @@ -0,0 +1,22 @@ +--- ../src-base/minecraft/net/minecraft/network/handshake/client/C00Handshake.java ++++ ../src-work/minecraft/net/minecraft/network/handshake/client/C00Handshake.java +@@ -12,8 +12,8 @@ + public class C00Handshake extends Packet + { + private int field_149600_a; +- private String field_149598_b; +- private int field_149599_c; ++ public String field_149598_b; // CraftBukkit private -> public ++ public int field_149599_c; // CraftBukkit private -> public + private EnumConnectionState field_149597_d; + private static final String __OBFID = "CL_00001372"; + +@@ -31,7 +31,7 @@ + public void readPacketData(PacketBuffer p_148837_1_) throws IOException + { + this.field_149600_a = p_148837_1_.readVarIntFromBuffer(); +- this.field_149598_b = p_148837_1_.readStringFromBuffer(255); ++ this.field_149598_b = p_148837_1_.readStringFromBuffer(Short.MAX_VALUE); // Spigot + this.field_149599_c = p_148837_1_.readUnsignedShort(); + this.field_149597_d = EnumConnectionState.func_150760_a(p_148837_1_.readVarIntFromBuffer()); + } diff --git a/patches/net/minecraft/network/play/client/C01PacketChatMessage.java.patch b/patches/net/minecraft/network/play/client/C01PacketChatMessage.java.patch new file mode 100644 index 0000000..bdddff2 --- /dev/null +++ b/patches/net/minecraft/network/play/client/C01PacketChatMessage.java.patch @@ -0,0 +1,14 @@ +--- ../src-base/minecraft/net/minecraft/network/play/client/C01PacketChatMessage.java ++++ ../src-work/minecraft/net/minecraft/network/play/client/C01PacketChatMessage.java +@@ -52,4 +52,11 @@ + { + this.processPacket((INetHandlerPlayServer)p_148833_1_); + } ++ ++ // CraftBukkit start - make chat async ++ public boolean hasPriority() ++ { ++ return !this.field_149440_a.startsWith("/"); ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/network/play/client/C03PacketPlayer.java.patch b/patches/net/minecraft/network/play/client/C03PacketPlayer.java.patch new file mode 100644 index 0000000..be44d17 --- /dev/null +++ b/patches/net/minecraft/network/play/client/C03PacketPlayer.java.patch @@ -0,0 +1,28 @@ +--- ../src-base/minecraft/net/minecraft/network/play/client/C03PacketPlayer.java ++++ ../src-work/minecraft/net/minecraft/network/play/client/C03PacketPlayer.java +@@ -10,15 +10,17 @@ + + public class C03PacketPlayer extends Packet + { +- protected double field_149479_a; +- protected double field_149477_b; +- protected double field_149478_c; +- protected double field_149475_d; +- protected float field_149476_e; +- protected float field_149473_f; ++ // CraftBukkit start - protected -> public ++ public double field_149479_a; ++ public double field_149477_b; ++ public double field_149478_c; ++ public double field_149475_d; ++ public float field_149476_e; ++ public float field_149473_f; ++ // CraftBukkit end + protected boolean field_149474_g; +- protected boolean field_149480_h; +- protected boolean field_149481_i; ++ public boolean field_149480_h; // CraftBukkit - protected -> public ++ public boolean field_149481_i; + private static final String __OBFID = "CL_00001360"; + + public C03PacketPlayer() {} diff --git a/patches/net/minecraft/network/play/client/C0DPacketCloseWindow.java.patch b/patches/net/minecraft/network/play/client/C0DPacketCloseWindow.java.patch new file mode 100644 index 0000000..f9df09e --- /dev/null +++ b/patches/net/minecraft/network/play/client/C0DPacketCloseWindow.java.patch @@ -0,0 +1,16 @@ +--- ../src-base/minecraft/net/minecraft/network/play/client/C0DPacketCloseWindow.java ++++ ../src-work/minecraft/net/minecraft/network/play/client/C0DPacketCloseWindow.java +@@ -15,11 +15,12 @@ + + public C0DPacketCloseWindow() {} + +- @SideOnly(Side.CLIENT) ++ // CraftBukkit start - Add constructor + public C0DPacketCloseWindow(int p_i45247_1_) + { + this.field_149556_a = p_i45247_1_; + } ++ // CraftBukkit end + + public void processPacket(INetHandlerPlayServer p_148833_1_) + { diff --git a/patches/net/minecraft/network/play/client/C17PacketCustomPayload.java.patch b/patches/net/minecraft/network/play/client/C17PacketCustomPayload.java.patch new file mode 100644 index 0000000..0d96dc1 --- /dev/null +++ b/patches/net/minecraft/network/play/client/C17PacketCustomPayload.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/network/play/client/C17PacketCustomPayload.java ++++ ../src-work/minecraft/net/minecraft/network/play/client/C17PacketCustomPayload.java +@@ -12,7 +12,7 @@ + public class C17PacketCustomPayload extends Packet + { + private String field_149562_a; +- private int field_149560_b; ++ public int field_149560_b; // CraftBukkit - private -> public + private byte[] field_149561_c; + private static final String __OBFID = "CL_00001356"; + diff --git a/patches/net/minecraft/network/play/server/S05PacketSpawnPosition.java.patch b/patches/net/minecraft/network/play/server/S05PacketSpawnPosition.java.patch new file mode 100644 index 0000000..b5b8fa6 --- /dev/null +++ b/patches/net/minecraft/network/play/server/S05PacketSpawnPosition.java.patch @@ -0,0 +1,15 @@ +--- ../src-base/minecraft/net/minecraft/network/play/server/S05PacketSpawnPosition.java ++++ ../src-work/minecraft/net/minecraft/network/play/server/S05PacketSpawnPosition.java +@@ -10,9 +10,9 @@ + + public class S05PacketSpawnPosition extends Packet + { +- private int field_149364_a; +- private int field_149362_b; +- private int field_149363_c; ++ public int field_149364_a; // CraftBukkit - private -> public ++ public int field_149362_b; // CraftBukkit - private -> public ++ public int field_149363_c; // CraftBukkit - private -> public + private static final String __OBFID = "CL_00001336"; + + public S05PacketSpawnPosition() {} diff --git a/patches/net/minecraft/network/play/server/S21PacketChunkData.java.patch b/patches/net/minecraft/network/play/server/S21PacketChunkData.java.patch new file mode 100644 index 0000000..9b57022 --- /dev/null +++ b/patches/net/minecraft/network/play/server/S21PacketChunkData.java.patch @@ -0,0 +1,54 @@ +--- ../src-base/minecraft/net/minecraft/network/play/server/S21PacketChunkData.java ++++ ../src-work/minecraft/net/minecraft/network/play/server/S21PacketChunkData.java +@@ -198,8 +198,10 @@ + if (aextendedblockstorage[l] != null && (!p_149269_1_ || !aextendedblockstorage[l].isEmpty()) && (p_149269_2_ & 1 << l) != 0) + { + nibblearray = aextendedblockstorage[l].getMetadataArray(); +- System.arraycopy(nibblearray.data, 0, abyte, j, nibblearray.data.length); +- j += nibblearray.data.length; ++ // Spigot start ++ nibblearray.copyToByteArray(abyte, j); ++ j += nibblearray.getByteLength(); ++ // Spigot end + } + } + +@@ -208,8 +210,10 @@ + if (aextendedblockstorage[l] != null && (!p_149269_1_ || !aextendedblockstorage[l].isEmpty()) && (p_149269_2_ & 1 << l) != 0) + { + nibblearray = aextendedblockstorage[l].getBlocklightArray(); +- System.arraycopy(nibblearray.data, 0, abyte, j, nibblearray.data.length); +- j += nibblearray.data.length; ++ // Spigot start ++ nibblearray.copyToByteArray(abyte, j); ++ j += nibblearray.getByteLength(); ++ // Spigot end + } + } + +@@ -220,8 +224,10 @@ + if (aextendedblockstorage[l] != null && (!p_149269_1_ || !aextendedblockstorage[l].isEmpty()) && (p_149269_2_ & 1 << l) != 0) + { + nibblearray = aextendedblockstorage[l].getSkylightArray(); +- System.arraycopy(nibblearray.data, 0, abyte, j, nibblearray.data.length); +- j += nibblearray.data.length; ++ // Spigot start ++ nibblearray.copyToByteArray(abyte, j); ++ j += nibblearray.getByteLength(); ++ // Spigot end + } + } + } +@@ -233,8 +239,10 @@ + if (aextendedblockstorage[l] != null && (!p_149269_1_ || !aextendedblockstorage[l].isEmpty()) && aextendedblockstorage[l].getBlockMSBArray() != null && (p_149269_2_ & 1 << l) != 0) + { + nibblearray = aextendedblockstorage[l].getBlockMSBArray(); +- System.arraycopy(nibblearray.data, 0, abyte, j, nibblearray.data.length); +- j += nibblearray.data.length; ++ // Spigot start ++ nibblearray.copyToByteArray(abyte, j); ++ j += nibblearray.getByteLength(); ++ // Spigot end + } + } + } diff --git a/patches/net/minecraft/network/play/server/S26PacketMapChunkBulk.java.patch b/patches/net/minecraft/network/play/server/S26PacketMapChunkBulk.java.patch new file mode 100644 index 0000000..893b190 --- /dev/null +++ b/patches/net/minecraft/network/play/server/S26PacketMapChunkBulk.java.patch @@ -0,0 +1,117 @@ +--- ../src-base/minecraft/net/minecraft/network/play/server/S26PacketMapChunkBulk.java ++++ ../src-work/minecraft/net/minecraft/network/play/server/S26PacketMapChunkBulk.java +@@ -24,10 +24,18 @@ + private byte[][] field_149260_f; + private int field_149261_g; + private boolean field_149267_h; +- private static byte[] field_149268_i = new byte[0]; +- private static final String __OBFID = "CL_00001306"; +- private int maxLen = 0; +- private Semaphore deflateGate; ++ private byte[] field_149268_i = new byte[0]; // CraftBukkit - remove static ++ // CraftBukkit start ++ static final ThreadLocal localDeflater = new ThreadLocal() ++ { ++ @Override ++ protected Deflater initialValue() ++ { ++ // Don't use higher compression level, slows things down too much ++ return new Deflater(6); ++ } ++ }; ++ // CraftBukkit end + + public S26PacketMapChunkBulk() {} + +@@ -46,6 +54,15 @@ + { + Chunk chunk = (Chunk)p_i45197_1_.get(k); + S21PacketChunkData.Extracted extracted = S21PacketChunkData.func_149269_a(chunk, true, 65535); ++ ++ if (field_149268_i.length < j + extracted.field_150282_a.length) ++ { ++ byte[] abyte = new byte[j + extracted.field_150282_a.length]; ++ System.arraycopy(field_149268_i, 0, abyte, 0, field_149268_i.length); ++ field_149268_i = abyte; ++ } ++ ++ System.arraycopy(extracted.field_150282_a, 0, field_149268_i, j, extracted.field_150282_a.length); + j += extracted.field_150282_a.length; + this.field_149266_a[k] = chunk.xPosition; + this.field_149264_b[k] = chunk.zPosition; +@@ -53,34 +70,36 @@ + this.field_149262_d[k] = extracted.field_150281_c; + this.field_149260_f[k] = extracted.field_150282_a; + } +- this.deflateGate = new Semaphore(1); +- maxLen = j; +- } +- +- private void deflate() +- { +- byte[] data = new byte[maxLen]; +- int offset = 0; +- for (int x = 0; x < field_149260_f.length; x++) +- { +- System.arraycopy(field_149260_f[x], 0, data, offset, field_149260_f[x].length); +- offset += field_149260_f[x].length; +- } ++ /* CraftBukkit start - Moved to compress() + Deflater deflater = new Deflater(-1); + +- try +- { +- deflater.setInput(data, 0, data.length); ++ try { ++ deflater.setInput(buildBuffer, 0, j); + deflater.finish(); +- byte[] deflated = new byte[data.length]; +- this.field_149261_g = deflater.deflate(deflated); +- this.field_149263_e = deflated; ++ this.buffer = new byte[j]; ++ this.size = deflater.deflate(this.buffer); ++ } finally { ++ deflater.end(); + } +- finally ++ */ ++ } ++ ++ // Add compression method ++ public void compress() ++ { ++ if (this.field_149263_e != null) + { +- deflater.end(); ++ return; + } ++ ++ Deflater deflater = localDeflater.get(); ++ deflater.reset(); ++ deflater.setInput(this.field_149268_i); ++ deflater.finish(); ++ this.field_149263_e = new byte[this.field_149268_i.length + 100]; ++ this.field_149261_g = deflater.deflate(this.field_149263_e); + } ++ // CraftBukkit end + + public static int func_149258_c() + { +@@ -155,16 +174,7 @@ + + public void writePacketData(PacketBuffer p_148840_1_) throws IOException + { +- if (this.field_149263_e == null) +- { +- deflateGate.acquireUninterruptibly(); +- if (this.field_149263_e == null) +- { +- deflate(); +- } +- deflateGate.release(); +- } +- ++ compress(); // CraftBukkit + p_148840_1_.writeShort(this.field_149266_a.length); + p_148840_1_.writeInt(this.field_149261_g); + p_148840_1_.writeBoolean(this.field_149267_h); diff --git a/patches/net/minecraft/network/rcon/RConConsoleSource.java.patch b/patches/net/minecraft/network/rcon/RConConsoleSource.java.patch new file mode 100644 index 0000000..a77c109 --- /dev/null +++ b/patches/net/minecraft/network/rcon/RConConsoleSource.java.patch @@ -0,0 +1,16 @@ +--- ../src-base/minecraft/net/minecraft/network/rcon/RConConsoleSource.java ++++ ../src-work/minecraft/net/minecraft/network/rcon/RConConsoleSource.java +@@ -25,6 +25,13 @@ + return new ChatComponentText(this.getCommandSenderName()); + } + ++ // CraftBukkit start - Send a String ++ public void sendMessage(String message) ++ { ++ this.buffer.append(message); ++ } ++ // CraftBukkit end ++ + public void addChatMessage(IChatComponent p_145747_1_) + { + this.buffer.append(p_145747_1_.getUnformattedText()); diff --git a/patches/net/minecraft/potion/Potion.java.patch b/patches/net/minecraft/potion/Potion.java.patch new file mode 100644 index 0000000..4303e05 --- /dev/null +++ b/patches/net/minecraft/potion/Potion.java.patch @@ -0,0 +1,79 @@ +--- ../src-base/minecraft/net/minecraft/potion/Potion.java ++++ ../src-work/minecraft/net/minecraft/potion/Potion.java +@@ -17,6 +17,12 @@ + import net.minecraft.util.DamageSource; + import net.minecraft.util.StringUtils; + ++// CraftBukkit start ++import net.minecraft.entity.projectile.EntityPotion; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason; ++// CraftBukkit end ++ + public class Potion + { + public static final Potion[] potionTypes = new Potion[32]; +@@ -78,6 +84,7 @@ + } + + this.liquidColor = p_i1573_3_; ++ org.bukkit.potion.PotionEffectType.registerPotionEffectType(new org.bukkit.craftbukkit.potion.CraftPotionEffectType(this)); // CraftBukkit + } + + protected Potion setIconIndex(int p_76399_1_, int p_76399_2_) +@@ -97,14 +104,14 @@ + { + if (p_76394_1_.getHealth() < p_76394_1_.getMaxHealth()) + { +- p_76394_1_.heal(1.0F); ++ p_76394_1_.heal(1.0F, RegainReason.MAGIC_REGEN); // CraftBukkit + } + } + else if (this.id == poison.id) + { + if (p_76394_1_.getHealth() > 1.0F) + { +- p_76394_1_.attackEntityFrom(DamageSource.magic, 1.0F); ++ p_76394_1_.attackEntityFrom(CraftEventFactory.POISON, 1.0F); // CraftBukkit - DamageSource.MAGIC -> CraftEventFactory.POISON + } + } + else if (this.id == wither.id) +@@ -131,12 +138,19 @@ + } + else + { +- p_76394_1_.heal((float)Math.max(4 << p_76394_2_, 0)); ++ p_76394_1_.heal((float)Math.max(4 << p_76394_2_, 0), RegainReason.MAGIC); // CraftBukkit + } + } + + public void affectEntity(EntityLivingBase p_76402_1_, EntityLivingBase p_76402_2_, int p_76402_3_, double p_76402_4_) + { ++ // CraftBukkit start - Delegate; we need EntityPotion ++ applyInstantEffect(p_76402_1_, p_76402_2_, p_76402_3_, p_76402_4_, null); ++ } ++ ++ public void applyInstantEffect(EntityLivingBase p_76402_1_, EntityLivingBase p_76402_2_, int p_76402_3_, double p_76402_4_, EntityPotion potion) ++ { ++ // CraftBukkit end + int j; + + if ((this.id != heal.id || p_76402_2_.isEntityUndead()) && (this.id != harm.id || !p_76402_2_.isEntityUndead())) +@@ -151,14 +165,15 @@ + } + else + { +- p_76402_2_.attackEntityFrom(DamageSource.causeIndirectMagicDamage(p_76402_2_, p_76402_1_), (float)j); ++ // CraftBukkit - The "damager" needs to be the potion ++ p_76402_2_.attackEntityFrom(DamageSource.causeIndirectMagicDamage(potion != null ? potion : p_76402_2_, p_76402_1_), (float)j); + } + } + } + else + { + j = (int)(p_76402_4_ * (double)(4 << p_76402_3_) + 0.5D); +- p_76402_2_.heal((float)j); ++ p_76402_2_.heal((float)j, RegainReason.MAGIC); // CraftBukkit + } + } + diff --git a/patches/net/minecraft/scoreboard/ServerScoreboard.java.patch b/patches/net/minecraft/scoreboard/ServerScoreboard.java.patch new file mode 100644 index 0000000..29cf228 --- /dev/null +++ b/patches/net/minecraft/scoreboard/ServerScoreboard.java.patch @@ -0,0 +1,138 @@ +--- ../src-base/minecraft/net/minecraft/scoreboard/ServerScoreboard.java ++++ ../src-work/minecraft/net/minecraft/scoreboard/ServerScoreboard.java +@@ -32,7 +32,7 @@ + + if (this.field_96553_b.contains(p_96536_1_.func_96645_d())) + { +- this.scoreboardMCServer.getConfigurationManager().sendPacketToAllPlayers(new S3CPacketUpdateScore(p_96536_1_, 0)); ++ this.sendAll(new S3CPacketUpdateScore(p_96536_1_, 0)); // CraftBukkit - Internal packet method + } + + this.func_96551_b(); +@@ -41,7 +41,7 @@ + public void func_96516_a(String p_96516_1_) + { + super.func_96516_a(p_96516_1_); +- this.scoreboardMCServer.getConfigurationManager().sendPacketToAllPlayers(new S3CPacketUpdateScore(p_96516_1_)); ++ this.sendAll(new S3CPacketUpdateScore(p_96516_1_)); // CraftBukkit - Internal packet method + this.func_96551_b(); + } + +@@ -54,7 +54,7 @@ + { + if (this.func_96552_h(scoreobjective1) > 0) + { +- this.scoreboardMCServer.getConfigurationManager().sendPacketToAllPlayers(new S3DPacketDisplayScoreboard(p_96530_1_, p_96530_2_)); ++ this.sendAll(new S3DPacketDisplayScoreboard(p_96530_1_, p_96530_2_)); // CraftBukkit - Internal packet method + } + else + { +@@ -66,7 +66,7 @@ + { + if (this.field_96553_b.contains(p_96530_2_)) + { +- this.scoreboardMCServer.getConfigurationManager().sendPacketToAllPlayers(new S3DPacketDisplayScoreboard(p_96530_1_, p_96530_2_)); ++ this.sendAll(new S3DPacketDisplayScoreboard(p_96530_1_, p_96530_2_)); // CraftBukkit - Internal packet method + } + else + { +@@ -82,7 +82,7 @@ + if (super.func_151392_a(p_151392_1_, p_151392_2_)) + { + ScorePlayerTeam scoreplayerteam = this.getTeam(p_151392_2_); +- this.scoreboardMCServer.getConfigurationManager().sendPacketToAllPlayers(new S3EPacketTeams(scoreplayerteam, Arrays.asList(new String[] {p_151392_1_}), 3)); ++ this.sendAll(new S3EPacketTeams(scoreplayerteam, Arrays.asList(new String[] { p_151392_1_}), 3)); // CraftBukkit - Internal packet method + this.func_96551_b(); + return true; + } +@@ -95,7 +95,7 @@ + public void removePlayerFromTeam(String p_96512_1_, ScorePlayerTeam p_96512_2_) + { + super.removePlayerFromTeam(p_96512_1_, p_96512_2_); +- this.scoreboardMCServer.getConfigurationManager().sendPacketToAllPlayers(new S3EPacketTeams(p_96512_2_, Arrays.asList(new String[] {p_96512_1_}), 4)); ++ this.sendAll(new S3EPacketTeams(p_96512_2_, Arrays.asList(new String[] { p_96512_1_}), 4)); // CraftBukkit - Internal packet method + this.func_96551_b(); + } + +@@ -111,7 +111,7 @@ + + if (this.field_96553_b.contains(p_96532_1_)) + { +- this.scoreboardMCServer.getConfigurationManager().sendPacketToAllPlayers(new S3BPacketScoreboardObjective(p_96532_1_, 2)); ++ this.sendAll(new S3BPacketScoreboardObjective(p_96532_1_, 2)); // CraftBukkit - Internal packet method + } + + this.func_96551_b(); +@@ -132,21 +132,21 @@ + public void broadcastTeamCreated(ScorePlayerTeam p_96523_1_) + { + super.broadcastTeamCreated(p_96523_1_); +- this.scoreboardMCServer.getConfigurationManager().sendPacketToAllPlayers(new S3EPacketTeams(p_96523_1_, 0)); ++ this.sendAll(new S3EPacketTeams(p_96523_1_, 0)); // CraftBukkit - Internal packet method + this.func_96551_b(); + } + + public void broadcastTeamRemoved(ScorePlayerTeam p_96538_1_) + { + super.broadcastTeamRemoved(p_96538_1_); +- this.scoreboardMCServer.getConfigurationManager().sendPacketToAllPlayers(new S3EPacketTeams(p_96538_1_, 2)); ++ this.sendAll(new S3EPacketTeams(p_96538_1_, 2)); // CraftBukkit - Internal packet method + this.func_96551_b(); + } + + public void func_96513_c(ScorePlayerTeam p_96513_1_) + { + super.func_96513_c(p_96513_1_); +- this.scoreboardMCServer.getConfigurationManager().sendPacketToAllPlayers(new S3EPacketTeams(p_96513_1_, 1)); ++ this.sendAll(new S3EPacketTeams(p_96513_1_, 1)); // CraftBukkit - Internal packet method + this.func_96551_b(); + } + +@@ -194,7 +194,13 @@ + + while (iterator.hasNext()) + { +- EntityPlayerMP entityplayermp = (EntityPlayerMP)iterator.next(); ++ EntityPlayerMP entityplayermp = (EntityPlayerMP) iterator.next(); ++ ++ if (entityplayermp.getBukkitEntity().getScoreboard().getHandle() != this) ++ { ++ continue; // CraftBukkit - Only players on this board ++ } ++ + Iterator iterator1 = list.iterator(); + + while (iterator1.hasNext()) +@@ -230,7 +236,13 @@ + + while (iterator.hasNext()) + { +- EntityPlayerMP entityplayermp = (EntityPlayerMP)iterator.next(); ++ EntityPlayerMP entityplayermp = (EntityPlayerMP) iterator.next(); ++ ++ if (entityplayermp.getBukkitEntity().getScoreboard().getHandle() != this) ++ { ++ continue; // CraftBukkit - Only players on this board ++ } ++ + Iterator iterator1 = list.iterator(); + + while (iterator1.hasNext()) +@@ -257,4 +269,17 @@ + + return i; + } ++ ++ // CraftBukkit start - Send to players ++ private void sendAll(Packet packet) ++ { ++ for (EntityPlayerMP entityplayermp : (List) this.scoreboardMCServer.getConfigurationManager().playerEntityList) ++ { ++ if (entityplayermp.getBukkitEntity().getScoreboard().getHandle() == this) ++ { ++ entityplayermp.playerNetServerHandler.sendPacket(packet); ++ } ++ } ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/server/MinecraftServer.java.patch b/patches/net/minecraft/server/MinecraftServer.java.patch new file mode 100644 index 0000000..5dc143d --- /dev/null +++ b/patches/net/minecraft/server/MinecraftServer.java.patch @@ -0,0 +1,1192 @@ +--- ../src-base/minecraft/net/minecraft/server/MinecraftServer.java ++++ ../src-work/minecraft/net/minecraft/server/MinecraftServer.java +@@ -33,6 +33,8 @@ + import java.util.Random; + import java.util.UUID; + import java.util.concurrent.Callable; ++import java.util.logging.Level; ++ + import javax.imageio.ImageIO; + import net.minecraft.command.CommandBase; + import net.minecraft.command.ICommandManager; +@@ -50,6 +52,7 @@ + import net.minecraft.profiler.PlayerUsageSnooper; + import net.minecraft.profiler.Profiler; + import net.minecraft.server.dedicated.DedicatedServer; ++import net.minecraft.server.dedicated.PropertyManager; + import net.minecraft.server.gui.IUpdatePlayerListBox; + import net.minecraft.server.management.PlayerProfileCache; + import net.minecraft.server.management.ServerConfigurationManager; +@@ -80,18 +83,49 @@ + import net.minecraftforge.common.MinecraftForge; + import net.minecraftforge.event.world.WorldEvent; + ++// CraftBukkit start ++import java.io.IOException; ++ ++import jline.console.ConsoleReader; ++import joptsimple.OptionSet; ++import net.minecraft.world.chunk.storage.AnvilSaveHandler; ++import org.bukkit.World.Environment; ++import org.bukkit.craftbukkit.SpigotTimings; // Spigot ++import org.bukkit.craftbukkit.util.Waitable; ++import org.bukkit.event.server.RemoteServerCommandEvent; ++import org.bukkit.event.world.WorldSaveEvent; ++// CraftBukkit end ++// Cauldron start ++import java.util.Map; ++import java.lang.reflect.Constructor; ++import joptsimple.OptionParser; ++import cpw.mods.fml.common.asm.transformers.SideTransformer; ++import net.minecraft.command.ServerCommand; ++import net.minecraft.tileentity.TileEntity; ++import net.minecraft.world.WorldProvider; ++import net.minecraftforge.cauldron.CauldronUtils; ++import net.minecraftforge.cauldron.configuration.CauldronConfig; ++import net.minecraftforge.cauldron.configuration.TileEntityConfig; ++import net.minecraftforge.common.util.EnumHelper; ++ ++import org.bukkit.configuration.ConfigurationSection; ++import org.bukkit.configuration.file.YamlConfiguration; ++import org.bukkit.craftbukkit.CraftServer; ++import org.bukkit.craftbukkit.block.CraftBlock; ++// Cauldron end ++ + public abstract class MinecraftServer implements ICommandSender, Runnable, IPlayerUsage + { + private static final Logger logger = LogManager.getLogger(); + public static final File field_152367_a = new File("usercache.json"); + private static MinecraftServer mcServer; +- private final ISaveFormat anvilConverterForAnvilFile; ++ public ISaveFormat anvilConverterForAnvilFile; // CraftBukkit - private final -> public + private final PlayerUsageSnooper usageSnooper = new PlayerUsageSnooper("server", this, getSystemTimeMillis()); +- private final File anvilFile; ++ public File anvilFile; // CraftBukkit - private final -> public + private final List tickables = new ArrayList(); + private final ICommandManager commandManager; + public final Profiler theProfiler = new Profiler(); +- private final NetworkSystem field_147144_o; ++ private NetworkSystem field_147144_o; // Spigot + private final ServerStatusResponse field_147147_p = new ServerStatusResponse(); + private final Random field_147146_q = new Random(); + @SideOnly(Side.SERVER) +@@ -135,8 +169,39 @@ + private long field_147142_T = 0L; + private final GameProfileRepository field_152365_W; + private final PlayerProfileCache field_152366_X; ++ // CraftBukkit start ++ public List worlds = new ArrayList(); ++ public org.bukkit.craftbukkit.CraftServer server; ++ public static OptionSet options; // Cauldron ++ public org.bukkit.command.ConsoleCommandSender console; ++ public org.bukkit.command.RemoteConsoleCommandSender remoteConsole; ++ public ConsoleReader reader; ++ public static int currentTick = (int)(System.currentTimeMillis() / 50); ++ public final Thread primaryThread; ++ public java.util.Queue processQueue = new java.util.concurrent.ConcurrentLinkedQueue(); ++ public int autosavePeriod; ++ // CraftBukkit end ++ // Spigot start ++ private static final int TPS = 20; ++ private static final int TICK_TIME = 1000000000 / TPS; ++ public final double[] recentTps = new double[ 3 ]; ++ // Spigot end ++ // Cauldron start ++ public static CauldronConfig cauldronConfig; ++ public static TileEntityConfig tileEntityConfig; ++ public static YamlConfiguration configuration; ++ public static YamlConfiguration commandsConfiguration; ++ public static File configFile; ++ public static File commandFile; ++ public static double currentTps = 0; ++ public static boolean useJline = true; ++ public static boolean useConsole = true; ++ public static boolean callingForgeTick = false; ++ public static List> bannedTileEntityUpdates = new ArrayList>(); ++ // Cauldron end + private static final String __OBFID = "CL_00001462"; + ++ // Cauldron start - IntegratedServer requires this + public MinecraftServer(File p_i45281_1_, Proxy p_i45281_2_) + { + this.field_152366_X = new PlayerProfileCache(this, field_152367_a); +@@ -149,10 +214,68 @@ + this.field_152364_T = new YggdrasilAuthenticationService(p_i45281_2_, UUID.randomUUID().toString()); + this.field_147143_S = this.field_152364_T.createMinecraftSessionService(); + this.field_152365_W = this.field_152364_T.createProfileRepository(); ++ this.primaryThread = new Thread(this, "Server thread"); // CraftBukkit ++ this.cauldronConfig = new CauldronConfig("cauldron.yml", "cauldron"); ++ this.tileEntityConfig = new TileEntityConfig("tileentities.yml", "cauldron_te"); + } ++ // Cauldron end + +- protected abstract boolean startServer() throws IOException; ++ public MinecraftServer(OptionSet options, Proxy proxy) // CraftBukkit - signature file -> OptionSet ++ { ++ this.field_152366_X = new PlayerProfileCache(this, field_152367_a); ++ mcServer = this; ++ this.serverProxy = proxy; ++ // this.anvilFile = p_i45281_1_; // CraftBukkit ++ // this.field_147144_o = new NetworkSystem(this); // Spigot ++ this.commandManager = new ServerCommandManager(); ++ // this.anvilConverterForAnvilFile = new AnvilSaveConverter(p_i45281_1_); // CraftBukkit - moved to DedicatedServer.init ++ this.field_152364_T = new YggdrasilAuthenticationService(proxy, UUID.randomUUID().toString()); ++ this.field_147143_S = this.field_152364_T.createMinecraftSessionService(); ++ this.field_152365_W = this.field_152364_T.createProfileRepository(); ++ // Cauldron start ++ this.cauldronConfig = new CauldronConfig("cauldron.yml", "cauldron"); ++ this.tileEntityConfig = new TileEntityConfig("tileentities.yml", "cauldron_te"); ++ // Cauldron end ++ // CraftBukkit start ++ this.options = options; ++ // Try to see if we're actually running in a terminal, disable jline if not ++ if (System.console() == null) ++ { ++ System.setProperty("jline.terminal", "jline.UnsupportedTerminal"); ++ this.useJline = false; // Cauldron ++ } + ++ try ++ { ++ this.reader = new ConsoleReader(System.in, System.out); ++ this.reader.setExpandEvents(false); // Avoid parsing exceptions for uncommonly used event designators ++ } ++ catch (Throwable e) ++ { ++ try ++ { ++ // Try again with jline disabled for Windows users without C++ 2008 Redistributable ++ System.setProperty("jline.terminal", "jline.UnsupportedTerminal"); ++ System.setProperty("user.language", "en"); ++ this.useJline = false; // Cauldron ++ this.reader = new ConsoleReader(System.in, System.out); ++ this.reader.setExpandEvents(false); ++ } ++ catch (IOException ex) ++ { ++ logger.warn((String) null, ex); ++ } ++ } ++ net.minecraftforge.cauldron.CauldronHooks.enableThreadContentionMonitoring(); ++ Runtime.getRuntime().addShutdownHook(new org.bukkit.craftbukkit.util.ServerShutdownThread(this)); ++ primaryThread = new Thread(this, "Server thread"); // Moved from main ++ } ++ ++ public abstract PropertyManager getPropertyManager(); ++ // CraftBukkit end ++ ++ protected abstract boolean startServer() throws java.net.UnknownHostException; // CraftBukkit - throws UnknownHostException ++ + protected void convertMapIfNeeded(String p_71237_1_) + { + if (this.getActiveAnvilConverter().isOldMapFormat(p_71237_1_)) +@@ -172,6 +295,7 @@ + MinecraftServer.logger.info("Converting... " + p_73718_1_ + "%"); + } + } ++ + @SideOnly(Side.CLIENT) + public void resetProgressAndMessage(String p_73721_1_) {} + @SideOnly(Side.CLIENT) +@@ -195,10 +319,17 @@ + + protected void loadAllWorlds(String p_71247_1_, String p_71247_2_, long p_71247_3_, WorldType p_71247_5_, String p_71247_6_) + { ++ // Cauldron start - register vanilla server commands ++ ServerCommandManager vanillaCommandManager = (ServerCommandManager)this.getCommandManager(); ++ vanillaCommandManager.registerVanillaCommands(); ++ // Cauldron end + this.convertMapIfNeeded(p_71247_1_); + this.setUserMessage("menu.loadingLevel"); +- ISaveHandler isavehandler = this.anvilConverterForAnvilFile.getSaveLoader(p_71247_1_, true); +- WorldInfo worldinfo = isavehandler.loadWorldInfo(); ++ // Cauldron start - SaveHandler/WorldInfo below are not used and must be disabled to prevent FML receiving different handlers for overworld ++ //ISaveHandler isavehandler = this.anvilConverterForAnvilFile.getSaveLoader(p_71247_1_, true); ++ //WorldInfo worldinfo = isavehandler.loadWorldInfo(); ++ // Cauldron end ++ /* CraftBukkit start - Removed worldsettings + WorldSettings worldsettings; + + if (worldinfo == null) +@@ -215,11 +346,79 @@ + { + worldsettings.enableBonusChest(); + } ++ // */ + +- WorldServer overWorld = (isDemo() ? new DemoWorldServer(this, isavehandler, p_71247_2_, 0, theProfiler) : new WorldServer(this, isavehandler, p_71247_2_, 0, worldsettings, theProfiler)); +- for (int dim : DimensionManager.getStaticDimensionIDs()) ++ WorldSettings worldsettings = new WorldSettings(p_71247_3_, this.getGameType(), this.canStructuresSpawn(), this.isHardcore(), p_71247_5_); ++ worldsettings.func_82750_a(p_71247_6_); ++ WorldServer world; ++ ++ // Cauldron - overworld generator is handled in World after plugins load ++ WorldServer overWorld = (isDemo() ? new DemoWorldServer(this, new AnvilSaveHandler(server.getWorldContainer(), p_71247_2_, true), p_71247_2_, 0, theProfiler) : new WorldServer(this, new AnvilSaveHandler(server.getWorldContainer(), p_71247_2_, true), p_71247_2_, 0, worldsettings, theProfiler, Environment.getEnvironment(0), null)); ++ ++ for (int dimension : DimensionManager.getStaticDimensionIDs()) + { +- WorldServer world = (dim == 0 ? overWorld : new WorldServerMulti(this, isavehandler, p_71247_2_, dim, worldsettings, overWorld, theProfiler)); ++ String worldType = ""; ++ String name = ""; ++ String oldName = ""; ++ org.bukkit.generator.ChunkGenerator gen = null; ++ // Cauldron start ++ Environment env = Environment.getEnvironment(dimension); ++ if (dimension != 0) ++ { ++ if ((dimension == -1 && !this.getAllowNether()) || (dimension == 1 && !this.server.getAllowEnd())) ++ continue; ++ ++ if (env == null) ++ { ++ WorldProvider provider = WorldProvider.getProviderForDimension(dimension); ++ worldType = provider.getClass().getSimpleName().toLowerCase(); ++ worldType = worldType.replace("worldprovider", ""); ++ oldName = "world_" + worldType.toLowerCase(); ++ worldType = worldType.replace("provider", ""); ++ env = Environment.getEnvironment(DimensionManager.getProviderType(provider.getClass())); ++ name = provider.getSaveFolder(); ++ if (name == null) name = "DIM0"; ++ } ++ else ++ { ++ worldType = env.toString().toLowerCase(); ++ name = "DIM" + dimension; ++ oldName = p_71247_1_ + "_" + worldType; ++ oldName = oldName.replaceAll(" ", "_"); ++ } ++ ++ // check if the world is enabled or not ++ if (!configuration.isBoolean("world-settings." + worldType + ".enabled")) { ++ configuration.set("world-settings." + worldType + ".enabled", true); ++ } ++ boolean enabled = configuration.getBoolean("world-settings." + worldType + ".enabled"); ++ try { ++ configuration.save(MinecraftServer.configFile); ++ } catch (IOException e) { ++ e.printStackTrace(); ++ } ++ if (!enabled) ++ continue; ++ // end world enabled check ++ ++ gen = this.server.getGenerator(name); ++ worldsettings = new WorldSettings(p_71247_3_, this.getGameType(), this.canStructuresSpawn(), this.isHardcore(), p_71247_5_); ++ worldsettings.func_82750_a(p_71247_6_); ++ ++ CauldronUtils.migrateWorlds(worldType, oldName, p_71247_1_, name); ++ ++ this.setUserMessage(name); ++ } ++ ++ world = (dimension == 0 ? overWorld : new WorldServerMulti(this, new AnvilSaveHandler(server.getWorldContainer(), name, true), name, dimension, worldsettings, overWorld, this.theProfiler, env, gen)); ++ // Cauldron end ++ if (gen != null) ++ { ++ world.getWorld().getPopulators().addAll(gen.getDefaultPopulators(world.getWorld())); ++ } ++ ++ this.server.scoreboardManager = new org.bukkit.craftbukkit.scoreboard.CraftScoreboardManager(this, world.getScoreboard()); ++ this.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldInitEvent(world.getWorld())); + world.addWorldAccess(new WorldManager(this, world)); + + if (!this.isSinglePlayer()) +@@ -227,12 +426,14 @@ + world.getWorldInfo().setGameType(this.getGameType()); + } + +- MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(world)); ++ this.serverConfigManager.setPlayerManager(this.worlds.toArray(new WorldServer[this.worlds.size()])); ++ // CraftBukkit end ++ MinecraftForge.EVENT_BUS.post(new WorldEvent.Load((World)world)); // Forge + } +- +- this.serverConfigManager.setPlayerManager(new WorldServer[]{ overWorld }); + this.func_147139_a(this.func_147135_j()); + this.initialWorldChunkLoad(); ++ CraftBlock.dumpMaterials(); ++ // Cauldron end + } + + protected void initialWorldChunkLoad() +@@ -244,9 +445,12 @@ + int i = 0; + this.setUserMessage("menu.generatingTerrain"); + byte b0 = 0; ++ // Cauldron start - we now handle CraftBukkit's keepSpawnInMemory logic in DimensionManager. Prevents crashes with mods such as DivineRPG and speeds up server startup time by a ton. + logger.info("Preparing start region for level " + b0); + WorldServer worldserver = this.worldServers[b0]; + ChunkCoordinates chunkcoordinates = worldserver.getSpawnPoint(); ++ boolean before = worldserver.theChunkProviderServer.loadChunkOnProvideRequest; ++ worldserver.theChunkProviderServer.loadChunkOnProvideRequest = true; + long j = getSystemTimeMillis(); + + for (int k = -192; k <= 192 && this.isServerRunning(); k += 16) +@@ -265,7 +469,8 @@ + worldserver.theChunkProviderServer.loadChunk(chunkcoordinates.posX + k >> 4, chunkcoordinates.posZ + l >> 4); + } + } +- ++ worldserver.theChunkProviderServer.loadChunkOnProvideRequest = before; ++ // Cauldron end + this.clearCurrentTask(); + } + +@@ -292,19 +497,17 @@ + { + this.currentTask = null; + this.percentDone = 0; ++ this.server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.POSTWORLD); // CraftBukkit + } + +- protected void saveAllWorlds(boolean p_71267_1_) ++ protected void saveAllWorlds(boolean p_71267_1_) throws MinecraftException // CraftBukkit - added throws + { + if (!this.worldIsBeingDeleted) + { +- WorldServer[] aworldserver = this.worldServers; +- if (aworldserver == null) return; //Forge: Just in case, NPE protection as it has been encountered. +- int i = aworldserver.length; +- +- for (int j = 0; j < i; ++j) ++ // CraftBukkit start ++ for (int j = 0; j < this.worlds.size(); ++j) + { +- WorldServer worldserver = aworldserver[j]; ++ WorldServer worldserver = this.worlds.get(j); + + if (worldserver != null) + { +@@ -313,25 +516,41 @@ + logger.info("Saving chunks for level \'" + worldserver.getWorldInfo().getWorldName() + "\'/" + worldserver.provider.getDimensionName()); + } + +- try ++ worldserver.saveAllChunks(true, (IProgressUpdate) null); ++ worldserver.flush(); ++ WorldSaveEvent event = new WorldSaveEvent(worldserver.getWorld()); ++ this.server.getPluginManager().callEvent(event); ++ // Cauldron start - save world configs ++ if (worldserver.cauldronConfig != null) + { +- worldserver.saveAllChunks(true, (IProgressUpdate)null); ++ worldserver.cauldronConfig.save(); + } +- catch (MinecraftException minecraftexception) ++ if (worldserver.tileentityConfig != null) + { +- logger.warn(minecraftexception.getMessage()); ++ worldserver.tileentityConfig.save(); + } ++ // Cauldron end + } + } ++ ++ // CraftBukkit end + } + } + +- public void stopServer() ++ public void stopServer() throws MinecraftException // CraftBukkit - added throws + { + if (!this.worldIsBeingDeleted && Loader.instance().hasReachedState(LoaderState.SERVER_STARTED) && !serverStopped) // make sure the save is valid and we don't save twice + { + logger.info("Stopping server"); + ++ // CraftBukkit start ++ if (this.server != null) ++ { ++ this.server.disablePlugins(); ++ } ++ ++ // CraftBukkit end ++ + if (this.func_147137_ag() != null) + { + this.func_147137_ag().terminateEndpoints(); +@@ -347,7 +566,14 @@ + if (this.worldServers != null) + { + logger.info("Saving worlds"); +- this.saveAllWorlds(false); ++ try ++ { ++ this.saveAllWorlds(false); ++ } ++ catch (MinecraftException e) ++ { ++ e.printStackTrace(); ++ } + + for (int i = 0; i < this.worldServers.length; ++i) + { +@@ -380,6 +606,13 @@ + this.serverRunning = false; + } + ++ // Spigot Start ++ private static double calcTps(double avg, double exp, double tps) ++ { ++ return (avg * exp) + (tps * (1 - exp)); ++ } ++ // Spigot End ++ + public void run() + { + try +@@ -392,45 +625,41 @@ + this.field_147147_p.func_151315_a(new ChatComponentText(this.motd)); + this.field_147147_p.func_151321_a(new ServerStatusResponse.MinecraftProtocolVersionIdentifier("1.7.10", 5)); + this.func_147138_a(this.field_147147_p); ++ DedicatedServer.allowPlayerLogins = true; // Cauldron - server is ready, allow player logins ++ // Spigot start ++ Arrays.fill(recentTps, 20); ++ long lastTick = 0, catchupTime = 0, curTime, wait; + + while (this.serverRunning) + { +- long j = getSystemTimeMillis(); +- long k = j - i; ++ curTime = System.nanoTime(); ++ wait = TICK_TIME - (curTime - lastTick) - catchupTime; + +- if (k > 2000L && i - this.timeOfLastWarning >= 15000L) ++ if (wait > 0) + { +- logger.warn("Can\'t keep up! Did the system time change, or is the server overloaded? Running {}ms behind, skipping {} tick(s)", new Object[] {Long.valueOf(k), Long.valueOf(k / 50L)}); +- k = 2000L; +- this.timeOfLastWarning = i; ++ Thread.sleep(wait / 1000000); ++ catchupTime = 0; ++ continue; + } +- +- if (k < 0L) ++ else + { +- logger.warn("Time ran backwards! Did the system time change?"); +- k = 0L; ++ catchupTime = Math.min(1000000000, Math.abs(wait)); + } + +- l += k; +- i = j; +- +- if (this.worldServers[0].areAllPlayersAsleep()) ++ if (MinecraftServer.currentTick++ % 100 == 0) + { +- this.tick(); +- l = 0L; ++ currentTps = 1E9 / (curTime - lastTick); ++ recentTps[0] = calcTps(recentTps[0], 0.92, currentTps); // 1/exp(5sec/1min) ++ recentTps[1] = calcTps(recentTps[1], 0.9835, currentTps); // 1/exp(5sec/5min) ++ recentTps[2] = calcTps(recentTps[2], 0.9945, currentTps); // 1/exp(5sec/15min) + } +- else +- { +- while (l > 50L) +- { +- l -= 50L; +- this.tick(); +- } +- } + +- Thread.sleep(Math.max(1L, 50L - l)); ++ lastTick = curTime; ++ this.tick(); + this.serverIsRunning = true; + } ++ ++ // Spigot end + FMLCommonHandler.instance().handleServerStopping(); + FMLCommonHandler.instance().expectServerStopped(); // has to come before finalTick to avoid race conditions + } +@@ -448,6 +677,14 @@ + catch (Throwable throwable1) + { + logger.error("Encountered an unexpected exception", throwable1); ++ ++ // Spigot Start ++ if (throwable1.getCause() != null) ++ { ++ logger.error("\tCause of unexpected exception was", throwable1.getCause()); ++ } ++ ++ // Spigot End + CrashReport crashreport = null; + + if (throwable1 instanceof ReportedException) +@@ -477,6 +714,7 @@ + { + try + { ++ org.spigotmc.WatchdogThread.doStop(); // Spigot + this.stopServer(); + this.serverStopped = true; + } +@@ -486,6 +724,16 @@ + } + finally + { ++ // CraftBukkit start - Restore terminal to original settings ++ try ++ { ++ this.reader.getTerminal().restore(); ++ } ++ catch (Exception e) ++ { ++ } ++ ++ // CraftBukkit end + FMLCommonHandler.instance().handleServerStopped(); + this.serverStopped = true; + this.systemExitNow(); +@@ -532,8 +780,11 @@ + + public void tick() + { ++ SpigotTimings.serverTickTimer.startTiming(); // Spigot + long i = System.nanoTime(); ++ callingForgeTick = true; // Cauldron start - handle loadOnProviderRequests during forge tick event + FMLCommonHandler.instance().onPreServerTick(); ++ callingForgeTick = false; // Cauldron end + ++this.tickCounter; + + if (this.startProfiling) +@@ -562,12 +813,21 @@ + this.field_147147_p.func_151318_b().func_151330_a(agameprofile); + } + +- if (this.tickCounter % 900 == 0) ++ if ((this.autosavePeriod > 0) && ((this.tickCounter % this.autosavePeriod) == 0)) // CraftBukkit + { ++ SpigotTimings.worldSaveTimer.startTiming(); // Spigot + this.theProfiler.startSection("save"); + this.serverConfigManager.saveAllPlayerData(); +- this.saveAllWorlds(true); ++ try ++ { ++ this.saveAllWorlds(true); ++ } ++ catch (MinecraftException e) ++ { ++ e.printStackTrace(); ++ } + this.theProfiler.endSection(); ++ SpigotTimings.worldSaveTimer.stopTiming(); // Spigot + } + + this.theProfiler.startSection("tallying"); +@@ -575,25 +835,57 @@ + this.theProfiler.endSection(); + this.theProfiler.startSection("snooper"); + +- if (!this.usageSnooper.isSnooperRunning() && this.tickCounter > 100) ++ if (isSnooperEnabled() && !this.usageSnooper.isSnooperRunning() && this.tickCounter > 100) // Spigot + { + this.usageSnooper.startSnooper(); + } + +- if (this.tickCounter % 6000 == 0) ++ if (isSnooperEnabled() && this.tickCounter % 6000 == 0) // Spigot + { + this.usageSnooper.addMemoryStatsToSnooper(); + } + + this.theProfiler.endSection(); + this.theProfiler.endSection(); ++ callingForgeTick = true; // Cauldron start - handle loadOnProviderRequests during forge tick event + FMLCommonHandler.instance().onPostServerTick(); ++ callingForgeTick = false; // Cauldron end ++ SpigotTimings.serverTickTimer.stopTiming(); // Spigot ++ org.spigotmc.CustomTimingsHandler.tick(); // Spigot + } + + public void updateTimeLightAndEntities() + { + this.theProfiler.startSection("levels"); ++ SpigotTimings.schedulerTimer.startTiming(); // Spigot ++ // CraftBukkit start ++ this.server.getScheduler().mainThreadHeartbeat(this.tickCounter); ++ SpigotTimings.schedulerTimer.stopTiming(); // Spigot ++ ++ // Run tasks that are waiting on processing ++ SpigotTimings.processQueueTimer.startTiming(); // Spigot ++ while (!processQueue.isEmpty()) ++ { ++ processQueue.remove().run(); ++ } ++ SpigotTimings.processQueueTimer.stopTiming(); // Spigot ++ ++ SpigotTimings.chunkIOTickTimer.startTiming(); // Spigot + net.minecraftforge.common.chunkio.ChunkIOExecutor.tick(); ++ SpigotTimings.chunkIOTickTimer.stopTiming(); // Spigot ++ ++ SpigotTimings.timeUpdateTimer.startTiming(); // Spigot ++ // Send time updates to everyone, it will get the right time from the world the player is in. ++ if (this.tickCounter % 20 == 0) ++ { ++ for (int i = 0; i < this.getConfigurationManager().playerEntityList.size(); ++i) ++ { ++ EntityPlayerMP entityplayermp = (EntityPlayerMP) this.getConfigurationManager().playerEntityList.get(i); ++ entityplayermp.playerNetServerHandler.sendPacket(new S03PacketTimeUpdate(entityplayermp.worldObj.getTotalWorldTime(), entityplayermp.getPlayerTime(), entityplayermp.worldObj.getGameRules().getGameRuleBooleanValue("doDaylightCycle"))); // Add support for per player time ++ } ++ } ++ SpigotTimings.timeUpdateTimer.stopTiming(); // Spigot ++ + int i; + + Integer[] ids = DimensionManager.getIDs(this.tickCounter % 200 == 0); +@@ -602,19 +894,21 @@ + int id = ids[x]; + long j = System.nanoTime(); + +- if (id == 0 || this.getAllowNether()) +- { ++ // CraftBukkit start ++ //if (id == 0 || this.getAllowNether()) ++ //{ + WorldServer worldserver = DimensionManager.getWorld(id); + this.theProfiler.startSection(worldserver.getWorldInfo().getWorldName()); + this.theProfiler.startSection("pools"); + this.theProfiler.endSection(); +- ++ /* Drop global time updates + if (this.tickCounter % 20 == 0) + { + this.theProfiler.startSection("timeSync"); + this.serverConfigManager.sendPacketToAllPlayersInDimension(new S03PacketTimeUpdate(worldserver.getTotalWorldTime(), worldserver.getWorldTime(), worldserver.getGameRules().getGameRuleBooleanValue("doDaylightCycle")), worldserver.provider.dimensionId); + this.theProfiler.endSection(); + } ++ // CraftBukkit end */ + + this.theProfiler.startSection("tick"); + FMLCommonHandler.instance().onPreWorldTick(worldserver); +@@ -622,22 +916,46 @@ + + try + { ++ worldserver.timings.doTick.startTiming(); // Spigot + worldserver.tick(); ++ worldserver.timings.doTick.stopTiming(); // Spigot + } + catch (Throwable throwable1) + { +- crashreport = CrashReport.makeCrashReport(throwable1, "Exception ticking world"); ++ // Spigot Start ++ try ++ { ++ crashreport = CrashReport.makeCrashReport(throwable1, "Exception ticking world"); ++ } ++ catch (Throwable t) ++ { ++ throw new RuntimeException("Error generating crash report", t); ++ } ++ ++ // Spigot End + worldserver.addWorldInfoToCrashReport(crashreport); + throw new ReportedException(crashreport); + } + + try + { ++ worldserver.timings.tickEntities.startTiming(); // Spigot + worldserver.updateEntities(); ++ worldserver.timings.tickEntities.stopTiming(); // Spigot + } + catch (Throwable throwable) + { +- crashreport = CrashReport.makeCrashReport(throwable, "Exception ticking world entities"); ++ // Spigot Start ++ try ++ { ++ crashreport = CrashReport.makeCrashReport(throwable, "Exception ticking world entities"); ++ } ++ catch (Throwable t) ++ { ++ throw new RuntimeException("Error generating crash report", t); ++ } ++ ++ // Spigot End + worldserver.addWorldInfoToCrashReport(crashreport); + throw new ReportedException(crashreport); + } +@@ -645,10 +963,12 @@ + FMLCommonHandler.instance().onPostWorldTick(worldserver); + this.theProfiler.endSection(); + this.theProfiler.startSection("tracker"); ++ worldserver.timings.tracker.startTiming(); // Spigot + worldserver.getEntityTracker().updateTrackedEntities(); ++ worldserver.timings.tracker.stopTiming(); // Spigot + this.theProfiler.endSection(); + this.theProfiler.endSection(); +- } ++ // } // CraftBukkit + + worldTickTimes.get(id)[this.tickCounter % 100] = System.nanoTime() - j; + } +@@ -656,15 +976,21 @@ + this.theProfiler.endStartSection("dim_unloading"); + DimensionManager.unloadWorlds(worldTickTimes); + this.theProfiler.endStartSection("connection"); ++ SpigotTimings.connectionTimer.startTiming(); // Spigot + this.func_147137_ag().networkTick(); ++ SpigotTimings.connectionTimer.stopTiming(); // Spigot + this.theProfiler.endStartSection("players"); ++ SpigotTimings.playerListTimer.startTiming(); // Spigot + this.serverConfigManager.sendPlayerInfoToAllPlayers(); ++ SpigotTimings.playerListTimer.stopTiming(); // Spigot + this.theProfiler.endStartSection("tickables"); + ++ SpigotTimings.tickablesTimer.startTiming(); // Spigot + for (i = 0; i < this.tickables.size(); ++i) + { + ((IUpdatePlayerListBox)this.tickables.get(i)).update(); + } ++ SpigotTimings.tickablesTimer.stopTiming(); // Spigot + + this.theProfiler.endSection(); + } +@@ -699,6 +1025,13 @@ + + public WorldServer worldServerForDimension(int p_71218_1_) + { ++ // Cauldron start - this is required for MystCraft agebooks to teleport correctly ++ // verify the nether or the end is allowed, and if not return overworld ++ if ((p_71218_1_ == -1 && !this.getAllowNether()) || (p_71218_1_ == 1 && !this.server.getAllowEnd())) ++ { ++ return DimensionManager.getWorld(0); ++ } ++ // Cauldron end + WorldServer ret = DimensionManager.getWorld(p_71218_1_); + if (ret == null) + { +@@ -784,13 +1117,14 @@ + + public List getPossibleCompletions(ICommandSender p_71248_1_, String p_71248_2_) + { +- ArrayList arraylist = new ArrayList(); ++ // Cauldron start - add mod commands to list then pass to bukkit ++ java.util.HashSet arraylist = new java.util.HashSet(); // use a set here to avoid duplicates + + if (p_71248_2_.startsWith("/")) + { +- p_71248_2_ = p_71248_2_.substring(1); +- boolean flag = !p_71248_2_.contains(" "); +- List list = this.commandManager.getPossibleCommands(p_71248_1_, p_71248_2_); ++ String char1 = p_71248_2_.substring(1); // rename var to avoid removing slash from passed message ++ boolean flag = !char1.contains(" "); ++ List list = this.commandManager.getPossibleCommands(p_71248_1_, char1); + + if (list != null) + { +@@ -798,40 +1132,25 @@ + + while (iterator.hasNext()) + { +- String s3 = (String)iterator.next(); ++ String command = (String)iterator.next(); + + if (flag) + { +- arraylist.add("/" + s3); ++ arraylist.add("/" + command); + } + else + { +- arraylist.add(s3); ++ arraylist.add(command); + } + } + } +- +- return arraylist; + } +- else +- { +- String[] astring = p_71248_2_.split(" ", -1); +- String s1 = astring[astring.length - 1]; +- String[] astring1 = this.serverConfigManager.getAllUsernames(); +- int i = astring1.length; + +- for (int j = 0; j < i; ++j) +- { +- String s2 = astring1[j]; +- +- if (CommandBase.doesStringStartWith(s1, s2)) +- { +- arraylist.add(s2); +- } +- } +- +- return arraylist; +- } ++ arraylist.addAll(this.server.tabComplete(p_71248_1_, p_71248_2_)); // add craftbukkit commands ++ ArrayList completions = new ArrayList(arraylist); ++ Collections.sort(completions); // sort the final list ++ return completions; ++ // Cauldron end + } + + public static MinecraftServer getServer() +@@ -1034,7 +1353,7 @@ + + public boolean isServerInOnlineMode() + { +- return this.onlineMode; ++ return this.server.getOnlineMode(); // CraftBukkit + } + + public void setOnlineMode(boolean p_71229_1_) +@@ -1124,7 +1443,7 @@ + + public NetworkSystem func_147137_ag() + { +- return this.field_147144_o; ++ return (this.field_147144_o) == null ? this.field_147144_o = new NetworkSystem(this) : this.field_147144_o; // Spigot + } + + @SideOnly(Side.CLIENT) +@@ -1259,8 +1578,11 @@ + { + Bootstrap.func_151354_b(); + ++ OptionSet options = loadOptions(p_main_0_); ++ + try + { ++ /* CraftBukkit start - Replace everything + boolean flag = true; + String s = null; + String s1 = "."; +@@ -1356,16 +1678,34 @@ + { + dedicatedserver.setGuiEnabled(); + } ++ // */ ++ // CraftBukkit end ++ if (CauldronUtils.deobfuscatedEnvironment()) useJline = false; // Cauldron ++ DedicatedServer dedicatedserver = new DedicatedServer(options); + +- dedicatedserver.startServerThread(); +- Runtime.getRuntime().addShutdownHook(new Thread("Server Shutdown Thread") ++ if (options.has("port")) + { +- private static final String __OBFID = "CL_00001806"; +- public void run() ++ int port = (Integer) options.valueOf("port"); ++ ++ if (port > 0) + { +- dedicatedserver.stopServer(); ++ dedicatedserver.setServerPort(port); + } +- }); ++ } ++ ++ if (options.has("universe")) ++ { ++ dedicatedserver.anvilFile = (File) options.valueOf("universe"); ++ } ++ ++ if (options.has("world")) ++ { ++ dedicatedserver.setFolderName((String) options.valueOf("world")); ++ } ++ ++ dedicatedserver.primaryThread.start(); ++ // Runtime.getRuntime().addShutdownHook(new ThreadShutdown("Server Shutdown Thread", dedicatedserver)); ++ // CraftBukkit end + } + catch (Exception exception) + { +@@ -1400,15 +1740,70 @@ + @SideOnly(Side.SERVER) + public String getPlugins() + { +- return ""; ++ // CraftBukkit start - Whole method ++ StringBuilder result = new StringBuilder(); ++ org.bukkit.plugin.Plugin[] plugins = server.getPluginManager().getPlugins(); ++ result.append(server.getName()); ++ result.append(" on Bukkit "); ++ result.append(server.getBukkitVersion()); ++ ++ if (plugins.length > 0 && this.server.getQueryPlugins()) ++ { ++ result.append(": "); ++ ++ for (int i = 0; i < plugins.length; i++) ++ { ++ if (i > 0) ++ { ++ result.append("; "); ++ } ++ ++ result.append(plugins[i].getDescription().getName()); ++ result.append(" "); ++ result.append(plugins[i].getDescription().getVersion().replaceAll(";", ",")); ++ } ++ } ++ ++ return result.toString(); ++ // CraftBukkit end + } + + @SideOnly(Side.SERVER) +- public String handleRConCommand(String p_71252_1_) ++ public String handleRConCommand(final String par1Str) + { +- RConConsoleSource.instance.resetLog(); +- this.commandManager.executeCommand(RConConsoleSource.instance, p_71252_1_); +- return RConConsoleSource.instance.getLogContents(); ++ Waitable waitable = new Waitable() ++ { ++ @Override ++ protected String evaluate() ++ { ++ RConConsoleSource.instance.resetLog(); ++ // Event changes start ++ RemoteServerCommandEvent event = new RemoteServerCommandEvent(MinecraftServer.this.remoteConsole, par1Str); ++ MinecraftServer.this.server.getPluginManager().callEvent(event); ++ // Event changes end ++ ServerCommand servercommand = new ServerCommand(event.getCommand(), RConConsoleSource.instance); ++ MinecraftServer.this.server.dispatchServerCommand(MinecraftServer.this.remoteConsole, servercommand); // CraftBukkit ++ // this.n.a(RemoteControlCommandListener.instance, s); ++ return RConConsoleSource.instance.getLogContents(); ++ } ++ }; ++ processQueue.add(waitable); ++ ++ try ++ { ++ return waitable.get(); ++ } ++ catch (java.util.concurrent.ExecutionException e) ++ { ++ throw new RuntimeException("Exception processing rcon command " + par1Str, e.getCause()); ++ } ++ catch (InterruptedException e) ++ { ++ Thread.currentThread().interrupt(); // Maintain interrupted state ++ throw new RuntimeException("Interrupted processing rcon command " + par1Str, e); ++ } ++ ++ // CraftBukkit end + } + + @SideOnly(Side.SERVER) +@@ -1455,9 +1850,213 @@ + return this.serverStopped; + } + ++ public static OptionSet loadOptions(String[] args) { ++ OptionParser parser = new OptionParser() { ++ { ++ acceptsAll(Arrays.asList("?", "help"), "Show the help"); ++ ++ acceptsAll(Arrays.asList("c", "config"), "Properties file to use") ++ .withRequiredArg() ++ .ofType(File.class) ++ .defaultsTo(new File("server.properties")) ++ .describedAs("Properties file"); ++ ++ acceptsAll(Arrays.asList("P", "plugins"), "Plugin directory to use") ++ .withRequiredArg() ++ .ofType(File.class) ++ .defaultsTo(new File("plugins")) ++ .describedAs("Plugin directory"); ++ ++ acceptsAll(Arrays.asList("h", "host", "server-ip"), "Host to listen on") ++ .withRequiredArg() ++ .ofType(String.class) ++ .describedAs("Hostname or IP"); ++ ++ acceptsAll(Arrays.asList("W", "world-dir", "universe", "world-container"), "World container") ++ .withRequiredArg() ++ .ofType(File.class) ++ .describedAs("Directory containing worlds"); ++ ++ acceptsAll(Arrays.asList("w", "world", "level-name"), "World name") ++ .withRequiredArg() ++ .ofType(String.class) ++ .describedAs("World name"); ++ ++ acceptsAll(Arrays.asList("p", "port", "server-port"), "Port to listen on") ++ .withRequiredArg() ++ .ofType(Integer.class) ++ .describedAs("Port"); ++ ++ acceptsAll(Arrays.asList("o", "online-mode"), "Whether to use online authentication") ++ .withRequiredArg() ++ .ofType(Boolean.class) ++ .describedAs("Authentication"); ++ ++ acceptsAll(Arrays.asList("s", "size", "max-players"), "Maximum amount of players") ++ .withRequiredArg() ++ .ofType(Integer.class) ++ .describedAs("Server size"); ++ ++ acceptsAll(Arrays.asList("d", "date-format"), "Format of the date to display in the console (for log entries)") ++ .withRequiredArg() ++ .ofType(SimpleDateFormat.class) ++ .describedAs("Log date format"); ++ ++ acceptsAll(Arrays.asList("log-pattern"), "Specfies the log filename pattern") ++ .withRequiredArg() ++ .ofType(String.class) ++ .defaultsTo("server.log") ++ .describedAs("Log filename"); ++ ++ acceptsAll(Arrays.asList("log-limit"), "Limits the maximum size of the log file (0 = unlimited)") ++ .withRequiredArg() ++ .ofType(Integer.class) ++ .defaultsTo(0) ++ .describedAs("Max log size"); ++ ++ acceptsAll(Arrays.asList("log-count"), "Specified how many log files to cycle through") ++ .withRequiredArg() ++ .ofType(Integer.class) ++ .defaultsTo(1) ++ .describedAs("Log count"); ++ ++ acceptsAll(Arrays.asList("log-append"), "Whether to append to the log file") ++ .withRequiredArg() ++ .ofType(Boolean.class) ++ .defaultsTo(true) ++ .describedAs("Log append"); ++ ++ acceptsAll(Arrays.asList("log-strip-color"), "Strips color codes from log file"); ++ ++ acceptsAll(Arrays.asList("b", "bukkit-settings"), "File for bukkit settings") ++ .withRequiredArg() ++ .ofType(File.class) ++ .defaultsTo(new File("bukkit.yml")) ++ .describedAs("Yml file"); ++ ++ acceptsAll(Arrays.asList("C", "commands-settings"), "File for command settings") ++ .withRequiredArg() ++ .ofType(File.class) ++ .defaultsTo(new File("commands.yml")) ++ .describedAs("Yml file"); ++ ++ acceptsAll(Arrays.asList("nojline"), "Disables jline and emulates the vanilla console"); ++ ++ acceptsAll(Arrays.asList("noconsole"), "Disables the console"); ++ ++ acceptsAll(Arrays.asList("v", "version"), "Show the CraftBukkit Version"); ++ ++ acceptsAll(Arrays.asList("demo"), "Demo mode"); ++ } ++ }; ++ ++ OptionSet options = null; ++ ++ try { ++ options = parser.parse(args); ++ } catch (joptsimple.OptionException ex) { ++ logger.log(org.apache.logging.log4j.Level.ERROR, ex.getLocalizedMessage()); ++ } ++ ++ if ((options == null) || (options.has("?"))) { ++ try { ++ parser.printHelpOn(System.out); ++ } catch (IOException ex) { ++ logger.log(org.apache.logging.log4j.Level.ERROR, ex); ++ } ++ } else { ++ try { ++ // This trick bypasses Maven Shade's clever rewriting of our getProperty call when using String literals ++ String jline_UnsupportedTerminal = new String(new char[] {'j','l','i','n','e','.','U','n','s','u','p','p','o','r','t','e','d','T','e','r','m','i','n','a','l'}); ++ String jline_terminal = new String(new char[] {'j','l','i','n','e','.','t','e','r','m','i','n','a','l'}); ++ ++ useJline = !(jline_UnsupportedTerminal).equals(System.getProperty(jline_terminal)); ++ ++ if (options.has("nojline")) { ++ System.setProperty("user.language", "en"); ++ useJline = false; ++ } ++ ++ if (!useJline) { ++ // This ensures the terminal literal will always match the jline implementation ++ System.setProperty(jline.TerminalFactory.JLINE_TERMINAL, jline.UnsupportedTerminal.class.getName()); ++ } ++ ++ ++ if (options.has("noconsole")) { ++ useConsole = false; ++ } ++ // Cauldron start - initialize config ++ configFile = (File) options.valueOf("bukkit-settings"); ++ commandFile = (File)options.valueOf("commands-settings"); ++ configuration = YamlConfiguration.loadConfiguration(configFile); ++ configuration.options().copyDefaults(true); ++ configuration.setDefaults(YamlConfiguration.loadConfiguration(MinecraftServer.class.getClassLoader().getResourceAsStream("configurations/bukkit.yml"))); ++ ConfigurationSection legacyAlias = null; ++ if (!configuration.isString("aliases")) { ++ legacyAlias = configuration.getConfigurationSection("aliases"); ++ configuration.set("aliases", "now-in-commands.yml"); ++ } ++ try { ++ configuration.save(configFile); ++ } catch (IOException ex) { ++ logger.log(org.apache.logging.log4j.Level.ERROR, "Could not save " + configFile, ex); ++ } ++ if (commandFile.isFile()) { ++ legacyAlias = null; ++ } ++ commandsConfiguration = YamlConfiguration.loadConfiguration(commandFile); ++ commandsConfiguration.options().copyDefaults(true); ++ commandsConfiguration.setDefaults(YamlConfiguration.loadConfiguration(MinecraftServer.class.getClassLoader().getResourceAsStream("configurations/commands.yml"))); ++ try { ++ commandsConfiguration.save(commandFile); ++ } catch (IOException ex) { ++ logger.log(org.apache.logging.log4j.Level.ERROR, "Could not save " + commandFile, ex); ++ } ++ ++ // Migrate aliases from old file and add previously implicit $1- to pass all arguments ++ if (legacyAlias != null) { ++ ConfigurationSection aliases = commandsConfiguration.createSection("aliases"); ++ for (String key : legacyAlias.getKeys(false)) { ++ ArrayList commands = new ArrayList(); ++ ++ if (legacyAlias.isList(key)) { ++ for (String command : legacyAlias.getStringList(key)) { ++ commands.add(command + " $1-"); ++ } ++ } else { ++ commands.add(legacyAlias.getString(key) + " $1-"); ++ } ++ ++ aliases.set(key, commands); ++ } ++ } ++ ++ try { ++ commandsConfiguration.save(commandFile); ++ } catch (IOException ex) { ++ logger.log(org.apache.logging.log4j.Level.ERROR, "Could not save " + commandFile, ex); ++ } ++ ++ return options; ++ // Cauldron end ++ } catch (Throwable t) { ++ t.printStackTrace(); ++ } ++ } ++ return null; // Cauldron ++ } ++ + @SideOnly(Side.SERVER) + public void setForceGamemode(boolean p_104055_1_) + { + this.isGamemodeForced = p_104055_1_; + } ++ ++ // CraftBukkit start ++ public static Logger getLogger() ++ { ++ return logger; ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch b/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch new file mode 100644 index 0000000..cd70938 --- /dev/null +++ b/patches/net/minecraft/server/dedicated/DedicatedServer.java.patch @@ -0,0 +1,249 @@ +--- ../src-base/minecraft/net/minecraft/server/dedicated/DedicatedServer.java ++++ ../src-work/minecraft/net/minecraft/server/dedicated/DedicatedServer.java +@@ -34,9 +34,19 @@ + import net.minecraft.world.World; + import net.minecraft.world.WorldSettings; + import net.minecraft.world.WorldType; ++import net.minecraft.world.chunk.storage.AnvilSaveConverter; + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import java.io.PrintStream; ++import org.apache.logging.log4j.Level; ++ ++import org.bukkit.craftbukkit.LoggerOutputStream; ++import org.bukkit.craftbukkit.SpigotTimings; // Spigot ++import org.bukkit.event.server.ServerCommandEvent; ++// CraftBukkit end ++ + @SideOnly(Side.SERVER) + public class DedicatedServer extends MinecraftServer implements IServer + { +@@ -44,7 +54,7 @@ + public final List pendingCommandList = Collections.synchronizedList(new ArrayList()); + private RConThreadQuery theRConThreadQuery; + private RConThreadMain theRConThreadMain; +- private PropertyManager settings; ++ public PropertyManager settings; // CraftBukkit - private -> public + private ServerEula field_154332_n; + private boolean canSpawnStructures; + private WorldSettings.GameType gameType; +@@ -52,9 +62,12 @@ + public static boolean allowPlayerLogins = false; + private static final String __OBFID = "CL_00001784"; + +- public DedicatedServer(File p_i1508_1_) ++ // CraftBukkit start - Signature changed ++ public DedicatedServer(joptsimple.OptionSet options) + { +- super(p_i1508_1_, Proxy.NO_PROXY); ++ super(options, Proxy.NO_PROXY); ++ // super(p_i1508_1_, Proxy.NO_PROXY); ++ // CraftBukkit end + Thread thread = new Thread("Server Infinisleeper") + { + private static final String __OBFID = "CL_00001787"; +@@ -82,31 +95,77 @@ + }; + } + +- protected boolean startServer() throws IOException ++ protected boolean startServer() throws java.net.UnknownHostException // CraftBukkit - throws UnknownHostException + { + Thread thread = new Thread("Server console handler") + { + private static final String __OBFID = "CL_00001786"; ++ final DedicatedServer server = DedicatedServer.this; + public void run() + { +- BufferedReader bufferedreader = new BufferedReader(new InputStreamReader(System.in)); +- String s4; ++ // CraftBukkit start ++ if (!useConsole) ++ { ++ return; ++ } ++ // CraftBukkit end + ++ jline.console.ConsoleReader bufferedreader = this.server.reader; // CraftBukkit ++ String s; ++ + try + { +- while (!DedicatedServer.this.isServerStopped() && DedicatedServer.this.isServerRunning() && (s4 = bufferedreader.readLine()) != null) ++ // CraftBukkit start - JLine disabling compatibility ++ while (!this.server.isServerStopped() && this.server.isServerRunning()) + { +- DedicatedServer.this.addPendingCommand(s4, DedicatedServer.this); ++ if (useJline) ++ { ++ s = bufferedreader.readLine(">", null); ++ } ++ else ++ { ++ s = bufferedreader.readLine(); ++ } ++ if (s != null) ++ { ++ this.server.addPendingCommand(s, this.server); ++ } ++ // CraftBukkit end + } ++ + } +- catch (IOException ioexception1) ++ catch (IOException ioexception) + { +- DedicatedServer.field_155771_h.error("Exception handling console input", ioexception1); ++ DedicatedServer.field_155771_h.error("Exception handling console input", ioexception); + } + } + }; + thread.setDaemon(true); + thread.start(); ++ // CraftBukkit start - TODO: handle command-line logging arguments ++ java.util.logging.Logger global = java.util.logging.Logger.getLogger(""); ++ global.setUseParentHandlers(false); ++ ++ for (java.util.logging.Handler handler : global.getHandlers()) ++ { ++ global.removeHandler(handler); ++ } ++ ++ global.addHandler(new org.bukkit.craftbukkit.util.ForwardLogHandler()); ++ final org.apache.logging.log4j.core.Logger logger = ((org.apache.logging.log4j.core.Logger) LogManager.getRootLogger()); ++ ++ for (org.apache.logging.log4j.core.Appender appender : logger.getAppenders().values()) ++ { ++ if (appender instanceof org.apache.logging.log4j.core.appender.ConsoleAppender) ++ { ++ logger.removeAppender(appender); ++ } ++ } ++ ++ new Thread(new org.bukkit.craftbukkit.util.TerminalConsoleWriterThread(System.out, this.reader)).start(); ++ System.setOut(new PrintStream(new LoggerOutputStream(logger, Level.INFO), true)); ++ System.setErr(new PrintStream(new LoggerOutputStream(logger, Level.WARN), true)); ++ // CraftBukkit end + field_155771_h.info("Starting minecraft server version 1.7.10"); + + if (Runtime.getRuntime().maxMemory() / 1024L / 1024L < 512L) +@@ -117,7 +176,7 @@ + FMLCommonHandler.instance().onServerStart(this); + + field_155771_h.info("Loading properties"); +- this.settings = new PropertyManager(new File("server.properties")); ++ this.settings = new PropertyManager(this.options); // CraftBukkit - CLI argument support + this.field_154332_n = new ServerEula(new File("eula.txt")); + + if (!this.field_154332_n.func_154346_a()) +@@ -172,6 +231,16 @@ + this.setServerPort(this.settings.getIntProperty("server-port", 25565)); + } + ++ // Spigot start ++ this.func_152361_a((ServerConfigurationManager) (new DedicatedPlayerList(this))); ++ org.spigotmc.SpigotConfig.init(); ++ org.spigotmc.SpigotConfig.registerCommands(); ++ // Spigot end ++ // Cauldron start ++ this.cauldronConfig.registerCommands(); ++ this.tileEntityConfig.registerCommands(); ++ // Cauldron end ++ + field_155771_h.info("Generating keypair"); + this.setKeyPair(CryptManager.createNewKeyPair()); + field_155771_h.info("Starting Minecraft server on " + (this.getServerHostname().length() == 0 ? "*" : this.getServerHostname()) + ":" + this.getServerPort()); +@@ -180,7 +249,7 @@ + { + this.func_147137_ag().addLanEndpoint(inetaddress, this.getServerPort()); + } +- catch (IOException ioexception) ++ catch (Throwable ioexception) // CraftBukkit - IOException -> Throwable + { + field_155771_h.warn("**** FAILED TO BIND TO PORT!"); + field_155771_h.warn("The exception was: {}", new Object[] {ioexception.toString()}); +@@ -196,10 +265,17 @@ + field_155771_h.warn("To change this, set \"online-mode\" to \"true\" in the server.properties file."); + } + +- if (this.func_152368_aE()) ++ try + { +- this.func_152358_ax().func_152658_c(); ++ if (this.func_152368_aE()) ++ { ++ this.func_152358_ax().func_152658_c(); ++ } + } ++ catch (IOException e) ++ { ++ e.printStackTrace(); ++ } + + if (!PreYggdrasilConverter.func_152714_a(this.settings)) + { +@@ -208,7 +284,8 @@ + else + { + FMLCommonHandler.instance().onServerStarted(); +- this.func_152361_a(new DedicatedPlayerList(this)); ++ // this.func_152361_a(new DedicatedPlayerList(this)); // CraftBukkit - moved up ++ this.anvilConverterForAnvilFile = new AnvilSaveConverter(server.getWorldContainer()); // CraftBukkit - moved from MinecraftServer constructor + long j = System.nanoTime(); + + if (this.getFolderName() == null) +@@ -274,11 +351,30 @@ + this.theRConThreadMain.startThread(); + } + ++ // CraftBukkit start ++ if (this.server.getBukkitSpawnRadius() > -1) ++ { ++ field_155771_h ++ .info("'settings.spawn-radius' in bukkit.yml has been moved to 'spawn-protection' in server.properties. I will move your config for you."); ++ this.settings.serverProperties.remove("spawn-protection"); ++ this.settings.getIntProperty("spawn-protection", this.server.getBukkitSpawnRadius()); ++ this.server.removeBukkitSpawnRadius(); ++ this.settings.saveProperties(); ++ } ++ // CraftBukkit end ++ + return FMLCommonHandler.instance().handleServerStarting(this); + } + } + } + ++ // CraftBukkit start ++ public PropertyManager getPropertyManager() ++ { ++ return this.settings; ++ } ++ // CraftBukkit end ++ + public boolean canStructuresSpawn() + { + return this.canSpawnStructures; +@@ -364,11 +460,19 @@ + + public void executePendingCommands() + { ++ SpigotTimings.serverCommandTimer.startTiming(); // Spigot + while (!this.pendingCommandList.isEmpty()) + { +- ServerCommand servercommand = (ServerCommand)this.pendingCommandList.remove(0); +- this.getCommandManager().executeCommand(servercommand.sender, servercommand.command); ++ ServerCommand servercommand = (ServerCommand) this.pendingCommandList.remove(0); ++ // CraftBukkit start - ServerCommand for preprocessing ++ ServerCommandEvent event = new ServerCommandEvent(this.console, servercommand.command); ++ this.server.getPluginManager().callEvent(event); ++ servercommand = new ServerCommand(event.getCommand(), servercommand.sender); ++ // this.getCommandManager().executeCommand(servercommand.sender, servercommand.command); // Called in dispatchServerCommand ++ this.server.dispatchServerCommand(this.console, servercommand); ++ // CraftBukkit end + } ++ SpigotTimings.serverCommandTimer.stopTiming(); // Spigot + } + + public boolean isDedicatedServer() diff --git a/patches/net/minecraft/server/dedicated/PropertyManager.java.patch b/patches/net/minecraft/server/dedicated/PropertyManager.java.patch new file mode 100644 index 0000000..cf3180e --- /dev/null +++ b/patches/net/minecraft/server/dedicated/PropertyManager.java.patch @@ -0,0 +1,98 @@ +--- ../src-base/minecraft/net/minecraft/server/dedicated/PropertyManager.java ++++ ../src-work/minecraft/net/minecraft/server/dedicated/PropertyManager.java +@@ -10,11 +10,13 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++import joptsimple.OptionSet; // CraftBukkit ++ + @SideOnly(Side.SERVER) + public class PropertyManager + { + private static final Logger field_164440_a = LogManager.getLogger(); +- private final Properties serverProperties = new Properties(); ++ public final Properties serverProperties = new Properties(); // CraftBukkit - private -> public + private final File serverPropertiesFile; + private static final String __OBFID = "CL_00001782"; + +@@ -58,6 +60,26 @@ + } + } + ++ // CraftBukkit start ++ private OptionSet options = null; ++ ++ public PropertyManager(final OptionSet options) ++ { ++ this((File) options.valueOf("config")); ++ this.options = options; ++ } ++ ++ private T getOverride(String name, T value) ++ { ++ if ((this.options != null) && (this.options.has(name))) ++ { ++ return (T) this.options.valueOf(name); ++ } ++ ++ return value; ++ } ++ // CraftBukkit end ++ + public void generateNewProperties() + { + field_164440_a.info("Generating new properties file"); +@@ -70,6 +92,13 @@ + + try + { ++ // CraftBukkit start - Don't attempt writing to file if it's read only ++ if (this.serverPropertiesFile.exists() && !this.serverPropertiesFile.canWrite()) ++ { ++ return; ++ } ++ ++ // CraftBukkit end + fileoutputstream = new FileOutputStream(this.serverPropertiesFile); + this.serverProperties.store(fileoutputstream, "Minecraft server properties"); + } +@@ -108,20 +137,20 @@ + this.saveProperties(); + } + +- return this.serverProperties.getProperty(p_73671_1_, p_73671_2_); ++ return this.getOverride(p_73671_1_, this.serverProperties.getProperty(p_73671_1_, p_73671_2_)); // CraftBukkit + } + + public int getIntProperty(String p_73669_1_, int p_73669_2_) + { + try + { +- return Integer.parseInt(this.getStringProperty(p_73669_1_, "" + p_73669_2_)); ++ return this.getOverride(p_73669_1_, Integer.parseInt(this.getStringProperty(p_73669_1_, "" + p_73669_2_))); // CraftBukkit + } + catch (Exception exception) + { + this.serverProperties.setProperty(p_73669_1_, "" + p_73669_2_); + this.saveProperties(); +- return p_73669_2_; ++ return this.getOverride(p_73669_1_, p_73669_2_); // CraftBukkit + } + } + +@@ -129,13 +158,13 @@ + { + try + { +- return Boolean.parseBoolean(this.getStringProperty(p_73670_1_, "" + p_73670_2_)); ++ return this.getOverride(p_73670_1_, Boolean.parseBoolean(this.getStringProperty(p_73670_1_, "" + p_73670_2_))); // CraftBukkit + } + catch (Exception exception) + { + this.serverProperties.setProperty(p_73670_1_, "" + p_73670_2_); + this.saveProperties(); +- return p_73670_2_; ++ return this.getOverride(p_73670_1_, p_73670_2_); // CraftBukkit + } + } + diff --git a/patches/net/minecraft/server/integrated/IntegratedServer.java.patch b/patches/net/minecraft/server/integrated/IntegratedServer.java.patch new file mode 100644 index 0000000..98d30c1 --- /dev/null +++ b/patches/net/minecraft/server/integrated/IntegratedServer.java.patch @@ -0,0 +1,60 @@ +--- ../src-base/minecraft/net/minecraft/server/integrated/IntegratedServer.java ++++ ../src-work/minecraft/net/minecraft/server/integrated/IntegratedServer.java +@@ -13,9 +13,11 @@ + import net.minecraft.crash.CrashReport; + import net.minecraft.profiler.PlayerUsageSnooper; + import net.minecraft.server.MinecraftServer; ++import net.minecraft.server.dedicated.PropertyManager; + import net.minecraft.util.CryptManager; + import net.minecraft.util.HttpUtil; + import net.minecraft.world.EnumDifficulty; ++import net.minecraft.world.MinecraftException; + import net.minecraft.world.WorldManager; + import net.minecraft.world.WorldServer; + import net.minecraft.world.WorldServerMulti; +@@ -78,7 +80,7 @@ + this.initialWorldChunkLoad(); + } + +- protected boolean startServer() throws IOException ++ protected boolean startServer() throws java.net.UnknownHostException // Cauldron + { + logger.info("Starting integrated minecraft server version 1.7.10"); + this.setOnlineMode(true); +@@ -103,7 +105,15 @@ + { + logger.info("Saving and pausing game..."); + this.getConfigurationManager().saveAllPlayerData(); +- this.saveAllWorlds(false); ++ try ++ { ++ this.saveAllWorlds(false); ++ } ++ catch (MinecraftException e) ++ { ++ // TODO Auto-generated catch block ++ e.printStackTrace(); ++ } + } + + if (!this.isGamePaused) +@@ -236,7 +246,7 @@ + } + } + +- public void stopServer() ++ public void stopServer() throws MinecraftException // Cauldron + { + super.stopServer(); + +@@ -277,4 +287,10 @@ + { + return 4; + } ++ ++ @Override ++ public PropertyManager getPropertyManager() ++ { ++ return null; ++ } + } diff --git a/patches/net/minecraft/server/management/BanEntry.java.patch b/patches/net/minecraft/server/management/BanEntry.java.patch new file mode 100644 index 0000000..9c6936c --- /dev/null +++ b/patches/net/minecraft/server/management/BanEntry.java.patch @@ -0,0 +1,33 @@ +--- ../src-base/minecraft/net/minecraft/server/management/BanEntry.java ++++ ../src-work/minecraft/net/minecraft/server/management/BanEntry.java +@@ -76,4 +76,30 @@ + p_152641_1_.addProperty("expires", this.banEndDate == null ? "forever" : dateFormat.format(this.banEndDate)); + p_152641_1_.addProperty("reason", this.reason); + } ++ ++ // CraftBukkit start ++ public String getSource() { ++ return this.bannedBy; ++ } ++ ++ public Date getCreated() { ++ return this.banStartDate; ++ } ++ ++ private static Object checkExpiry(Object object, JsonObject jsonobject) { ++ Date expires = null; ++ ++ try { ++ expires = jsonobject.has("expires") ? dateFormat.parse(jsonobject.get("expires").getAsString()) : null; ++ } catch (ParseException ex) { ++ // Guess we don't have a date ++ } ++ ++ if (expires == null || expires.after(new Date())) { ++ return object; ++ } else { ++ return null; ++ } ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/server/management/ItemInWorldManager.java.patch b/patches/net/minecraft/server/management/ItemInWorldManager.java.patch new file mode 100644 index 0000000..42e6655 --- /dev/null +++ b/patches/net/minecraft/server/management/ItemInWorldManager.java.patch @@ -0,0 +1,298 @@ +--- ../src-base/minecraft/net/minecraft/server/management/ItemInWorldManager.java ++++ ../src-work/minecraft/net/minecraft/server/management/ItemInWorldManager.java +@@ -4,6 +4,7 @@ + import net.minecraft.block.material.Material; + import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.entity.player.EntityPlayerMP; ++import net.minecraft.item.Item; + import net.minecraft.item.ItemStack; + import net.minecraft.item.ItemSword; + import net.minecraft.network.play.server.S23PacketBlockChange; +@@ -13,13 +14,28 @@ + import net.minecraft.world.WorldSettings; + import net.minecraftforge.common.ForgeHooks; + import net.minecraftforge.common.MinecraftForge; +-import cpw.mods.fml.common.eventhandler.Event; + import net.minecraftforge.event.ForgeEventFactory; + import net.minecraftforge.event.entity.player.PlayerDestroyItemEvent; +-import net.minecraftforge.event.entity.player.PlayerInteractEvent; +-import net.minecraftforge.event.entity.player.PlayerInteractEvent.Action; + import net.minecraftforge.event.world.BlockEvent; + ++// CraftBukkit start ++import net.minecraft.init.Blocks; ++ ++import org.bukkit.event.block.BlockBreakEvent; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.craftbukkit.inventory.CraftInventory; ++import org.bukkit.event.Event; ++import org.bukkit.event.block.Action; ++import org.bukkit.event.player.PlayerInteractEvent; ++// CraftBukkit end ++// Cauldron start ++import net.minecraft.inventory.ContainerPlayer; ++import net.minecraft.inventory.IInventory; ++import net.minecraft.server.MinecraftServer; ++import org.bukkit.craftbukkit.inventory.CraftInventoryView; ++import org.bukkit.event.inventory.InventoryType; ++// Cauldron end ++ + public class ItemInWorldManager + { + /** Forge reach distance */ +@@ -135,15 +151,29 @@ + + public void onBlockClicked(int p_73074_1_, int p_73074_2_, int p_73074_3_, int p_73074_4_) + { ++ // CraftBukkit start ++ org.bukkit.event.player.PlayerInteractEvent cbEvent = CraftEventFactory.callPlayerInteractEvent(this.thisPlayerMP, Action.LEFT_CLICK_BLOCK, p_73074_1_, p_73074_2_, p_73074_3_, p_73074_4_, this.thisPlayerMP.inventory.getCurrentItem()); ++ + if (!this.gameType.isAdventure() || this.thisPlayerMP.isCurrentToolAdventureModeExempt(p_73074_1_, p_73074_2_, p_73074_3_)) + { +- PlayerInteractEvent event = ForgeEventFactory.onPlayerInteract(thisPlayerMP, Action.LEFT_CLICK_BLOCK, p_73074_1_, p_73074_2_, p_73074_3_, p_73074_4_, theWorld); +- if (event.isCanceled()) ++ net.minecraftforge.event.entity.player.PlayerInteractEvent event = ForgeEventFactory.onPlayerInteract(this.thisPlayerMP, net.minecraftforge.event.entity.player.PlayerInteractEvent.Action.LEFT_CLICK_BLOCK, p_73074_1_, p_73074_2_, p_73074_3_, p_73074_4_, theWorld); // Forge ++ ++ if (cbEvent.isCancelled() || event.isCanceled()) + { +- thisPlayerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73074_1_, p_73074_2_, p_73074_3_, theWorld)); ++ // Let the client know the block still exists ++ ((EntityPlayerMP) this.thisPlayerMP).playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73074_1_, p_73074_2_, p_73074_3_, this.theWorld)); ++ // Update any tile entity data for this block ++ TileEntity tileentity = this.theWorld.getTileEntity(p_73074_1_, p_73074_2_, p_73074_3_); ++ ++ if (tileentity != null) ++ { ++ this.thisPlayerMP.playerNetServerHandler.sendPacket(tileentity.getDescriptionPacket()); ++ } ++ + return; + } + ++ // CraftBukkit end + if (this.isCreative()) + { + if (!this.theWorld.extinguishFire((EntityPlayer)null, p_73074_1_, p_73074_2_, p_73074_3_, p_73074_4_)) +@@ -157,30 +187,56 @@ + float f = 1.0F; + Block block = this.theWorld.getBlock(p_73074_1_, p_73074_2_, p_73074_3_); + +- +- if (!block.isAir(theWorld, p_73074_1_, p_73074_2_, p_73074_3_)) ++ // CraftBukkit start - Swings at air do *NOT* exist. ++ if (cbEvent.useInteractedBlock() == org.bukkit.event.Event.Result.DENY || event.useBlock == cpw.mods.fml.common.eventhandler.Event.Result.DENY) // Cauldron + { +- if (event.useBlock != Event.Result.DENY) ++ // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. ++ if (block == Blocks.wooden_door) + { +- block.onBlockClicked(theWorld, p_73074_1_, p_73074_2_, p_73074_3_, thisPlayerMP); +- theWorld.extinguishFire(null, p_73074_1_, p_73074_2_, p_73074_3_, p_73074_4_); ++ // For some reason *BOTH* the bottom/top part have to be marked updated. ++ boolean bottom = (this.theWorld.getBlockMetadata(p_73074_1_, p_73074_2_, p_73074_3_) & 8) == 0; ++ ((EntityPlayerMP) this.thisPlayerMP).playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73074_1_, p_73074_2_, p_73074_3_, this.theWorld)); ++ ((EntityPlayerMP) this.thisPlayerMP).playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73074_1_, p_73074_2_ + (bottom ? 1 : -1), p_73074_3_, this.theWorld)); + } +- else ++ else if (block == Blocks.trapdoor) + { +- thisPlayerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73074_1_, p_73074_2_, p_73074_3_, theWorld)); ++ ((EntityPlayerMP) this.thisPlayerMP).playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73074_1_, p_73074_2_, p_73074_3_, this.theWorld)); + } +- f = block.getPlayerRelativeBlockHardness(thisPlayerMP, thisPlayerMP.worldObj, p_73074_1_, p_73074_2_, p_73074_3_); + } +- +- if (event.useItem == Event.Result.DENY) ++ else if (!block.isAir(theWorld, p_73074_1_, p_73074_2_, p_73074_3_)) + { +- if (f >= 1.0f) ++ block.onBlockClicked(this.theWorld, p_73074_1_, p_73074_2_, p_73074_3_, this.thisPlayerMP); ++ f = block.getPlayerRelativeBlockHardness(this.thisPlayerMP, this.thisPlayerMP.worldObj, p_73074_1_, p_73074_2_, p_73074_3_); ++ // Allow fire punching to be blocked ++ this.theWorld.extinguishFire((EntityPlayer) null, p_73074_1_, p_73074_2_, p_73074_3_, p_73074_4_); ++ } ++ if (cbEvent.useItemInHand() == org.bukkit.event.Event.Result.DENY || event.useItem == cpw.mods.fml.common.eventhandler.Event.Result.DENY) // Forge ++ { ++ // If we 'insta destroyed' then the client needs to be informed. ++ if (f > 1.0f) + { +- thisPlayerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73074_1_, p_73074_2_, p_73074_3_, theWorld)); ++ ((EntityPlayerMP) this.thisPlayerMP).playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73074_1_, p_73074_2_, p_73074_3_, this.theWorld)); + } ++ + return; + } + ++ org.bukkit.event.block.BlockDamageEvent blockEvent = CraftEventFactory.callBlockDamageEvent(this.thisPlayerMP, p_73074_1_, p_73074_2_, p_73074_3_, this.thisPlayerMP.inventory.getCurrentItem(), f >= 1.0f); ++ ++ if (blockEvent.isCancelled()) ++ { ++ // Let the client know the block still exists ++ ((EntityPlayerMP) this.thisPlayerMP).playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73074_1_, p_73074_2_, p_73074_3_, this.theWorld)); ++ return; ++ } ++ ++ if (blockEvent.getInstaBreak()) ++ { ++ f = 2.0f; ++ } ++ ++ // CraftBukkit end ++ + if (!block.isAir(theWorld, p_73074_1_, p_73074_2_, p_73074_3_) && f >= 1.0F) + { + this.tryHarvestBlock(p_73074_1_, p_73074_2_, p_73074_3_); +@@ -269,6 +325,12 @@ + return false; + } + Block block = this.theWorld.getBlock(p_73084_1_, p_73084_2_, p_73084_3_); ++ ++ if (block == Blocks.air) ++ { ++ return false; // CraftBukkit - A plugin set block to air without cancelling ++ } ++ + int l = this.theWorld.getBlockMetadata(p_73084_1_, p_73084_2_, p_73084_3_); + this.theWorld.playAuxSFXAtEntity(this.thisPlayerMP, 2001, p_73084_1_, p_73084_2_, p_73084_3_, Block.getIdFromBlock(block) + (this.theWorld.getBlockMetadata(p_73084_1_, p_73084_2_, p_73084_3_) << 12)); + boolean flag = false; +@@ -350,57 +412,104 @@ + + public boolean activateBlockOrUseItem(EntityPlayer p_73078_1_, World p_73078_2_, ItemStack p_73078_3_, int p_73078_4_, int p_73078_5_, int p_73078_6_, int p_73078_7_, float p_73078_8_, float p_73078_9_, float p_73078_10_) + { +- PlayerInteractEvent event = ForgeEventFactory.onPlayerInteract(p_73078_1_, Action.RIGHT_CLICK_BLOCK, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_7_, p_73078_2_); +- if (event.isCanceled()) +- { +- thisPlayerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73078_4_, p_73078_5_, p_73078_6_, theWorld)); +- return false; +- } +- +- if (p_73078_3_ != null && p_73078_3_.getItem().onItemUseFirst(p_73078_3_, p_73078_1_, p_73078_2_, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_7_, p_73078_8_, p_73078_9_, p_73078_10_)) +- { +- if (p_73078_3_.stackSize <= 0) ForgeEventFactory.onPlayerDestroyItem(thisPlayerMP, p_73078_3_); +- return true; +- } +- ++ // CraftBukkit start - Interact + Block block = p_73078_2_.getBlock(p_73078_4_, p_73078_5_, p_73078_6_); +- boolean isAir = block.isAir(p_73078_2_, p_73078_4_, p_73078_5_, p_73078_6_); +- boolean useBlock = !p_73078_1_.isSneaking() || p_73078_1_.getHeldItem() == null; +- if (!useBlock) useBlock = p_73078_1_.getHeldItem().getItem().doesSneakBypassUse(p_73078_2_, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_1_); ++ boolean isAir = block.isAir(p_73078_2_, p_73078_4_, p_73078_5_, p_73078_6_); // Cauldron + boolean result = false; + +- if (useBlock) ++ if (!isAir) + { +- if (event.useBlock != Event.Result.DENY) ++ org.bukkit.event.player.PlayerInteractEvent event = CraftEventFactory.callPlayerInteractEvent(p_73078_1_, org.bukkit.event.block.Action.RIGHT_CLICK_BLOCK, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_7_, p_73078_3_); ++ net.minecraftforge.event.entity.player.PlayerInteractEvent forgeEvent = ForgeEventFactory.onPlayerInteract(p_73078_1_, net.minecraftforge.event.entity.player.PlayerInteractEvent.Action.RIGHT_CLICK_BLOCK, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_7_, p_73078_2_); ++ // Cauldron start ++ // if forge event is explicitly cancelled, return ++ if (forgeEvent.isCanceled()) + { ++ thisPlayerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73078_4_, p_73078_5_, p_73078_6_, theWorld)); ++ return false; ++ } ++ // if we have no explicit deny, check if item can be used ++ if (event.useItemInHand() != org.bukkit.event.Event.Result.DENY && forgeEvent.useItem != cpw.mods.fml.common.eventhandler.Event.Result.DENY) ++ { ++ Item item = (p_73078_3_ != null ? p_73078_3_.getItem() : null); ++ // try to use an item in hand before activating a block. Used for items such as IC2's wrench. ++ if (item != null && item.onItemUseFirst(p_73078_3_, p_73078_1_, p_73078_2_, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_7_, p_73078_8_, p_73078_9_, p_73078_10_)) ++ { ++ if (p_73078_3_.stackSize <= 0) ForgeEventFactory.onPlayerDestroyItem(thisPlayerMP, p_73078_3_); ++ return true; ++ } ++ } ++ // Cauldron end ++ if (event.useInteractedBlock() == org.bukkit.event.Event.Result.DENY || forgeEvent.useBlock == cpw.mods.fml.common.eventhandler.Event.Result.DENY) ++ { ++ // If we denied a door from opening, we need to send a correcting update to the client, as it already opened the door. ++ if (block == Blocks.wooden_door) ++ { ++ boolean bottom = (p_73078_2_.getBlockMetadata(p_73078_4_, p_73078_5_, p_73078_6_) & 8) == 0; ++ ((EntityPlayerMP) p_73078_1_).playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73078_4_, p_73078_5_ + (bottom ? 1 : -1), p_73078_6_, p_73078_2_)); ++ } ++ ++ result = (event.useItemInHand() != org.bukkit.event.Event.Result.ALLOW); ++ } ++ else if (!p_73078_1_.isSneaking() || p_73078_3_ == null || p_73078_1_.getHeldItem().getItem().doesSneakBypassUse(p_73078_2_, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_1_)) ++ { + result = block.onBlockActivated(p_73078_2_, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_1_, p_73078_7_, p_73078_8_, p_73078_9_, p_73078_10_); ++ // Cauldron start - if bukkitView is null, create one. Required for Ender Chests since they do not use NetworkRegistry.openRemoteGUI ++ if (thisPlayerMP != null && !(thisPlayerMP.openContainer instanceof ContainerPlayer)) ++ { ++ if (thisPlayerMP.openContainer.getBukkitView() == null) ++ { ++ TileEntity te = thisPlayerMP.worldObj.getTileEntity(p_73078_4_, p_73078_5_, p_73078_6_); ++ if (te != null && te instanceof IInventory) ++ { ++ IInventory teInv = (IInventory)te; ++ CraftInventory inventory = new CraftInventory(teInv); ++ thisPlayerMP.openContainer.bukkitView = new CraftInventoryView(thisPlayerMP.getBukkitEntity(), inventory, thisPlayerMP.openContainer); ++ } ++ else ++ { ++ thisPlayerMP.openContainer.bukkitView = new CraftInventoryView(thisPlayerMP.getBukkitEntity(), MinecraftServer.getServer().server.createInventory(thisPlayerMP.getBukkitEntity(), InventoryType.CHEST), thisPlayerMP.openContainer); ++ } ++ ++ thisPlayerMP.openContainer = CraftEventFactory.callInventoryOpenEvent(thisPlayerMP, thisPlayerMP.openContainer, false); ++ if (thisPlayerMP.openContainer == null) ++ { ++ thisPlayerMP.openContainer = thisPlayerMP.inventoryContainer; ++ return false; ++ } ++ } ++ } ++ // Cauldron end + } +- else ++ ++ if (p_73078_3_ != null && !result) + { +- thisPlayerMP.playerNetServerHandler.sendPacket(new S23PacketBlockChange(p_73078_4_, p_73078_5_, p_73078_6_, theWorld)); +- result = event.useItem != Event.Result.ALLOW; ++ int meta = p_73078_3_.getItemDamage(); ++ int size = p_73078_3_.stackSize; ++ result = p_73078_3_.tryPlaceItemIntoWorld(p_73078_1_, p_73078_2_, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_7_, p_73078_8_, p_73078_9_, p_73078_10_); ++ ++ // The item count should not decrement in Creative mode. ++ if (this.isCreative()) ++ { ++ p_73078_3_.setItemDamage(meta); ++ p_73078_3_.stackSize = size; ++ } ++ ++ if (p_73078_3_.stackSize <= 0) ++ { ++ ForgeEventFactory.onPlayerDestroyItem(this.thisPlayerMP, p_73078_3_); ++ } + } +- } + +- if (p_73078_3_ != null && !result && event.useItem != Event.Result.DENY) +- { +- int meta = p_73078_3_.getItemDamage(); +- int size = p_73078_3_.stackSize; +- result = p_73078_3_.tryPlaceItemIntoWorld(p_73078_1_, p_73078_2_, p_73078_4_, p_73078_5_, p_73078_6_, p_73078_7_, p_73078_8_, p_73078_9_, p_73078_10_); +- if (isCreative()) ++ // If we have 'true' and no explicit deny *or* an explicit allow -- run the item part of the hook ++ if (p_73078_3_ != null && ((!result && event.useItemInHand() != org.bukkit.event.Event.Result.DENY) || event.useItemInHand() == org.bukkit.event.Event.Result.ALLOW)) + { +- p_73078_3_.setItemDamage(meta); +- p_73078_3_.stackSize = size; ++ this.tryUseItem(p_73078_1_, p_73078_2_, p_73078_3_); + } +- if (p_73078_3_.stackSize <= 0) ForgeEventFactory.onPlayerDestroyItem(thisPlayerMP, p_73078_3_); + } + +- /* Re-enable if this causes bukkit incompatibility, or re-write client side to only send a single packet per right click. +- if (par3ItemStack != null && ((!result && event.useItem != Event.Result.DENY) || event.useItem == Event.Result.ALLOW)) +- { +- this.tryUseItem(thisPlayerMP, par2World, par3ItemStack); +- }*/ + return result; ++ // CraftBukkit end + } + + public void setWorld(WorldServer p_73080_1_) diff --git a/patches/net/minecraft/server/management/PlayerManager.java.patch b/patches/net/minecraft/server/management/PlayerManager.java.patch new file mode 100644 index 0000000..5aee6ec --- /dev/null +++ b/patches/net/minecraft/server/management/PlayerManager.java.patch @@ -0,0 +1,132 @@ +--- ../src-base/minecraft/net/minecraft/server/management/PlayerManager.java ++++ ../src-work/minecraft/net/minecraft/server/management/PlayerManager.java +@@ -18,17 +18,23 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++//CraftBukkit start ++import java.util.Collections; ++import java.util.Queue; ++// CraftBukkit end ++ + public class PlayerManager + { + private static final Logger field_152627_a = LogManager.getLogger(); + private final WorldServer theWorldServer; + private final List players = new ArrayList(); + private final LongHashMap playerInstances = new LongHashMap(); +- private final List chunkWatcherWithPlayers = new ArrayList(); +- private final List playerInstanceList = new ArrayList(); ++ private final Queue chunkWatcherWithPlayers = new java.util.concurrent.ConcurrentLinkedQueue(); // CraftBukkit ArrayList -> ConcurrentLinkedQueue ++ private final Queue playerInstanceList = new java.util.concurrent.ConcurrentLinkedQueue(); // CraftBukkit ArrayList -> ConcurrentLinkedQueue + private int playerViewRadius; + private long previousTotalWorldTime; + private final int[][] xzDirectionsConst = new int[][] {{1, 0}, {0, 1}, { -1, 0}, {0, -1}}; ++ private boolean wasNotEmpty; // CraftBukkit + private static final String __OBFID = "CL_00001434"; + + public PlayerManager(WorldServer p_i1176_1_) +@@ -37,6 +43,14 @@ + this.func_152622_a(p_i1176_1_.func_73046_m().getConfigurationManager().getViewDistance()); + } + ++ // Cauldron start - vanilla compatibility ++ public PlayerManager(WorldServer p_i1176_1_, int viewDistance /* Spigot */) ++ { ++ this.theWorldServer = p_i1176_1_; ++ this.func_152622_a(viewDistance); // Spigot ++ } ++ // Cauldron end ++ + public WorldServer getWorldServer() + { + return this.theWorldServer; +@@ -51,34 +65,53 @@ + if (i - this.previousTotalWorldTime > 8000L) + { + this.previousTotalWorldTime = i; ++ // CraftBukkit start - Use iterator ++ java.util.Iterator iterator = this.playerInstanceList.iterator(); + +- for (j = 0; j < this.playerInstanceList.size(); ++j) ++ while (iterator.hasNext()) + { +- playerinstance = (PlayerManager.PlayerInstance)this.playerInstanceList.get(j); ++ playerinstance = (PlayerManager.PlayerInstance)iterator.next(); + playerinstance.sendChunkUpdate(); + playerinstance.processChunk(); + } + } + else + { +- for (j = 0; j < this.chunkWatcherWithPlayers.size(); ++j) ++ java.util.Iterator iterator = this.chunkWatcherWithPlayers.iterator(); ++ ++ while (iterator.hasNext()) + { +- playerinstance = (PlayerManager.PlayerInstance)this.chunkWatcherWithPlayers.get(j); ++ playerinstance = (PlayerManager.PlayerInstance)iterator.next(); + playerinstance.sendChunkUpdate(); ++ iterator.remove(); ++ // CraftBukkit end + } + } + +- this.chunkWatcherWithPlayers.clear(); ++ // this.chunkWatcherWithPlayers.clear(); // CraftBukkit - Removals are already covered + + if (this.players.isEmpty()) + { ++ if (!wasNotEmpty) ++ { ++ return; // CraftBukkit - Only do unload when we go from non-empty to empty ++ } ++ + WorldProvider worldprovider = this.theWorldServer.provider; + + if (!worldprovider.canRespawnHere()) + { + this.theWorldServer.theChunkProviderServer.unloadAllChunks(); + } ++ ++ // CraftBukkit start ++ wasNotEmpty = false; + } ++ else ++ { ++ wasNotEmpty = true; ++ } ++ // CraftBukkit end + } + + public boolean func_152621_a(int p_152621_1_, int p_152621_2_) +@@ -102,6 +135,20 @@ + return playerinstance; + } + ++ // CraftBukkit start ++ public final boolean isChunkInUse(int x, int z) ++ { ++ PlayerManager.PlayerInstance pi = getOrCreateChunkWatcher(x, z, false); ++ ++ if (pi != null) ++ { ++ return (pi.playersWatchingChunk.size() > 0); ++ } ++ ++ return false; ++ } ++ // CraftBukkit end ++ + public void markBlockForUpdate(int p_151250_1_, int p_151250_2_, int p_151250_3_) + { + int l = p_151250_1_ >> 4; +@@ -541,7 +588,7 @@ + { + i = this.chunkLocation.chunkXPos * 16; + j = this.chunkLocation.chunkZPos * 16; +- this.sendToAllPlayersWatchingChunk(new S21PacketChunkData(PlayerManager.this.theWorldServer.getChunkFromChunkCoords(this.chunkLocation.chunkXPos, this.chunkLocation.chunkZPos), false, this.flagsYAreasToUpdate)); ++ this.sendToAllPlayersWatchingChunk(new S21PacketChunkData(PlayerManager.this.theWorldServer.getChunkFromChunkCoords(this.chunkLocation.chunkXPos, this.chunkLocation.chunkZPos), (this.flagsYAreasToUpdate == 0xFFFF), this.flagsYAreasToUpdate)); // CraftBukkit - send everything (including biome) if all sections flagged + + // Forge: Grabs ALL tile entities is costly on a modded server, only send needed ones + for (k = 0; false && k < 16; ++k) diff --git a/patches/net/minecraft/server/management/ServerConfigurationManager.java.patch b/patches/net/minecraft/server/management/ServerConfigurationManager.java.patch new file mode 100644 index 0000000..abfe0c6 --- /dev/null +++ b/patches/net/minecraft/server/management/ServerConfigurationManager.java.patch @@ -0,0 +1,1052 @@ +--- ../src-base/minecraft/net/minecraft/server/management/ServerConfigurationManager.java ++++ ../src-work/minecraft/net/minecraft/server/management/ServerConfigurationManager.java +@@ -6,6 +6,8 @@ + import com.mojang.authlib.GameProfile; + + import cpw.mods.fml.common.FMLCommonHandler; ++import cpw.mods.fml.common.network.FMLEmbeddedChannel; ++import cpw.mods.fml.common.network.FMLOutboundHandler; + import cpw.mods.fml.relauncher.Side; + import cpw.mods.fml.relauncher.SideOnly; + import java.io.File; +@@ -58,15 +60,37 @@ + import net.minecraft.world.Teleporter; + import net.minecraft.world.World; + import net.minecraft.world.WorldProvider; ++import net.minecraft.world.WorldProviderEnd; + import net.minecraft.world.WorldServer; + import net.minecraft.world.WorldSettings; + import net.minecraft.world.demo.DemoWorldManager; + import net.minecraft.world.storage.IPlayerFileData; ++import net.minecraftforge.common.DimensionManager; + import net.minecraftforge.common.chunkio.ChunkIOExecutor; ++import net.minecraftforge.common.network.ForgeMessage; ++import net.minecraftforge.common.network.ForgeNetworkHandler; + + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import net.minecraft.server.network.NetHandlerLoginServer; ++import org.bukkit.craftbukkit.CraftServer; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.Bukkit; ++import org.bukkit.Location; ++import org.bukkit.TravelAgent; ++import org.bukkit.entity.Player; ++import org.bukkit.event.player.PlayerChangedWorldEvent; ++import org.bukkit.event.player.PlayerPortalEvent; ++import org.bukkit.event.player.PlayerJoinEvent; ++import org.bukkit.event.player.PlayerLoginEvent; ++import org.bukkit.event.player.PlayerQuitEvent; ++import org.bukkit.event.player.PlayerRespawnEvent; ++import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; ++import org.bukkit.util.Vector; ++// CraftBukkit end ++ + public abstract class ServerConfigurationManager + { + public static final File field_152613_a = new File("banned-players.json"); +@@ -82,8 +106,8 @@ + private final UserListOps ops; + private final UserListWhitelist whiteListedPlayers; + private final Map field_148547_k; +- private IPlayerFileData playerNBTManagerObj; +- private boolean whiteListEnforced; ++ public IPlayerFileData playerNBTManagerObj; // CraftBukkit - private -> public ++ public boolean whiteListEnforced; // CraftBukkit - private -> public + protected int maxPlayers; + private int viewDistance; + private WorldSettings.GameType gameType; +@@ -91,8 +115,16 @@ + private int playerPingIndex; + private static final String __OBFID = "CL_00001423"; + ++ // CraftBukkit start ++ private CraftServer cserver; ++ + public ServerConfigurationManager(MinecraftServer p_i1500_1_) + { ++ p_i1500_1_.server = new CraftServer(p_i1500_1_, this); ++ p_i1500_1_.console = org.bukkit.craftbukkit.command.ColouredConsoleSender.getInstance(); ++ p_i1500_1_.reader.addCompleter(new org.bukkit.craftbukkit.command.ConsoleCommandCompleter(p_i1500_1_.server)); ++ this.cserver = p_i1500_1_.server; ++ // CraftBukkit end + this.bannedPlayers = new UserListBans(field_152613_a); + this.bannedIPs = new BanList(field_152614_b); + this.ops = new UserListOps(field_152615_c); +@@ -131,12 +163,32 @@ + s1 = p_72355_1_.getSocketAddress().toString(); + } + +- logger.info(p_72355_2_.getCommandSenderName() + "[" + s1 + "] logged in with entity id " + p_72355_2_.getEntityId() + " at (" + p_72355_2_.posX + ", " + p_72355_2_.posY + ", " + p_72355_2_.posZ + ")"); ++ // CraftBukkit - add world to 'logged in' message. ++ logger.info(p_72355_2_.getCommandSenderName() + "[" + s1 + "] logged in with entity id " + p_72355_2_.getEntityId() + " at ([" + p_72355_2_.worldObj.worldInfo.getWorldName() + "] " + p_72355_2_.posX + ", " + p_72355_2_.posY + ", " + p_72355_2_.posZ + ")"); + WorldServer worldserver = this.mcServer.worldServerForDimension(p_72355_2_.dimension); + ChunkCoordinates chunkcoordinates = worldserver.getSpawnPoint(); + this.func_72381_a(p_72355_2_, (EntityPlayerMP)null, worldserver); + p_72355_2_.playerNetServerHandler = nethandlerplayserver; ++ // CraftBukkit start -- Don't send a higher than 60 MaxPlayer size, otherwise the PlayerInfo window won't render correctly. ++ int maxPlayers = this.getMaxPlayers(); ++ ++ if (maxPlayers > 60) ++ { ++ maxPlayers = 60; ++ } ++ // CraftBukkit end ++ ++ // Cauldron start - send DimensionRegisterMessage to client before attempting to login to a Bukkit dimension ++ if (DimensionManager.isBukkitDimension(p_72355_2_.dimension)) ++ { ++ FMLEmbeddedChannel serverChannel = ForgeNetworkHandler.getServerChannel(); ++ serverChannel.attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER); ++ serverChannel.attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(p_72355_2_); ++ serverChannel.writeOutbound(new ForgeMessage.DimensionRegisterMessage(p_72355_2_.dimension, worldserver.getWorld().getEnvironment().getId())); ++ } ++ // Cauldron end + nethandlerplayserver.sendPacket(new S01PacketJoinGame(p_72355_2_.getEntityId(), p_72355_2_.theItemInWorldManager.getGameType(), worldserver.getWorldInfo().isHardcoreModeEnabled(), worldserver.provider.dimensionId, worldserver.difficultySetting, this.getMaxPlayers(), worldserver.getWorldInfo().getTerrainType())); ++ p_72355_2_.getBukkitEntity().sendSupportedChannels(); // CraftBukkit + nethandlerplayserver.sendPacket(new S3FPacketCustomPayload("MC|Brand", this.getServerInstance().getServerModName().getBytes(Charsets.UTF_8))); + nethandlerplayserver.sendPacket(new S05PacketSpawnPosition(chunkcoordinates.posX, chunkcoordinates.posY, chunkcoordinates.posZ)); + nethandlerplayserver.sendPacket(new S39PacketPlayerAbilities(p_72355_2_.capabilities)); +@@ -145,6 +197,7 @@ + p_72355_2_.func_147099_x().func_150884_b(p_72355_2_); + this.func_96456_a((ServerScoreboard)worldserver.getScoreboard(), p_72355_2_); + this.mcServer.func_147132_au(); ++ /* CraftBukkit start - login message is handled in the event + ChatComponentTranslation chatcomponenttranslation; + + if (!p_72355_2_.getCommandSenderName().equalsIgnoreCase(s)) +@@ -158,6 +211,7 @@ + + chatcomponenttranslation.getChatStyle().setColor(EnumChatFormatting.YELLOW); + this.sendChatMsg(chatcomponenttranslation); ++ // CraftBukkit end*/ + this.playerLoggedIn(p_72355_2_); + nethandlerplayserver.setPlayerLocation(p_72355_2_.posX, p_72355_2_.posY, p_72355_2_.posZ, p_72355_2_.rotationYaw, p_72355_2_.rotationPitch); + this.updateTimeAndWeatherForPlayer(p_72355_2_, worldserver); +@@ -192,7 +246,7 @@ + } + } + +- protected void func_96456_a(ServerScoreboard p_96456_1_, EntityPlayerMP p_96456_2_) ++ public void func_96456_a(ServerScoreboard p_96456_1_, EntityPlayerMP p_96456_2_) // CraftBukkit - protected -> public + { + HashSet hashset = new HashSet(); + Iterator iterator = p_96456_1_.getTeams().iterator(); +@@ -225,6 +279,11 @@ + + public void setPlayerManager(WorldServer[] p_72364_1_) + { ++ if (this.playerNBTManagerObj != null) ++ { ++ return; // CraftBukkit ++ } ++ + this.playerNBTManagerObj = p_72364_1_[0].getSaveHandler().getSaveHandler(); + } + +@@ -248,7 +307,7 @@ + + public NBTTagCompound readPlayerDataFromFile(EntityPlayerMP p_72380_1_) + { +- NBTTagCompound nbttagcompound = this.mcServer.worldServers[0].getWorldInfo().getPlayerNBTTagCompound(); ++ NBTTagCompound nbttagcompound = this.mcServer.worlds.get(0).getWorldInfo().getPlayerNBTTagCompound(); + NBTTagCompound nbttagcompound1; + + if (p_72380_1_.getCommandSenderName().equals(this.mcServer.getServerOwner()) && nbttagcompound != null) +@@ -281,18 +340,61 @@ + + public void playerLoggedIn(EntityPlayerMP p_72377_1_) + { +- this.sendPacketToAllPlayers(new S38PacketPlayerListItem(p_72377_1_.getCommandSenderName(), true, 1000)); ++ cserver.detectListNameConflict(p_72377_1_); // CraftBukkit ++ // this.sendPacketToAllPlayers(new S38PacketPlayerListItem(p_72377_1_.getCommandSenderName(), true, 1000)); // CraftBukkit - replaced with loop below + this.playerEntityList.add(p_72377_1_); + WorldServer worldserver = this.mcServer.worldServerForDimension(p_72377_1_.dimension); ++ // CraftBukkit start ++ PlayerJoinEvent playerJoinEvent = new PlayerJoinEvent(this.cserver.getPlayer(p_72377_1_), "\u00A7e" + p_72377_1_.getCommandSenderName() ++ + " joined the game."); ++ this.cserver.getPluginManager().callEvent(playerJoinEvent); ++ String joinMessage = playerJoinEvent.getJoinMessage(); ++ ++ if ((joinMessage != null) && (joinMessage.length() > 0)) ++ { ++ for (IChatComponent line : org.bukkit.craftbukkit.util.CraftChatMessage.fromString(joinMessage)) ++ { ++ this.mcServer.getConfigurationManager().sendPacketToAllPlayers(new S02PacketChat(line)); ++ } ++ } ++ ++ this.cserver.onPlayerJoin(playerJoinEvent.getPlayer()); + ChunkIOExecutor.adjustPoolSize(this.getCurrentPlayerCount()); +- worldserver.spawnEntityInWorld(p_72377_1_); +- this.func_72375_a(p_72377_1_, (WorldServer)null); ++ // CraftBukkit end ++ // CraftBukkit start - Only add if the player wasn't moved in the event ++ if (p_72377_1_.worldObj == worldserver && !worldserver.playerEntities.contains(p_72377_1_)) ++ { ++ worldserver.spawnEntityInWorld(p_72377_1_); ++ this.func_72375_a(p_72377_1_, (WorldServer) null); ++ } ++ // CraftBukkit end ++ // CraftBukkit start - sendAll above replaced with this loop ++ S38PacketPlayerListItem packet = new S38PacketPlayerListItem(p_72377_1_.listName, true, 1000); + + for (int i = 0; i < this.playerEntityList.size(); ++i) + { +- EntityPlayerMP entityplayermp1 = (EntityPlayerMP)this.playerEntityList.get(i); +- p_72377_1_.playerNetServerHandler.sendPacket(new S38PacketPlayerListItem(entityplayermp1.getCommandSenderName(), true, entityplayermp1.ping)); ++ EntityPlayerMP entityplayermp1 = (EntityPlayerMP) this.playerEntityList.get(i); ++ ++ if (entityplayermp1.getBukkitEntity().canSee(p_72377_1_.getBukkitEntity())) ++ { ++ entityplayermp1.playerNetServerHandler.sendPacket(packet); ++ } + } ++ // CraftBukkit end ++ for (int i = 0; i < this.playerEntityList.size(); ++i) ++ { ++ EntityPlayerMP entityplayermp1 = (EntityPlayerMP) this.playerEntityList.get(i); ++ ++ // CraftBukkit start ++ if (!p_72377_1_.getBukkitEntity().canSee(entityplayermp1.getBukkitEntity())) ++ { ++ continue; ++ } ++ ++ // .name -> .listName ++ p_72377_1_.playerNetServerHandler.sendPacket(new S38PacketPlayerListItem(entityplayermp1.listName, true, entityplayermp1.ping)); ++ // CraftBukkit end ++ } + } + + public void updatePlayerPertinentChunks(EntityPlayerMP p_72358_1_) +@@ -300,14 +402,33 @@ + p_72358_1_.getServerForPlayer().getPlayerManager().updatePlayerPertinentChunks(p_72358_1_); + } + ++ // Cauldron start - vanilla compatibility + public void playerLoggedOut(EntityPlayerMP p_72367_1_) + { +- FMLCommonHandler.instance().firePlayerLoggedOut(p_72367_1_); ++ disconnect(p_72367_1_); ++ } ++ // Cauldron end ++ ++ public String disconnect(EntityPlayerMP p_72367_1_) // CraftBukkit - return string ++ { + p_72367_1_.triggerAchievement(StatList.leaveGameStat); ++ // Cauldron start - don't show quit messages for players that haven't actually connected ++ PlayerQuitEvent playerQuitEvent = null; ++ if (p_72367_1_.playerNetServerHandler != null) ++ { ++ // CraftBukkit start - Quitting must be before we do final save of data, in case plugins need to modify it ++ org.bukkit.craftbukkit.event.CraftEventFactory.handleInventoryCloseEvent(p_72367_1_); ++ playerQuitEvent = new PlayerQuitEvent(this.cserver.getPlayer(p_72367_1_), "\u00A7e" + p_72367_1_.getCommandSenderName() + " left the game."); ++ this.cserver.getPluginManager().callEvent(playerQuitEvent); ++ p_72367_1_.getBukkitEntity().disconnect(playerQuitEvent.getQuitMessage()); ++ // CraftBukkit end ++ } ++ // Cauldron end ++ FMLCommonHandler.instance().firePlayerLoggedOut(p_72367_1_); + this.writePlayerData(p_72367_1_); + WorldServer worldserver = p_72367_1_.getServerForPlayer(); + +- if (p_72367_1_.ridingEntity != null) ++ if (p_72367_1_.ridingEntity != null && !(p_72367_1_.ridingEntity instanceof EntityPlayerMP)) // CraftBukkit - Don't remove players + { + worldserver.removePlayerEntityDangerously(p_72367_1_.ridingEntity); + logger.debug("removing player mount"); +@@ -316,9 +437,35 @@ + worldserver.removeEntity(p_72367_1_); + worldserver.getPlayerManager().removePlayer(p_72367_1_); + this.playerEntityList.remove(p_72367_1_); +- this.field_148547_k.remove(p_72367_1_.getUniqueID()); +- net.minecraftforge.common.chunkio.ChunkIOExecutor.adjustPoolSize(this.getCurrentPlayerCount()); +- this.sendPacketToAllPlayers(new S38PacketPlayerListItem(p_72367_1_.getCommandSenderName(), false, 9999)); ++ this.field_148547_k.remove(p_72367_1_.getCommandSenderName()); ++ ChunkIOExecutor.adjustPoolSize(this.getCurrentPlayerCount()); // CraftBukkit ++ // CraftBukkit start - .name -> .listName, replace sendAll with loop ++ // this.sendAll(new PacketPlayOutPlayerInfo(entityplayermp.getName(), false, 9999)); ++ S38PacketPlayerListItem packet = new S38PacketPlayerListItem(p_72367_1_.listName, false, 9999); ++ ++ for (int i = 0; i < this.playerEntityList.size(); ++i) ++ { ++ EntityPlayerMP entityplayermp1 = (EntityPlayerMP) this.playerEntityList.get(i); ++ ++ if (entityplayermp1.getBukkitEntity().canSee(p_72367_1_.getBukkitEntity())) ++ { ++ entityplayermp1.playerNetServerHandler.sendPacket(packet); ++ } ++ } ++ ++ // This removes the scoreboard (and player reference) for the specific player in the manager ++ this.cserver.getScoreboardManager().removePlayer(p_72367_1_.getBukkitEntity()); ++ // Cauldron start ++ if (playerQuitEvent != null) ++ { ++ return playerQuitEvent.getQuitMessage(); ++ } ++ else ++ { ++ return null; ++ } ++ // Cauldron end ++ // CraftBukkit end + } + + public String allowUserToConnect(SocketAddress p_148542_1_, GameProfile p_148542_2_) +@@ -359,6 +506,71 @@ + } + } + ++ // CraftBukkit start - Whole method, SocketAddress to LoginListener, added hostname to signature, return EntityPlayer ++ public EntityPlayerMP attemptLogin(NetHandlerLoginServer loginlistener, GameProfile gameprofile, String hostname) ++ { ++ // Instead of kicking then returning, we need to store the kick reason ++ // in the event, check with plugins to see if it's ok, and THEN kick ++ // depending on the outcome. ++ SocketAddress socketaddress = loginlistener.field_147333_a.getSocketAddress(); ++ EntityPlayerMP entity = new EntityPlayerMP(this.mcServer, this.mcServer.worldServerForDimension(0), gameprofile, new ItemInWorldManager( ++ this.mcServer.worldServerForDimension(0))); ++ Player player = entity.getBukkitEntity(); ++ PlayerLoginEvent event = new PlayerLoginEvent(player, hostname, ((java.net.InetSocketAddress) socketaddress).getAddress(), ++ ((java.net.InetSocketAddress) loginlistener.field_147333_a.getRawAddress()).getAddress()); // Spigot ++ String s; ++ ++ if (this.bannedPlayers.func_152702_a(gameprofile) && !this.bannedPlayers.func_152683_b(gameprofile).hasBanExpired()) ++ { ++ UserListBansEntry banentry = (UserListBansEntry) this.bannedPlayers.func_152683_b(gameprofile); ++ s = "You are banned from this server!\nReason: " + banentry.getBanReason(); ++ ++ if (banentry.getBanEndDate() != null) ++ { ++ s = s + "\nYour ban will be removed on " + dateFormat.format(banentry.getBanEndDate()); ++ } ++ ++ // return s; ++ event.disallow(PlayerLoginEvent.Result.KICK_BANNED, s); ++ } ++ else if (!this.func_152607_e(gameprofile)) ++ { ++ // return "You are not white-listed on this server!"; ++ event.disallow(PlayerLoginEvent.Result.KICK_WHITELIST, org.spigotmc.SpigotConfig.whitelistMessage); // Spigot ++ } ++ else if (this.bannedIPs.func_152708_a(socketaddress) && !this.bannedPlayers.func_152683_b(gameprofile).hasBanExpired()) ++ { ++ IPBanEntry ipbanentry = this.bannedIPs.func_152709_b(socketaddress); ++ s = "Your IP address is banned from this server!\nReason: " + ipbanentry.getBanReason(); ++ ++ if (ipbanentry.getBanEndDate() != null) ++ { ++ s = s + "\nYour ban will be removed on " + dateFormat.format(ipbanentry.getBanEndDate()); ++ } ++ // return s; ++ event.disallow(PlayerLoginEvent.Result.KICK_BANNED, s); ++ } ++ else ++ { ++ // return this.players.size() >= this.maxPlayers ? "The server is full!" : null; ++ if (this.playerEntityList.size() >= this.maxPlayers) ++ { ++ event.disallow(PlayerLoginEvent.Result.KICK_FULL, org.spigotmc.SpigotConfig.serverFullMessage); // Spigot ++ } ++ } ++ ++ this.cserver.getPluginManager().callEvent(event); ++ ++ if (event.getResult() != PlayerLoginEvent.Result.ALLOWED) ++ { ++ loginlistener.func_147322_a(event.getKickMessage()); ++ return null; ++ } ++ ++ return entity; ++ // CraftBukkit end ++ } ++ + public EntityPlayerMP createPlayerForUser(GameProfile p_148545_1_) + { + UUID uuid = EntityPlayer.func_146094_a(p_148545_1_); +@@ -397,116 +609,316 @@ + return new EntityPlayerMP(this.mcServer, this.mcServer.worldServerForDimension(0), p_148545_1_, (ItemInWorldManager)object); + } + +- public EntityPlayerMP respawnPlayer(EntityPlayerMP p_72368_1_, int p_72368_2_, boolean p_72368_3_) ++ public EntityPlayerMP processLogin(GameProfile gameprofile, EntityPlayerMP player) // CraftBukkit - added EntityPlayer + { +- World world = mcServer.worldServerForDimension(p_72368_2_); +- if (world == null) ++ ArrayList arraylist = new ArrayList(); ++ EntityPlayerMP entityplayermp; ++ ++ for (int i = 0; i < this.playerEntityList.size(); ++i) + { +- p_72368_2_ = 0; ++ entityplayermp = (EntityPlayerMP) this.playerEntityList.get(i); ++ ++ if (entityplayermp.getCommandSenderName().equalsIgnoreCase(gameprofile.getName())) ++ { ++ arraylist.add(entityplayermp); ++ } + } +- else if (!world.provider.canRespawnHere()) ++ Iterator iterator = arraylist.iterator(); ++ ++ while (iterator.hasNext()) + { +- p_72368_2_ = world.provider.getRespawnDimension(p_72368_1_); ++ entityplayermp = (EntityPlayerMP) iterator.next(); ++ entityplayermp.playerNetServerHandler.kickPlayerFromServer("You logged in from another location"); + } + +- p_72368_1_.getServerForPlayer().getEntityTracker().removePlayerFromTrackers(p_72368_1_); +- p_72368_1_.getServerForPlayer().getEntityTracker().removeEntityFromAllTrackingPlayers(p_72368_1_); +- p_72368_1_.getServerForPlayer().getPlayerManager().removePlayer(p_72368_1_); +- this.playerEntityList.remove(p_72368_1_); +- this.mcServer.worldServerForDimension(p_72368_1_.dimension).removePlayerEntityDangerously(p_72368_1_); +- ChunkCoordinates chunkcoordinates = p_72368_1_.getBedLocation(p_72368_2_); +- boolean flag1 = p_72368_1_.isSpawnForced(p_72368_2_); +- p_72368_1_.dimension = p_72368_2_; ++ /* CraftBukkit start + Object object; + + if (this.mcServer.isDemo()) + { +- object = new DemoWorldManager(this.mcServer.worldServerForDimension(p_72368_1_.dimension)); ++ object = new DemoWorldManager(this.mcServer.worldServerForDimension(0)); + } + else + { +- object = new ItemInWorldManager(this.mcServer.worldServerForDimension(p_72368_1_.dimension)); ++ object = new ItemInWorldManager(this.mcServer.worldServerForDimension(0)); + } + +- EntityPlayerMP entityplayermp1 = new EntityPlayerMP(this.mcServer, this.mcServer.worldServerForDimension(p_72368_1_.dimension), p_72368_1_.getGameProfile(), (ItemInWorldManager)object); +- entityplayermp1.playerNetServerHandler = p_72368_1_.playerNetServerHandler; +- entityplayermp1.clonePlayer(p_72368_1_, p_72368_3_); +- entityplayermp1.dimension = p_72368_2_; +- entityplayermp1.setEntityId(p_72368_1_.getEntityId()); +- WorldServer worldserver = this.mcServer.worldServerForDimension(p_72368_1_.dimension); +- this.func_72381_a(entityplayermp1, p_72368_1_, worldserver); ++ return new EntityPlayerMP(this.mcServer, this.mcServer.worldServerForDimension(0), p_148545_1_, (ItemInWorldManager)object); ++ // */ ++ return player; ++ // CraftBukkit end ++ } ++ ++ // Cauldron start - refactor entire method for sanity. ++ public EntityPlayerMP respawnPlayer(EntityPlayerMP par1EntityPlayerMP, int par2, boolean par3) ++ { ++ return this.respawnPlayer(par1EntityPlayerMP, par2, par3, null); ++ } ++ ++ public EntityPlayerMP respawnPlayer(EntityPlayerMP par1EntityPlayerMP, int targetDimension, boolean returnFromEnd, Location location) ++ { ++ // Phase 1 - check if the player is allowed to respawn in same dimension ++ World world = mcServer.worldServerForDimension(targetDimension); ++ org.bukkit.World fromWorld = par1EntityPlayerMP.getBukkitEntity().getWorld(); ++ ++ if (world == null) ++ { ++ targetDimension = 0; ++ } ++ else if (location == null && !world.provider.canRespawnHere()) // ignore plugins ++ { ++ targetDimension = world.provider.getRespawnDimension(par1EntityPlayerMP); ++ } ++ ++ // Phase 2 - handle return from End ++ if (returnFromEnd) ++ { ++ WorldServer exitWorld = this.mcServer.worldServerForDimension(targetDimension); ++ Location enter = par1EntityPlayerMP.getBukkitEntity().getLocation(); ++ Location exit = null; ++ // THE_END -> NORMAL; use bed if available, otherwise default spawn ++ exit = ((org.bukkit.craftbukkit.entity.CraftPlayer) par1EntityPlayerMP.getBukkitEntity()).getBedSpawnLocation(); ++ ++ if (exit == null || ((CraftWorld) exit.getWorld()).getHandle().dimension != 0) ++ { ++ exit = exitWorld.getWorld().getSpawnLocation(); ++ } ++ PlayerPortalEvent event = new PlayerPortalEvent(par1EntityPlayerMP.getBukkitEntity(), enter, exit, org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT, ++ TeleportCause.END_PORTAL); ++ event.useTravelAgent(false); ++ Bukkit.getServer().getPluginManager().callEvent(event); ++ if (event.isCancelled() || event.getTo() == null) ++ { ++ return null; ++ } ++ } ++ ++ // Phase 3 - remove current player from current dimension ++ par1EntityPlayerMP.getServerForPlayer().getEntityTracker().removePlayerFromTrackers(par1EntityPlayerMP); ++ // par1EntityPlayerMP.getServerForPlayer().getEntityTracker().removeEntityFromAllTrackingPlayers(par1EntityPlayerMP); // CraftBukkit ++ par1EntityPlayerMP.getServerForPlayer().getPlayerManager().removePlayer(par1EntityPlayerMP); ++ this.playerEntityList.remove(par1EntityPlayerMP); ++ this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension).removePlayerEntityDangerously(par1EntityPlayerMP); ++ ++ // Phase 4 - handle bed spawn ++ ChunkCoordinates bedSpawnChunkCoords = par1EntityPlayerMP.getBedLocation(targetDimension); ++ boolean spawnForced = par1EntityPlayerMP.isSpawnForced(targetDimension); ++ par1EntityPlayerMP.dimension = targetDimension; ++ // CraftBukkit start ++ EntityPlayerMP entityplayermp1 = par1EntityPlayerMP; ++ entityplayermp1.setWorld(this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension)); // make sure to update reference for bed spawn logic ++ entityplayermp1.playerConqueredTheEnd = false; + ChunkCoordinates chunkcoordinates1; ++ boolean isBedSpawn = false; ++ org.bukkit.World toWorld = entityplayermp1.getBukkitEntity().getWorld(); + +- if (chunkcoordinates != null) ++ if (location == null) // use bed logic only if player respawns (player death) + { +- chunkcoordinates1 = EntityPlayer.verifyRespawnCoordinates(this.mcServer.worldServerForDimension(p_72368_1_.dimension), chunkcoordinates, flag1); ++ if (bedSpawnChunkCoords != null) // if player has a bed ++ { ++ chunkcoordinates1 = EntityPlayer.verifyRespawnCoordinates(this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension), ++ bedSpawnChunkCoords, spawnForced); + +- if (chunkcoordinates1 != null) ++ if (chunkcoordinates1 != null) ++ { ++ isBedSpawn = true; ++ entityplayermp1.setLocationAndAngles((double) ((float) chunkcoordinates1.posX + 0.5F), (double) ((float) chunkcoordinates1.posY + 0.1F), ++ (double) ((float) chunkcoordinates1.posZ + 0.5F), 0.0F, 0.0F); ++ entityplayermp1.setSpawnChunk(bedSpawnChunkCoords, spawnForced); ++ location = new Location(toWorld, bedSpawnChunkCoords.posX + 0.5, bedSpawnChunkCoords.posY, bedSpawnChunkCoords.posZ + 0.5); ++ } ++ else ++ // bed was not found (broken) ++ { ++ //entityplayermp1.setSpawnChunk(null, true); // CraftBukkit ++ entityplayermp1.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(0, 0)); ++ location = new Location(toWorld, toWorld.getSpawnLocation().getX(), toWorld.getSpawnLocation().getY(), toWorld.getSpawnLocation().getZ()); // use the spawnpoint as location ++ } ++ } ++ ++ if (location == null) + { +- entityplayermp1.setLocationAndAngles((double)((float)chunkcoordinates1.posX + 0.5F), (double)((float)chunkcoordinates1.posY + 0.1F), (double)((float)chunkcoordinates1.posZ + 0.5F), 0.0F, 0.0F); +- entityplayermp1.setSpawnChunk(chunkcoordinates, flag1); ++ location = new Location(toWorld, toWorld.getSpawnLocation().getX(), toWorld.getSpawnLocation().getY(), toWorld.getSpawnLocation().getZ()); // use the world spawnpoint as default location + } +- else ++ ++ Player respawnPlayer = this.cserver.getPlayer(entityplayermp1); ++ PlayerRespawnEvent respawnEvent = new PlayerRespawnEvent(respawnPlayer, location, isBedSpawn); ++ this.cserver.getPluginManager().callEvent(respawnEvent); ++ ++ if (!spawnForced) // mods override plugins + { +- entityplayermp1.playerNetServerHandler.sendPacket(new S2BPacketChangeGameState(0, 0.0F)); ++ location = respawnEvent.getRespawnLocation(); + } ++ ++ par1EntityPlayerMP.reset(); + } ++ else ++ // plugin ++ { ++ location.setWorld(this.mcServer.worldServerForDimension(targetDimension).getWorld()); ++ } + +- worldserver.theChunkProviderServer.loadChunk((int)entityplayermp1.posX >> 4, (int)entityplayermp1.posZ >> 4); ++ WorldServer targetWorld = ((CraftWorld) location.getWorld()).getHandle(); ++ entityplayermp1.setPositionAndRotation(location.getX(), location.getY(), location.getZ(), location.getYaw(), location.getPitch()); ++ // CraftBukkit end ++ targetWorld.theChunkProviderServer.loadChunk((int) entityplayermp1.posX >> 4, (int) entityplayermp1.posZ >> 4); + +- while (!worldserver.getCollidingBoundingBoxes(entityplayermp1, entityplayermp1.boundingBox).isEmpty()) ++ while (!targetWorld.getCollidingBoundingBoxes(entityplayermp1, entityplayermp1.boundingBox).isEmpty()) + { + entityplayermp1.setPosition(entityplayermp1.posX, entityplayermp1.posY + 1.0D, entityplayermp1.posZ); + } + +- entityplayermp1.playerNetServerHandler.sendPacket(new S07PacketRespawn(entityplayermp1.dimension, entityplayermp1.worldObj.difficultySetting, entityplayermp1.worldObj.getWorldInfo().getTerrainType(), entityplayermp1.theItemInWorldManager.getGameType())); +- chunkcoordinates1 = worldserver.getSpawnPoint(); +- entityplayermp1.playerNetServerHandler.setPlayerLocation(entityplayermp1.posX, entityplayermp1.posY, entityplayermp1.posZ, entityplayermp1.rotationYaw, entityplayermp1.rotationPitch); ++ // Phase 5 - Respawn player in new world ++ int actualDimension = targetWorld.provider.dimensionId; ++ // Cauldron - change dim for bukkit added dimensions ++ if (DimensionManager.isBukkitDimension(actualDimension)) ++ { ++ FMLEmbeddedChannel serverChannel = ForgeNetworkHandler.getServerChannel(); ++ serverChannel.attr(FMLOutboundHandler.FML_MESSAGETARGET).set(FMLOutboundHandler.OutboundTarget.PLAYER); ++ serverChannel.attr(FMLOutboundHandler.FML_MESSAGETARGETARGS).set(entityplayermp1); ++ serverChannel.writeOutbound(new ForgeMessage.DimensionRegisterMessage(actualDimension, targetWorld.getWorld().getEnvironment().getId())); ++ } ++ // Cauldron end ++ // CraftBukkit start ++ entityplayermp1.playerNetServerHandler.sendPacket(new S07PacketRespawn(actualDimension, targetWorld.difficultySetting, targetWorld.getWorldInfo() ++ .getTerrainType(), entityplayermp1.theItemInWorldManager.getGameType())); ++ entityplayermp1.setWorld(targetWorld); // in case plugin changed it ++ entityplayermp1.isDead = false; ++ entityplayermp1.playerNetServerHandler.teleport(new Location(targetWorld.getWorld(), entityplayermp1.posX, entityplayermp1.posY, entityplayermp1.posZ, ++ entityplayermp1.rotationYaw, entityplayermp1.rotationPitch)); ++ entityplayermp1.setSneaking(false); ++ chunkcoordinates1 = targetWorld.getSpawnPoint(); ++ // CraftBukkit end + entityplayermp1.playerNetServerHandler.sendPacket(new S05PacketSpawnPosition(chunkcoordinates1.posX, chunkcoordinates1.posY, chunkcoordinates1.posZ)); +- entityplayermp1.playerNetServerHandler.sendPacket(new S1FPacketSetExperience(entityplayermp1.experience, entityplayermp1.experienceTotal, entityplayermp1.experienceLevel)); +- this.updateTimeAndWeatherForPlayer(entityplayermp1, worldserver); +- worldserver.getPlayerManager().addPlayer(entityplayermp1); +- worldserver.spawnEntityInWorld(entityplayermp1); ++ entityplayermp1.playerNetServerHandler.sendPacket(new S1FPacketSetExperience(entityplayermp1.experience, entityplayermp1.experienceTotal, ++ entityplayermp1.experienceLevel)); ++ this.updateTimeAndWeatherForPlayer(entityplayermp1, targetWorld); ++ targetWorld.getPlayerManager().addPlayer(entityplayermp1); ++ targetWorld.spawnEntityInWorld(entityplayermp1); + this.playerEntityList.add(entityplayermp1); + entityplayermp1.addSelfToInternalCraftingInventory(); + entityplayermp1.setHealth(entityplayermp1.getHealth()); +- FMLCommonHandler.instance().firePlayerRespawnEvent(entityplayermp1); ++ // If world changed then fire the appropriate change world event else respawn ++ if (fromWorld != location.getWorld()) ++ { ++ FMLCommonHandler.instance().firePlayerChangedDimensionEvent(entityplayermp1, ((CraftWorld) fromWorld).getHandle().provider.dimensionId, ++ ((CraftWorld) location.getWorld()).getHandle().provider.dimensionId); // Cauldron - fire forge changed dimension event ++ } ++ else ++ FMLCommonHandler.instance().firePlayerRespawnEvent(entityplayermp1); + return entityplayermp1; + } + +- public void transferPlayerToDimension(EntityPlayerMP p_72356_1_, int p_72356_2_) ++ // Cauldron start - refactor transferPlayerToDimension to be compatible with Bukkit. These methods are to be used when a player comes in contact with a portal ++ public void transferPlayerToDimension(EntityPlayerMP p_72356_1_, int p_72356_2_) // wrapper for vanilla compatibility + { + transferPlayerToDimension(p_72356_1_, p_72356_2_, mcServer.worldServerForDimension(p_72356_2_).getDefaultTeleporter()); + } + +- public void transferPlayerToDimension(EntityPlayerMP p_72356_1_, int p_72356_2_, Teleporter teleporter) ++ public void transferPlayerToDimension(EntityPlayerMP p_72356_1_, int p_72356_2_, Teleporter teleporter) // mods such as Twilight Forest call this method directly + { +- int j = p_72356_1_.dimension; +- WorldServer worldserver = this.mcServer.worldServerForDimension(p_72356_1_.dimension); +- p_72356_1_.dimension = p_72356_2_; +- WorldServer worldserver1 = this.mcServer.worldServerForDimension(p_72356_1_.dimension); +- p_72356_1_.playerNetServerHandler.sendPacket(new S07PacketRespawn(p_72356_1_.dimension, worldserver1.difficultySetting, worldserver1.getWorldInfo().getTerrainType(), p_72356_1_.theItemInWorldManager.getGameType())); // Forge: Use new dimensions information +- worldserver.removePlayerEntityDangerously(p_72356_1_); +- p_72356_1_.isDead = false; +- this.transferEntityToWorld(p_72356_1_, j, worldserver, worldserver1, teleporter); +- this.func_72375_a(p_72356_1_, worldserver); +- p_72356_1_.playerNetServerHandler.setPlayerLocation(p_72356_1_.posX, p_72356_1_.posY, p_72356_1_.posZ, p_72356_1_.rotationYaw, p_72356_1_.rotationPitch); +- p_72356_1_.theItemInWorldManager.setWorld(worldserver1); +- this.updateTimeAndWeatherForPlayer(p_72356_1_, worldserver1); +- this.syncPlayerInventory(p_72356_1_); +- Iterator iterator = p_72356_1_.getActivePotionEffects().iterator(); ++ this.transferPlayerToDimension(p_72356_1_, p_72356_2_, teleporter, TeleportCause.MOD); // use our mod cause ++ } + ++ public void transferPlayerToDimension(EntityPlayerMP par1EntityPlayerMP, int par2, TeleportCause cause) ++ { ++ this.transferPlayerToDimension(par1EntityPlayerMP, par2, mcServer.worldServerForDimension(par2).getDefaultTeleporter(), cause); ++ } ++ ++ public void transferPlayerToDimension(EntityPlayerMP par1EntityPlayerMP, int targetDimension, Teleporter teleporter, TeleportCause cause) // Cauldron - add TeleportCause ++ { ++ // Allow Forge hotloading on teleport ++ WorldServer fromWorld = this.mcServer.worldServerForDimension(par1EntityPlayerMP.dimension); ++ WorldServer exitWorld = this.mcServer.worldServerForDimension(targetDimension); ++ ++ // CraftBukkit start - Replaced the standard handling of portals with a more customised method. ++ Location enter = par1EntityPlayerMP.getBukkitEntity().getLocation(); ++ Location exit = null; ++ boolean useTravelAgent = false; ++ ++ if (exitWorld != null) ++ { ++ exit = this.calculateTarget(enter, exitWorld); ++ if (cause != cause.MOD) // don't use travel agent for custom dimensions ++ { ++ useTravelAgent = true; ++ } ++ } ++ ++ // allow forge mods to be the teleporter ++ TravelAgent agent = null; ++ if (exit != null && teleporter == null) ++ { ++ teleporter = ((CraftWorld) exit.getWorld()).getHandle().getDefaultTeleporter(); ++ if (teleporter instanceof TravelAgent) ++ { ++ agent = (TravelAgent) teleporter; ++ } ++ } ++ else ++ { ++ if (teleporter instanceof TravelAgent) ++ { ++ agent = (TravelAgent) teleporter; ++ } ++ } ++ if (agent == null) // mod teleporter such as Twilight Forest ++ { ++ agent = org.bukkit.craftbukkit.CraftTravelAgent.DEFAULT; // return arbitrary TA to compensate for implementation dependent plugins ++ } ++ ++ PlayerPortalEvent event = new PlayerPortalEvent(par1EntityPlayerMP.getBukkitEntity(), enter, exit, agent, cause); ++ event.useTravelAgent(useTravelAgent); ++ Bukkit.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled() || event.getTo() == null) ++ { ++ return; ++ } ++ ++ exit = event.useTravelAgent() && cause != cause.MOD ? event.getPortalTravelAgent().findOrCreate(event.getTo()) : event.getTo(); // make sure plugins don't override travelagent for mods ++ ++ if (exit == null) ++ { ++ return; ++ } ++ ++ exitWorld = ((CraftWorld) exit.getWorld()).getHandle(); ++ Vector velocity = par1EntityPlayerMP.getBukkitEntity().getVelocity(); ++ boolean before = exitWorld.theChunkProviderServer.loadChunkOnProvideRequest; ++ exitWorld.theChunkProviderServer.loadChunkOnProvideRequest = true; ++ exitWorld.getDefaultTeleporter().adjustExit(par1EntityPlayerMP, exit, velocity); ++ exitWorld.theChunkProviderServer.loadChunkOnProvideRequest = before; ++ // CraftBukkit end ++ ++ par1EntityPlayerMP.dimension = targetDimension; ++ par1EntityPlayerMP.playerNetServerHandler.sendPacket(new S07PacketRespawn(par1EntityPlayerMP.dimension, par1EntityPlayerMP.worldObj.difficultySetting, ++ par1EntityPlayerMP.worldObj.getWorldInfo().getTerrainType(), par1EntityPlayerMP.theItemInWorldManager.getGameType())); ++ fromWorld.removePlayerEntityDangerously(par1EntityPlayerMP); ++ par1EntityPlayerMP.isDead = false; ++ this.transferEntityToWorld(par1EntityPlayerMP, fromWorld.provider.dimensionId, fromWorld, exitWorld, teleporter); ++ this.func_72375_a(par1EntityPlayerMP, fromWorld); ++ par1EntityPlayerMP.playerNetServerHandler.setPlayerLocation(par1EntityPlayerMP.posX, par1EntityPlayerMP.posY, par1EntityPlayerMP.posZ, ++ par1EntityPlayerMP.rotationYaw, par1EntityPlayerMP.rotationPitch); ++ par1EntityPlayerMP.theItemInWorldManager.setWorld(exitWorld); ++ this.updateTimeAndWeatherForPlayer(par1EntityPlayerMP, exitWorld); ++ this.syncPlayerInventory(par1EntityPlayerMP); ++ Iterator iterator = par1EntityPlayerMP.getActivePotionEffects().iterator(); ++ + while (iterator.hasNext()) + { + PotionEffect potioneffect = (PotionEffect)iterator.next(); +- p_72356_1_.playerNetServerHandler.sendPacket(new S1DPacketEntityEffect(p_72356_1_.getEntityId(), potioneffect)); ++ par1EntityPlayerMP.playerNetServerHandler.sendPacket(new S1DPacketEntityEffect(par1EntityPlayerMP.getEntityId(), potioneffect)); + } +- FMLCommonHandler.instance().firePlayerChangedDimensionEvent(p_72356_1_, j, p_72356_2_); ++ FMLCommonHandler.instance().firePlayerChangedDimensionEvent(par1EntityPlayerMP, fromWorld.dimension, targetDimension); + } + + public void transferEntityToWorld(Entity p_82448_1_, int p_82448_2_, WorldServer p_82448_3_, WorldServer p_82448_4_) + { +- transferEntityToWorld(p_82448_1_, p_82448_2_, p_82448_3_, p_82448_4_, p_82448_4_.getDefaultTeleporter()); ++ // CraftBukkit start - Split into modular functions ++ //transferEntityToWorld(p_82448_1_, p_82448_2_, p_82448_3_, p_82448_4_, p_82448_4_.getDefaultTeleporter()); ++ Location exit = this.calculateTarget(p_82448_1_.getBukkitEntity().getLocation(), p_82448_4_); ++ this.repositionEntity(p_82448_1_, exit, true); + } + + public void transferEntityToWorld(Entity p_82448_1_, int p_82448_2_, WorldServer p_82448_3_, WorldServer p_82448_4_, Teleporter teleporter) +@@ -592,6 +1004,197 @@ + p_82448_1_.setWorld(p_82448_4_); + } + ++ // Copy of original a(Entity, int, WorldServer, WorldServer) method with only location calculation logic ++ public Location calculateTarget(Location enter, World target) ++ { ++ WorldServer worldserver = ((CraftWorld) enter.getWorld()).getHandle(); ++ WorldServer worldserver1 = ((CraftWorld) target.getWorld()).getHandle(); ++ int i = worldserver.dimension; ++ double y = enter.getY(); ++ float yaw = enter.getYaw(); ++ float pitch = enter.getPitch(); ++ double d0 = enter.getX(); ++ double d1 = enter.getZ(); ++ double d2 = 8.0D; ++ ++ /* ++ double d3 = entity.locX; ++ double d4 = entity.locY; ++ double d5 = entity.locZ; ++ float f = entity.yaw; ++ ++ worldserver.methodProfiler.a("moving"); ++ */ ++ if (worldserver1.dimension == -1) ++ { ++ d0 /= d2; ++ d1 /= d2; ++ /* ++ entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); ++ if (entity.isAlive()) { ++ worldserver.entityJoinedWorld(entity, false); ++ } ++ */ ++ } ++ else if (worldserver1.dimension == 0) ++ { ++ d0 *= d2; ++ d1 *= d2; ++ /* ++ entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); ++ if (entity.isAlive()) { ++ worldserver.entityJoinedWorld(entity, false); ++ } ++ */ ++ } ++ else ++ { ++ ChunkCoordinates chunkcoordinates; ++ ++ if (i == 1) ++ { ++ // use default NORMAL world spawn instead of target ++ worldserver1 = this.mcServer.worlds.get(0); ++ chunkcoordinates = worldserver1.getSpawnPoint(); ++ } ++ else ++ { ++ chunkcoordinates = worldserver1.getEntrancePortalLocation(); ++ } ++ ++ // Cauldron start - validate chunkcoordinates ++ if (chunkcoordinates != null) ++ { ++ d0 = (double) chunkcoordinates.posX; ++ y = (double) chunkcoordinates.posY; ++ d1 = (double) chunkcoordinates.posZ; ++ yaw = 90.0F; ++ pitch = 0.0F; ++ } ++ // Cauldron end ++ /* ++ entity.setPositionRotation(d0, entity.locY, d1, 90.0F, 0.0F); ++ if (entity.isAlive()) { ++ worldserver.entityJoinedWorld(entity, false); ++ } ++ */ ++ } ++ ++ // worldserver.methodProfiler.b(); ++ if (i != 1) ++ { ++ // worldserver.methodProfiler.a("placing"); ++ d0 = (double) MathHelper.clamp_int((int) d0, -29999872, 29999872); ++ d1 = (double) MathHelper.clamp_int((int) d1, -29999872, 29999872); ++ /* ++ if (entity.isAlive()) { ++ worldserver1.addEntity(entity); ++ entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); ++ worldserver1.entityJoinedWorld(entity, false); ++ worldserver1.t().a(entity, d3, d4, d5, f); ++ } ++ ++ worldserver.methodProfiler.b(); ++ */ ++ } ++ ++ // entity.spawnIn(worldserver1); ++ return new Location(worldserver1.getWorld(), d0, y, d1, yaw, pitch); ++ } ++ ++ // copy of original a(Entity, int, WorldServer, WorldServer) method with only entity repositioning logic ++ public void repositionEntity(Entity entity, Location exit, boolean portal) ++ { ++ int i = entity.dimension; ++ WorldServer worldserver = (WorldServer) entity.worldObj; ++ WorldServer worldserver1 = ((CraftWorld) exit.getWorld()).getHandle(); ++ /* ++ double d0 = entity.locX; ++ double d1 = entity.locZ; ++ double d2 = 8.0D; ++ double d3 = entity.locX; ++ double d4 = entity.locY; ++ double d5 = entity.locZ; ++ float f = entity.yaw; ++ */ ++ worldserver.theProfiler.startSection("moving"); ++ entity.setLocationAndAngles(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); ++ ++ if (entity.isEntityAlive()) ++ { ++ worldserver.updateEntityWithOptionalForce(entity, false); ++ } ++ ++ /* ++ if (entity.dimension == -1) { ++ d0 /= d2; ++ d1 /= d2; ++ entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); ++ if (entity.isAlive()) { ++ worldserver.entityJoinedWorld(entity, false); ++ } ++ } else if (entity.dimension == 0) { ++ d0 *= d2; ++ d1 *= d2; ++ entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch); ++ if (entity.isAlive()) { ++ worldserver.entityJoinedWorld(entity, false); ++ } ++ } else { ++ ChunkCoordinates chunkcoordinates; ++ ++ if (i == 1) { ++ chunkcoordinates = worldserver1.getSpawn(); ++ } else { ++ chunkcoordinates = worldserver1.getDimensionSpawn(); ++ } ++ ++ d0 = (double) chunkcoordinates.x; ++ entity.locY = (double) chunkcoordinates.y; ++ d1 = (double) chunkcoordinates.z; ++ entity.setPositionRotation(d0, entity.locY, d1, 90.0F, 0.0F); ++ if (entity.isAlive()) { ++ worldserver.entityJoinedWorld(entity, false); ++ } ++ } ++ */ ++ worldserver.theProfiler.endSection(); ++ ++ if (i != 1) ++ { ++ worldserver.theProfiler.startSection("placing"); ++ ++ /* ++ d0 = (double) MathHelper.a((int) d0, -29999872, 29999872); ++ d1 = (double) MathHelper.a((int) d1, -29999872, 29999872); ++ */ ++ if (entity.isEntityAlive()) ++ { ++ // entity.setPositionRotation(d0, entity.locY, d1, entity.yaw, entity.pitch) ++ // worldserver1.s().a(entity, d3, d4, d5, f); ++ if (portal) ++ { ++ Vector velocity = entity.getBukkitEntity().getVelocity(); ++ worldserver1.getDefaultTeleporter().adjustExit(entity, exit, velocity); // Should be getTravelAgent ++ entity.setLocationAndAngles(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); ++ ++ if (entity.motionX != velocity.getX() || entity.motionY != velocity.getY() || entity.motionZ != velocity.getZ()) ++ { ++ entity.getBukkitEntity().setVelocity(velocity); ++ } ++ } ++ ++ worldserver1.spawnEntityInWorld(entity); ++ worldserver1.updateEntityWithOptionalForce(entity, false); ++ } ++ ++ worldserver.theProfiler.endSection(); ++ } ++ ++ entity.setWorld(worldserver1); ++ // CraftBukkit end ++ } ++ + public void sendPlayerInfoToAllPlayers() + { + if (++this.playerPingIndex > 600) +@@ -599,11 +1202,13 @@ + this.playerPingIndex = 0; + } + ++ /* CraftBukkit start - Remove updating of lag to players -- it spams way to much on big servers. + if (this.playerPingIndex < this.playerEntityList.size()) + { + EntityPlayerMP entityplayermp = (EntityPlayerMP)this.playerEntityList.get(this.playerPingIndex); + this.sendPacketToAllPlayers(new S38PacketPlayerListItem(entityplayermp.getCommandSenderName(), true, entityplayermp.ping)); + } ++ // CraftBukkit end */ + } + + public void sendPacketToAllPlayers(Packet p_148540_1_) +@@ -864,13 +1469,24 @@ + for (int j = 0; j < this.playerEntityList.size(); ++j) + { + EntityPlayerMP entityplayermp = (EntityPlayerMP)this.playerEntityList.get(j); +- ++ // CraftBukkit start - Test if player receiving packet can see the source of the packet ++ if (p_148543_1_ != null && p_148543_1_ instanceof EntityPlayerMP ++ && !entityplayermp.getBukkitEntity().canSee(((EntityPlayerMP) p_148543_1_).getBukkitEntity())) ++ { ++ continue; ++ } ++ // CraftBukkit end + if (entityplayermp != p_148543_1_ && entityplayermp.dimension == p_148543_10_) + { + double d4 = p_148543_2_ - entityplayermp.posX; + double d5 = p_148543_4_ - entityplayermp.posY; + double d6 = p_148543_6_ - entityplayermp.posZ; +- ++ // Cauldron start - send packets only to players within configured player tracking range) ++ if (p_148543_8_ > org.spigotmc.TrackingRange.getEntityTrackingRange(entityplayermp, 512)) ++ { ++ p_148543_8_ = org.spigotmc.TrackingRange.getEntityTrackingRange(entityplayermp, 512); ++ } ++ // Cauldron end + if (d4 * d4 + d5 * d5 + d6 * d6 < p_148543_8_ * p_148543_8_) + { + entityplayermp.playerNetServerHandler.sendPacket(p_148543_11_); +@@ -925,16 +1541,19 @@ + + if (p_72354_2_.isRaining()) + { ++ // CraftBukkit start - handle player weather + 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))); ++ p_72354_1_.setPlayerWeather(org.bukkit.WeatherType.DOWNFALL, false); ++ // CraftBukkit end + } + } + + public void syncPlayerInventory(EntityPlayerMP p_72385_1_) + { + p_72385_1_.sendContainerToPlayer(p_72385_1_.inventoryContainer); +- p_72385_1_.setPlayerHealthUpdated(); ++ p_72385_1_.getBukkitEntity().updateScaledHealth(); // CraftBukkit - Update scaled health on respawn and worldchange + p_72385_1_.playerNetServerHandler.sendPacket(new S09PacketHeldItemChange(p_72385_1_.inventory.currentItem)); + } + +@@ -950,7 +1569,10 @@ + + public String[] getAvailablePlayerDat() + { +- return this.mcServer.worldServers[0].getSaveHandler().getSaveHandler().getAvailablePlayerDat(); ++ // Cauldron start - don't crash if the overworld isn't loaded ++ List worldServers = this.mcServer.worlds; ++ return worldServers.isEmpty() ? new String[0] : worldServers.get(0).getSaveHandler().getSaveHandler().getAvailablePlayerDat(); // CraftBukkit ++ // Cauldron end + } + + public void setWhiteListEnabled(boolean p_72371_1_) +@@ -1019,12 +1641,30 @@ + + public void removeAllPlayers() + { +- for (int i = 0; i < this.playerEntityList.size(); ++i) ++ while (!this.playerEntityList.isEmpty()) + { +- ((EntityPlayerMP)this.playerEntityList.get(i)).playerNetServerHandler.kickPlayerFromServer("Server closed"); ++ // Spigot start ++ EntityPlayerMP p = (EntityPlayerMP) this.playerEntityList.get(0); ++ p.playerNetServerHandler.kickPlayerFromServer(this.mcServer.server.getShutdownMessage()); ++ ++ if ((!this.playerEntityList.isEmpty()) && (this.playerEntityList.get(0) == p)) ++ { ++ this.playerEntityList.remove(0); // Prevent shutdown hang if already disconnected ++ } ++ // Spigot end + } + } + ++ // CraftBukkit start - Support multi-line messages ++ public void sendMessage(IChatComponent[] ichatbasecomponent) ++ { ++ for (IChatComponent component : ichatbasecomponent) ++ { ++ sendChatMsgImpl(component, true); ++ } ++ } ++ // CraftBukkit end ++ + public void sendChatMsgImpl(IChatComponent p_148544_1_, boolean p_148544_2_) + { + this.mcServer.addChatMessage(p_148544_1_); diff --git a/patches/net/minecraft/server/management/UserList.java.patch b/patches/net/minecraft/server/management/UserList.java.patch new file mode 100644 index 0000000..ca6b34a --- /dev/null +++ b/patches/net/minecraft/server/management/UserList.java.patch @@ -0,0 +1,15 @@ +--- ../src-base/minecraft/net/minecraft/server/management/UserList.java ++++ ../src-work/minecraft/net/minecraft/server/management/UserList.java +@@ -184,6 +184,12 @@ + return this.field_152696_d.size() < 1; + } + ++ // CraftBukkit start ++ public Collection getValues() { ++ return this.field_152696_d.values(); ++ } ++ // CraftBukkit end ++ + @SideOnly(Side.SERVER) + public void func_152679_g() throws IOException + { diff --git a/patches/net/minecraft/server/management/UserListEntry.java.patch b/patches/net/minecraft/server/management/UserListEntry.java.patch new file mode 100644 index 0000000..d098c36 --- /dev/null +++ b/patches/net/minecraft/server/management/UserListEntry.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/server/management/UserListEntry.java ++++ ../src-work/minecraft/net/minecraft/server/management/UserListEntry.java +@@ -17,7 +17,7 @@ + this.field_152642_a = p_i1147_1_; + } + +- Object func_152640_f() ++ public Object func_152640_f() // CraftBukkit - private -> public + { + return this.field_152642_a; + } diff --git a/patches/net/minecraft/server/management/UserListOps.java.patch b/patches/net/minecraft/server/management/UserListOps.java.patch new file mode 100644 index 0000000..8cda80d --- /dev/null +++ b/patches/net/minecraft/server/management/UserListOps.java.patch @@ -0,0 +1,10 @@ +--- ../src-base/minecraft/net/minecraft/server/management/UserListOps.java ++++ ../src-work/minecraft/net/minecraft/server/management/UserListOps.java +@@ -35,6 +35,7 @@ + + protected String func_152699_b(GameProfile p_152699_1_) + { ++ if (p_152699_1_ == null || p_152699_1_.getId() == null) return "invalid"; // Cauldron - handle GameProfiles with no ID + return p_152699_1_.getId().toString(); + } + diff --git a/patches/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch b/patches/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch new file mode 100644 index 0000000..e961924 --- /dev/null +++ b/patches/net/minecraft/server/network/NetHandlerHandshakeTCP.java.patch @@ -0,0 +1,122 @@ +--- ../src-base/minecraft/net/minecraft/server/network/NetHandlerHandshakeTCP.java ++++ ../src-work/minecraft/net/minecraft/server/network/NetHandlerHandshakeTCP.java +@@ -3,6 +3,7 @@ + import cpw.mods.fml.common.FMLCommonHandler; + import io.netty.util.concurrent.GenericFutureListener; + import net.minecraft.network.EnumConnectionState; ++import net.minecraft.network.INetHandler; + import net.minecraft.network.NetworkManager; + import net.minecraft.network.handshake.INetHandlerHandshakeServer; + import net.minecraft.network.handshake.client.C00Handshake; +@@ -11,8 +12,24 @@ + import net.minecraft.util.ChatComponentText; + import net.minecraft.util.IChatComponent; + ++ ++// CraftBukkit start ++import java.net.InetAddress; ++import java.util.HashMap; ++// CraftBukkit end ++// Spigot start ++import com.mojang.authlib.properties.Property; ++import com.mojang.util.UUIDTypeAdapter; ++// Spigot end ++ + public class NetHandlerHandshakeTCP implements INetHandlerHandshakeServer + { ++ private static final com.google.gson.Gson gson = new com.google.gson.Gson(); // Spigot ++ // CraftBukkit start ++ private static final HashMap throttleTracker = new HashMap(); ++ private static int throttleCounter = 0; ++ // CraftBukkit end ++ + private final MinecraftServer field_147387_a; + private final NetworkManager field_147386_b; + private static final String __OBFID = "CL_00001456"; +@@ -39,6 +56,52 @@ + this.field_147386_b.setConnectionState(EnumConnectionState.LOGIN); + ChatComponentText chatcomponenttext; + ++ // CraftBukkit start ++ try ++ { ++ long currentTime = System.currentTimeMillis(); ++ long connectionThrottle = MinecraftServer.getServer().server.getConnectionThrottle(); ++ InetAddress address = ((java.net.InetSocketAddress) this.field_147386_b.getSocketAddress()).getAddress(); ++ ++ synchronized (throttleTracker) ++ { ++ if (throttleTracker.containsKey(address) && !"127.0.0.1".equals(address.getHostAddress()) && currentTime - throttleTracker.get(address) < connectionThrottle) ++ { ++ throttleTracker.put(address, currentTime); ++ chatcomponenttext = new ChatComponentText("Connection throttled! Please wait before reconnecting."); ++ this.field_147386_b.scheduleOutboundPacket(new S00PacketDisconnect(chatcomponenttext), new GenericFutureListener[0]); ++ this.field_147386_b.closeChannel(chatcomponenttext); // Should be close ++ return; ++ } ++ ++ throttleTracker.put(address, currentTime); ++ throttleCounter++; ++ ++ if (throttleCounter > 200) ++ { ++ throttleCounter = 0; ++ // Cleanup stale entries ++ java.util.Iterator iter = throttleTracker.entrySet().iterator(); ++ ++ while (iter.hasNext()) ++ { ++ java.util.Map.Entry entry = (java.util.Map.Entry) iter.next(); ++ ++ if (entry.getValue() > connectionThrottle) ++ { ++ iter.remove(); ++ } ++ } ++ } ++ } ++ } ++ catch (Throwable t) ++ { ++ org.apache.logging.log4j.LogManager.getLogger().debug("Failed to check connection throttle", t); ++ } ++ ++ // CraftBukkit end ++ + if (p_147383_1_.func_149595_d() > 5) + { + chatcomponenttext = new ChatComponentText("Outdated server! I\'m still on 1.7.10"); +@@ -54,6 +117,33 @@ + else + { + this.field_147386_b.setNetHandler(new NetHandlerLoginServer(this.field_147387_a, this.field_147386_b)); ++ ++ // Spigot Start ++ if (org.spigotmc.SpigotConfig.bungee) ++ { ++ String[] split = p_147383_1_.field_149598_b.split("\00"); ++ ++ if (split.length == 3 || split.length == 4) ++ { ++ p_147383_1_.field_149598_b = split[0]; ++ field_147386_b.socketAddress = new java.net.InetSocketAddress(split[1], ((java.net.InetSocketAddress) field_147386_b.getSocketAddress()).getPort()); ++ field_147386_b.spoofedUUID = UUIDTypeAdapter.fromString( split[2] ); ++ } ++ else ++ { ++ chatcomponenttext = new ChatComponentText("If you wish to use IP forwarding, please enable it in your BungeeCord config as well!"); ++ this.field_147386_b.scheduleOutboundPacket(new S00PacketDisconnect(chatcomponenttext), new GenericFutureListener[0]); ++ this.field_147386_b.closeChannel(chatcomponenttext); ++ return; ++ } ++ ++ if (split.length == 4) ++ { ++ field_147386_b.spoofedProfile = gson.fromJson(split[3], Property[].class); ++ } ++ } ++ // Spigot End ++ ((NetHandlerLoginServer) this.field_147386_b.getNetHandler()).hostname = p_147383_1_.field_149598_b + ":" + p_147383_1_.field_149599_c; // CraftBukkit - set hostname + } + + break; diff --git a/patches/net/minecraft/server/network/NetHandlerLoginServer.java.patch b/patches/net/minecraft/server/network/NetHandlerLoginServer.java.patch new file mode 100644 index 0000000..115567e --- /dev/null +++ b/patches/net/minecraft/server/network/NetHandlerLoginServer.java.patch @@ -0,0 +1,239 @@ +--- ../src-base/minecraft/net/minecraft/server/network/NetHandlerLoginServer.java ++++ ../src-work/minecraft/net/minecraft/server/network/NetHandlerLoginServer.java +@@ -13,6 +13,7 @@ + import java.util.UUID; + import java.util.concurrent.atomic.AtomicInteger; + import javax.crypto.SecretKey; ++ + import net.minecraft.network.EnumConnectionState; + import net.minecraft.network.NetworkManager; + import net.minecraft.network.login.INetHandlerLoginServer; +@@ -29,6 +30,14 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import net.minecraft.entity.player.EntityPlayerMP; ++import org.bukkit.craftbukkit.util.Waitable; ++import org.bukkit.event.player.AsyncPlayerPreLoginEvent; ++import org.bukkit.event.player.PlayerPreLoginEvent; ++// CraftBukkit end ++import com.mojang.authlib.properties.Property; ++ + public class NetHandlerLoginServer implements INetHandlerLoginServer + { + private static final AtomicInteger field_147331_b = new AtomicInteger(0); +@@ -37,16 +46,17 @@ + private final byte[] field_147330_e = new byte[4]; + private final MinecraftServer field_147327_f; + public final NetworkManager field_147333_a; +- private NetHandlerLoginServer.LoginState field_147328_g; ++ private LoginState field_147328_g; + private int field_147336_h; + private GameProfile field_147337_i; + private String field_147334_j; + private SecretKey field_147335_k; ++ public String hostname = ""; // CraftBukkit - add field + private static final String __OBFID = "CL_00001458"; + + public NetHandlerLoginServer(MinecraftServer p_i45298_1_, NetworkManager p_i45298_2_) + { +- this.field_147328_g = NetHandlerLoginServer.LoginState.HELLO; ++ this.field_147328_g = LoginState.HELLO; + this.field_147334_j = ""; + this.field_147327_f = p_i45298_1_; + this.field_147333_a = p_i45298_2_; +@@ -55,7 +65,7 @@ + + public void onNetworkTick() + { +- if (this.field_147328_g == NetHandlerLoginServer.LoginState.READY_TO_ACCEPT) ++ if (this.field_147328_g == LoginState.READY_TO_ACCEPT) + { + this.func_147326_c(); + } +@@ -81,24 +91,54 @@ + } + } + ++ // Spigot start ++ public void initUUID() ++ { ++ UUID uuid; ++ if ( field_147333_a.spoofedUUID != null ) ++ { ++ uuid = field_147333_a.spoofedUUID; ++ } else ++ { ++ uuid = UUID.nameUUIDFromBytes( ( "OfflinePlayer:" + this.field_147337_i.getName() ).getBytes( Charsets.UTF_8 ) ); ++ } ++ ++ this.field_147337_i = new GameProfile( uuid, this.field_147337_i.getName() ); ++ ++ if (field_147333_a.spoofedProfile != null) ++ { ++ for ( Property property : field_147333_a.spoofedProfile ) ++ { ++ this.field_147337_i.getProperties().put( property.getName(), property ); ++ } ++ } ++ } ++ // Spigot end ++ + public void func_147326_c() + { ++ // Spigot start - Moved to initUUID ++ /* + if (!this.field_147337_i.isComplete()) + { + this.field_147337_i = this.func_152506_a(this.field_147337_i); + } ++ */ ++ // Spigot end + +- String s = this.field_147327_f.getConfigurationManager().allowUserToConnect(this.field_147333_a.getSocketAddress(), this.field_147337_i); ++ // CraftBukkit start - fire PlayerLoginEvent ++ EntityPlayerMP s = this.field_147327_f.getConfigurationManager().attemptLogin(this, this.field_147337_i, this.hostname); + +- if (s != null) ++ if (s == null) + { +- this.func_147322_a(s); ++ // this.func_147322_a(s); ++ // CraftBukkit end + } + else + { + this.field_147328_g = NetHandlerLoginServer.LoginState.ACCEPTED; + this.field_147333_a.scheduleOutboundPacket(new S02PacketLoginSuccess(this.field_147337_i), new GenericFutureListener[0]); +- FMLNetworkHandler.fmlServerHandshake(this.field_147327_f.getConfigurationManager(), this.field_147333_a, this.field_147327_f.getConfigurationManager().createPlayerForUser(this.field_147337_i)); ++ FMLNetworkHandler.fmlServerHandshake(this.field_147327_f.getConfigurationManager(), this.field_147333_a, this.field_147327_f.getConfigurationManager().processLogin(this.field_147337_i, s)); // CraftBukkit - add player reference + } + } + +@@ -114,29 +154,29 @@ + + public void onConnectionStateTransition(EnumConnectionState p_147232_1_, EnumConnectionState p_147232_2_) + { +- Validate.validState(this.field_147328_g == NetHandlerLoginServer.LoginState.ACCEPTED || this.field_147328_g == NetHandlerLoginServer.LoginState.HELLO, "Unexpected change in protocol", new Object[0]); ++ Validate.validState(this.field_147328_g == LoginState.ACCEPTED || this.field_147328_g == LoginState.HELLO, "Unexpected change in protocol", new Object[0]); + Validate.validState(p_147232_2_ == EnumConnectionState.PLAY || p_147232_2_ == EnumConnectionState.LOGIN, "Unexpected protocol " + p_147232_2_, new Object[0]); + } + + public void processLoginStart(C00PacketLoginStart p_147316_1_) + { +- Validate.validState(this.field_147328_g == NetHandlerLoginServer.LoginState.HELLO, "Unexpected hello packet", new Object[0]); ++ Validate.validState(this.field_147328_g == LoginState.HELLO, "Unexpected hello packet", new Object[0]); + this.field_147337_i = p_147316_1_.func_149304_c(); + + if (this.field_147327_f.isServerInOnlineMode() && !this.field_147333_a.isLocalChannel()) + { +- this.field_147328_g = NetHandlerLoginServer.LoginState.KEY; ++ this.field_147328_g = LoginState.KEY; + this.field_147333_a.scheduleOutboundPacket(new S01PacketEncryptionRequest(this.field_147334_j, this.field_147327_f.getKeyPair().getPublic(), this.field_147330_e), new GenericFutureListener[0]); + } + else + { +- this.field_147328_g = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT; ++ (new ThreadPlayerLookupUUID(this, "User Authenticator #" + field_147331_b.incrementAndGet())).start(); // Spigot + } + } + + public void processEncryptionResponse(C01PacketEncryptionResponse p_147315_1_) + { +- Validate.validState(this.field_147328_g == NetHandlerLoginServer.LoginState.KEY, "Unexpected key packet", new Object[0]); ++ Validate.validState(this.field_147328_g == LoginState.KEY, "Unexpected key packet", new Object[0]); + PrivateKey privatekey = this.field_147327_f.getKeyPair().getPrivate(); + + if (!Arrays.equals(this.field_147330_e, p_147315_1_.func_149299_b(privatekey))) +@@ -148,51 +188,7 @@ + this.field_147335_k = p_147315_1_.func_149300_a(privatekey); + this.field_147328_g = NetHandlerLoginServer.LoginState.AUTHENTICATING; + this.field_147333_a.enableEncryption(this.field_147335_k); +- (new Thread("User Authenticator #" + field_147331_b.incrementAndGet()) +- { +- private static final String __OBFID = "CL_00001459"; +- public void run() +- { +- GameProfile gameprofile = NetHandlerLoginServer.this.field_147337_i; +- +- try +- { +- String s = (new BigInteger(CryptManager.getServerIdHash(NetHandlerLoginServer.this.field_147334_j, NetHandlerLoginServer.this.field_147327_f.getKeyPair().getPublic(), NetHandlerLoginServer.this.field_147335_k))).toString(16); +- NetHandlerLoginServer.this.field_147337_i = NetHandlerLoginServer.this.field_147327_f.func_147130_as().hasJoinedServer(new GameProfile((UUID)null, gameprofile.getName()), s); +- +- if (NetHandlerLoginServer.this.field_147337_i != null) +- { +- NetHandlerLoginServer.logger.info("UUID of player " + NetHandlerLoginServer.this.field_147337_i.getName() + " is " + NetHandlerLoginServer.this.field_147337_i.getId()); +- NetHandlerLoginServer.this.field_147328_g = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT; +- } +- else if (NetHandlerLoginServer.this.field_147327_f.isSinglePlayer()) +- { +- NetHandlerLoginServer.logger.warn("Failed to verify username but will let them in anyway!"); +- NetHandlerLoginServer.this.field_147337_i = NetHandlerLoginServer.this.func_152506_a(gameprofile); +- NetHandlerLoginServer.this.field_147328_g = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT; +- } +- else +- { +- NetHandlerLoginServer.this.func_147322_a("Failed to verify username!"); +- NetHandlerLoginServer.logger.error("Username \'" + NetHandlerLoginServer.this.field_147337_i.getName() + "\' tried to join with an invalid session"); +- } +- } +- catch (AuthenticationUnavailableException authenticationunavailableexception) +- { +- if (NetHandlerLoginServer.this.field_147327_f.isSinglePlayer()) +- { +- NetHandlerLoginServer.logger.warn("Authentication servers are down but will let them in anyway!"); +- NetHandlerLoginServer.this.field_147337_i = NetHandlerLoginServer.this.func_152506_a(gameprofile); +- NetHandlerLoginServer.this.field_147328_g = NetHandlerLoginServer.LoginState.READY_TO_ACCEPT; +- } +- else +- { +- NetHandlerLoginServer.this.func_147322_a("Authentication servers are down. Please try again later, sorry!"); +- NetHandlerLoginServer.logger.error("Couldn\'t verify username because servers are unavailable"); +- } +- } +- } +- }).start(); ++ (new ThreadPlayerLookupUUID(this, "User Authenticator #" + field_147331_b.incrementAndGet())).start(); + } + } + +@@ -202,6 +198,37 @@ + return new GameProfile(uuid, p_152506_1_.getName()); + } + ++ // Cauldron start - access methods for ThreadPlayerLookupUUID ++ static String getLoginServerId(NetHandlerLoginServer loginServer) { ++ return loginServer.field_147334_j; ++ } ++ ++ static MinecraftServer getMinecraftServer(NetHandlerLoginServer loginServer) { ++ return loginServer.field_147327_f; ++ } ++ ++ static SecretKey getSecretKey(NetHandlerLoginServer loginServer) { ++ return loginServer.field_147335_k; ++ } ++ ++ static GameProfile processPlayerLoginGameProfile(NetHandlerLoginServer loginServer, GameProfile gameprofile) { ++ return loginServer.field_147337_i = gameprofile; ++ } ++ ++ static GameProfile getGameProfile(NetHandlerLoginServer loginServer) { ++ return loginServer.field_147337_i; ++ } ++ ++ static Logger getLogger() { ++ return logger; ++ } ++ ++ static void setLoginState(NetHandlerLoginServer loginServer, LoginState state) ++ { ++ loginServer.field_147328_g = state; ++ } ++ // Cauldron end ++ + static enum LoginState + { + HELLO, diff --git a/patches/net/minecraft/server/network/NetHandlerStatusServer.java.patch b/patches/net/minecraft/server/network/NetHandlerStatusServer.java.patch new file mode 100644 index 0000000..885e48b --- /dev/null +++ b/patches/net/minecraft/server/network/NetHandlerStatusServer.java.patch @@ -0,0 +1,61 @@ +--- ../src-base/minecraft/net/minecraft/server/network/NetHandlerStatusServer.java ++++ ../src-work/minecraft/net/minecraft/server/network/NetHandlerStatusServer.java +@@ -1,5 +1,6 @@ + package net.minecraft.server.network; + ++ + import io.netty.util.concurrent.GenericFutureListener; + import net.minecraft.network.EnumConnectionState; + import net.minecraft.network.NetworkManager; +@@ -11,6 +12,13 @@ + import net.minecraft.server.MinecraftServer; + import net.minecraft.util.IChatComponent; + ++// CraftBukkit start ++import java.net.InetSocketAddress; ++import net.minecraft.network.ServerStatusResponse; ++import net.minecraft.util.ChatComponentText; ++import org.bukkit.craftbukkit.util.CraftIconCache; ++// CraftBukkit end ++ + public class NetHandlerStatusServer implements INetHandlerStatusServer + { + private final MinecraftServer field_147314_a; +@@ -37,7 +45,36 @@ + + public void processServerQuery(C00PacketServerQuery p_147312_1_) + { +- this.field_147313_b.scheduleOutboundPacket(new S00PacketServerInfo(this.field_147314_a.func_147134_at()), new GenericFutureListener[0]); ++ // CraftBukkit start - fire ping event ++ class ServerListPingEvent extends org.bukkit.event.server.ServerListPingEvent ++ { ++ CraftIconCache icon = field_147314_a.server.getServerIcon(); ++ ++ ServerListPingEvent() ++ { ++ super(((InetSocketAddress) field_147313_b.getSocketAddress()).getAddress(), field_147314_a.getMOTD(), field_147314_a.getConfigurationManager().getCurrentPlayerCount(), field_147314_a.getConfigurationManager().getMaxPlayers()); ++ } ++ ++ @Override ++ public void setServerIcon(org.bukkit.util.CachedServerIcon icon) ++ { ++ if (!(icon instanceof CraftIconCache)) ++ { ++ throw new IllegalArgumentException(icon + " was not created by " + org.bukkit.craftbukkit.CraftServer.class); ++ } ++ ++ this.icon = (CraftIconCache) icon; ++ } ++ } ++ ServerListPingEvent event = new ServerListPingEvent(); ++ this.field_147314_a.server.getPluginManager().callEvent(event); ++ ServerStatusResponse ping = new ServerStatusResponse(); ++ ping.func_151320_a(event.icon.value); ++ ping.func_151315_a(new ChatComponentText(event.getMotd())); ++ ping.func_151319_a(new ServerStatusResponse.PlayerCountData(event.getMaxPlayers(), field_147314_a.getConfigurationManager().getCurrentPlayerCount())); ++ ping.func_151321_a(new ServerStatusResponse.MinecraftProtocolVersionIdentifier(field_147314_a.getServerModName() + " " + field_147314_a.getMinecraftVersion(), 5)); // TODO: Update when protocol changes ++ this.field_147313_b.scheduleOutboundPacket(new S00PacketServerInfo(ping), new GenericFutureListener[0]); ++ // CraftBukkit end + } + + public void processPing(C01PacketPing p_147311_1_) diff --git a/patches/net/minecraft/stats/StatFileWriter.java.patch b/patches/net/minecraft/stats/StatFileWriter.java.patch new file mode 100644 index 0000000..af15939 --- /dev/null +++ b/patches/net/minecraft/stats/StatFileWriter.java.patch @@ -0,0 +1,15 @@ +--- ../src-base/minecraft/net/minecraft/stats/StatFileWriter.java ++++ ../src-work/minecraft/net/minecraft/stats/StatFileWriter.java +@@ -27,6 +27,12 @@ + { + if (!p_150871_2_.isAchievement() || this.canUnlockAchievement((Achievement)p_150871_2_)) + { ++ // CraftBukkit start ++ org.bukkit.event.Cancellable cancellable = org.bukkit.craftbukkit.event.CraftEventFactory.handleStatisticsIncrease(p_150871_1_, p_150871_2_, this.writeStat(p_150871_2_), p_150871_3_); ++ if (cancellable != null && cancellable.isCancelled()) { ++ return; ++ } ++ // CraftBukkit end + this.func_150873_a(p_150871_1_, p_150871_2_, this.writeStat(p_150871_2_) + p_150871_3_); + } + } diff --git a/patches/net/minecraft/tileentity/MobSpawnerBaseLogic.java.patch b/patches/net/minecraft/tileentity/MobSpawnerBaseLogic.java.patch new file mode 100644 index 0000000..0964ba4 --- /dev/null +++ b/patches/net/minecraft/tileentity/MobSpawnerBaseLogic.java.patch @@ -0,0 +1,46 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/MobSpawnerBaseLogic.java ++++ ../src-work/minecraft/net/minecraft/tileentity/MobSpawnerBaseLogic.java +@@ -17,6 +17,8 @@ + import net.minecraft.util.WeightedRandom; + import net.minecraft.world.World; + ++import org.bukkit.event.entity.CreatureSpawnEvent; // CraftBukkit ++ + public abstract class MobSpawnerBaseLogic + { + public int spawnDelay = 20; +@@ -162,7 +164,15 @@ + + if (p_98265_1_.worldObj != null) + { +- p_98265_1_.worldObj.spawnEntityInWorld(p_98265_1_); ++ p_98265_1_.worldObj.addEntity(p_98265_1_, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit ++ ++ // Spigot Start ++ if (p_98265_1_.worldObj.getSpigotConfig().nerfSpawnerMobs) // Cauldron ++ { ++ p_98265_1_.fromMobSpawner = true; ++ } ++ ++ // Spigot End + } + + NBTTagCompound nbttagcompound2; +@@ -190,7 +200,7 @@ + + if (p_98265_1_.worldObj != null) + { +- p_98265_1_.worldObj.spawnEntityInWorld(entity2); ++ p_98265_1_.worldObj.addEntity(entity2, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit + } + + entity1.mountEntity(entity2); +@@ -202,7 +212,7 @@ + else if (p_98265_1_ instanceof EntityLivingBase && p_98265_1_.worldObj != null) + { + ((EntityLiving)p_98265_1_).onSpawnWithEgg((IEntityLivingData)null); +- this.getSpawnerWorld().spawnEntityInWorld(p_98265_1_); ++ this.getSpawnerWorld().addEntity(p_98265_1_, CreatureSpawnEvent.SpawnReason.SPAWNER); // CraftBukkit + } + + return p_98265_1_; diff --git a/patches/net/minecraft/tileentity/TileEntity.java.patch b/patches/net/minecraft/tileentity/TileEntity.java.patch new file mode 100644 index 0000000..8b36b9b --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntity.java.patch @@ -0,0 +1,61 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntity.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntity.java +@@ -22,18 +22,22 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++import org.spigotmc.CustomTimingsHandler; // Spigot ++import org.bukkit.inventory.InventoryHolder; // CraftBukkit ++ + public class TileEntity + { + private static final Logger logger = LogManager.getLogger(); + private static Map nameToClassMap = new HashMap(); +- private static Map classToNameMap = new HashMap(); +- protected World worldObj; ++ public static Map classToNameMap = new HashMap(); // Cauldron - private -> public ++ public World worldObj; // CraftBukkit - protected -> public + public int xCoord; + public int yCoord; + public int zCoord; + protected boolean tileEntityInvalid; + public int blockMetadata = -1; + public Block blockType; ++ public CustomTimingsHandler tickTimer = org.bukkit.craftbukkit.SpigotTimings.getTileEntityTimings(this); // Spigot + private static final String __OBFID = "CL_00000340"; + + public static void addMapping(Class p_145826_0_, String p_145826_1_) +@@ -106,7 +110,11 @@ + } + catch (Exception exception) + { +- exception.printStackTrace(); ++ // Cauldron start - better debug ++ FMLLog.log(Level.ERROR, exception, ++ "A TileEntity %s(%s) located @ %s,%s,%s has thrown an exception during creation, it cannot be created. Report this to the mod author", ++ p_145827_0_.getString("id"), oclass.getName(), p_145827_0_.getInteger("x"), p_145827_0_.getInteger("y"), p_145827_0_.getInteger("z")); ++ // Cauldron end + } + + if (tileentity != null) +@@ -282,6 +290,20 @@ + addMapping(TileEntityFlowerPot.class, "FlowerPot"); + } + ++ // CraftBukkit start ++ public InventoryHolder getOwner() ++ { ++ org.bukkit.block.BlockState state = worldObj.getWorld().getBlockAt(xCoord, yCoord, zCoord).getState(); ++ ++ if (state instanceof InventoryHolder) ++ { ++ return (InventoryHolder) state; ++ } ++ ++ return null; ++ } ++ // CraftBukkit end ++ + // -- BEGIN FORGE PATCHES -- + /** + * Determines if this TileEntity requires update calls. diff --git a/patches/net/minecraft/tileentity/TileEntityBeacon.java.patch b/patches/net/minecraft/tileentity/TileEntityBeacon.java.patch new file mode 100644 index 0000000..ca827c1 --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntityBeacon.java.patch @@ -0,0 +1,59 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityBeacon.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityBeacon.java +@@ -18,6 +18,11 @@ + import net.minecraft.stats.AchievementList; + import net.minecraft.util.AxisAlignedBB; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class TileEntityBeacon extends TileEntity implements IInventory + { + public static final Potion[][] effectsList = new Potion[][] {{Potion.moveSpeed, Potion.digSpeed}, {Potion.resistance, Potion.jump}, {Potion.damageBoost}, {Potion.regeneration}}; +@@ -31,6 +36,35 @@ + private int secondaryEffect; + private ItemStack payment; + private String field_146008_p; ++ // CraftBukkit start ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() ++ { ++ return new ItemStack[] { this.payment }; ++ } ++ ++ public void onOpen(CraftHumanEntity who) ++ { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) ++ { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() ++ { ++ return transaction; ++ } ++ ++ public void setMaxStackSize(int size) ++ { ++ maxStack = size; ++ } ++ // CraftBukkit end + private static final String __OBFID = "CL_00000339"; + + public void updateEntity() +@@ -343,7 +377,7 @@ + + public int getInventoryStackLimit() + { +- return 1; ++ return maxStack; // CraftBukkit + } + + public boolean isUseableByPlayer(EntityPlayer p_70300_1_) diff --git a/patches/net/minecraft/tileentity/TileEntityBrewingStand.java.patch b/patches/net/minecraft/tileentity/TileEntityBrewingStand.java.patch new file mode 100644 index 0000000..0a5fff5 --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntityBrewingStand.java.patch @@ -0,0 +1,109 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityBrewingStand.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityBrewingStand.java +@@ -13,17 +13,55 @@ + import net.minecraft.nbt.NBTTagList; + import net.minecraft.potion.PotionHelper; + ++// CraftBukkit start ++import net.minecraft.server.MinecraftServer; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++import org.bukkit.event.inventory.BrewEvent; ++// CraftBukkit end ++ + public class TileEntityBrewingStand extends TileEntity implements ISidedInventory + { + private static final int[] field_145941_a = new int[] {3}; + private static final int[] field_145947_i = new int[] {0, 1, 2}; +- private ItemStack[] brewingItemStacks = new ItemStack[4]; +- private int brewTime; ++ public ItemStack[] brewingItemStacks = new ItemStack[4]; // CraftBukkit - private -> public ++ public int brewTime; // CraftBukkit - private -> public + private int filledSlots; + private Item ingredientID; + private String field_145942_n; ++ private int lastTick = MinecraftServer.currentTick; // CraftBukkit + private static final String __OBFID = "CL_00000345"; + ++ // CraftBukkit start ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = 64; ++ ++ public void onOpen(CraftHumanEntity who) ++ { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) ++ { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() ++ { ++ return transaction; ++ } ++ ++ public ItemStack[] getContents() ++ { ++ return this.brewingItemStacks; ++ } ++ ++ public void setMaxStackSize(int size) ++ { ++ maxStack = size; ++ } ++ // CraftBukkit end ++ + public String getInventoryName() + { + return this.hasCustomInventoryName() ? this.field_145942_n : "container.brewing"; +@@ -46,12 +84,17 @@ + + public void updateEntity() + { ++ // CraftBukkit start - Use wall time instead of ticks for brewing ++ int elapsedTicks = MinecraftServer.currentTick - this.lastTick; ++ this.lastTick = MinecraftServer.currentTick; ++ + if (this.brewTime > 0) + { +- --this.brewTime; ++ this.brewTime -= elapsedTicks; + +- if (this.brewTime == 0) ++ if (this.brewTime <= 0) // == -> <= + { ++ // CraftBukkit end + this.brewPotions(); + this.markDirty(); + } +@@ -141,7 +184,19 @@ + if (this.canBrew()) + { + ItemStack itemstack = this.brewingItemStacks[3]; ++ // CraftBukkit start ++ if (getOwner() != null) ++ { ++ BrewEvent event = new BrewEvent(worldObj.getWorld().getBlockAt(xCoord, yCoord, zCoord), (org.bukkit.inventory.BrewerInventory) this.getOwner() ++ .getInventory()); ++ org.bukkit.Bukkit.getPluginManager().callEvent(event); + ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ } ++ // CraftBukkit end + for (int i = 0; i < 3; ++i) + { + if (this.brewingItemStacks[i] != null && this.brewingItemStacks[i].getItem() instanceof ItemPotion) +@@ -280,7 +335,7 @@ + + public int getInventoryStackLimit() + { +- return 64; ++ return this.maxStack; // CraftBukkit + } + + public boolean isUseableByPlayer(EntityPlayer p_70300_1_) diff --git a/patches/net/minecraft/tileentity/TileEntityChest.java.patch b/patches/net/minecraft/tileentity/TileEntityChest.java.patch new file mode 100644 index 0000000..fbeb9dc --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntityChest.java.patch @@ -0,0 +1,123 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityChest.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityChest.java +@@ -15,6 +15,12 @@ + import net.minecraft.nbt.NBTTagList; + import net.minecraft.util.AxisAlignedBB; + ++// CraftBukkit start ++import net.minecraft.init.Blocks; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class TileEntityChest extends TileEntity implements IInventory + { + private ItemStack[] chestContents = new ItemStack[36]; +@@ -31,6 +37,36 @@ + private String customName; + private static final String __OBFID = "CL_00000346"; + ++ // CraftBukkit start ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() ++ { ++ return this.chestContents; ++ } ++ ++ public void onOpen(CraftHumanEntity who) ++ { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) ++ { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() ++ { ++ return transaction; ++ } ++ ++ public void setMaxStackSize(int size) ++ { ++ maxStack = size; ++ } ++ // CraftBukkit end ++ + public TileEntityChest() + { + this.cachedChestType = -1; +@@ -296,6 +332,12 @@ + public void updateEntity() + { + super.updateEntity(); ++ ++ if (this.worldObj == null) ++ { ++ return; // CraftBukkit ++ } ++ + this.checkForAdjacentChests(); + ++this.ticksSinceSync; + float f; +@@ -410,8 +452,28 @@ + this.numPlayersUsing = 0; + } + ++ int oldPower = Math.max(0, Math.min(15, this.numPlayersUsing)); // CraftBukkit - Get power before new viewer is added + ++this.numPlayersUsing; ++ ++ if (this.worldObj == null) ++ { ++ return; // CraftBukkit ++ } ++ + this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, this.numPlayersUsing); ++ ++ // CraftBukkit start - Call redstone event ++ if (this.getBlockType() == Blocks.trapped_chest) ++ { ++ int newPower = Math.max(0, Math.min(15, this.numPlayersUsing)); ++ ++ if (oldPower != newPower) ++ { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(worldObj, this.xCoord, this.yCoord, this.zCoord, oldPower, newPower); ++ } ++ } ++ ++ // CraftBukkit end + this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType()); + this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType()); + } +@@ -420,8 +482,28 @@ + { + if (this.getBlockType() instanceof BlockChest) + { ++ int oldPower = Math.max(0, Math.min(15, this.numPlayersUsing)); // CraftBukkit - Get power before new viewer is added + --this.numPlayersUsing; ++ ++ if (this.worldObj == null) ++ { ++ return; // CraftBukkit ++ } ++ + this.worldObj.addBlockEvent(this.xCoord, this.yCoord, this.zCoord, this.getBlockType(), 1, this.numPlayersUsing); ++ ++ // CraftBukkit start - Call redstone event ++ if (this.getBlockType() == Blocks.trapped_chest) ++ { ++ int newPower = Math.max(0, Math.min(15, this.numPlayersUsing)); ++ ++ if (oldPower != newPower) ++ { ++ org.bukkit.craftbukkit.event.CraftEventFactory.callRedstoneChange(worldObj, this.xCoord, this.yCoord, this.zCoord, oldPower, newPower); ++ } ++ } ++ ++ // CraftBukkit end + this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord, this.zCoord, this.getBlockType()); + this.worldObj.notifyBlocksOfNeighborChange(this.xCoord, this.yCoord - 1, this.zCoord, this.getBlockType()); + } diff --git a/patches/net/minecraft/tileentity/TileEntityCommandBlock.java.patch b/patches/net/minecraft/tileentity/TileEntityCommandBlock.java.patch new file mode 100644 index 0000000..764cf12 --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntityCommandBlock.java.patch @@ -0,0 +1,58 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityCommandBlock.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityCommandBlock.java +@@ -12,39 +12,9 @@ + + public class TileEntityCommandBlock extends TileEntity + { +- private final CommandBlockLogic field_145994_a = new CommandBlockLogic() +- { +- private static final String __OBFID = "CL_00000348"; +- public ChunkCoordinates getPlayerCoordinates() +- { +- return new ChunkCoordinates(TileEntityCommandBlock.this.xCoord, TileEntityCommandBlock.this.yCoord, TileEntityCommandBlock.this.zCoord); +- } +- public World getEntityWorld() +- { +- return TileEntityCommandBlock.this.getWorldObj(); +- } +- public void func_145752_a(String p_145752_1_) +- { +- super.func_145752_a(p_145752_1_); +- TileEntityCommandBlock.this.markDirty(); +- } +- public void func_145756_e() +- { +- TileEntityCommandBlock.this.getWorldObj().markBlockForUpdate(TileEntityCommandBlock.this.xCoord, TileEntityCommandBlock.this.yCoord, TileEntityCommandBlock.this.zCoord); +- } +- @SideOnly(Side.CLIENT) +- public int func_145751_f() +- { +- return 0; +- } +- @SideOnly(Side.CLIENT) +- public void func_145757_a(ByteBuf p_145757_1_) +- { +- p_145757_1_.writeInt(TileEntityCommandBlock.this.xCoord); +- p_145757_1_.writeInt(TileEntityCommandBlock.this.yCoord); +- p_145757_1_.writeInt(TileEntityCommandBlock.this.zCoord); +- } +- }; ++ private final TileEntityCommandBlockListener field_145994_a_CB = new TileEntityCommandBlockListener(this); // CraftBukkit ++ private final CommandBlockLogic field_145994_a = field_145994_a_CB; // Cauldron ++ + private static final String __OBFID = "CL_00000347"; + + public void writeToNBT(NBTTagCompound p_145841_1_) +@@ -70,4 +40,12 @@ + { + return this.field_145994_a; + } ++ ++ // Cauldron start ++ @Override ++ public boolean canUpdate() ++ { ++ return false; ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraft/tileentity/TileEntityComparator.java.patch b/patches/net/minecraft/tileentity/TileEntityComparator.java.patch new file mode 100644 index 0000000..aaae5fa --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntityComparator.java.patch @@ -0,0 +1,15 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityComparator.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityComparator.java +@@ -28,4 +28,12 @@ + { + this.field_145997_a = p_145995_1_; + } ++ ++ // Cauldron start ++ @Override ++ public boolean canUpdate() ++ { ++ return false; ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraft/tileentity/TileEntityDispenser.java.patch b/patches/net/minecraft/tileentity/TileEntityDispenser.java.patch new file mode 100644 index 0000000..1809089 --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntityDispenser.java.patch @@ -0,0 +1,87 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityDispenser.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityDispenser.java +@@ -7,6 +7,13 @@ + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.nbt.NBTTagList; + ++// CraftBukkit start ++import java.util.List; ++ ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.entity.HumanEntity; ++// CraftBukkit end ++ + public class TileEntityDispenser extends TileEntity implements IInventory + { + private ItemStack[] field_146022_i = new ItemStack[9]; +@@ -14,6 +21,36 @@ + protected String field_146020_a; + private static final String __OBFID = "CL_00000352"; + ++ // CraftBukkit start ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() ++ { ++ return this.field_146022_i; ++ } ++ ++ public void onOpen(CraftHumanEntity who) ++ { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) ++ { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() ++ { ++ return transaction; ++ } ++ ++ public void setMaxStackSize(int size) ++ { ++ maxStack = size; ++ } ++ // CraftBukkit end ++ + public int getSizeInventory() + { + return 9; +@@ -79,6 +116,11 @@ + { + if (this.field_146022_i[k] != null && this.field_146021_j.nextInt(j++) == 0) + { ++ if (this.field_146022_i[k].stackSize == 0) ++ { ++ continue; // CraftBukkit ++ } ++ + i = k; + } + } +@@ -176,7 +218,7 @@ + + public int getInventoryStackLimit() + { +- return 64; ++ return maxStack; // CraftBukkit + } + + public boolean isUseableByPlayer(EntityPlayer p_70300_1_) +@@ -192,4 +234,12 @@ + { + return true; + } ++ ++ // Cauldron start ++ @Override ++ public boolean canUpdate() ++ { ++ return false; ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraft/tileentity/TileEntityDropper.java.patch b/patches/net/minecraft/tileentity/TileEntityDropper.java.patch new file mode 100644 index 0000000..5e97e9a --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntityDropper.java.patch @@ -0,0 +1,15 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityDropper.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityDropper.java +@@ -8,4 +8,12 @@ + { + return this.hasCustomInventoryName() ? this.field_146020_a : "container.dropper"; + } ++ ++ // Cauldron start ++ @Override ++ public boolean canUpdate() ++ { ++ return false; ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraft/tileentity/TileEntityEndPortal.java.patch b/patches/net/minecraft/tileentity/TileEntityEndPortal.java.patch new file mode 100644 index 0000000..fa47fd5 --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntityEndPortal.java.patch @@ -0,0 +1,15 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityEndPortal.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityEndPortal.java +@@ -3,4 +3,12 @@ + public class TileEntityEndPortal extends TileEntity + { + private static final String __OBFID = "CL_00000365"; ++ ++ // Cauldron start ++ @Override ++ public boolean canUpdate() ++ { ++ return false; ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraft/tileentity/TileEntityFlowerPot.java.patch b/patches/net/minecraft/tileentity/TileEntityFlowerPot.java.patch new file mode 100644 index 0000000..f6dc35e --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntityFlowerPot.java.patch @@ -0,0 +1,15 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityFlowerPot.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityFlowerPot.java +@@ -55,4 +55,12 @@ + { + return this.flowerPotData; + } ++ ++ // Cauldron start ++ @Override ++ public boolean canUpdate() ++ { ++ return false; ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraft/tileentity/TileEntityFurnace.java.patch b/patches/net/minecraft/tileentity/TileEntityFurnace.java.patch new file mode 100644 index 0000000..e3390fd --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntityFurnace.java.patch @@ -0,0 +1,219 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityFurnace.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityFurnace.java +@@ -19,7 +19,17 @@ + import net.minecraft.item.crafting.FurnaceRecipes; + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.nbt.NBTTagList; ++import net.minecraft.server.MinecraftServer; + ++// CraftBukkit start ++import java.util.List; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.entity.HumanEntity; ++import org.bukkit.event.inventory.FurnaceBurnEvent; ++import org.bukkit.event.inventory.FurnaceSmeltEvent; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++// CraftBukkit end ++ + public class TileEntityFurnace extends TileEntity implements ISidedInventory + { + private static final int[] slotsTop = new int[] {0}; +@@ -30,6 +40,37 @@ + public int currentItemBurnTime; + public int furnaceCookTime; + private String field_145958_o; ++ ++ // CraftBukkit start ++ private int lastTick = MinecraftServer.currentTick; ++ private int maxStack = MAX_STACK; ++ public List transaction = new java.util.ArrayList(); ++ ++ public ItemStack[] getContents() ++ { ++ return this.furnaceItemStacks; ++ } ++ ++ public void onOpen(CraftHumanEntity who) ++ { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) ++ { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() ++ { ++ return transaction; ++ } ++ ++ public void setMaxStackSize(int size) ++ { ++ maxStack = size; ++ } ++ // CraftBukkit end + private static final String __OBFID = "CL_00000357"; + + public int getSizeInventory() +@@ -166,7 +207,7 @@ + + public int getInventoryStackLimit() + { +- return 64; ++ return maxStack; // CraftBukkit + } + + @SideOnly(Side.CLIENT) +@@ -195,52 +236,85 @@ + { + boolean flag = this.furnaceBurnTime > 0; + boolean flag1 = false; ++ // CraftBukkit start - Use wall time instead of ticks for cooking ++ int elapsedTicks = MinecraftServer.currentTick - this.lastTick; ++ this.lastTick = MinecraftServer.currentTick; + ++ // CraftBukkit - moved from below ++ if (this.isBurning() && this.canSmelt()) ++ { ++ this.furnaceCookTime += elapsedTicks; ++ ++ if (this.furnaceCookTime >= 200) ++ { ++ this.furnaceCookTime %= 200; ++ this.smeltItem(); ++ flag1 = true; ++ } ++ } ++ else ++ { ++ this.furnaceCookTime = 0; ++ } ++ ++ // CraftBukkit end ++ + if (this.furnaceBurnTime > 0) + { +- --this.furnaceBurnTime; ++ this.furnaceBurnTime -= elapsedTicks; // CraftBukkit + } + + if (!this.worldObj.isRemote) + { +- if (this.furnaceBurnTime != 0 || this.furnaceItemStacks[1] != null && this.furnaceItemStacks[0] != null) ++ // CraftBukkit start - Handle multiple elapsed ticks ++ if (this.furnaceBurnTime <= 0 && this.canSmelt() && this.furnaceItemStacks[1] != null) // CraftBukkit - == to <= + { +- if (this.furnaceBurnTime == 0 && this.canSmelt()) ++ CraftItemStack fuel = CraftItemStack.asCraftMirror(this.furnaceItemStacks[1]); ++ FurnaceBurnEvent furnaceBurnEvent = new FurnaceBurnEvent(this.worldObj.getWorld().getBlockAt(this.xCoord, this.yCoord, this.zCoord), fuel, getItemBurnTime(this.furnaceItemStacks[1])); ++ this.worldObj.getServer().getPluginManager().callEvent(furnaceBurnEvent); ++ ++ if (furnaceBurnEvent.isCancelled()) + { +- this.currentItemBurnTime = this.furnaceBurnTime = getItemBurnTime(this.furnaceItemStacks[1]); ++ return; ++ } + +- if (this.furnaceBurnTime > 0) ++ this.currentItemBurnTime = furnaceBurnEvent.getBurnTime(); ++ this.furnaceBurnTime += this.currentItemBurnTime; ++ ++ if (this.furnaceBurnTime > 0 && furnaceBurnEvent.isBurning()) ++ { ++ // CraftBukkit end ++ flag1 = true; ++ ++ if (this.furnaceItemStacks[1] != null) + { +- flag1 = true; ++ --this.furnaceItemStacks[1].stackSize; + +- if (this.furnaceItemStacks[1] != null) ++ if (this.furnaceItemStacks[1].stackSize == 0) + { +- --this.furnaceItemStacks[1].stackSize; +- +- if (this.furnaceItemStacks[1].stackSize == 0) +- { +- this.furnaceItemStacks[1] = furnaceItemStacks[1].getItem().getContainerItem(furnaceItemStacks[1]); +- } ++ this.furnaceItemStacks[1] = furnaceItemStacks[1].getItem().getContainerItem(furnaceItemStacks[1]); + } + } + } ++ } + +- if (this.isBurning() && this.canSmelt()) +- { +- ++this.furnaceCookTime; ++ /* CraftBukkit start - Moved up ++ if (this.isBurning() && this.canSmelt()) ++ { ++ ++this.furnaceCookTime; + +- if (this.furnaceCookTime == 200) +- { +- this.furnaceCookTime = 0; +- this.smeltItem(); +- flag1 = true; +- } +- } +- else ++ if (this.furnaceCookTime == 200) + { + this.furnaceCookTime = 0; ++ this.smeltItem(); ++ flag1 = true; + } + } ++ else ++ { ++ this.furnaceCookTime = 0; ++ } ++ // CraftBukkit end */ + + if (flag != this.furnaceBurnTime > 0) + { +@@ -277,16 +351,37 @@ + if (this.canSmelt()) + { + ItemStack itemstack = FurnaceRecipes.smelting().getSmeltingResult(this.furnaceItemStacks[0]); ++ // CraftBukkit start ++ CraftItemStack source = CraftItemStack.asCraftMirror(this.furnaceItemStacks[0]); ++ org.bukkit.inventory.ItemStack result = CraftItemStack.asBukkitCopy(itemstack); ++ FurnaceSmeltEvent furnaceSmeltEvent = new FurnaceSmeltEvent(this.worldObj.getWorld().getBlockAt(this.xCoord, this.yCoord, this.zCoord), source, result); ++ this.worldObj.getServer().getPluginManager().callEvent(furnaceSmeltEvent); + +- if (this.furnaceItemStacks[2] == null) ++ if (furnaceSmeltEvent.isCancelled()) + { +- this.furnaceItemStacks[2] = itemstack.copy(); ++ return; + } +- else if (this.furnaceItemStacks[2].getItem() == itemstack.getItem()) ++ ++ result = furnaceSmeltEvent.getResult(); ++ itemstack = CraftItemStack.asNMSCopy(result); ++ ++ if (itemstack != null) + { +- this.furnaceItemStacks[2].stackSize += itemstack.stackSize; // Forge BugFix: Results may have multiple items ++ if (this.furnaceItemStacks[2] == null) ++ { ++ this.furnaceItemStacks[2] = itemstack; ++ } ++ else if (CraftItemStack.asCraftMirror(this.furnaceItemStacks[2]).isSimilar(result)) ++ { ++ this.furnaceItemStacks[2].stackSize += itemstack.stackSize; ++ } ++ else ++ { ++ return; ++ } + } + ++ // CraftBukkit end + --this.furnaceItemStacks[0].stackSize; + + if (this.furnaceItemStacks[0].stackSize <= 0) diff --git a/patches/net/minecraft/tileentity/TileEntityHopper.java.patch b/patches/net/minecraft/tileentity/TileEntityHopper.java.patch new file mode 100644 index 0000000..8186774 --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntityHopper.java.patch @@ -0,0 +1,245 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityHopper.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityHopper.java +@@ -18,11 +18,52 @@ + import net.minecraft.util.MathHelper; + import net.minecraft.world.World; + ++// CraftBukkit start ++import net.minecraft.entity.item.EntityMinecartHopper; ++import net.minecraft.inventory.InventoryLargeChest; ++import org.bukkit.craftbukkit.entity.CraftHumanEntity; ++import org.bukkit.craftbukkit.inventory.CraftItemStack; ++import org.bukkit.entity.HumanEntity; ++import org.bukkit.event.inventory.InventoryMoveItemEvent; ++import org.bukkit.event.inventory.InventoryPickupItemEvent; ++import org.bukkit.inventory.Inventory; ++// CraftBukkit end ++ + public class TileEntityHopper extends TileEntity implements IHopper + { + private ItemStack[] field_145900_a = new ItemStack[5]; + private String field_145902_i; + private int field_145901_j = -1; ++ ++ // CraftBukkit start ++ public List transaction = new java.util.ArrayList(); ++ private int maxStack = MAX_STACK; ++ ++ public ItemStack[] getContents() ++ { ++ return this.field_145900_a; ++ } ++ ++ public void onOpen(CraftHumanEntity who) ++ { ++ transaction.add(who); ++ } ++ ++ public void onClose(CraftHumanEntity who) ++ { ++ transaction.remove(who); ++ } ++ ++ public List getViewers() ++ { ++ return transaction; ++ } ++ ++ public void setMaxStackSize(int size) ++ { ++ maxStack = size; ++ } ++ // CraftBukkit end + private static final String __OBFID = "CL_00000359"; + + public void readFromNBT(NBTTagCompound p_145839_1_) +@@ -212,12 +253,18 @@ + + if (flag) + { +- this.func_145896_c(8); ++ this.func_145896_c(this.worldObj.getSpigotConfig().hopperTransfer); // Spigot // Cauldron + this.markDirty(); + return true; + } + } + ++ // Spigot start ++ if (!this.func_145888_j()) ++ { ++ this.func_145896_c(this.worldObj.getSpigotConfig().hopperCheck); // Cauldron ++ } ++ // Spigot end + return false; + } + else +@@ -285,18 +332,70 @@ + if (this.getStackInSlot(j) != null) + { + ItemStack itemstack = this.getStackInSlot(j).copy(); +- ItemStack itemstack1 = func_145889_a(iinventory, this.decrStackSize(j, 1), i); +- ++ // CraftBukkit start - Call event when pushing items into other inventories ++ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(this.decrStackSize(j, 1)); ++ Inventory destinationInventory; ++ ++ // Have to special case large chests as they work oddly ++ if (iinventory instanceof InventoryLargeChest) ++ { ++ destinationInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) iinventory); ++ } ++ else ++ { ++ // Cauldron start - support mod inventories, with no owners ++ try { ++ if (iinventory.getOwner() != null) { ++ destinationInventory = iinventory.getOwner().getInventory(); ++ } else { ++ // TODO: create a mod inventory for passing to the event, instead of null ++ destinationInventory = null; ++ } ++ } catch (AbstractMethodError e) { // fixes openblocks AbstractMethodError ++ if (iinventory instanceof net.minecraft.tileentity.TileEntity) { ++ org.bukkit.inventory.InventoryHolder holder = net.minecraftforge.cauldron.CauldronUtils.getOwner((net.minecraft.tileentity.TileEntity)iinventory); ++ if (holder != null) { ++ destinationInventory = holder.getInventory(); ++ } else { ++ destinationInventory = null; ++ } ++ } else { ++ destinationInventory = null; ++ } ++ } ++ // Cauldron end ++ } ++ ++ InventoryMoveItemEvent event = new InventoryMoveItemEvent(this.getOwner().getInventory(), oitemstack.clone(), destinationInventory, true); ++ this.getWorldObj().getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ this.setInventorySlotContents(j, itemstack); ++ this.func_145896_c(worldObj.spigotConfig.hopperTransfer); // Spigot ++ return false; ++ } ++ ++ ItemStack itemstack1 = func_145889_a(iinventory, CraftItemStack.asNMSCopy(event.getItem()), i); ++ + if (itemstack1 == null || itemstack1.stackSize == 0) + { +- iinventory.markDirty(); ++ if (event.getItem().equals(oitemstack)) ++ { ++ iinventory.markDirty(); ++ } ++ else ++ { ++ this.setInventorySlotContents(j, itemstack); ++ } ++ ++ // CraftBukkit end + return true; + } +- ++ + this.setInventorySlotContents(j, itemstack); + } + } +- + return false; + } + } +@@ -427,11 +526,70 @@ + if (itemstack != null && func_145890_b(p_145892_1_, itemstack, p_145892_2_, p_145892_3_)) + { + ItemStack itemstack1 = itemstack.copy(); +- ItemStack itemstack2 = func_145889_a(p_145892_0_, p_145892_1_.decrStackSize(p_145892_2_, 1), -1); ++ // CraftBukkit start - Call event on collection of items from inventories into the hopper ++ CraftItemStack oitemstack = CraftItemStack.asCraftMirror(p_145892_1_.decrStackSize(p_145892_2_, 1)); ++ Inventory sourceInventory; + ++ // Have to special case large chests as they work oddly ++ if (p_145892_1_ instanceof InventoryLargeChest) ++ { ++ sourceInventory = new org.bukkit.craftbukkit.inventory.CraftInventoryDoubleChest((InventoryLargeChest) p_145892_1_); ++ } ++ else ++ { ++ // Cauldron start - support mod inventories, with no owners ++ try ++ { ++ if (p_145892_1_.getOwner() != null) ++ { ++ sourceInventory = p_145892_1_.getOwner().getInventory(); ++ } ++ else ++ { ++ // TODO: create a mod inventory for passing to the event, instead of null ++ sourceInventory = null; ++ } ++ } ++ catch (AbstractMethodError e) ++ { ++ sourceInventory = null; ++ } ++ // Cauldron end ++ } ++ ++ InventoryMoveItemEvent event = new InventoryMoveItemEvent(sourceInventory, oitemstack.clone(), p_145892_0_.getOwner().getInventory(), false); ++ p_145892_0_.getWorldObj().getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ p_145892_1_.setInventorySlotContents(p_145892_2_, itemstack1); ++ ++ if (p_145892_0_ instanceof TileEntityHopper) ++ { ++ ((TileEntityHopper) p_145892_0_).func_145896_c(p_145892_0_.getWorldObj().spigotConfig.hopperTransfer); // Spigot ++ } ++ else if (p_145892_0_ instanceof EntityMinecartHopper) ++ { ++ ((EntityMinecartHopper) p_145892_0_).setDisplayTileData(p_145892_0_.getWorldObj().spigotConfig.hopperTransfer / 2); // Spigot ++ } ++ ++ return false; ++ } ++ ++ ItemStack itemstack2 = func_145889_a(p_145892_0_, CraftItemStack.asNMSCopy(event.getItem()), -1); ++ + if (itemstack2 == null || itemstack2.stackSize == 0) + { +- p_145892_1_.markDirty(); ++ if (event.getItem().equals(oitemstack)) ++ { ++ p_145892_1_.markDirty(); ++ } ++ else ++ { ++ p_145892_1_.setInventorySlotContents(p_145892_2_, itemstack1); ++ } ++ ++ // CraftBukkit end + return true; + } + +@@ -451,6 +609,20 @@ + } + else + { ++ // CraftBukkit start ++ // Cauldron start - vanilla compatibility ++ if (p_145898_0_.getOwner() != null && p_145898_1_.getBukkitEntity() != null) ++ { ++ InventoryPickupItemEvent event = new InventoryPickupItemEvent(p_145898_0_.getOwner().getInventory(), (org.bukkit.entity.Item) p_145898_1_.getBukkitEntity()); ++ p_145898_1_.worldObj.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return false; ++ } ++ } ++ // Cauldron end ++ // CraftBukkit end + ItemStack itemstack = p_145898_1_.getEntityItem().copy(); + ItemStack itemstack1 = func_145889_a(p_145898_0_, itemstack, -1); + diff --git a/patches/net/minecraft/tileentity/TileEntityNote.java.patch b/patches/net/minecraft/tileentity/TileEntityNote.java.patch new file mode 100644 index 0000000..834cbaa --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntityNote.java.patch @@ -0,0 +1,27 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityNote.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityNote.java +@@ -68,7 +68,23 @@ + b0 = 4; + } + +- p_145878_1_.addBlockEvent(p_145878_2_, p_145878_3_, p_145878_4_, Blocks.noteblock, b0, this.note); ++ // CraftBukkit start ++ org.bukkit.event.block.NotePlayEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callNotePlayEvent(this.worldObj, p_145878_2_, p_145878_3_, p_145878_4_, b0, this.note); ++ ++ if (!event.isCancelled()) ++ { ++ this.worldObj.addBlockEvent(p_145878_2_, p_145878_3_, p_145878_4_, Blocks.noteblock, event.getInstrument().getType(), event.getNote().getId()); ++ } ++ ++ // CraftBukkit end + } + } ++ ++ // Cauldron start ++ @Override ++ public boolean canUpdate() ++ { ++ return false; ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraft/tileentity/TileEntityPiston.java.patch b/patches/net/minecraft/tileentity/TileEntityPiston.java.patch new file mode 100644 index 0000000..450ce59 --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntityPiston.java.patch @@ -0,0 +1,14 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntityPiston.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntityPiston.java +@@ -140,6 +140,11 @@ + + public void updateEntity() + { ++ if (this.worldObj == null) ++ { ++ return; // CraftBukkit ++ } ++ + this.lastProgress = this.progress; + + if (this.lastProgress >= 1.0F) diff --git a/patches/net/minecraft/tileentity/TileEntitySign.java.patch b/patches/net/minecraft/tileentity/TileEntitySign.java.patch new file mode 100644 index 0000000..0396749 --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntitySign.java.patch @@ -0,0 +1,59 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntitySign.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntitySign.java +@@ -11,7 +11,7 @@ + { + public String[] signText = new String[] {"", "", "", ""}; + public int lineBeingEdited = -1; +- private boolean field_145916_j = true; ++ public boolean field_145916_j = true; // CraftBukkit - private -> public + private EntityPlayer field_145917_k; + private static final String __OBFID = "CL_00000363"; + +@@ -43,7 +43,19 @@ + public Packet getDescriptionPacket() + { + String[] astring = new String[4]; +- System.arraycopy(this.signText, 0, astring, 0, 4); ++ ++ // CraftBukkit start - Limit sign text to 15 chars per line ++ for (int i = 0; i < 4; ++i) ++ { ++ astring[i] = this.signText[i]; ++ ++ if (this.signText[i].length() > 15) ++ { ++ astring[i] = this.signText[i].substring(0, 15); ++ } ++ } ++ ++ // CraftBukkit end + return new S33PacketUpdateSign(this.xCoord, this.yCoord, this.zCoord, astring); + } + +@@ -72,4 +84,26 @@ + { + return this.field_145917_k; + } ++ ++ // CraftBukkit start - central method to limit sign text to 15 chars per line ++ public static String[] sanitizeLines(String[] lines) { ++ String[] astring = new String[4]; ++ for (int i = 0; i < 4; ++i) { ++ astring[i] = lines[i]; ++ ++ if (lines[i].length() > 15) { ++ astring[i] = lines[i].substring(0, 15); ++ } ++ } ++ return astring; ++ } ++ // CraftBukkit end ++ ++ // Cauldron start ++ @Override ++ public boolean canUpdate() ++ { ++ return false; ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraft/tileentity/TileEntitySkull.java.patch b/patches/net/minecraft/tileentity/TileEntitySkull.java.patch new file mode 100644 index 0000000..8e19707 --- /dev/null +++ b/patches/net/minecraft/tileentity/TileEntitySkull.java.patch @@ -0,0 +1,31 @@ +--- ../src-base/minecraft/net/minecraft/tileentity/TileEntitySkull.java ++++ ../src-work/minecraft/net/minecraft/tileentity/TileEntitySkull.java +@@ -79,6 +79,14 @@ + this.func_152109_d(); + } + ++ // Cauldron start ++ @Override ++ public boolean canUpdate() ++ { ++ return false; ++ } ++ // Cauldron end ++ + private void func_152109_d() + { + if (this.field_152110_j != null && !StringUtils.isNullOrEmpty(this.field_152110_j.getName())) +@@ -113,6 +121,13 @@ + this.field_145910_i = p_145903_1_; + } + ++ // CraftBukkit start ++ public int getRotation() ++ { ++ return this.field_145910_i; ++ } ++ // CraftBukkit end ++ + @SideOnly(Side.CLIENT) + public int func_145906_b() + { diff --git a/patches/net/minecraft/util/EntityDamageSourceIndirect.java.patch b/patches/net/minecraft/util/EntityDamageSourceIndirect.java.patch new file mode 100644 index 0000000..95cb10a --- /dev/null +++ b/patches/net/minecraft/util/EntityDamageSourceIndirect.java.patch @@ -0,0 +1,14 @@ +--- ../src-base/minecraft/net/minecraft/util/EntityDamageSourceIndirect.java ++++ ../src-work/minecraft/net/minecraft/util/EntityDamageSourceIndirect.java +@@ -33,4 +33,11 @@ + String s1 = s + ".item"; + return itemstack != null && itemstack.hasDisplayName() && StatCollector.canTranslate(s1) ? new ChatComponentTranslation(s1, new Object[] {p_151519_1_.func_145748_c_(), ichatcomponent, itemstack.func_151000_E()}): new ChatComponentTranslation(s, new Object[] {p_151519_1_.func_145748_c_(), ichatcomponent}); + } ++ ++ // CraftBukkit start ++ public Entity getProximateDamageSource() ++ { ++ return super.getEntity(); ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/util/FoodStats.java.patch b/patches/net/minecraft/util/FoodStats.java.patch new file mode 100644 index 0000000..262621b --- /dev/null +++ b/patches/net/minecraft/util/FoodStats.java.patch @@ -0,0 +1,85 @@ +--- ../src-base/minecraft/net/minecraft/util/FoodStats.java ++++ ../src-work/minecraft/net/minecraft/util/FoodStats.java +@@ -7,16 +7,31 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.world.EnumDifficulty; ++// CraftBukkit start ++import net.minecraft.entity.player.EntityPlayerMP; ++import net.minecraft.network.play.server.S06PacketUpdateHealth; ++// CraftBukkit end + + public class FoodStats + { +- private int foodLevel = 20; +- private float foodSaturationLevel = 5.0F; +- private float foodExhaustionLevel; +- private int foodTimer; ++ // CraftBukkit start - All made public ++ public int foodLevel = 20; ++ public float foodSaturationLevel = 5.0F; ++ public float foodExhaustionLevel; ++ public int foodTimer; ++ private EntityPlayer entityplayer; ++ // CraftBukkit end + private int prevFoodLevel = 20; + private static final String __OBFID = "CL_00001729"; + ++ // CraftBukkit start - added EntityPlayer constructor ++ public FoodStats(EntityPlayer entityplayer) ++ { ++ org.apache.commons.lang.Validate.notNull(entityplayer); ++ this.entityplayer = entityplayer; ++ } ++ // CraftBukkit end ++ + public void addStats(int p_75122_1_, float p_75122_2_) + { + this.foodLevel = Math.min(p_75122_1_ + this.foodLevel, 20); +@@ -25,7 +40,17 @@ + + public void func_151686_a(ItemFood p_151686_1_, ItemStack p_151686_2_) + { +- this.addStats(p_151686_1_.func_150905_g(p_151686_2_), p_151686_1_.func_150906_h(p_151686_2_)); ++ // CraftBukkit start ++ int oldFoodLevel = foodLevel; ++ org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(entityplayer, p_151686_1_.func_150905_g(p_151686_2_) + oldFoodLevel); ++ ++ if (!event.isCancelled()) ++ { ++ this.addStats(event.getFoodLevel() - oldFoodLevel, p_151686_1_.func_150906_h(p_151686_2_)); ++ } ++ ++ ((EntityPlayerMP) entityplayer).playerNetServerHandler.sendPacket(new S06PacketUpdateHealth(((EntityPlayerMP) entityplayer).getBukkitEntity().getScaledHealth(), entityplayer.getFoodStats().foodLevel, entityplayer.getFoodStats().foodSaturationLevel)); ++ // CraftBukkit end + } + + public void onUpdate(EntityPlayer p_75118_1_) +@@ -43,7 +68,16 @@ + } + else if (enumdifficulty != EnumDifficulty.PEACEFUL) + { +- this.foodLevel = Math.max(this.foodLevel - 1, 0); ++ // CraftBukkit start ++ org.bukkit.event.entity.FoodLevelChangeEvent event = org.bukkit.craftbukkit.event.CraftEventFactory.callFoodLevelChangeEvent(p_75118_1_, Math.max(this.foodLevel - 1, 0)); ++ ++ if (!event.isCancelled()) ++ { ++ this.foodLevel = event.getFoodLevel(); ++ } ++ ++ ((EntityPlayerMP) p_75118_1_).playerNetServerHandler.sendPacket(new S06PacketUpdateHealth(((EntityPlayerMP) p_75118_1_).getBukkitEntity().getScaledHealth(), this.foodLevel, this.foodSaturationLevel)); ++ // CraftBukkit end + } + } + +@@ -53,7 +87,8 @@ + + if (this.foodTimer >= 80) + { +- p_75118_1_.heal(1.0F); ++ // CraftBukkit - added RegainReason ++ p_75118_1_.heal(1.0F, org.bukkit.event.entity.EntityRegainHealthEvent.RegainReason.SATIATED); + this.addExhaustion(3.0F); + this.foodTimer = 0; + } diff --git a/patches/net/minecraft/util/IntHashMap.java.patch b/patches/net/minecraft/util/IntHashMap.java.patch new file mode 100644 index 0000000..a581f46 --- /dev/null +++ b/patches/net/minecraft/util/IntHashMap.java.patch @@ -0,0 +1,29 @@ +--- ../src-base/minecraft/net/minecraft/util/IntHashMap.java ++++ ../src-work/minecraft/net/minecraft/util/IntHashMap.java +@@ -10,7 +10,7 @@ + private int threshold = 12; + private final float growFactor = 0.75F; + private transient volatile int versionStamp; +- private Set keySet = new HashSet(); ++ // private Set keySet = new HashSet(); // CraftBukkit - expensive and unused + private static final String __OBFID = "CL_00001490"; + + private static int computeHash(int p_76044_0_) +@@ -61,7 +61,7 @@ + + public void addKey(int p_76038_1_, Object p_76038_2_) + { +- this.keySet.add(Integer.valueOf(p_76038_1_)); ++ //this.keySet.add(Integer.valueOf(p_76038_1_)); // CraftBukkit + int j = computeHash(p_76038_1_); + int k = getSlotIndex(j, this.slots.length); + +@@ -125,7 +125,7 @@ + + public Object removeObject(int p_76049_1_) + { +- this.keySet.remove(Integer.valueOf(p_76049_1_)); ++ //this.keySet.remove(Integer.valueOf(p_76049_1_)); // CraftBukkit + IntHashMap.Entry entry = this.removeEntry(p_76049_1_); + return entry == null ? null : entry.valueEntry; + } diff --git a/patches/net/minecraft/util/RegistryNamespaced.java.patch b/patches/net/minecraft/util/RegistryNamespaced.java.patch new file mode 100644 index 0000000..5b4f8f3 --- /dev/null +++ b/patches/net/minecraft/util/RegistryNamespaced.java.patch @@ -0,0 +1,36 @@ +--- ../src-base/minecraft/net/minecraft/util/RegistryNamespaced.java ++++ ../src-work/minecraft/net/minecraft/util/RegistryNamespaced.java +@@ -5,6 +5,11 @@ + import java.util.Iterator; + import java.util.Map; + ++// Cauldron start ++import cpw.mods.fml.common.FMLLog; ++import net.minecraft.block.Block; ++// Cauldron end ++ + public class RegistryNamespaced extends RegistrySimple implements IObjectIntIterable + { + protected ObjectIntIdentityMap underlyingIntegerMap = new ObjectIntIdentityMap(); +@@ -18,6 +23,21 @@ + + public void addObject(int p_148756_1_, String p_148756_2_, Object p_148756_3_) + { ++ // Cauldron start - register item/block materials for Bukkit ++ boolean isForgeBlock = p_148756_3_ instanceof Block && (p_148756_3_.getClass().getName().length() > 3 && !p_148756_3_.getClass().getName().startsWith("net.minecraft.block")) ? true : false; ++ org.bukkit.Material material = org.bukkit.Material.addMaterial(p_148756_1_, p_148756_2_, isForgeBlock); ++ if (material != null) ++ { ++ if (isForgeBlock) ++ { ++ FMLLog.info("Injected new Forge block material %s with ID %d.", material.name(), material.getId()); ++ } ++ else ++ { ++ FMLLog.info("Injected new Forge item material %s with ID %d.", material.name(), material.getId()); ++ } ++ } ++ // Cauldron end + this.underlyingIntegerMap.func_148746_a(p_148756_3_, p_148756_1_); + this.putObject(ensureNamespaced(p_148756_2_), p_148756_3_); + } diff --git a/patches/net/minecraft/util/WeightedRandomFishable.java.patch b/patches/net/minecraft/util/WeightedRandomFishable.java.patch new file mode 100644 index 0000000..f5fa100 --- /dev/null +++ b/patches/net/minecraft/util/WeightedRandomFishable.java.patch @@ -0,0 +1,17 @@ +--- ../src-base/minecraft/net/minecraft/util/WeightedRandomFishable.java ++++ ../src-work/minecraft/net/minecraft/util/WeightedRandomFishable.java +@@ -6,9 +6,11 @@ + + public class WeightedRandomFishable extends WeightedRandom.Item + { +- private final ItemStack field_150711_b; +- private float field_150712_c; +- private boolean field_150710_d; ++ // Cauldron start - private -> public ++ public final ItemStack field_150711_b; ++ public float field_150712_c; ++ public boolean field_150710_d; ++ // Cauldron end + private static final String __OBFID = "CL_00001664"; + + public WeightedRandomFishable(ItemStack p_i45317_1_, int p_i45317_2_) diff --git a/patches/net/minecraft/village/Village.java.patch b/patches/net/minecraft/village/Village.java.patch new file mode 100644 index 0000000..095ddd2 --- /dev/null +++ b/patches/net/minecraft/village/Village.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/village/Village.java ++++ ../src-work/minecraft/net/minecraft/village/Village.java +@@ -71,7 +71,7 @@ + { + EntityIronGolem entityirongolem = new EntityIronGolem(this.worldObj); + entityirongolem.setPosition(vec3.xCoord, vec3.yCoord, vec3.zCoord); +- this.worldObj.spawnEntityInWorld(entityirongolem); ++ this.worldObj.addEntity(entityirongolem, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_DEFENSE); // CraftBukkit + ++this.numIronGolems; + } + } diff --git a/patches/net/minecraft/village/VillageSiege.java.patch b/patches/net/minecraft/village/VillageSiege.java.patch new file mode 100644 index 0000000..1abb5c8 --- /dev/null +++ b/patches/net/minecraft/village/VillageSiege.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/village/VillageSiege.java ++++ ../src-work/minecraft/net/minecraft/village/VillageSiege.java +@@ -196,7 +196,7 @@ + } + + entityzombie.setLocationAndAngles(vec3.xCoord, vec3.yCoord, vec3.zCoord, this.worldObj.rand.nextFloat() * 360.0F, 0.0F); +- this.worldObj.spawnEntityInWorld(entityzombie); ++ this.worldObj.addEntity(entityzombie, org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason.VILLAGE_INVASION); // CraftBukkit + ChunkCoordinates chunkcoordinates = this.theVillage.getCenter(); + entityzombie.setHomeArea(chunkcoordinates.posX, chunkcoordinates.posY, chunkcoordinates.posZ, this.theVillage.getVillageRadius()); + return true; diff --git a/patches/net/minecraft/world/Explosion.java.patch b/patches/net/minecraft/world/Explosion.java.patch new file mode 100644 index 0000000..6eee678 --- /dev/null +++ b/patches/net/minecraft/world/Explosion.java.patch @@ -0,0 +1,117 @@ +--- ../src-base/minecraft/net/minecraft/world/Explosion.java ++++ ../src-work/minecraft/net/minecraft/world/Explosion.java +@@ -20,6 +20,12 @@ + import net.minecraft.util.MathHelper; + import net.minecraft.util.Vec3; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.entity.EntityExplodeEvent; ++import org.bukkit.Location; ++// CraftBukkit end ++ + public class Explosion + { + public boolean isFlaming; +@@ -34,6 +40,7 @@ + public float explosionSize; + public List affectedBlockPositions = new ArrayList(); + private Map field_77288_k = new HashMap(); ++ public boolean wasCanceled = false; // CraftBukkit + private static final String __OBFID = "CL_00000134"; + + public Explosion(World p_i1948_1_, Entity p_i1948_2_, double p_i1948_3_, double p_i1948_5_, double p_i1948_7_, float p_i1948_9_) +@@ -48,6 +55,12 @@ + + public void doExplosionA() + { ++ // CraftBukkit start ++ if (this.explosionSize < 0.1F) ++ { ++ return; ++ } ++ // CraftBukkit end + float f = this.explosionSize; + HashSet hashset = new HashSet(); + int i; +@@ -135,7 +148,15 @@ + d7 /= d9; + double d10 = (double)this.worldObj.getBlockDensity(vec3, entity.boundingBox); + double d11 = (1.0D - d4) * d10; +- entity.attackEntityFrom(DamageSource.setExplosionSource(this), (float)((int)((d11 * d11 + d11) / 2.0D * 8.0D * (double)this.explosionSize + 1.0D))); ++ // CraftBukkit start ++ CraftEventFactory.entityDamage = exploder; ++ if (!entity.attackEntityFrom(DamageSource.setExplosionSource(this), (float) ((int) ((d11 * d11 + d11) / 2.0D * 8.0D ++ * (double) this.explosionSize + 1.0D)))) ++ { ++ CraftEventFactory.entityDamage = null; ++ continue; ++ } ++ // CraftBukkit end + double d8 = EnchantmentProtection.func_92092_a(entity, d11); + entity.motionX += d5 * d8; + entity.motionY += d6 * d8; +@@ -174,6 +195,39 @@ + + if (this.isSmoking) + { ++ // CraftBukkit start ++ org.bukkit.World bworld = this.worldObj.getWorld(); ++ org.bukkit.entity.Entity explode = this.exploder == null ? null : this.exploder.getBukkitEntity(); ++ Location location = new Location(bworld, this.explosionX, this.explosionY, this.explosionZ); ++ List blockList = new ArrayList(); ++ ++ for (int i1 = this.affectedBlockPositions.size() - 1; i1 >= 0; i1--) ++ { ++ ChunkPosition cpos = (ChunkPosition) this.affectedBlockPositions.get(i1); ++ org.bukkit.block.Block bblock = bworld.getBlockAt(cpos.chunkPosX, cpos.chunkPosY, cpos.chunkPosZ); ++ ++ if (bblock.getType() != org.bukkit.Material.AIR) ++ { ++ blockList.add(bblock); ++ } ++ } ++ ++ EntityExplodeEvent event = new EntityExplodeEvent(explode, location, blockList, 0.3F); ++ this.worldObj.getServer().getPluginManager().callEvent(event); ++ this.affectedBlockPositions.clear(); ++ ++ for (org.bukkit.block.Block bblock : event.blockList()) ++ { ++ ChunkPosition coords = new ChunkPosition(bblock.getX(), bblock.getY(), bblock.getZ()); ++ affectedBlockPositions.add(coords); ++ } ++ ++ if (event.isCancelled()) ++ { ++ this.wasCanceled = true; ++ return; ++ } ++ // CraftBukkit end + iterator = this.affectedBlockPositions.iterator(); + + while (iterator.hasNext()) +@@ -209,7 +263,8 @@ + { + if (block.canDropFromExplosion(this)) + { +- block.dropBlockAsItemWithChance(this.worldObj, i, j, k, this.worldObj.getBlockMetadata(i, j, k), 1.0F / this.explosionSize, 0); ++ // CraftBukkit - add yield ++ block.dropBlockAsItemWithChance(this.worldObj, i, j, k, this.worldObj.getBlockMetadata(i, j, k), event.getYield(), 0); + } + + block.onBlockExploded(this.worldObj, i, j, k, this); +@@ -232,7 +287,12 @@ + + if (block.getMaterial() == Material.air && block1.func_149730_j() && this.explosionRNG.nextInt(3) == 0) + { +- this.worldObj.setBlock(i, j, k, Blocks.fire); ++ // CraftBukkit start - Ignition by explosion ++ if (!org.bukkit.craftbukkit.event.CraftEventFactory.callBlockIgniteEvent(this.worldObj, i, j, k, this).isCancelled()) ++ { ++ this.worldObj.setBlock(i, j, k, Blocks.fire); ++ } ++ // CraftBukkit end + } + } + } diff --git a/patches/net/minecraft/world/SpawnerAnimals.java.patch b/patches/net/minecraft/world/SpawnerAnimals.java.patch new file mode 100644 index 0000000..5b040f0 --- /dev/null +++ b/patches/net/minecraft/world/SpawnerAnimals.java.patch @@ -0,0 +1,130 @@ +--- ../src-base/minecraft/net/minecraft/world/SpawnerAnimals.java ++++ ../src-work/minecraft/net/minecraft/world/SpawnerAnimals.java +@@ -22,9 +22,15 @@ + import cpw.mods.fml.common.eventhandler.Event.Result; + import net.minecraftforge.event.ForgeEventFactory; + ++// CraftBukkit start ++import org.bukkit.craftbukkit.util.LongHash; ++import org.bukkit.craftbukkit.util.LongObjectHashMap; ++import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; ++// CraftBukkit end ++ + public final class SpawnerAnimals + { +- private HashMap eligibleChunksForSpawning = new HashMap(); ++ private LongObjectHashMap eligibleChunksForSpawning = new LongObjectHashMap(); // CraftBukkit - HashMap -> LongObjectHashMap + private static final String __OBFID = "CL_00000152"; + + protected static ChunkPosition func_151350_a(World p_151350_0_, int p_151350_1_, int p_151350_2_) +@@ -54,22 +60,30 @@ + int j = MathHelper.floor_double(entityplayer.posX / 16.0D); + k = MathHelper.floor_double(entityplayer.posZ / 16.0D); + byte b0 = 8; ++ // Spigot Start ++ b0 = p_77192_1_.getSpigotConfig().mobSpawnRange; // Cauldron ++ b0 = (b0 > p_77192_1_.getSpigotConfig().viewDistance) ? (byte) p_77192_1_.spigotConfig.viewDistance : b0; // Cauldron ++ b0 = (b0 > 8) ? 8 : b0; ++ // Spigot End + + for (int l = -b0; l <= b0; ++l) + { + for (int i1 = -b0; i1 <= b0; ++i1) + { + boolean flag3 = l == -b0 || l == b0 || i1 == -b0 || i1 == b0; +- ChunkCoordIntPair chunkcoordintpair = new ChunkCoordIntPair(l + j, i1 + k); ++ // CraftBukkit start ++ long chunkCoords = LongHash.toLong(l + j, i1 + k); + + if (!flag3) + { +- this.eligibleChunksForSpawning.put(chunkcoordintpair, Boolean.valueOf(false)); ++ this.eligibleChunksForSpawning.put(chunkCoords, false); + } +- else if (!this.eligibleChunksForSpawning.containsKey(chunkcoordintpair)) ++ else if (!this.eligibleChunksForSpawning.containsKey(chunkCoords)) + { +- this.eligibleChunksForSpawning.put(chunkcoordintpair, Boolean.valueOf(true)); ++ this.eligibleChunksForSpawning.put(chunkCoords, true); + } ++ ++ // CraftBukkit end + } + } + } +@@ -82,22 +96,46 @@ + for (int k3 = 0; k3 < k; ++k3) + { + EnumCreatureType enumcreaturetype = aenumcreaturetype[k3]; ++ // CraftBukkit start - Use per-world spawn limits ++ int limit = enumcreaturetype.getMaxNumberOfCreature(); + +- if ((!enumcreaturetype.getPeacefulCreature() || p_77192_3_) && (enumcreaturetype.getPeacefulCreature() || p_77192_2_) && (!enumcreaturetype.getAnimal() || p_77192_4_) && p_77192_1_.countEntities(enumcreaturetype, true) <= enumcreaturetype.getMaxNumberOfCreature() * this.eligibleChunksForSpawning.size() / 256) ++ switch (enumcreaturetype) + { ++ case monster: ++ limit = p_77192_1_.getWorld().getMonsterSpawnLimit(); ++ break; ++ case creature: ++ limit = p_77192_1_.getWorld().getAnimalSpawnLimit(); ++ break; ++ case waterCreature: ++ limit = p_77192_1_.getWorld().getWaterAnimalSpawnLimit(); ++ break; ++ case ambient: ++ limit = p_77192_1_.getWorld().getAmbientSpawnLimit(); ++ break; ++ } ++ ++ if (limit == 0) ++ { ++ continue; ++ } ++ ++ // CraftBukkit end ++ ++ if ((!enumcreaturetype.getPeacefulCreature() || p_77192_3_) && (enumcreaturetype.getPeacefulCreature() || p_77192_2_) && (!enumcreaturetype.getAnimal() || p_77192_4_) && p_77192_1_.countEntities(enumcreaturetype.getCreatureClass()) <= limit * eligibleChunksForSpawning.size() / 256) // CraftBukkit - use per-world limits ++ { + Iterator iterator = this.eligibleChunksForSpawning.keySet().iterator(); +- ArrayList tmp = new ArrayList(eligibleChunksForSpawning.keySet()); +- Collections.shuffle(tmp); +- iterator = tmp.iterator(); + label110: + + while (iterator.hasNext()) + { +- ChunkCoordIntPair chunkcoordintpair1 = (ChunkCoordIntPair)iterator.next(); ++ // CraftBukkit start ++ long key = ((Long) iterator.next()).longValue(); + +- if (!((Boolean)this.eligibleChunksForSpawning.get(chunkcoordintpair1)).booleanValue()) ++ if (!(this.eligibleChunksForSpawning.get(key))) + { +- ChunkPosition chunkposition = func_151350_a(p_77192_1_, chunkcoordintpair1.chunkXPos, chunkcoordintpair1.chunkZPos); ++ ChunkPosition chunkposition = func_151350_a(p_77192_1_, LongHash.msw(key), LongHash.lsw(key)); ++ // CraftBukkit end + int j1 = chunkposition.chunkPosX; + int k1 = chunkposition.chunkPosY; + int l1 = chunkposition.chunkPosZ; +@@ -170,7 +208,8 @@ + if (canSpawn == Result.ALLOW || (canSpawn == Result.DEFAULT && entityliving.getCanSpawnHere())) + { + ++i2; +- p_77192_1_.spawnEntityInWorld(entityliving); ++ // CraftBukkit start - Added a reason for spawning this creature, moved entityliving.onSpawnWithEgg(ientitylivingdata) up ++ p_77192_1_.addEntity(entityliving, SpawnReason.NATURAL); + if (!ForgeEventFactory.doSpecialSpawn(entityliving, p_77192_1_, f, f1, f2)) + { + ientitylivingdata = entityliving.onSpawnWithEgg(ientitylivingdata); +@@ -266,8 +305,10 @@ + } + + entityliving.setLocationAndAngles((double)f, (double)f1, (double)f2, p_77191_6_.nextFloat() * 360.0F, 0.0F); +- p_77191_0_.spawnEntityInWorld(entityliving); ++ // CraftBukkit start - Added a reason for spawning this creature, moved entityliving.a(ientitylivingdata) up + ientitylivingdata = entityliving.onSpawnWithEgg(ientitylivingdata); ++ p_77191_0_.addEntity(entityliving, SpawnReason.CHUNK_GEN); ++ // CraftBukkit end + flag = true; + } + diff --git a/patches/net/minecraft/world/Teleporter.java.patch b/patches/net/minecraft/world/Teleporter.java.patch new file mode 100644 index 0000000..e09bfa5 --- /dev/null +++ b/patches/net/minecraft/world/Teleporter.java.patch @@ -0,0 +1,838 @@ +--- ../src-base/minecraft/net/minecraft/world/Teleporter.java ++++ ../src-work/minecraft/net/minecraft/world/Teleporter.java +@@ -12,6 +12,12 @@ + import net.minecraft.util.LongHashMap; + import net.minecraft.util.MathHelper; + ++// CraftBukkit start ++import org.bukkit.Location; ++import org.bukkit.event.entity.EntityPortalExitEvent; ++import org.bukkit.util.Vector; ++// CraftBukkit end ++ + public class Teleporter + { + private final WorldServer worldServerInstance; +@@ -20,100 +26,172 @@ + private final List destinationCoordinateKeys = new ArrayList(); + private static final String __OBFID = "CL_00000153"; + +- public Teleporter(WorldServer p_i1963_1_) ++ public Teleporter(WorldServer par1WorldServer) + { +- this.worldServerInstance = p_i1963_1_; +- this.random = new Random(p_i1963_1_.getSeed()); ++ this.worldServerInstance = par1WorldServer; ++ this.random = new Random(par1WorldServer.getSeed()); + } + +- public void placeInPortal(Entity p_77185_1_, double p_77185_2_, double p_77185_4_, double p_77185_6_, float p_77185_8_) ++ public void placeInPortal(Entity par1Entity, double par2, double par4, double par6, float par8) + { + if (this.worldServerInstance.provider.dimensionId != 1) + { +- if (!this.placeInExistingPortal(p_77185_1_, p_77185_2_, p_77185_4_, p_77185_6_, p_77185_8_)) ++ if (!this.placeInExistingPortal(par1Entity, par2, par4, par6, par8)) + { +- this.makePortal(p_77185_1_); +- this.placeInExistingPortal(p_77185_1_, p_77185_2_, p_77185_4_, p_77185_6_, p_77185_8_); ++ this.makePortal(par1Entity); ++ this.placeInExistingPortal(par1Entity, par2, par4, par6, par8); + } + } + else + { +- int i = MathHelper.floor_double(p_77185_1_.posX); +- int j = MathHelper.floor_double(p_77185_1_.posY) - 1; +- int k = MathHelper.floor_double(p_77185_1_.posZ); +- byte b0 = 1; +- byte b1 = 0; ++ // CraftBukkit start - Modularize end portal creation ++ ChunkCoordinates created = this.createEndPortal(par2, par4, par6); ++ par1Entity.setLocationAndAngles((double) created.posX, (double) created.posY, (double) created.posZ, par1Entity.rotationYaw, 0.0F); ++ par1Entity.motionX = par1Entity.motionY = par1Entity.motionZ = 0.0D; ++ } ++ } + +- for (int l = -2; l <= 2; ++l) ++ // Split out from original a(Entity, double, double, double, float) method in order to enable being called from createPortal ++ private ChunkCoordinates createEndPortal(double x, double y, double z) ++ { ++ int i = MathHelper.floor_double(x); ++ int j = MathHelper.floor_double(y) - 1; ++ int k = MathHelper.floor_double(z); ++ // CraftBukkit end ++ byte b0 = 1; ++ byte b1 = 0; ++ ++ for (int l = -2; l <= 2; ++l) ++ { ++ for (int i1 = -2; i1 <= 2; ++i1) + { +- for (int i1 = -2; i1 <= 2; ++i1) ++ for (int j1 = -1; j1 < 3; ++j1) + { +- for (int j1 = -1; j1 < 3; ++j1) ++ int k1 = i + i1 * b0 + l * b1; ++ int l1 = j + j1; ++ int i2 = k + i1 * b1 - l * b0; ++ boolean flag = j1 < 0; ++ this.worldServerInstance.setBlock(k1, l1, i2, flag ? Blocks.obsidian : Blocks.air); ++ } ++ } ++ } ++ ++ // CraftBukkit start ++ return new ChunkCoordinates(i, j, k); ++ } ++ ++ // use logic based on creation to verify end portal ++ private ChunkCoordinates findEndPortal(ChunkCoordinates portal) ++ { ++ int i = portal.posX; ++ int j = portal.posY - 1; ++ int k = portal.posZ; ++ byte b0 = 1; ++ byte b1 = 0; ++ ++ for (int l = -2; l <= 2; ++l) ++ { ++ for (int i1 = -2; i1 <= 2; ++i1) ++ { ++ for (int j1 = -1; j1 < 3; ++j1) ++ { ++ int k1 = i + i1 * b0 + l * b1; ++ int l1 = j + j1; ++ int i2 = k + i1 * b1 - l * b0; ++ boolean flag = j1 < 0; ++ ++ if (this.worldServerInstance.getBlock(k1, l1, i2) != (flag ? Blocks.obsidian : Blocks.air)) + { +- int k1 = i + i1 * b0 + l * b1; +- int l1 = j + j1; +- int i2 = k + i1 * b1 - l * b0; +- boolean flag = j1 < 0; +- this.worldServerInstance.setBlock(k1, l1, i2, flag ? Blocks.obsidian : Blocks.air); ++ return null; + } + } + } ++ } + +- p_77185_1_.setLocationAndAngles((double)i, (double)j, (double)k, p_77185_1_.rotationYaw, 0.0F); +- p_77185_1_.motionX = p_77185_1_.motionY = p_77185_1_.motionZ = 0.0D; ++ return new ChunkCoordinates(i, j, k); ++ } ++ // CraftBukkit end ++ ++ public boolean placeInExistingPortal(Entity par1Entity, double par2, double par4, double par6, float par8) ++ { ++ // CraftBukkit start - Modularize portal search process and entity teleportation ++ ChunkCoordinates found = this.findPortal(par1Entity.posX, par1Entity.posY, par1Entity.posZ, 128); ++ ++ if (found == null) ++ { ++ return false; + } ++ ++ Location exit = new Location(this.worldServerInstance.getWorld(), found.posX, found.posY, found.posZ, par8, par1Entity.rotationPitch); ++ Vector velocity = par1Entity.getBukkitEntity().getVelocity(); ++ this.adjustExit(par1Entity, exit, velocity); ++ par1Entity.setLocationAndAngles(exit.getX(), exit.getY(), exit.getZ(), exit.getYaw(), exit.getPitch()); ++ ++ if (par1Entity.motionX != velocity.getX() || par1Entity.motionY != velocity.getY() || par1Entity.motionZ != velocity.getZ()) ++ { ++ par1Entity.getBukkitEntity().setVelocity(velocity); ++ } ++ ++ return true; + } + +- public boolean placeInExistingPortal(Entity p_77184_1_, double p_77184_2_, double p_77184_4_, double p_77184_6_, float p_77184_8_) ++ public ChunkCoordinates findPortal(double x, double y, double z, int short1) + { +- short short1 = 128; ++ if (this.worldServerInstance.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END) ++ { ++ return this.findEndPortal(this.worldServerInstance.provider.getEntrancePortalLocation()); ++ } ++ ++ // CraftBukkit end + double d3 = -1.0D; + int i = 0; + int j = 0; + int k = 0; +- int l = MathHelper.floor_double(p_77184_1_.posX); +- int i1 = MathHelper.floor_double(p_77184_1_.posZ); ++ // CraftBukkit start ++ int l = MathHelper.floor_double(x); ++ int i1 = MathHelper.floor_double(z); ++ // CraftBukkit end + long j1 = ChunkCoordIntPair.chunkXZ2Int(l, i1); + boolean flag = true; +- double d7; +- int l3; ++ double d4; ++ int k1; + + if (this.destinationCoordinateCache.containsItem(j1)) + { +- Teleporter.PortalPosition portalposition = (Teleporter.PortalPosition)this.destinationCoordinateCache.getValueByKey(j1); ++ PortalPosition chunkcoordinatesportal = (PortalPosition) this.destinationCoordinateCache.getValueByKey(j1); + d3 = 0.0D; +- i = portalposition.posX; +- j = portalposition.posY; +- k = portalposition.posZ; +- portalposition.lastUpdateTime = this.worldServerInstance.getTotalWorldTime(); ++ i = chunkcoordinatesportal.posX; ++ j = chunkcoordinatesportal.posY; ++ k = chunkcoordinatesportal.posZ; ++ chunkcoordinatesportal.lastUpdateTime = this.worldServerInstance.getTotalWorldTime(); + flag = false; + } + else + { +- for (l3 = l - short1; l3 <= l + short1; ++l3) ++ for (k1 = l - short1; k1 <= l + short1; ++k1) + { +- double d4 = (double)l3 + 0.5D - p_77184_1_.posX; ++ double d5 = (double) k1 + 0.5D - x; // CraftBukkit + + for (int l1 = i1 - short1; l1 <= i1 + short1; ++l1) + { +- double d5 = (double)l1 + 0.5D - p_77184_1_.posZ; ++ double d6 = (double) l1 + 0.5D - z; // CraftBukkit + + for (int i2 = this.worldServerInstance.getActualHeight() - 1; i2 >= 0; --i2) + { +- if (this.worldServerInstance.getBlock(l3, i2, l1) == Blocks.portal) ++ if (this.worldServerInstance.getBlock(k1, i2, l1) == Blocks.portal) + { +- while (this.worldServerInstance.getBlock(l3, i2 - 1, l1) == Blocks.portal) ++ while (this.worldServerInstance.getBlock(k1, i2 - 1, l1) == Blocks.portal) + { + --i2; + } + +- d7 = (double)i2 + 0.5D - p_77184_1_.posY; +- double d8 = d4 * d4 + d7 * d7 + d5 * d5; ++ d4 = (double) i2 + 0.5D - y; // CraftBukkit ++ double d7 = d5 * d5 + d4 * d4 + d6 * d6; + +- if (d3 < 0.0D || d8 < d3) ++ if (d3 < 0.0D || d7 < d3) + { +- d3 = d8; +- i = l3; ++ d3 = d7; ++ i = k1; + j = i2; + k = l1; + } +@@ -127,61 +205,93 @@ + { + if (flag) + { +- this.destinationCoordinateCache.add(j1, new Teleporter.PortalPosition(i, j, k, this.worldServerInstance.getTotalWorldTime())); ++ this.destinationCoordinateCache.add(j1, new PortalPosition(i, j, k, this.worldServerInstance.getTotalWorldTime())); + this.destinationCoordinateKeys.add(Long.valueOf(j1)); + } + +- double d11 = (double)i + 0.5D; +- double d6 = (double)j + 0.5D; +- d7 = (double)k + 0.5D; +- int i4 = -1; ++ // CraftBukkit start - Moved entity teleportation logic into exit ++ return new ChunkCoordinates(i, j, k); ++ } ++ else ++ { ++ return null; ++ } ++ } ++ // Entity repositioning logic split out from original b method and combined with repositioning logic for The End from original a method ++ public void adjustExit(Entity entity, Location position, Vector velocity) ++ { ++ Location from = position.clone(); ++ Vector before = velocity.clone(); ++ int i = position.getBlockX(); ++ int j = position.getBlockY(); ++ int k = position.getBlockZ(); ++ float f = position.getYaw(); + ++ if (this.worldServerInstance.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END) ++ { ++ // entity.setPositionRotation((double) i, (double) j, (double) k, entity.yaw, 0.0F); ++ // entity.motX = entity.motY = entity.motZ = 0.0D; ++ position.setPitch(0.0F); ++ velocity.setX(0); ++ velocity.setY(0); ++ velocity.setZ(0); ++ } ++ else ++ { ++ double d4; ++ int k1; ++ // CraftBukkit end ++ double d8 = (double) i + 0.5D; ++ double d9 = (double) j + 0.5D; ++ d4 = (double) k + 0.5D; ++ int j2 = -1; ++ + if (this.worldServerInstance.getBlock(i - 1, j, k) == Blocks.portal) + { +- i4 = 2; ++ j2 = 2; + } + + if (this.worldServerInstance.getBlock(i + 1, j, k) == Blocks.portal) + { +- i4 = 0; ++ j2 = 0; + } + + if (this.worldServerInstance.getBlock(i, j, k - 1) == Blocks.portal) + { +- i4 = 3; ++ j2 = 3; + } + + if (this.worldServerInstance.getBlock(i, j, k + 1) == Blocks.portal) + { +- i4 = 1; ++ j2 = 1; + } + +- int j2 = p_77184_1_.getTeleportDirection(); ++ int k2 = entity.getTeleportDirection(); + +- if (i4 > -1) ++ if (j2 > -1) + { +- int k2 = Direction.rotateLeft[i4]; +- int l2 = Direction.offsetX[i4]; +- int i3 = Direction.offsetZ[i4]; +- int j3 = Direction.offsetX[k2]; +- int k3 = Direction.offsetZ[k2]; +- boolean flag1 = !this.worldServerInstance.isAirBlock(i + l2 + j3, j, k + i3 + k3) || !this.worldServerInstance.isAirBlock(i + l2 + j3, j + 1, k + i3 + k3); +- boolean flag2 = !this.worldServerInstance.isAirBlock(i + l2, j, k + i3) || !this.worldServerInstance.isAirBlock(i + l2, j + 1, k + i3); ++ int l2 = Direction.rotateLeft[j2]; ++ int i3 = Direction.offsetX[j2]; ++ int j3 = Direction.offsetZ[j2]; ++ int k3 = Direction.offsetX[l2]; ++ int l3 = Direction.offsetZ[l2]; ++ boolean flag1 = !this.worldServerInstance.isAirBlock(i + i3 + k3, j, k + j3 + l3) || !this.worldServerInstance.isAirBlock(i + i3 + k3, j + 1, k + j3 + l3); ++ boolean flag2 = !this.worldServerInstance.isAirBlock(i + i3, j, k + j3) || !this.worldServerInstance.isAirBlock(i + i3, j + 1, k + j3); + + if (flag1 && flag2) + { +- i4 = Direction.rotateOpposite[i4]; +- k2 = Direction.rotateOpposite[k2]; +- l2 = Direction.offsetX[i4]; +- i3 = Direction.offsetZ[i4]; +- j3 = Direction.offsetX[k2]; +- k3 = Direction.offsetZ[k2]; +- l3 = i - j3; +- d11 -= (double)j3; +- int k1 = k - k3; +- d7 -= (double)k3; +- flag1 = !this.worldServerInstance.isAirBlock(l3 + l2 + j3, j, k1 + i3 + k3) || !this.worldServerInstance.isAirBlock(l3 + l2 + j3, j + 1, k1 + i3 + k3); +- flag2 = !this.worldServerInstance.isAirBlock(l3 + l2, j, k1 + i3) || !this.worldServerInstance.isAirBlock(l3 + l2, j + 1, k1 + i3); ++ j2 = Direction.rotateOpposite[j2]; ++ l2 = Direction.rotateOpposite[l2]; ++ i3 = Direction.offsetX[j2]; ++ j3 = Direction.offsetZ[j2]; ++ k3 = Direction.offsetX[l2]; ++ l3 = Direction.offsetZ[l2]; ++ k1 = i - k3; ++ d8 -= (double) k3; ++ int i4 = k - l3; ++ d4 -= (double) l3; ++ flag1 = !this.worldServerInstance.isAirBlock(k1 + i3 + k3, j, i4 + j3 + l3) || !this.worldServerInstance.isAirBlock(k1 + i3 + k3, j + 1, i4 + j3 + l3); ++ flag2 = !this.worldServerInstance.isAirBlock(k1 + i3, j, i4 + j3) || !this.worldServerInstance.isAirBlock(k1 + i3, j + 1, i4 + j3); + } + + float f1 = 0.5F; +@@ -200,24 +310,24 @@ + f2 = 0.0F; + } + +- d11 += (double)((float)j3 * f1 + f2 * (float)l2); +- d7 += (double)((float)k3 * f1 + f2 * (float)i3); ++ d8 += (double)((float) k3 * f1 + f2 * (float) i3); ++ d4 += (double)((float) l3 * f1 + f2 * (float) j3); + float f3 = 0.0F; + float f4 = 0.0F; + float f5 = 0.0F; + float f6 = 0.0F; + +- if (i4 == j2) ++ if (j2 == k2) + { + f3 = 1.0F; + f4 = 1.0F; + } +- else if (i4 == Direction.rotateOpposite[j2]) ++ else if (j2 == Direction.rotateOpposite[k2]) + { + f3 = -1.0F; + f4 = -1.0F; + } +- else if (i4 == Direction.rotateRight[j2]) ++ else if (j2 == Direction.rotateRight[k2]) + { + f5 = 1.0F; + f6 = -1.0F; +@@ -228,33 +338,77 @@ + f6 = 1.0F; + } + +- double d9 = p_77184_1_.motionX; +- double d10 = p_77184_1_.motionZ; +- p_77184_1_.motionX = d9 * (double)f3 + d10 * (double)f6; +- p_77184_1_.motionZ = d9 * (double)f5 + d10 * (double)f4; +- p_77184_1_.rotationYaw = p_77184_8_ - (float)(j2 * 90) + (float)(i4 * 90); ++ // CraftBukkit start ++ double d10 = velocity.getX(); ++ double d11 = velocity.getZ(); ++ // CraftBukkit end ++ // CraftBukkit start - Adjust position and velocity instances instead of entity ++ velocity.setX(d10 * (double) f3 + d11 * (double) f6); ++ velocity.setZ(d10 * (double) f5 + d11 * (double) f4); ++ f = f - (float)(k2 * 90) + (float)(j2 * 90); + } + else + { +- p_77184_1_.motionX = p_77184_1_.motionY = p_77184_1_.motionZ = 0.0D; ++ // entity.motX = entity.motY = entity.motZ = 0.0D; ++ velocity.setX(0); ++ velocity.setY(0); ++ velocity.setZ(0); + } + +- p_77184_1_.setLocationAndAngles(d11, d6, d7, p_77184_1_.rotationYaw, p_77184_1_.rotationPitch); +- return true; ++ // entity.setPositionRotation(d8, d9, d4, entity.yaw, entity.pitch); ++ position.setX(d8); ++ position.setY(d9); ++ position.setZ(d4); ++ position.setYaw(f); + } ++ ++ EntityPortalExitEvent event = new EntityPortalExitEvent(entity.getBukkitEntity(), from, position, before, velocity); ++ this.worldServerInstance.getServer().getPluginManager().callEvent(event); ++ Location to = event.getTo(); ++ ++ if (event.isCancelled() || to == null || !entity.isEntityAlive()) ++ { ++ position.setX(from.getX()); ++ position.setY(from.getY()); ++ position.setZ(from.getZ()); ++ position.setYaw(from.getYaw()); ++ position.setPitch(from.getPitch()); ++ velocity.copy(before); ++ } + else + { +- return false; ++ position.setX(to.getX()); ++ position.setY(to.getY()); ++ position.setZ(to.getZ()); ++ position.setYaw(to.getYaw()); ++ position.setPitch(to.getPitch()); ++ velocity.copy(event.getAfter()); // event.getAfter() will never be null, as setAfter() will cause an NPE if null is passed in + } ++ ++ // CraftBukkit end + } + +- public boolean makePortal(Entity p_85188_1_) ++ public boolean makePortal(Entity par1Entity) + { +- byte b0 = 16; ++ // CraftBukkit start - Allow for portal creation to be based on coordinates instead of entity ++ return this.createPortal(par1Entity.posX, par1Entity.posY, par1Entity.posZ, 16); ++ } ++ ++ public boolean createPortal(double x, double y, double z, int b0) ++ { ++ if (this.worldServerInstance.getWorld().getEnvironment() == org.bukkit.World.Environment.THE_END) ++ { ++ this.createEndPortal(x, y, z); ++ return true; ++ } ++ ++ // CraftBukkit end + double d0 = -1.0D; +- int i = MathHelper.floor_double(p_85188_1_.posX); +- int j = MathHelper.floor_double(p_85188_1_.posY); +- int k = MathHelper.floor_double(p_85188_1_.posZ); ++ // CraftBukkit start ++ int i = MathHelper.floor_double(x); ++ int j = MathHelper.floor_double(y); ++ int k = MathHelper.floor_double(z); ++ // CraftBukkit end + int l = i; + int i1 = j; + int j1 = k; +@@ -262,8 +416,10 @@ + int l1 = this.random.nextInt(4); + int i2; + double d1; +- int k2; + double d2; ++ int j2; ++ int k2; ++ int l2; + int i3; + int j3; + int k3; +@@ -271,125 +427,123 @@ + int i4; + int j4; + int k4; +- int l4; +- int i5; + double d3; + double d4; +- ++ + for (i2 = i - b0; i2 <= i + b0; ++i2) + { +- d1 = (double)i2 + 0.5D - p_85188_1_.posX; +- +- for (k2 = k - b0; k2 <= k + b0; ++k2) ++ d1 = (double) i2 + 0.5D - x; // CraftBukkit ++ ++ for (j2 = k - b0; j2 <= k + b0; ++j2) + { +- d2 = (double)k2 + 0.5D - p_85188_1_.posZ; ++ d2 = (double) j2 + 0.5D - z; // CraftBukkit + label274: +- +- for (i3 = this.worldServerInstance.getActualHeight() - 1; i3 >= 0; --i3) ++ ++ for (k2 = this.worldServerInstance.getActualHeight() - 1; k2 >= 0; --k2) + { +- if (this.worldServerInstance.isAirBlock(i2, i3, k2)) ++ if (this.worldServerInstance.isAirBlock(i2, k2, j2)) + { +- while (i3 > 0 && this.worldServerInstance.isAirBlock(i2, i3 - 1, k2)) ++ while (k2 > 0 && this.worldServerInstance.isAirBlock(i2, k2 - 1, j2)) + { +- --i3; ++ --k2; + } +- +- for (j3 = l1; j3 < l1 + 4; ++j3) ++ ++ for (i3 = l1; i3 < l1 + 4; ++i3) + { +- k3 = j3 % 2; +- l3 = 1 - k3; +- +- if (j3 % 4 >= 2) ++ l2 = i3 % 2; ++ k3 = 1 - l2; ++ ++ if (i3 % 4 >= 2) + { ++ l2 = -l2; + k3 = -k3; +- l3 = -l3; + } +- +- for (i4 = 0; i4 < 3; ++i4) ++ ++ for (j3 = 0; j3 < 3; ++j3) + { +- for (j4 = 0; j4 < 4; ++j4) ++ for (i4 = 0; i4 < 4; ++i4) + { +- for (k4 = -1; k4 < 4; ++k4) ++ for (l3 = -1; l3 < 4; ++l3) + { +- l4 = i2 + (j4 - 1) * k3 + i4 * l3; +- i5 = i3 + k4; +- int j5 = k2 + (j4 - 1) * l3 - i4 * k3; +- +- if (k4 < 0 && !this.worldServerInstance.getBlock(l4, i5, j5).getMaterial().isSolid() || k4 >= 0 && !this.worldServerInstance.isAirBlock(l4, i5, j5)) ++ k4 = i2 + (i4 - 1) * l2 + j3 * k3; ++ j4 = k2 + l3; ++ int l4 = j2 + (i4 - 1) * k3 - j3 * l2; ++ ++ if (l3 < 0 && !this.worldServerInstance.getBlock(k4, j4, l4).getMaterial().isSolid() || l3 >= 0 && !this.worldServerInstance.isAirBlock(k4, j4, l4)) + { + continue label274; + } + } + } + } +- +- d3 = (double)i3 + 0.5D - p_85188_1_.posY; ++ ++ d3 = (double) k2 + 0.5D - y; // CraftBukkit + d4 = d1 * d1 + d3 * d3 + d2 * d2; +- ++ + if (d0 < 0.0D || d4 < d0) + { + d0 = d4; + l = i2; +- i1 = i3; +- j1 = k2; +- k1 = j3 % 4; ++ i1 = k2; ++ j1 = j2; ++ k1 = i3 % 4; + } + } + } + } + } + } +- ++ + if (d0 < 0.0D) + { + for (i2 = i - b0; i2 <= i + b0; ++i2) + { +- d1 = (double)i2 + 0.5D - p_85188_1_.posX; +- +- for (k2 = k - b0; k2 <= k + b0; ++k2) ++ d1 = (double) i2 + 0.5D - x; // CraftBukkit ++ ++ for (j2 = k - b0; j2 <= k + b0; ++j2) + { +- d2 = (double)k2 + 0.5D - p_85188_1_.posZ; ++ d2 = (double) j2 + 0.5D - z; // CraftBukkit + label222: +- +- for (i3 = this.worldServerInstance.getActualHeight() - 1; i3 >= 0; --i3) ++ ++ for (k2 = this.worldServerInstance.getActualHeight() - 1; k2 >= 0; --k2) + { +- if (this.worldServerInstance.isAirBlock(i2, i3, k2)) ++ if (this.worldServerInstance.isAirBlock(i2, k2, j2)) + { +- while (i3 > 0 && this.worldServerInstance.isAirBlock(i2, i3 - 1, k2)) ++ while (k2 > 0 && this.worldServerInstance.isAirBlock(i2, k2 - 1, j2)) + { +- --i3; ++ --k2; + } +- +- for (j3 = l1; j3 < l1 + 2; ++j3) ++ ++ for (i3 = l1; i3 < l1 + 2; ++i3) + { +- k3 = j3 % 2; +- l3 = 1 - k3; +- +- for (i4 = 0; i4 < 4; ++i4) ++ l2 = i3 % 2; ++ k3 = 1 - l2; ++ ++ for (j3 = 0; j3 < 4; ++j3) + { +- for (j4 = -1; j4 < 4; ++j4) ++ for (i4 = -1; i4 < 4; ++i4) + { +- k4 = i2 + (i4 - 1) * k3; +- l4 = i3 + j4; +- i5 = k2 + (i4 - 1) * l3; +- +- if (j4 < 0 && !this.worldServerInstance.getBlock(k4, l4, i5).getMaterial().isSolid() || j4 >= 0 && !this.worldServerInstance.isAirBlock(k4, l4, i5)) ++ l3 = i2 + (j3 - 1) * l2; ++ k4 = k2 + i4; ++ j4 = j2 + (j3 - 1) * k3; ++ ++ if (i4 < 0 && !this.worldServerInstance.getBlock(l3, k4, j4).getMaterial().isSolid() || i4 >= 0 && !this.worldServerInstance.isAirBlock(l3, k4, j4)) + { + continue label222; + } + } + } +- +- d3 = (double)i3 + 0.5D - p_85188_1_.posY; ++ ++ d3 = (double) k2 + 0.5D - y; // CraftBukkit + d4 = d1 * d1 + d3 * d3 + d2 * d2; +- ++ + if (d0 < 0.0D || d4 < d0) + { + d0 = d4; + l = i2; +- i1 = i3; +- j1 = k2; +- k1 = j3 % 2; ++ i1 = k2; ++ j1 = j2; ++ k1 = i3 % 2; + } + } + } +@@ -397,93 +551,93 @@ + } + } + } +- +- int k5 = l; +- int j2 = i1; +- k2 = j1; +- int l5 = k1 % 2; +- int l2 = 1 - l5; +- ++ ++ int i5 = l; ++ int j5 = i1; ++ j2 = j1; ++ int k5 = k1 % 2; ++ int l5 = 1 - k5; ++ + if (k1 % 4 >= 2) + { ++ k5 = -k5; + l5 = -l5; +- l2 = -l2; + } +- ++ + boolean flag; +- ++ + if (d0 < 0.0D) + { + if (i1 < 70) + { + i1 = 70; + } +- ++ + if (i1 > this.worldServerInstance.getActualHeight() - 10) + { + i1 = this.worldServerInstance.getActualHeight() - 10; + } +- +- j2 = i1; +- +- for (i3 = -1; i3 <= 1; ++i3) ++ ++ j5 = i1; ++ ++ for (k2 = -1; k2 <= 1; ++k2) + { +- for (j3 = 1; j3 < 3; ++j3) ++ for (i3 = 1; i3 < 3; ++i3) + { +- for (k3 = -1; k3 < 3; ++k3) ++ for (l2 = -1; l2 < 3; ++l2) + { +- l3 = k5 + (j3 - 1) * l5 + i3 * l2; +- i4 = j2 + k3; +- j4 = k2 + (j3 - 1) * l2 - i3 * l5; +- flag = k3 < 0; +- this.worldServerInstance.setBlock(l3, i4, j4, flag ? Blocks.obsidian : Blocks.air); ++ k3 = i5 + (i3 - 1) * k5 + k2 * l5; ++ j3 = j5 + l2; ++ i4 = j2 + (i3 - 1) * l5 - k2 * k5; ++ flag = l2 < 0; ++ this.worldServerInstance.setBlock(k3, j3, i4, flag ? Blocks.obsidian : Blocks.air); + } + } + } + } +- +- for (i3 = 0; i3 < 4; ++i3) ++ ++ for (k2 = 0; k2 < 4; ++k2) + { +- for (j3 = 0; j3 < 4; ++j3) ++ for (i3 = 0; i3 < 4; ++i3) + { +- for (k3 = -1; k3 < 4; ++k3) ++ for (l2 = -1; l2 < 4; ++l2) + { +- l3 = k5 + (j3 - 1) * l5; +- i4 = j2 + k3; +- j4 = k2 + (j3 - 1) * l2; +- flag = j3 == 0 || j3 == 3 || k3 == -1 || k3 == 3; +- this.worldServerInstance.setBlock(l3, i4, j4, (Block)(flag ? Blocks.obsidian : Blocks.portal), 0, 2); ++ k3 = i5 + (i3 - 1) * k5; ++ j3 = j5 + l2; ++ i4 = j2 + (i3 - 1) * l5; ++ flag = i3 == 0 || i3 == 3 || l2 == -1 || l2 == 3; ++ this.worldServerInstance.setBlock(k3, j3, i4, flag ? Blocks.obsidian : Blocks.portal, 0, 2); + } + } +- +- for (j3 = 0; j3 < 4; ++j3) ++ ++ for (i3 = 0; i3 < 4; ++i3) + { +- for (k3 = -1; k3 < 4; ++k3) ++ for (l2 = -1; l2 < 4; ++l2) + { +- l3 = k5 + (j3 - 1) * l5; +- i4 = j2 + k3; +- j4 = k2 + (j3 - 1) * l2; +- this.worldServerInstance.notifyBlocksOfNeighborChange(l3, i4, j4, this.worldServerInstance.getBlock(l3, i4, j4)); ++ k3 = i5 + (i3 - 1) * k5; ++ j3 = j5 + l2; ++ i4 = j2 + (i3 - 1) * l5; ++ this.worldServerInstance.notifyBlocksOfNeighborChange(k3, j3, i4, this.worldServerInstance.getBlock(k3, j3, i4)); + } + } + } +- ++ + return true; + } + +- public void removeStalePortalLocations(long p_85189_1_) ++ public void removeStalePortalLocations(long par1) + { +- if (p_85189_1_ % 100L == 0L) ++ if (par1 % 100L == 0L) + { + Iterator iterator = this.destinationCoordinateKeys.iterator(); +- long j = p_85189_1_ - 600L; +- ++ long j = par1 - 600L; ++ + while (iterator.hasNext()) + { +- Long olong = (Long)iterator.next(); +- Teleporter.PortalPosition portalposition = (Teleporter.PortalPosition)this.destinationCoordinateCache.getValueByKey(olong.longValue()); +- +- if (portalposition == null || portalposition.lastUpdateTime < j) ++ Long olong = (Long) iterator.next(); ++ PortalPosition chunkcoordinatesportal = (PortalPosition) this.destinationCoordinateCache.getValueByKey(olong.longValue()); ++ ++ if (chunkcoordinatesportal == null || chunkcoordinatesportal.lastUpdateTime < j) + { + iterator.remove(); + this.destinationCoordinateCache.remove(olong.longValue()); +@@ -491,16 +645,16 @@ + } + } + } +- ++ + public class PortalPosition extends ChunkCoordinates + { + public long lastUpdateTime; + private static final String __OBFID = "CL_00000154"; +- +- public PortalPosition(int p_i1962_2_, int p_i1962_3_, int p_i1962_4_, long p_i1962_5_) ++ ++ public PortalPosition(int par2, int par3, int par4, long par5) + { +- super(p_i1962_2_, p_i1962_3_, p_i1962_4_); +- this.lastUpdateTime = p_i1962_5_; ++ super(par2, par3, par4); ++ this.lastUpdateTime = par5; + } + } + } diff --git a/patches/net/minecraft/world/World.java.patch b/patches/net/minecraft/world/World.java.patch new file mode 100644 index 0000000..8d5cbfc --- /dev/null +++ b/patches/net/minecraft/world/World.java.patch @@ -0,0 +1,1282 @@ +--- ../src-base/minecraft/net/minecraft/world/World.java ++++ ../src-work/minecraft/net/minecraft/world/World.java +@@ -23,9 +23,11 @@ + import net.minecraft.crash.CrashReport; + import net.minecraft.crash.CrashReportCategory; + import net.minecraft.entity.Entity; ++import net.minecraft.entity.EntityList; + import net.minecraft.entity.EntityLiving; + import net.minecraft.entity.player.EntityPlayer; + import net.minecraft.init.Blocks; ++import net.minecraft.item.ItemBlock; + import net.minecraft.item.ItemStack; + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.pathfinding.PathEntity; +@@ -70,6 +72,49 @@ + import net.minecraftforge.event.entity.PlaySoundAtEntityEvent; + import net.minecraft.entity.EnumCreatureType; + ++// CraftBukkit start ++import net.minecraft.entity.EntityLivingBase; ++import net.minecraft.entity.item.EntityItem; ++import net.minecraft.entity.monster.EntityGhast; ++import net.minecraft.entity.monster.EntityGolem; ++import net.minecraft.entity.monster.EntityMob; ++import net.minecraft.entity.monster.EntitySlime; ++import net.minecraft.entity.passive.EntityAnimal; ++import net.minecraft.entity.passive.EntityWaterMob; ++import net.minecraft.entity.player.EntityPlayerMP; ++import net.minecraft.world.gen.ChunkProviderServer; ++import org.bukkit.Bukkit; ++import org.bukkit.World.Environment; ++import org.bukkit.block.BlockState; ++import org.bukkit.craftbukkit.util.CraftMagicNumbers; ++import org.bukkit.craftbukkit.util.LongHashSet; ++import org.bukkit.craftbukkit.util.UnsafeList; ++import org.bukkit.generator.ChunkGenerator; ++import org.bukkit.craftbukkit.CraftServer; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import org.bukkit.event.block.BlockCanBuildEvent; ++import org.bukkit.event.block.BlockPhysicsEvent; ++import org.bukkit.event.block.BlockPlaceEvent; ++import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; ++import org.bukkit.event.weather.WeatherChangeEvent; ++import org.bukkit.event.weather.ThunderChangeEvent; ++// CraftBukkit end ++// Spigot Start ++import net.minecraft.entity.item.EntityXPOrb; ++import org.bukkit.craftbukkit.SpigotTimings; ++// Spigot end ++// Cauldron start ++import net.minecraft.nbt.NBTTagCompound; ++import net.minecraftforge.cauldron.CauldronHooks; ++import net.minecraftforge.cauldron.configuration.CauldronConfig; ++import net.minecraftforge.cauldron.configuration.CauldronWorldConfig; ++import net.minecraftforge.cauldron.configuration.TileEntityConfig; ++import net.minecraftforge.cauldron.configuration.TileEntityWorldConfig; ++import net.minecraftforge.common.DimensionManager; ++import org.bukkit.block.BlockState; ++// Cauldron end ++ + public abstract class World implements IBlockAccess + { + /** +@@ -83,10 +128,10 @@ + + public boolean scheduledUpdatesAreImmediate; + public List loadedEntityList = new ArrayList(); +- protected List unloadedEntityList = new ArrayList(); ++ public List unloadedEntityList = new ArrayList(); // Cauldron + public List loadedTileEntityList = new ArrayList(); + private List addedTileEntityList = new ArrayList(); +- private List field_147483_b = new ArrayList(); ++ public List field_147483_b = new ArrayList(); // Cauldron + public List playerEntities = new ArrayList(); + public List weatherEffects = new ArrayList(); + private long cloudColour = 16777215L; +@@ -100,26 +145,90 @@ + public int lastLightningBolt; + public EnumDifficulty difficultySetting; + public Random rand = new Random(); +- public final WorldProvider provider; ++ public WorldProvider provider; // CraftBukkit - remove final + protected List worldAccesses = new ArrayList(); +- protected IChunkProvider chunkProvider; ++ public IChunkProvider chunkProvider; // CraftBukkit - public + protected final ISaveHandler saveHandler; +- protected WorldInfo worldInfo; ++ public WorldInfo worldInfo; // CraftBukkit - public + public boolean findingSpawnPoint; + public MapStorage mapStorage; + public VillageCollection villageCollectionObj; + protected final VillageSiege villageSiegeObj = new VillageSiege(this); + public final Profiler theProfiler; + private final Calendar theCalendar = Calendar.getInstance(); +- protected Scoreboard worldScoreboard = new Scoreboard(); ++ public Scoreboard worldScoreboard = new Scoreboard(); // CraftBukkit - protected -> public + public boolean isRemote; +- protected Set activeChunkSet = new HashSet(); ++ // CraftBukkit start - public, longhashset ++ public boolean spawnHostileMobs; ++ public boolean spawnPeacefulMobs; ++ // Added the following ++ public long ticksPerAnimalSpawns; ++ public long ticksPerMonsterSpawns; ++ public boolean populating; ++ private int tickPosition; ++ // CraftBukkit end ++ public Set activeChunkSet = new HashSet(); // Cauldron - protected -> public + private int ambientTickCountdown; +- protected boolean spawnHostileMobs; +- protected boolean spawnPeacefulMobs; + private ArrayList collidingBoundingBoxes; + private boolean field_147481_N; + int[] lightUpdateBlockList; ++ // Cauldron start ++ public boolean restoringBlockStates = false; ++ public boolean captureBlockStates = false; ++ public boolean captureTreeGeneration = false; ++ public ArrayList capturedBlockStates = new ArrayList(); ++ public ArrayList capturedItems = new ArrayList(); ++ public int entitiesTicked; ++ public int tilesTicked; ++ public CauldronWorldConfig cauldronConfig; ++ public TileEntityWorldConfig tileentityConfig; ++ // preload world crash report classes to fix NCDFE masking StackOverflow/memory error, see #721 ++ private static boolean preloadedCrashClasses = false; ++ { ++ if (!preloadedCrashClasses) ++ { ++ // generate a temporary crash report ++ Throwable throwable = new Throwable(); ++ CrashReport crashreport = CrashReport.makeCrashReport(throwable, "Exception while updating neighbours"); ++ CrashReportCategory crashreportcategory = crashreport.makeCategory("Block being updated"); ++ ++ // loads all the required classes - including net.minecraft.crash.CallableBlockType (package private) ++ crashreportcategory.addCrashSectionCallable("Source block type", new Callable() { ++ public String call() ++ { ++ return ""; ++ } ++ }); ++ CrashReportCategory.func_147153_a(crashreportcategory, 0, 0, 0, Blocks.air, -1); ++ ++ preloadedCrashClasses = true; ++ } ++ } ++ // Cauldron end ++ // Spigot start ++ ++ /** Positions to update */ ++ protected final gnu.trove.map.hash.TLongShortHashMap activeChunkSet_CB; ++ public float growthOdds = 100; ++ protected float modifiedOdds = 100; ++ ++ public static long chunkToKey(int x, int z) ++ { ++ long k = ((((long) x) & 0xFFFF0000L) << 16) | ((((long) x) & 0x0000FFFFL) << 0); ++ k |= ((((long) z) & 0xFFFF0000L) << 32) | ((((long) z) & 0x0000FFFFL) << 16); ++ return k; ++ } ++ ++ public static int keyToX(long k) ++ { ++ return (int) (((k >> 16) & 0xFFFF0000) | (k & 0x0000FFFF)); ++ } ++ ++ public static int keyToZ(long k) ++ { ++ return (int) (((k >> 32) & 0xFFFF0000L) | ((k >> 16) & 0x0000FFFF)); ++ } ++ // Spigot end + private static final String __OBFID = "CL_00000140"; + public boolean restoringBlockSnapshots = false; + public boolean captureBlockSnapshots = false; +@@ -166,6 +275,24 @@ + return this.provider.worldChunkMgr; + } + ++ // CraftBukkit start ++ private final CraftWorld world; ++ public boolean pvpMode; ++ public boolean keepSpawnInMemory = false; // Cauldron - default to false to give forge's keepLoaded higher priority ++ public ChunkGenerator generator; ++ public final org.spigotmc.SpigotWorldConfig spigotConfig; // Spigot ++ public final SpigotTimings.WorldTimingsHandler timings; // Spigot ++ ++ public CraftWorld getWorld() ++ { ++ return this.world; ++ } ++ ++ public CraftServer getServer() ++ { ++ return (CraftServer) Bukkit.getServer(); ++ } ++ + @SideOnly(Side.CLIENT) + public World(ISaveHandler p_i45368_1_, String p_i45368_2_, WorldProvider p_i45368_3_, WorldSettings p_i45368_4_, Profiler p_i45368_5_) + { +@@ -179,6 +306,12 @@ + this.worldInfo = new WorldInfo(p_i45368_4_, p_i45368_2_); + this.provider = p_i45368_3_; + perWorldStorage = new MapStorage((ISaveHandler)null); ++ // Cauldron start ++ this.world = null; ++ this.timings = null; ++ this.spigotConfig = null; ++ this.activeChunkSet_CB = null; ++ // Cauldron end + } + + // Broken up so that the WorldClient gets the chance to set the mapstorage object before the dimension initializes +@@ -207,8 +340,173 @@ + this.calculateInitialWeather(); + } + ++ // Changed signature - added gen and env ++ public World(ISaveHandler p_i45369_1_, String p_i45369_2_, WorldSettings p_i45369_3_, WorldProvider p_i45369_4_, Profiler p_i45369_5_, ChunkGenerator gen, ++ org.bukkit.World.Environment env) ++ { ++ this.spigotConfig = new org.spigotmc.SpigotWorldConfig(p_i45369_2_); // Spigot ++ // Cauldron start ++ this.cauldronConfig = new CauldronWorldConfig(p_i45369_2_, MinecraftServer.getServer().cauldronConfig); ++ this.tileentityConfig = new TileEntityWorldConfig(p_i45369_2_, MinecraftServer.getServer().tileEntityConfig); ++ // Cauldron end ++ this.worldInfo = p_i45369_1_.loadWorldInfo(); // Spigot ++ this.generator = gen; ++ this.world = new CraftWorld((WorldServer) this, gen, env); ++ this.ticksPerAnimalSpawns = this.getServer().getTicksPerAnimalSpawns(); // CraftBukkit ++ this.ticksPerMonsterSpawns = this.getServer().getTicksPerMonsterSpawns(); // CraftBukkit ++ // CraftBukkit end ++ // Spigot start ++ this.activeChunkSet_CB = new gnu.trove.map.hash.TLongShortHashMap(spigotConfig.chunksPerTick * 5, 0.7f, Long.MIN_VALUE, Short.MIN_VALUE); ++ this.activeChunkSet_CB.setAutoCompactionFactor(0); ++ // Spigot end ++ this.ambientTickCountdown = this.rand.nextInt(12000); ++ this.spawnHostileMobs = true; ++ this.spawnPeacefulMobs = true; ++ this.collidingBoundingBoxes = new ArrayList(); ++ this.lightUpdateBlockList = new int[32768]; ++ this.saveHandler = p_i45369_1_; ++ this.theProfiler = p_i45369_5_; ++ // Cauldron start ++ // Provides a solution for different worlds getting different copies of the same data, potentially rewriting the data or causing race conditions/stale data ++ // Buildcraft has suffered from the issue this fixes. If you load the same data from two different worlds they can get two different copies of the same object, thus the last saved gets final say. ++ if (DimensionManager.getWorld(0) != null) // if overworld has loaded, use its mapstorage ++ { ++ this.mapStorage = DimensionManager.getWorld(0).mapStorage; ++ } ++ else ++ // if we are loading overworld, create a new mapstorage ++ { ++ this.mapStorage = new MapStorage(p_i45369_1_); ++ } ++ // Cauldron end ++ // this.worldInfo = p_i45369_1_.loadWorldInfo(); // Spigot - Moved up ++ ++ if (p_i45369_4_ != null) ++ { ++ this.provider = p_i45369_4_; ++ } ++ else if (this.worldInfo != null && this.worldInfo.getDimension() != 0) // Cauldron ++ { ++ this.provider = WorldProvider.getProviderForDimension(this.worldInfo.getDimension()); // Cauldron ++ } ++ else ++ { ++ this.provider = WorldProvider.getProviderForDimension(0); ++ } ++ ++ if (this.worldInfo == null) ++ { ++ this.worldInfo = new WorldInfo(p_i45369_3_, p_i45369_2_); ++ this.worldInfo.setDimension(this.provider.dimensionId); // Cauldron - Save dimension to level.dat ++ } ++ else ++ { ++ this.worldInfo.setWorldName(p_i45369_2_); ++ // Cauldron start - Use saved dimension from level.dat. Fixes issues with MultiVerse ++ if (this.worldInfo.getDimension() != 0) ++ this.provider.dimensionId = this.worldInfo.getDimension(); ++ else ++ { ++ this.worldInfo.setDimension(this.provider.dimensionId); ++ } ++ // Cauldron end ++ } ++ ++ // Cauldron start - Guarantee provider dimension is not reset. This is required for mods that rely on the provider ID to match the client dimension. Without this, IC2 will send the wrong ID to clients. ++ int providerId = this.provider.dimensionId; ++ this.provider.registerWorld(this); ++ this.provider.dimensionId = providerId; ++ // Cauldron end ++ // Cauldron start - workaround to fix TC with overworld ++ if (this.worldInfo.getDimension() == 0) ++ { ++ generator = this.getServer().getGenerator(p_i45369_2_); ++ if (generator != null) ++ { ++ getWorld().setGenerator(generator); ++ getWorld().getPopulators().addAll(generator.getDefaultPopulators(getWorld())); ++ } ++ } ++ // Cauldron end ++ this.chunkProvider = this.createChunkProvider(); ++ ++ if (this instanceof WorldServer) ++ { ++ this.perWorldStorage = new MapStorage(new WorldSpecificSaveHandler((WorldServer) this, p_i45369_1_)); ++ } ++ else ++ { ++ this.perWorldStorage = new MapStorage((ISaveHandler) null); ++ } ++ ++ timings = new SpigotTimings.WorldTimingsHandler(this); // Spigot - code below can generate new world and access timings ++ if (!this.worldInfo.isInitialized()) ++ { ++ try ++ { ++ this.initialize(p_i45369_3_); ++ } ++ catch (Throwable throwable1) ++ { ++ CrashReport crashreport = CrashReport.makeCrashReport(throwable1, "Exception initializing level"); ++ ++ try ++ { ++ this.addWorldInfoToCrashReport(crashreport); ++ } ++ catch (Throwable throwable) ++ { ++ ; ++ } ++ ++ throw new ReportedException(crashreport); ++ } ++ ++ this.worldInfo.setServerInitialized(true); ++ } ++ ++ VillageCollection villagecollection = (VillageCollection) this.perWorldStorage.loadData(VillageCollection.class, "villages"); ++ ++ if (villagecollection == null) ++ { ++ this.villageCollectionObj = new VillageCollection(this); ++ this.perWorldStorage.setData("villages", this.villageCollectionObj); ++ } ++ else ++ { ++ this.villageCollectionObj = villagecollection; ++ this.villageCollectionObj.func_82566_a(this); ++ } ++ ++ this.calculateInitialSkylight(); ++ this.calculateInitialWeather(); ++ this.getServer().addWorld(this.world); // CraftBukkit ++ } ++ + public World(ISaveHandler p_i45369_1_, String p_i45369_2_, WorldSettings p_i45369_3_, WorldProvider p_i45369_4_, Profiler p_i45369_5_) + { ++ // Cauldron start - handle dummy worlds ++ if (DimensionManager.getWorld(0) != null) ++ { ++ this.spigotConfig = new org.spigotmc.SpigotWorldConfig(p_i45369_2_); // Spigot ++ this.cauldronConfig = new CauldronWorldConfig(p_i45369_2_, MinecraftServer.getServer().cauldronConfig); ++ this.tileentityConfig = new TileEntityWorldConfig(p_i45369_2_, MinecraftServer.getServer().tileEntityConfig); ++ this.world = DimensionManager.getWorld(0).getWorld(); ++ this.timings = DimensionManager.getWorld(0).timings; ++ this.activeChunkSet_CB = new gnu.trove.map.hash.TLongShortHashMap(spigotConfig.chunksPerTick * 5, 0.7f, Long.MIN_VALUE, Short.MIN_VALUE); ++ this.activeChunkSet_CB.setAutoCompactionFactor(0); ++ this.mapStorage = DimensionManager.getWorld(0).mapStorage; ++ } ++ else ++ { ++ this.spigotConfig = null; ++ this.cauldronConfig = null; ++ this.world = null; ++ this.timings = null; ++ this.activeChunkSet_CB = null; ++ this.mapStorage = null; ++ } ++ // Cauldron end + this.ambientTickCountdown = this.rand.nextInt(12000); + this.spawnHostileMobs = true; + this.spawnPeacefulMobs = true; +@@ -216,7 +514,6 @@ + this.lightUpdateBlockList = new int[32768]; + this.saveHandler = p_i45369_1_; + this.theProfiler = p_i45369_5_; +- this.mapStorage = getMapStorage(p_i45369_1_); + this.worldInfo = p_i45369_1_.loadWorldInfo(); + + if (p_i45369_4_ != null) +@@ -235,13 +532,26 @@ + if (this.worldInfo == null) + { + this.worldInfo = new WorldInfo(p_i45369_3_, p_i45369_2_); ++ this.worldInfo.setDimension(this.provider.dimensionId); // Cauldron - Save dimension to level.dat + } + else + { + this.worldInfo.setWorldName(p_i45369_2_); ++ // Cauldron start - Use saved dimension from level.dat. Fixes issues with MultiVerse ++ if (this.worldInfo.getDimension() != 0) ++ this.provider.dimensionId = this.worldInfo.getDimension(); ++ else ++ { ++ this.worldInfo.setDimension(this.provider.dimensionId); ++ } ++ // Cauldron end + } + ++ // Cauldron start - Guarantee provider dimension is not reset. This is required for mods that rely on the provider ID to match the client dimension. Without this, IC2 will send the wrong ID to clients. ++ int providerId = this.provider.dimensionId; + this.provider.registerWorld(this); ++ this.provider.dimensionId = providerId; ++ // Cauldron end + this.chunkProvider = this.createChunkProvider(); + + if (this instanceof WorldServer) +@@ -294,6 +604,7 @@ + this.calculateInitialSkylight(); + this.calculateInitialWeather(); + } ++ // Cauldron end + + private static MapStorage s_mapStorage; + private static ISaveHandler s_savehandler; +@@ -336,6 +647,18 @@ + + public Block getBlock(int p_147439_1_, int p_147439_2_, int p_147439_3_) + { ++ // Cauldron start - tree generation ++ if (captureTreeGeneration) ++ { ++ for (BlockState blockstate : capturedBlockStates) ++ { ++ if (blockstate.getX() == p_147439_1_ && blockstate.getY() == p_147439_2_ && blockstate.getZ() == p_147439_3_) ++ { ++ return CraftMagicNumbers.getBlock(blockstate.getTypeId()); ++ } ++ } ++ } ++ // Cauldron end + if (p_147439_1_ >= -30000000 && p_147439_3_ >= -30000000 && p_147439_1_ < 30000000 && p_147439_3_ < 30000000 && p_147439_2_ >= 0 && p_147439_2_ < 256) + { + Chunk chunk = null; +@@ -404,7 +727,7 @@ + } + } + +- protected boolean chunkExists(int p_72916_1_, int p_72916_2_) ++ public boolean chunkExists(int p_72916_1_, int p_72916_2_) // Cauldron - protected -> public for repackaging + { + return this.chunkProvider.chunkExists(p_72916_1_, p_72916_2_); + } +@@ -421,6 +744,33 @@ + + public boolean setBlock(int p_147465_1_, int p_147465_2_, int p_147465_3_, Block p_147465_4_, int p_147465_5_, int p_147465_6_) + { ++ // Cauldron start - tree generation ++ if (this.captureTreeGeneration) ++ { ++ BlockState blockstate = null; ++ ++ for (BlockState previous : capturedBlockStates) ++ { ++ if (previous.getX() == p_147465_1_ && previous.getY() == p_147465_2_ && previous.getZ() == p_147465_3_) ++ { ++ blockstate = previous; ++ break; ++ } ++ } ++ if (blockstate != null) ++ { ++ capturedBlockStates.remove(blockstate); ++ } ++ else ++ { ++ blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(this, p_147465_1_, p_147465_2_, p_147465_3_, p_147465_6_); ++ } ++ blockstate.setTypeId(CraftMagicNumbers.getId(p_147465_4_)); ++ blockstate.setRawData((byte) p_147465_5_); ++ this.capturedBlockStates.add(blockstate); ++ return true; ++ } ++ // Cauldron end + if (p_147465_1_ >= -30000000 && p_147465_3_ >= -30000000 && p_147465_1_ < 30000000 && p_147465_3_ < 30000000) + { + if (p_147465_2_ < 0) +@@ -448,8 +798,22 @@ + this.capturedBlockSnapshots.add(blockSnapshot); + } + ++ // Cauldron start - capture blockstates ++ org.bukkit.block.BlockState blockstate = null; ++ if (this.captureBlockStates) ++ { ++ blockstate = org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(this, p_147465_1_, p_147465_2_, p_147465_3_, p_147465_6_); ++ this.capturedBlockStates.add(blockstate); ++ } ++ + boolean flag = chunk.func_150807_a(p_147465_1_ & 15, p_147465_2_, p_147465_3_ & 15, p_147465_4_, p_147465_5_); + ++ if (!flag && this.captureBlockStates) ++ { ++ this.capturedBlockStates.remove(blockstate); ++ } ++ // Cauldron end ++ + if (!flag && blockSnapshot != null) + { + this.capturedBlockSnapshots.remove(blockSnapshot); +@@ -460,7 +824,8 @@ + this.func_147451_t(p_147465_1_, p_147465_2_, p_147465_3_); + this.theProfiler.endSection(); + +- if (flag && blockSnapshot == null) // Don't notify clients or update physics while capturing blockstates ++ // Cauldron add !this.captureBlockStates ++ if (flag && (blockSnapshot == null || !this.captureBlockStates)) // Don't notify clients or update physics while capturing blockstates + { + // Modularize client and physic updates + this.markAndNotifyBlock(p_147465_1_, p_147465_2_, p_147465_3_, chunk, block1, p_147465_4_, p_147465_6_); +@@ -496,6 +861,19 @@ + + public int getBlockMetadata(int p_72805_1_, int p_72805_2_, int p_72805_3_) + { ++ // Cauldron start - tree generation ++ if (captureTreeGeneration) ++ { ++ for (BlockState blockstate : capturedBlockStates) ++ { ++ if (blockstate.getX() == p_72805_1_ && blockstate.getY() == p_72805_2_ && blockstate.getZ() == p_72805_3_) ++ { ++ return blockstate.getRawData(); ++ } ++ } ++ } ++ // Cauldron end ++ + if (p_72805_1_ >= -30000000 && p_72805_3_ >= -30000000 && p_72805_1_ < 30000000 && p_72805_3_ < 30000000) + { + if (p_72805_2_ < 0) +@@ -610,6 +988,12 @@ + + public void notifyBlockChange(int p_147444_1_, int p_147444_2_, int p_147444_3_, Block p_147444_4_) + { ++ // CraftBukkit start ++ if (this.populating) ++ { ++ return; ++ } ++ // CraftBukkit end + this.notifyBlocksOfNeighborChange(p_147444_1_, p_147444_2_, p_147444_3_, p_147444_4_); + } + +@@ -694,6 +1078,21 @@ + + try + { ++ // CraftBukkit start ++ CraftWorld world = ((WorldServer) this).getWorld(); ++ ++ if (world != null) ++ { ++ BlockPhysicsEvent event = new BlockPhysicsEvent(world.getBlockAt(p_147460_1_, p_147460_2_, p_147460_3_), ++ CraftMagicNumbers.getId(p_147460_4_)); ++ this.getServer().getPluginManager().callEvent(event); ++ ++ if (event.isCancelled()) ++ { ++ return; ++ } ++ } ++ // CraftBukkit end + block.onNeighborBlockChange(this, p_147460_1_, p_147460_2_, p_147460_3_, p_147460_4_); + } + catch (Throwable throwable1) +@@ -1307,8 +1706,14 @@ + + public boolean spawnEntityInWorld(Entity p_72838_1_) + { ++ // CraftBukkit start - Used for entities other than creatures ++ return this.addEntity(p_72838_1_, SpawnReason.DEFAULT); // Set reason as DEFAULT ++ } ++ ++ public boolean addEntity(Entity p_72838_1_, SpawnReason spawnReason) // Changed signature, added SpawnReason ++ { + // do not drop any items while restoring blocksnapshots. Prevents dupes +- if (!this.isRemote && (p_72838_1_ == null || (p_72838_1_ instanceof net.minecraft.entity.item.EntityItem && this.restoringBlockSnapshots))) return false; ++ if (!this.isRemote && (p_72838_1_ == null || (p_72838_1_ instanceof net.minecraft.entity.item.EntityItem && (this.restoringBlockSnapshots || this.restoringBlockStates)))) return false; + + int i = MathHelper.floor_double(p_72838_1_.posX / 16.0D); + int j = MathHelper.floor_double(p_72838_1_.posZ / 16.0D); +@@ -1319,8 +1724,84 @@ + flag = true; + } + ++ // CraftBukkit start ++ org.bukkit.event.Cancellable event = null; ++ // Cauldron start - workaround for handling CraftBukkit's SpawnReason with customspawners and block spawners ++ if (p_72838_1_.spawnReason != null && p_72838_1_.spawnReason.equals("natural")) ++ { ++ spawnReason = SpawnReason.NATURAL; ++ } ++ else if (p_72838_1_.spawnReason != null && p_72838_1_.spawnReason.equals("spawner")) ++ { ++ spawnReason = SpawnReason.SPAWNER; ++ } ++ // Cauldron end ++ ++ if (p_72838_1_ instanceof EntityLivingBase && !(p_72838_1_ instanceof EntityPlayerMP)) ++ { ++ // Cauldron start - add custom entity support ++ boolean isAnimal = p_72838_1_ instanceof EntityAnimal || p_72838_1_ instanceof EntityWaterMob || p_72838_1_ instanceof EntityGolem ++ || p_72838_1_.isCreatureType(EnumCreatureType.creature, false); ++ boolean isMonster = p_72838_1_ instanceof EntityMob || p_72838_1_ instanceof EntityGhast || p_72838_1_ instanceof EntitySlime ++ || p_72838_1_.isCreatureType(EnumCreatureType.monster, false); ++ // Cauldron end ++ ++ if (spawnReason != SpawnReason.CUSTOM) ++ { ++ if (isAnimal && !spawnPeacefulMobs || isMonster && !spawnHostileMobs) ++ { ++ p_72838_1_.isDead = true; ++ return false; ++ } ++ } ++ ++ event = CraftEventFactory.callCreatureSpawnEvent((EntityLivingBase) p_72838_1_, spawnReason); ++ } ++ else if (p_72838_1_ instanceof EntityItem) ++ { ++ event = CraftEventFactory.callItemSpawnEvent((EntityItem) p_72838_1_); ++ } ++ else if (p_72838_1_.getBukkitEntity() instanceof org.bukkit.entity.Projectile) ++ { ++ // Not all projectiles extend EntityProjectile, so check for Bukkit interface instead ++ event = CraftEventFactory.callProjectileLaunchEvent(p_72838_1_); ++ } ++ // Spigot start ++ else if (p_72838_1_ instanceof EntityXPOrb) ++ { ++ EntityXPOrb xp = (EntityXPOrb) p_72838_1_; ++ double radius = this.getSpigotConfig().expMerge; // Cauldron ++ ++ if (radius > 0) ++ { ++ List entities = this.getEntitiesWithinAABBExcludingEntity(p_72838_1_, p_72838_1_.boundingBox.expand(radius, radius, radius)); ++ ++ for (Entity e : entities) ++ { ++ if (e instanceof EntityXPOrb) ++ { ++ EntityXPOrb loopItem = (EntityXPOrb) e; ++ ++ if (!loopItem.isDead) ++ { ++ xp.xpValue += loopItem.xpValue; ++ loopItem.setDead(); ++ } ++ } ++ } ++ } ++ } // Spigot end ++ ++ if (event != null && (event.isCancelled() || p_72838_1_.isDead)) ++ { ++ p_72838_1_.isDead = true; ++ return false; ++ } ++ // CraftBukkit end ++ + if (!flag && !this.chunkExists(i, j)) + { ++ p_72838_1_.isDead = true; // CraftBukkit + return false; + } + else +@@ -1336,6 +1817,7 @@ + this.getChunkFromChunkCoords(i, j).addEntity(p_72838_1_); + this.loadedEntityList.add(p_72838_1_); + this.onEntityAdded(p_72838_1_); ++ net.minecraftforge.cauldron.CauldronHooks.logEntitySpawn(this, p_72838_1_, spawnReason); + return true; + } + } +@@ -1346,6 +1828,8 @@ + { + ((IWorldAccess)this.worldAccesses.get(i)).onEntityCreate(p_72923_1_); + } ++ ++ p_72923_1_.valid = true; // CraftBukkit + } + + public void onEntityRemoved(Entity p_72847_1_) +@@ -1354,6 +1838,8 @@ + { + ((IWorldAccess)this.worldAccesses.get(i)).onEntityDestroy(p_72847_1_); + } ++ ++ p_72847_1_.valid = false; // CraftBukkit + } + + public void removeEntity(Entity p_72900_1_) +@@ -1397,6 +1883,19 @@ + } + + this.loadedEntityList.remove(p_72973_1_); ++ // CraftBukkit start - Decrement loop variable field if we've already ticked this entity ++ int index = this.loadedEntityList.indexOf(p_72973_1_); ++ ++ if (index != -1) ++ { ++ if (index <= this.tickPosition) ++ { ++ this.tickPosition--; ++ } ++ ++ this.loadedEntityList.remove(index); ++ } ++ // CraftBukkit end + this.onEntityRemoved(p_72973_1_); + } + +@@ -1408,40 +1907,58 @@ + public List getCollidingBoundingBoxes(Entity p_72945_1_, AxisAlignedBB p_72945_2_) + { + this.collidingBoundingBoxes.clear(); ++ if (CauldronHooks.checkBoundingBoxSize(p_72945_1_, p_72945_2_)) return new ArrayList(); // Removing misbehaved living entities + int i = MathHelper.floor_double(p_72945_2_.minX); + int j = MathHelper.floor_double(p_72945_2_.maxX + 1.0D); + int k = MathHelper.floor_double(p_72945_2_.minY); + int l = MathHelper.floor_double(p_72945_2_.maxY + 1.0D); + int i1 = MathHelper.floor_double(p_72945_2_.minZ); + int j1 = MathHelper.floor_double(p_72945_2_.maxZ + 1.0D); ++ // Spigot start ++ int ystart = ((k - 1) < 0) ? 0 : (k - 1); + +- for (int k1 = i; k1 < j; ++k1) ++ for (int chunkx = (i >> 4); chunkx <= ((j - 1) >> 4); chunkx++) + { +- for (int l1 = i1; l1 < j1; ++l1) ++ int cx = chunkx << 4; ++ ++ for (int chunkz = (i1 >> 4); chunkz <= ((j1 - 1) >> 4); chunkz++) + { +- if (this.blockExists(k1, 64, l1)) ++ if (!this.chunkExists(chunkx, chunkz)) + { +- for (int i2 = k - 1; i2 < l; ++i2) +- { +- Block block; ++ continue; ++ } + +- if (k1 >= -30000000 && k1 < 30000000 && l1 >= -30000000 && l1 < 30000000) ++ int cz = chunkz << 4; ++ Chunk chunk = this.getChunkFromChunkCoords(chunkx, chunkz); ++ // Compute ranges within chunk ++ int xstart = (i < cx) ? cx : i; ++ int xend = (j < (cx + 16)) ? j : (cx + 16); ++ int zstart = (i1 < cz) ? cz : i1; ++ int zend = (j1 < (cz + 16)) ? j1 : (cz + 16); ++ ++ // Loop through blocks within chunk ++ for (int x = xstart; x < xend; x++) ++ { ++ for (int z = zstart; z < zend; z++) ++ { ++ for (int y = ystart; y < l; y++) + { +- block = this.getBlock(k1, i2, l1); +- } +- else +- { +- block = Blocks.stone; +- } ++ Block block = chunk.getBlock(x - cx, y, z - cz); + +- block.addCollisionBoxesToList(this, k1, i2, l1, p_72945_2_, this.collidingBoundingBoxes, p_72945_1_); ++ if (block != null) ++ { ++ block.addCollisionBoxesToList(this, x, y, z, p_72945_2_, this.collidingBoundingBoxes, p_72945_1_); ++ } ++ } + } + } + } + } ++ // Spigot end + + double d0 = 0.25D; + List list = this.getEntitiesWithinAABBExcludingEntity(p_72945_1_, p_72945_2_.expand(d0, d0, d0)); ++ net.minecraftforge.cauldron.CauldronHooks.logEntitySize(this, p_72945_1_, list); // Cauldron add logging for entity collisions + + for (int j2 = 0; j2 < list.size(); ++j2) + { +@@ -1797,11 +2314,22 @@ + Entity entity; + CrashReport crashreport; + CrashReportCategory crashreportcategory; ++ // Cauldron start ++ entitiesTicked = 0; ++ tilesTicked = 0; ++ // Cauldron end + + for (i = 0; i < this.weatherEffects.size(); ++i) + { + entity = (Entity)this.weatherEffects.get(i); + ++ // CraftBukkit start - Fixed an NPE ++ if (entity == null) ++ { ++ continue; ++ } ++ // CraftBukkit end ++ + try + { + ++entity.ticksExisted; +@@ -1862,10 +2390,13 @@ + + this.unloadedEntityList.clear(); + this.theProfiler.endStartSection("regular"); ++ org.spigotmc.ActivationRange.activateEntities(this); // Spigot ++ timings.entityTick.startTiming(); // Spigot + +- for (i = 0; i < this.loadedEntityList.size(); ++i) ++ // CraftBukkit start - Use field for loop variable ++ for (this.tickPosition = 0; this.tickPosition < this.loadedEntityList.size(); ++this.tickPosition) + { +- entity = (Entity)this.loadedEntityList.get(i); ++ entity = (Entity)this.loadedEntityList.get(this.tickPosition); + + if (entity.ridingEntity != null) + { +@@ -1884,7 +2415,9 @@ + { + try + { ++ SpigotTimings.tickEntityTimer.startTiming(); // Spigot + this.updateEntity(entity); ++ SpigotTimings.tickEntityTimer.stopTiming(); // Spigot + } + catch (Throwable throwable1) + { +@@ -1917,29 +2450,56 @@ + this.getChunkFromChunkCoords(j, l).removeEntity(entity); + } + +- this.loadedEntityList.remove(i--); ++ this.loadedEntityList.remove(this.tickPosition--); // CraftBukkit - Use field for loop variable + this.onEntityRemoved(entity); + } + + this.theProfiler.endSection(); + } + ++ timings.entityTick.stopTiming(); // Spigot + this.theProfiler.endStartSection("blockEntities"); ++ timings.tileEntityTick.startTiming(); // Spigot + this.field_147481_N = true; ++ // CraftBukkit start - From below, clean up tile entities before ticking them ++ if (!this.field_147483_b.isEmpty()) ++ { ++ for (Object tile : field_147483_b) ++ { ++ ((TileEntity) tile).onChunkUnload(); ++ } ++ this.loadedTileEntityList.removeAll(this.field_147483_b); ++ this.field_147483_b.clear(); ++ } ++ // CraftBukkit end + Iterator iterator = this.loadedTileEntityList.iterator(); + + while (iterator.hasNext()) + { + TileEntity tileentity = (TileEntity)iterator.next(); + +- if (!tileentity.isInvalid() && tileentity.hasWorldObj() && this.blockExists(tileentity.xCoord, tileentity.yCoord, tileentity.zCoord)) ++ // Spigot start ++ if (tileentity == null) + { ++ getServer().getLogger().severe("Cauldron has detected a null entity and has removed it, preventing a crash"); ++ iterator.remove(); ++ continue; ++ } ++ // Spigot end ++ ++ if (!tileentity.isInvalid() && tileentity.hasWorldObj() && CauldronHooks.canTileEntityTick(tileentity, this) ++ && this.blockExists(tileentity.xCoord, tileentity.yCoord, tileentity.zCoord)) ++ { + try + { ++ tileentity.tickTimer.startTiming(); // Spigot ++ tilesTicked++; + tileentity.updateEntity(); ++ tileentity.tickTimer.stopTiming(); // Spigot + } + catch (Throwable throwable) + { ++ tileentity.tickTimer.stopTiming(); // Spigot + crashreport = CrashReport.makeCrashReport(throwable, "Ticking block entity"); + crashreportcategory = crashreport.makeCategory("Block entity being ticked"); + tileentity.func_145828_a(crashreportcategory); +@@ -1972,6 +2532,11 @@ + } + } + ++ timings.tileEntityTick.stopTiming(); // Spigot ++ timings.tileEntityPending.startTiming(); // Spigot ++ this.field_147481_N = false; ++ ++ /* CraftBukkit start - Moved up + if (!this.field_147483_b.isEmpty()) + { + for (Object tile : field_147483_b) +@@ -1981,6 +2546,7 @@ + this.loadedTileEntityList.removeAll(this.field_147483_b); + this.field_147483_b.clear(); + } ++ */ // CraftBukkit end + + this.field_147481_N = false; + +@@ -2016,17 +2582,23 @@ + this.addedTileEntityList.clear(); + } + ++ timings.tileEntityPending.stopTiming(); // Spigot + this.theProfiler.endSection(); + this.theProfiler.endSection(); + } + + public void func_147448_a(Collection p_147448_1_) + { +- List dest = field_147481_N ? addedTileEntityList : loadedTileEntityList; +- for(TileEntity entity : (Collection)p_147448_1_) ++ // Cauldron start ++ Collection dest = field_147481_N ? addedTileEntityList : loadedTileEntityList; // List -> Collection for CB loadedTileEntityList type change ++ for(Object entity : p_147448_1_) + { +- if(entity.canUpdate()) dest.add(entity); ++ if (CauldronHooks.canUpdate((TileEntity) entity)) ++ { ++ dest.add(entity); ++ } + } ++ // Cauldron end + } + + public void updateEntity(Entity p_72870_1_) +@@ -2041,16 +2613,27 @@ + 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 forceUpdate = false; // Cauldron + + if (!canUpdate) + { + EntityEvent.CanUpdate event = new EntityEvent.CanUpdate(p_72866_1_); + MinecraftForge.EVENT_BUS.post(event); + canUpdate = event.canUpdate; ++ forceUpdate = canUpdate; // Cauldron + } +- ++ // Spigot start ++ if (!isForced && !forceUpdate && !org.spigotmc.ActivationRange.checkIfActive(p_72866_1_)) // Cauldron - ignore if forge event forced update or entity is in forced chunk ++ { ++ p_72866_1_.ticksExisted++; ++ p_72866_1_.inactiveTick(); ++ return; ++ } ++ // Spigot end + if (canUpdate) + { ++ p_72866_1_.tickTimer.startTiming(); ++ entitiesTicked++; // Cauldron + 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 +2717,7 @@ + p_72866_1_.riddenByEntity = null; + } + } ++ p_72866_1_.tickTimer.stopTiming(); // Spigot + } + } + +@@ -2570,7 +3154,7 @@ + return; + } + +- if (p_147455_4_.canUpdate()) ++ if (CauldronHooks.canUpdate(p_147455_4_)) + { + if (this.field_147481_N) + { +@@ -2718,7 +3302,15 @@ + + if (i <= 0) + { +- this.worldInfo.setThundering(!this.worldInfo.isThundering()); ++ // CraftBukkit start ++ ThunderChangeEvent thunder = new ThunderChangeEvent(this.getWorld(), !this.worldInfo.isThundering()); ++ this.getServer().getPluginManager().callEvent(thunder); ++ ++ if (!thunder.isCancelled()) ++ { ++ this.worldInfo.setThundering(!this.worldInfo.isThundering()); ++ } ++ // CraftBukkit end + } + } + +@@ -2754,7 +3346,15 @@ + + if (j <= 0) + { +- this.worldInfo.setRaining(!this.worldInfo.isRaining()); ++ // CraftBukkit start ++ WeatherChangeEvent weather = new WeatherChangeEvent(this.getWorld(), !this.worldInfo.isRaining()); ++ this.getServer().getPluginManager().callEvent(weather); ++ ++ if (!weather.isCancelled()) ++ { ++ this.worldInfo.setRaining(!this.worldInfo.isRaining()); ++ } ++ // CraftBukkit end + } + } + +@@ -2777,8 +3377,41 @@ + protected void setActivePlayerChunksAndCheckLight() + { + this.activeChunkSet.clear(); ++ // Cauldron start - add persistent chunks to be ticked for growth ++ this.activeChunkSet_CB.clear(); ++ for (ChunkCoordIntPair chunk : getPersistentChunks().keySet()) ++ { ++ this.activeChunkSet.add(chunk); ++ long key = chunkToKey(chunk.chunkXPos, chunk.chunkZPos); ++ this.activeChunkSet_CB.put(key, (short) 0); ++ if (!this.chunkExists(chunk.chunkXPos, chunk.chunkZPos)) ++ { ++ ((WorldServer) this).theChunkProviderServer.loadChunk(chunk.chunkXPos, chunk.chunkZPos); ++ } ++ } ++ // Cauldron end + this.theProfiler.startSection("buildList"); +- this.activeChunkSet.addAll(getPersistentChunks().keySet()); ++ // Spigot start ++ int optimalChunks = this.getSpigotConfig().chunksPerTick; // Cauldron ++ ++ // Quick conditions to allow us to exist early ++ if (optimalChunks <= 0) // Cauldron tick chunks even if no players are logged in ++ { ++ return; ++ } ++ ++ // Keep chunks with growth inside of the optimal chunk range ++ int chunksPerPlayer = Math.min(200, Math.max(1, (int) (((optimalChunks - playerEntities.size()) / (double) playerEntities.size()) + 0.5))); ++ // Cauldron start - use server view distance instead of capping it at 7 ++ int randRange = this.func_152379_p(); ++ if (randRange < 1) ++ { ++ throw new IllegalArgumentException("Too small view radius! edit spigot.yml and change view-distance to a value > 0."); ++ } ++ // Cauldron end ++ // odds of growth happening vs growth happening in vanilla ++ this.growthOdds = this.modifiedOdds = Math.max(35, Math.min(100, ((chunksPerPlayer + 1) * 100F) / 15F)); ++ // Spigot end + int i; + EntityPlayer entityplayer; + int j; +@@ -2788,17 +3421,28 @@ + for (i = 0; i < this.playerEntities.size(); ++i) + { + entityplayer = (EntityPlayer)this.playerEntities.get(i); +- j = MathHelper.floor_double(entityplayer.posX / 16.0D); +- k = MathHelper.floor_double(entityplayer.posZ / 16.0D); +- l = this.func_152379_p(); ++ int chunkX = MathHelper.floor_double(entityplayer.posX / 16.0D); ++ int chunkZ = MathHelper.floor_double(entityplayer.posZ / 16.0D); ++ // Spigot start - Always update the chunk the player is on ++ long key = chunkToKey(chunkX, chunkZ); ++ int existingPlayers = Math.max(0, activeChunkSet_CB.get(key)); //filter out -1's ++ activeChunkSet_CB.put(key, (short) (existingPlayers + 1)); ++ activeChunkSet.add(new ChunkCoordIntPair(chunkX, chunkZ)); // Cauldron - vanilla compatibility + +- for (int i1 = -l; i1 <= l; ++i1) ++ // Check and see if we update the chunks surrounding the player this tick ++ for (int chunk = 0; chunk < chunksPerPlayer; chunk++) + { +- for (int j1 = -l; j1 <= l; ++j1) ++ int dx = (rand.nextBoolean() ? 1 : -1) * rand.nextInt(randRange); ++ int dz = (rand.nextBoolean() ? 1 : -1) * rand.nextInt(randRange); ++ long hash = chunkToKey(dx + chunkX, dz + chunkZ); ++ ++ if (!activeChunkSet_CB.contains(hash) && this.chunkExists(dx + chunkX, dz + chunkZ)) + { +- this.activeChunkSet.add(new ChunkCoordIntPair(i1 + j, j1 + k)); ++ activeChunkSet_CB.put(hash, (short) -1); //no players ++ activeChunkSet.add(new ChunkCoordIntPair(dx + chunkX, dz + chunkZ)); // Cauldron - vanilla compatibility + } + } ++ // Spigot End + } + + this.theProfiler.endSection(); +@@ -2810,7 +3454,7 @@ + + this.theProfiler.startSection("playerCheckLight"); + +- if (!this.playerEntities.isEmpty()) ++ if (this.getSpigotConfig().randomLightUpdates && !this.playerEntities.isEmpty()) // Spigot // Cauldron + { + i = this.rand.nextInt(this.playerEntities.size()); + entityplayer = (EntityPlayer)this.playerEntities.get(i); +@@ -3284,8 +3928,21 @@ + { + Entity entity = (Entity)this.loadedEntityList.get(j); + +- if ((!(entity instanceof EntityLiving) || !((EntityLiving)entity).isNoDespawnRequired()) && p_72907_1_.isAssignableFrom(entity.getClass())) ++ // CraftBukkit start - Split out persistent check, don't apply it to special persistent mobs ++ if (entity instanceof EntityLiving) + { ++ EntityLiving entityliving = (EntityLiving) entity; ++ ++ if (entityliving.canDespawn_CB() && entityliving.isNoDespawnRequired()) ++ { ++ continue; ++ } ++ } ++ ++ if (p_72907_1_.isAssignableFrom(entity.getClass())) ++ { ++ // if ((!(entity instanceof EntityLiving) || !((EntityLiving)entity).isNoDespawnRequired()) && p_72907_1_.isAssignableFrom(entity.getClass())) ++ // CraftBukkit end + ++i; + } + } +@@ -3314,8 +3971,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_); ++ if (block1 == null) return false; // Cauldron + AxisAlignedBB axisalignedbb = p_147472_5_ ? null : p_147472_1_.getCollisionBoundingBoxFromPool(this, p_147472_2_, p_147472_3_, p_147472_4_); +- return axisalignedbb != null && !this.checkNoEntityCollision(axisalignedbb, p_147472_7_) ? false : (block1.getMaterial() == Material.circuits && p_147472_1_ == Blocks.anvil ? true : block1.isReplaceable(this, p_147472_2_, p_147472_3_, p_147472_4_) && p_147472_1_.canReplace(this, p_147472_2_, p_147472_3_, p_147472_4_, p_147472_6_, p_147472_8_)); ++ // CraftBukkit start - store default return ++ boolean defaultReturn = axisalignedbb != null && !this.checkNoEntityCollision(axisalignedbb, p_147472_7_) ? false ++ : (block1.getMaterial() == Material.circuits && p_147472_1_ == Blocks.anvil ? true : block1.isReplaceable(this, p_147472_2_, p_147472_3_, ++ p_147472_4_) && p_147472_1_.canReplace(this, p_147472_2_, p_147472_3_, p_147472_4_, p_147472_6_, p_147472_8_)); ++ BlockCanBuildEvent event = new BlockCanBuildEvent(this.getWorld().getBlockAt(p_147472_2_, p_147472_3_, p_147472_4_), ++ CraftMagicNumbers.getId(p_147472_1_), defaultReturn); ++ this.getServer().getPluginManager().callEvent(event); ++ return event.isBuildable(); ++ // CraftBukkit end + } + + 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 +4130,12 @@ + for (int i = 0; i < this.playerEntities.size(); ++i) + { + EntityPlayer entityplayer1 = (EntityPlayer)this.playerEntities.get(i); ++ // CraftBukkit start - Fixed an NPE ++ if (entityplayer1 == null || entityplayer1.isDead) ++ { ++ continue; ++ } ++ // CraftBukkit end + 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 +4161,12 @@ + for (int i = 0; i < this.playerEntities.size(); ++i) + { + EntityPlayer entityplayer1 = (EntityPlayer)this.playerEntities.get(i); +- ++ // CraftBukkit start - Fixed an NPE ++ if (entityplayer1 == null || entityplayer1.isDead) ++ { ++ continue; ++ } ++ // CraftBukkit end + if (!entityplayer1.capabilities.disableDamage && entityplayer1.isEntityAlive()) + { + double d5 = entityplayer1.getDistanceSq(p_72846_1_, p_72846_3_, p_72846_5_); +@@ -3660,6 +4337,18 @@ + + public void updateAllPlayersSleepingFlag() {} + ++ // CraftBukkit start ++ // Calls the method that checks to see if players are sleeping ++ // Called by CraftPlayer.setPermanentSleeping() ++ public void checkSleepStatus() ++ { ++ if (!this.isRemote) ++ { ++ this.updateAllPlayersSleepingFlag(); ++ } ++ } ++ // CraftBukkit end ++ + public float getWeightedThunderStrength(float p_72819_1_) + { + return (this.prevThunderingStrength + (this.thunderingStrength - this.prevThunderingStrength) * p_72819_1_) * this.getRainStrength(p_72819_1_); +@@ -3932,8 +4621,8 @@ + */ + public void addTileEntity(TileEntity entity) + { +- List dest = field_147481_N ? addedTileEntityList : loadedTileEntityList; +- if(entity.canUpdate()) ++ Collection dest = field_147481_N ? addedTileEntityList : loadedTileEntityList; // Cauldron - List -> Collection for CB loadedTileEntityList type change ++ if (CauldronHooks.canUpdate(entity)) + { + dest.add(entity); + } +@@ -4029,4 +4718,60 @@ + } + return count; + } ++ ++ // Cauldron start ++ public boolean isEmpty(int x, int y, int z) // Required until SS inheritance bug is fixed ++ { ++ return isAirBlock(x, y, z); ++ } ++ ++ public Block getType(int x, int y, int z) // Required until SS inheritance bug is fixed ++ { ++ return getBlock(x, y, z); ++ } ++ ++ public boolean isActiveChunk(int x, int z) ++ { ++ return getPersistentChunks().containsKey(new ChunkCoordIntPair(x, z)) || activeChunkSet_CB.containsKey(chunkToKey(x, z)); ++ } ++ ++ public boolean isActiveChunk(long key) ++ { ++ return isActiveChunk(keyToX(key), keyToZ(key)); ++ } ++ ++ public boolean isActiveBlockCoord(int x, int z) ++ { ++ return isActiveChunk(x >> 4, z >> 4); ++ } ++ ++ public boolean inActiveChunk(Entity entity) ++ { ++ return isActiveBlockCoord(MathHelper.floor_double(entity.posX), MathHelper.floor_double(entity.posZ)); ++ } ++ ++ // this method is used by ForgeMultipart and Immibis's Microblocks ++ public boolean canPlaceMultipart(Block block, int x, int y, int z) ++ { ++ BlockPlaceEvent placeEvent = null; ++ if (ItemStack.currentPlayer != null) ++ { ++ placeEvent = org.bukkit.craftbukkit.event.CraftEventFactory.callBlockPlaceEvent(this, ItemStack.currentPlayer, ++ org.bukkit.craftbukkit.block.CraftBlockState.getBlockState(this, x, y, z, 3), x, y, z); ++ } ++ ++ if (placeEvent != null && (placeEvent.isCancelled() || !placeEvent.canBuild())) ++ { ++ return false; ++ } ++ ++ return true; ++ } ++ ++ public org.spigotmc.SpigotWorldConfig getSpigotConfig() ++ { ++ if (this.spigotConfig == null) if (DimensionManager.getWorld(0) != null) return DimensionManager.getWorld(0).spigotConfig; ++ return this.spigotConfig; ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraft/world/WorldManager.java.patch b/patches/net/minecraft/world/WorldManager.java.patch new file mode 100644 index 0000000..308e0d9 --- /dev/null +++ b/patches/net/minecraft/world/WorldManager.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/world/WorldManager.java ++++ ../src-work/minecraft/net/minecraft/world/WorldManager.java +@@ -12,7 +12,7 @@ + public class WorldManager implements IWorldAccess + { + private MinecraftServer mcServer; +- private WorldServer theWorldServer; ++ public WorldServer theWorldServer; // CraftBukkit - private -> public + private static final String __OBFID = "CL_00001433"; + + public WorldManager(MinecraftServer p_i1517_1_, WorldServer p_i1517_2_) diff --git a/patches/net/minecraft/world/WorldServer.java.patch b/patches/net/minecraft/world/WorldServer.java.patch new file mode 100644 index 0000000..8748918 --- /dev/null +++ b/patches/net/minecraft/world/WorldServer.java.patch @@ -0,0 +1,607 @@ +--- ../src-base/minecraft/net/minecraft/world/WorldServer.java ++++ ../src-work/minecraft/net/minecraft/world/WorldServer.java +@@ -67,11 +67,25 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import net.minecraft.block.ITileEntityProvider; ++import net.minecraft.block.BlockJukebox; ++import net.minecraft.tileentity.*; ++import org.bukkit.WeatherType; ++import org.bukkit.block.BlockState; ++import org.bukkit.craftbukkit.util.LongHash; ++ ++import org.bukkit.event.block.BlockFormEvent; ++import org.bukkit.event.weather.LightningStrikeEvent; ++import org.bukkit.event.weather.ThunderChangeEvent; ++import org.bukkit.event.weather.WeatherChangeEvent; ++// CraftBukkit end ++ + public class WorldServer extends World + { + private static final Logger logger = LogManager.getLogger(); + private final MinecraftServer mcServer; +- private final EntityTracker theEntityTracker; ++ public EntityTracker theEntityTracker; // CraftBukkit - private final -> public + private final PlayerManager thePlayerManager; + private Set pendingTickListEntriesHashSet; + private TreeSet pendingTickListEntriesTreeSet; +@@ -92,9 +106,13 @@ + protected Set doneChunks = new HashSet(); + public List customTeleporters = new ArrayList(); + ++ // CraftBukkit start ++ public final int dimension; ++ + public WorldServer(MinecraftServer p_i45284_1_, ISaveHandler p_i45284_2_, String p_i45284_3_, int p_i45284_4_, WorldSettings p_i45284_5_, Profiler p_i45284_6_) + { + super(p_i45284_2_, p_i45284_3_, p_i45284_5_, WorldProvider.getProviderForDimension(p_i45284_4_), p_i45284_6_); ++ this.dimension = p_i45284_4_; + this.mcServer = p_i45284_1_; + this.theEntityTracker = new EntityTracker(this); + this.thePlayerManager = new PlayerManager(this); +@@ -124,6 +142,47 @@ + this.mapStorage.setData("scoreboard", scoreboardsavedata); + } + ++ scoreboardsavedata.func_96499_a(this.worldScoreboard); ++ ((ServerScoreboard) this.worldScoreboard).func_96547_a(scoreboardsavedata); ++ } ++ ++ // Add env and gen to constructor ++ public WorldServer(MinecraftServer p_i45284_1_, ISaveHandler p_i45284_2_, String p_i45284_3_, int p_i45284_4_, WorldSettings p_i45284_5_, ++ Profiler p_i45284_6_, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) ++ { ++ super(p_i45284_2_, p_i45284_3_, p_i45284_5_, WorldProvider.getProviderForDimension(p_i45284_4_), p_i45284_6_, gen, env); ++ this.dimension = p_i45284_4_; ++ this.pvpMode = p_i45284_1_.isPVPEnabled(); ++ // CraftBukkit end ++ this.mcServer = p_i45284_1_; ++ this.theEntityTracker = new EntityTracker(this); ++ this.thePlayerManager = new PlayerManager(this, spigotConfig.viewDistance); // Spigot ++ ++ if (this.entityIdMap == null) ++ { ++ this.entityIdMap = new IntHashMap(); ++ } ++ ++ if (this.pendingTickListEntriesHashSet == null) ++ { ++ this.pendingTickListEntriesHashSet = new HashSet(); ++ } ++ ++ if (this.pendingTickListEntriesTreeSet == null) ++ { ++ this.pendingTickListEntriesTreeSet = new TreeSet(); ++ } ++ ++ this.worldTeleporter = new org.bukkit.craftbukkit.CraftTravelAgent(this); // CraftBukkit ++ this.worldScoreboard = new ServerScoreboard(p_i45284_1_); ++ ScoreboardSaveData scoreboardsavedata = (ScoreboardSaveData) this.mapStorage.loadData(ScoreboardSaveData.class, "scoreboard"); ++ ++ if (scoreboardsavedata == null) ++ { ++ scoreboardsavedata = new ScoreboardSaveData(); ++ this.mapStorage.setData("scoreboard", scoreboardsavedata); ++ } ++ + if (!(this instanceof WorldServerMulti)) //Forge: We fix the global mapStorage, which causes us to share scoreboards early. So don't associate the save data with the temporary scoreboard + { + scoreboardsavedata.func_96499_a(this.worldScoreboard); +@@ -132,6 +191,31 @@ + DimensionManager.setWorld(p_i45284_4_, this); + } + ++ public WorldServer(MinecraftServer minecraftServer, ISaveHandler saveHandler, String par2String, WorldProvider provider, WorldSettings par4WorldSettings, ++ Profiler theProfiler) ++ { ++ super(saveHandler, par2String, provider, par4WorldSettings, theProfiler); ++ this.dimension = provider.dimensionId; ++ this.pvpMode = minecraftServer.isPVPEnabled(); ++ this.mcServer = minecraftServer; ++ this.theEntityTracker = null; ++ this.thePlayerManager = null; ++ this.worldTeleporter = null; ++ } ++ ++ private boolean canSpawn(int x, int z) ++ { ++ if (this.generator != null) ++ { ++ return this.generator.canSpawn(this.getWorld(), x, z); ++ } ++ else ++ { ++ return this.provider.canCoordinateBeSpawn(x, z); ++ } ++ } ++ // CraftBukkit end ++ + public void tick() + { + super.tick(); +@@ -155,12 +239,19 @@ + } + + this.theProfiler.startSection("mobSpawner"); ++ // CraftBukkit start - Only call spawner if we have players online and the world allows for mobs or animals ++ long time = this.worldInfo.getWorldTotalTime(); + +- if (this.getGameRules().getGameRuleBooleanValue("doMobSpawning")) ++ if (this.getGameRules().getGameRuleBooleanValue("doMobSpawning") && (this.spawnHostileMobs || this.spawnPeacefulMobs) && (this instanceof WorldServer && this.playerEntities.size() > 0)) + { +- this.animalSpawner.findChunksForSpawning(this, this.spawnHostileMobs, this.spawnPeacefulMobs, this.worldInfo.getWorldTotalTime() % 400L == 0L); ++ timings.mobSpawn.startTiming(); // Spigot ++ this.animalSpawner.findChunksForSpawning(this, this.spawnHostileMobs ++ && (this.ticksPerMonsterSpawns != 0 && time % this.ticksPerMonsterSpawns == 0L), this.spawnPeacefulMobs ++ && (this.ticksPerAnimalSpawns != 0 && time % this.ticksPerAnimalSpawns == 0L), this.worldInfo.getWorldTotalTime() % 400L == 0L); ++ timings.mobSpawn.stopTiming(); // Spigot + } +- ++ // CraftBukkit end ++ timings.doChunkUnload.startTiming(); // Spigot + this.theProfiler.endStartSection("chunkSource"); + this.chunkProvider.unloadQueuedChunks(); + int j = this.calculateSkylightSubtracted(1.0F); +@@ -177,23 +268,40 @@ + this.worldInfo.setWorldTime(this.worldInfo.getWorldTime() + 1L); + } + ++ timings.doChunkUnload.stopTiming(); // Spigot + this.theProfiler.endStartSection("tickPending"); ++ timings.doTickPending.startTiming(); // Spigot + this.tickUpdates(false); ++ timings.doChunkUnload.stopTiming(); // Spigot + this.theProfiler.endStartSection("tickBlocks"); ++ timings.doTickTiles.startTiming(); // Spigot + this.func_147456_g(); ++ timings.doTickTiles.stopTiming(); // Spigot + this.theProfiler.endStartSection("chunkMap"); ++ timings.doChunkMap.startTiming(); // Spigot + this.thePlayerManager.updatePlayerInstances(); ++ timings.doChunkMap.stopTiming(); // Spigot + this.theProfiler.endStartSection("village"); ++ timings.doVillages.startTiming(); // Spigot + this.villageCollectionObj.tick(); + this.villageSiegeObj.tick(); ++ timings.doVillages.stopTiming(); // Spigot + this.theProfiler.endStartSection("portalForcer"); ++ timings.doPortalForcer.startTiming(); // Spigot + this.worldTeleporter.removeStalePortalLocations(this.getTotalWorldTime()); + for (Teleporter tele : customTeleporters) + { + tele.removeStalePortalLocations(getTotalWorldTime()); + } ++ timings.doPortalForcer.stopTiming(); // Spigot + this.theProfiler.endSection(); ++ timings.doSounds.startTiming(); // Spigot + this.func_147488_Z(); ++ timings.doSounds.stopTiming(); // Spigot ++ ++ timings.doChunkGC.startTiming(); // Spigot ++ this.getWorld().processChunkGC(); // CraftBukkit ++ timings.doChunkGC.stopTiming(); // Spigot + } + + public BiomeGenBase.SpawnListEntry spawnRandomCreature(EnumCreatureType p_73057_1_, int p_73057_2_, int p_73057_3_, int p_73057_4_) +@@ -212,7 +320,7 @@ + { + EntityPlayer entityplayer = (EntityPlayer)iterator.next(); + +- if (!entityplayer.isPlayerSleeping()) ++ if (!entityplayer.isPlayerSleeping() && !entityplayer.fauxSleeping) // CraftBukkit + { + this.allPlayersSleeping = false; + break; +@@ -240,7 +348,25 @@ + + private void resetRainAndThunder() + { +- provider.resetRainAndThunder(); ++ // CraftBukkit start ++ WeatherChangeEvent weather = new WeatherChangeEvent(this.getWorld(), false); ++ this.getServer().getPluginManager().callEvent(weather); ++ ThunderChangeEvent thunder = new ThunderChangeEvent(this.getWorld(), false); ++ this.getServer().getPluginManager().callEvent(thunder); ++ ++ if (!weather.isCancelled()) ++ { ++ this.worldInfo.setRainTime(0); ++ this.worldInfo.setRaining(false); ++ } ++ ++ if (!thunder.isCancelled()) ++ { ++ this.worldInfo.setThunderTime(0); ++ this.worldInfo.setThundering(false); ++ } ++ // CraftBukkit end ++ if (!weather.isCancelled() && !thunder.isCancelled()) provider.resetRainAndThunder(); // Cauldron + } + + public boolean areAllPlayersAsleep() +@@ -248,19 +374,26 @@ + if (this.allPlayersSleeping && !this.isRemote) + { + Iterator iterator = this.playerEntities.iterator(); ++ // CraftBukkit - This allows us to assume that some people are in bed but not really, allowing time to pass in spite of AFKers ++ boolean foundActualSleepers = false; + EntityPlayer entityplayer; + + do + { + if (!iterator.hasNext()) + { +- return true; ++ return foundActualSleepers; // CraftBukkit + } + + entityplayer = (EntityPlayer)iterator.next(); ++ // CraftBukkit start ++ if (entityplayer.isPlayerFullyAsleep()) ++ { ++ foundActualSleepers = true; ++ } + } +- while (entityplayer.isPlayerFullyAsleep()); +- ++ while (entityplayer.isPlayerFullyAsleep() || entityplayer.fauxSleeping); ++ // CraftBukkit end + return false; + } + else +@@ -302,15 +435,29 @@ + super.func_147456_g(); + int i = 0; + int j = 0; +- Iterator iterator = this.activeChunkSet.iterator(); ++ // Iterator iterator = this.activeChunkSet.iterator(); + +- while (iterator.hasNext()) ++ // Spigot start ++ for (gnu.trove.iterator.TLongShortIterator iter = activeChunkSet_CB.iterator(); iter.hasNext();) + { +- ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair)iterator.next(); +- int k = chunkcoordintpair.chunkXPos * 16; +- int l = chunkcoordintpair.chunkZPos * 16; ++ iter.advance(); ++ long chunkCoord = iter.key(); ++ int chunkX = World.keyToX(chunkCoord); ++ int chunkZ = World.keyToZ(chunkCoord); ++ // If unloaded, or in process of being unloaded, drop it ++ if ((!this.chunkExists(chunkX, chunkZ)) || (this.theChunkProviderServer.chunksToUnload.contains(chunkX, chunkZ))) ++ { ++ activeChunkSet.remove(new ChunkCoordIntPair(chunkX, chunkZ)); // Cauldron - vanilla compatibility ++ iter.remove(); ++ continue; ++ } ++ // Spigot end ++ // ChunkCoordIntPair chunkcoordintpair = (ChunkCoordIntPair) iterator.next(); ++ int k = chunkX * 16; ++ int l = chunkZ * 16; ++ + this.theProfiler.startSection("getChunk"); +- Chunk chunk = this.getChunkFromChunkCoords(chunkcoordintpair.chunkXPos, chunkcoordintpair.chunkZPos); ++ Chunk chunk = this.getChunkFromChunkCoords(chunkX, chunkZ); + this.func_147467_a(k, l, chunk); + this.theProfiler.endStartSection("tickChunk"); + chunk.func_150804_b(false); +@@ -346,12 +493,32 @@ + + if (this.isBlockFreezableNaturally(j1 + k, l1 - 1, k1 + l)) + { +- this.setBlock(j1 + k, l1 - 1, k1 + l, Blocks.ice); ++ // CraftBukkit start ++ BlockState blockState = this.getWorld().getBlockAt(j1 + k, l1 - 1, k1 + l).getState(); ++ blockState.setTypeId(Block.getIdFromBlock(Blocks.ice)); ++ BlockFormEvent iceBlockForm = new BlockFormEvent(blockState.getBlock(), blockState); ++ this.getServer().getPluginManager().callEvent(iceBlockForm); ++ ++ if (!iceBlockForm.isCancelled()) ++ { ++ blockState.update(true); ++ } ++ // CraftBukkit end + } + + if (this.isRaining() && this.func_147478_e(j1 + k, l1, k1 + l, true)) + { +- this.setBlock(j1 + k, l1, k1 + l, Blocks.snow_layer); ++ // CraftBukkit start ++ BlockState blockState = this.getWorld().getBlockAt(j1 + k, l1, k1 + l).getState(); ++ blockState.setTypeId(Block.getIdFromBlock(Blocks.snow_layer)); ++ BlockFormEvent snow = new BlockFormEvent(blockState.getBlock(), blockState); ++ this.getServer().getPluginManager().callEvent(snow); ++ ++ if (!snow.isCancelled()) ++ { ++ blockState.update(true); ++ } ++ // CraftBukkit end + } + + if (this.isRaining()) +@@ -388,6 +555,7 @@ + if (block.getTickRandomly()) + { + ++i; ++ this.growthOdds = (iter.value() < 1) ? this.modifiedOdds : 100; // Spigot - grow fast if no players are in this chunk (value = player count) + block.updateTick(this, j2 + k, l2 + extendedblockstorage.getYLocation(), k2 + l, this.rand); + } + } +@@ -396,6 +564,13 @@ + + this.theProfiler.endSection(); + } ++ // Spigot Start ++ if (this.getSpigotConfig().clearChunksOnTick) // Cauldron ++ { ++ activeChunkSet_CB.clear(); ++ activeChunkSet.clear(); // Cauldron ++ } ++ // Spigot End + } + + public boolean isBlockTickScheduledThisTick(int p_147477_1_, int p_147477_2_, int p_147477_3_, Block p_147477_4_) +@@ -474,7 +649,7 @@ + + public void updateEntities() + { +- if (this.playerEntities.isEmpty() && getPersistentChunks().isEmpty()) ++ if (this.playerEntities.isEmpty() && getPersistentChunks().isEmpty()) // Cauldron Use Forge logic here + { + if (this.updateEntityTick++ >= 1200) + { +@@ -506,7 +681,16 @@ + { + if (i > 1000) + { +- i = 1000; ++ // CraftBukkit start - If the server has too much to process over time, try to alleviate that ++ if (i > 20 * 1000) ++ { ++ i = i / 20; ++ } ++ else ++ { ++ i = 1000; ++ } ++ // CraftBukkit end + } + + this.theProfiler.startSection("cleaning"); +@@ -651,7 +835,37 @@ + protected IChunkProvider createChunkProvider() + { + IChunkLoader ichunkloader = this.saveHandler.getChunkLoader(this.provider); +- this.theChunkProviderServer = new ChunkProviderServer(this, ichunkloader, this.provider.createChunkGenerator()); ++ // Cauldron start - if provider is vanilla, proceed to create a bukkit compatible chunk generator ++ if (this.provider.getClass().toString().length() <= 3 || this.provider.getClass().toString().contains("net.minecraft")) ++ { ++ // CraftBukkit start ++ org.bukkit.craftbukkit.generator.InternalChunkGenerator gen; ++ ++ if (this.generator != null) ++ { ++ gen = new org.bukkit.craftbukkit.generator.CustomChunkGenerator(this, this.getSeed(), this.generator); ++ } ++ else if (this.provider instanceof WorldProviderHell) ++ { ++ gen = new org.bukkit.craftbukkit.generator.NetherChunkGenerator(this, this.getSeed()); ++ } ++ else if (this.provider instanceof WorldProviderEnd) ++ { ++ gen = new org.bukkit.craftbukkit.generator.SkyLandsChunkGenerator(this, this.getSeed()); ++ } ++ else ++ { ++ gen = new org.bukkit.craftbukkit.generator.NormalChunkGenerator(this, this.getSeed()); ++ } ++ this.theChunkProviderServer = new ChunkProviderServer(this, ichunkloader, gen); ++ // CraftBukkit end ++ } ++ else ++ // custom provider, load normally for forge compatibility ++ { ++ this.theChunkProviderServer = new ChunkProviderServer(this, ichunkloader, this.provider.createChunkGenerator()); ++ } ++ // Cauldron end + return this.theChunkProviderServer; + } + +@@ -659,29 +873,31 @@ + { + ArrayList arraylist = new ArrayList(); + +- for(int x = (p_147486_1_ >> 4); x <= (p_147486_4_ >> 4); x++) ++ // CraftBukkit start - Get tile entities from chunks instead of world ++ for (int chunkX = (p_147486_1_ >> 4); chunkX <= ((p_147486_4_ - 1) >> 4); chunkX++) + { +- for(int z = (p_147486_3_ >> 4); z <= (p_147486_6_ >> 4); z++) ++ for (int chunkZ = (p_147486_3_ >> 4); chunkZ <= ((p_147486_6_ - 1) >> 4); chunkZ++) + { +- Chunk chunk = getChunkFromChunkCoords(x, z); +- if (chunk != null) ++ Chunk chunk = getChunkFromChunkCoords(chunkX, chunkZ); ++ ++ if (chunk == null) + { +- for(Object obj : chunk.chunkTileEntityMap.values()) ++ continue; ++ } ++ ++ for (Object te : chunk.chunkTileEntityMap.values()) ++ { ++ TileEntity tileentity = (TileEntity) te; ++ ++ if ((tileentity.xCoord >= p_147486_1_) && (tileentity.yCoord >= p_147486_2_) && (tileentity.zCoord >= p_147486_3_) ++ && (tileentity.xCoord < p_147486_4_) && (tileentity.yCoord < p_147486_5_) && (tileentity.zCoord < p_147486_6_)) + { +- TileEntity entity = (TileEntity)obj; +- if (!entity.isInvalid()) +- { +- if (entity.xCoord >= p_147486_1_ && entity.yCoord >= p_147486_2_ && entity.zCoord >= p_147486_3_ && +- entity.xCoord <= p_147486_4_ && entity.yCoord <= p_147486_5_ && entity.zCoord <= p_147486_6_) +- { +- arraylist.add(entity); +- } +- } ++ arraylist.add(tileentity); + } + } + } + } +- ++ // CraftBukkit end + return arraylist; + } + +@@ -733,7 +949,28 @@ + int i = 0; + int j = this.provider.getAverageGroundLevel(); + int k = 0; ++ // CraftBukkit start ++ if (this.generator != null) ++ { ++ Random rand = new Random(this.getSeed()); ++ org.bukkit.Location spawn = this.generator.getFixedSpawnLocation(((WorldServer) this).getWorld(), rand); + ++ if (spawn != null) ++ { ++ if (spawn.getWorld() != ((WorldServer) this).getWorld()) ++ { ++ throw new IllegalStateException("Cannot set spawn point for " + this.worldInfo.getWorldName() + " to be in another world (" ++ + spawn.getWorld().getName() + ")"); ++ } ++ else ++ { ++ this.worldInfo.setSpawnPosition(spawn.getBlockX(), spawn.getBlockY(), spawn.getBlockZ()); ++ this.findingSpawnPoint = false; ++ return; ++ } ++ } ++ } ++ // CraftBukkit end + if (chunkposition != null) + { + i = chunkposition.chunkPosX; +@@ -876,6 +1113,20 @@ + + public boolean addWeatherEffect(Entity p_72942_1_) + { ++ // Cauldron start - vanilla compatibility ++ if (p_72942_1_ instanceof net.minecraft.entity.effect.EntityLightningBolt) ++ { ++ // CraftBukkit start ++ LightningStrikeEvent lightning = new LightningStrikeEvent(this.getWorld(), (org.bukkit.entity.LightningStrike) p_72942_1_.getBukkitEntity()); ++ this.getServer().getPluginManager().callEvent(lightning); ++ ++ if (lightning.isCancelled()) ++ { ++ return false; ++ } ++ // CraftBukkit end ++ } ++ // Cauldron end + 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 +1145,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_) + { ++ // CraftBukkit start ++ Explosion explosion = super.newExplosion(p_72885_1_, p_72885_2_, p_72885_4_, p_72885_6_, p_72885_8_, p_72885_9_, p_72885_10_); ++ ++ if (explosion.wasCanceled) ++ { ++ return explosion; ++ } ++ ++ /* Remove + Explosion explosion = new Explosion(this, p_72885_1_, p_72885_2_, p_72885_4_, p_72885_6_, p_72885_8_); + explosion.isFlaming = p_72885_9_; + explosion.isSmoking = p_72885_10_; + if (net.minecraftforge.event.ForgeEventFactory.onExplosionStart(this, explosion)) return explosion; + explosion.doExplosionA(); + explosion.doExplosionB(false); +- ++ */ ++ // CraftBukkit end - TODO: Check if explosions are still properly implemented + if (!p_72885_10_) + { + explosion.affectedBlockPositions.clear(); +@@ -977,7 +1238,7 @@ + { + boolean flag = this.isRaining(); + super.updateWeather(); +- ++ /* CraftBukkit start + if (this.prevRainingStrength != this.rainingStrength) + { + this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(7, this.rainingStrength), this.provider.dimensionId); +@@ -988,10 +1249,6 @@ + this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(8, this.thunderingStrength), this.provider.dimensionId); + } + +- /*The function in use here has been replaced in order to only send the weather info to players in the correct dimension, +- rather than to all players on the server. This is what causes the client-side rain, as the +- client believes that it has started raining locally, rather than in another dimension. +- */ + if (flag != this.isRaining()) + { + if (flag) +@@ -1006,6 +1263,20 @@ + this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(7, this.rainingStrength), this.provider.dimensionId); + this.mcServer.getConfigurationManager().sendPacketToAllPlayersInDimension(new S2BPacketChangeGameState(8, this.thunderingStrength), this.provider.dimensionId); + } ++ // */ ++ if (flag != this.isRaining()) ++ { ++ // Only send weather packets to those affected ++ for (int i = 0; i < this.playerEntities.size(); ++i) ++ { ++ if (((EntityPlayerMP) this.playerEntities.get(i)).worldObj == this) ++ { ++ ((EntityPlayerMP) this.playerEntities.get(i)).setPlayerWeather((!flag ? WeatherType.DOWNFALL : WeatherType.CLEAR), false); ++ } ++ } ++ ++ // CraftBukkit end ++ } + } + + protected int func_152379_p() +@@ -1069,4 +1340,31 @@ + this(); + } + } ++ ++ // CraftBukkit start - Compatibility methods for BlockChangeDelegate ++ public boolean setRawTypeId(int x, int y, int z, int typeId) ++ { ++ return this.setBlock(x, y, z, Block.getBlockById(typeId), 0, 4); ++ } ++ ++ public boolean setRawTypeIdAndData(int x, int y, int z, int typeId, int data) ++ { ++ return this.setBlock(x, y, z, Block.getBlockById(typeId), data, 4); ++ } ++ ++ public boolean setTypeId(int x, int y, int z, int typeId) ++ { ++ return this.setBlock(x, y, z, Block.getBlockById(typeId), 0, 3); ++ } ++ ++ public boolean setTypeIdAndData(int x, int y, int z, int typeId, int data) ++ { ++ return this.setBlock(x, y, z, Block.getBlockById(typeId), data, 3); ++ } ++ ++ public int getTypeId(int x, int y, int z) ++ { ++ return Block.getIdFromBlock(getBlock(x, y, z)); ++ } ++ // CraftBukkit end + } diff --git a/patches/net/minecraft/world/WorldServerMulti.java.patch b/patches/net/minecraft/world/WorldServerMulti.java.patch new file mode 100644 index 0000000..7382cf4 --- /dev/null +++ b/patches/net/minecraft/world/WorldServerMulti.java.patch @@ -0,0 +1,36 @@ +--- ../src-base/minecraft/net/minecraft/world/WorldServerMulti.java ++++ ../src-work/minecraft/net/minecraft/world/WorldServerMulti.java +@@ -9,6 +9,17 @@ + { + private static final String __OBFID = "CL_00001430"; + ++ // CraftBukkit start - Add Environment and ChunkGenerator arguments ++ public WorldServerMulti(MinecraftServer p_i45283_1_, ISaveHandler p_i45283_2_, String p_i45283_3_, int p_i45283_4_, WorldSettings p_i45283_5_, WorldServer p_i45283_6_, Profiler p_i45283_7_, org.bukkit.World.Environment env, org.bukkit.generator.ChunkGenerator gen) ++ { ++ super(p_i45283_1_, p_i45283_2_, p_i45283_3_, p_i45283_4_, p_i45283_5_, p_i45283_7_, env, gen); ++ // CraftBukkit end ++ this.mapStorage = p_i45283_6_.mapStorage; ++ this.worldScoreboard = p_i45283_6_.getScoreboard(); ++ //this.worldInfo = new DerivedWorldInfo(p_i45283_6_.getWorldInfo()); ++ } ++ ++ // Cauldron start - vanilla compatibility + public WorldServerMulti(MinecraftServer p_i45283_1_, ISaveHandler p_i45283_2_, String p_i45283_3_, int p_i45283_4_, WorldSettings p_i45283_5_, WorldServer p_i45283_6_, Profiler p_i45283_7_) + { + super(p_i45283_1_, p_i45283_2_, p_i45283_3_, p_i45283_4_, p_i45283_5_, p_i45283_7_); +@@ -16,9 +27,15 @@ + this.worldScoreboard = p_i45283_6_.getScoreboard(); + this.worldInfo = new DerivedWorldInfo(p_i45283_6_.getWorldInfo()); + } ++ // Cauldron end + ++ /* we handle all saving including perWorldStorage in WorldServer.saveLevel. This needs to be disabled since we follow ++ // bukkit's world saving methods by using a seperate save handler for each world. Each world folder needs to generate a corresponding ++ // level.dat for plugins that require it such as MultiWorld. + protected void saveLevel() throws MinecraftException + { + this.perWorldStorage.saveAllData(); + } ++ */ ++ // Cauldron end + } diff --git a/patches/net/minecraft/world/WorldType.java.patch b/patches/net/minecraft/world/WorldType.java.patch new file mode 100644 index 0000000..3fcd419 --- /dev/null +++ b/patches/net/minecraft/world/WorldType.java.patch @@ -0,0 +1,23 @@ +--- ../src-base/minecraft/net/minecraft/world/WorldType.java ++++ ../src-work/minecraft/net/minecraft/world/WorldType.java +@@ -19,6 +19,7 @@ + import net.minecraft.world.gen.layer.GenLayerZoom; + import cpw.mods.fml.relauncher.Side; + import cpw.mods.fml.relauncher.SideOnly; ++import net.minecraftforge.common.util.EnumHelper; // Cauldron + + public class WorldType + { +@@ -49,6 +50,12 @@ + this.canBeCreated = true; + this.worldTypeId = p_i1960_1_; + worldTypes[p_i1960_1_] = this; ++ // Cauldron start - add worldtype for bukkit if it does not already exist ++ if (org.bukkit.WorldType.getByName(p_i1960_2_) == null) ++ { ++ EnumHelper.addBukkitWorldType(p_i1960_2_); ++ } ++ // Cauldron end + } + + public String getWorldTypeName() diff --git a/patches/net/minecraft/world/biome/BiomeDecorator.java.patch b/patches/net/minecraft/world/biome/BiomeDecorator.java.patch new file mode 100644 index 0000000..43a53c9 --- /dev/null +++ b/patches/net/minecraft/world/biome/BiomeDecorator.java.patch @@ -0,0 +1,164 @@ +--- ../src-base/minecraft/net/minecraft/world/biome/BiomeDecorator.java ++++ ../src-work/minecraft/net/minecraft/world/biome/BiomeDecorator.java +@@ -24,6 +24,14 @@ + import net.minecraftforge.common.*; + import net.minecraftforge.event.terraingen.*; + ++// Spigot Start ++import java.util.ArrayList; ++import java.util.Iterator; ++import java.util.List; ++ ++import net.minecraft.world.chunk.Chunk; ++// Spigot End ++ + public class BiomeDecorator + { + public World currentWorld; +@@ -61,6 +69,7 @@ + public int clayPerChunk; + public int bigMushroomsPerChunk; + public boolean generateLakes; ++ private final List chunksToUnload = new ArrayList(); // Spigot + private static final String __OBFID = "CL_00000164"; + + public BiomeDecorator() +@@ -194,7 +203,7 @@ + { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; +- i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2); ++ i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot + WorldGenerator worldgenerator = p_150513_1_.getRandomWorldGenForGrass(this.randomGenerator); + worldgenerator.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } +@@ -204,7 +213,7 @@ + { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; +- i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2); ++ i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot + (new WorldGenDeadBush(Blocks.deadbush)).generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + +@@ -214,7 +223,7 @@ + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; + +- for (i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2); i1 > 0 && this.currentWorld.isAirBlock(k, i1 - 1, l); --i1) ++ for (i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); i1 > 0 && this.currentWorld.isAirBlock(k, i1 - 1, l); --i1) // Spigot + { + ; + } +@@ -229,7 +238,7 @@ + { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; +- i1 = this.currentWorld.getHeightValue(k, l); ++ i1 = this.getHighestBlockYAt(k, l); // Spigot + this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + +@@ -237,7 +246,7 @@ + { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; +- i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2); ++ i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot + this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + } +@@ -246,7 +255,7 @@ + { + j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; +- l = nextInt(this.currentWorld.getHeightValue(j, k) * 2); ++ l = nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot + this.mushroomBrownGen.generate(this.currentWorld, this.randomGenerator, j, l, k); + } + +@@ -254,7 +263,7 @@ + { + j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; +- l = nextInt(this.currentWorld.getHeightValue(j, k) * 2); ++ l = nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot + this.mushroomRedGen.generate(this.currentWorld, this.randomGenerator, j, l, k); + } + +@@ -263,7 +272,7 @@ + { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; +- i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2); ++ i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot + this.reedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + +@@ -271,7 +280,7 @@ + { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; +- i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2); ++ i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot + this.reedGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + +@@ -280,7 +289,7 @@ + { + j = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + k = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; +- l = nextInt(this.currentWorld.getHeightValue(j, k) * 2); ++ l = nextInt(this.getHighestBlockYAt(j, k) * 2); // Spigot + (new WorldGenPumpkin()).generate(this.currentWorld, this.randomGenerator, j, l, k); + } + +@@ -289,7 +298,7 @@ + { + k = this.chunk_X + this.randomGenerator.nextInt(16) + 8; + l = this.chunk_Z + this.randomGenerator.nextInt(16) + 8; +- i1 = nextInt(this.currentWorld.getHeightValue(k, l) * 2); ++ i1 = nextInt(this.getHighestBlockYAt(k, l) * 2); // Spigot + this.cactusGen.generate(this.currentWorld, this.randomGenerator, k, i1, l); + } + +@@ -313,6 +322,7 @@ + } + } + ++ this.unloadChunks(); // Spigot - unload chunks we force loaded + MinecraftForge.EVENT_BUS.post(new DecorateBiomeEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z)); + } + +@@ -360,6 +370,31 @@ + MinecraftForge.ORE_GEN_BUS.post(new OreGenEvent.Post(currentWorld, randomGenerator, chunk_X, chunk_Z)); + } + ++ // Spigot start - force load chunks ++ private int getHighestBlockYAt(int i, int j) ++ { ++ // Make sure the chunk is loaded ++ if (!this.currentWorld.chunkExists(i >> 4, j >> 4)) ++ { ++ // If not, load it, then add it to our unload list ++ this.chunksToUnload.add(this.currentWorld.getChunkFromChunkCoords(i >> 4, j >> 4)); ++ } ++ ++ return this.currentWorld.getHeightValue(i, j); ++ } ++ ++ private void unloadChunks() ++ { ++ Iterator iter = this.chunksToUnload.iterator(); ++ ++ while (iter.hasNext()) ++ { ++ this.currentWorld.getWorld().unloadChunk(iter.next().bukkitChunk); ++ iter.remove(); ++ } ++ } ++ // Spigot end ++ + private int nextInt(int i) { + if (i <= 1) + return 0; diff --git a/patches/net/minecraft/world/chunk/Chunk.java.patch b/patches/net/minecraft/world/chunk/Chunk.java.patch new file mode 100644 index 0000000..bc3a65f --- /dev/null +++ b/patches/net/minecraft/world/chunk/Chunk.java.patch @@ -0,0 +1,266 @@ +--- ../src-base/minecraft/net/minecraft/world/chunk/Chunk.java ++++ ../src-work/minecraft/net/minecraft/world/chunk/Chunk.java +@@ -36,6 +36,17 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import net.minecraft.block.BlockContainer; ++import org.bukkit.Bukkit; ++// CraftBukkit end ++// Spigot start ++import net.minecraft.entity.EntityLiving; ++import net.minecraft.entity.EnumCreatureType; ++import net.minecraft.entity.player.EntityPlayerMP; ++import net.minecraft.inventory.IInventory; ++// Spigot end ++ + public class Chunk + { + private static final Logger logger = LogManager.getLogger(); +@@ -62,6 +73,8 @@ + 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) ++ public int lastAccessedTick; // Cauldron track last time the chunk was accessed + private static final String __OBFID = "CL_00000373"; + + public Chunk(World p_i1995_1_, int p_i1995_2_, int p_i1995_3_) +@@ -80,13 +93,22 @@ + + for (int k = 0; k < this.entityLists.length; ++k) + { +- this.entityLists[k] = new ArrayList(); ++ this.entityLists[k] = new org.bukkit.craftbukkit.util.UnsafeList(); // CraftBukkit - ArrayList -> UnsafeList + } + + Arrays.fill(this.precipitationHeightMap, -999); + Arrays.fill(this.blockBiomeArray, (byte) - 1); ++ // CraftBukkit start ++ if (!(this instanceof EmptyChunk)) ++ { ++ this.bukkitChunk = new org.bukkit.craftbukkit.CraftChunk(this); ++ } + } + ++ public org.bukkit.Chunk bukkitChunk; ++ public boolean mustSave; ++ // CraftBukkit end ++ + 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_); +@@ -589,9 +611,10 @@ + + if (!this.worldObj.isRemote) + { ++ if (block1 == null) return false; // Cauldron + block1.onBlockPreDestroy(this.worldObj, l1, p_150807_2_, i2, k1); + } +- ++ // Cauldron - Removed CB patch that fixes BUKKIT-5238 to prevent stackoverflows. See issue #1165 and #1169 + 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,14 @@ + + if (i != this.xPosition || j != this.zPosition) + { +- logger.warn("Wrong location! " + p_76612_1_ + " (at " + i + ", " + j + " instead of " + this.xPosition + ", " + this.zPosition + ")"); +- Thread.dumpStack(); ++ // CraftBukkit start ++ Bukkit.getLogger().warning("Wrong location for " + p_76612_1_ + " in world '" + worldObj.getWorld().getName() + "'!"); ++ //logger.warn("Wrong location! " + p_76612_1_ + " (at " + i + ", " + j + " instead of " + this.xPosition + ", " + this.zPosition + ")"); ++ //Thread.dumpStack(); ++ Bukkit.getLogger().warning( ++ "Entity is at " + p_76612_1_.posX + "," + p_76612_1_.posZ + " (chunk " + i + "," + j + ") but was stored in chunk " + this.xPosition + "," ++ + this.zPosition); ++ // CraftBukkit end + } + + int k = MathHelper.floor_double(p_76612_1_.posY / 16.0D); +@@ -799,6 +828,26 @@ + p_76612_1_.chunkCoordY = k; + p_76612_1_.chunkCoordZ = this.zPosition; + this.entityLists[k].add(p_76612_1_); ++ // Spigot start - increment creature type count ++ // Keep this synced up with World.a(Class) ++ if (p_76612_1_ instanceof EntityLiving) ++ { ++ EntityLiving entityliving = (EntityLiving) p_76612_1_; ++ ++ if (entityliving.canDespawn_CB() && entityliving.isNoDespawnRequired()) ++ { ++ return; ++ } ++ } ++ ++ for (EnumCreatureType creatureType : EnumCreatureType.values()) ++ { ++ if (creatureType.getCreatureClass().isAssignableFrom(p_76612_1_.getClass())) ++ { ++ this.entityCount.adjustOrPutValue(creatureType.getCreatureClass(), 1, 1); ++ } ++ } ++ // Spigot end + } + + public void removeEntity(Entity p_76622_1_) +@@ -819,6 +868,26 @@ + } + + this.entityLists[p_76608_2_].remove(p_76608_1_); ++ // Spigot start - decrement creature type count ++ // Keep this synced up with World.a(Class) ++ if (p_76608_1_ instanceof EntityLiving) ++ { ++ EntityLiving entityliving = (EntityLiving) p_76608_1_; ++ ++ if (entityliving.canDespawn_CB() && entityliving.isNoDespawnRequired()) ++ { ++ return; ++ } ++ } ++ ++ for (EnumCreatureType creatureType : EnumCreatureType.values()) ++ { ++ if (creatureType.getCreatureClass().isAssignableFrom(p_76608_1_.getClass())) ++ { ++ this.entityCount.adjustValue(creatureType.getCreatureClass(), -1); ++ } ++ } ++ // Spigot end + } + + public boolean canBlockSeeTheSky(int p_76619_1_, int p_76619_2_, int p_76619_3_) +@@ -874,9 +943,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_; ++ // Cauldron start - validate TE for corrupted data ++ Block block = null; ++ try ++ { ++ block = this.getBlock(p_150812_1_, p_150812_2_, p_150812_3_); ++ } ++ catch (ArrayIndexOutOfBoundsException e) ++ { ++ System.out.println("ERROR: Detected corrupted TileEntity " + p_150812_4_ + " with bad extended block ID of " ++ + ((p_150812_2_ & 15) << 8 | p_150812_3_ << 4 | p_150812_1_) + " @ " + p_150812_4_.xCoord + ", " + p_150812_4_.yCoord + ", " ++ + p_150812_4_.zCoord + ". Removing TE to avoid crash..."); ++ p_150812_4_.invalidate(); ++ return; ++ } + + int metadata = getBlockMetadata(p_150812_1_, p_150812_2_, p_150812_3_); +- if (this.getBlock(p_150812_1_, p_150812_2_, p_150812_3_).hasTileEntity(metadata)) ++ if (block != null && block.hasTileEntity(metadata)) // Cauldron end + { + if (this.chunkTileEntityMap.containsKey(chunkposition)) + { +@@ -886,6 +969,16 @@ + p_150812_4_.validate(); + this.chunkTileEntityMap.put(chunkposition, p_150812_4_); + } ++ // CraftBukkit start ++ else if (net.minecraft.server.MinecraftServer.getServer().tileEntityConfig.enableTEPlaceWarning.getValue()) // Cauldron ++ { ++ System.out.println("Attempted to place a tile entity (" + p_150812_4_ + ") at " + p_150812_4_.xCoord + "," + p_150812_4_.yCoord + "," ++ + p_150812_4_.zCoord + " (" + org.bukkit.Material.getMaterial(Block.getIdFromBlock(getBlock(p_150812_1_, p_150812_2_, p_150812_3_))) ++ + ") where there was no entity tile!"); ++ System.out.println("Chunk coordinates: " + (this.xPosition * 16) + "," + (this.zPosition * 16)); ++ new Exception().printStackTrace(); ++ } ++ // CraftBukkit end + } + + public void removeTileEntity(int p_150805_1_, int p_150805_2_, int p_150805_3_) +@@ -936,6 +1029,21 @@ + + for (int i = 0; i < this.entityLists.length; ++i) + { ++ // CraftBukkit start ++ java.util.Iterator iter = this.entityLists[i].iterator(); ++ ++ while (iter.hasNext()) ++ { ++ Entity entity = (Entity) iter.next(); ++ ++ // Do not pass along players, as doing so can get them stuck outside of time. ++ // (which for example disables inventory icon updates and prevents block breaking) ++ if (entity instanceof EntityPlayerMP) ++ { ++ iter.remove(); ++ } ++ } ++ // CraftBukkit end + this.worldObj.unloadEntities(this.entityLists[i]); + } + MinecraftForge.EVENT_BUS.post(new ChunkEvent.Unload(this)); +@@ -1035,6 +1143,7 @@ + + public void populateChunk(IChunkProvider p_76624_1_, IChunkProvider p_76624_2_, int p_76624_3_, int p_76624_4_) + { ++ worldObj.timings.syncChunkLoadPostTimer.startTiming(); // Spigot + 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 +1163,7 @@ + { + p_76624_1_.populate(p_76624_2_, p_76624_3_ - 1, p_76624_4_ - 1); + } ++ worldObj.timings.syncChunkLoadPostTimer.stopTiming(); // Spigot + } + + public int getPrecipitationHeight(int p_76626_1_, int p_76626_2_) +@@ -1184,8 +1294,10 @@ + if ((p_76607_2_ & 1 << l) != 0 && this.storageArrays[l] != null) + { + nibblearray = this.storageArrays[l].getMetadataArray(); +- System.arraycopy(p_76607_1_, k, nibblearray.data, 0, nibblearray.data.length); +- k += nibblearray.data.length; ++ // Spigot start ++ System.arraycopy(p_76607_1_, k, nibblearray.getValueArray(), 0, nibblearray.getValueArray().length); ++ k += nibblearray.getValueArray().length; ++ // Spigot end + } + } + +@@ -1194,8 +1306,10 @@ + if ((p_76607_2_ & 1 << l) != 0 && this.storageArrays[l] != null) + { + nibblearray = this.storageArrays[l].getBlocklightArray(); +- System.arraycopy(p_76607_1_, k, nibblearray.data, 0, nibblearray.data.length); +- k += nibblearray.data.length; ++ // Spigot start ++ System.arraycopy(p_76607_1_, k, nibblearray.getValueArray(), 0, nibblearray.getValueArray().length); ++ k += nibblearray.getValueArray().length; ++ // Spigot end + } + } + +@@ -1206,8 +1320,10 @@ + if ((p_76607_2_ & 1 << l) != 0 && this.storageArrays[l] != null) + { + nibblearray = this.storageArrays[l].getSkylightArray(); +- System.arraycopy(p_76607_1_, k, nibblearray.data, 0, nibblearray.data.length); +- k += nibblearray.data.length; ++ // Spigot start ++ System.arraycopy(p_76607_1_, k, nibblearray.getValueArray(), 0, nibblearray.getValueArray().length); ++ k += nibblearray.getValueArray().length; ++ // Spigot end + } + } + } +@@ -1229,8 +1345,8 @@ + nibblearray = this.storageArrays[l].createBlockMSBArray(); + } + +- System.arraycopy(p_76607_1_, k, nibblearray.data, 0, nibblearray.data.length); +- k += nibblearray.data.length; ++ System.arraycopy(p_76607_1_, k, nibblearray.getValueArray(), 0, nibblearray.getValueArray().length); ++ k += nibblearray.getValueArray().length; + } + } + else if (p_76607_4_ && this.storageArrays[l] != null && this.storageArrays[l].getBlockMSBArray() != null) diff --git a/patches/net/minecraft/world/chunk/NibbleArray.java.patch b/patches/net/minecraft/world/chunk/NibbleArray.java.patch new file mode 100644 index 0000000..c1eef4e --- /dev/null +++ b/patches/net/minecraft/world/chunk/NibbleArray.java.patch @@ -0,0 +1,233 @@ +--- ../src-base/minecraft/net/minecraft/world/chunk/NibbleArray.java ++++ ../src-work/minecraft/net/minecraft/world/chunk/NibbleArray.java +@@ -1,47 +1,215 @@ + package net.minecraft.world.chunk; + ++import java.util.Arrays; // Spigot ++ + public class NibbleArray + { +- public final byte[] data; ++ public byte[] data; // Spigot - remove final // Cauldron - make public + private final int depthBits; + private final int depthBitsPlusFour; + private static final String __OBFID = "CL_00000371"; + +- public NibbleArray(int p_i1992_1_, int p_i1992_2_) ++ // Spigot start ++ private byte trivialValue; ++ private byte trivialByte; ++ private int length; ++ private static final int LEN2K = 2048; // Universal length used right now - optimize around this ++ private static final byte[][] TrivLen2k; ++ ++ static + { +- this.data = new byte[p_i1992_1_ >> 1]; +- this.depthBits = p_i1992_2_; +- this.depthBitsPlusFour = p_i1992_2_ + 4; ++ TrivLen2k = new byte[16][]; ++ ++ for (int i = 0; i < 16; i++) ++ { ++ TrivLen2k[i] = new byte[LEN2K]; ++ Arrays.fill(TrivLen2k[i], (byte)(i | (i << 4))); ++ } + } + +- public NibbleArray(byte[] p_i1993_1_, int p_i1993_2_) ++ // Try to convert array to trivial array ++ public void detectAndProcessTrivialArray() + { +- this.data = p_i1993_1_; +- this.depthBits = p_i1993_2_; +- this.depthBitsPlusFour = p_i1993_2_ + 4; ++ trivialValue = (byte)(data[0] & 0xF); ++ trivialByte = (byte)(trivialValue | (trivialValue << 4)); ++ ++ for (int i = 0; i < data.length; i++) ++ { ++ if (data[i] != trivialByte) ++ { ++ return; ++ } ++ } ++ ++ // All values matches, so array is trivial ++ this.length = data.length; ++ this.data = null; + } + +- public int get(int p_76582_1_, int p_76582_2_, int p_76582_3_) ++ // Force array to non-trivial state ++ public void forceToNonTrivialArray() + { +- int l = p_76582_2_ << this.depthBitsPlusFour | p_76582_3_ << this.depthBits | p_76582_1_; ++ if (this.data == null) ++ { ++ this.data = new byte[this.length]; ++ ++ if (this.trivialByte != 0) ++ { ++ Arrays.fill(this.data, this.trivialByte); ++ } ++ } ++ } ++ ++ // Test if array is in trivial state ++ public boolean isTrivialArray() ++ { ++ return (this.data == null); ++ } ++ ++ // Get value of all elements (only valid if array is in trivial state) ++ public int getTrivialArrayValue() ++ { ++ return this.trivialValue; ++ } ++ ++ // Get logical length of byte array for nibble data (whether trivial or non-trivial) ++ public int getByteLength() ++ { ++ if (this.data == null) ++ { ++ return this.length; ++ } ++ else ++ { ++ return this.data.length; ++ } ++ } ++ ++ // Return byte encoding of array (whether trivial or non-trivial) - returns read-only array if trivial (do not modify!) ++ public byte[] getValueArray() ++ { ++ if (this.data != null) ++ { ++ return this.data; ++ } ++ else ++ { ++ byte[] rslt; ++ ++ if (this.length == LEN2K) // All current uses are 2k long, but be safe ++ { ++ rslt = TrivLen2k[this.trivialValue]; ++ } ++ else ++ { ++ rslt = new byte[this.length]; ++ ++ if (this.trivialByte != 0) ++ { ++ Arrays.fill(rslt, this.trivialByte); ++ } ++ } ++ ++ return rslt; ++ } ++ } ++ ++ // Copy byte representation of array to given offset in given byte array ++ public int copyToByteArray(byte[] dest, int off) ++ { ++ if (this.data == null) ++ { ++ Arrays.fill(dest, off, off + this.length, this.trivialByte); ++ return off + this.length; ++ } ++ else ++ { ++ System.arraycopy(this.data, 0, dest, off, this.data.length); ++ return off + this.data.length; ++ } ++ } ++ ++ // Resize array to given byte length ++ public void resizeArray(int len) ++ { ++ if (this.data == null) ++ { ++ this.length = len; ++ } ++ else if (this.data.length != len) ++ { ++ byte[] newa = new byte[len]; ++ System.arraycopy(this.data, 0, newa, 0, ((this.data.length > len) ? len : this.data.length)); ++ this.data = newa; ++ } ++ } ++ // Spigot end ++ ++ public NibbleArray(int par1, int par2) ++ { ++ // Spigot start ++ //this.a = new byte[i >> 1]; ++ this.data = null; // Start off as trivial value (all same zero value) ++ this.length = par1 >> 1; ++ this.trivialByte = this.trivialValue = 0; ++ // Spigot end ++ this.depthBits = par2; ++ this.depthBitsPlusFour = par2 + 4; ++ } ++ ++ public NibbleArray(byte[] par1ArrayOfByte, int par2) ++ { ++ this.data = par1ArrayOfByte; ++ this.depthBits = par2; ++ this.depthBitsPlusFour = par2 + 4; ++ detectAndProcessTrivialArray(); // Spigot ++ } ++ ++ public int get(int par1, int par2, int par3) ++ { ++ if (this.data == null) ++ { ++ return this.trivialValue; // Spigot ++ } ++ ++ int l = par2 << this.depthBitsPlusFour | par3 << this.depthBits | par1; + int i1 = l >> 1; + int j1 = l & 1; + return j1 == 0 ? this.data[i1] & 15 : this.data[i1] >> 4 & 15; + } + +- public void set(int p_76581_1_, int p_76581_2_, int p_76581_3_, int p_76581_4_) ++ public void set(int par1, int par2, int par3, int par4) + { +- int i1 = p_76581_2_ << this.depthBitsPlusFour | p_76581_3_ << this.depthBits | p_76581_1_; ++ // Spigot start ++ if (this.data == null) ++ { ++ if (par4 != this.trivialValue) // Not same as trivial value, array no longer trivial ++ { ++ this.data = new byte[this.length]; ++ ++ if (this.trivialByte != 0) ++ { ++ Arrays.fill(this.data, this.trivialByte); ++ } ++ } ++ else ++ { ++ return; ++ } ++ } ++ ++ // Spigot end ++ int i1 = par2 << this.depthBitsPlusFour | par3 << this.depthBits | par1; + int j1 = i1 >> 1; + int k1 = i1 & 1; + + if (k1 == 0) + { +- this.data[j1] = (byte)(this.data[j1] & 240 | p_76581_4_ & 15); ++ this.data[j1] = (byte)(this.data[j1] & 240 | par4 & 15); + } + else + { +- this.data[j1] = (byte)(this.data[j1] & 15 | (p_76581_4_ & 15) << 4); ++ this.data[j1] = (byte)(this.data[j1] & 15 | (par4 & 15) << 4); + } + } + } diff --git a/patches/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch b/patches/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch new file mode 100644 index 0000000..202c464 --- /dev/null +++ b/patches/net/minecraft/world/chunk/storage/AnvilChunkLoader.java.patch @@ -0,0 +1,228 @@ +--- ../src-base/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java ++++ ../src-work/minecraft/net/minecraft/world/chunk/storage/AnvilChunkLoader.java +@@ -33,6 +33,13 @@ + import org.apache.logging.log4j.Logger; + + import cpw.mods.fml.common.FMLLog; ++// Cauldron start ++import java.util.Map; ++import net.minecraft.server.MinecraftServer; ++import net.minecraftforge.cauldron.CauldronUtils; ++import net.minecraftforge.common.util.EnumHelper; ++import cpw.mods.fml.common.asm.transformers.SideTransformer; ++// Cauldron end + + public class AnvilChunkLoader implements IChunkLoader, IThreadedFileIO + { +@@ -41,6 +48,7 @@ + private Set pendingAnvilChunksCoordinates = new HashSet(); + private Object syncLockObject = new Object(); + public final File chunkSaveLocation; ++ private List checkedTileEntities = new ArrayList(); // Cauldron + private static final String __OBFID = "CL_00000384"; + + public AnvilChunkLoader(File p_i2003_1_) +@@ -73,13 +81,16 @@ + + public Chunk loadChunk(World p_75815_1_, int p_75815_2_, int p_75815_3_) throws IOException + { ++ p_75815_1_.timings.syncChunkLoadDataTimer.startTiming(); // Spigot + Object[] data = this.loadChunk__Async(p_75815_1_, p_75815_2_, p_75815_3_); ++ p_75815_1_.timings.syncChunkLoadDataTimer.stopTiming(); // Spigot + + if (data != null) + { + Chunk chunk = (Chunk) data[0]; + NBTTagCompound nbttagcompound = (NBTTagCompound) data[1]; + this.loadEntities(p_75815_1_, nbttagcompound.getCompoundTag("Level"), chunk); ++ MinecraftForge.EVENT_BUS.post(new ChunkDataEvent.Load(chunk, nbttagcompound)); // Cauldron - Don't call ChunkDataEvent.Load async + return chunk; + } + +@@ -156,8 +167,8 @@ + if (!chunk.isAtLocation(p_75822_2_, p_75822_3_)) + { + logger.error("Chunk file at " + p_75822_2_ + "," + p_75822_3_ + " is in the wrong location; relocating. (Expected " + p_75822_2_ + ", " + p_75822_3_ + ", got " + chunk.xPosition + ", " + chunk.zPosition + ")"); +- p_75822_4_.setInteger("xPos", p_75822_2_); +- p_75822_4_.setInteger("zPos", p_75822_3_); ++ p_75822_4_.getCompoundTag("Level").setInteger("xPos", p_75822_2_); // CraftBukkit - .getCompound("Level") ++ p_75822_4_.getCompoundTag("Level").setInteger("zPos", p_75822_3_); // CraftBukkit - .getCompound("Level") + // Have to move tile entities since we don't load them at this stage + NBTTagList tileEntities = p_75822_4_.getCompoundTag("Level").getTagList("TileEntities", 10); + +@@ -187,8 +198,18 @@ + + public void saveChunk(World p_75816_1_, Chunk p_75816_2_) throws MinecraftException, IOException + { +- p_75816_1_.checkSessionLock(); ++ // CraftBukkit start - "handle" exception ++ try ++ { ++ p_75816_1_.checkSessionLock(); ++ } ++ catch (MinecraftException ex) ++ { ++ ex.printStackTrace(); ++ } + ++ // CraftBukkit end ++ + try + { + NBTTagCompound nbttagcompound = new NBTTagCompound(); +@@ -230,7 +251,7 @@ + + public boolean writeNextIO() + { +- AnvilChunkLoader.PendingChunk pendingchunk = null; ++ PendingChunk pendingchunktosave = null; + Object object = this.syncLockObject; + + synchronized (this.syncLockObject) +@@ -240,15 +261,15 @@ + return false; + } + +- pendingchunk = (AnvilChunkLoader.PendingChunk)this.chunksToRemove.remove(0); +- this.pendingAnvilChunksCoordinates.remove(pendingchunk.chunkCoordinate); ++ pendingchunktosave = (PendingChunk) this.chunksToRemove.remove(0); ++ this.pendingAnvilChunksCoordinates.remove(pendingchunktosave.chunkCoordinate); + } + +- if (pendingchunk != null) ++ if (pendingchunktosave != null) + { + try + { +- this.writeChunkNBTTags(pendingchunk); ++ this.writeChunkNBTTags(pendingchunktosave); + } + catch (Exception exception) + { +@@ -259,7 +280,7 @@ + return true; + } + +- private void writeChunkNBTTags(AnvilChunkLoader.PendingChunk p_75821_1_) throws IOException ++ public void writeChunkNBTTags(AnvilChunkLoader.PendingChunk p_75821_1_) throws java.io.IOException // CraftBukkit - public -> private, added throws + { + DataOutputStream dataoutputstream = RegionFileCache.getChunkOutputStream(this.chunkSaveLocation, p_75821_1_.chunkCoordinate.chunkXPos, p_75821_1_.chunkCoordinate.chunkZPos); + CompressedStreamTools.write(p_75821_1_.nbtTags, dataoutputstream); +@@ -307,19 +328,19 @@ + + if (extendedblockstorage.getBlockMSBArray() != null) + { +- nbttagcompound1.setByteArray("Add", extendedblockstorage.getBlockMSBArray().data); ++ nbttagcompound1.setByteArray("Add", extendedblockstorage.getBlockMSBArray().getValueArray()); // Spigot + } + +- nbttagcompound1.setByteArray("Data", extendedblockstorage.getMetadataArray().data); +- nbttagcompound1.setByteArray("BlockLight", extendedblockstorage.getBlocklightArray().data); ++ nbttagcompound1.setByteArray("Data", extendedblockstorage.getMetadataArray().getValueArray()); // Spigot ++ nbttagcompound1.setByteArray("BlockLight", extendedblockstorage.getBlocklightArray().getValueArray()); // Spigot + + if (flag) + { +- nbttagcompound1.setByteArray("SkyLight", extendedblockstorage.getSkylightArray().data); ++ nbttagcompound1.setByteArray("SkyLight", extendedblockstorage.getSkylightArray().getValueArray()); // Spigot + } + else + { +- nbttagcompound1.setByteArray("SkyLight", new byte[extendedblockstorage.getBlocklightArray().data.length]); ++ nbttagcompound1.setByteArray("SkyLight", new byte[extendedblockstorage.getBlocklightArray().getValueArray().length]); // Spigot + } + + nbttaglist.appendTag(nbttagcompound1); +@@ -455,6 +476,7 @@ + + public void loadEntities(World p_75823_1_, NBTTagCompound p_75823_2_, Chunk chunk) + { ++ p_75823_1_.timings.syncChunkLoadEntitiesTimer.startTiming(); // Spigot + NBTTagList nbttaglist1 = p_75823_2_.getTagList("Entities", 10); + + if (nbttaglist1 != null) +@@ -468,24 +490,31 @@ + if (entity2 != null) + { + chunk.addEntity(entity2); +- Entity entity = entity2; +- +- for (NBTTagCompound nbttagcompound2 = nbttagcompound3; nbttagcompound2.hasKey("Riding", 10); nbttagcompound2 = nbttagcompound2.getCompoundTag("Riding")) ++ // Cauldron start - check to see if we killed entity due to invalid location ++ if (!entity2.isDead) + { +- Entity entity1 = EntityList.createEntityFromNBT(nbttagcompound2.getCompoundTag("Riding"), p_75823_1_); ++ Entity entity = entity2; + +- if (entity1 != null) ++ for (NBTTagCompound nbttagcompound2 = nbttagcompound3; nbttagcompound2.hasKey("Riding", 10); nbttagcompound2 = nbttagcompound2.getCompoundTag("Riding")) + { +- chunk.addEntity(entity1); +- entity.mountEntity(entity1); +- } ++ Entity entity1 = EntityList.createEntityFromNBT(nbttagcompound2.getCompoundTag("Riding"), p_75823_1_); + +- entity = entity1; ++ if (entity1 != null) ++ { ++ chunk.addEntity(entity1); ++ entity.mountEntity(entity1); ++ } ++ ++ entity = entity1; ++ } + } ++ // Cauldron end + } + } + } + ++ p_75823_1_.timings.syncChunkLoadEntitiesTimer.stopTiming(); // Spigot ++ p_75823_1_.timings.syncChunkLoadTileEntitiesTimer.startTiming(); // Spigot + NBTTagList nbttaglist2 = p_75823_2_.getTagList("TileEntities", 10); + + if (nbttaglist2 != null) +@@ -497,11 +526,35 @@ + + if (tileentity != null) + { ++ // Cauldron start - check if TE should tick and inject into Bukkit's InventoryType ++ if (!this.checkedTileEntities.contains(tileentity.getClass())) ++ { ++ // verify if TE should tick ++ if (MinecraftServer.getServer().tileEntityConfig.preventInvalidTileEntityUpdates.getValue()) ++ { ++ SideTransformer.allowInvalidSide = true; ++ if (!CauldronUtils.isOverridingUpdateEntity(tileentity.getClass()) && CauldronUtils.canTileEntityUpdate(tileentity.getClass())) ++ { ++ if (MinecraftServer.getServer().tileEntityConfig.enableTECanUpdateWarning.getValue()) ++ { ++ MinecraftServer.getServer().logInfo("Detected TE " + tileentity.getClass().getName() + " with canUpdate set to true and no updateEntity override!. Please report to mod author as this can hurt performance."); ++ } ++ MinecraftServer.getServer().bannedTileEntityUpdates.add(tileentity.getClass()); ++ } ++ SideTransformer.allowInvalidSide = false; ++ } ++ // inject TE into InventoryType to support inventory events ++ EnumHelper.addInventoryType(tileentity); ++ this.checkedTileEntities.add(tileentity.getClass()); ++ } ++ // Cauldron end + chunk.addTileEntity(tileentity); + } + } + } + ++ p_75823_1_.timings.syncChunkLoadTileEntitiesTimer.stopTiming(); // Spigot ++ p_75823_1_.timings.syncChunkLoadTileTicksTimer.startTiming(); // Spigot + if (p_75823_2_.hasKey("TileTicks", 9)) + { + NBTTagList nbttaglist3 = p_75823_2_.getTagList("TileTicks", 10); +@@ -515,6 +568,7 @@ + } + } + } ++ p_75823_1_.timings.syncChunkLoadTileTicksTimer.stopTiming(); // Spigot + + // return chunk; + } diff --git a/patches/net/minecraft/world/chunk/storage/AnvilSaveHandler.java.patch b/patches/net/minecraft/world/chunk/storage/AnvilSaveHandler.java.patch new file mode 100644 index 0000000..816fb33 --- /dev/null +++ b/patches/net/minecraft/world/chunk/storage/AnvilSaveHandler.java.patch @@ -0,0 +1,25 @@ +--- ../src-base/minecraft/net/minecraft/world/chunk/storage/AnvilSaveHandler.java ++++ ../src-work/minecraft/net/minecraft/world/chunk/storage/AnvilSaveHandler.java +@@ -21,6 +21,11 @@ + public IChunkLoader getChunkLoader(WorldProvider p_75763_1_) + { + File file1 = this.getWorldDirectory(); ++ // Cauldron start ++ // To workaround the issue of Bukkit relying on every world having a seperate container ++ // we won't be generating a DIMXX folder for chunk loaders since this name is already generated ++ // for the world container with provider.getSaveFolder(). ++ /* + File file2; + + if (p_75763_1_.getSaveFolder() != null) +@@ -32,7 +37,9 @@ + else + { + return new AnvilChunkLoader(file1); +- } ++ } */ ++ return new AnvilChunkLoader(file1); ++ // Cauldron end + } + + public void saveWorldInfoWithPlayer(WorldInfo p_75755_1_, NBTTagCompound p_75755_2_) diff --git a/patches/net/minecraft/world/chunk/storage/ChunkLoader.java.patch b/patches/net/minecraft/world/chunk/storage/ChunkLoader.java.patch new file mode 100644 index 0000000..a2651a7 --- /dev/null +++ b/patches/net/minecraft/world/chunk/storage/ChunkLoader.java.patch @@ -0,0 +1,17 @@ +--- ../src-base/minecraft/net/minecraft/world/chunk/storage/ChunkLoader.java ++++ ../src-work/minecraft/net/minecraft/world/chunk/storage/ChunkLoader.java +@@ -113,9 +113,11 @@ + NBTTagCompound nbttagcompound1 = new NBTTagCompound(); + nbttagcompound1.setByte("Y", (byte)(j & 255)); + nbttagcompound1.setByteArray("Blocks", abyte1); +- nbttagcompound1.setByteArray("Data", nibblearray.data); +- nbttagcompound1.setByteArray("SkyLight", nibblearray1.data); +- nbttagcompound1.setByteArray("BlockLight", nibblearray2.data); ++ // Spigot start - data -> getValueArray() accessor ++ nbttagcompound1.setByteArray("Data", nibblearray.getValueArray()); ++ nbttagcompound1.setByteArray("SkyLight", nibblearray1.getValueArray()); ++ nbttagcompound1.setByteArray("BlockLight", nibblearray2.getValueArray()); ++ // Spigot end + nbttaglist.appendTag(nbttagcompound1); + } + } diff --git a/patches/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch b/patches/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch new file mode 100644 index 0000000..dffa033 --- /dev/null +++ b/patches/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java.patch @@ -0,0 +1,217 @@ +--- ../src-base/minecraft/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java ++++ ../src-work/minecraft/net/minecraft/world/chunk/storage/ExtendedBlockStorage.java +@@ -31,6 +31,29 @@ + } + } + ++ // CraftBukkit start ++ public ExtendedBlockStorage(int y, boolean flag, byte[] blkIds, byte[] extBlkIds) ++ { ++ this.yBase = y; ++ this.blockLSBArray = blkIds; ++ ++ if (extBlkIds != null) ++ { ++ this.blockMSBArray = new NibbleArray(extBlkIds, 4); ++ } ++ ++ this.blockMetadataArray = new NibbleArray(this.blockLSBArray.length, 4); ++ this.blocklightArray = new NibbleArray(this.blockLSBArray.length, 4); ++ ++ if (flag) ++ { ++ this.skylightArray = new NibbleArray(this.blockLSBArray.length, 4); ++ } ++ ++ this.removeInvalidBlocks(); ++ } ++ // CraftBukkit end ++ + public Block getBlockByExtId(int p_150819_1_, int p_150819_2_, int p_150819_3_) + { + int l = this.blockLSBArray[p_150819_2_ << 8 | p_150819_3_ << 4 | p_150819_1_] & 255; +@@ -139,6 +162,106 @@ + + public void removeInvalidBlocks() + { ++ // CraftBukkit start - Optimize for speed ++ byte[] blkIds = this.blockLSBArray; ++ int cntNonEmpty = 0; ++ int cntTicking = 0; ++ ++ if (this.blockMSBArray == null) // No extended block IDs? Don't waste time messing with them ++ { ++ for (int off = 0; off < blkIds.length; off++) ++ { ++ int l = blkIds[off] & 0xFF; ++ ++ if (l > 0) ++ { ++ if (Block.getBlockById(l) == null) ++ { ++ blkIds[off] = 0; ++ } ++ else ++ { ++ ++cntNonEmpty; ++ ++ if (Block.getBlockById(l).getTickRandomly()) ++ { ++ ++cntTicking; ++ } ++ } ++ } ++ } ++ } ++ else ++ { ++ this.blockMSBArray.forceToNonTrivialArray(); // Spigot ++ byte[] ext = this.blockMSBArray.getValueArray(); ++ ++ for (int off = 0, off2 = 0; off < blkIds.length;) ++ { ++ byte extid = ext[off2]; ++ int l = (blkIds[off] & 0xFF) | ((extid & 0xF) << 8); // Even data ++ ++ if (l > 0) ++ { ++ if (Block.getBlockById(l) == null) ++ { ++ blkIds[off] = 0; ++ ext[off2] &= 0xF0; ++ } ++ else ++ { ++ ++cntNonEmpty; ++ ++ if (Block.getBlockById(l).getTickRandomly()) ++ { ++ ++cntTicking; ++ } ++ } ++ } ++ ++ off++; ++ l = (blkIds[off] & 0xFF) | ((extid & 0xF0) << 4); // Odd data ++ ++ if (l > 0) ++ { ++ if (Block.getBlockById(l) == null) ++ { ++ blkIds[off] = 0; ++ ext[off2] &= 0x0F; ++ } ++ else ++ { ++ ++cntNonEmpty; ++ ++ if (Block.getBlockById(l).getTickRandomly()) ++ { ++ ++cntTicking; ++ } ++ } ++ } ++ ++ off++; ++ off2++; ++ } ++ ++ // Spigot start ++ this.blockMSBArray.detectAndProcessTrivialArray(); ++ ++ if (this.blockMSBArray.isTrivialArray() && (this.blockMSBArray.getTrivialArrayValue() == 0)) ++ { ++ this.blockMSBArray = null; ++ } ++ ++ // Spigot end ++ } ++ ++ this.blockRefCount = cntNonEmpty; ++ this.tickRefCount = cntTicking; ++ } ++ ++ public void old_recalcBlockCounts() ++ { ++ // CraftBukkit end + this.blockRefCount = 0; + this.tickRefCount = 0; + +@@ -197,29 +320,72 @@ + + public void setBlockLSBArray(byte[] p_76664_1_) + { +- this.blockLSBArray = p_76664_1_; ++ this.blockLSBArray = this.validateByteArray(p_76664_1_); // CraftBukkit - Validate data + } + + public void setBlockMSBArray(NibbleArray p_76673_1_) + { +- this.blockMSBArray = p_76673_1_; ++ // CraftBukkit start - Don't hang on to an empty nibble array ++ boolean empty = true; ++ ++ // Spigot start ++ if ((!p_76673_1_.isTrivialArray()) || (p_76673_1_.getTrivialArrayValue() != 0)) ++ { ++ empty = false; ++ } ++ ++ // Spigot end ++ ++ if (empty) ++ { ++ return; ++ } ++ ++ // CraftBukkit end ++ this.blockMSBArray = this.validateNibbleArray(p_76673_1_); // CraftBukkit - Validate data + } + + public void setBlockMetadataArray(NibbleArray p_76668_1_) + { +- this.blockMetadataArray = p_76668_1_; ++ this.blockMetadataArray = this.validateNibbleArray(p_76668_1_); // CraftBukkit - Validate data + } + + public void setBlocklightArray(NibbleArray p_76659_1_) + { +- this.blocklightArray = p_76659_1_; ++ this.blocklightArray = this.validateNibbleArray(p_76659_1_); // CraftBukkit - Validate data + } + + public void setSkylightArray(NibbleArray p_76666_1_) + { +- this.skylightArray = p_76666_1_; ++ this.skylightArray = this.validateNibbleArray(p_76666_1_); // CraftBukkit - Validate data + } + ++ // CraftBukkit start - Validate array lengths ++ private NibbleArray validateNibbleArray(NibbleArray nibbleArray) ++ { ++ // Spigot start - fix for more awesome nibble arrays ++ if (nibbleArray != null && nibbleArray.getByteLength() < 2048) ++ { ++ nibbleArray.resizeArray(2048); ++ } ++ ++ // Spigot end ++ return nibbleArray; ++ } ++ ++ private byte[] validateByteArray(byte[] byteArray) ++ { ++ if (byteArray != null && byteArray.length < 4096) ++ { ++ byte[] newArray = new byte[4096]; ++ System.arraycopy(byteArray, 0, newArray, 0, byteArray.length); ++ byteArray = newArray; ++ } ++ ++ return byteArray; ++ } ++ // CraftBukkit end ++ + @SideOnly(Side.CLIENT) + public NibbleArray createBlockMSBArray() + { diff --git a/patches/net/minecraft/world/chunk/storage/RegionFileCache.java.patch b/patches/net/minecraft/world/chunk/storage/RegionFileCache.java.patch new file mode 100644 index 0000000..5c19476 --- /dev/null +++ b/patches/net/minecraft/world/chunk/storage/RegionFileCache.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraft/world/chunk/storage/RegionFileCache.java ++++ ../src-work/minecraft/net/minecraft/world/chunk/storage/RegionFileCache.java +@@ -10,7 +10,7 @@ + + public class RegionFileCache + { +- private static final Map regionsByFilename = new HashMap(); ++ public static final Map regionsByFilename = new HashMap(); // CraftBukkit - private -> public + private static final String __OBFID = "CL_00000383"; + + public static synchronized RegionFile createOrLoadRegionFile(File p_76550_0_, int p_76550_1_, int p_76550_2_) diff --git a/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch b/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch new file mode 100644 index 0000000..38d8ec9 --- /dev/null +++ b/patches/net/minecraft/world/gen/ChunkProviderServer.java.patch @@ -0,0 +1,465 @@ +--- ../src-base/minecraft/net/minecraft/world/gen/ChunkProviderServer.java ++++ ../src-work/minecraft/net/minecraft/world/gen/ChunkProviderServer.java +@@ -32,23 +32,40 @@ + + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; ++// CraftBukkit start ++import java.util.Random; ++import net.minecraft.block.BlockSand; ++import org.bukkit.Server; ++import org.bukkit.craftbukkit.util.LongHash; ++import org.bukkit.craftbukkit.util.LongHashSet; ++import org.bukkit.craftbukkit.util.LongObjectHashMap; ++import org.bukkit.event.world.ChunkUnloadEvent; ++// CraftBukkit end ++// Cauldron start ++import cpw.mods.fml.common.FMLCommonHandler; ++import net.minecraft.server.MinecraftServer; ++import net.minecraftforge.cauldron.configuration.CauldronConfig; ++import net.minecraftforge.cauldron.CauldronHooks; ++// Cauldron end + + public class ChunkProviderServer implements IChunkProvider + { + private static final Logger logger = LogManager.getLogger(); +- private Set chunksToUnload = Collections.newSetFromMap(new ConcurrentHashMap()); +- private Chunk defaultEmptyChunk; ++ public LongHashSet chunksToUnload = new LongHashSet(); // LongHashSet ++ public Chunk defaultEmptyChunk; + public IChunkProvider currentChunkProvider; + public IChunkLoader currentChunkLoader; +- public boolean loadChunkOnProvideRequest = true; +- public LongHashMap loadedChunkHashMap = new LongHashMap(); +- public List loadedChunks = new ArrayList(); ++ public boolean loadChunkOnProvideRequest = MinecraftServer.getServer().cauldronConfig.loadChunkOnRequest.getValue(); // Cauldron - if true, allows mods to force load chunks. to disable, set load-chunk-on-request in cauldron.yml to false ++ public int initialTick; // Cauldron counter to keep track of when this loader was created ++ public LongObjectHashMap loadedChunkHashMap = new LongObjectHashMap(); ++ public List loadedChunks = new ArrayList(); // Cauldron - vanilla compatibility + public WorldServer worldObj; + private Set loadingChunks = com.google.common.collect.Sets.newHashSet(); + private static final String __OBFID = "CL_00001436"; + + public ChunkProviderServer(WorldServer p_i1520_1_, IChunkLoader p_i1520_2_, IChunkProvider p_i1520_3_) + { ++ this.initialTick = MinecraftServer.currentTick; // Cauldron keep track of when the loader was created + this.defaultEmptyChunk = new EmptyChunk(p_i1520_1_, 0, 0); + this.worldObj = p_i1520_1_; + this.currentChunkLoader = p_i1520_2_; +@@ -57,10 +74,10 @@ + + public boolean chunkExists(int p_73149_1_, int p_73149_2_) + { +- return this.loadedChunkHashMap.containsItem(ChunkCoordIntPair.chunkXZ2Int(p_73149_1_, p_73149_2_)); ++ return this.loadedChunkHashMap.containsKey(LongHash.toLong(p_73149_1_, p_73149_2_)); // CraftBukkit + } + +- public List func_152380_a() ++ public List func_152380_a() // Vanilla compatibility + { + return this.loadedChunks; + } +@@ -74,20 +91,39 @@ + int l = p_73241_2_ * 16 + 8 - chunkcoordinates.posZ; + short short1 = 128; + ++ // CraftBukkit start + if (k < -short1 || k > short1 || l < -short1 || l > short1) + { +- this.chunksToUnload.add(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(p_73241_1_, p_73241_2_))); ++ this.chunksToUnload.add(p_73241_1_, p_73241_2_); ++ Chunk c = this.loadedChunkHashMap.get(LongHash.toLong(p_73241_1_, p_73241_2_)); ++ ++ if (c != null) ++ { ++ c.mustSave = true; ++ } ++ CauldronHooks.logChunkUnload(this, p_73241_1_, p_73241_2_, "Chunk added to unload queue"); + } ++ ++ // CraftBukkit end + } + else + { +- this.chunksToUnload.add(Long.valueOf(ChunkCoordIntPair.chunkXZ2Int(p_73241_1_, p_73241_2_))); ++ // CraftBukkit start ++ this.chunksToUnload.add(p_73241_1_, p_73241_2_); ++ Chunk c = this.loadedChunkHashMap.get(LongHash.toLong(p_73241_1_, p_73241_2_)); ++ ++ if (c != null) ++ { ++ c.mustSave = true; ++ } ++ CauldronHooks.logChunkUnload(this, p_73241_1_, p_73241_2_, "Chunk added to unload queue"); ++ // CraftBukkit end + } + } + + public void unloadAllChunks() + { +- Iterator iterator = this.loadedChunks.iterator(); ++ Iterator iterator = this.loadedChunkHashMap.values().iterator(); // CraftBukkit + + while (iterator.hasNext()) + { +@@ -103,9 +139,9 @@ + + public Chunk loadChunk(int par1, int par2, Runnable runnable) + { +- long k = ChunkCoordIntPair.chunkXZ2Int(par1, par2); +- this.chunksToUnload.remove(Long.valueOf(k)); +- Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(k); ++ this.chunksToUnload.remove(par1, par2); ++ Chunk chunk = (Chunk) this.loadedChunkHashMap.get(LongHash.toLong(par1, par2)); ++ boolean newChunk = false; + AnvilChunkLoader loader = null; + + if (this.currentChunkLoader instanceof AnvilChunkLoader) +@@ -113,6 +149,8 @@ + loader = (AnvilChunkLoader) this.currentChunkLoader; + } + ++ CauldronHooks.logChunkLoad(this, "Get", par1, par2, true); ++ + // We can only use the queue for already generated chunks + if (chunk == null && loader != null && loader.chunkExists(this.worldObj, par1, par2)) + { +@@ -142,18 +180,19 @@ + + public Chunk originalLoadChunk(int p_73158_1_, int p_73158_2_) + { +- long k = ChunkCoordIntPair.chunkXZ2Int(p_73158_1_, p_73158_2_); +- this.chunksToUnload.remove(Long.valueOf(k)); +- Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(k); ++ this.chunksToUnload.remove(p_73158_1_, p_73158_2_); ++ Chunk chunk = (Chunk) this.loadedChunkHashMap.get(LongHash.toLong(p_73158_1_, p_73158_2_)); ++ boolean newChunk = false; // CraftBukkit + + if (chunk == null) + { +- boolean added = loadingChunks.add(k); ++ worldObj.timings.syncChunkLoadTimer.startTiming(); // Spigot ++ boolean added = loadingChunks.add(LongHash.toLong(p_73158_1_, p_73158_2_)); + if (!added) + { + cpw.mods.fml.common.FMLLog.bigWarning("There is an attempt to load a chunk (%d,%d) in dimension %d that is already being loaded. This will cause weird chunk breakages.", p_73158_1_, p_73158_2_, worldObj.provider.dimensionId); + } +- chunk = ForgeChunkManager.fetchDormantChunk(k, this.worldObj); ++ chunk = ForgeChunkManager.fetchDormantChunk(LongHash.toLong(p_73158_1_, p_73158_2_), this.worldObj); + if (chunk == null) + { + chunk = this.safeLoadChunk(p_73158_1_, p_73158_2_); +@@ -176,18 +215,39 @@ + 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_)})); +- crashreportcategory.addCrashSection("Position hash", Long.valueOf(k)); ++ crashreportcategory.addCrashSection("Position hash", LongHash.toLong(p_73158_1_, p_73158_2_)); + crashreportcategory.addCrashSection("Generator", this.currentChunkProvider.makeString()); + throw new ReportedException(crashreport); + } + } ++ ++ newChunk = true; // CraftBukkit + } + +- this.loadedChunkHashMap.add(k, chunk); +- this.loadedChunks.add(chunk); +- loadingChunks.remove(k); +- chunk.onChunkLoad(); ++ this.loadedChunkHashMap.put(LongHash.toLong(p_73158_1_, p_73158_2_), chunk); // CraftBukkit ++ this.loadedChunks.add(chunk); // Cauldron - vanilla compatibility ++ loadingChunks.remove(LongHash.toLong(p_73158_1_, p_73158_2_)); // Cauldron - LongHash ++ ++ if (chunk != null) ++ { ++ chunk.onChunkLoad(); ++ } ++ // CraftBukkit start ++ Server server = this.worldObj.getServer(); ++ ++ if (server != null) ++ { ++ /* ++ * If it's a new world, the first few chunks are generated inside ++ * the World constructor. We can't reliably alter that, so we have ++ * no way of creating a CraftWorld/CraftServer at that point. ++ */ ++ server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(chunk.bukkitChunk, newChunk)); ++ } ++ ++ // CraftBukkit end + chunk.populateChunk(this, this, p_73158_1_, p_73158_2_); ++ worldObj.timings.syncChunkLoadTimer.stopTiming(); // Spigot + } + + return chunk; +@@ -195,11 +255,29 @@ + + public Chunk provideChunk(int p_73154_1_, int p_73154_2_) + { +- Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(ChunkCoordIntPair.chunkXZ2Int(p_73154_1_, p_73154_2_)); +- return chunk == null ? (!this.worldObj.findingSpawnPoint && !this.loadChunkOnProvideRequest ? this.defaultEmptyChunk : this.loadChunk(p_73154_1_, p_73154_2_)) : chunk; ++ // CraftBukkit start ++ Chunk chunk = (Chunk) this.loadedChunkHashMap.get(LongHash.toLong(p_73154_1_, p_73154_2_)); ++ chunk = chunk == null ? (shouldLoadChunk() ? this.loadChunk(p_73154_1_, p_73154_2_) : this.defaultEmptyChunk) : chunk; // Cauldron handle forge server tick events and load the chunk within 5 seconds of the world being loaded (for chunk loaders) ++ ++ if (chunk == this.defaultEmptyChunk) ++ { ++ return chunk; ++ } ++ ++ if (p_73154_1_ != chunk.xPosition || p_73154_2_ != chunk.zPosition) ++ { ++ logger.error("Chunk (" + chunk.xPosition + ", " + chunk.zPosition + ") stored at (" + p_73154_1_ + ", " + p_73154_2_ + ") in world '" + worldObj.getWorld().getName() + "'"); ++ logger.error(chunk.getClass().getName()); ++ Throwable ex = new Throwable(); ++ ex.fillInStackTrace(); ++ ex.printStackTrace(); ++ } ++ chunk.lastAccessedTick = MinecraftServer.getServer().getTickCounter(); // Cauldron ++ return chunk; ++ // CraftBukkit end + } + +- private Chunk safeLoadChunk(int p_73239_1_, int p_73239_2_) ++ public Chunk safeLoadChunk(int p_73239_1_, int p_73239_2_) // CraftBukkit - private -> public + { + if (this.currentChunkLoader == null) + { +@@ -209,6 +287,7 @@ + { + try + { ++ CauldronHooks.logChunkLoad(this, "Safe Load", p_73239_1_, p_73239_2_, false); // Cauldron + Chunk chunk = this.currentChunkLoader.loadChunk(this.worldObj, p_73239_1_, p_73239_2_); + + if (chunk != null) +@@ -217,8 +296,11 @@ + + if (this.currentChunkProvider != null) + { ++ worldObj.timings.syncChunkLoadStructuresTimer.startTiming(); // Spigot + this.currentChunkProvider.recreateStructures(p_73239_1_, p_73239_2_); ++ worldObj.timings.syncChunkLoadStructuresTimer.stopTiming(); // Spigot + } ++ chunk.lastAccessedTick = MinecraftServer.getServer().getTickCounter(); // Cauldron + } + + return chunk; +@@ -231,7 +313,7 @@ + } + } + +- private void safeSaveExtraChunkData(Chunk p_73243_1_) ++ public void safeSaveExtraChunkData(Chunk p_73243_1_) // CraftBukkit - private -> public + { + if (this.currentChunkLoader != null) + { +@@ -246,7 +328,7 @@ + } + } + +- private void safeSaveChunk(Chunk p_73242_1_) ++ public void safeSaveChunk(Chunk p_73242_1_) // CraftBukkit - private -> public + { + if (this.currentChunkLoader != null) + { +@@ -254,15 +336,18 @@ + { + p_73242_1_.lastSaveTime = this.worldObj.getTotalWorldTime(); + this.currentChunkLoader.saveChunk(this.worldObj, p_73242_1_); ++ // CraftBukkit start - IOException to Exception + } +- catch (IOException ioexception) ++ catch (Exception ioexception) + { + logger.error("Couldn\'t save chunk", ioexception); + } ++ /* Remove extra exception + catch (MinecraftException minecraftexception) + { + logger.error("Couldn\'t save chunk; already in use by another instance of Minecraft?", minecraftexception); + } ++ // CraftBukkit end */ + } + } + +@@ -277,6 +362,35 @@ + if (this.currentChunkProvider != null) + { + this.currentChunkProvider.populate(p_73153_1_, p_73153_2_, p_73153_3_); ++ // CraftBukkit start ++ BlockSand.fallInstantly = true; ++ Random random = new Random(); ++ random.setSeed(worldObj.getSeed()); ++ long xRand = random.nextLong() / 2L * 2L + 1L; ++ long zRand = random.nextLong() / 2L * 2L + 1L; ++ random.setSeed((long) p_73153_2_ * xRand + (long) p_73153_3_ * zRand ^ worldObj.getSeed()); ++ org.bukkit.World world = this.worldObj.getWorld(); ++ ++ if (world != null) ++ { ++ this.worldObj.populating = true; ++ ++ try ++ { ++ for (org.bukkit.generator.BlockPopulator populator : world.getPopulators()) ++ { ++ populator.populate(world, random, chunk.bukkitChunk); ++ } ++ } ++ finally ++ { ++ this.worldObj.populating = false; ++ } ++ } ++ ++ BlockSand.fallInstantly = false; ++ this.worldObj.getServer().getPluginManager().callEvent(new org.bukkit.event.world.ChunkPopulateEvent(chunk.bukkitChunk)); ++ // CraftBukkit end + GameRegistry.generateWorld(p_73153_2_, p_73153_3_, worldObj, currentChunkProvider, p_73153_1_); + chunk.setChunkModified(); + } +@@ -286,11 +400,13 @@ + public boolean saveChunks(boolean p_73151_1_, IProgressUpdate p_73151_2_) + { + int i = 0; +- ArrayList arraylist = Lists.newArrayList(this.loadedChunks); ++ // Cauldron start - use thread-safe method for iterating loaded chunks ++ Object[] chunks = this.loadedChunks.toArray(); + +- for (int j = 0; j < arraylist.size(); ++j) ++ for (int j = 0; j < chunks.length; ++j) + { +- Chunk chunk = (Chunk)arraylist.get(j); ++ Chunk chunk = (Chunk)chunks[j]; ++ //Cauldron end + + if (p_73151_1_) + { +@@ -325,36 +441,60 @@ + { + if (!this.worldObj.levelSaving) + { +- for (ChunkCoordIntPair forced : this.worldObj.getPersistentChunks().keySet()) ++ // Cauldron start - remove any chunk that has a ticket associated with it ++ if (!this.chunksToUnload.isEmpty()) + { +- this.chunksToUnload.remove(ChunkCoordIntPair.chunkXZ2Int(forced.chunkXPos, forced.chunkZPos)); ++ for (ChunkCoordIntPair forcedChunk : this.worldObj.getPersistentChunks().keys()) ++ { ++ this.chunksToUnload.remove(forcedChunk.chunkXPos, forcedChunk.chunkZPos); ++ } + } ++ // Cauldron end ++ // CraftBukkit start ++ Server server = this.worldObj.getServer(); + +- for (int i = 0; i < 100; ++i) ++ for (int i = 0; i < 100 && !this.chunksToUnload.isEmpty(); i++) + { +- if (!this.chunksToUnload.isEmpty()) ++ long chunkcoordinates = this.chunksToUnload.popFirst(); ++ Chunk chunk = this.loadedChunkHashMap.get(chunkcoordinates); ++ ++ if (chunk == null) + { +- Long olong = (Long)this.chunksToUnload.iterator().next(); +- Chunk chunk = (Chunk)this.loadedChunkHashMap.getValueByKey(olong.longValue()); ++ continue; ++ } + +- if (chunk != null) +- { +- chunk.onChunkUnload(); +- this.safeSaveChunk(chunk); +- this.safeSaveExtraChunkData(chunk); +- this.loadedChunks.remove(chunk); +- ForgeChunkManager.putDormantChunk(ChunkCoordIntPair.chunkXZ2Int(chunk.xPosition, chunk.zPosition), chunk); +- 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) ++ { ++ 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); ++ ++ if (!event.isCancelled()) ++ { ++ CauldronHooks.logChunkUnload(this, chunk.xPosition, chunk.zPosition, "Unloading Chunk at"); ++ ++ chunk.onChunkUnload(); ++ this.safeSaveChunk(chunk); ++ this.safeSaveExtraChunkData(chunk); ++ // this.unloadQueue.remove(olong); ++ this.loadedChunkHashMap.remove(chunkcoordinates); // CraftBukkit ++ this.loadedChunks.remove(chunk); // Cauldron - vanilla compatibility ++ ForgeChunkManager.putDormantChunk(chunkcoordinates, chunk); ++ if(this.loadedChunkHashMap.size() == 0 && ForgeChunkManager.getPersistentChunksFor(this.worldObj).size() == 0 && !DimensionManager.shouldLoadSpawn(this.worldObj.provider.dimensionId)){ ++ DimensionManager.unloadWorld(this.worldObj.provider.dimensionId); ++ return currentChunkProvider.unloadQueuedChunks(); ++ } + } + } + ++ // CraftBukkit end ++ + if (this.currentChunkLoader != null) + { + this.currentChunkLoader.chunkTick(); +@@ -371,7 +511,8 @@ + + public String makeString() + { +- return "ServerChunkCache: " + this.loadedChunkHashMap.getNumHashElements() + " Drop: " + this.chunksToUnload.size(); ++ // CraftBukkit - this.chunks.count() -> .values().size() ++ return "ServerChunkCache: " + this.loadedChunkHashMap.values().size() + " Drop: " + this.chunksToUnload.size(); + } + + public List getPossibleCreatures(EnumCreatureType p_73155_1_, int p_73155_2_, int p_73155_3_, int p_73155_4_) +@@ -386,8 +527,32 @@ + + public int getLoadedChunkCount() + { +- return this.loadedChunkHashMap.getNumHashElements(); ++ // CraftBukkit - this.chunks.count() -> .values().size() ++ return this.loadedChunkHashMap.values().size(); + } + + public void recreateStructures(int p_82695_1_, int p_82695_2_) {} ++ ++ // Cauldron start ++ private boolean shouldLoadChunk() ++ { ++ return this.worldObj.findingSpawnPoint || ++ this.loadChunkOnProvideRequest || ++ (MinecraftServer.callingForgeTick && MinecraftServer.getServer().cauldronConfig.loadChunkOnForgeTick.getValue()) || ++ (MinecraftServer.currentTick - initialTick <= 100); ++ } ++ ++ public long lastAccessed(int x, int z) ++ { ++ long chunkHash = LongHash.toLong(x, z); ++ if (!loadedChunkHashMap.containsKey(chunkHash)) return 0; ++ return loadedChunkHashMap.get(chunkHash).lastAccessedTick; ++ } ++ ++ /*private boolean shouldUnloadChunk(Chunk chunk) ++ { ++ if (chunk == null) return false; ++ return MinecraftServer.getServer().getTickCounter() - chunk.lastAccessedTick > CauldronConfig.chunkGCGracePeriod.getValue(); ++ }*/ ++ // Cauldron end + } diff --git a/patches/net/minecraft/world/gen/feature/WorldGenShrub.java.patch b/patches/net/minecraft/world/gen/feature/WorldGenShrub.java.patch new file mode 100644 index 0000000..fda3ae8 --- /dev/null +++ b/patches/net/minecraft/world/gen/feature/WorldGenShrub.java.patch @@ -0,0 +1,16 @@ +--- ../src-base/minecraft/net/minecraft/world/gen/feature/WorldGenShrub.java ++++ ../src-work/minecraft/net/minecraft/world/gen/feature/WorldGenShrub.java +@@ -62,7 +62,13 @@ + } + } + } ++ // CraftBukkit start - Return false if gen was unsuccessful ++ } ++ else ++ { ++ return false; + } ++ // CraftBukkit end + + return true; + } diff --git a/patches/net/minecraft/world/gen/structure/MapGenStronghold.java.patch b/patches/net/minecraft/world/gen/structure/MapGenStronghold.java.patch new file mode 100644 index 0000000..57d8893 --- /dev/null +++ b/patches/net/minecraft/world/gen/structure/MapGenStronghold.java.patch @@ -0,0 +1,21 @@ +--- ../src-base/minecraft/net/minecraft/world/gen/structure/MapGenStronghold.java ++++ ../src-work/minecraft/net/minecraft/world/gen/structure/MapGenStronghold.java +@@ -92,7 +92,17 @@ + double d1 = (1.25D * (double)l + random.nextDouble()) * this.field_82671_h * (double)l; + int j1 = (int)Math.round(Math.cos(d0) * d1); + int k1 = (int)Math.round(Math.sin(d0) * d1); +- ChunkPosition chunkposition = this.worldObj.getWorldChunkManager().findBiomePosition((j1 << 4) + 8, (k1 << 4) + 8, 112, this.field_151546_e, random); ++ // Cauldron start - catch invalid positions ++ ChunkPosition chunkposition = null; ++ try ++ { ++ chunkposition = this.worldObj.getWorldChunkManager().findBiomePosition((j1 << 4) + 8, (k1 << 4) + 8, 112, this.field_151546_e, random); ++ } ++ catch (ArrayIndexOutOfBoundsException e) ++ { ++ // ignore ++ } ++ // Cauldron end + + if (chunkposition != null) + { diff --git a/patches/net/minecraft/world/gen/structure/MapGenStructure.java.patch b/patches/net/minecraft/world/gen/structure/MapGenStructure.java.patch new file mode 100644 index 0000000..1fc1fa0 --- /dev/null +++ b/patches/net/minecraft/world/gen/structure/MapGenStructure.java.patch @@ -0,0 +1,21 @@ +--- ../src-base/minecraft/net/minecraft/world/gen/structure/MapGenStructure.java ++++ ../src-work/minecraft/net/minecraft/world/gen/structure/MapGenStructure.java +@@ -239,8 +239,17 @@ + { + if (this.field_143029_e == null) + { +- this.field_143029_e = (MapGenStructureData)p_143027_1_.perWorldStorage.loadData(MapGenStructureData.class, this.func_143025_a()); ++ // Spigot Start ++ if (p_143027_1_.getSpigotConfig().saveStructureInfo && !this.func_143025_a().equals("Mineshaft")) // Cauldron ++ { ++ this.field_143029_e = (MapGenStructureData) p_143027_1_.loadItemData(MapGenStructureData.class, this.func_143025_a()); ++ } ++ else ++ { ++ this.field_143029_e = new MapGenStructureData(this.func_143025_a()); ++ } + ++ // Spigot End + if (this.field_143029_e == null) + { + this.field_143029_e = new MapGenStructureData(this.func_143025_a()); diff --git a/patches/net/minecraft/world/gen/structure/StructureStart.java.patch b/patches/net/minecraft/world/gen/structure/StructureStart.java.patch new file mode 100644 index 0000000..80d2af6 --- /dev/null +++ b/patches/net/minecraft/world/gen/structure/StructureStart.java.patch @@ -0,0 +1,12 @@ +--- ../src-base/minecraft/net/minecraft/world/gen/structure/StructureStart.java ++++ ../src-work/minecraft/net/minecraft/world/gen/structure/StructureStart.java +@@ -41,7 +41,8 @@ + { + StructureComponent structurecomponent = (StructureComponent)iterator.next(); + +- if (structurecomponent.getBoundingBox().intersectsWith(p_75068_3_) && !structurecomponent.addComponentParts(p_75068_1_, p_75068_2_, p_75068_3_)) ++ // Cauldron - validate structurecomponent ++ if ((structurecomponent == null || structurecomponent.getBoundingBox() == null) || (structurecomponent.getBoundingBox().intersectsWith(p_75068_3_) && !structurecomponent.addComponentParts(p_75068_1_, p_75068_2_, p_75068_3_))) + { + iterator.remove(); + } diff --git a/patches/net/minecraft/world/storage/ISaveHandler.java.patch b/patches/net/minecraft/world/storage/ISaveHandler.java.patch new file mode 100644 index 0000000..c0d8b88 --- /dev/null +++ b/patches/net/minecraft/world/storage/ISaveHandler.java.patch @@ -0,0 +1,9 @@ +--- ../src-base/minecraft/net/minecraft/world/storage/ISaveHandler.java ++++ ../src-work/minecraft/net/minecraft/world/storage/ISaveHandler.java +@@ -27,4 +27,6 @@ + File getMapFileFromName(String p_75758_1_); + + String getWorldDirectoryName(); ++ ++ java.util.UUID getUUID(); // CraftBukkit + } diff --git a/patches/net/minecraft/world/storage/MapData.java.patch b/patches/net/minecraft/world/storage/MapData.java.patch new file mode 100644 index 0000000..fb5fc73 --- /dev/null +++ b/patches/net/minecraft/world/storage/MapData.java.patch @@ -0,0 +1,116 @@ +--- ../src-base/minecraft/net/minecraft/world/storage/MapData.java ++++ ../src-work/minecraft/net/minecraft/world/storage/MapData.java +@@ -14,6 +14,14 @@ + import net.minecraft.world.World; + import net.minecraft.world.WorldSavedData; + ++// CraftBukkit start ++import java.util.UUID; ++ ++import org.bukkit.craftbukkit.CraftServer; ++import org.bukkit.craftbukkit.CraftWorld; ++import org.bukkit.craftbukkit.map.CraftMapView; ++// CraftBukkit end ++ + 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(); ++ ++ // CraftBukkit start ++ public final CraftMapView mapView; ++ private CraftServer server; ++ private UUID uniqueId = null; ++ // CraftBukkit end + private static final String __OBFID = "CL_00000577"; + + public MapData(String p_i2140_1_) + { + super(p_i2140_1_); ++ // CraftBukkit start ++ mapView = new CraftMapView(this); ++ server = (CraftServer) org.bukkit.Bukkit.getServer(); ++ // CraftBukkit end + } + + public void readFromNBT(NBTTagCompound p_76184_1_) +@@ -107,7 +125,7 @@ + { + if (!this.playersHashMap.containsKey(p_76191_1_)) + { +- MapData.MapInfo mapinfo = new MapData.MapInfo(p_76191_1_); ++ MapData.MapInfo mapinfo = new MapData.MapInfo(this, p_76191_1_); // Cauldron + this.playersHashMap.put(p_76191_1_, mapinfo); + this.playersArrayList.add(mapinfo); + } +@@ -265,7 +283,7 @@ + + if (mapinfo == null) + { +- mapinfo = new MapData.MapInfo(p_82568_1_); ++ mapinfo = new MapData.MapInfo(this, p_82568_1_); // Cauldron + this.playersHashMap.put(p_82568_1_, mapinfo); + this.playersArrayList.add(mapinfo); + } +@@ -300,10 +318,12 @@ + private byte[] lastPlayerLocationOnMap; + public int field_82569_d; + private boolean field_82570_i; ++ final MapData mapDataObj; // Cauldron + private static final String __OBFID = "CL_00000578"; + +- public MapInfo(EntityPlayer p_i2138_2_) ++ public MapInfo(MapData mapData, EntityPlayer p_i2138_2_) + { ++ this.mapDataObj = mapData; // Cauldron + this.entityplayerObj = p_i2138_2_; + + for (int i = 0; i < this.field_76209_b.length; ++i) +@@ -328,20 +348,37 @@ + int i; + int i1; + ++ // Spigot start ++ boolean custom = this.mapDataObj.mapView.renderers.size() > 1 || !(this.mapDataObj.mapView.renderers.get(0) instanceof org.bukkit.craftbukkit.map.CraftMapRenderer); ++ org.bukkit.craftbukkit.map.RenderData render = (custom) ? this.mapDataObj.mapView.render((org.bukkit.craftbukkit.entity.CraftPlayer) entityplayerObj.getBukkitEntity()) : null; // CraftBukkit ++ + if (--this.ticksUntilPlayerLocationMapUpdate < 0) + { + this.ticksUntilPlayerLocationMapUpdate = 4; +- abyte = new byte[MapData.this.playersVisibleOnMap.size() * 3 + 1]; ++ abyte = new byte[((custom) ? render.cursors.size() : this.mapDataObj.playersVisibleOnMap.size()) * 3 + 1]; // CraftBukkit + abyte[0] = 1; + i = 0; +- +- for (Iterator iterator = MapData.this.playersVisibleOnMap.values().iterator(); iterator.hasNext(); ++i) ++ ++ // CraftBukkit start ++ ++ // Spigot start ++ for (Iterator iterator = ((custom) ? render.cursors.iterator() : this.mapDataObj.playersVisibleOnMap.values().iterator()); iterator.hasNext(); ++i) + { +- MapData.MapCoord mapcoord = (MapData.MapCoord)iterator.next(); +- abyte[i * 3 + 1] = (byte)(mapcoord.iconSize << 4 | mapcoord.iconRotation & 15); +- abyte[i * 3 + 2] = mapcoord.centerX; +- abyte[i * 3 + 3] = mapcoord.centerZ; ++ org.bukkit.map.MapCursor cursor = (custom) ? (org.bukkit.map.MapCursor) iterator.next() : null; ++ ++ if (cursor != null && !cursor.isVisible()) ++ { ++ continue; ++ } ++ ++ MapCoord deco = (custom) ? null : (MapCoord) iterator.next(); ++ abyte[i * 3 + 1] = (byte)(((custom) ? cursor.getRawType() : deco.iconSize) << 4 | ((custom) ? cursor.getDirection() : deco.iconRotation) & 15); ++ abyte[i * 3 + 2] = (byte)((custom) ? cursor.getX() : deco.centerX); ++ abyte[i * 3 + 3] = (byte)((custom) ? cursor.getY() : deco.centerZ); + } ++ ++ // Spigot end ++ // CraftBukkit end + + boolean flag = !p_76204_1_.isOnItemFrame(); + diff --git a/patches/net/minecraft/world/storage/SaveHandler.java.patch b/patches/net/minecraft/world/storage/SaveHandler.java.patch new file mode 100644 index 0000000..51ec1a6 --- /dev/null +++ b/patches/net/minecraft/world/storage/SaveHandler.java.patch @@ -0,0 +1,233 @@ +--- ../src-base/minecraft/net/minecraft/world/storage/SaveHandler.java ++++ ../src-work/minecraft/net/minecraft/world/storage/SaveHandler.java +@@ -10,6 +10,7 @@ + import cpw.mods.fml.common.FMLCommonHandler; + import cpw.mods.fml.common.StartupQuery; + import net.minecraft.entity.player.EntityPlayer; ++import net.minecraft.entity.player.EntityPlayerMP; + import net.minecraft.nbt.CompressedStreamTools; + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.server.MinecraftServer; +@@ -19,6 +20,13 @@ + import org.apache.logging.log4j.LogManager; + import org.apache.logging.log4j.Logger; + ++// CraftBukkit start ++import java.util.UUID; ++ ++import org.bukkit.craftbukkit.entity.CraftPlayer; ++// CraftBukkit end ++import cpw.mods.fml.common.registry.GameData; // Cauldron ++ + public class SaveHandler implements ISaveHandler, IPlayerFileData + { + private static final Logger logger = LogManager.getLogger(); +@@ -27,6 +35,8 @@ + private final File mapDataDir; + private final long initializationTime = MinecraftServer.getSystemTimeMillis(); + private final String saveDirectoryName; ++ private UUID uuid = null; // CraftBukkit ++ private static boolean initializedBukkit = false; // Cauldron + private static final String __OBFID = "CL_00000585"; + + public SaveHandler(File p_i2146_1_, String p_i2146_2_, boolean p_i2146_3_) +@@ -65,7 +75,7 @@ + catch (IOException ioexception) + { + ioexception.printStackTrace(); +- throw new RuntimeException("Failed to check session lock, aborting"); ++ throw new RuntimeException("Failed to check session lock for world " + this.worldDirectory + ", aborting"); // Cauldron + } + } + +@@ -85,7 +95,7 @@ + { + if (datainputstream.readLong() != this.initializationTime) + { +- throw new MinecraftException("The save is being accessed from another location, aborting"); ++ throw new MinecraftException("The save folder for world " + this.worldDirectory + " is being accessed from another location, aborting"); // Cauldron + } + } + finally +@@ -95,7 +105,10 @@ + } + catch (IOException ioexception) + { +- throw new MinecraftException("Failed to check session lock, aborting"); ++ // Cauldron start ++ ioexception.printStackTrace(); ++ throw new MinecraftException("Failed to check session lock for world " + this.worldDirectory + ", aborting"); ++ // Cauldron end + } + } + +@@ -120,6 +133,7 @@ + nbttagcompound1 = nbttagcompound.getCompoundTag("Data"); + worldInfo = new WorldInfo(nbttagcompound1); + FMLCommonHandler.instance().handleWorldDataLoad(this, worldInfo, nbttagcompound); ++ this.initBukkitData(worldInfo); // Cauldron + return worldInfo; + } + catch (StartupQuery.AbortedException e) +@@ -143,6 +157,7 @@ + nbttagcompound1 = nbttagcompound.getCompoundTag("Data"); + worldInfo = new WorldInfo(nbttagcompound1); + FMLCommonHandler.instance().handleWorldDataLoad(this, worldInfo, nbttagcompound); ++ this.initBukkitData(worldInfo); // Cauldron + return worldInfo; + } + catch (StartupQuery.AbortedException e) +@@ -154,7 +169,7 @@ + exception.printStackTrace(); + } + } +- ++ this.initBukkitData(worldInfo); // Cauldron + return null; + } + +@@ -282,6 +297,18 @@ + + if (nbttagcompound != null) + { ++ // CraftBukkit start ++ if (p_75752_1_ instanceof EntityPlayerMP) ++ { ++ CraftPlayer player = (CraftPlayer) p_75752_1_.getBukkitEntity(); // Cauldron ++ // Only update first played if it is older than the one we have ++ long modified = new File(playersDirectory, p_75752_1_.getCommandSenderName() + ".dat").lastModified(); ++ if (modified < player.getFirstPlayed()) { ++ player.setFirstPlayed(modified); ++ } ++ } ++ // CraftBukkit end ++ + p_75752_1_.readFromNBT(nbttagcompound); + } + +@@ -289,6 +316,27 @@ + return nbttagcompound; + } + ++ // CraftBukkit start ++ public NBTTagCompound getPlayerData(String par1Str) ++ { ++ try ++ { ++ File file1 = new File(this.playersDirectory, par1Str + ".dat"); ++ ++ if (file1.exists()) ++ { ++ return CompressedStreamTools.readCompressed(new FileInputStream(file1)); ++ } ++ } ++ catch (Exception exception) ++ { ++ logger.warn("Failed to load player data for " + par1Str); ++ } ++ ++ return null; ++ } ++ // CraftBukkit end ++ + public IPlayerFileData getSaveHandler() + { + return this; +@@ -320,4 +368,97 @@ + { + return this.saveDirectoryName; + } ++ ++ // CraftBukkit start ++ public UUID getUUID() ++ { ++ if (uuid != null) ++ { ++ return uuid; ++ } ++ ++ File file1 = new File(this.worldDirectory, "uid.dat"); ++ ++ if (file1.exists()) ++ { ++ DataInputStream dis = null; ++ ++ try ++ { ++ dis = new DataInputStream(new FileInputStream(file1)); ++ return uuid = new UUID(dis.readLong(), dis.readLong()); ++ } ++ catch (IOException ex) ++ { ++ logger.warn("Failed to read " + file1 + ", generating new random UUID", ex); ++ } ++ finally ++ { ++ if (dis != null) ++ { ++ try ++ { ++ dis.close(); ++ } ++ catch (IOException ex) ++ { ++ // NOOP ++ } ++ } ++ } ++ } ++ ++ uuid = UUID.randomUUID(); ++ DataOutputStream dos = null; ++ ++ try ++ { ++ dos = new DataOutputStream(new FileOutputStream(file1)); ++ dos.writeLong(uuid.getMostSignificantBits()); ++ dos.writeLong(uuid.getLeastSignificantBits()); ++ } ++ catch (IOException ex) ++ { ++ logger.warn("Failed to write " + file1, ex); ++ } ++ finally ++ { ++ if (dos != null) ++ { ++ try ++ { ++ dos.close(); ++ } ++ catch (IOException ex) ++ { ++ // NOOP ++ } ++ } ++ } ++ ++ return uuid; ++ } ++ ++ public File getPlayerDir() ++ { ++ return playersDirectory; ++ } ++ // CraftBukkit end ++ ++ // Cauldron start ++ public void initBukkitData(WorldInfo worldInfo) ++ { ++ // inject bukkit materials before plugins load ++ if (!this.initializedBukkit && (worldInfo == null || worldInfo.getDimension() == 0)) ++ { ++ GameData.injectBlockBukkitMaterials(); ++ GameData.injectItemBukkitMaterials(); ++ // since we modify bukkit enums, we need to guarantee that plugins are ++ // loaded after all mods have been loaded by FML to avoid race conditions. ++ MinecraftServer.getServer().server.loadPlugins(); ++ MinecraftServer.getServer().server.enablePlugins(org.bukkit.plugin.PluginLoadOrder.STARTUP); ++ this.initializedBukkit = true; ++ } ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraft/world/storage/SaveHandlerMP.java.patch b/patches/net/minecraft/world/storage/SaveHandlerMP.java.patch new file mode 100644 index 0000000..65e5baa --- /dev/null +++ b/patches/net/minecraft/world/storage/SaveHandlerMP.java.patch @@ -0,0 +1,24 @@ +--- ../src-base/minecraft/net/minecraft/world/storage/SaveHandlerMP.java ++++ ../src-work/minecraft/net/minecraft/world/storage/SaveHandlerMP.java +@@ -3,6 +3,8 @@ + import cpw.mods.fml.relauncher.Side; + import cpw.mods.fml.relauncher.SideOnly; + import java.io.File; ++import java.util.UUID; ++ + import net.minecraft.nbt.NBTTagCompound; + import net.minecraft.world.MinecraftException; + import net.minecraft.world.WorldProvider; +@@ -50,4 +52,12 @@ + { + return null; + } ++ ++ // Cauldron start ++ @Override ++ public UUID getUUID() ++ { ++ return this.getUUID(); ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraft/world/storage/WorldInfo.java.patch b/patches/net/minecraft/world/storage/WorldInfo.java.patch new file mode 100644 index 0000000..1db2bc9 --- /dev/null +++ b/patches/net/minecraft/world/storage/WorldInfo.java.patch @@ -0,0 +1,48 @@ +--- ../src-base/minecraft/net/minecraft/world/storage/WorldInfo.java ++++ ../src-work/minecraft/net/minecraft/world/storage/WorldInfo.java +@@ -117,6 +117,7 @@ + this.thunderTime = p_i2157_1_.getInteger("thunderTime"); + this.thundering = p_i2157_1_.getBoolean("thundering"); + this.hardcore = p_i2157_1_.getBoolean("hardcore"); ++ this.dimension = p_i2157_1_.getInteger("dimension"); // Cauldron + + if (p_i2157_1_.hasKey("initialized", 99)) + { +@@ -193,6 +194,7 @@ + this.allowCommands = p_i2159_1_.allowCommands; + this.initialized = p_i2159_1_.initialized; + this.theGameRules = p_i2159_1_.theGameRules; ++ this.dimension = p_i2159_1_.dimension; // Cauldron + } + + public NBTTagCompound getNBTTagCompound() +@@ -234,6 +236,7 @@ + p_76064_1_.setBoolean("allowCommands", this.allowCommands); + p_76064_1_.setBoolean("initialized", this.initialized); + p_76064_1_.setTag("GameRules", this.theGameRules.writeGameRulesToNBT()); ++ p_76064_1_.setInteger("dimension", this.dimension); // Cauldron + + if (p_76064_2_ != null) + { +@@ -282,6 +285,21 @@ + return this.playerTag; + } + ++ // Cauldron start ++ /** ++ * Sets the Dimension. ++ */ ++ public void setDimension(int dim) ++ { ++ this.dimension = dim; ++ } ++ ++ public int getDimension() ++ { ++ return this.dimension; ++ } ++ // Cauldron end ++ + public int getVanillaDimension() + { + return this.dimension; diff --git a/patches/net/minecraftforge/common/DimensionManager.java.patch b/patches/net/minecraftforge/common/DimensionManager.java.patch new file mode 100644 index 0000000..d1b9601 --- /dev/null +++ b/patches/net/minecraftforge/common/DimensionManager.java.patch @@ -0,0 +1,376 @@ +--- ../src-base/minecraft/net/minecraftforge/common/DimensionManager.java ++++ ../src-work/minecraft/net/minecraftforge/common/DimensionManager.java +@@ -34,6 +34,15 @@ + import net.minecraft.world.storage.ISaveHandler; + import net.minecraft.world.storage.SaveHandler; + import net.minecraftforge.event.world.WorldEvent; ++// Cauldron start ++import net.minecraft.server.dedicated.DedicatedServer; ++import net.minecraft.world.chunk.storage.AnvilSaveHandler; ++import net.minecraftforge.cauldron.CauldronUtils; ++import net.minecraftforge.common.util.EnumHelper; ++import org.bukkit.World.Environment; ++import org.bukkit.WorldCreator; ++import org.bukkit.generator.ChunkGenerator; ++// Cauldron end + + public class DimensionManager + { +@@ -46,6 +55,11 @@ + private static BitSet dimensionMap = new BitSet(Long.SIZE << 4); + private static ConcurrentMap weakWorldMap = new MapMaker().weakKeys().weakValues().makeMap(); + private static Multiset leakedWorlds = HashMultiset.create(); ++ // Cauldron start ++ private static Hashtable, Integer> classToProviders = new Hashtable, Integer>(); ++ private static ArrayList bukkitDims = new ArrayList(); // used to keep track of Bukkit dimensions ++ private static final String FILE_SEPARATOR = System.getProperty("file.separator"); ++ // Cauldron end + + public static boolean registerProviderType(int id, Class provider, boolean keepLoaded) + { +@@ -53,7 +67,23 @@ + { + return false; + } ++ // Cauldron start - register provider with bukkit and add appropriate config option ++ String worldType = "unknown"; ++ if (id != -1 && id != 0 && id != 1) // ignore vanilla ++ { ++ worldType = provider.getSimpleName().toLowerCase(); ++ worldType = worldType.replace("worldprovider", ""); ++ worldType = worldType.replace("provider", ""); ++ registerBukkitEnvironment(id, worldType); ++ } ++ else ++ { ++ worldType = Environment.getEnvironment(id).name().toLowerCase(); ++ } ++ keepLoaded = MinecraftServer.getServer().cauldronConfig.getBoolean("world-environment-settings." + worldType + ".keep-world-loaded", keepLoaded); ++ // Cauldron end + providers.put(id, provider); ++ classToProviders.put(provider, id); + spawnSettings.put(id, keepLoaded); + return true; + } +@@ -157,28 +187,33 @@ + + public static Integer[] getIDs(boolean check) + { +- if (check) ++ // Cauldron start - check config option and only log world leak messages if enabled ++ if (MinecraftServer.getServer().cauldronConfig.worldLeakDebug.getValue()) + { +- List allWorlds = Lists.newArrayList(weakWorldMap.keySet()); +- allWorlds.removeAll(worlds.values()); +- for (ListIterator li = allWorlds.listIterator(); li.hasNext(); ) ++ if (check) + { +- World w = li.next(); +- leakedWorlds.add(System.identityHashCode(w)); +- } +- for (World w : allWorlds) +- { +- int leakCount = leakedWorlds.count(System.identityHashCode(w)); +- if (leakCount == 5) ++ List allWorlds = Lists.newArrayList(weakWorldMap.keySet()); ++ allWorlds.removeAll(worlds.values()); ++ for (ListIterator li = allWorlds.listIterator(); li.hasNext(); ) + { +- FMLLog.fine("The world %x (%s) may have leaked: first encounter (5 occurences).\n", System.identityHashCode(w), w.getWorldInfo().getWorldName()); ++ World w = li.next(); ++ leakedWorlds.add(System.identityHashCode(w)); + } +- else if (leakCount % 5 == 0) ++ for (World w : allWorlds) + { +- FMLLog.fine("The world %x (%s) may have leaked: seen %d times.\n", System.identityHashCode(w), w.getWorldInfo().getWorldName(), leakCount); ++ int leakCount = leakedWorlds.count(System.identityHashCode(w)); ++ if (leakCount == 5) ++ { ++ FMLLog.fine("The world %x (%s) may have leaked: first encounter (5 occurences). Note: This may be a caused by a mod, plugin, or just a false-positive(No memory leak). If server crashes due to OOM, report to Cauldron.\n", System.identityHashCode(w), w.getWorldInfo().getWorldName()); ++ } ++ else if (leakCount % 5 == 0) ++ { ++ FMLLog.fine("The world %x (%s) may have leaked: seen %d times. Note: This may be a caused by a mod, plugin, or just a false-positive(No memory leak). If server crashes due to OOM, report to Cauldron.\n", System.identityHashCode(w), w.getWorldInfo().getWorldName(), leakCount); ++ } + } + } + } ++ // Cauldron end + return getIDs(); + } + public static Integer[] getIDs() +@@ -191,12 +226,23 @@ + if (world != null) + { + worlds.put(id, world); +- weakWorldMap.put(world, world); ++ // Cauldron start - check config option and only log world leak messages if enabled ++ if (MinecraftServer.getServer().cauldronConfig.worldLeakDebug.getValue()) ++ { ++ weakWorldMap.put(world, world); ++ } ++ // handle all world adds here for Bukkit ++ if (!MinecraftServer.getServer().worlds.contains(world)) ++ { ++ MinecraftServer.getServer().worlds.add(world); ++ } ++ // Cauldron end + MinecraftServer.getServer().worldTickTimes.put(id, new long[100]); + FMLLog.info("Loading dimension %d (%s) (%s)", id, world.getWorldInfo().getWorldName(), world.func_73046_m()); + } + else + { ++ MinecraftServer.getServer().worlds.remove(getWorld(id)); // Cauldron - remove world from our new world arraylist + worlds.remove(id); + MinecraftServer.getServer().worldTickTimes.remove(id); + FMLLog.info("Unloading dimension %d", id); +@@ -224,6 +270,7 @@ + } + + public static void initDimension(int dim) { ++ if (dim == 0) return; // Cauldron - overworld + WorldServer overworld = getWorld(0); + if (overworld == null) + { +@@ -231,6 +278,12 @@ + } + try + { ++ // Cauldron start - Fixes MultiVerse issue when mods such as Twilight Forest try to hotload their dimension when using its WorldProvider ++ if(net.minecraftforge.cauldron.CauldronHooks.craftWorldLoading) ++ { ++ return; ++ } ++ // Cauldron end + DimensionManager.getProviderType(dim); + } + catch (Exception e) +@@ -242,9 +295,52 @@ + ISaveHandler savehandler = overworld.getSaveHandler(); + WorldSettings worldSettings = new WorldSettings(overworld.getWorldInfo()); + +- WorldServer world = (dim == 0 ? overworld : new WorldServerMulti(mcServer, savehandler, overworld.getWorldInfo().getWorldName(), dim, worldSettings, overworld, mcServer.theProfiler)); ++ // Cauldron start - handles hotloading dimensions ++ String worldType; ++ String name; ++ String oldName = ""; ++ Environment env = Environment.getEnvironment(getProviderType(dim)); ++ if (dim >= -1 && dim <= 1) ++ { ++ if ((dim == -1 && !mcServer.getAllowNether()) || (dim == 1 && !mcServer.server.getAllowEnd())) ++ return; ++ worldType = env.toString().toLowerCase(); ++ name = "DIM" + dim; ++ } ++ else ++ { ++ WorldProvider provider = WorldProvider.getProviderForDimension(dim); ++ worldType = provider.getClass().getSimpleName().toLowerCase(); ++ worldType = worldType.replace("worldprovider", ""); ++ oldName = "world_" + worldType; ++ worldType = worldType.replace("provider", ""); ++ ++ if (Environment.getEnvironment(DimensionManager.getProviderType(dim)) == null) ++ env = DimensionManager.registerBukkitEnvironment(DimensionManager.getProviderType(provider.getClass()), worldType); ++ ++ name = provider.getSaveFolder(); ++ if (name == null) name = "DIM0"; ++ } ++ // add ability to disable dimensions ++ if (!MinecraftServer.getServer().cauldronConfig.getBoolean("world-environment-settings." + worldType + ".enabled", true)) ++ return; ++ ++ CauldronUtils.migrateWorlds(worldType, oldName, overworld.getWorldInfo().getWorldName(), name); // Cauldron ++ ChunkGenerator gen = mcServer.server.getGenerator(name); ++ if (mcServer instanceof DedicatedServer) { ++ worldSettings.func_82750_a(((DedicatedServer) mcServer).getStringProperty("generator-settings", "")); ++ } ++ WorldServer world = new WorldServerMulti(mcServer, new AnvilSaveHandler(mcServer.server.getWorldContainer(), name, true), name, dim, worldSettings, overworld, mcServer.theProfiler, env, gen); ++ ++ if (gen != null) ++ { ++ world.getWorld().getPopulators().addAll(gen.getDefaultPopulators(world.getWorld())); ++ } ++ mcServer.getConfigurationManager().setPlayerManager(mcServer.worlds.toArray(new WorldServer[mcServer.worlds.size()])); + world.addWorldAccess(new WorldManager(mcServer, world)); + MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(world)); ++ mcServer.server.getPluginManager().callEvent(new org.bukkit.event.world.WorldLoadEvent(world.getWorld())); ++ // Cauldron end + if (!mcServer.isSinglePlayer()) + { + world.getWorldInfo().setGameType(mcServer.getGameType()); +@@ -253,6 +349,79 @@ + mcServer.func_147139_a(mcServer.func_147135_j()); + } + ++ // Cauldron start - new method for handling creation of Bukkit dimensions. Currently supports MultiVerse ++ public static WorldServer initDimension(WorldCreator creator, WorldSettings worldSettings) { ++ WorldServer overworld = getWorld(0); ++ if (overworld == null) { ++ throw new RuntimeException("Cannot Hotload Dim: Overworld is not Loaded!"); ++ } ++ ++ MinecraftServer mcServer = overworld.func_73046_m(); ++ ++ String worldType; ++ String name; ++ ++ int providerId = 0; ++ if (creator.environment() != null) ++ providerId = creator.environment().getId(); ++ try { ++ providerId = getProviderType(providerId); ++ } ++ catch (IllegalArgumentException e) ++ { ++ // do nothing ++ } ++ ++ Environment env = creator.environment(); ++ worldType = env.name().toLowerCase(); ++ name = creator.name(); ++ int dim = 0; ++ // Use saved dimension from level.dat if it exists. This guarantees that after a world is created, the same dimension will be used. Fixes issues with MultiVerse ++ AnvilSaveHandler saveHandler = new AnvilSaveHandler(mcServer.server.getWorldContainer(), name, true); ++ if (saveHandler.loadWorldInfo() != null) ++ { ++ int savedDim = saveHandler.loadWorldInfo().getDimension(); ++ if (savedDim != 0 && savedDim != -1 && savedDim != 1) ++ { ++ dim = savedDim; ++ } ++ } ++ if (dim == 0) ++ { ++ dim = getNextFreeDimId(); ++ } ++ ++ if (!isDimensionRegistered(dim)) // handle reloads properly ++ { ++ registerDimension(dim, providerId); ++ addBukkitDimension(dim); ++ } ++ ChunkGenerator gen = creator.generator(); ++ if (mcServer instanceof DedicatedServer) { ++ worldSettings.func_82750_a(((DedicatedServer) mcServer).getStringProperty("generator-settings", "")); ++ } ++ ++ WorldServer world = new WorldServerMulti(mcServer, saveHandler, name, dim, worldSettings, overworld, mcServer.theProfiler, env, gen); ++ ++ if (gen != null) ++ { ++ world.getWorld().getPopulators().addAll(gen.getDefaultPopulators(world.getWorld())); ++ } ++ world.provider.dimensionId = dim; // Fix for TerrainControl injecting their own WorldProvider ++ mcServer.getConfigurationManager().setPlayerManager(mcServer.worlds.toArray(new WorldServer[mcServer.worlds.size()])); ++ ++ world.addWorldAccess(new WorldManager(mcServer, world)); ++ MinecraftForge.EVENT_BUS.post(new WorldEvent.Load(world)); ++ if (!mcServer.isSinglePlayer()) ++ { ++ world.getWorldInfo().setGameType(mcServer.getGameType()); ++ } ++ mcServer.func_147139_a(mcServer.func_147135_j()); ++ ++ return world; ++ } ++ // Cauldron end ++ + public static WorldServer getWorld(int id) + { + return worlds.get(id); +@@ -266,7 +435,7 @@ + public static boolean shouldLoadSpawn(int dim) + { + int id = getProviderType(dim); +- return spawnSettings.containsKey(id) && spawnSettings.get(id); ++ return ((spawnSettings.containsKey(id) && spawnSettings.get(id)) || (getWorld(dim) != null && getWorld(dim).keepSpawnInMemory)); // Cauldron added bukkit check + } + + static +@@ -306,7 +475,8 @@ + } + + public static void unloadWorld(int id) { +- unloadQueue.add(id); ++ if (!shouldLoadSpawn(id)) // Cauldron - prevent mods from force unloading if we have it disabled ++ unloadQueue.add(id); + } + + /* +@@ -315,26 +485,9 @@ + public static void unloadWorlds(Hashtable worldTickTimes) { + for (int id : unloadQueue) { + WorldServer w = worlds.get(id); +- try { +- if (w != null) +- { +- w.saveAllChunks(true, null); +- } +- else +- { +- FMLLog.warning("Unexpected world unload - world %d is already unloaded", id); +- } +- } catch (MinecraftException e) { +- e.printStackTrace(); +- } +- finally ++ if (w != null) + { +- if (w != null) +- { +- MinecraftForge.EVENT_BUS.post(new WorldEvent.Unload(w)); +- w.flush(); +- setWorld(id, null); +- } ++ MinecraftServer.getServer().server.unloadWorld(w.getWorld(), true); // Cauldron - unload through our new method for simplicity + } + } + unloadQueue.clear(); +@@ -425,4 +578,45 @@ + return null; + } + } ++ ++ // Cauldron start - add registration for Bukkit Environments ++ public static Environment registerBukkitEnvironment(int dim, String providerName) ++ { ++ Environment env = Environment.getEnvironment(dim); ++ if (env == null) // Cauldron if environment not found, register one ++ { ++ providerName = providerName.replace("WorldProvider", ""); ++ env = EnumHelper.addBukkitEnvironment(dim, providerName.toUpperCase()); ++ Environment.registerEnvironment(env); ++ } ++ return env; ++ } ++ ++ public static int getProviderType(Class provider) ++ { ++ return classToProviders.get(provider); ++ } ++ ++ public static void addBukkitDimension(int dim) ++ { ++ if (!bukkitDims.contains(dim)) ++ bukkitDims.add(dim); ++ } ++ ++ public static void removeBukkitDimension(int dim) ++ { ++ if (bukkitDims.contains(dim)) ++ bukkitDims.remove(bukkitDims.indexOf(dim)); ++ } ++ ++ public static ArrayList getBukkitDimensionIDs() ++ { ++ return bukkitDims; ++ } ++ ++ public static boolean isBukkitDimension(int dim) ++ { ++ return bukkitDims.contains(dim); ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraftforge/common/ForgeHooks.java.patch b/patches/net/minecraftforge/common/ForgeHooks.java.patch new file mode 100644 index 0000000..c63caa8 --- /dev/null +++ b/patches/net/minecraftforge/common/ForgeHooks.java.patch @@ -0,0 +1,45 @@ +--- ../src-base/minecraft/net/minecraftforge/common/ForgeHooks.java ++++ ../src-work/minecraft/net/minecraftforge/common/ForgeHooks.java +@@ -63,6 +63,7 @@ + import net.minecraftforge.event.world.BlockEvent; + import net.minecraftforge.event.world.NoteBlockEvent; + import static net.minecraft.init.Blocks.*; ++import net.minecraftforge.common.util.FakePlayer; // Cauldron + + public class ForgeHooks + { +@@ -439,6 +440,8 @@ + + public static BlockEvent.BreakEvent onBlockBreakEvent(World world, GameType gameType, EntityPlayerMP entityPlayer, int x, int y, int z) + { ++ // Cauldron - pre-cancel handled in BreakEvent ++ /* + // Logic from tryHarvestBlock for pre-canceling the event + boolean preCancelEvent = false; + if (gameType.isAdventure() && !entityPlayer.isCurrentToolAdventureModeExempt(x, y, z)) +@@ -449,9 +452,9 @@ + { + preCancelEvent = true; + } +- ++ */ + // Tell client the block is gone immediately then process events +- if (world.getTileEntity(x, y, z) == null) ++ if (world.getTileEntity(x, y, z) == null && !(entityPlayer instanceof FakePlayer)) // Cauldron - don't send packets to fakeplayers + { + S23PacketBlockChange packet = new S23PacketBlockChange(x, y, z, world); + packet.field_148883_d = Blocks.air; +@@ -463,11 +466,11 @@ + Block block = world.getBlock(x, y, z); + int blockMetadata = world.getBlockMetadata(x, y, z); + BlockEvent.BreakEvent event = new BlockEvent.BreakEvent(x, y, z, world, block, blockMetadata, entityPlayer); +- event.setCanceled(preCancelEvent); ++ // event.setCanceled(preCancelEvent); // Cauldron + MinecraftForge.EVENT_BUS.post(event); + + // Handle if the event is canceled +- if (event.isCanceled()) ++ if (event.isCanceled() && !(entityPlayer instanceof FakePlayer)) // Cauldron - don't send packets to fakeplayers + { + // Let the client know the block still exists + entityPlayer.playerNetServerHandler.sendPacket(new S23PacketBlockChange(x, y, z, world)); diff --git a/patches/net/minecraftforge/common/ForgeVersion.java.patch b/patches/net/minecraftforge/common/ForgeVersion.java.patch new file mode 100644 index 0000000..e3b4c01 --- /dev/null +++ b/patches/net/minecraftforge/common/ForgeVersion.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/net/minecraftforge/common/ForgeVersion.java ++++ ../src-work/minecraft/net/minecraftforge/common/ForgeVersion.java +@@ -25,7 +25,7 @@ + //This number is incremented every time a interface changes or new major feature is added, and reset every Minecraft version + public static final int revisionVersion = 2; + //This number is incremented every time Jenkins builds Forge, and never reset. Should always be 0 in the repo code. +- public static final int buildVersion = 0; ++ public static final int buildVersion = 1291; // Cauldron + + private static Status status = PENDING; + private static String target = null; diff --git a/patches/net/minecraftforge/common/WorldSpecificSaveHandler.java.patch b/patches/net/minecraftforge/common/WorldSpecificSaveHandler.java.patch new file mode 100644 index 0000000..0b0caec --- /dev/null +++ b/patches/net/minecraftforge/common/WorldSpecificSaveHandler.java.patch @@ -0,0 +1,22 @@ +--- ../src-base/minecraft/net/minecraftforge/common/WorldSpecificSaveHandler.java ++++ ../src-work/minecraft/net/minecraftforge/common/WorldSpecificSaveHandler.java +@@ -1,6 +1,7 @@ + package net.minecraftforge.common; + + import java.io.File; ++import java.util.UUID; + + import net.minecraft.world.chunk.storage.IChunkLoader; + import net.minecraft.world.storage.IPlayerFileData; +@@ -43,4 +44,11 @@ + return new File(dataDir, name + ".dat"); + } + ++ // Cauldron start ++ @Override ++ public UUID getUUID() ++ { ++ return parent.getUUID(); ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraftforge/common/chunkio/ChunkIOProvider.java.patch b/patches/net/minecraftforge/common/chunkio/ChunkIOProvider.java.patch new file mode 100644 index 0000000..e9223dd --- /dev/null +++ b/patches/net/minecraftforge/common/chunkio/ChunkIOProvider.java.patch @@ -0,0 +1,34 @@ +--- ../src-base/minecraft/net/minecraftforge/common/chunkio/ChunkIOProvider.java ++++ ../src-work/minecraft/net/minecraftforge/common/chunkio/ChunkIOProvider.java +@@ -9,6 +9,9 @@ + import java.io.IOException; + import java.util.concurrent.atomic.AtomicInteger; + ++import org.bukkit.Server; ++import org.bukkit.craftbukkit.util.LongHash; ++ + class ChunkIOProvider implements AsynchronousExecutor.CallBackProvider { + private final AtomicInteger threadNumber = new AtomicInteger(1); + +@@ -41,13 +44,20 @@ + 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(); +- queuedChunk.provider.loadedChunkHashMap.add(ChunkCoordIntPair.chunkXZ2Int(queuedChunk.x, queuedChunk.z), chunk); ++ queuedChunk.provider.loadedChunkHashMap.put(LongHash.toLong(queuedChunk.x, queuedChunk.z), chunk); + queuedChunk.provider.loadedChunks.add(chunk); + chunk.onChunkLoad(); + + if (queuedChunk.provider.currentChunkProvider != null) { ++ queuedChunk.provider.worldObj.timings.syncChunkLoadStructuresTimer.startTiming(); // Spigot + queuedChunk.provider.currentChunkProvider.recreateStructures(queuedChunk.x, queuedChunk.z); ++ queuedChunk.provider.worldObj.timings.syncChunkLoadStructuresTimer.stopTiming(); // Spigot + } ++ ++ Server server = queuedChunk.provider.worldObj.getServer(); ++ if (server != null) { ++ server.getPluginManager().callEvent(new org.bukkit.event.world.ChunkLoadEvent(chunk.bukkitChunk, false)); ++ } + + chunk.populateChunk(queuedChunk.provider, queuedChunk.provider, queuedChunk.x, queuedChunk.z); + } diff --git a/patches/net/minecraftforge/common/network/ForgeNetworkHandler.java.patch b/patches/net/minecraftforge/common/network/ForgeNetworkHandler.java.patch new file mode 100644 index 0000000..97cc2f5 --- /dev/null +++ b/patches/net/minecraftforge/common/network/ForgeNetworkHandler.java.patch @@ -0,0 +1,12 @@ +--- ../src-base/minecraft/net/minecraftforge/common/network/ForgeNetworkHandler.java ++++ ../src-work/minecraft/net/minecraftforge/common/network/ForgeNetworkHandler.java +@@ -35,4 +35,9 @@ + clientChannel.pipeline().addAfter(handlerName, "DimensionHandler", new DimensionMessageHandler()); + clientChannel.pipeline().addAfter(handlerName, "FluidIdRegistryHandler", new FluidIdRegistryMessageHandler()); + } ++ ++ public static FMLEmbeddedChannel getServerChannel() ++ { ++ return channelPair.get(Side.SERVER); ++ } + } diff --git a/patches/net/minecraftforge/common/util/EnumHelper.java.patch b/patches/net/minecraftforge/common/util/EnumHelper.java.patch new file mode 100644 index 0000000..bd83a8a --- /dev/null +++ b/patches/net/minecraftforge/common/util/EnumHelper.java.patch @@ -0,0 +1,195 @@ +--- ../src-base/minecraft/net/minecraftforge/common/util/EnumHelper.java ++++ ../src-work/minecraft/net/minecraftforge/common/util/EnumHelper.java +@@ -21,7 +21,23 @@ + import net.minecraft.world.EnumSkyBlock; + import net.minecraft.world.gen.structure.StructureStrongholdPieces.Stronghold.Door; + import net.minecraftforge.classloading.FMLForgePlugin; ++// Cauldron start ++import cpw.mods.fml.relauncher.ReflectionHelper; ++import net.minecraft.inventory.IInventory; ++import net.minecraft.server.MinecraftServer; ++import net.minecraft.tileentity.TileEntity; + ++import org.apache.logging.log4j.Level; ++import org.apache.logging.log4j.LogManager; ++import org.apache.logging.log4j.Logger; ++import org.bukkit.World; ++import org.bukkit.WorldType; ++import org.bukkit.block.Biome; ++import org.bukkit.craftbukkit.entity.CraftEntity; ++import org.bukkit.entity.EntityType; ++import org.bukkit.event.inventory.InventoryType; ++// Cauldron end ++ + public class EnumHelper + { + private static Object reflectionFactory = null; +@@ -30,6 +46,7 @@ + private static Method newFieldAccessor = null; + private static Method fieldAccessorSet = null; + private static boolean isSetup = false; ++ private static final Logger logger = LogManager.getLogger(); + + //Some enums are decompiled with extra arguments, so lets check for that + @SuppressWarnings("rawtypes") +@@ -51,6 +68,73 @@ + {EnumRarity.class, EnumChatFormatting.class, String.class} + }; + ++ // Cauldron start ++ public static Biome addBukkitBiome(String name) ++ { ++ return (Biome)addEnum(Biome.class, name, new Class[0], new Object[0]); ++ } ++ ++ public static World.Environment addBukkitEnvironment(int id, String name) ++ { ++ if (!isSetup) ++ { ++ setup(); ++ } ++ ++ return (World.Environment)addEnum(World.Environment.class, name, new Class[] { Integer.TYPE }, new Object[] { Integer.valueOf(id) }); ++ } ++ ++ public static WorldType addBukkitWorldType(String name) ++ { ++ if (!isSetup) ++ { ++ setup(); ++ } ++ ++ WorldType worldType = addEnum(WorldType.class, name, new Class [] { String.class }, new Object[] { name }); ++ Map BY_NAME = ReflectionHelper.getPrivateValue(WorldType.class, null, "BY_NAME"); ++ BY_NAME.put(name.toUpperCase(), worldType); ++ ++ return worldType; ++ } ++ ++ public static EntityType addBukkitEntityType(String name, Class clazz, int typeId, boolean independent) { ++ String entityType = name.replace("-", "_").toUpperCase(); ++ EntityType bukkitType = addEnum(EntityType.class, entityType, new Class[] { String.class, Class.class, Integer.TYPE, Boolean.TYPE }, new Object[] { name, clazz, typeId, independent }); ++ ++ Map NAME_MAP = ReflectionHelper.getPrivateValue(EntityType.class, null, "NAME_MAP"); ++ Map ID_MAP = ReflectionHelper.getPrivateValue(EntityType.class, null, "ID_MAP"); ++ ++ NAME_MAP.put(name.toLowerCase(), bukkitType); ++ ID_MAP.put((short)typeId, bukkitType); ++ ++ ++ return bukkitType; ++ } ++ ++ public static InventoryType addInventoryType(TileEntity tileentity) ++ { ++ if (!IInventory.class.isAssignableFrom(tileentity.getClass())) return null; ++ String id = (String)TileEntity.classToNameMap.get(tileentity.getClass()); ++ ++ try ++ { ++ IInventory teInv = (IInventory)tileentity; ++ int size = teInv.getSizeInventory(); ++ return addEnum(org.bukkit.event.inventory.InventoryType.class, id, new Class[]{Integer.TYPE, String.class}, new Object[]{size, id}); ++ } ++ catch (Throwable e) ++ { ++ if (MinecraftServer.getServer().tileEntityConfig.enableTEInventoryWarning.getValue()) ++ { ++ logger.log(Level.WARN, "Could not create inventory type " + tileentity.getClass().getName() + " Exception: " + e.toString()); ++ logger.log(Level.WARN, "Could not determine default inventory size for type " + tileentity.getClass().getName() + " using size of 9"); ++ } ++ return addEnum(org.bukkit.event.inventory.InventoryType.class, id, new Class[]{Integer.TYPE, String.class}, new Object[]{9, id}); ++ } ++ } ++ // Cauldron end ++ + public static EnumAction addAction(String name) + { + return addEnum(EnumAction.class, name); +@@ -280,6 +364,86 @@ + } + } + ++ // Cauldron start ++ @SuppressWarnings("unchecked") ++ public static > T replaceEnum(Class enumType, String enumName, int ordinal, Class[] paramTypes, Object[] paramValues) ++ { ++ if (!isSetup) ++ { ++ setup(); ++ } ++ ++ Field valuesField = null; ++ Field[] fields = enumType.getDeclaredFields(); ++ ++ for (Field field : fields) ++ { ++ String name = field.getName(); ++ if (name.equals("$VALUES") || name.equals("ENUM$VALUES")) //Added 'ENUM$VALUES' because Eclipse's internal compiler doesn't follow standards ++ { ++ valuesField = field; ++ break; ++ } ++ } ++ ++ int flags = (FMLForgePlugin.RUNTIME_DEOBF ? Modifier.PUBLIC : Modifier.PRIVATE) | Modifier.STATIC | Modifier.FINAL | 0x1000 /*SYNTHETIC*/; ++ if (valuesField == null) ++ { ++ String valueType = String.format("[L%s;", enumType.getName().replace('.', '/')); ++ ++ for (Field field : fields) ++ { ++ if ((field.getModifiers() & flags) == flags && ++ field.getType().getName().replace('.', '/').equals(valueType)) //Apparently some JVMs return .'s and some don't.. ++ { ++ valuesField = field; ++ break; ++ } ++ } ++ } ++ ++ if (valuesField == null) ++ { ++ FMLLog.severe("Could not find $VALUES field for enum: %s", enumType.getName()); ++ FMLLog.severe("Runtime Deobf: %s", FMLForgePlugin.RUNTIME_DEOBF); ++ FMLLog.severe("Flags: %s", String.format("%16s", Integer.toBinaryString(flags)).replace(' ', '0')); ++ FMLLog.severe("Fields:"); ++ for (Field field : fields) ++ { ++ String mods = String.format("%16s", Integer.toBinaryString(field.getModifiers())).replace(' ', '0'); ++ FMLLog.severe(" %s %s: %s", mods, field.getName(), field.getType().getName()); ++ } ++ return null; ++ } ++ ++ valuesField.setAccessible(true); ++ try ++ { ++ Enum[] previousValues = (Enum[])(Enum[])valuesField.get(enumType); ++ Enum[] newValues = new Enum[previousValues.length]; ++ Enum newValue = null; ++ for (Enum enumValue : previousValues) ++ { ++ if (enumValue.ordinal() == ordinal) ++ { ++ newValue = makeEnum(enumType, enumName, ordinal, paramTypes, paramValues); ++ newValues[enumValue.ordinal()] = newValue; ++ } ++ else newValues[enumValue.ordinal()] = enumValue; ++ } ++ List values = new ArrayList(Arrays.asList(newValues)); ++ setFailsafeFieldValue(valuesField, null, values.toArray((Enum[])(Enum[])Array.newInstance(enumType, 0))); ++ cleanEnumCache(enumType); ++ return (T) newValue; ++ } ++ catch (Exception e) ++ { ++ e.printStackTrace(); ++ throw new RuntimeException(e.getMessage(), e); ++ } ++ } ++ // Cauldron end ++ + static + { + if (!isSetup) diff --git a/patches/net/minecraftforge/common/util/FakePlayerFactory.java.patch b/patches/net/minecraftforge/common/util/FakePlayerFactory.java.patch new file mode 100644 index 0000000..594cfb7 --- /dev/null +++ b/patches/net/minecraftforge/common/util/FakePlayerFactory.java.patch @@ -0,0 +1,31 @@ +--- ../src-base/minecraft/net/minecraftforge/common/util/FakePlayerFactory.java ++++ ../src-work/minecraft/net/minecraftforge/common/util/FakePlayerFactory.java +@@ -35,12 +35,24 @@ + */ + public static FakePlayer get(WorldServer world, GameProfile username) + { +- if (!fakePlayers.containsKey(username)) ++ // Cauldron start - Refactored below to avoid a hashCode check with a null GameProfile ID ++ if (username == null || username.getName() == null) return null; ++ ++ for (Map.Entry mapEntry : fakePlayers.entrySet()) + { +- FakePlayer fakePlayer = new FakePlayer(world, username); +- fakePlayers.put(username, fakePlayer); ++ GameProfile gameprofile = mapEntry.getKey(); ++ if (gameprofile.getName().equals(username.getName())) ++ { ++ return mapEntry.getValue(); ++ } + } +- ++ FakePlayer fakePlayer = new FakePlayer(world, username); ++ if (username.getId() == null) // GameProfile hashCode check will fail with a null ID ++ { ++ username = new GameProfile(UUID.randomUUID(), username.getName()); // Create new GameProfile with random UUID ++ } ++ // Cauldron end ++ fakePlayers.put(username, fakePlayer); + return fakePlayers.get(username); + } + diff --git a/patches/net/minecraftforge/event/entity/living/LivingSpawnEvent.java.patch b/patches/net/minecraftforge/event/entity/living/LivingSpawnEvent.java.patch new file mode 100644 index 0000000..862a5da --- /dev/null +++ b/patches/net/minecraftforge/event/entity/living/LivingSpawnEvent.java.patch @@ -0,0 +1,18 @@ +--- ../src-base/minecraft/net/minecraftforge/event/entity/living/LivingSpawnEvent.java ++++ ../src-work/minecraft/net/minecraftforge/event/entity/living/LivingSpawnEvent.java +@@ -48,6 +48,7 @@ + public CheckSpawn(EntityLiving entity, World world, float x, float y, float z) + { + super(entity, world, x, y, z); ++ entity.spawnReason = "natural"; // Cauldron - used to handle CraftBukkit's SpawnReason with CustomSpawners + } + } + +@@ -71,6 +72,7 @@ + public SpecialSpawn(EntityLiving entity, World world, float x, float y, float z) + { + super(entity, world, x, y, z); ++ entity.spawnReason = "spawner"; // Cauldron - used to handle CraftBukkit's SpawnReason with CustomSpawners + } + } + diff --git a/patches/net/minecraftforge/event/world/BlockEvent.java.patch b/patches/net/minecraftforge/event/world/BlockEvent.java.patch new file mode 100644 index 0000000..630d583 --- /dev/null +++ b/patches/net/minecraftforge/event/world/BlockEvent.java.patch @@ -0,0 +1,39 @@ +--- ../src-base/minecraft/net/minecraftforge/event/world/BlockEvent.java ++++ ../src-work/minecraft/net/minecraftforge/event/world/BlockEvent.java +@@ -16,6 +16,11 @@ + import net.minecraftforge.common.ForgeHooks; + import net.minecraftforge.common.util.BlockSnapshot; + ++// Cauldron start ++import org.bukkit.craftbukkit.event.CraftEventFactory; ++import net.minecraft.entity.player.EntityPlayerMP; ++// Cauldron end ++ + public class BlockEvent extends Event { + private static final boolean DEBUG = Boolean.parseBoolean(System.getProperty("forge.debugBlockEvent", "false")); + +@@ -80,17 +85,18 @@ + super(x, y, z, world, block, blockMetadata); + this.player = player; + +- if (block == null || !ForgeHooks.canHarvestBlock(block, player, blockMetadata) || // Handle empty block or player unable to break block scenario +- block.canSilkHarvest(world, player, x, y, z, blockMetadata) && EnchantmentHelper.getSilkTouchModifier(player)) // If the block is being silk harvested, the exp dropped is 0 ++ // Cauldron start - handle event on bukkit side ++ org.bukkit.event.block.BlockBreakEvent bukkitEvent = CraftEventFactory.callBlockBreakEvent(world, x, y, z, block, blockMetadata, ++ (EntityPlayerMP) player); ++ if (bukkitEvent.isCancelled()) + { +- this.exp = 0; ++ this.setCanceled(true); + } + else + { +- int meta = block.getDamageValue(world, x, y, z); +- int bonusLevel = EnchantmentHelper.getFortuneModifier(player); +- this.exp = block.getExpDrop(world, meta, bonusLevel); ++ this.exp = bukkitEvent.getExpToDrop(); + } ++ // Cauldron end + } + + public EntityPlayer getPlayer() diff --git a/patches/net/minecraftforge/oredict/OreDictionary.java.patch b/patches/net/minecraftforge/oredict/OreDictionary.java.patch new file mode 100644 index 0000000..05f2f2a --- /dev/null +++ b/patches/net/minecraftforge/oredict/OreDictionary.java.patch @@ -0,0 +1,20 @@ +--- ../src-base/minecraft/net/minecraftforge/oredict/OreDictionary.java ++++ ../src-work/minecraft/net/minecraftforge/oredict/OreDictionary.java +@@ -216,7 +216,7 @@ + { + ShapedRecipes recipe = (ShapedRecipes)obj; + ItemStack output = recipe.getRecipeOutput(); +- if (output != null && containsMatch(false, exclusions, output)) ++ if ((output != null && containsMatch(false, exclusions, output)) || output == null) // Cauldron - fixes NPE's with null recipes being added to forge + { + continue; + } +@@ -231,7 +231,7 @@ + { + ShapelessRecipes recipe = (ShapelessRecipes)obj; + ItemStack output = recipe.getRecipeOutput(); +- if (output != null && containsMatch(false, exclusions, output)) ++ if ((output != null && containsMatch(false, exclusions, output)) || output == null) // Cauldron - fixes NPE's with null recipes being added to forge + { + continue; + } diff --git a/patches/net/minecraftforge/oredict/ShapedOreRecipe.java.patch b/patches/net/minecraftforge/oredict/ShapedOreRecipe.java.patch new file mode 100644 index 0000000..f6bae3c --- /dev/null +++ b/patches/net/minecraftforge/oredict/ShapedOreRecipe.java.patch @@ -0,0 +1,51 @@ +--- ../src-base/minecraft/net/minecraftforge/oredict/ShapedOreRecipe.java ++++ ../src-work/minecraft/net/minecraftforge/oredict/ShapedOreRecipe.java +@@ -6,6 +6,10 @@ + import java.util.Map; + import java.util.Map.Entry; + ++// Cauldron start ++import org.bukkit.inventory.Recipe; ++// Cauldron end ++ + import net.minecraft.block.Block; + import net.minecraft.item.crafting.IRecipe; + import net.minecraft.inventory.InventoryCrafting; +@@ -13,6 +17,7 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.item.crafting.ShapedRecipes; + import net.minecraft.world.World; ++import net.minecraftforge.cauldron.inventory.CustomModRecipe; + + public class ShapedOreRecipe implements IRecipe + { +@@ -25,6 +30,7 @@ + private int width = 0; + private int height = 0; + private boolean mirrored = true; ++ private ShapedRecipes vanillaRecipe = null; // Cauldron - bukkit compatibility + + public ShapedOreRecipe(Block result, Object... recipe){ this(new ItemStack(result), recipe); } + public ShapedOreRecipe(Item result, Object... recipe){ this(new ItemStack(result), recipe); } +@@ -127,6 +133,7 @@ + + ShapedOreRecipe(ShapedRecipes recipe, Map replacements) + { ++ vanillaRecipe = recipe; // Cauldron - bukkit compatibility + output = recipe.getRecipeOutput(); + width = recipe.recipeWidth; + height = recipe.recipeHeight; +@@ -255,4 +262,13 @@ + { + return this.input; + } ++ ++ // Cauldron start - required for Bukkit API ++ @Override ++ public Recipe toBukkitRecipe() { ++ if (vanillaRecipe != null) ++ return vanillaRecipe.toBukkitRecipe(); ++ return new CustomModRecipe(this); ++ } ++ // Cauldron end + } diff --git a/patches/net/minecraftforge/oredict/ShapelessOreRecipe.java.patch b/patches/net/minecraftforge/oredict/ShapelessOreRecipe.java.patch new file mode 100644 index 0000000..ae00843 --- /dev/null +++ b/patches/net/minecraftforge/oredict/ShapelessOreRecipe.java.patch @@ -0,0 +1,49 @@ +--- ../src-base/minecraft/net/minecraftforge/oredict/ShapelessOreRecipe.java ++++ ../src-work/minecraft/net/minecraftforge/oredict/ShapelessOreRecipe.java +@@ -6,6 +6,10 @@ + import java.util.Map.Entry; + import java.util.List; + ++// Cauldron start ++import org.bukkit.inventory.Recipe; ++// Cauldron end ++ + import net.minecraft.block.Block; + import net.minecraft.item.crafting.IRecipe; + import net.minecraft.inventory.InventoryCrafting; +@@ -13,11 +17,13 @@ + import net.minecraft.item.ItemStack; + import net.minecraft.item.crafting.ShapelessRecipes; + import net.minecraft.world.World; ++import net.minecraftforge.cauldron.inventory.CustomModRecipe; + + public class ShapelessOreRecipe implements IRecipe + { + private ItemStack output = null; + private ArrayList input = new ArrayList(); ++ private ShapelessRecipes vanillaRecipe = null; // Cauldron - bukkit compatibility + + public ShapelessOreRecipe(Block result, Object... recipe){ this(new ItemStack(result), recipe); } + public ShapelessOreRecipe(Item result, Object... recipe){ this(new ItemStack(result), recipe); } +@@ -59,6 +65,7 @@ + @SuppressWarnings("unchecked") + ShapelessOreRecipe(ShapelessRecipes recipe, Map replacements) + { ++ vanillaRecipe = recipe; // Cauldron - bukkit compatibility + output = recipe.getRecipeOutput(); + + for(ItemStack ingred : ((List)recipe.recipeItems)) +@@ -146,4 +153,13 @@ + { + return this.input; + } ++ ++ // Cauldron start - required for Bukkit API ++ @Override ++ public Recipe toBukkitRecipe() { ++ if (vanillaRecipe != null) ++ return vanillaRecipe.toBukkitRecipe(); ++ return new CustomModRecipe(this); ++ } ++ // Cauldron end + } diff --git a/patches/org/bukkit/Bukkit.java.patch b/patches/org/bukkit/Bukkit.java.patch new file mode 100644 index 0000000..fe66c31 --- /dev/null +++ b/patches/org/bukkit/Bukkit.java.patch @@ -0,0 +1,10 @@ +--- ../src-base/minecraft/org/bukkit/Bukkit.java ++++ ../src-work/minecraft/org/bukkit/Bukkit.java +@@ -301,6 +301,7 @@ + */ + public static void reload() { + server.reload(); ++ org.spigotmc.CustomTimingsHandler.reload(); // Spigot + } + + /** diff --git a/patches/org/bukkit/Effect.java.patch b/patches/org/bukkit/Effect.java.patch new file mode 100644 index 0000000..0de855a --- /dev/null +++ b/patches/org/bukkit/Effect.java.patch @@ -0,0 +1,259 @@ +--- ../src-base/minecraft/org/bukkit/Effect.java ++++ ../src-work/minecraft/org/bukkit/Effect.java +@@ -5,6 +5,7 @@ + import com.google.common.collect.Maps; + + import org.bukkit.block.BlockFace; ++import org.bukkit.material.MaterialData; + import org.bukkit.potion.Potion; + + /** +@@ -79,27 +80,183 @@ + /** + * The flames seen on a mobspawner; a visual effect. + */ +- MOBSPAWNER_FLAMES(2004, Type.VISUAL); ++ MOBSPAWNER_FLAMES(2004, Type.VISUAL), ++ /** ++ * The spark that comes off a fireworks ++ */ ++ FIREWORKS_SPARK("fireworksSpark", Type.PARTICLE), ++ /** ++ * Critical hit particles ++ */ ++ CRIT("crit", Type.PARTICLE), ++ /** ++ * Blue critical hit particles ++ */ ++ MAGIC_CRIT("magicCrit", Type.PARTICLE), ++ /** ++ * Multicolored potion effect particles ++ */ ++ POTION_SWIRL("mobSpell", Type.PARTICLE), ++ /** ++ * Multicolored potion effect particles that are slightly transparent ++ */ ++ POTION_SWIRL_TRANSPARENT("mobSpellAmbient", Type.PARTICLE), ++ /** ++ * A puff of white potion swirls ++ */ ++ SPELL("spell", Type.PARTICLE), ++ /** ++ * A puff of white stars ++ */ ++ INSTANT_SPELL("instantSpell", Type.PARTICLE), ++ /** ++ * A puff of purple particles ++ */ ++ WITCH_MAGIC("witchMagic", Type.PARTICLE), ++ /** ++ * The note that appears above note blocks ++ */ ++ NOTE("note", Type.PARTICLE), ++ /** ++ * The particles shown at nether portals ++ */ ++ PORTAL("portal", Type.PARTICLE), ++ /** ++ * The symbols that fly towards the enchantment table ++ */ ++ FLYING_GLYPH("enchantmenttable", Type.PARTICLE), ++ /** ++ * Fire particles ++ */ ++ FLAME("flame", Type.PARTICLE), ++ /** ++ * The particles that pop out of lava ++ */ ++ LAVA_POP("lava", Type.PARTICLE), ++ /** ++ * A small gray square ++ */ ++ FOOTSTEP("footstep", Type.PARTICLE), ++ /** ++ * Water particles ++ */ ++ SPLASH("splash", Type.PARTICLE), ++ /** ++ * Smoke particles ++ */ ++ PARTICLE_SMOKE("smoke", Type.PARTICLE), ++ /** ++ * The biggest explosion particle effect ++ */ ++ EXPLOSION_HUGE("hugeexplosion", Type.PARTICLE), ++ /** ++ * A larger version of the explode particle ++ */ ++ EXPLOSION_LARGE("largeexplode", Type.PARTICLE), ++ /** ++ * Explosion particles ++ */ ++ EXPLOSION("explode", Type.PARTICLE), ++ /** ++ * Small gray particles ++ */ ++ VOID_FOG("depthsuspend", Type.PARTICLE), ++ /** ++ * Small gray particles ++ */ ++ SMALL_SMOKE("townaura", Type.PARTICLE), ++ /** ++ * A puff of white smoke ++ */ ++ CLOUD("cloud", Type.PARTICLE), ++ /** ++ * Multicolored dust particles ++ */ ++ COLOURED_DUST("reddust", Type.PARTICLE), ++ /** ++ * Snowball breaking ++ */ ++ SNOWBALL_BREAK("snowballpoof", Type.PARTICLE), ++ /** ++ * The water drip particle that appears on blocks under water ++ */ ++ WATERDRIP("dripWater", Type.PARTICLE), ++ /** ++ * The lava drip particle that appears on blocks under lava ++ */ ++ LAVADRIP("dripLava", Type.PARTICLE), ++ /** ++ * White particles ++ */ ++ SNOW_SHOVEL("snowshovel", Type.PARTICLE), ++ /** ++ * The particle shown when a slime jumps ++ */ ++ SLIME("slime", Type.PARTICLE), ++ /** ++ * The particle that appears when breading animals ++ */ ++ HEART("heart", Type.PARTICLE), ++ /** ++ * The particle that appears when hitting a villager ++ */ ++ VILLAGER_THUNDERCLOUD("angryVillager", Type.PARTICLE), ++ /** ++ * The particle that appears when trading with a villager ++ */ ++ HAPPY_VILLAGER("happyVillager", Type.PARTICLE), ++ /** ++ * The particles generated when a tool breaks. ++ * This particle requires a Material so that the client can select the correct texture. ++ */ ++ ITEM_BREAK("iconcrack", Type.PARTICLE, Material.class), ++ /** ++ * The particles generated while breaking a block. ++ * This particle requires a Material and data value so that the client can select the correct texture. ++ */ ++ TILE_BREAK("blockcrack", Type.PARTICLE, MaterialData.class), ++ /** ++ * The particles generated while sprinting a block ++ * This particle requires a Material and data value so that the client can select the correct texture. ++ */ ++ TILE_DUST("blockdust", Type.PARTICLE, MaterialData.class); + + private final int id; + private final Type type; + private final Class data; + private static final Map BY_ID = Maps.newHashMap(); ++ private static final Map BY_NAME = Maps.newHashMap(); ++ private final String particleName; + +- Effect(int id, Type type) { ++ private Effect(int id, Type type) { + this(id,type,null); + } + +- Effect(int id, Type type, Class data) { ++ private Effect(int id, Type type, Class data) { + this.id = id; + this.type = type; + this.data = data; ++ particleName = null; + } + ++ private Effect(String particleName, Type type, Class data) { ++ this.particleName = particleName; ++ this.type = type; ++ id = 0; ++ this.data = data; ++ } ++ ++ private Effect(String particleName, Type type) { ++ this.particleName = particleName; ++ this.type = type; ++ id = 0; ++ this.data = null; ++ } ++ + /** + * Gets the ID for this effect. + * +- * @return ID of this effect ++ * @return if this Effect isn't of type PARTICLE it returns ID of this effect + * @deprecated Magic value + */ + @Deprecated +@@ -108,6 +265,15 @@ + } + + /** ++ * Returns the effect's name. This returns null if the effect is not a particle ++ * ++ * @return The effect's name ++ */ ++ public String getName() { ++ return particleName; ++ } ++ ++ /** + * @return The type of the effect. + */ + public Type getType() { +@@ -115,8 +281,7 @@ + } + + /** +- * @return The class which represents data for this effect, or null if +- * none ++ * @return if this Effect isn't of type PARTICLE it returns the class which represents data for this effect, or null if none + */ + public Class getData() { + return this.data; +@@ -136,12 +301,32 @@ + + static { + for (Effect effect : values()) { +- BY_ID.put(effect.id, effect); ++ if (effect.type != Type.PARTICLE) { ++ BY_ID.put(effect.id, effect); ++ } + } + } + + /** ++ * Gets the Effect associated with the given name. ++ * ++ * @param name name of the Effect to return ++ * @return Effect with the given name ++ */ ++ public static Effect getByName(String name) { ++ return BY_NAME.get(name); ++ } ++ ++ static { ++ for (Effect effect : values()) { ++ if (effect.type == Type.PARTICLE) { ++ BY_NAME.put(effect.particleName, effect); ++ } ++ } ++ } ++ ++ /** + * Represents the type of an effect. + */ +- public enum Type {SOUND, VISUAL} ++ public enum Type {SOUND, VISUAL, PARTICLE} + } diff --git a/patches/org/bukkit/GameMode.java.patch b/patches/org/bukkit/GameMode.java.patch new file mode 100644 index 0000000..2547dd4 --- /dev/null +++ b/patches/org/bukkit/GameMode.java.patch @@ -0,0 +1,16 @@ +--- ../src-base/minecraft/org/bukkit/GameMode.java ++++ ../src-work/minecraft/org/bukkit/GameMode.java +@@ -11,7 +11,13 @@ + * have + */ + public enum GameMode { ++ // Cauldron start - FakePlayers do not set their gametype and use the default + /** ++ * Default mode ++ */ ++ NOT_SET(-1), ++ // Cauldron end ++ /** + * Creative mode may fly, build instantly, become invulnerable and create + * free items. + */ diff --git a/patches/org/bukkit/Material.java.patch b/patches/org/bukkit/Material.java.patch new file mode 100644 index 0000000..850d532 --- /dev/null +++ b/patches/org/bukkit/Material.java.patch @@ -0,0 +1,272 @@ +--- ../src-base/minecraft/org/bukkit/Material.java ++++ ../src-work/minecraft/org/bukkit/Material.java +@@ -3,6 +3,22 @@ + import java.lang.reflect.Constructor; + import java.util.Map; + ++// Cauldron start ++import java.lang.reflect.Array; ++import java.lang.reflect.Constructor; ++import java.lang.reflect.Field; ++import java.lang.reflect.Method; ++import java.util.ArrayList; ++import java.util.Arrays; ++import java.util.List; ++ ++import org.bukkit.inventory.ItemStack; ++ ++import net.minecraftforge.common.util.EnumHelper; ++import net.minecraftforge.cauldron.api.inventory.BukkitOreDictionary; ++import net.minecraftforge.cauldron.api.inventory.OreDictionaryEntry; ++// Cauldron end ++ + import org.apache.commons.lang.Validate; + import org.bukkit.map.MapView; + import org.bukkit.material.Bed; +@@ -418,14 +434,30 @@ + private final int id; + private final Constructor ctor; + private static Material[] byId = new Material[383]; +- private final static Map BY_NAME = Maps.newHashMap(); ++ private static Map BY_NAME = Maps.newHashMap(); // Cauldron - remove final + private final int maxStack; + private final short durability; ++ // Cauldron start ++ private static Object reflectionFactory; ++ private static Method newConstructorAccessor; ++ private static Method newInstance; ++ private static Method newFieldAccessor; ++ private static Method fieldAccessorSet; ++ private static boolean isSetup; ++ private boolean isForgeBlock = false; ++ // Cauldron end + + private Material(final int id) { + this(id, 64); + } + ++ // Cauldron start - constructor used to set if the Material is a block or not ++ private Material(final int id, boolean flag) { ++ this(id, 64); ++ this.isForgeBlock = flag; ++ } ++ // Cauldron end ++ + private Material(final int id, final int stack) { + this(id, stack, MaterialData.class); + } +@@ -526,7 +558,7 @@ + * @return true if this material is a block + */ + public boolean isBlock() { +- return id < 256; ++ return id < 256 || isForgeBlock; // Cauldron + } + + /** +@@ -615,16 +647,202 @@ + } catch (NumberFormatException ex) {} + + if (result == null) { +- String filtered = name.toUpperCase(); +- +- filtered = filtered.replaceAll("\\s+", "_").replaceAll("\\W", ""); ++ // Cauldron start - extract to normalizeName() ++ String filtered = normalizeName(name); + result = BY_NAME.get(filtered); ++ // Cauldron end + } + ++ // Cauldron start - Try the ore dictionary ++ if (result == null) { ++ BukkitOreDictionary dict = net.minecraftforge.cauldron.api.Cauldron.getOreDictionary(); ++ OreDictionaryEntry entry = dict.getOreEntry(name); ++ if (entry != null) { ++ List items = dict.getDefinitions(entry); ++ if (items.size() > 0) { ++ // TODO check sanity on multiple item results ++ ItemStack item = items.get(0); ++ if (item.getDurability() == 0 || item.getDurability() == Short.MAX_VALUE) { ++ result = item.getType(); ++ } else { ++ // bad! we have an item with data! ++ } ++ } ++ } ++ } ++ // Cauldron end ++ + return result; + } + ++ /* =============================== Cauldron START ============================= */ ++ ++ // use a normalize() function to ensure it is accessible after a round-trip ++ public static String normalizeName(String name) { ++ return name.toUpperCase().replaceAll("(:|\\s)", "_").replaceAll("\\W", ""); ++ } ++ ++ public static Material addMaterial(int id, boolean isBlock) ++ { ++ return addMaterial(id, "X" + String.valueOf(id), isBlock); ++ } ++ ++ public static Material addMaterial(int id, String name, boolean isBlock) { ++ if (byId[id] == null) { ++ String materialName = normalizeName(name); ++ Material material = (Material) EnumHelper.addEnum(Material.class, materialName, new Class[]{Integer.TYPE, Boolean.TYPE}, new Object[]{Integer.valueOf(id), isBlock}); ++ byId[id] = material; ++ BY_NAME.put(materialName, material); ++ BY_NAME.put("X" + String.valueOf(id), material); ++ return material; ++ } ++ return null; ++ } ++ ++ public static void setMaterialName(int id, String name, boolean flag) { ++ String materialName = normalizeName(name); ++ ++ if (byId[id] == null) ++ { ++ addMaterial(id, materialName, flag); ++ } ++ else // replace existing enum ++ { ++ /* TODO: find out how to do this with Forge's EnumHelper (addEnum?) - used for enabling descriptive (vs numeric) Material names ++ Material material = getMaterial(id); ++ BY_NAME.remove(material); ++ Material newMaterial = EnumHelper.replaceEnum(Material.class, material_name, material.ordinal(), new Class[] { Integer.TYPE }, new Object[] { Integer.valueOf(id) }); ++ if (newMaterial == null) ++ System.out.println("Error replacing Material " + name + " with id " + id); ++ else { ++ byId[id] = newMaterial; ++ BY_NAME.put(material_name, newMaterial); ++ } ++ */ ++ } ++ } ++ ++ private static void setup() ++ { ++ if (isSetup) ++ { ++ return; ++ } ++ try { ++ Method getReflectionFactory = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("getReflectionFactory", new Class[0]); ++ reflectionFactory = getReflectionFactory.invoke(null, new Object[0]); ++ newConstructorAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newConstructorAccessor", new Class[] { Constructor.class }); ++ newInstance = Class.forName("sun.reflect.ConstructorAccessor").getDeclaredMethod("newInstance", new Class[] { Object[].class }); ++ newFieldAccessor = Class.forName("sun.reflect.ReflectionFactory").getDeclaredMethod("newFieldAccessor", new Class[] { Field.class, Boolean.TYPE }); ++ fieldAccessorSet = Class.forName("sun.reflect.FieldAccessor").getDeclaredMethod("set", new Class[] { Object.class, Object.class }); ++ } catch (Exception e) { ++ e.printStackTrace(); ++ } ++ ++ isSetup = true; ++ } ++ ++ private static Object getConstructorAccessor(Class enumClass, Class[] additionalParameterTypes) throws Exception { ++ Class[] parameterTypes = null; ++ ++ parameterTypes = new Class[additionalParameterTypes.length + 2]; ++ parameterTypes[0] = String.class; ++ parameterTypes[1] = Integer.TYPE; ++ System.arraycopy(additionalParameterTypes, 0, parameterTypes, 2, additionalParameterTypes.length); ++ ++ return newConstructorAccessor.invoke(reflectionFactory, new Object[] { enumClass.getDeclaredConstructor(parameterTypes) }); ++ } ++ ++ private static > T makeEnum(Class enumClass, String value, int ordinal, Class[] additionalTypes, Object[] additionalValues) throws Exception { ++ Object[] parms = null; ++ ++ parms = new Object[additionalValues.length + 2]; ++ parms[0] = value; ++ parms[1] = Integer.valueOf(ordinal); ++ System.arraycopy(additionalValues, 0, parms, 2, additionalValues.length); ++ ++ return (T)enumClass.cast(newInstance.invoke(getConstructorAccessor(enumClass, additionalTypes), new Object[] { parms })); ++ } ++ ++ private static void setFailsafeFieldValue(Field field, Object target, Object value) throws Exception { ++ field.setAccessible(true); ++ Field modifiersField = Field.class.getDeclaredField("modifiers"); ++ modifiersField.setAccessible(true); ++ modifiersField.setInt(field, field.getModifiers() & 0xFFFFFFEF); ++ Object fieldAccessor = newFieldAccessor.invoke(reflectionFactory, new Object[] { field, Boolean.valueOf(false) }); ++ fieldAccessorSet.invoke(fieldAccessor, new Object[] { target, value }); ++ } ++ ++ private static void blankField(Class enumClass, String fieldName) throws Exception { ++ for (Field field : Class.class.getDeclaredFields()) ++ if (field.getName().contains(fieldName)) { ++ field.setAccessible(true); ++ setFailsafeFieldValue(field, enumClass, null); ++ break; ++ } ++ } ++ ++ private static void cleanEnumCache(Class enumClass) throws Exception ++ { ++ blankField(enumClass, "enumConstantDirectory"); ++ blankField(enumClass, "enumConstants"); ++ } ++ ++ public static > T replaceEnum(Class enumType, String enumName, int ordinal, Class[] paramTypes, Object[] paramValues) ++ { ++ if (!isSetup) setup(); ++ Field valuesField = null; ++ Field[] fields = enumType.getDeclaredFields(); ++ int flags = 4122; ++ String valueType = String.format("[L%s;", new Object[] { enumType.getName() }); ++ ++ for (Field field : fields) { ++ if (((field.getModifiers() & flags) != flags) || (!field.getType().getName().equals(valueType))) { ++ continue; ++ } ++ valuesField = field; ++ break; ++ } ++ ++ valuesField.setAccessible(true); ++ try ++ { ++ Enum[] previousValues = (Enum[])(Enum[])valuesField.get(enumType); ++ Enum[] newValues = new Enum[previousValues.length]; ++ Enum newValue = null; ++ for (Enum enumValue : previousValues) ++ { ++ if (enumValue.ordinal() == ordinal) ++ { ++ newValue = makeEnum(enumType, enumName, ordinal, paramTypes, paramValues); ++ newValues[enumValue.ordinal()] = newValue; ++ } ++ else newValues[enumValue.ordinal()] = enumValue; ++ } ++ List values = new ArrayList(Arrays.asList(newValues)); ++ ++ setFailsafeFieldValue(valuesField, null, values.toArray((Enum[])(Enum[])Array.newInstance(enumType, 0))); ++ cleanEnumCache(enumType); ++ return (T) newValue; ++ } catch (Exception e) { ++ e.printStackTrace(); ++ throw new RuntimeException(e.getMessage(), e); ++ } ++ } ++ /* =============================== Cauldron END============================= */ ++ + static { ++ // Cauldron start ++ byId = new Material[32000]; ++ BY_NAME = Maps.newHashMap(); ++ ++ reflectionFactory = null; ++ newConstructorAccessor = null; ++ newInstance = null; ++ newFieldAccessor = null; ++ fieldAccessorSet = null; ++ isSetup = false; ++ // Cauldron end + for (Material material : values()) { + if (byId.length > material.id) { + byId[material.id] = material; diff --git a/patches/org/bukkit/World.java.patch b/patches/org/bukkit/World.java.patch new file mode 100644 index 0000000..86e15f0 --- /dev/null +++ b/patches/org/bukkit/World.java.patch @@ -0,0 +1,72 @@ +--- ../src-base/minecraft/org/bukkit/World.java ++++ ../src-work/minecraft/org/bukkit/World.java +@@ -1155,6 +1155,56 @@ + */ + public boolean isGameRule(String rule); + ++ // Spigot start ++ public class Spigot ++ { ++ ++ /** ++ * Plays an effect to all players within a default radius around a given ++ * location. ++ * ++ * @param location the {@link Location} around which players must be to ++ * see the effect ++ * @param effect the {@link Effect} ++ * @throws IllegalArgumentException if the location or effect is null. ++ * It also throws when the effect requires a material or a material data ++ */ ++ public void playEffect(Location location, Effect effect) ++ { ++ throw new UnsupportedOperationException( "Not supported yet." ); ++ } ++ ++ /** ++ * Plays an effect to all players within a default radius around a given ++ * location. The effect will use the provided material (and material ++ * data if required). The particle's position on the client will be the ++ * given location, adjusted on each axis by a normal distribution with ++ * mean 0 and standard deviation given in the offset parameters, each ++ * particle has independently calculated offsets. The effect will have ++ * the given speed and particle count if the effect is a particle. Some ++ * effect will create multiple particles. ++ * ++ * @param location the {@link Location} around which players must be to ++ * see the effect ++ * @param effect effect the {@link Effect} ++ * @param id the item/block/data id for the effect ++ * @param data the data value of the block/item for the effect ++ * @param offsetX the amount to be randomly offset by in the X axis ++ * @param offsetY the amount to be randomly offset by in the Y axis ++ * @param offsetZ the amount to be randomly offset by in the Z axis ++ * @param speed the speed of the particles ++ * @param particleCount the number of particles ++ * @param radius the radius around the location ++ */ ++ public void playEffect(Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius) ++ { ++ throw new UnsupportedOperationException( "Not supported yet." ); ++ } ++ } ++ ++ Spigot spigot(); ++ // Spigot end ++ + /** + * Represents various map environment types that a world may be + */ +@@ -1203,6 +1253,12 @@ + return lookup.get(id); + } + ++ // Cauldron start - allow forge to register environments ++ public static void registerEnvironment(Environment env) { ++ lookup.put(env.getId(),env); ++ } ++ // Cauldron end ++ + static { + for (Environment env : values()) { + lookup.put(env.getId(), env); diff --git a/patches/org/bukkit/command/Command.java.patch b/patches/org/bukkit/command/Command.java.patch new file mode 100644 index 0000000..b82033f --- /dev/null +++ b/patches/org/bukkit/command/Command.java.patch @@ -0,0 +1,26 @@ +--- ../src-base/minecraft/org/bukkit/command/Command.java ++++ ../src-work/minecraft/org/bukkit/command/Command.java +@@ -31,6 +31,7 @@ + protected String usageMessage; + private String permission; + private String permissionMessage; ++ public org.spigotmc.CustomTimingsHandler timings; // Spigot + + protected Command(String name) { + this(name, "", "/" + name, new ArrayList()); +@@ -44,6 +45,7 @@ + this.usageMessage = usageMessage; + this.aliases = aliases; + this.activeAliases = new ArrayList(aliases); ++ this.timings = new org.spigotmc.CustomTimingsHandler("** Command: " + name); // Spigot + } + + /** +@@ -200,6 +202,7 @@ + public boolean setLabel(String name) { + this.nextLabel = name; + if (!isRegistered()) { ++ this.timings = new org.spigotmc.CustomTimingsHandler("** Command: " + name); // Spigot + this.label = name; + return true; + } diff --git a/patches/org/bukkit/command/SimpleCommandMap.java.patch b/patches/org/bukkit/command/SimpleCommandMap.java.patch new file mode 100644 index 0000000..7dcd0fa --- /dev/null +++ b/patches/org/bukkit/command/SimpleCommandMap.java.patch @@ -0,0 +1,18 @@ +--- ../src-base/minecraft/org/bukkit/command/SimpleCommandMap.java ++++ ../src-work/minecraft/org/bukkit/command/SimpleCommandMap.java +@@ -176,11 +176,15 @@ + } + + try { ++ target.timings.startTiming(); // Spigot + // Note: we don't return the result of target.execute as thats success / failure, we return handled (true) or not handled (false) + target.execute(sender, sentCommandLabel, Arrays_copyOfRange(args, 1, args.length)); ++ target.timings.stopTiming(); // Spigot + } catch (CommandException ex) { ++ target.timings.stopTiming(); // Spigot + throw ex; + } catch (Throwable ex) { ++ target.timings.stopTiming(); // Spigot + throw new CommandException("Unhandled exception executing '" + commandLine + "' in " + target, ex); + } + diff --git a/patches/org/bukkit/command/defaults/GameModeCommand.java.patch b/patches/org/bukkit/command/defaults/GameModeCommand.java.patch new file mode 100644 index 0000000..b0d0308 --- /dev/null +++ b/patches/org/bukkit/command/defaults/GameModeCommand.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/org/bukkit/command/defaults/GameModeCommand.java ++++ ../src-work/minecraft/org/bukkit/command/defaults/GameModeCommand.java +@@ -50,7 +50,7 @@ + + GameMode mode = GameMode.getByValue(value); + +- if (mode == null) { ++ if (mode == null || mode == GameMode.NOT_SET) { // Cauldron + if (modeArg.equalsIgnoreCase("creative") || modeArg.equalsIgnoreCase("c")) { + mode = GameMode.CREATIVE; + } else if (modeArg.equalsIgnoreCase("adventure") || modeArg.equalsIgnoreCase("a")) { diff --git a/patches/org/bukkit/command/defaults/PluginsCommand.java.patch b/patches/org/bukkit/command/defaults/PluginsCommand.java.patch new file mode 100644 index 0000000..6979979 --- /dev/null +++ b/patches/org/bukkit/command/defaults/PluginsCommand.java.patch @@ -0,0 +1,15 @@ +--- ../src-base/minecraft/org/bukkit/command/defaults/PluginsCommand.java ++++ ../src-work/minecraft/org/bukkit/command/defaults/PluginsCommand.java +@@ -40,4 +40,12 @@ + + return "(" + plugins.length + "): " + pluginList.toString(); + } ++ ++ // Spigot Start ++ @Override ++ public java.util.List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException ++ { ++ return java.util.Collections.emptyList(); ++ } ++ // Spigot End + } diff --git a/patches/org/bukkit/command/defaults/ReloadCommand.java.patch b/patches/org/bukkit/command/defaults/ReloadCommand.java.patch new file mode 100644 index 0000000..35a890b --- /dev/null +++ b/patches/org/bukkit/command/defaults/ReloadCommand.java.patch @@ -0,0 +1,28 @@ +--- ../src-base/minecraft/org/bukkit/command/defaults/ReloadCommand.java ++++ ../src-work/minecraft/org/bukkit/command/defaults/ReloadCommand.java +@@ -18,11 +18,25 @@ + + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { ++ // Cauldron start - disable reload as it causes many issues with mods ++ /* + if (!testPermission(sender)) return true; + ++ org.spigotmc.CustomTimingsHandler.reload(); // Spigot: TODO: Why is this here? + Bukkit.reload(); + Command.broadcastCommandMessage(sender, ChatColor.GREEN + "Reload complete."); ++ */ ++ sender.sendMessage(ChatColor.RED + "Reload not allowed on a Cauldron server."); ++ // Cauldron end + + return true; + } ++ ++ // Spigot Start ++ @Override ++ public java.util.List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException ++ { ++ return java.util.Collections.emptyList(); ++ } ++ // Spigot End + } diff --git a/patches/org/bukkit/command/defaults/TellCommand.java.patch b/patches/org/bukkit/command/defaults/TellCommand.java.patch new file mode 100644 index 0000000..3214f12 --- /dev/null +++ b/patches/org/bukkit/command/defaults/TellCommand.java.patch @@ -0,0 +1,19 @@ +--- ../src-base/minecraft/org/bukkit/command/defaults/TellCommand.java ++++ ../src-work/minecraft/org/bukkit/command/defaults/TellCommand.java +@@ -45,4 +45,16 @@ + + return true; + } ++ ++ // Spigot Start ++ @Override ++ public java.util.List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException ++ { ++ if ( args.length == 0 ) ++ { ++ return super.tabComplete( sender, alias, args ); ++ } ++ return java.util.Collections.emptyList(); ++ } ++ // Spigot End + } diff --git a/patches/org/bukkit/command/defaults/TestForCommand.java.patch b/patches/org/bukkit/command/defaults/TestForCommand.java.patch new file mode 100644 index 0000000..8255145 --- /dev/null +++ b/patches/org/bukkit/command/defaults/TestForCommand.java.patch @@ -0,0 +1,19 @@ +--- ../src-base/minecraft/org/bukkit/command/defaults/TestForCommand.java ++++ ../src-work/minecraft/org/bukkit/command/defaults/TestForCommand.java +@@ -23,4 +23,16 @@ + sender.sendMessage(ChatColor.RED + "/testfor is only usable by commandblocks with analog output."); + return true; + } ++ ++ // Spigot Start ++ @Override ++ public java.util.List tabComplete(CommandSender sender, String alias, String[] args) throws IllegalArgumentException ++ { ++ if ( args.length == 0 ) ++ { ++ return super.tabComplete( sender, alias, args ); ++ } ++ return java.util.Collections.emptyList(); ++ } ++ // Spigot End + } diff --git a/patches/org/bukkit/command/defaults/TimingsCommand.java.patch b/patches/org/bukkit/command/defaults/TimingsCommand.java.patch new file mode 100644 index 0000000..6ce3d2c --- /dev/null +++ b/patches/org/bukkit/command/defaults/TimingsCommand.java.patch @@ -0,0 +1,160 @@ +--- ../src-base/minecraft/org/bukkit/command/defaults/TimingsCommand.java ++++ ../src-work/minecraft/org/bukkit/command/defaults/TimingsCommand.java +@@ -19,23 +19,97 @@ + + import com.google.common.collect.ImmutableList; + ++// Spigot start ++import java.io.ByteArrayOutputStream; ++import java.io.OutputStream; ++import java.net.HttpURLConnection; ++import java.net.URL; ++import java.net.URLEncoder; ++import java.util.logging.Level; ++ ++import org.bukkit.command.RemoteConsoleCommandSender; ++import org.bukkit.plugin.SimplePluginManager; ++import org.spigotmc.CustomTimingsHandler; ++// Spigot end ++ + public class TimingsCommand extends BukkitCommand { +- private static final List TIMINGS_SUBCOMMANDS = ImmutableList.of("merged", "reset", "separate"); ++ private static final List TIMINGS_SUBCOMMANDS = ImmutableList.of("report", "reset", "on", "off", "paste"); // Spigot ++ public static long timingStart = 0; // Spigot + + public TimingsCommand(String name) { + super(name); +- this.description = "Records timings for all plugin events"; +- this.usageMessage = "/timings "; ++ this.description = "Manages Spigot Timings data to see performance of the server."; // Spigot ++ this.usageMessage = "/timings "; // Spigot + this.setPermission("bukkit.command.timings"); + } + ++ // Spigot start - redesigned Timings Command ++ public void executeSpigotTimings(CommandSender sender, String[] args) { ++ if ( "on".equals( args[0] ) ) ++ { ++ ( (SimplePluginManager) Bukkit.getPluginManager() ).useTimings( true ); ++ CustomTimingsHandler.reload(); ++ sender.sendMessage( "Enabled Timings & Reset" ); ++ return; ++ } else if ( "off".equals( args[0] ) ) ++ { ++ ( (SimplePluginManager) Bukkit.getPluginManager() ).useTimings( false ); ++ sender.sendMessage( "Disabled Timings" ); ++ return; ++ } ++ ++ if ( !Bukkit.getPluginManager().useTimings() ) ++ { ++ sender.sendMessage( "Please enable timings by typing /timings on" ); ++ return; ++ } ++ ++ boolean paste = "paste".equals( args[0] ); ++ if ("reset".equals(args[0])) { ++ CustomTimingsHandler.reload(); ++ sender.sendMessage("Timings reset"); ++ } else if ("merged".equals(args[0]) || "report".equals(args[0]) || paste) { ++ long sampleTime = System.nanoTime() - timingStart; ++ int index = 0; ++ File timingFolder = new File("timings"); ++ timingFolder.mkdirs(); ++ File timings = new File(timingFolder, "timings.txt"); ++ ByteArrayOutputStream bout = ( paste ) ? new ByteArrayOutputStream() : null; ++ while (timings.exists()) timings = new File(timingFolder, "timings" + (++index) + ".txt"); ++ PrintStream fileTimings = null; ++ try { ++ fileTimings = ( paste ) ? new PrintStream( bout ) : new PrintStream( timings ); ++ ++ CustomTimingsHandler.printTimings(fileTimings); ++ fileTimings.println( "Sample time " + sampleTime + " (" + sampleTime / 1E9 + "s)" ); ++ ++ if ( paste ) ++ { ++ new PasteThread( sender, bout ).start(); ++ return; ++ } ++ ++ sender.sendMessage("Timings written to " + timings.getPath()); ++ sender.sendMessage( "Paste contents of file into form at http://www.spigotmc.org/go/timings to read results." ); ++ ++ } catch (IOException e) { ++ } finally { ++ if (fileTimings != null) { ++ fileTimings.close(); ++ } ++ } ++ } ++ } ++ // Spigot end ++ + @Override + public boolean execute(CommandSender sender, String currentAlias, String[] args) { + if (!testPermission(sender)) return true; +- if (args.length != 1) { ++ if (args.length < 1) { // Spigot + sender.sendMessage(ChatColor.RED + "Usage: " + usageMessage); + return false; + } ++ if (true) { executeSpigotTimings(sender, args); return true; } // Spigot + if (!sender.getServer().getPluginManager().useTimings()) { + sender.sendMessage("Please enable timings by setting \"settings.plugin-profiling\" to true in bukkit.yml"); + return true; +@@ -118,4 +192,55 @@ + } + return ImmutableList.of(); + } ++ ++ // Spigot start ++ private static class PasteThread extends Thread ++ { ++ ++ private final CommandSender sender; ++ private final ByteArrayOutputStream bout; ++ ++ public PasteThread(CommandSender sender, ByteArrayOutputStream bout) ++ { ++ super( "Timings paste thread" ); ++ this.sender = sender; ++ this.bout = bout; ++ } ++ ++ @Override ++ public synchronized void start() { ++ if (sender instanceof RemoteConsoleCommandSender) { ++ run(); ++ } else { ++ super.start(); ++ } ++ } ++ ++ @Override ++ public void run() ++ { ++ try ++ { ++ HttpURLConnection con = (HttpURLConnection) new URL( "http://paste.ubuntu.com/" ).openConnection(); ++ con.setDoOutput( true ); ++ con.setRequestMethod( "POST" ); ++ con.setInstanceFollowRedirects( false ); ++ ++ OutputStream out = con.getOutputStream(); ++ out.write( "poster=Spigot&syntax=text&content=".getBytes( "UTF-8" ) ); ++ out.write( URLEncoder.encode( bout.toString( "UTF-8" ), "UTF-8" ).getBytes( "UTF-8" ) ); ++ out.close(); ++ con.getInputStream().close(); ++ ++ String location = con.getHeaderField( "Location" ); ++ String pasteID = location.substring( "http://paste.ubuntu.com/".length(), location.length() - 1 ); ++ sender.sendMessage( ChatColor.GREEN + "View timings results can be viewed at http://www.spigotmc.org/go/timings?url=" + pasteID ); ++ } catch ( IOException ex ) ++ { ++ sender.sendMessage( ChatColor.RED + "Error pasting timings, check your console for more information" ); ++ Bukkit.getServer().getLogger().log( Level.WARNING, "Could not paste timings", ex ); ++ } ++ } ++ } ++ // Spigot end + } diff --git a/patches/org/bukkit/conversations/BooleanPrompt.java.patch b/patches/org/bukkit/conversations/BooleanPrompt.java.patch new file mode 100644 index 0000000..5e6a84b --- /dev/null +++ b/patches/org/bukkit/conversations/BooleanPrompt.java.patch @@ -0,0 +1,17 @@ +--- ../src-base/minecraft/org/bukkit/conversations/BooleanPrompt.java ++++ ../src-work/minecraft/org/bukkit/conversations/BooleanPrompt.java +@@ -15,12 +15,13 @@ + + @Override + protected boolean isInputValid(ConversationContext context, String input) { +- String[] accepted = {"true", "false", "on", "off", "yes", "no"}; ++ String[] accepted = {"true", "false", "on", "off", "yes", "no" /* Spigot: */, "y", "n", "1", "0", "right", "wrong", "correct", "incorrect", "valid", "invalid"}; // Spigot + return ArrayUtils.contains(accepted, input.toLowerCase()); + } + + @Override + protected Prompt acceptValidatedInput(ConversationContext context, String input) { ++ if (input.equalsIgnoreCase("y") || input.equals("1") || input.equalsIgnoreCase("right") || input.equalsIgnoreCase("correct") || input.equalsIgnoreCase("valid")) input = "true"; // Spigot + return acceptValidatedInput(context, BooleanUtils.toBoolean(input)); + } + diff --git a/patches/org/bukkit/conversations/Conversation.java.patch b/patches/org/bukkit/conversations/Conversation.java.patch new file mode 100644 index 0000000..7fe8cb7 --- /dev/null +++ b/patches/org/bukkit/conversations/Conversation.java.patch @@ -0,0 +1,23 @@ +--- ../src-base/minecraft/org/bukkit/conversations/Conversation.java ++++ ../src-work/minecraft/org/bukkit/conversations/Conversation.java +@@ -209,6 +209,7 @@ + * @param input The user's chat text. + */ + public void acceptInput(String input) { ++ try { // Spigot + if (currentPrompt != null) { + + // Echo the user's input +@@ -228,6 +229,12 @@ + currentPrompt = currentPrompt.acceptInput(context, input); + outputNextPrompt(); + } ++ // Spigot Start ++ } catch ( Throwable t ) ++ { ++ org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.SEVERE, "Error handling conversation prompt", t ); ++ } ++ // Spigot End + } + + /** diff --git a/patches/org/bukkit/entity/Arrow.java.patch b/patches/org/bukkit/entity/Arrow.java.patch new file mode 100644 index 0000000..ac85d36 --- /dev/null +++ b/patches/org/bukkit/entity/Arrow.java.patch @@ -0,0 +1,25 @@ +--- ../src-base/minecraft/org/bukkit/entity/Arrow.java ++++ ../src-work/minecraft/org/bukkit/entity/Arrow.java +@@ -39,4 +39,22 @@ + * @param critical whether or not it should be critical + */ + public void setCritical(boolean critical); ++ ++ // Spigot start ++ public class Spigot extends Entity.Spigot ++ { ++ ++ public double getDamage() ++ { ++ throw new UnsupportedOperationException( "Not supported yet." ); ++ } ++ ++ public void setDamage(double damage) ++ { ++ throw new UnsupportedOperationException( "Not supported yet." ); ++ } ++ } ++ ++ Spigot spigot(); ++ // Spigot end + } diff --git a/patches/org/bukkit/entity/Entity.java.patch b/patches/org/bukkit/entity/Entity.java.patch new file mode 100644 index 0000000..8c53505 --- /dev/null +++ b/patches/org/bukkit/entity/Entity.java.patch @@ -0,0 +1,25 @@ +--- ../src-base/minecraft/org/bukkit/entity/Entity.java ++++ ../src-work/minecraft/org/bukkit/entity/Entity.java +@@ -291,4 +291,22 @@ + * @return The current vehicle. + */ + public Entity getVehicle(); ++ ++ // Spigot Start ++ public class Spigot ++ { ++ ++ /** ++ * Returns whether this entity is invulnerable. ++ * ++ * @return True if the entity is invulnerable. ++ */ ++ public boolean isInvulnerable() ++ { ++ throw new UnsupportedOperationException( "Not supported yet." ); ++ } ++ } ++ ++ Spigot spigot(); ++ // Spigot End + } diff --git a/patches/org/bukkit/entity/Player.java.patch b/patches/org/bukkit/entity/Player.java.patch new file mode 100644 index 0000000..81938be --- /dev/null +++ b/patches/org/bukkit/entity/Player.java.patch @@ -0,0 +1,80 @@ +--- ../src-base/minecraft/org/bukkit/entity/Player.java ++++ ../src-work/minecraft/org/bukkit/entity/Player.java +@@ -1035,4 +1035,77 @@ + * @see Player#setHealthScaled(boolean) + */ + public double getHealthScale(); ++ ++ // Spigot start ++ public class Spigot extends Entity.Spigot ++ { ++ ++ /** ++ * Gets the connection address of this player, regardless of whether it ++ * has been spoofed or not. ++ * ++ * @return the player's connection address ++ */ ++ public InetSocketAddress getRawAddress() ++ { ++ throw new UnsupportedOperationException( "Not supported yet." ); ++ } ++ ++ public void playEffect(Location location, Effect effect, int id, int data, float offsetX, float offsetY, float offsetZ, float speed, int particleCount, int radius) ++ { ++ throw new UnsupportedOperationException( "Not supported yet." ); ++ } ++ ++ /** ++ * Gets whether the player collides with entities ++ * ++ * @return the player's collision toggle state ++ */ ++ public boolean getCollidesWithEntities() ++ { ++ throw new UnsupportedOperationException( "Not supported yet." ); ++ } ++ ++ /** ++ * Sets whether the player collides with entities ++ * ++ * @param collides whether the player should collide with entities or ++ * not. ++ */ ++ public void setCollidesWithEntities(boolean collides) ++ { ++ throw new UnsupportedOperationException( "Not supported yet." ); ++ } ++ ++ /** ++ * Respawns the player if dead. ++ */ ++ public void respawn() ++ { ++ throw new UnsupportedOperationException( "Not supported yet." ); ++ } ++ ++ /** ++ * Gets player locale language. ++ * ++ * @return the player's client language settings ++ */ ++ public String getLocale() ++ { ++ throw new UnsupportedOperationException( "Not supported yet." ); ++ } ++ ++ /** ++ * Gets all players hidden with {@link hidePlayer(org.bukkit.entity.Player)}. ++ * ++ * @return a Set with all hidden players ++ */ ++ public java.util.Set getHiddenPlayers() ++ { ++ throw new UnsupportedOperationException( "Not supported yet." ); ++ } ++ } ++ ++ Spigot spigot(); ++ // Spigot end + } diff --git a/patches/org/bukkit/event/entity/EntityDamageByBlockEvent.java.patch b/patches/org/bukkit/event/entity/EntityDamageByBlockEvent.java.patch new file mode 100644 index 0000000..73587af --- /dev/null +++ b/patches/org/bukkit/event/entity/EntityDamageByBlockEvent.java.patch @@ -0,0 +1,21 @@ +--- ../src-base/minecraft/org/bukkit/event/entity/EntityDamageByBlockEvent.java ++++ ../src-work/minecraft/org/bukkit/event/entity/EntityDamageByBlockEvent.java +@@ -2,6 +2,7 @@ + + import java.util.Map; + ++import com.google.common.base.Function; + import org.bukkit.block.Block; + import org.bukkit.entity.Entity; + +@@ -22,8 +23,8 @@ + this.damager = damager; + } + +- public EntityDamageByBlockEvent(final Block damager, final Entity damagee, final DamageCause cause, final Map modifiers) { +- super(damagee, cause, modifiers); ++ public EntityDamageByBlockEvent(final Block damager, final Entity damagee, final DamageCause cause, final Map modifiers, final Map> modifierFunctions) { ++ super(damagee, cause, modifiers, modifierFunctions); + this.damager = damager; + } + diff --git a/patches/org/bukkit/event/entity/EntityDamageByEntityEvent.java.patch b/patches/org/bukkit/event/entity/EntityDamageByEntityEvent.java.patch new file mode 100644 index 0000000..a877dd8 --- /dev/null +++ b/patches/org/bukkit/event/entity/EntityDamageByEntityEvent.java.patch @@ -0,0 +1,21 @@ +--- ../src-base/minecraft/org/bukkit/event/entity/EntityDamageByEntityEvent.java ++++ ../src-work/minecraft/org/bukkit/event/entity/EntityDamageByEntityEvent.java +@@ -2,6 +2,7 @@ + + import java.util.Map; + ++import com.google.common.base.Function; + import org.bukkit.entity.Entity; + + /** +@@ -21,8 +22,8 @@ + this.damager = damager; + } + +- public EntityDamageByEntityEvent(final Entity damager, final Entity damagee, final DamageCause cause, final Map modifiers) { +- super(damagee, cause, modifiers); ++ public EntityDamageByEntityEvent(final Entity damager, final Entity damagee, final DamageCause cause, final Map modifiers, final Map> modifierFunctions) { ++ super(damagee, cause, modifiers, modifierFunctions); + this.damager = damager; + } + diff --git a/patches/org/bukkit/event/entity/EntityDamageEvent.java.patch b/patches/org/bukkit/event/entity/EntityDamageEvent.java.patch new file mode 100644 index 0000000..60d0cb0 --- /dev/null +++ b/patches/org/bukkit/event/entity/EntityDamageEvent.java.patch @@ -0,0 +1,85 @@ +--- ../src-base/minecraft/org/bukkit/event/entity/EntityDamageEvent.java ++++ ../src-work/minecraft/org/bukkit/event/entity/EntityDamageEvent.java +@@ -10,6 +10,8 @@ + import org.bukkit.event.HandlerList; + import org.bukkit.util.NumberConversions; + ++import com.google.common.base.Function; ++import com.google.common.base.Functions; + import com.google.common.collect.ImmutableMap; + + /** +@@ -18,7 +20,9 @@ + public class EntityDamageEvent extends EntityEvent implements Cancellable { + private static final HandlerList handlers = new HandlerList(); + private static final DamageModifier[] MODIFIERS = DamageModifier.values(); ++ private static final Function ZERO = Functions.constant(-0.0); + private final Map modifiers; ++ private final Map> modifierFunctions; + private final Map originals; + private boolean cancelled; + private final DamageCause cause; +@@ -30,16 +34,20 @@ + + @Deprecated + public EntityDamageEvent(final Entity damagee, final DamageCause cause, final double damage) { +- this(damagee, cause, new EnumMap(ImmutableMap.of(DamageModifier.BASE, damage))); ++ this(damagee, cause, new EnumMap(ImmutableMap.of(DamageModifier.BASE, damage)), new EnumMap>(ImmutableMap.of(DamageModifier.BASE, ZERO))); + } + +- public EntityDamageEvent(final Entity damagee, final DamageCause cause, final Map modifiers) { ++ public EntityDamageEvent(final Entity damagee, final DamageCause cause, final Map modifiers, final Map> modifierFunctions) { + super(damagee); + Validate.isTrue(modifiers.containsKey(DamageModifier.BASE), "BASE DamageModifier missing"); + Validate.isTrue(!modifiers.containsKey(null), "Cannot have null DamageModifier"); ++ Validate.noNullElements(modifiers.values(), "Cannot have null modifier values"); ++ Validate.isTrue(modifiers.keySet().equals(modifierFunctions.keySet()), "Must have a modifier function for each DamageModifier"); ++ Validate.noNullElements(modifierFunctions.values(), "Cannot have null modifier function"); + this.originals = new EnumMap(modifiers); + this.cause = cause; + this.modifiers = modifiers; ++ this.modifierFunctions = modifierFunctions; + } + + public boolean isCancelled() { +@@ -149,11 +157,39 @@ + } + + /** +- * Sets the raw amount of damage caused by the event ++ * Sets the raw amount of damage caused by the event. ++ *

++ * For compatibility this also recalculates the modifiers and scales ++ * them by the difference between the modifier for the previous damage ++ * value and the new one. + * + * @param damage The raw amount of damage caused by the event + */ + public void setDamage(double damage) { ++ // These have to happen in the same order as the server calculates them, keep the enum sorted ++ double remaining = damage; ++ double oldRemaining = getDamage(DamageModifier.BASE); ++ for (DamageModifier modifier : MODIFIERS) { ++ if (!isApplicable(modifier)) { ++ continue; ++ } ++ ++ Function modifierFunction = modifierFunctions.get(modifier); ++ double newVanilla = modifierFunction.apply(remaining); ++ double oldVanilla = modifierFunction.apply(oldRemaining); ++ double difference = oldVanilla - newVanilla; ++ ++ // Don't allow value to cross zero, assume zero values should be negative ++ double old = getDamage(modifier); ++ if (old > 0) { ++ setDamage(modifier, Math.max(0, old - difference)); ++ } else { ++ setDamage(modifier, Math.min(0, old - difference)); ++ } ++ remaining += newVanilla; ++ oldRemaining += oldVanilla; ++ } ++ + setDamage(DamageModifier.BASE, damage); + } + diff --git a/patches/org/bukkit/event/player/PlayerLoginEvent.java.patch b/patches/org/bukkit/event/player/PlayerLoginEvent.java.patch new file mode 100644 index 0000000..45e002a --- /dev/null +++ b/patches/org/bukkit/event/player/PlayerLoginEvent.java.patch @@ -0,0 +1,66 @@ +--- ../src-base/minecraft/org/bukkit/event/player/PlayerLoginEvent.java ++++ ../src-work/minecraft/org/bukkit/event/player/PlayerLoginEvent.java +@@ -14,6 +14,7 @@ + private final String hostname; + private Result result = Result.ALLOWED; + private String message = ""; ++ private final InetAddress realAddress; // Spigot + + /** + * @deprecated Address should be provided in other constructor +@@ -40,19 +41,26 @@ + * @param address The address the player used to connect, provided for + * timing issues + */ +- public PlayerLoginEvent(final Player player, final String hostname, final InetAddress address) { ++ public PlayerLoginEvent(final Player player, final String hostname, final InetAddress address, final InetAddress realAddress) { // Spigot + super(player); + this.hostname = hostname; + this.address = address; ++ // Spigot start ++ this.realAddress = address; + } + ++ public PlayerLoginEvent(final Player player, final String hostname, final InetAddress address) { ++ this(player, hostname, address, address); ++ // Spigot end ++ } ++ + /** + * @deprecated Address and hostname should be provided in other + * constructor + */ + @Deprecated + public PlayerLoginEvent(final Player player, final Result result, final String message) { +- this(player, "", null, result, message); ++ this(player, "", null, result, message, null); // Spigot + } + + /** +@@ -65,13 +73,24 @@ + * @param result The result status for this event + * @param message The message to be displayed if result denies login + */ +- public PlayerLoginEvent(final Player player, String hostname, final InetAddress address, final Result result, final String message) { +- this(player, hostname, address); ++ public PlayerLoginEvent(final Player player, String hostname, final InetAddress address, final Result result, final String message, final InetAddress realAddress) { // Spigot ++ this(player, hostname, address, realAddress); // Spigot + this.result = result; + this.message = message; + } + ++ // Spigot start + /** ++ * Gets the connection address of this player, regardless of whether it has been spoofed or not. ++ * ++ * @return the player's connection address ++ */ ++ public InetAddress getRealAddress() { ++ return realAddress; ++ } ++ // Spigot end ++ ++ /** + * Gets the current result of the login, as an enum + * + * @return Current Result of the login diff --git a/patches/org/bukkit/event/player/PlayerTeleportEvent.java.patch b/patches/org/bukkit/event/player/PlayerTeleportEvent.java.patch new file mode 100644 index 0000000..be76ae5 --- /dev/null +++ b/patches/org/bukkit/event/player/PlayerTeleportEvent.java.patch @@ -0,0 +1,17 @@ +--- ../src-base/minecraft/org/bukkit/event/player/PlayerTeleportEvent.java ++++ ../src-work/minecraft/org/bukkit/event/player/PlayerTeleportEvent.java +@@ -55,7 +55,14 @@ + * portal + */ + END_PORTAL, ++ // Cauldron start - added cause for mods + /** ++ * Indicates the teleportation was caused by a player entering a ++ * Mod portal ++ */ ++ MOD, ++ // Cauldron end ++ /** + * Indicates the teleportation was caused by an event not covered by + * this enum + */ diff --git a/patches/org/bukkit/plugin/SimplePluginManager.java.patch b/patches/org/bukkit/plugin/SimplePluginManager.java.patch new file mode 100644 index 0000000..e64bc92 --- /dev/null +++ b/patches/org/bukkit/plugin/SimplePluginManager.java.patch @@ -0,0 +1,31 @@ +--- ../src-base/minecraft/org/bukkit/plugin/SimplePluginManager.java ++++ ../src-work/minecraft/org/bukkit/plugin/SimplePluginManager.java +@@ -132,7 +132,9 @@ + try { + description = loader.getPluginDescription(file); + String name = description.getName(); +- if (name.equalsIgnoreCase("bukkit") || name.equalsIgnoreCase("minecraft") || name.equalsIgnoreCase("mojang")) { ++ if (name.equalsIgnoreCase("bukkit") || name.equalsIgnoreCase("minecraft") || name.equalsIgnoreCase("mojang") ++ // Cauldron - Add more restricted names ++ || name.equalsIgnoreCase("spigot") || name.equalsIgnoreCase("forge") || name.equalsIgnoreCase("cauldron") || name.equalsIgnoreCase("mcpc")) { + server.getLogger().log(Level.SEVERE, "Could not load '" + file.getPath() + "' in folder '" + directory.getPath() + "': Restricted Name"); + continue; + } else if (description.rawName.indexOf(' ') != -1) { +@@ -188,6 +190,9 @@ + } + } + ++ // Cauldron - fill names for Cauldron-provided dependencies ++ loadedPlugins.addAll(ImmutableSet.of("Cauldron", "Forge", "MCPC", "MCPC+")); ++ + while (!plugins.isEmpty()) { + boolean missingDependency = true; + Iterator pluginIterator = plugins.keySet().iterator(); +@@ -295,6 +300,7 @@ + } + } + ++ org.bukkit.command.defaults.TimingsCommand.timingStart = System.nanoTime(); // Spigot + return result.toArray(new Plugin[result.size()]); + } + diff --git a/patches/org/bukkit/plugin/SimpleServicesManager.java.patch b/patches/org/bukkit/plugin/SimpleServicesManager.java.patch new file mode 100644 index 0000000..0c5733c --- /dev/null +++ b/patches/org/bukkit/plugin/SimpleServicesManager.java.patch @@ -0,0 +1,12 @@ +--- ../src-base/minecraft/org/bukkit/plugin/SimpleServicesManager.java ++++ ../src-work/minecraft/org/bukkit/plugin/SimpleServicesManager.java +@@ -79,7 +79,8 @@ + while (it2.hasNext()) { + RegisteredServiceProvider registered = it2.next(); + +- if (registered.getPlugin().equals(plugin)) { ++ Plugin oPlugin = registered.getPlugin(); ++ if (oPlugin != null ? oPlugin.equals(plugin) : plugin == null) { + it2.remove(); + unregisteredEvents.add(new ServiceUnregisterEvent(registered)); + } diff --git a/patches/org/bukkit/plugin/TimedRegisteredListener.java.patch b/patches/org/bukkit/plugin/TimedRegisteredListener.java.patch new file mode 100644 index 0000000..7d0a6c8 --- /dev/null +++ b/patches/org/bukkit/plugin/TimedRegisteredListener.java.patch @@ -0,0 +1,51 @@ +--- ../src-base/minecraft/org/bukkit/plugin/TimedRegisteredListener.java ++++ ../src-work/minecraft/org/bukkit/plugin/TimedRegisteredListener.java +@@ -11,6 +11,10 @@ + public class TimedRegisteredListener extends RegisteredListener { + private int count; + private long totalTime; ++ // Spigot start ++ public long curTickTotal = 0; ++ public long violations = 0; ++ // Spigot end + private Class eventClass; + private boolean multiple = false; + +@@ -20,6 +24,13 @@ + + @Override + public void callEvent(Event event) throws EventException { ++ // Spigot start ++ if ( org.bukkit.Bukkit.getServer() != null && !org.bukkit.Bukkit.getServer().getPluginManager().useTimings() ) ++ { ++ super.callEvent( event ); ++ return; ++ } ++ // Spigot end + if (event.isAsynchronous()) { + super.callEvent(event); + return; +@@ -34,7 +45,11 @@ + } + long start = System.nanoTime(); + super.callEvent(event); +- totalTime += System.nanoTime() - start; ++ // Spigot start ++ long diff = System.nanoTime() - start; ++ curTickTotal += diff; ++ totalTime += diff; ++ // Spigot end + } + + private static Class getCommonSuperclass(Class class1, Class class2) { +@@ -50,6 +65,10 @@ + public void reset() { + count = 0; + totalTime = 0; ++ // Spigot start ++ curTickTotal = 0; ++ violations = 0; ++ // Spigot end + } + + /** diff --git a/patches/org/bukkit/plugin/java/JavaPluginLoader.java.patch b/patches/org/bukkit/plugin/java/JavaPluginLoader.java.patch new file mode 100644 index 0000000..6acf7fe --- /dev/null +++ b/patches/org/bukkit/plugin/java/JavaPluginLoader.java.patch @@ -0,0 +1,233 @@ +--- ../src-base/minecraft/org/bukkit/plugin/java/JavaPluginLoader.java ++++ ../src-work/minecraft/org/bukkit/plugin/java/JavaPluginLoader.java +@@ -1,5 +1,15 @@ + package org.bukkit.plugin.java; + ++// Cauldron start ++import java.io.BufferedReader; ++import java.io.InputStreamReader; ++import com.google.common.collect.BiMap; ++import com.google.common.collect.HashBiMap; ++import net.md_5.specialsource.InheritanceMap; ++import net.md_5.specialsource.JarMapping; ++import net.md_5.specialsource.transformer.MavenShade; ++// Cauldron end ++ + import java.io.File; + import java.io.FileNotFoundException; + import java.io.IOException; +@@ -10,6 +20,7 @@ + import java.util.HashMap; + import java.util.HashSet; + import java.util.LinkedHashMap; ++import java.util.List; + import java.util.Map; + import java.util.Set; + import java.util.jar.JarEntry; +@@ -39,8 +50,11 @@ + import org.bukkit.plugin.RegisteredListener; + import org.bukkit.plugin.TimedRegisteredListener; + import org.bukkit.plugin.UnknownDependencyException; ++import org.spigotmc.CustomTimingsHandler; // Spigot + import org.yaml.snakeyaml.error.YAMLException; + ++import com.google.common.collect.ImmutableList; ++ + /** + * Represents a Java plugin loader, allowing plugins in the form of .jar + */ +@@ -49,6 +63,7 @@ + private final Pattern[] fileFilters = new Pattern[] { Pattern.compile("\\.jar$"), }; + private final Map> classes = new HashMap>(); + private final Map loaders = new LinkedHashMap(); ++ public static final CustomTimingsHandler pluginParentTimer = new CustomTimingsHandler("** Plugins"); // Spigot + + /** + * This class was not meant to be constructed explicitly +@@ -59,43 +74,41 @@ + server = instance; + } + +- public Plugin loadPlugin(final File file) throws InvalidPluginException { ++ public Plugin loadPlugin(File file) throws InvalidPluginException { + Validate.notNull(file, "File cannot be null"); + + if (!file.exists()) { + throw new InvalidPluginException(new FileNotFoundException(file.getPath() + " does not exist")); + } + +- final PluginDescriptionFile description; ++ PluginDescriptionFile description; + try { + description = getPluginDescription(file); + } catch (InvalidDescriptionException ex) { + throw new InvalidPluginException(ex); + } + +- final File parentFile = file.getParentFile(); +- final File dataFolder = new File(parentFile, description.getName()); +- @SuppressWarnings("deprecation") +- final File oldDataFolder = new File(parentFile, description.getRawName()); ++ File dataFolder = new File(file.getParentFile(), description.getName()); ++ File oldDataFolder = getDataFolder(file); + + // Found old data folder + if (dataFolder.equals(oldDataFolder)) { + // They are equal -- nothing needs to be done! + } else if (dataFolder.isDirectory() && oldDataFolder.isDirectory()) { +- server.getLogger().warning(String.format( +- "While loading %s (%s) found old-data folder: `%s' next to the new one `%s'", +- description.getFullName(), ++ server.getLogger().log(Level.INFO, String.format( ++ "While loading %s (%s) found old-data folder: %s next to the new one: %s", ++ description.getName(), + file, + oldDataFolder, + dataFolder + )); + } else if (oldDataFolder.isDirectory() && !dataFolder.exists()) { + if (!oldDataFolder.renameTo(dataFolder)) { +- throw new InvalidPluginException("Unable to rename old data folder: `" + oldDataFolder + "' to: `" + dataFolder + "'"); ++ throw new InvalidPluginException("Unable to rename old data folder: '" + oldDataFolder + "' to: '" + dataFolder + "'"); + } + server.getLogger().log(Level.INFO, String.format( +- "While loading %s (%s) renamed data folder: `%s' to `%s'", +- description.getFullName(), ++ "While loading %s (%s) renamed data folder: '%s' to '%s'", ++ description.getName(), + file, + oldDataFolder, + dataFolder +@@ -104,14 +117,19 @@ + + if (dataFolder.exists() && !dataFolder.isDirectory()) { + throw new InvalidPluginException(String.format( +- "Projected datafolder: `%s' for %s (%s) exists and is not a directory", ++ "Projected datafolder: '%s' for %s (%s) exists and is not a directory", + dataFolder, +- description.getFullName(), ++ description.getName(), + file + )); + } + +- for (final String pluginName : description.getDepend()) { ++ List depend = description.getDepend(); ++ if (depend == null) { ++ depend = ImmutableList.of(); ++ } ++ ++ for (String pluginName : depend) { + if (loaders == null) { + throw new UnknownDependencyException(pluginName); + } +@@ -122,7 +140,7 @@ + } + } + +- final PluginClassLoader loader; ++ PluginClassLoader loader; + try { + loader = new PluginClassLoader(this, getClass().getClassLoader(), description, dataFolder, file); + } catch (InvalidPluginException ex) { +@@ -136,6 +154,26 @@ + return loader.plugin; + } + ++ private File getDataFolder(File file) { ++ File dataFolder = null; ++ ++ String filename = file.getName(); ++ int index = file.getName().lastIndexOf("."); ++ ++ if (index != -1) { ++ String name = filename.substring(0, index); ++ ++ dataFolder = new File(file.getParentFile(), name); ++ } else { ++ // This is if there is no extension, which should not happen ++ // Using _ to prevent name collision ++ ++ dataFolder = new File(file.getParentFile(), filename + "_"); ++ } ++ ++ return dataFolder; ++ } ++ + public PluginDescriptionFile getPluginDescription(File file) throws InvalidDescriptionException { + Validate.notNull(file, "File cannot be null"); + +@@ -283,13 +321,19 @@ + } + } + ++ final CustomTimingsHandler timings = new CustomTimingsHandler("Plugin: " + plugin.getDescription().getFullName() + " Event: " + listener.getClass().getName() + "::" + method.getName()+"("+eventClass.getSimpleName()+")", pluginParentTimer); // Spigot + EventExecutor executor = new EventExecutor() { + public void execute(Listener listener, Event event) throws EventException { + try { + if (!eventClass.isAssignableFrom(event.getClass())) { + return; + } ++ // Spigot start ++ boolean isAsync = event.isAsynchronous(); ++ if (!isAsync) timings.startTiming(); + method.invoke(listener, event); ++ if (!isAsync) timings.stopTiming(); ++ // Spigot end + } catch (InvocationTargetException ex) { + throw new EventException(ex.getCause()); + } catch (Throwable t) { +@@ -297,7 +341,7 @@ + } + } + }; +- if (useTimings) { ++ if (false) { // Spigot - RL handles useTimings check now + eventSet.add(new TimedRegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled())); + } else { + eventSet.add(new RegisteredListener(listener, executor, eh.priority(), plugin, eh.ignoreCancelled())); +@@ -362,4 +406,44 @@ + } + } + } ++ ++ // Cauldron start ++ private InheritanceMap globalInheritanceMap = null; ++ ++ /** ++ * Get the inheritance map for remapping all plugins ++ */ ++ public InheritanceMap getGlobalInheritanceMap() { ++ if (globalInheritanceMap == null) { ++ Map relocationsCurrent = new HashMap(); ++ relocationsCurrent.put("net.minecraft.server", "net.minecraft.server."+PluginClassLoader.getNativeVersion()); ++ JarMapping currentMappings = new JarMapping(); ++ ++ try { ++ currentMappings.loadMappings( ++ new BufferedReader(new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream("mappings/"+PluginClassLoader.getNativeVersion()+"/cb2numpkg.srg"))), ++ new MavenShade(relocationsCurrent), ++ null, false); ++ } catch (IOException ex) { ++ ex.printStackTrace(); ++ throw new RuntimeException(ex); ++ } ++ ++ BiMap inverseClassMap = HashBiMap.create(currentMappings.classes).inverse(); ++ globalInheritanceMap = new InheritanceMap(); ++ ++ BufferedReader reader = new BufferedReader(new InputStreamReader(this.getClass().getClassLoader().getResourceAsStream("mappings/"+PluginClassLoader.getNativeVersion()+"/nms.inheritmap"))); ++ ++ try { ++ globalInheritanceMap.load(reader, inverseClassMap); ++ } catch (IOException ex) { ++ ex.printStackTrace(); ++ throw new RuntimeException(ex); ++ } ++ System.out.println("Loaded inheritance map of "+globalInheritanceMap.size()+" classes"); ++ } ++ ++ return globalInheritanceMap; ++ } ++ // Cauldron end + } diff --git a/patches/org/bukkit/plugin/java/PluginClassLoader.java.patch b/patches/org/bukkit/plugin/java/PluginClassLoader.java.patch new file mode 100644 index 0000000..cb028a5 --- /dev/null +++ b/patches/org/bukkit/plugin/java/PluginClassLoader.java.patch @@ -0,0 +1,486 @@ +--- ../src-base/minecraft/org/bukkit/plugin/java/PluginClassLoader.java ++++ ../src-work/minecraft/org/bukkit/plugin/java/PluginClassLoader.java +@@ -1,5 +1,23 @@ + package org.bukkit.plugin.java; + ++// Cauldron start ++import net.md_5.specialsource.provider.ClassLoaderProvider; ++import net.md_5.specialsource.transformer.MavenShade; ++//import org.bouncycastle.util.io.Streams; ++import net.md_5.specialsource.*; ++import net.md_5.specialsource.repo.*; ++import net.minecraft.server.MinecraftServer; ++import net.minecraftforge.cauldron.configuration.CauldronConfig; ++import net.minecraftforge.cauldron.CauldronUtils; ++ ++import org.bukkit.plugin.PluginDescriptionFile; ++import java.io.*; ++import java.net.JarURLConnection; ++import java.security.CodeSigner; ++import java.security.CodeSource; ++import java.util.concurrent.*; ++// Cauldron end ++ + import java.io.File; + import java.net.MalformedURLException; + import java.net.URL; +@@ -15,16 +33,40 @@ + /** + * A ClassLoader for plugins, to allow shared classes across multiple plugins + */ +-final class PluginClassLoader extends URLClassLoader { ++public class PluginClassLoader extends URLClassLoader { + private final JavaPluginLoader loader; +- private final Map> classes = new HashMap>(); ++ private final ConcurrentMap> classes = new ConcurrentHashMap>(); // Cauldron - Threadsafe classloading + private final PluginDescriptionFile description; + private final File dataFolder; + private final File file; +- final JavaPlugin plugin; ++ JavaPlugin plugin; // Cauldron - remove final + private JavaPlugin pluginInit; + private IllegalStateException pluginState; ++ // Cauldron start ++ private JarRemapper remapper; // class remapper for this plugin, or null ++ private RemapperProcessor remapperProcessor; // secondary; for inheritance & remapping reflection ++ private boolean debug; // classloader debugging ++ private int remapFlags = -1; + ++ private static ConcurrentMap jarMappings = new ConcurrentHashMap(); ++ private static final int F_GLOBAL_INHERIT = 1 << 1; ++ private static final int F_REMAP_OBCPRE = 1 << 2; ++ private static final int F_REMAP_NMS152 = 1 << 3; ++ private static final int F_REMAP_NMS164 = 1 << 4; ++ private static final int F_REMAP_NMS172 = 1 << 5; ++ private static final int F_REMAP_NMS179 = 1 << 6; ++ private static final int F_REMAP_NMS1710 = 1 << 7; ++ private static final int F_REMAP_OBC152 = 1 << 8; ++ private static final int F_REMAP_OBC164 = 1 << 9; ++ private static final int F_REMAP_OBC172 = 1 << 10; ++ private static final int F_REMAP_OBC179 = 1 << 11; ++ private static final int F_REMAP_OBC1710 = 1 << 12; ++ private static final int F_REMAP_NMSPRE_MASK= 0xffff0000; // "unversioned" NMS plugin version ++ ++ // This trick bypasses Maven Shade's package rewriting when using String literals [same trick in jline] ++ private static final String org_bukkit_craftbukkit = new String(new char[] {'o','r','g','/','b','u','k','k','i','t','/','c','r','a','f','t','b','u','k','k','i','t'}); ++ // Cauldron end ++ + PluginClassLoader(final JavaPluginLoader loader, final ClassLoader parent, final PluginDescriptionFile description, final File dataFolder, final File file) throws InvalidPluginException, MalformedURLException { + super(new URL[] {file.toURI().toURL()}, parent); + Validate.notNull(loader, "Loader cannot be null"); +@@ -34,6 +76,113 @@ + this.dataFolder = dataFolder; + this.file = file; + ++ // Cauldron start ++ ++ String pluginName = this.description.getName(); ++ ++ // configure default remapper settings ++ boolean useCustomClassLoader = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.custom-class-loader", true); ++ debug = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.debug", false); ++ boolean remapNMS1710 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-nms-v1_7_R4", true); ++ boolean remapNMS179 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-nms-v1_7_R3", true); ++ boolean remapNMS172 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-nms-v1_7_R1", true); ++ boolean remapNMS164 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-nms-v1_6_R3", true); ++ boolean remapNMS152 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-nms-v1_5_R3", true); ++ String remapNMSPre = MinecraftServer.getServer().cauldronConfig.getString("plugin-settings.default.remap-nms-pre", "false"); ++ boolean remapOBC1710 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-obc-v1_7_R4", true); ++ boolean remapOBC179 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-obc-v1_7_R3", true); ++ boolean remapOBC172 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-obc-v1_7_R1", true); ++ boolean remapOBC164 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-obc-v1_6_R3", true); ++ boolean remapOBC152 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-obc-v1_5_R3", true); ++ boolean remapOBCPre = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-obc-pre", false); ++ boolean globalInherit = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.global-inheritance", true); ++ boolean pluginInherit = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.plugin-inheritance", true); ++ boolean reflectFields = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-reflect-field", true); ++ boolean reflectClass = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-reflect-class", true); ++ boolean allowFuture = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings.default.remap-allow-future", false); ++ ++ // plugin-specific overrides ++ useCustomClassLoader = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".custom-class-loader", useCustomClassLoader, false); ++ debug = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".debug", debug, false); ++ remapNMS1710 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-nms-v1_7_R4", remapNMS1710, false); ++ remapNMS179 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-nms-v1_7_R3", remapNMS179, false); ++ remapNMS172 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-nms-v1_7_R1", remapNMS172, false); ++ remapNMS164 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-nms-v1_6_R3", remapNMS164, false); ++ remapNMS152 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-nms-v1_5_R3", remapNMS152, false); ++ remapNMSPre = MinecraftServer.getServer().cauldronConfig.getString("plugin-settings."+pluginName+".remap-nms-pre", remapNMSPre, false); ++ remapOBC1710 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-obc-v1_7_R4", remapOBC1710, false); ++ remapOBC179 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-obc-v1_7_R3", remapOBC179, false); ++ remapOBC172 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-obc-v1_7_R1", remapOBC172, false); ++ remapOBC164 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-obc-v1_6_R3", remapOBC164, false); ++ remapOBC152 = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-obc-v1_5_R3", remapOBC152, false); ++ remapOBCPre = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-obc-pre", remapOBCPre, false); ++ globalInherit = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".global-inheritance", globalInherit, false); ++ pluginInherit = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".plugin-inheritance", pluginInherit, false); ++ reflectFields = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-reflect-field", reflectFields, false); ++ reflectClass = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-reflect-class", reflectClass, false); ++ allowFuture = MinecraftServer.getServer().cauldronConfig.getBoolean("plugin-settings."+pluginName+".remap-allow-future", allowFuture, false); ++ ++ if (debug) { ++ System.out.println("PluginClassLoader debugging enabled for "+pluginName); ++ } ++ ++ if (!useCustomClassLoader) { ++ remapper = null; ++ return; ++ } ++ ++ int flags = 0; ++ if (remapNMS1710) flags |= F_REMAP_NMS1710; ++ if (remapNMS179) flags |= F_REMAP_NMS179; ++ if (remapNMS172) flags |= F_REMAP_NMS172; ++ if (remapNMS164) flags |= F_REMAP_NMS164; ++ if (remapNMS152) flags |= F_REMAP_NMS152; ++ if (!remapNMSPre.equals("false")) { ++ if (remapNMSPre.equals("1.7.10")) flags |= 0x17100000; ++ else if (remapNMSPre.equals("1.7.9")) flags |= 0x01790000; ++ else if (remapNMSPre.equals("1.7.2")) flags |= 0x01720000; ++ else if (remapNMSPre.equals("1.6.4")) flags |= 0x01640000; ++ else if (remapNMSPre.equals("1.5.2")) flags |= 0x01520000; ++ else { ++ System.out.println("Unsupported nms-remap-pre version '"+remapNMSPre+"', disabling"); ++ } ++ } ++ if (remapOBC1710) flags |= F_REMAP_OBC1710; ++ if (remapOBC179) flags |= F_REMAP_OBC179; ++ if (remapOBC172) flags |= F_REMAP_OBC172; ++ if (remapOBC164) flags |= F_REMAP_OBC164; ++ if (remapOBC152) flags |= F_REMAP_OBC152; ++ if (remapOBCPre) flags |= F_REMAP_OBCPRE; ++ if (globalInherit) flags |= F_GLOBAL_INHERIT; ++ ++ remapFlags = flags; // used in findClass0 ++ JarMapping jarMapping = getJarMapping(flags); ++ ++ // Load inheritance map ++ if ((flags & F_GLOBAL_INHERIT) != 0) { ++ if (debug) { ++ System.out.println("Enabling global inheritance remapping"); ++ //ClassLoaderProvider.verbose = debug; // TODO: changed in https://github.com/md-5/SpecialSource/commit/132584eda4f0860c9d14f4c142e684a027a128b8#L3L48 ++ } ++ jarMapping.setInheritanceMap(loader.getGlobalInheritanceMap()); ++ jarMapping.setFallbackInheritanceProvider(new ClassLoaderProvider(this)); ++ } ++ ++ remapper = new JarRemapper(jarMapping); ++ ++ if (pluginInherit || reflectFields || reflectClass) { ++ remapperProcessor = new RemapperProcessor( ++ pluginInherit ? loader.getGlobalInheritanceMap() : null, ++ (reflectFields || reflectClass) ? jarMapping : null); ++ ++ remapperProcessor.setRemapReflectField(reflectFields); ++ remapperProcessor.setRemapReflectClass(reflectClass); ++ remapperProcessor.debug = debug; ++ } else { ++ remapperProcessor = null; ++ } ++ // Cauldron end ++ + try { + Class jarClass; + try { +@@ -58,34 +207,290 @@ + } + + @Override +- protected Class findClass(String name) throws ClassNotFoundException { ++ public Class findClass(String name) throws ClassNotFoundException { // Cauldron - public access for plugins to support CB NMS -> MCP class remap + return findClass(name, true); + } + +- Class findClass(String name, boolean checkGlobal) throws ClassNotFoundException { +- if (name.startsWith("org.bukkit.") || name.startsWith("net.minecraft.")) { +- throw new ClassNotFoundException(name); ++ // Cauldron start ++ /** ++ * Get the "native" obfuscation version, from our Maven shading version. ++ */ ++ public static String getNativeVersion() { ++ // see https://github.com/mbax/VanishNoPacket/blob/master/src/main/java/org/kitteh/vanish/compat/NMSManager.java ++ if (CauldronUtils.deobfuscatedEnvironment()) return "v1_7_R4"; // support plugins in deobf environment ++ final String packageName = org.bukkit.craftbukkit.CraftServer.class.getPackage().getName(); ++ return packageName.substring(packageName.lastIndexOf('.') + 1); ++ } ++ ++ /** ++ * Load NMS mappings from CraftBukkit mc-dev to repackaged srgnames for FML runtime deobf ++ * ++ * @param jarMapping An existing JarMappings instance to load into ++ * @param obfVersion CraftBukkit version with internal obfuscation counter identifier ++ * >=1.4.7 this is the major version + R#. v1_4_R1=1.4.7, v1_5_R1=1.5, v1_5_R2=1.5.1.. ++ * For older versions (including pre-safeguard) it is the full Minecraft version number ++ * @throws IOException ++ */ ++ private void loadNmsMappings(JarMapping jarMapping, String obfVersion) throws IOException { ++ Map relocations = new HashMap(); ++ // mc-dev jar to CB, apply version shading (aka plugin safeguard) ++ relocations.put("net.minecraft.server", "net.minecraft.server." + obfVersion); ++ ++ // support for running 1.7.10 plugins in Cauldron dev ++ if (CauldronUtils.deobfuscatedEnvironment() && obfVersion.equals("v1_7_R4")) ++ { ++ jarMapping.loadMappings( ++ new BufferedReader(new InputStreamReader(loader.getClass().getClassLoader().getResourceAsStream("mappings/"+obfVersion+"/cb2pkgmcp.srg"))), ++ new MavenShade(relocations), ++ null, false); ++ ++ jarMapping.loadMappings( ++ new BufferedReader(new InputStreamReader(loader.getClass().getClassLoader().getResourceAsStream("mappings/"+obfVersion+"/obf2pkgmcp.srg"))), ++ null, // no version relocation for obf ++ null, false); ++ // resolve naming conflict in FML/CB ++ jarMapping.methods.put("net/minecraft/server/"+obfVersion+"/PlayerConnection/getPlayer ()Lorg/bukkit/craftbukkit/entity/CraftPlayer;", "getPlayerB"); + } +- Class result = classes.get(name); ++ else ++ { ++ jarMapping.loadMappings( ++ new BufferedReader(new InputStreamReader(loader.getClass().getClassLoader().getResourceAsStream("mappings/"+obfVersion+"/cb2numpkg.srg"))), ++ new MavenShade(relocations), ++ null, false); + +- if (result == null) { +- if (checkGlobal) { +- result = loader.getClassByName(name); ++ if (obfVersion.equals("v1_7_R4")) { ++ jarMapping.loadMappings( ++ new BufferedReader(new InputStreamReader(loader.getClass().getClassLoader().getResourceAsStream("mappings/"+obfVersion+"/obf2numpkg.srg"))), ++ null, // no version relocation for obf ++ null, false); + } + ++ // resolve naming conflict in FML/CB ++ jarMapping.methods.put("net/minecraft/server/"+obfVersion+"/PlayerConnection/getPlayer ()Lorg/bukkit/craftbukkit/"+getNativeVersion()+"/entity/CraftPlayer;", "getPlayerB"); ++ } ++ // remap bouncycastle to Forge's included copy, not the vanilla obfuscated copy (not in Cauldron), see #133 ++ //jarMapping.packages.put("net/minecraft/"+obfVersion+"/org/bouncycastle", "org/bouncycastle"); No longer needed ++ } ++ ++ private JarMapping getJarMapping(int flags) { ++ JarMapping jarMapping = jarMappings.get(flags); ++ ++ if (jarMapping != null) { ++ if (debug) { ++ System.out.println("Mapping reused for "+Integer.toHexString(flags)); ++ } ++ return jarMapping; ++ } ++ ++ jarMapping = new JarMapping(); ++ try { ++ ++ // Guava 10 is part of the Bukkit API, so plugins can use it, but FML includes Guava 15 ++ // To resolve this conflict, remap plugin usages to Guava 10 in a separate package ++ // Most plugins should keep this enabled, unless they want a newer Guava ++ jarMapping.packages.put("com/google/common", "guava10/com/google/common"); ++ jarMapping.packages.put(org_bukkit_craftbukkit + "/libs/com/google/gson", "com/google/gson"); // Handle Gson being in a "normal" place ++ // Bukkit moves these packages to nms while we keep them in root so we must relocate them for plugins that rely on them ++ jarMapping.packages.put("net/minecraft/util/io", "io"); ++ jarMapping.packages.put("net/minecraft/util/com", "com"); ++ jarMapping.packages.put("net/minecraft/util/gnu", "gnu"); ++ jarMapping.packages.put("net/minecraft/util/org", "org"); ++ ++ if ((flags & F_REMAP_NMS1710) != 0) { ++ loadNmsMappings(jarMapping, "v1_7_R4"); ++ } ++ ++ if ((flags & F_REMAP_NMS179) != 0) { ++ loadNmsMappings(jarMapping, "v1_7_R3"); ++ } ++ ++ if ((flags & F_REMAP_NMS172) != 0) { ++ loadNmsMappings(jarMapping, "v1_7_R1"); ++ } ++ ++ if ((flags & F_REMAP_NMS164) != 0) { ++ loadNmsMappings(jarMapping, "v1_6_R3"); ++ } ++ ++ if ((flags & F_REMAP_NMS152) != 0) { ++ loadNmsMappings(jarMapping, "v1_5_R3"); ++ } ++ ++ if ((flags & F_REMAP_OBC1710) != 0) { ++ if (CauldronUtils.deobfuscatedEnvironment()) ++ jarMapping.packages.put(org_bukkit_craftbukkit+"/v1_7_R4", org_bukkit_craftbukkit); ++ else jarMapping.packages.put(org_bukkit_craftbukkit+"/v1_7_R4", org_bukkit_craftbukkit+"/"+getNativeVersion()); ++ } ++ ++ if ((flags & F_REMAP_OBC179) != 0) { ++ if (CauldronUtils.deobfuscatedEnvironment()) ++ jarMapping.packages.put(org_bukkit_craftbukkit+"/v1_7_R3", org_bukkit_craftbukkit); ++ else jarMapping.packages.put(org_bukkit_craftbukkit+"/v1_7_R3", org_bukkit_craftbukkit+"/"+getNativeVersion()); ++ } ++ ++ if ((flags & F_REMAP_OBC172) != 0) { ++ if (CauldronUtils.deobfuscatedEnvironment()) ++ jarMapping.packages.put(org_bukkit_craftbukkit+"/v1_7_R1", org_bukkit_craftbukkit+"/"+getNativeVersion()); ++ else jarMapping.packages.put(org_bukkit_craftbukkit+"/v1_7_R1", org_bukkit_craftbukkit+"/"+getNativeVersion()); ++ } ++ ++ if ((flags & F_REMAP_OBC164) != 0) { ++ jarMapping.packages.put(org_bukkit_craftbukkit+"/v1_6_R3", org_bukkit_craftbukkit+"/"+getNativeVersion()); ++ } ++ ++ if ((flags & F_REMAP_OBC152) != 0) { ++ jarMapping.packages.put(org_bukkit_craftbukkit+"/v1_5_R3", org_bukkit_craftbukkit+"/"+getNativeVersion()); ++ } ++ ++ if ((flags & F_REMAP_OBCPRE) != 0) { ++ // enabling unversioned obc not currently compatible with versioned obc plugins (overmapped) - ++ // admins should enable remap-obc-pre on a per-plugin basis, as needed ++ // then map unversioned to current version ++ jarMapping.packages.put(org_bukkit_craftbukkit+"/libs/org/objectweb/asm", "org/objectweb/asm"); // ? ++ jarMapping.packages.put(org_bukkit_craftbukkit, org_bukkit_craftbukkit+"/"+getNativeVersion()); ++ } ++ ++ if ((flags & F_REMAP_NMSPRE_MASK) != 0) { ++ String obfVersion; ++ switch (flags & F_REMAP_NMSPRE_MASK) ++ { ++ case 0x17100000: obfVersion = "v1_7_R4"; break; ++ case 0x01790000: obfVersion = "v1_7_R3"; break; ++ case 0x01720000: obfVersion = "v1_7_R1"; break; ++ case 0x01640000: obfVersion = "v1_6_R3"; break; ++ case 0x01510000: obfVersion = "v1_5_R2"; break; ++ default: throw new IllegalArgumentException("Invalid unversioned mapping flags: "+Integer.toHexString(flags & F_REMAP_NMSPRE_MASK)+" in "+Integer.toHexString(flags)); ++ } ++ ++ jarMapping.loadMappings( ++ new BufferedReader(new InputStreamReader(loader.getClass().getClassLoader().getResourceAsStream("mappings/" + obfVersion + "/cb2numpkg.srg"))), ++ null, // no version relocation! ++ null, false); ++ } ++ ++ System.out.println("Mapping loaded "+jarMapping.packages.size()+" packages, "+jarMapping.classes.size()+" classes, "+jarMapping.fields.size()+" fields, "+jarMapping.methods.size()+" methods, flags "+Integer.toHexString(flags)); ++ ++ JarMapping currentJarMapping = jarMappings.putIfAbsent(flags, jarMapping); ++ return currentJarMapping == null ? jarMapping : currentJarMapping; ++ } catch (IOException ex) { ++ ex.printStackTrace(); ++ throw new RuntimeException(ex); ++ } ++ } ++ ++ Class findClass(String name, boolean checkGlobal) throws ClassNotFoundException { ++ // Cauldron start - remap any calls for classes with packaged nms version ++ if (name.startsWith("net.minecraft.")) ++ { ++ JarMapping jarMapping = this.getJarMapping(remapFlags); // grab from SpecialSource ++ String remappedClass = jarMapping.classes.get(name.replaceAll("\\.", "\\/")); // get remapped pkgmcp class name ++ Class clazz = ((net.minecraft.launchwrapper.LaunchClassLoader)MinecraftServer.getServer().getClass().getClassLoader()).findClass(remappedClass); ++ return clazz; ++ } ++ if (name.startsWith("org.bukkit.")) { ++ if (debug) { ++ System.out.println("Unexpected plugin findClass on OBC/NMS: name="+name+", checkGlobal="+checkGlobal+"; returning not found"); ++ } ++ throw new ClassNotFoundException(name); ++ } ++ // custom loader, if enabled, threadsafety ++ synchronized (name.intern()) { ++ Class result = classes.get(name); ++ + if (result == null) { +- result = super.findClass(name); ++ if (checkGlobal) { ++ result = loader.getClassByName(name); // Don't warn on deprecation, but maintain overridability ++ } + ++ if (result == null) { ++ if (remapper == null) { ++ result = super.findClass(name); ++ } else { ++ result = remappedFindClass(name); ++ } ++ ++ if (result != null) { ++ loader.setClass(name, result); ++ } ++ } + if (result != null) { +- loader.setClass(name, result); ++ Class old = classes.putIfAbsent(name, result); ++ if (old != null && old != result) { ++ System.err.println("Defined class " + name + " twice as different classes, " + result + " and " + old); ++ result = old; ++ } + } + } + +- classes.put(name, result); ++ return result; + } ++ // Cauldron end ++ } ++ private Class remappedFindClass(String name) throws ClassNotFoundException { ++ Class result = null; + ++ try { ++ // Load the resource to the name ++ String path = name.replace('.', '/').concat(".class"); ++ URL url = this.findResource(path); ++ if (url != null) { ++ InputStream stream = url.openStream(); ++ if (stream != null) { ++ byte[] bytecode = null; ++ ++ // Reflection remap and inheritance extract ++ if (remapperProcessor != null) { ++ // add to inheritance map ++ bytecode = remapperProcessor.process(stream); ++ if (bytecode == null) stream = url.openStream(); ++ } ++ ++ /*if (bytecode == null) { ++ bytecode = Streams.readAll(stream); ++ }*/ ++ ++ // Remap the classes ++ byte[] remappedBytecode = remapper.remapClassFile(bytecode, RuntimeRepo.getInstance()); ++ ++ if (debug) { ++ File file = new File("remapped-plugin-classes/"+name+".class"); ++ file.getParentFile().mkdirs(); ++ try { ++ FileOutputStream fileOutputStream = new FileOutputStream(file); ++ fileOutputStream.write(remappedBytecode); ++ fileOutputStream.close(); ++ } catch (IOException ex) { ++ ex.printStackTrace(); ++ } ++ } ++ ++ // Define (create) the class using the modified byte code ++ // The top-child class loader is used for this to prevent access violations ++ // Set the codesource to the jar, not within the jar, for compatibility with ++ // plugins that do new File(getClass().getProtectionDomain().getCodeSource().getLocation().toURI())) ++ // instead of using getResourceAsStream - see https://github.com/MinecraftPortCentral/Cauldron-Plus/issues/75 ++ JarURLConnection jarURLConnection = (JarURLConnection) url.openConnection(); // parses only ++ URL jarURL = jarURLConnection.getJarFileURL(); ++ CodeSource codeSource = new CodeSource(jarURL, new CodeSigner[0]); ++ ++ result = this.defineClass(name, remappedBytecode, 0, remappedBytecode.length, codeSource); ++ if (result != null) { ++ // Resolve it - sets the class loader of the class ++ this.resolveClass(result); ++ } ++ } ++ } ++ } catch (Throwable t) { ++ if (debug) { ++ System.out.println("remappedFindClass("+name+") exception: "+t); ++ t.printStackTrace(); ++ } ++ throw new ClassNotFoundException("Failed to remap class "+name, t); ++ } ++ + return result; + } ++ // Cauldron end + + Set getClasses() { + return classes.keySet(); diff --git a/patches/org/bukkit/plugin/messaging/Messenger.java.patch b/patches/org/bukkit/plugin/messaging/Messenger.java.patch new file mode 100644 index 0000000..5b70737 --- /dev/null +++ b/patches/org/bukkit/plugin/messaging/Messenger.java.patch @@ -0,0 +1,11 @@ +--- ../src-base/minecraft/org/bukkit/plugin/messaging/Messenger.java ++++ ../src-work/minecraft/org/bukkit/plugin/messaging/Messenger.java +@@ -18,7 +18,7 @@ + /** + * Represents the largest size that a Plugin Channel may be. + */ +- public static final int MAX_CHANNEL_SIZE = 16; ++ public static final int MAX_CHANNEL_SIZE = 20; // Cauldron - Vanilla increased limit of C17PacketCustomPayload size from 16 -> 20 in 1.7 + + /** + * Checks if the specified channel is a reserved name. diff --git a/patches/org/bukkit/plugin/messaging/StandardMessenger.java.patch b/patches/org/bukkit/plugin/messaging/StandardMessenger.java.patch new file mode 100644 index 0000000..c440163 --- /dev/null +++ b/patches/org/bukkit/plugin/messaging/StandardMessenger.java.patch @@ -0,0 +1,19 @@ +--- ../src-base/minecraft/org/bukkit/plugin/messaging/StandardMessenger.java ++++ ../src-work/minecraft/org/bukkit/plugin/messaging/StandardMessenger.java +@@ -421,7 +421,15 @@ + Set registrations = getIncomingChannelRegistrations(channel); + + for (PluginMessageListenerRegistration registration : registrations) { +- registration.getListener().onPluginMessageReceived(channel, source, message); ++ // Spigot Start ++ try ++ { ++ registration.getListener().onPluginMessageReceived( channel, source, message ); ++ } catch ( Throwable t ) ++ { ++ org.bukkit.Bukkit.getLogger().log( java.util.logging.Level.WARNING, "Could not pass incoming plugin message to " + registration.getPlugin(), t ); ++ } ++ // Spigot End + } + } + diff --git a/patches/org/bukkit/potion/PotionEffectType.java.patch b/patches/org/bukkit/potion/PotionEffectType.java.patch new file mode 100644 index 0000000..9a04c2c --- /dev/null +++ b/patches/org/bukkit/potion/PotionEffectType.java.patch @@ -0,0 +1,57 @@ +--- ../src-base/minecraft/org/bukkit/potion/PotionEffectType.java ++++ ../src-work/minecraft/org/bukkit/potion/PotionEffectType.java +@@ -202,7 +202,7 @@ + return "PotionEffectType[" + id + ", " + getName() + "]"; + } + +- private static final PotionEffectType[] byId = new PotionEffectType[24]; ++ private static final Map byId = new HashMap(); // Cauldron change underlying storage to map + private static final Map byName = new HashMap(); + // will break on updates. + private static boolean acceptingNew = true; +@@ -216,9 +216,9 @@ + */ + @Deprecated + public static PotionEffectType getById(int id) { +- if (id >= byId.length || id < 0) ++ if (id >= byId.size() || id < 0) // Cauldron + return null; +- return byId[id]; ++ return byId.get(id); // Cauldron + } + + /** +@@ -240,15 +240,18 @@ + * @param type PotionType to register + */ + public static void registerPotionEffectType(PotionEffectType type) { ++ // Cauldron start - allow vanilla to replace potions ++ /* + if (byId[type.id] != null || byName.containsKey(type.getName().toLowerCase())) { + throw new IllegalArgumentException("Cannot set already-set type"); + } else if (!acceptingNew) { + throw new IllegalStateException( + "No longer accepting new potion effect types (can only be done by the server implementation)"); + } +- +- byId[type.id] = type; ++ */ ++ byId.put(type.id, type); + byName.put(type.getName().toLowerCase(), type); ++ // Cauldron end + } + + /** +@@ -264,6 +267,11 @@ + * @return Array of types. + */ + public static PotionEffectType[] values() { +- return byId.clone(); ++ // Cauldron start ++ int maxId = 0; ++ for(int id : byId.keySet()) maxId = Math.max(maxId, id); ++ PotionEffectType[] result = new PotionEffectType[maxId + 1]; ++ return byId.values().toArray(result); // Cauldron change underlying storage to map ++ // Cauldron end + } + } diff --git a/settings.gradle b/settings.gradle new file mode 100644 index 0000000..b7ee386 --- /dev/null +++ b/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'cauldron' \ No newline at end of file diff --git a/src/main/guava10.zip b/src/main/guava10.zip new file mode 100644 index 0000000000000000000000000000000000000000..cbb0a4d255772cbbac4ce575d608ea583a72bcaa GIT binary patch literal 1563660 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%0AVYeOs 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

ag(05AON6A}Jmr z7H1rm8p2o2h8aWW zOUqhL^Xx6R3U?zoqS%}4s=UKcv-w~fMAMo52%JwH9jzD;D=|=5cS1`qMwV$#`Z$9q zNoO&r_CFXpPTv_{WWYvIUB_viC!Ygl>%4s9Qsin_(mh)U-!#>pmek#pVws69GTM?< zwlCoJ*LspW|G3l$HYtHAoXDA7W%P(&>xvzQR2O%vaCp!yDsl7>J~P)V2Mi3{82o3t zT0lUnW%9+Rq+hkV|AmLbzgg3TRO;^(nxnQd_q9*-gPSN4Q|HfMx0%o%9phNK!54`? zG89(N;iGUYC}A`VJN-PZ`D4}6PG@wgJHOmRoC}iY`ADFl`+M$A_{*j}x?Nser*9qN zbAdFY8sKQo(#JnM!{(T^S@(dH<{t2 zRa<1o0-O~@=$nKVeqg#uCbwhd@DF|Rq^0Jlq}@%t)D=YB^}2mH+Du9 zVG1+a*>d@zZ7!Dvq#D8*qK=39`__lf!(pBg^YF{FfM}&^juDTgFddL_8rZ%P#-uY~ z8G{7?I%I}(f^-WfTJkVx@^0BMh5PwAox>Y`1B($u1Gnc>;t^xytwVEGyEP}LvAjmF zF$B(##VXR-Md9E$JnAxhzFZeUB;4fIX3veyED1l1OIsjPvY4s$#^RrfiR#ne!oipp z*P&XdRmlTsjp0-`3SV)pYSxv#^Vc3^?w<*#;?|lW$+jtOr;?mP)vrC7-h8-?)JK%( zLKkp{Rhf$KnlrUXS*8h-rp{HsON*1-O;Uvo@w{|GvTtfFCFMA5M&WgIQRnq#A>b@X zee%+Y2ukT}0I^7WQi4vLh@{Q14dkDaxf@5H7}H&IE(9q8Sbf0oUbZPwz<~3v8naIY z3O*98%Ln-P_Z`X0;>Wvk5 z>yA2URf1-uCvfx$T-`wQqX0dU+QN8041 zUUVPV5jQB-dinupY>Dy}m?obX38hJObZfz>b}7X_Y(*k>ab9Y>!hUVeVx00R zy>F{j%~Z3|RV?{dsLV|xwgx$!ltKMTY{Z!Rm+uwl*_5 zvDLJ>cHpEsVT>s}!B0HFkJK=oKG>ZPGn1LUG**-2%WRpv(41sSN<7in{mDA-+qWg9Nnl8$y8rcW*@gTc^MW22eV*!)#^ z{ybOxDj@kPi(}bLI+HS*3P(FUhH7q<(z_Titn2ir zqTEIL!Uim6EWKi#!09a!U#1T_#`7_Iil>Ej8M-YtE~nTSK=Mt9eu! zX{#NO&*b$7(r;xKF74+^?K0*hHr4+GSz|s=Pt0MkJ_0k2_c%7982Dg74a!w&Fqi4sp)NHU zfv(?4>z9uYznA>RgZ2>PDyO$Lj{8IRt?Xv>=`z-9ptMRH`@Y_pWHM<2ZW6O`{zV3U zjpMAs)cYl|jZm+2QsZLwP-HNR^^|ozirdPXw#agA3|B?9~X0X%g8cBTMTI zd8R6Hk*^=U2h6c4VpJ!FOgA3ltmOD`B-FW6b`o!jX{xJDs&eW;z<7_t_9JkD=d|51 zY;V_*Kx>~c} zI*BPDl!(8Mpr`R`g%h$9C9UVaIV6L#NOasL!uj2#mNvtlZ z^+JF4syhqM^jp~fHIl&_qVw`AtAJm4k)HEh?6^>2lfj z=)3hi#n)oc1tYd7Rrg|KE z_tFhuy`VAzgf^Bpx}^!*ht9kGD}2=M-n2>1t>b0XIAXMm(1FwA{N?}3Cf7P`BC!Wz zlnlYYV>UYVp_yWte?nxrJHySR^x+&30p?mqa)YVhhFmi+sZC5OtEtm}CET~IVet2r zoQ*IVVb&w+r~68@et9Dt=|EyF*NsL9geq~^%{wqo%+3*(AoN+5#6@{&D)ySvsxpDH z+>RJB4Um3DoiMQuch@IgNLDA_*uG)F0LvaORcp0;@N&c-0MXh%M z^H|NAGfu3!s$7SVxlYeS3ln62y55YJ_eyT&%v@VpJ0N_Yz5Dp7v3Xy=z`x^KqfFlI zGUXxHp^#IS;*X5vb+X>6v=!9bNDr$a)D$?WIiiTEY{_LyHmiziWMICWUjl3r$Eq*) zCEiO&;GtsHo9+?4NKH(pr#YyV2#b@Ot4rGnd?2{Y$?QgV+kFGM-vS0qOv*X`P>%Zy z?N1P}c(A*Gq~Ca1`08iyw|vdogJ>&6Wfm;Ed*9i%+Kj!jTM{0v8|1W9zb~h6vfDW^ zW4ean_|#__DR$42+V-YcfUa>s7MggI<8e*u@gsISK7LypFM{Pg0<%}ZWhVoy*4yo{ z(_MJ=4>&9HW%$GFztW6_OI|)gAy%UsqnppaShnVd(8j7#W9#gnBuysJC2yH1wcVi0 z=+9e&3|nU7oEuUxjVKU_^M8zQ*6-*iKCH6liC-H&9tYg>-~18E9)(`j3rbo**QdnYtuh;Eh3NVLzKR z??qA^N+uA@wpvqeBdkEz!_pWec*U%wOpjzI9G{&~+{=>Uj*nK{=`qwu{}Q#`vE7?q z-BrOURFQ%xc0xA00)z2^N#PsteZVansgcw|dk&y8P@#PQ36p`27BIdYdR$gse?aIU z-nlmpIlQdB{4EKLUItUksTPRABAC-4V16|ZyD;$6&_2F&=&xVFgfF5T_S)3m=7QgsgOyQST)*b(K{{J%c{qJTMfERL_hC?N^=l!C z9e$MIYcd9c0|cf>&m!+^tHed>z(%!Om7l`0QBy7|+Z=g0Th?!HH$*}2#l|Z#kA0L) zchMB1QBOlqE`agsHpC$_?Wc_G+=PiHueDnZvoU2!EH0*Iui+F#gwe-D1Vfp4;A*2X zj!i2nV~~9**_)vEMb)Sa+@BlV!EXcWnXYD<7RxHKcpci-Os3H#sgY=!DZ{v5YW{Zz zhcy=-=3-{3B~B) zDQMpF1q>VXbka@_K3I~Y_P<;I*plYNUBTl{?}cV2;({|wiNtafHHNM!nWVv?NhpXH zZk}?M1n00jp$@C2SwPRs@n(~h?;a_PSC0>jP&}c_&-@5mhu2w;JkG_**S7Rzw*z}D z>HjGO39a!#<;#1kQ`btQ$Aosj)*nv>Ip+|SOVdT~5MYwN8MtVZ&MoY#=1PbN%s$^cUC;x}_9C-@FoSIXc4tSIS}6D^ z^U@tdE5y^D^dz*LH)H)!pYAPUj$*I%LMJfpE7Rb)Ij5`8h_=ZYQ#V zJjWJcAo^j5?&tbw#I#1R6E3thz9NSeQ9U|GoKM#33R#hvcRZq8%wrY_axN0)9vC`!aaH1Is0l?d z^1X&?>6PLgs>5u77yF$Cej~rR2hTTS*Ea6JDeMCTn;dWWrr@;m2&)});~rbDyx~IR zpyAlb7&%4ov5g9s*e3S?;?XCk7{s4{yXYY$RFZ1HM&BI24!h8Qb;DMx6Amx$EZaz+Cd3fGk3Iy`!BJMV#3Wx@fNZX>9ES74&ur`omM+=Md zv}OMg<Y{;#u&nRp`f^W90e{1=N6K_a zR=U75I$4>SMzk`Tvs^kDE525D5XID0$JF1;Y2~ms!Ee#A+(szac~BMd^ns6rU5kfy z+1(cWB&N;9b6CZE>_$ENult) zja%YV6}L}Y(LAIWnXf5vqW(^zMhW3AO3!>^`r-dT`PtZHGtQfsr&@A7OS+2QIXFFc zz5-p)Wfn65sf`*&%g&*=$M&pZk|lu?3Ypzy+Bn7J+ubc4PN%3j!yAWi;p{uO zcn9US?BNvO!TX7}Wt}_!#AiY;mq^txhK^Olf~`mEf{$o$;i5b&{hK{pEiTr2X4rOI zx7;giGNBG=CmfM3?l^S#KjXg5pz6Z<|6kznuO(pr0f%5qAz;3A{4Y2h{C~jVtqAUK zaCp4@%IzMnOMBXu-eP`uQj?4nyr~(r8 z^fCzoa_jH6dVeN@Me^1_hnq1Ca;XT7rGa&Q1^&WA%@-cvjh;{bg@>)b@F4&HiU))* zJox<&9*!kH30-0p+-t+6_k^>MZFQKRu6@PS}IA#{DY>brhN&m#LBQXrt#i4VBv60!Vp8!`vT@LJq z1%JfV+ZYgmTmPKX$0%?JR2M9$A1kI~l=QIy<_z9btGH#SqV|eh|7uZU7Ljb2d_P|n zO^)bV7n6~vzOiehN8x5`n3%3Z{{Vcj#iN>#rx)~K#<@f&xRYnPKUrliu7f(}JwMVS z&9e+;BfGlh&~gs5+z@HXx*VX^xjC^6C$rp@3nki>*7*RNpL^g8pNh_7%$E3;r<)j@5@vuJMtwR6y8?jnn-psA{9BD|auM$6VN z|Cf!kLF_cKHsSitG1X7EhrT`kaDU?y2{orQIt@;|@z&7~{5*ilk4bm%me#R*hnq>H ztoJVi#;>Gl>nOBI%Ut|Nq1xgx*v}C5VgBm_c1X8MjY-(!+Q*8Z%Udg#(nBa6U>pA6 zCE(0Ib+~VTo9cxTM{(@<{{y51cf43YTePuZVEM+L?Slr`bw@NwC-)#>;7?c)u6 zW&l(;IeGWzaaCB|X#Ze3X$t*B41z>q!j3!rFg3b5`gwd2AJ$s=jQ>su6hjT%l@i4S z-cjB;Q^ZUgh`3b!~G}jVoBlFGpk$ zX`U3Pa60Kj_vF0mgr4piXrW7Kg4rwnqUlJluO}Y;yQA0SVM<4^MkPr-VZt^hVQMiO z)bpw_%A*^mP_Py_UhUmjGHEPzlHtS})jJI=ofkoK&Oax_nFW;b1E`zSGH@$|>uTwo z6QyWwIp!sv6|#6rCrqC8)nYuj<>mTh-U!dDu~4+Lw8uO1q6!m+eqmd8l0W`_nkWSC z$BWBt(6%7pJ+Gc~n0T+CzNkNdDKo+6SlQZ}cZA_H?FiJ-J$PCA8cvgYaI+(VGyHKahHf@;Fr2+4oH_dEe9aoD~dr0DmlRt`o+eh@D zcZfVkL4x%cUEF--4g&u-A;mv&QKEL{Jg12GfzVQn1U{=C?NJ5e*=OB_Y*U9JM)E_- ziTT4(8Jh`#R33;`?4=>x z;Osu`dNsW(p@wVHcf;uv{`*h4;i(!dI+o8Fwxz1fS#}+kl%_QEsxB+UUQB*U1}fey z#y{TvD;KP02R+v?w_%AP2SJVeaAGWfUb12Wp+wA8Wr3Lhg9QFZT$m#63s0$m&>)x< zQ9BbOKr9U)yKrH%pnxQ&Ks^&+UDO0z*zKgi1x+9qkO$^Jl++4Q?Ju%Eo$V8hFNU^# zMdcBYnlxf!WQ+yH{4_PxFd>@NmO<1Ls?lSo^<#trcr;pnnr4sF=>X5N?zqLA2;19W z!kon0gd&ZLj<(pPT^WB;XDPP!IEi*J&3_;=1RQXQkg;r+H|vd8W7L~48n^OBv@SDh zSM|G7eej14UZ64~7mhHC+7?Nv6*q@oPmQM9H63A!Idhsa0K8Br$-H^&7`SvV#7;p7cQXSZ)wK z#mz=hpxLZ-!MY@?!Lo?GndN9LUS!>hz6JRU`gg^ec*kCnzr>=w?QPwAIQ@9$p3RM`k`N0cOAr8~t7SZ4u5;(&TJ%h*>1M+gfk z1me&qsJWNkS0BI$MCf`(h@b8gD=K}$KzG4acy7GxnV2q&;nW<k9 z3hzo-vGbkdvPllsFv@bNKc?R$8(8HVNYY8jjd~1|;@e2gE0#JjPmtYdBbTL+r4r?# z^t5fm4R1OT>~s zP=tZKAQYXkfHYKpamtvz(qrHvlNwlf7u0hfb~^|%;aCz%-)jfw32A%c4{}IssL=9F zGEYmk&*9X4S&hRMs3yFDpLH)pZ|4wrB~ml0~5pc4kJ z{aAZes32=2Lm8*^MXohR>Nb%QqXyjljx4bubrVzwh?|Y)nV^Hi7rC#YjI&au`pM4T zV)0?@Ur@!`Zq-EejQ1SfUd-x-#(eW?%2I?I6&3~};ex{oZ&0Q>?E3ZEUn99-3KCxe z29UgR0PX_F_!JtQfZ+ole4%i&o3;kEeg|22_n6Pjo$t6?-2DYI;_DicAJ{JVcwMl4 z5LLN2)QM0~v#Ph^Fx-T6K3>DuOy#~)gi&>G`gW4oc37%V*u83xC%D62PsV)x1}0XW z1C*=`+mgXca&M?X!)&dlVI^96E>df5@15#PnXeCtm;SIa?O87}Eruj}o{c1|Wg1-1 zbSFNgyZp(Bu^1$?rj$G`S+4X}Z2B=*IDL7G_As%lyWoI!kQ2#0%&B!obpKdHx9m8% zYMho##JPu71Gy=?>sV!0!FSG5-|}HRX0@p>W;fLojrwyWh4te3p1Tvs6{?<)=)T&NAaq0adv%vfYz(@F?2b50JSBs@PuNN*1za zDc7_b{t$gn^CAo)HlLp-Vqin}n+Opz;}!v-QJKsoKAMb6UopZ>?2fz9`b)#`D#PyP zR##L!7cl17W5YEz1QbV>9};hGB}0xapD=7xy@C=D{IgmOX%jBpNPfo^gu)5nk&7Sg z!tGsWAlyS(+f@MmCPreRG9I2|Y##hxFk#)XNf!Ql|E8w%O72bvZ5YZL|EHaA{Ml2` z4p<04Z_i&=Gjz02$6SSlSB9LM5R(7IAdExYA6J$(sis@I$<#a1RN+*BRbz!~nSf_C>1VmSQtkIc>pyrOS?7It?XY&EtQb)*noOFMKA%Ye%)e)Oa!_Yc;Q zkIdxQ)QxB4eD?+>aFw=}1%K>aTq(9;BWdYulWdd>jr8xM-MyU_>rFe%!zVk?hb+Nw zq{Pz?3>L8B(@DHPo%w+Or}gYYsPqoJ2@nwadodDeuCi} z(_`3x@e7{mWcY=+F^#Pb^LpK#%dCA@vc=M#HW{rM7MDi8>wwNeD^(-XZ(0o&jz~*t zmJ9&ZC|C?us`3rxrDB5qb{jfPk8c>(ieBJR-uG)rsc=gsa(kU+h+XIMSDd;c?{C~eX@wvu|k!sR;;xf z5}NjJlff)wxOwdj(jyvc`Cb*)K~$-|w!9In@4x*27UDi+5aZu`=@-mN|9AE%&Sw7- zaQ&0@hP2Gm7rxA>hqTr={_&!c29v19@%f%6 z%iPBI;&mnuv~r~+*q(|v7-!sEsTI7?tfgIHEz>fHzg8igYF$1Ia#UR6R!LMsdtVeDmQjsW7U_Qq8GgR+7MyT0OBYs{5d`iI@xY?--z zd0?QU@*0ADzZE{Rp)VG0cp9^gW+;Z@`ZFw<>JXxtSPeBcpqOgQr=K`DuvOp`O_38Z zs`*@1ue8p)UjiL*zB=601wn5Lg())->VP*WiVKpu^vqdCjPzZ`##-mwOghN!ldCpZ zST;(simQlfa4|IWmkI7YqUfX2EW}}9{ z2kr=}vQ`&C$*O{)^>6s9X1}ijrG*qHjD-$d5X=s%D73Am4GBng(taqHE7y@9{7n9- zThSiKiWVTGsGou+RRo8iqNr|KR2!IJHUB#<0&e73n9>v(am1){7 zz!?zU=>u6?pW_2TD)YcLY`!=CbozOqu};iy4B-Kn?X-o#!ffT0Y`OZ~clC(7R4P=Za1Wt_X_PSfZV zW8u>SV2_CzRqUpk|z^fn~_fka@Kd!G@8~sr4ht90Jc6|K|(xykAWV`7#PF2 zE>L(RitBo@oxY%bLmBZFPWFB7fv~4&krJcOq%knGIRc#Jsxs0}L9)#RU!*ehTz4NCeS2W;@v9uP-^`w@?ZFt} z2@J8t4PRzDOI=m&8guVY4z~V-*EFk=kCPOsdSzZta4<=( zd}f=KT2yBKeok=RJ#*>vM1G#!J=03b;34a8^fab$;nAwY+#t}=5x0oNLw#>{z7sQm@#Snao{hj@xAWGN0d% zDz9qpuR0RReryUc?KdlPl@wJrxOAtxfz9pSAymn9IPADJe(Qavx4-$+X6x~k_y~Mr z*eC?~_M^d15LmYz#{5N&4*mU_G<{-fdUPwU@$DONmDVjsZ_+K94v%M_IvQJDm8i=_ zle10feGMLH)H;Li_l^gH(D#RSXxux{Fn`6h_d{M=2F(dT$rC|!VdfAXEpc8ZMekK~ z#?I1vPVAEYt9qe&$VD9ThQ91Ec|Z~KGu6Q2XKK}E%XM%NNbPpRyJZ^5H-lh@=qgtr z9X6kXaKUP9Ye+gtYPyE+6vkX(Q%Wozqt_PWMxDR&n-!?% zv%9{?jdTL=g}2e)V=--uFDe%{OSc$H$x!-HOx;6S4djK{A5h%sZfr$Aev`)^WJ7w$ z_I9*N*n!nE`NX|INl=3SQG{8`M}5YUM&e1{Wv4U?04Vn(lr+LiH{}&16D1*%OH&D( zTZeNUD=+Qoe)~}aQ{jB<3}yBpz6vnCpK}nGGeS9i z>X#7KTR6H(Ey>03l|lGK6oKmQ`?ihq3DsRr;ETfG88RTiT!g{pYZLrU$j%pG%b8;z zu5Z%3@%}Ih?+LtI(I)G+`_;Abv}JX^bBFSl84*4_2!*%`Ur(la0^z60<3=c?79ydpyTSF}9?49z z@O)2{bTS?_O4Ylx3RlS`xN8yI>E$yhU7TiC@+Yf+R`OXO17ZvaV@8U4+K|o&1jj;) zt@&n-_lMcpv=P8^;t=yF;1gj*Oa5V6H+>mQGcV#!#)@!L(Ra{#3 z6&cc0uWYqGg3WyN2zyuC&y4R&r5xXGyNEvrgY=)LzJ_b{1H%La^^L9LuU{eZynOEMaQJ+5YM!nF*cfKra^KbFO%%+E5Lx`-T z@n$!X3b+iEP*AUi`cm-Wn*GA&KS>Sq(i)lMy!n4f`=;>9+w9ryj%{~r+qP}nww>(Q zX2-VCvDL9{r{i>d_IJMdW9H_}Jm+p-|DM|Q)~dBuE$y>H`(2J(BEL2BHGt~_o1yQ} zy>^|dKykEoop#=Hv@F6an98sCh?bZb4juE^G;u7Nm-~AsWTiXEVmk?~4k%!oaZ=E% z-*JH*L^3pqV+u?{O0Vx@^OSPse9*mCSts&@rU;Q1kxoRK1ZoxdFzVYA__tv$2Fo(Jha4jk1u%8jOQUL zRL~EG%Z;x;o-Zda#(Vre|3LNj5d)n32jkk68#}Emo>I=dg|dW6FX0hFHu-Kh7*PGT z#<3*bw-}19ZoSuR88O|q zgKgVJ|1BouCfbFWc5Tn-3Ij!g1-#)QqhqAOJ0LTm0SjRlUpp&1C^uZLyrQh$vC9mO z)(MA-vFz$L0#8e0Od7#i#dtBq_uA9T!luOFkkL0YWl%Oebd*zu_p_ti73v~k>@u09*<1T5+w_WF}^x1UHgjA2_opO(Y|95^TXpj%o(JeL}tT;K^V={ zbeFB6qudjq>vB(){!AJvgSe21#EHkx{-uqspbV8lV zL0BDW*`h4hK*PG6?g_sA_iZe>-n>W_HLZGNTA`u%pQIcW?U=V3k1Mg;?h7x_#CH%R zc$K(c)>4#jfRSJU&{4%H@b@SUuIg^gbhN3NEZ=~oW1eTiJmyk~J%tz@oxq81y?fdqmXTa?-rMGic z+-icVU`oMsIKJhDTtwWMzBne<{*-4VV~I$rZ|rRZQ#<}M{f^*)AyH_UiEWaRm?D%c z)`+sHwAdNK|KPI=h|gmA$x1OGK5u~d{5R4c{|BFcmp3UY6F_vL@+Oryo|Ujr(k8o8 z1|Esx60=c2LWzn-9`qBHg&z*$a@Ks8uO~;d`4cMT14WaEEaCG7KeWxbRM1LwsQDn{ zmB;xi$NKa6^^W}ujy&esRyw|8r)|5FiKmiR;LM%`U@2gv{|q0zTZyP*4LH^D98gdl z5SII3=0KohY7m>BgH}{aR1@+v*2^<6SMI4D%w%IK!l+;}Iu^gHJC%_zk9%v8M(s`k z3=bOf5GVyjiGrPG8dg{CL+HY@)R8P`8&u#lH?uGcZE_u$fE}7oWvs%x$-|BkuBj(e zMKYOa7eT;;o_?QEr^l?CV70FesnpOFfM3QsveMEYfJ5=zFd41P$5(chJG$jk$>g`4 zIL^>1ao?9AXV_iFz#k@Z5q(_e_17L0H6s&PXawkuvf6F|BA~C7@%JQogpY{A8}dyG z7_0PM2(jdHfZl4Jd?JWuS z8}`HY9z0kOX9tZQ4>_EMsQDd#hu9Gqcckd%1Dt;3FTe;Rxq{%05Q$~|8V?@EsM1+V zlHjl7^jda^siIBHRT7DHYn*+HeHeza^ChMY8)-_V0PwWMa5ve{YfI3KG$|3Hgy0>a zOb+Rn{j_J%CSQ5u3SE)Vr4%9J6-YsDzDJCsIOD%ayOj>w%03sglQ37oH(E1cnH^OxE(04wt<981*v`x>9j1*$pL(jx1{#wfs<#{&!dUbs zXdRfcyh7QX!F(C!n6g%rC8c1Wh+Z=QG%OCQ?K}>K!?(0RN5MEe-TG&a*j*25Ar8uG zhU?8wG?^V2SnR}anN$D)e+A9O6dJJ;(sPVIjPC(Idsm5h68P1Ur~#h>q|*+(*wPrx zqHe!44U03gd&jm(q;e<1O!ajH?5SOJP$k~R&e|qR8;f)wQbGGqWf)_r+pvY9mqA^o zZ+M3j1Y4;b)$;bY@mzK6g?peQQ`>oG>o~B);e#W`sAb70W&A|_sCf*rSn;A4&Ny*v zB_?!It43W06ne?vZXo8P2J0klnfUsCr~+-+GyMXtg)j~eJa4A<+56`b#?WU z?TpFQoYXcOd`w>MlXY7tOw`SbS`Sn_^k-X&xh1t(HHGP!m;UsSAVV!0ix~PrWe4<9 z%%aqw;ZHx>?yEd{ebRC9IpFqVj_7^5dRd&=h(*u_6Q)~Hd73%$;-QjBs@40qg{FgwH(JJru*>#LKY&V#N2H+ z*t2j=)#8K0alyG$4-Ch(`BNn$j$6)HzHJfO;d!{CuqdIklK8C=EQbZTfpJ$3@_BH~ zn1s;JSSCpOe{wtVv08_Iwyx4~r}xw0p-da$J8%3LAs^ndHRJ5_P>p%48DPPHuXbG+ zdpYEz`jdu_ehCw^rF?Ap&SwtCRV{<)nmGGjhTib-W4NK!y8g#MllsmKULY^+am{p6Neb(esYklhw;`5WhWxh-t^Vye?&31)hO{AAwd#3UURKgDifU80Z+QVT?zUuvFjCtoI!bTWMLhPhNvE#O6%bK=nvu=thL$DHN3j&lE`oRV$hNmQob| zAT%YQN8r7N>2@f=1*VTX&bV~u67emgw8a`?8f=N~tXB^{&C&ELr4C9uHQ)uiCQD); zAi#yW!beGFtDOJquHmt$WqPP6Bj&S=6=LqZ41xIYQRS98(~h(KWDrz>*YZTB#_^6# zrfLW8bti5g3>iakTr7`R*1&g|6V@xOt!CB4c!Z)3*Ltr0`_)d(m?6b&<+BD{8umzD z`I9P#ZU=b|@9Ap8d0DHDg^t~NjTbMrTMBziIxg?6*I6-cyZdHtq3_l>H5zcbS)k^y zW89i+?kOdXYFa8-7&>7(ENRq#>iagUPO)p&oUvF@Th`&YdsUje!yQgDDxTvMBLHus z-}Z{zhdJReof-y@{ME_y6*Nnq91*9U8W3LeO2NRGjJHEr_{*T@Kp)Y~ z8n$y{l3|(P03rF8Ffa^&Bt>{sq9Qw($E*s?Y)<_!clcXnh2mOKcI0hio5;BnS9ax} zF$Mjp^w0mbqWl+^yZ*RnwE`lsT{h$zwo)fjRP-)aIJmK|SMQNQr2XNM{GB zof0Wcp(GMX1@_Qun+W@hz+A_s^elq8wim@=H%KIEFc4w~7ZG9$;W- z+i%1RMq+M^;H#$s~%V(g)AK@wff=0dlAI9_k9d&NGq-mPG( zNJ~cgwk@+L1dal04FyF;hIRCdae$31u08AbP2DEiy;h|3W!PM^?`}AXH$R&y*6=_L z?Cp9}hlL@!Gm6A+L#XAXg=OHb<=(B>Vf4(M z#$nv+c<0#u@%v)3qh<$)1?_uCPPy%M7aVs!l5$S zWcg}~&jxF1X*T*cX>K))F=33vIuxq3DGG`n&S9eimKbJpV`X6$>kUTe7Unl*e0IQ? zl5>gtrp_S&&w%BlE5avI`}RFj+@fqt2~xd#Z`xf1merEwr}e#z=t=L2OJoVoSE36q z+;M$%sXwe~5P^_&Qr4^|_GGNwm94NdvfkvfnSOU|pa5t|h1Br;8?6o`P5gKsc(G%7F8jTufRF5-qjB;2@!FiiyC5Y^ z9)OrQ2BjYWN_3-E!^rP&?nwm4JNhnmaDAOF=ixFk)cPc*MoJ``odPeiVEhXo3x9|^ z;L=C;7$ql67$FoXeMQw^l*JzZB^5o3D4+1JM06XV2>DNR@jnKfVpL}3{%UqATeVh+ zLI(vD5UEkp)>VV0ETm%&h7{#V!VQm{GOg0BUhQ3_?nF)d#gb7)kog7p8x-^y{bYt2 zT1l2k%4v5#`o;OQ)jp5!-wo_b3~>z<%pZpR)T+P8Gv*ZB@es<)>21~GK~}r#b>7zq z3C;XE9KTI&Ke69!%xixM!_CGps4z=vIZPNAdbiXI21ro$5KUyFv1q^?Wh(miW7o1i zfA4g-#yqqiNqh;0PWSD_NI0oFH#i~+_B`_=bkM=qJW7oRo+1|sP|ug1UnQ+ctpay| z)lm9in9gyaM~Doe<4CHhILr)!Vm8X-1%g>E_%P9bs6+FvOsed@ebeF0oG~ z%w^Y!G*qqKDHLPUXh*;6F1nfYFsw;z+vK@|YTwb{8v4=ounjWA#7bZf;tVSmHsYqO zklnmz@cfC@a!9yHcGqURhYk(ZV1+BRFX`17~|Psk)xkeF=u-I@uDw-iIe_H}NFewtGW?j6_wG0^UVj z=cCt+{1W%Qz#ds0vO1wz3Xd{#O6i%oM0%v{F+q*8YA&4^f31(EX8xy`z8E3DWs!&+ zCP%*InC1)cwg!D$;~kuFt@L5>p)o4|{isxgvQSBtXn%UcxCT+J;V3|-*bJgbzh zd{NRNu_dPTWIeFeBg{wtYsvX9Mix3`%+?12JM=$fWS0MC~lP~-bP{GB+at<}`TvUJ&!dbQq+WA0Kly{*wIzp!dIp(h3a-ddTkDas6Fc|6OZ#R>3Z&F|2+BGV%V<9w?*rT~2LA*-oZ;Rf;{ z-75$O(s&-u9f#DLN#?~W^&Dz0+O5+bdBv{6vKZZKPL zf`Y+2>;^L&&WWdH=S<)U?FUmm^+byDWX|63c^H^jYqw#}^;frD;;P9~{%ExqF{rg2 z-WoLL6&6tvG0og|WRtO?9#)q1T~6bs)M+$~7jEAn(DsNu&;Gj$Pj*8w#r@TwDflN$ zT1I1X#r?@gfAlmSQ&azcIg6`mSTDf^M63OOsAT^!P8g%I{+D^in^oj^R%EM0fjVA{ zD(qY+r=X{Rh#VP-O4%!{fE0&g?x@45SI4gExtq1~l`3!$;#x7hKBq*fQo`EO{n+W~ zV)A0t|MUF?Brm2EmeqY&-lNl$+sUd^siQl5s2uhJDK3Qf?Z8_qV&)9f0QS&WXq^v1 z=k@XgxVIvZnqMr( zlaJSTdW z^nbof7mJwv#xj7d1s?%@GRhU%3frxROyM^@MTti+uID#}Q6Wnj<-f+t#4v_a!O}|G zhg-l@o37oO{Q|fIqh?hw*ZB1iVK|aORm{GpNzjc-1QoiStJrG4i%kQ59x~#_C&*;; zYfO-KaY5q9EzRRQjYcl~T3Un(1Z-_iXyH+dqeXrMj;o5pM87LbQ_HWq0}FYWEV5L` zto#ZX(-Ru6{4Vj(8VT8GDQ1AHxsXP_$;AV?TYowatf<^~mxxe#^_iI}YZ{)xR4A0V zvLrn(5n)TXx%iPVo+K|Pd`n_uV*-?$ZcGGGw)zDSEK(gbtkbJWydxepW{D^oRD08m zCt2iSOSx`$p_n;hFQRu6Bu)AwPdX=?d?6NQ%rcfNFX%6lnK18WXj-%zB)?JS^yWMx zOa?Bqji!A4BH^AeuHGmD*)Gw)j>P~wTDO$dnJsm-P1_?NLZ>YB5==2}{zfrN!}dHM zeuQDJlq2js)Qsz8R@F2^l!wr3B$b2LR5}49#MaL_|1v_qSAITx3q;T;a3=OYK@i*D z2r5>#wFaKK@MCK~Nc3o~x56=Aw3;Tnxx9c7ElUQlgc@W9Bm~{hA2pDuv$Y=D)xN~N zRRx7h_y_PyWp}BB3gtIBa5GO&ZZLBrT-0v!$9}EarxZ5Mz9#Pe*tlC=wdyU3ZfdBm`U z^yC`$WjXSLZYEUD9E*)!>I9x;xqlc9po7iCve_3V@S3FScY++oUFdA?Qj_mIUBbOP zdf|=_T8Sg|;Sqd zH(rdoxwjp*&-{ZP$U^D*bfEcB^bv`mqwR9MB%tRnThX$ z%y_?njqWmf!mzE9yHu!*VXDyONpzbehI{Gi0{s)Mi@Rsf#=~}oD7X!B!N98Ll=7|5@i=)xb#0TrDAJ8r-155XAgD(ZtQGt*WCcerW?k@ z4u&y0jEu~bh$b11KUu7Hp|n<<{7yH5Y|fJD`zVezO>2Sp)ECXxKJDu@?fJ`j+V*w- zIPLcrrWNBAYu9J2X&cJSO*O5SO(s`H+x67B16*B2dD#J1S8`1oH=QtRy9`KoTk`Ub zjYU!h!2URtB?Vclmekl;%U#Nih_g2*V62Cg6cm%pkK8U&6tJ1Klt92(^={r00x9gH z5=3~CLCQmihJXzl>exDk$XT(p1%L1jVzCfe_@qvwCK(>H$fQfdQ&$Nq(tfxWm22Nj z{Wrr!>74Pzn1lh>H+(Zv8D(LX`Ia(9=JNZQEJfSglT7J)7>#HnJa-G}+=w%8fR+`7 zk}K|j)#2R!n$Zeg>L$BqX;Np&uhDa9^fX8MNP??*N{yeg+LCWcWM1j)Gy}zP7LV9Z zhc3Ee$kamSDJ~lb;I7=+%aekM{3$hIj7Y^T)#K^CMHV|r3`R^wz71$%I$}TNb3++P zjVt7HlXkk_W21+t0LA#O>$02WHzlW<&8&7y?Z%LN9+-+TsY9DJ!gpm>?zpo2EQ3Kh zEi{`qT7~Y=+C{iU`oeW}1mC}g)PEg@;2>q_rijfZ0tq(&ZxzHRt`7^@i+p5wf|6EG z|CET{1&bl9Khnk0d2`g^j+;*5g6lq{yzBT z0y6h9JV(0pOMH&Bh=DUP_s(buNi1`?J3)CZyv<5~*P4XwEzQFxP&SU@Yn%zsEz3zl zm3WIV-fBWO(%n;CIomg0lLfK5u&Oo4hq^*NgR3`rn3JmVd#Z+m{_Q8hbPS0rJtQ&< z^pZC1z%uqEn7f{T0sT4tPCPvD#RUP5-|_u_fc|f|=cs5p1L6LW2q-bwIJ48O5CdB< z+Qg_5wLlY9=plYUniso%65ah;_!< zhNDXVEn7b2E`j0i_&3!MsEQs)C}!bdgoRp+_Pz{gS)oy7(m}u!YqilKe;dAXeWpSt z-?)w4O53(_Nh&p)cYpZ^h;u<_f>K0xq2xr%A6VSNdN4SgddeU~HfhLXm}2kcBc%*& z>=pxC%!zu{0qp#-6}fWHMJp+e*KLw@Ysa%5W`%1eCz~dY32)b$m|;J4%k&Q)g!^xL4ma5ah?t&>gh2j9A^4w!;-!G$<(G zP4daGz7~qv^@8Sk4%9xu?H|+e|0etn|=aoRLe3MD%`gUGdR!p4w%xWcPJL!a0fs$8HK`E!M%G4;f6)zJLi& z|9Mbu-0S}Igi6{R$#jpTZRAonb~U?eCnvKGzg0CMZlicKUodq&Mq=Dt&lz>?T(x5P zp4RA;FZd81o;x#vbRc@7;&PIb&WEc_U`Hh7=cLfz?H^t=M4^SYzC)`nLwT8;;Xwrq zMnQ*NW<_-c{NXgJJ5`YzE19r6h@E=iK+KjJcj+eYi>r%ikmwjl+smi&`)uMBwqTbO+{D|xsIM9~q3aI!Q!gLEIzO@&^;3wd8ma?3DsmH_f z86mLE)lft;#J_W)gkQbzrCKEo-IZPBMx22Te+cTCLvD;bAvwv#xkNYyV&R_SreJ&@ zG|4NjX`1En8@BG`d}ss9TwD!8-Z}3{7NgWj<3cj3+W2vuq@1zRFN0DZ`6G}&8x~-RR>FuC=lmwSg7BcVva<71qe8g+gZ@-Wn@Xil~yr~Yd&Z{)YzTmwE z@erbSKjcTlvs3#Ev{zll_h@@iWPY zcaFp!MsmkpVva8fua7Cz??OVGu@h;qkCYw#}HmKv(4UlQ*fJvI1{{hp; z8an*fQ~M94ul9EeFq`CgJfKp5F#GGbB1=MAg&L<62QVRyZ-GvoV~Ocp=g8}jc<~+~ z=7S(Sgn=O(cmjK3-}lh3vjQ|bNkc&;NL3bdH#6SdjQyU9^6a@)M%p9i@TM92)BG2W&lP~M4eYq47xw&9B@hprWxKV zOcI@%S;)U*>7(`6sYo-2U~Tu(HfI?M=B!dEU}ge}2WPa7=Ojvlz6=zZaIGgv+3~bc zb^))E*W+d}W#rOkVP-0)bTFxDqJT+Rs})#8eO%{z9wpS70Vpr)u=%RbwD=}NRr$_G zFsU}{p!_t1%DI@&N}AziOl|kAWG$Ao0KT&wif8aPQ%oL()vE+#21;M}nm`%h_r?2y zDHrPfdoQT&vI%c9=h?xOv4Yx(rXNb-sBO==2Hq^r+$~*N)#Sk#ahbmXg=pU| zi$Rd}7s)Ohb$p%FN5CmGq3JLAkH?&NGD8Osz46sNl?L zmzfX?zvlA^NumL9IsmN`<(gRXP~CC_8kZ5*7CPtobzfgTW?2|3Ey_02?iDc082I5K`Pf$up(DMK>tL z73vK*A?C!`$lSRyGQVi?QNnE;H`!EG51R$-3AVkw{sEX;*R4I9i(O!KA$=Gpl47`9tD3IipE&ex9G{kpyDF z`9H+)qD33uz9ekQ`0wXH#ucR#xnScKCZug88O1SjE$nNIt=G z3ub_DK9x-c880F=q?8(^HG#fB_qkvb14f*WUMb0d-i_8K9e>B(Ep2<6uFrd7EZ{am zK(z7>X(`RaE5+a&asp7d34%M`U|Xv_Qy968K7sO9Vhh2=_IOtP2J`9Kil@H=&9ZQ! zXsPF2_=CF6+Xg-4j>2bu7uz=~hV@)~2u+JXDPO-H^=@||pQpdP@wO$6df7wX?lQV6 zEb6-Z4St6JJ6`l_7(=F1S2P8DQZWHQnnMWv9k18+dof3C(Jpz;?{b8ZKFDJ*m4k4) zU^DHL%e_bBn)7p=D;r37Yso#rAJ(ef}4BlKlO{($4(9 z>Xd&-HdW1N7)MOt9XT~yxHG;ESGqMvmCa<=1=X`E=bU-B7Vf!URT<^+;pDrsjTj;% zIQArNnh4?SJhwZFB1Dd4B(aF+ukIa7SjCdZ+#lOdud$y`QycG2@8AI(T99`zrVsJh zKkz0piZ%LJU_@o>Naw>%Rkfo`wW2!qE!2W1PQ(a@63^08@kKO#)GYd2F1gXL9=mkX z%itS~XehEm*GC&OIutMpra$#~_<2D2cE*)LIrJA{&%RxwfWIjb5w75th@({_H4w+pPDK<;)uXbE<~yW^tM;f-&e4f7t2dsZIsFx>ROvi; znJ=41CPd%ZzPj`sT?tfQkv`(jyG^xfHEM#RN)+0b1l9QQE&Dq(@pLzgtFSvZ)CBP< zwzTY9dBX`?e^aI*_TB}7F{sejKMM55h~UeD{S-n1Q->_;cIlkHT!!9L;Sm-u_-mBL zu*2XpIQu5|;tC;lCs4f7A-T5*`B^41gCv0%35;Jrz;fq;*;FSXo?=(k%ZZXIcv$jtDr8C#km$n+bvi z=SbYthT4eBI)O3F5k!2Snoy3}0Xqx5I_{$F>U3^&CoZ?h6t{n`Yr@;g5U&xWp5yxF z$=7W)&qB-dSUYT{BS#Lgm1#7xDIRqu2HT^BJ+{TUMH|KSegw5g`Ex)^x6ZhgnyPZz zEDYc*nf3?-tI_7LDW!uWUKxKNd>@rL-E$h7p7V` z4owFQICUrq!U{|vFv;K__P{Ga3aufk@>pZk%J6~PUuP7YvEU|y!L}CH$(W1HNc;LY zdgB~@9;TT-rQ+bskfxY{l2Nak`>c2kau3Vr75RmCM8GRB;U0Pa1dVLg+Cy|;L+1ok zTJO=bNT<)@l;#SiLjh?To&5j=5zrzOP+^_Fhrl_wd4}yh8V1QBH_U=Ew(6n2!`O*y{J)B!fsj z9W>5D_Y?8Si@(T8zB_20#WBx)aghRXRK^bCo^#+y76VVa%eg4~B_3Vgri_1F^GHJ1 zIsO~@jFja*KzS(yZQe{!Q{R9q(KG_4`tG(BU>Q)ZgO#wLsRKA z^xmdeyl3ink0-kiUv9-m$GBKOS!jaGlyoN?R6udI_*mzN z#2sxpXLD}4ZlLwzfuA72nTV(me9!;H9mDmX{~CLUCfYVwSJwS6<@!R?PO<@T-Jcrs z%NN>z|Kt5bIBS?T{xwJ%g(l?a-bysI+11t=ii{V?7D_hs_u|~<^B3kfbhCiYEL&y0 z1XK^^OFK62>Gtl|m)rBH&M#-XAi~Yj>0GMS>dW}iA@5iT5@Hg-e1pO3I91uHZGR_; zRvOx~ug0VN36C$r6$!h)dEE-on|MaYVwj10y7mMsnX8r zPpZZ`@QW-M>jfw>Oo}j^JvmfL@dSWo@fM-b8G>OtH7&qxTFH_s^ZJ%y2V?qN(cb0( zJ4AY2-mbR=Y*a@=vysVf%Uv@RtU7U84kI1oajKc)>Ikel*pQosfYwgh{L2 zYAv0yi5P>e&J0FTm1RctW_l_@r94-KVxTD`Olx^6!Yw{m!3n2^3kKG15#rX+=y3MH zWRRdlbc1kF9W2Pf27jJRn~d?#tyDn8x}EgKP%(ouSox4G9qfDi*y>uC8dUif9txyJoZn_AO7N0|-wX9^bUG`-ZJibFZ8MjzHdGoea0OK^!O zDMwU9wt zG1QY8Z~;>mgzJDuxG>Q!6ww&EN*-mS*B_dU&|FBVK#-0Zyw)FbhmZTM1DNZ9O@_Vm z0V}R2;9NiS1|avK7Bj_RM)>04VeyL0mc2LHypTp>NY_VmJ8{|*aM5?BxDaC2$}bN; z#FHvkdJ*J=RP^FnrzI)V`3$j)HC8Bg>&aCWi|OmSeLO&q8-WNK@Sh#hsL9)W?fvl)zqLW6qTO|8T=S;n=jsFMa*FV*GRrqQXJe z8mx59p7Hx9BD+ZE9@j^GIT_DAwaNOiIBN2UqMu>HIqZ->so;^L?;-DE=n~P?-jkM} zd)!0^=lh3^02LI%ux0jGOc00krAwxr>`4vKBA(gigaY|=av<5vXqRl(VVio)ERHPn z1Zr7Q0OJ+zwR?xBBc3|Psw&|5YV6~6c>KYnLRVb@l)bE7Hj&WrV_spwAihKBu*3D- z%MrP>ZO#28mbHuSv*OssLZQ`8tNl)VnRJ`?dnO>eL=Br|;QOlB={R^9m|J-C{GU@i zsET|+E0tqYzJTsO`D?=LO?vg$8njgEQV&sBsd!7@hE+BX#2vWFXHW9t?IGR|bZb7m z0QpM#B*~A9^QWA&%F-pSFc<{0frK#)&m|9K360EXQMf&&+Gpcy^ zl%w`nEYzdFZ+#A0z4>mvd168>$#pUMuA_6gh`1YOP97E~y^ubFTx;|Dz`TA19pCFN z_=N#1KtISolnKT#SkwnQB}Zf81**uAj^~x#u%%yW^2=+F&{&>Qx`R@?*VJd$)JfLS znq04O*0@prklOn2p{$wjG8@XP@u8rb5WDeB3vMHMWk&0`G>=75K=+A2Y20tXUly}H zSRQzAO6!RqpF?KLJ9uBZx&Y-Wrx|=bll-WA!YyvRZWa2CuK0FeYrN?REh@fL30xaM zFrzQhpw6LdKbMuHTkZ>dLO>U(0ob-`^x9YX7UR*>=AHC&O!MHhgB>jXueAc1a(}+Q zaX{}Re_1}w2)3RBfD38s3+_`@Ri?Ky%Q17Wzpxf z(a3n}22QK7ZojT+Sn5we4F7Bo&AYe~@2V~h#(T5~iAf(>xfM>i08;E>XY|qPNhPZ< z@IX@$=<+WmaeFn4+5;cvnCJ%Q7*IUa!tIqBP*NdYqptLC^C8vD=F;>*( zQp9i-Icg*^?wF$&4wQNGMg}aF&c^nMUi3r;Q!+}_n@T{dVMHv-uPHT@=zfjeV#Sr` z^x}T_Ub~5Zzm$+8J2~hI8D>kjH%W$gD_L_Z?8{oat6>)80~O?>0!r>j5RTNx@)I4| z{zN#e2-H5R%8eW4W%*~Iv!>(6a0H(e&V;`ZD;@GuQa>{_H+n+YBMsn0W2jVWL< zC17%h`VYjYD!<2GakhR@g0fBms;x=fFJBnZQNjysJ2SE|+obSS+Dy_Un@=>!kL

z=7#Z1X>KQnxb63^`Vt%ae~jEd#d{3C@AC8tN9?B^{>U+RJ^DFeH(-M77c#<+Waqh- za*e|C9^s&k(SNY%?t{_gO@FIXuN*GW#d0)OLVzFhY)KTehjGY~zqTOJ ziH3Hh!HEXp2IIGN&@3}7XV1UXsjat^6vzuviwm)pn1Fo=3Jd$!*LHZ~^fr&WBkM#W;Ew;?Ise z)7IwRqa^8ShVwM9`>(C`4E&yM-EUdTt?NPgnhPBd5w4#Z*)ed_&SzeA zE+$xDbd=|Ic(3}N2(TfUm47|=z*|s@X;#r}3`nt5*F7A(Dm#SopMm{`cEW(Uq{Qpk zTvD@?Lal38$V}5E_BQ0uMh|n!=#@L*_>m% zMfnl#u$7P7VNKI{tP27RG;8CBAB+e*TTeqsw#hnmyp$a`ZS+BvGGmI4JCUhrvsq)U=cb7t3zsPU-_3546@ukn>8g=W+e1=ddj6$yP=LxQ`2n02 zor3$fE=Vi?7oz@FzcFfuzvmTDc|&9RDcCk}haKGA-Ip8m1N;4Gn{cnLuITUyB));V zLxT202tg9Qv4%Krj{^o0yO+1z4>z2Dd)wRh@OXU7W2Li@n4C(Fnp %t2yb=Gya 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

-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

soD4enx5=FPm1Oh~{i@@+wv{_zNvF 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

-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 z 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 z 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 z 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

ShiowNX}ZG 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

YJ?#!D)PfFwJ;&o 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Ỷ_teh(rY?qWE5jfp6Td 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 z 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/QNL^1cVHBB-NHt0 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 MNjj@WMWSTqvJ5%k@&L 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

+ * Get the value of a stty property, including the management of a cache. + *

+ * + * @param name the stty property. + * @return the stty property value. + */ + public int getProperty(String name) { + assert name != null; + // CraftBukkit start + long currentTime = System.currentTimeMillis(); + + try { + // tty properties are cached so we don't have to worry too much about getting term widht/height + if (config == null || currentTime - configLastFetched > 1000) { + config = get("-a"); + } + } catch (Exception e) { + Log.debug("Failed to query stty ", name, "\n", e); + } + + // always update the last fetched time and try to parse the output + if (currentTime - configLastFetched > 1000) { + configLastFetched = currentTime; + } + + return this.getProperty(name, config); + // CraftBukkit end + } + + /** + *

+ * Parses a stty output (provided by stty -a) and return the value of a given property. + *

+ * + * @param name property name. + * @param stty string resulting of stty -a execution. + * @return value of the given property. + */ + protected static int getProperty(String name, String stty) { + // try the first kind of regex + Pattern pattern = Pattern.compile(name + "\\s+=\\s+([^;]*)[;\\n\\r]"); + Matcher matcher = pattern.matcher(stty); + if (!matcher.find()) { + // try a second kind of regex + pattern = Pattern.compile(name + "\\s+([^;]*)[;\\n\\r]"); + matcher = pattern.matcher(stty); + if (!matcher.find()) { + // try a second try of regex + pattern = Pattern.compile("(\\S*)\\s+" + name); + matcher = pattern.matcher(stty); + if (!matcher.find()) { + return -1; + } + } + } + return parseControlChar(matcher.group(1)); + } + + private static int parseControlChar(String str) { + // under + if ("".equals(str)) { + return -1; + } + // octal + if (str.charAt(0) == '0') { + return Integer.parseInt(str, 8); + } + // decimal + if (str.charAt(0) >= '1' && str.charAt(0) <= '9') { + return Integer.parseInt(str, 10); + } + // control char + if (str.charAt(0) == '^') { + if (str.charAt(1) == '?') { + return 127; + } else { + return str.charAt(1) - 64; + } + } else if (str.charAt(0) == 'M' && str.charAt(1) == '-') { + if (str.charAt(2) == '^') { + if (str.charAt(3) == '?') { + return 127 + 128; + } else { + return str.charAt(3) - 64 + 128; + } + } else { + return str.charAt(2) + 128; + } + } else { + return str.charAt(0); + } + } + + private String stty(final String args) throws IOException, InterruptedException { + assert args != null; + return exec(String.format("%s %s < /dev/tty", sttyCommand, args)); + } + + private String exec(final String cmd) throws IOException, InterruptedException { + assert cmd != null; + return exec(shCommand, "-c", cmd); + } + + private String exec(final String... cmd) throws IOException, InterruptedException { + assert cmd != null; + + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + + Log.trace("Running: ", cmd); + + Process p = Runtime.getRuntime().exec(cmd); + + InputStream in = null; + InputStream err = null; + OutputStream out = null; + try { + int c; + in = p.getInputStream(); + while ((c = in.read()) != -1) { + bout.write(c); + } + err = p.getErrorStream(); + while ((c = err.read()) != -1) { + bout.write(c); + } + out = p.getOutputStream(); + p.waitFor(); + } + finally { + close(in, out, err); + } + + String result = bout.toString(); + + Log.trace("Result: ", result); + + return result; + } + + private static void close(final Closeable... closeables) { + for (Closeable c : closeables) { + try { + c.close(); + } + catch (Exception e) { + // Ignore + } + } + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/entity/EntityMinecartCommandBlockListener.java b/src/main/java/net/minecraft/entity/EntityMinecartCommandBlockListener.java new file mode 100644 index 0000000..1556c90 --- /dev/null +++ b/src/main/java/net/minecraft/entity/EntityMinecartCommandBlockListener.java @@ -0,0 +1,51 @@ +package net.minecraft.entity; + +import io.netty.buffer.ByteBuf; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.command.server.CommandBlockLogic; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.IChatComponent; +import net.minecraft.util.MathHelper; +import net.minecraft.world.World; +// CraftBukkit - package-private -> public +public class EntityMinecartCommandBlockListener extends CommandBlockLogic +{ + final EntityMinecartCommandBlock field_145768_a; + + EntityMinecartCommandBlockListener(EntityMinecartCommandBlock p_i45320_1_) + { + this.field_145768_a = p_i45320_1_; + this.sender = (org.bukkit.craftbukkit.entity.CraftMinecartCommand) p_i45320_1_.getBukkitEntity(); // CraftBukkit - Set the sender + } + + public void func_145756_e() + { + this.field_145768_a.getDataWatcher().updateObject(23, this.func_145753_i()); + this.field_145768_a.getDataWatcher().updateObject(24, IChatComponent.Serializer.func_150696_a(this.func_145749_h())); + } + + /** + * Return the position for this command sender. + */ + public ChunkCoordinates getPlayerCoordinates() + { + return new ChunkCoordinates(MathHelper.floor_double(this.field_145768_a.posX), MathHelper.floor_double(this.field_145768_a.posY + 0.5D), MathHelper.floor_double(this.field_145768_a.posZ)); + } + + public World getEntityWorld() + { + return this.field_145768_a.worldObj; + } + + @SideOnly(Side.CLIENT) + public int func_145751_f() + { + return 1; + } + @SideOnly(Side.CLIENT) + public void func_145757_a(ByteBuf p_145757_1_) + { + p_145757_1_.writeInt(field_145768_a.getEntityId()); + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/inventory/ContainerEnchantTableInventory.java b/src/main/java/net/minecraft/inventory/ContainerEnchantTableInventory.java new file mode 100644 index 0000000..71da152 --- /dev/null +++ b/src/main/java/net/minecraft/inventory/ContainerEnchantTableInventory.java @@ -0,0 +1,75 @@ +package net.minecraft.inventory; + +// CraftBukkit start +import java.util.List; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +import net.minecraft.item.ItemStack; +// CraftBukkit end + +public class ContainerEnchantTableInventory extends InventoryBasic // CraftBukkit -> public +{ + /** The brewing stand this slot belongs to. */ + final ContainerEnchantment container; + + // CraftBukkit start + public List transaction = new java.util.ArrayList(); + public org.bukkit.entity.Player player; + private int maxStack = MAX_STACK; + + public ItemStack[] getContents() + { + return this.inventoryContents; + } + + public void onOpen(CraftHumanEntity who) + { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) + { + transaction.remove(who); + } + + public List getViewers() + { + return transaction; + } + + public org.bukkit.inventory.InventoryHolder getOwner() + { + return this.player; + } + + public void setMaxStackSize(int size) + { + maxStack = size; + } + // CraftBukkit end + + ContainerEnchantTableInventory(ContainerEnchantment par1ContainerEnchantment, String par2Str, boolean par3, int par4) + { + super(par2Str, par3, par4); + this.container = par1ContainerEnchantment; + this.setMaxStackSize(1); // CraftBukkit + } + + /** + * Returns the maximum stack size for a inventory slot. Seems to always be 64, possibly will be extended. *Isn't + * this more of a set than a get?* + */ + public int getInventoryStackLimit() + { + return maxStack; // CraftBukkit + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void markDirty() + { + super.markDirty(); + this.container.onCraftMatrixChanged((IInventory) this); + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/inventory/ContainerRepairInventory.java b/src/main/java/net/minecraft/inventory/ContainerRepairInventory.java new file mode 100644 index 0000000..28f5b0d --- /dev/null +++ b/src/main/java/net/minecraft/inventory/ContainerRepairInventory.java @@ -0,0 +1,65 @@ +package net.minecraft.inventory; + +// CraftBukkit start +import java.util.List; +import org.bukkit.craftbukkit.entity.CraftHumanEntity; +import org.bukkit.entity.HumanEntity; +import net.minecraft.item.ItemStack; +// CraftBukkit end + +public class ContainerRepairInventory extends InventoryBasic // CraftBukkit - public +{ + final ContainerRepair repairContainer; + + // CraftBukkit start + public List transaction = new java.util.ArrayList(); + public org.bukkit.entity.Player player; + private int maxStack = MAX_STACK; + + public ItemStack[] getContents() + { + return this.inventoryContents; + } + + public void onOpen(CraftHumanEntity who) + { + transaction.add(who); + } + + public void onClose(CraftHumanEntity who) + { + transaction.remove(who); + } + + public List getViewers() + { + return transaction; + } + + public org.bukkit.inventory.InventoryHolder getOwner() + { + return this.player; + } + + public void setMaxStackSize(int size) + { + maxStack = size; + } + // CraftBukkit end + + ContainerRepairInventory(ContainerRepair par1ContainerRepair, String par2Str, boolean par3, int par4) + { + super(par2Str, par3, par4); + this.repairContainer = par1ContainerRepair; + this.setMaxStackSize(1); // CraftBukkit + } + + /** + * Called when an the contents of an Inventory change, usually + */ + public void markDirty() + { + super.markDirty(); + this.repairContainer.onCraftMatrixChanged((IInventory) this); + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/server/network/ThreadPlayerLookupUUID.java b/src/main/java/net/minecraft/server/network/ThreadPlayerLookupUUID.java new file mode 100644 index 0000000..206c259 --- /dev/null +++ b/src/main/java/net/minecraft/server/network/ThreadPlayerLookupUUID.java @@ -0,0 +1,142 @@ +package net.minecraft.server.network; + +import java.math.BigInteger; +import java.util.UUID; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.server.network.NetHandlerLoginServer.LoginState; +import net.minecraft.util.CryptManager; + +import com.mojang.authlib.GameProfile; +import com.mojang.authlib.exceptions.AuthenticationUnavailableException; + +// CraftBukkit start +import org.bukkit.craftbukkit.util.Waitable; +import org.bukkit.event.player.AsyncPlayerPreLoginEvent; +import org.bukkit.event.player.PlayerPreLoginEvent; +// CraftBukkit end + +class ThreadPlayerLookupUUID extends Thread +{ + final NetHandlerLoginServer field_151292_a; + private MinecraftServer mcServer; // Cauldron + + ThreadPlayerLookupUUID(NetHandlerLoginServer p_i45296_1_, String p_i45296_2_) + { + super(p_i45296_2_); + this.field_151292_a = p_i45296_1_; + this.mcServer = NetHandlerLoginServer.getMinecraftServer(this.field_151292_a); // Cauldron + } + + public void run() + { + GameProfile gameprofile = NetHandlerLoginServer.getGameProfile(this.field_151292_a); + try + { + // Spigot Start + if (!this.mcServer.isServerInOnlineMode()) + { + this.field_151292_a.initUUID(); + fireLoginEvents(); + return; + } + // Spigot End + String s = (new BigInteger(CryptManager.getServerIdHash(NetHandlerLoginServer.getLoginServerId(this.field_151292_a), this.mcServer.getKeyPair().getPublic(), NetHandlerLoginServer.getSecretKey(this.field_151292_a)))).toString(16); + NetHandlerLoginServer.processPlayerLoginGameProfile(this.field_151292_a, this.mcServer.func_147130_as().hasJoinedServer(new GameProfile((UUID)null, gameprofile.getName()), s)); + + if (NetHandlerLoginServer.getGameProfile(this.field_151292_a) != null) + { + fireLoginEvents(); // Spigot + } + else if (this.mcServer.isSinglePlayer()) + { + NetHandlerLoginServer.getLogger().warn("Failed to verify username but will let them in anyway!"); + NetHandlerLoginServer.processPlayerLoginGameProfile(this.field_151292_a, this.field_151292_a.func_152506_a(gameprofile)); + NetHandlerLoginServer.setLoginState(this.field_151292_a, LoginState.READY_TO_ACCEPT); + } + else + { + this.field_151292_a.func_147322_a("Failed to verify username!"); + NetHandlerLoginServer.getLogger().error("Username \'" + NetHandlerLoginServer.getGameProfile(this.field_151292_a).getName() + "\' tried to join with an invalid session"); + } + } + catch (AuthenticationUnavailableException authenticationunavailableexception) + { + if (this.mcServer.isSinglePlayer()) + { + NetHandlerLoginServer.getLogger().warn("Authentication servers are down but will let them in anyway!"); + NetHandlerLoginServer.processPlayerLoginGameProfile(this.field_151292_a, this.field_151292_a.func_152506_a(gameprofile)); + NetHandlerLoginServer.setLoginState(this.field_151292_a, LoginState.READY_TO_ACCEPT); + } + else + { + this.field_151292_a.func_147322_a("Authentication servers are down. Please try again later, sorry!"); + NetHandlerLoginServer.getLogger().error("Couldn\'t verify username because servers are unavailable"); + } + // CraftBukkit start - catch all exceptions + } + catch (Exception exception) + { + this.field_151292_a.func_147322_a("Failed to verify username!"); + this.mcServer.server.getLogger().log(java.util.logging.Level.WARNING, "Exception verifying " + NetHandlerLoginServer.getGameProfile(this.field_151292_a).getName(), exception); + // CraftBukkit end + } + } + + private void fireLoginEvents() throws Exception + { + // CraftBukkit start - fire PlayerPreLoginEvent + if (!this.field_151292_a.field_147333_a.isChannelOpen()) + { + return; + } + + String playerName = NetHandlerLoginServer.getGameProfile(this.field_151292_a).getName(); + java.net.InetAddress address = ((java.net.InetSocketAddress) this.field_151292_a.field_147333_a.getSocketAddress()).getAddress(); + java.util.UUID uniqueId = NetHandlerLoginServer.getGameProfile(this.field_151292_a).getId(); + final org.bukkit.craftbukkit.CraftServer server = this.mcServer.server; + + AsyncPlayerPreLoginEvent asyncEvent = new AsyncPlayerPreLoginEvent(playerName, address, uniqueId); + server.getPluginManager().callEvent(asyncEvent); + + if (PlayerPreLoginEvent.getHandlerList().getRegisteredListeners().length != 0) + { + final PlayerPreLoginEvent event = new PlayerPreLoginEvent(playerName, address, uniqueId); + + if (asyncEvent.getResult() != PlayerPreLoginEvent.Result.ALLOWED) + { + event.disallow(asyncEvent.getResult(), asyncEvent.getKickMessage()); + } + + Waitable waitable = new Waitable() + { + @Override + protected PlayerPreLoginEvent.Result evaluate() + { + server.getPluginManager().callEvent(event); + return event.getResult(); + } + }; + + NetHandlerLoginServer.getMinecraftServer(this.field_151292_a).processQueue.add(waitable); + + if (waitable.get() != PlayerPreLoginEvent.Result.ALLOWED) + { + this.field_151292_a.func_147322_a(event.getKickMessage()); + return; + } + } + else + { + if (asyncEvent.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) + { + this.field_151292_a.func_147322_a(asyncEvent.getKickMessage()); + return; + } + } + // CraftBukkit end + + NetHandlerLoginServer.getLogger().info("UUID of player " + NetHandlerLoginServer.getGameProfile(this.field_151292_a).getName() + " is " + NetHandlerLoginServer.getGameProfile(this.field_151292_a).getId());; + NetHandlerLoginServer.setLoginState(this.field_151292_a, LoginState.READY_TO_ACCEPT); + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraft/tileentity/TileEntityCommandBlockListener.java b/src/main/java/net/minecraft/tileentity/TileEntityCommandBlockListener.java new file mode 100644 index 0000000..0c5e9ce --- /dev/null +++ b/src/main/java/net/minecraft/tileentity/TileEntityCommandBlockListener.java @@ -0,0 +1,56 @@ +package net.minecraft.tileentity; + +import io.netty.buffer.ByteBuf; +import cpw.mods.fml.relauncher.Side; +import cpw.mods.fml.relauncher.SideOnly; +import net.minecraft.command.server.CommandBlockLogic; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.world.World; +// CraftBukkit - package-private -> public +public class TileEntityCommandBlockListener extends CommandBlockLogic +{ + final TileEntityCommandBlock field_145767_a; + + TileEntityCommandBlockListener(TileEntityCommandBlock p_i45441_1_) + { + this.field_145767_a = p_i45441_1_; + sender = new org.bukkit.craftbukkit.command.CraftBlockCommandSender(this); // CraftBukkit - add sender + } + + /** + * Return the position for this command sender. + */ + public ChunkCoordinates getPlayerCoordinates() + { + return new ChunkCoordinates(this.field_145767_a.xCoord, this.field_145767_a.yCoord, this.field_145767_a.zCoord); + } + + public World getEntityWorld() + { + return this.field_145767_a.getWorldObj(); + } + + public void func_145752_a(String p_145752_1_) + { + super.func_145752_a(p_145752_1_); + this.field_145767_a.markDirty(); + } + + public void func_145756_e() + { + this.field_145767_a.getWorldObj().markBlockForUpdate(this.field_145767_a.xCoord, this.field_145767_a.yCoord, this.field_145767_a.zCoord); + } + + @SideOnly(Side.CLIENT) + public int func_145751_f() + { + return 0; + } + @SideOnly(Side.CLIENT) + public void func_145757_a(ByteBuf p_145757_1_) + { + p_145757_1_.writeInt(field_145767_a.xCoord); + p_145757_1_.writeInt(field_145767_a.yCoord); + p_145757_1_.writeInt(field_145767_a.zCoord); + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/cauldron/CauldronHooks.java b/src/main/java/net/minecraftforge/cauldron/CauldronHooks.java new file mode 100644 index 0000000..ac7ac87 --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/CauldronHooks.java @@ -0,0 +1,469 @@ +package net.minecraftforge.cauldron; + +import gnu.trove.map.hash.TObjectIntHashMap; +import gnu.trove.map.hash.TObjectLongHashMap; + +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.lang.management.ManagementFactory; +import java.lang.reflect.Method; +import java.text.MessageFormat; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.management.MBeanServer; + +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.server.MinecraftServer; +import net.minecraft.tileentity.TileEntity; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.ChunkCoordinates; +import net.minecraft.util.MathHelper; +import net.minecraft.world.ChunkCoordIntPair; +import net.minecraft.world.World; +import net.minecraft.world.gen.ChunkProviderServer; + +import org.bukkit.event.entity.CreatureSpawnEvent.SpawnReason; + +import com.google.gson.stream.JsonWriter; + +public class CauldronHooks +{ + // Some mods such as Twilight Forest listen for specific events as their WorldProvider loads to hotload its dimension. This prevents this from happening so MV can create worlds using the same provider without issue. + public static boolean craftWorldLoading = false; + public static int tickingDimension = 0; + public static ChunkCoordIntPair tickingChunk = null; + public static Map, TileEntityCache> tileEntityCache = new HashMap, TileEntityCache>(); + + private static TObjectLongHashMap recentWarnings = new TObjectLongHashMap(); + + public static void logInfo(String msg, Object... args) + { + MinecraftServer.getServer().logInfo(MessageFormat.format(msg, args)); + } + + public static void logWarning(String msg, Object... args) + { + MinecraftServer.getServer().logWarning(MessageFormat.format(msg, args)); + } + + public static void logSevere(String msg, Object... args) + { + MinecraftServer.getServer().logSevere(MessageFormat.format(msg, args)); + } + + public static void logStack() + { + if (MinecraftServer.cauldronConfig.logWithStackTraces.getValue()) + { + Throwable ex = new Throwable(); + ex.fillInStackTrace(); + ex.printStackTrace(); + } + } + + public static void logEntityDeath(Entity entity) + { + if (MinecraftServer.cauldronConfig.entityDeathLogging.getValue()) + { + logInfo("Dim: {0} setDead(): {1}", entity.worldObj.provider.dimensionId, entity); + logStack(); + } + } + + public static void logEntityDespawn(Entity entity, String reason) + { + if (MinecraftServer.cauldronConfig.entityDespawnLogging.getValue()) + { + logInfo("Dim: {0} Despawning ({1}): {2}", entity.worldObj.provider.dimensionId, reason, entity); + //logInfo("Chunk Is Active: {0}", entity.worldObj.inActiveChunk(entity)); + logStack(); + } + } + + public static void logEntitySpawn(World world, Entity entity, SpawnReason spawnReason) + { + if (MinecraftServer.cauldronConfig.entitySpawnLogging.getValue()) + { + logInfo("Dim: {0} Spawning ({1}): {2}", world.provider.dimensionId, spawnReason, entity); + logInfo("Dim: {0} Entities Last Tick: {1}", world.provider.dimensionId, world.entitiesTicked); + logInfo("Dim: {0} Tiles Last Tick: {1}", world.provider.dimensionId, world.tilesTicked); + //logInfo("Chunk Is Active: {0}", world.inActiveChunk(entity)); + logStack(); + } + } + + public static void logChunkLoad(ChunkProviderServer provider, String msg, int x, int z, boolean logLoadOnRequest) + { + if (MinecraftServer.cauldronConfig.chunkLoadLogging.getValue()) + { + logInfo("{0} Chunk At [{1}] ({2}, {3})", msg, provider.worldObj.provider.dimensionId, x, z); + if (logLoadOnRequest) + { + logLoadOnRequest(provider, x, z); + } + logStack(); + } + } + + public static void logChunkUnload(ChunkProviderServer provider, int x, int z, String msg) + { + if (MinecraftServer.cauldronConfig.chunkUnloadLogging.getValue()) + { + logInfo("{0} [{1}] ({2}, {3})", msg, provider.worldObj.provider.dimensionId, x, z); + long currentTick = MinecraftServer.getServer().getTickCounter(); + long lastAccessed = provider.lastAccessed(x, z); + long diff = currentTick - lastAccessed; + logInfo(" Last accessed: {0, number} Current Tick: {1, number} [{2, number}]", lastAccessed, currentTick, diff); + } + } + + private static void logLoadOnRequest(ChunkProviderServer provider, int x, int z) + { + long currentTick = MinecraftServer.getServer().getTickCounter(); + long lastAccessed = provider.lastAccessed(x, z); + long diff = currentTick - lastAccessed; + logInfo(" Last accessed: {0, number} Current Tick: {1, number} [{2, number}]", lastAccessed, currentTick, diff); + logInfo(" Finding Spawn Point: {0}", provider.worldObj.findingSpawnPoint); + logInfo(" Load chunk on request: {0}", provider.loadChunkOnProvideRequest); + logInfo(" Calling Forge Tick: {0}", MinecraftServer.callingForgeTick); + logInfo(" Load chunk on forge tick: {0}", MinecraftServer.cauldronConfig.loadChunkOnForgeTick.getValue()); + long providerTickDiff = currentTick - provider.initialTick; + if (providerTickDiff <= 100) + { + logInfo(" Current Tick - Initial Tick: {0, number}", providerTickDiff); + } + } + + public static boolean checkBoundingBoxSize(Entity entity, AxisAlignedBB aabb) + { + if (!(entity instanceof EntityLivingBase) || entity instanceof EntityPlayer) return false; // only check living entities that are not players + int logSize = MinecraftServer.cauldronConfig.largeBoundingBoxLogSize.getValue(); + if (logSize <= 0 || !MinecraftServer.cauldronConfig.checkEntityBoundingBoxes.getValue()) return false; + int x = MathHelper.floor_double(aabb.minX); + int x1 = MathHelper.floor_double(aabb.maxX + 1.0D); + int y = MathHelper.floor_double(aabb.minY); + int y1 = MathHelper.floor_double(aabb.maxY + 1.0D); + int z = MathHelper.floor_double(aabb.minZ); + int z1 = MathHelper.floor_double(aabb.maxZ + 1.0D); + + int size = Math.abs(x1-x) * Math.abs(y1-y) * Math.abs(z1-z); + if (size > MinecraftServer.cauldronConfig.largeBoundingBoxLogSize.getValue()) + { + logWarning("Entity being removed for bounding box restrictions"); + logWarning("BB Size: {0} > {1} avg edge: {2}", size, logSize, aabb.getAverageEdgeLength()); + logWarning("Motion: ({0}, {1}, {2})", entity.motionX, entity.motionY, entity.motionZ); + logWarning("Calculated bounding box: {0}", aabb); + logWarning("Entity bounding box: {0}", entity.getBoundingBox()); + logWarning("Entity: {0}", entity); + NBTTagCompound tag = new NBTTagCompound(); + entity.writeToNBT(tag); + logWarning("Entity NBT: {0}", tag); + logStack(); + entity.setDead(); + return true; + } + return false; + } + + public static boolean checkEntitySpeed(Entity entity, double x, double y, double z) + { + int maxSpeed = MinecraftServer.cauldronConfig.entityMaxSpeed.getValue(); + if (maxSpeed > 0 && MinecraftServer.cauldronConfig.checkEntityMaxSpeeds.getValue()) + { + double distance = x * x + z * z; + if (distance > maxSpeed) + { + if (MinecraftServer.cauldronConfig.logEntitySpeedRemoval.getValue()) + { + logInfo("Speed violation: {0} was over {1} - Removing Entity: {2}", distance, maxSpeed, entity); + if (entity instanceof EntityLivingBase) + { + EntityLivingBase livingBase = (EntityLivingBase)entity; + logInfo("Entity Motion: ({0}, {1}, {2}) Move Strafing: {3} Move Forward: {4}", entity.motionX, entity.motionY, entity.motionZ, livingBase.moveStrafing, livingBase.moveForward); + } + + if (MinecraftServer.cauldronConfig.logWithStackTraces.getValue()) + { + logInfo("Move offset: ({0}, {1}, {2})", x, y, z); + logInfo("Motion: ({0}, {1}, {2})", entity.motionX, entity.motionY, entity.motionZ); + logInfo("Entity: {0}", entity); + NBTTagCompound tag = new NBTTagCompound(); + entity.writeToNBT(tag); + logInfo("Entity NBT: {0}", tag); + logStack(); + } + } + if (entity instanceof EntityPlayer) // Skip killing players + { + entity.motionX = 0; + entity.motionY = 0; + entity.motionZ = 0; + return false; + } + // Remove the entity; + entity.isDead = true; + return false; + } + } + return true; + } + + public static void logEntitySize(World world, Entity entity, List list) + { + if (!MinecraftServer.cauldronConfig.logEntityCollisionChecks.getValue()) return; + long largeCountLogSize = MinecraftServer.cauldronConfig.largeCollisionLogSize.getValue(); + if (largeCountLogSize > 0 && world.entitiesTicked > largeCountLogSize) + { + logWarning("Entity size > {0, number} at: {1}", largeCountLogSize, entity); + } + if (list == null) return; + long largeCollisionLogSize = MinecraftServer.cauldronConfig.largeCollisionLogSize.getValue(); + if (largeCollisionLogSize > 0 && + (MinecraftServer.getServer().getTickCounter() % 10) == 0 && + list.size() >= largeCollisionLogSize) + { + CauldronHooks.CollisionWarning warning = new CauldronHooks.CollisionWarning(world, entity); + if (recentWarnings.contains(warning)) + { + long lastWarned = recentWarnings.get(warning); + if ((MinecraftServer.getSystemTimeMillis() - lastWarned) < 30000) return; + } + recentWarnings.put(warning, System.currentTimeMillis()); + logWarning("Entity collision > {0, number} at: {1}", largeCollisionLogSize, entity); + } + } + + private static class CollisionWarning + { + public ChunkCoordinates chunkCoords; + public int dimensionId; + + public CollisionWarning(World world, Entity entity) + { + this.dimensionId = world.provider.dimensionId; + this.chunkCoords = new ChunkCoordinates(entity.chunkCoordX, entity.chunkCoordY, entity.chunkCoordZ); + } + + @Override + public boolean equals(Object otherObj) + { + if (!(otherObj instanceof CollisionWarning) || (otherObj == null)) return false; + CollisionWarning other = (CollisionWarning) otherObj; + return (other.dimensionId == this.dimensionId) && other.chunkCoords.equals(this.chunkCoords); + } + + @Override + public int hashCode() + { + return chunkCoords.hashCode() + dimensionId; + } + } + + public static boolean canTileEntityTick(TileEntity tileEntity, World world) + { + if (tileEntity == null || world.tileentityConfig == null) return false; + if (MinecraftServer.tileEntityConfig.skipTileEntityTicks.getValue()) + { + TileEntityCache teCache = tileEntityCache.get(tileEntity.getClass()); + if (teCache == null) + { + String teConfigPath = tileEntity.getClass().getName().replace(".", "-"); + teConfigPath = teConfigPath.replaceAll("[^A-Za-z0-9\\-]", ""); // Fix up odd class names to prevent YAML errors + teCache = new TileEntityCache(tileEntity.getClass(), world.getWorldInfo().getWorldName().toLowerCase(), teConfigPath, world.tileentityConfig.getBoolean(teConfigPath + ".tick-no-players", false), world.tileentityConfig.getInt(teConfigPath + ".tick-interval", 1)); + tileEntityCache.put(tileEntity.getClass(), teCache); + } + + // Tick with no players near? + if (!teCache.tickNoPlayers && !world.isActiveBlockCoord(tileEntity.xCoord, tileEntity.zCoord)) + { + return false; + } + + // Skip tick interval + if (teCache.tickInterval > 0 && (world.getWorldInfo().getWorldTotalTime() % teCache.tickInterval == 0L)) + { + return true; + } + return false; + } + return true; + } + + public static boolean canUpdate(TileEntity tileEntity) + { + if (tileEntity == null || !tileEntity.canUpdate() || MinecraftServer.bannedTileEntityUpdates.contains(tileEntity.getClass())) return false; // quick exit + return true; + } + + public static void writeChunks(File file, boolean logAll) + { + try + { + if (file.getParentFile() != null) + { + file.getParentFile().mkdirs(); + } + + FileWriter fileWriter = new FileWriter(file); + JsonWriter writer = new JsonWriter(fileWriter); + writer.setIndent(" "); + writer.beginArray(); + + for (net.minecraft.world.WorldServer world : MinecraftServer.getServer().worlds) + { + writer.beginObject(); + writer.name("name").value(world.getWorld().getName()); + writer.name("dimensionId").value(world.provider.dimensionId); + writer.name("players").value(world.playerEntities.size()); + writer.name("loadedChunks").value(world.theChunkProviderServer.loadedChunkHashMap.size()); + writer.name("activeChunks").value(world.activeChunkSet.size()); + writer.name("entities").value(world.loadedEntityList.size()); + writer.name("tiles").value(world.loadedTileEntityList.size()); + + TObjectIntHashMap chunkEntityCounts = new TObjectIntHashMap(); + TObjectIntHashMap classEntityCounts = new TObjectIntHashMap(); + TObjectIntHashMap entityCollisionCounts = new TObjectIntHashMap(); + Set collidingCoords = new HashSet(); + for (int i = 0; i < world.loadedEntityList.size(); i++) + { + Entity entity = (Entity) world.loadedEntityList.get(i); + ChunkCoordIntPair chunkCoords = new ChunkCoordIntPair((int) entity.posX >> 4, (int) entity.posZ >> 4); + chunkEntityCounts.adjustOrPutValue(chunkCoords, 1, 1); + classEntityCounts.adjustOrPutValue(entity.getClass(), 1, 1); + if ((entity.boundingBox != null) && logAll) + { + ChunkCoordinates coords = new ChunkCoordinates((int)Math.floor(entity.posX), (int)Math.floor(entity.posY), (int)Math.floor(entity.posZ)); + if (!collidingCoords.contains(coords)) + { + collidingCoords.add(coords); + int size = entity.worldObj.getEntitiesWithinAABBExcludingEntity(entity, entity.boundingBox.expand(1, 1, 1)).size(); + if (size < 5) + { + continue; + } + entityCollisionCounts.put(entity, size); + } + } + } + + TObjectIntHashMap chunkTileCounts = new TObjectIntHashMap(); + TObjectIntHashMap classTileCounts = new TObjectIntHashMap(); + writer.name("tiles").beginArray(); + for (int i = 0; i < world.loadedTileEntityList.size(); i++) + { + TileEntity tile = (TileEntity) world.loadedTileEntityList.get(i); + if (logAll) + { + writer.beginObject(); + writer.name("type").value(tile.getClass().toString()); + writer.name("x").value(tile.xCoord); + writer.name("y").value(tile.yCoord); + writer.name("z").value(tile.zCoord); + writer.name("isInvalid").value(tile.isInvalid()); + writer.name("canUpdate").value(tile.canUpdate()); + writer.name("block").value("" + tile.getBlockType()); + writer.endObject(); + } + ChunkCoordIntPair chunkCoords = new ChunkCoordIntPair(tile.xCoord >> 4, tile.zCoord >> 4); + chunkTileCounts.adjustOrPutValue(chunkCoords, 1, 1); + classTileCounts.adjustOrPutValue(tile.getClass(), 1, 1); + } + writer.endArray(); + + if (logAll) + { + writeChunkCounts(writer, "topEntityColliders", entityCollisionCounts, 20); + } + writeChunkCounts(writer, "entitiesByClass", classEntityCounts); + writeChunkCounts(writer, "entitiesByChunk", chunkEntityCounts); + + writeChunkCounts(writer, "tilesByClass", classTileCounts); + writeChunkCounts(writer, "tilesByChunk", chunkTileCounts); + + writer.endObject(); // Dimension + } + writer.endArray(); // Dimensions + writer.close(); + fileWriter.close(); + } + catch (Throwable throwable) + { + MinecraftServer.getServer().logSevere("Could not save chunk info report to " + file); + } + } + + private static void writeChunkCounts(JsonWriter writer, String name, final TObjectIntHashMap map) throws IOException + { + writeChunkCounts(writer, name, map, 0); + } + + private static void writeChunkCounts(JsonWriter writer, String name, final TObjectIntHashMap map, int max) throws IOException + { + List sortedCoords = new ArrayList(map.keySet()); + Collections.sort(sortedCoords, new Comparator() + { + @Override + public int compare(T s1, T s2) + { + return map.get(s2) - map.get(s1); + } + }); + + int i = 0; + writer.name(name).beginArray(); + for (T key : sortedCoords) + { + if ((max > 0) && (i++ > max)) + { + break; + } + if (map.get(key) < 5) + { + continue; + } + writer.beginObject(); + writer.name("key").value(key.toString()); + writer.name("count").value(map.get(key)); + writer.endObject(); + } + writer.endArray(); + } + + public static void dumpHeap(File file, boolean live) + { + try + { + if (file.getParentFile() != null) + { + file.getParentFile().mkdirs(); + } + Class clazz = Class.forName("com.sun.management.HotSpotDiagnosticMXBean"); + MBeanServer server = ManagementFactory.getPlatformMBeanServer(); + Object hotspotMBean = ManagementFactory.newPlatformMXBeanProxy(server, "com.sun.management:type=HotSpotDiagnostic", clazz); + Method m = clazz.getMethod("dumpHeap", String.class, boolean.class); + m.invoke(hotspotMBean, file.getPath(), live); + } + catch (Throwable t) + { + logSevere("Could not write heap to {0}", file); + } + } + + public static void enableThreadContentionMonitoring() + { + if (!MinecraftServer.cauldronConfig.enableThreadContentionMonitoring.getValue()) return; + java.lang.management.ThreadMXBean mbean = java.lang.management.ManagementFactory.getThreadMXBean(); + mbean.setThreadContentionMonitoringEnabled(true); + } +} diff --git a/src/main/java/net/minecraftforge/cauldron/CauldronUtils.java b/src/main/java/net/minecraftforge/cauldron/CauldronUtils.java new file mode 100644 index 0000000..e1f737d --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/CauldronUtils.java @@ -0,0 +1,147 @@ +package net.minecraftforge.cauldron; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import cpw.mods.fml.relauncher.FMLRelaunchLog; + +import org.bukkit.inventory.InventoryHolder; + +import net.minecraft.server.MinecraftServer; +import net.minecraft.tileentity.TileEntity; + +public class CauldronUtils { + private static boolean deobfuscated = false; + + public static boolean isOverridingUpdateEntity(Class c) + { + Class clazz = null; + String method = deobfuscatedEnvironment() ? "updateEntity" : "func_145845_h"; // updateEntity + try + { + clazz = c.getMethod(method).getDeclaringClass(); + } + catch (Throwable e) + { + //e.printStackTrace(); no need for spam + } + + return clazz != TileEntity.class; + } + + public static boolean canTileEntityUpdate(Class c) + { + boolean canUpdate = false; + try + { + Constructor ctor = c.getConstructor(); + TileEntity te = ctor.newInstance(); + canUpdate = te.canUpdate(); + } + catch (Throwable e) + { + // ignore + } + return canUpdate; + } + + public static void dumpAndSortClassList(List> classList) + { + List sortedClassList = new ArrayList(); + for (Class clazz : classList) + { + sortedClassList.add(clazz.getName()); + } + Collections.sort(sortedClassList); + if (MinecraftServer.tileEntityConfig.enableTECanUpdateWarning.getValue()) + { + for (String aSortedClassList : sortedClassList) { + MinecraftServer.getServer().logInfo("Detected TE " + aSortedClassList + " with canUpdate set to true and no updateEntity override!. This is NOT good, please report to mod author as this can hurt performance."); + } + } + } + + public static boolean migrateWorlds(String worldType, String oldWorldContainer, String newWorldContainer, String worldName) + { + boolean result = true; + File newWorld = new File(new File(newWorldContainer), worldName); + File oldWorld = new File(new File(oldWorldContainer), worldName); + + if ((!newWorld.isDirectory()) && (oldWorld.isDirectory())) + { + MinecraftServer.getServer().logInfo("---- Migration of old " + worldType + " folder required ----"); + MinecraftServer.getServer().logInfo("Cauldron has moved back to using the Forge World structure, your " + worldType + " folder will be moved to a new location in order to operate correctly."); + MinecraftServer.getServer().logInfo("We will move this folder for you, but it will mean that you need to move it back should you wish to stop using Cauldron in the future."); + MinecraftServer.getServer().logInfo("Attempting to move " + oldWorld + " to " + newWorld + "..."); + + if (newWorld.exists()) + { + MinecraftServer.getServer().logSevere("A file or folder already exists at " + newWorld + "!"); + MinecraftServer.getServer().logInfo("---- Migration of old " + worldType + " folder failed ----"); + result = false; + } + else if (newWorld.getParentFile().mkdirs() || newWorld.getParentFile().exists()) + { + MinecraftServer.getServer().logInfo("Success! To restore " + worldType + " in the future, simply move " + newWorld + " to " + oldWorld); + + // Migrate world data + try + { + com.google.common.io.Files.move(oldWorld, newWorld); + } + catch (IOException exception) + { + MinecraftServer.getServer().logSevere("Unable to move world data."); + exception.printStackTrace(); + result = false; + } + try + { + com.google.common.io.Files.copy(new File(oldWorld.getParent(), "level.dat"), new File(newWorld, "level.dat")); + } + catch (IOException exception) + { + MinecraftServer.getServer().logSevere("Unable to migrate world level.dat."); + } + + MinecraftServer.getServer().logInfo("---- Migration of old " + worldType + " folder complete ----"); + } + else result = false; + } + return result; + } + + public static InventoryHolder getOwner(TileEntity tileentity) + { + org.bukkit.block.BlockState state = tileentity.worldObj.getWorld().getBlockAt(tileentity.xCoord, tileentity.yCoord, tileentity.zCoord).getState(); + + if (state instanceof InventoryHolder) + { + return (InventoryHolder) state; + } + + return null; + } + + public static boolean deobfuscatedEnvironment() + { + try + { + // Are we in a 'decompiled' environment? + byte[] bs = ((net.minecraft.launchwrapper.LaunchClassLoader)CauldronUtils.class.getClassLoader()).getClassBytes("net.minecraft.world.World"); + if (bs != null) + { + //FMLRelaunchLog.info("Managed to load a deobfuscated Minecraft name- we are in a deobfuscated environment. Skipping runtime deobfuscation"); + deobfuscated = true; + } + } + catch (IOException e1) + { + } + return deobfuscated; + } +} diff --git a/src/main/java/net/minecraftforge/cauldron/CompatibilityMarker.java b/src/main/java/net/minecraftforge/cauldron/CompatibilityMarker.java new file mode 100644 index 0000000..fc14ba8 --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/CompatibilityMarker.java @@ -0,0 +1,5 @@ +package net.minecraftforge.cauldron; + +public class CompatibilityMarker { + +} diff --git a/src/main/java/net/minecraftforge/cauldron/TileEntityCache.java b/src/main/java/net/minecraftforge/cauldron/TileEntityCache.java new file mode 100644 index 0000000..6627cc2 --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/TileEntityCache.java @@ -0,0 +1,21 @@ +package net.minecraftforge.cauldron; + +import net.minecraft.tileentity.TileEntity; + +public class TileEntityCache { + + public Class tileEntityClass; + public boolean tickNoPlayers = false; + public int tickInterval = 1; + public String configPath; + public String worldName; + + public TileEntityCache(Class tileEntityClass, String worldName, String configPath, boolean tickNoPlayers, int tickInterval) + { + this.tileEntityClass = tileEntityClass; + this.worldName = worldName; + this.tickNoPlayers = tickNoPlayers; + this.tickInterval = tickInterval; + this.configPath = configPath; + } +} diff --git a/src/main/java/net/minecraftforge/cauldron/VersionInfo.java b/src/main/java/net/minecraftforge/cauldron/VersionInfo.java new file mode 100644 index 0000000..63f7277 --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/VersionInfo.java @@ -0,0 +1,109 @@ +package net.minecraftforge.cauldron; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; + +import argo.jdom.JdomParser; +import argo.jdom.JsonNode; +import argo.jdom.JsonRootNode; + +import com.google.common.base.Charsets; +import com.google.common.base.Splitter; +import com.google.common.base.Throwables; +import com.google.common.collect.Iterables; +import com.google.common.io.ByteStreams; +import com.google.common.io.Files; +import com.google.common.io.OutputSupplier; + +public class VersionInfo { + public static final VersionInfo INSTANCE = new VersionInfo(); + public final JsonRootNode versionData; + + public VersionInfo() + { + InputStream installProfile = getClass().getResourceAsStream("/cauldron_libs.json"); + JdomParser parser = new JdomParser(); + + try + { + versionData = parser.parse(new InputStreamReader(installProfile, Charsets.UTF_8)); + } + catch (Exception e) + { + throw Throwables.propagate(e); + } + } + + public static String getProfileName() + { + return INSTANCE.versionData.getStringValue("install","profileName"); + } + + public static String getVersionTarget() + { + return INSTANCE.versionData.getStringValue("install","target"); + } + public static File getLibraryPath(File root) + { + String path = INSTANCE.versionData.getStringValue("install","path"); + String[] split = Iterables.toArray(Splitter.on(':').omitEmptyStrings().split(path), String.class); + File dest = root; + Iterable subSplit = Splitter.on('.').omitEmptyStrings().split(split[0]); + for (String part : subSplit) + { + dest = new File(dest, part); + } + dest = new File(new File(dest, split[1]), split[2]); + String fileName = split[1]+"-"+split[2]+".jar"; + return new File(dest,fileName); + } + + public static String getVersion() + { + return INSTANCE.versionData.getStringValue("install","version"); + } + + public static String getWelcomeMessage() + { + return INSTANCE.versionData.getStringValue("install","welcome"); + } + + public static String getLogoFileName() + { + return INSTANCE.versionData.getStringValue("install","logo"); + } + + public static JsonNode getVersionInfo() + { + return INSTANCE.versionData.getNode("versionInfo"); + } + + public static File getMinecraftFile(File path) + { + return new File(new File(path, getMinecraftVersion()),getMinecraftVersion()+".jar"); + } + public static String getContainedFile() + { + return INSTANCE.versionData.getStringValue("install","filePath"); + } + public static void extractFile(File path) throws IOException + { + INSTANCE.doFileExtract(path); + } + + private void doFileExtract(File path) throws IOException + { + InputStream inputStream = getClass().getResourceAsStream("/"+getContainedFile()); + OutputSupplier outputSupplier = Files.newOutputStreamSupplier(path); + System.out.println("doFileExtract path = " + path.getAbsolutePath() + ", inputStream = " + inputStream + ", outputSupplier = " + outputSupplier); + ByteStreams.copy(inputStream, outputSupplier); + } + + public static String getMinecraftVersion() + { + return INSTANCE.versionData.getStringValue("install","minecraft"); + } +} \ No newline at end of file diff --git a/src/main/java/net/minecraftforge/cauldron/api/Cauldron.java b/src/main/java/net/minecraftforge/cauldron/api/Cauldron.java new file mode 100644 index 0000000..7f8f63a --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/api/Cauldron.java @@ -0,0 +1,29 @@ +package net.minecraftforge.cauldron.api; + +import net.minecraftforge.cauldron.api.inventory.BukkitOreDictionary; + +/** + * Represents the Bukkit plugin interface to Cauldron, for version and singleton handling + */ +public class Cauldron { + private static CauldronApi instance; + public static void setInterface(CauldronApi cauldron) { + if (instance != null) { + throw new IllegalStateException(); + } + instance = cauldron; + } + + /** + * Gets the current CauldronApi singleton + * + * @return current instance of CauldronApi. will always be present. + */ + public static CauldronApi getInterface() { + return instance; + } + + public static BukkitOreDictionary getOreDictionary() { + return instance.getOreDictionary(); + } +} diff --git a/src/main/java/net/minecraftforge/cauldron/api/CauldronApi.java b/src/main/java/net/minecraftforge/cauldron/api/CauldronApi.java new file mode 100644 index 0000000..f629ba5 --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/api/CauldronApi.java @@ -0,0 +1,22 @@ +package net.minecraftforge.cauldron.api; + +import net.minecraftforge.cauldron.api.inventory.BukkitOreDictionary; + +/** + * Represents the Bukkit plugin interface to Forge features. + */ +public interface CauldronApi { + /** + * Get the ore dictionary interface. + * + * @return ore dictionary interface + */ + public BukkitOreDictionary getOreDictionary(); + + /** + * Get the fishing interface. + * + * @return the fishing interface + */ + public Fishing getFishingInterface(); +} diff --git a/src/main/java/net/minecraftforge/cauldron/api/Fishing.java b/src/main/java/net/minecraftforge/cauldron/api/Fishing.java new file mode 100644 index 0000000..04aa7d8 --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/api/Fishing.java @@ -0,0 +1,72 @@ +package net.minecraftforge.cauldron.api; + +import com.google.common.base.Predicate; +import org.bukkit.inventory.ItemStack; + +import java.util.Random; + +/** + * Bukkit interface to Forge's FishingHooks class. + */ +public interface Fishing { + + /** + * Add a WeightedRandomFishable to the 'fish' results table. + * + * @param fish fishable item + */ + public void addFish(WeightedRandomFishable fish); + + /** + * Add a WeightedRandomFishable to the 'junk' results table. + * + * @param fish fishable item + */ + public void addJunk(WeightedRandomFishable fish); + + /** + * Add a WeightedRandomFishable to the 'treasure' results table. + * + * @param fish fishable item + */ + public void addTreasure(WeightedRandomFishable fish); + + /** + * Remove WeightedRandomFishables from the 'fish' results table. + * Modifications to the Fishable objects will not be kept. + * + * @param test a Predicate giving the removal condition + */ + public void removeMatchingFish(Predicate test); + + /** + * Remove WeightedRandomFishables from the 'junk' results table. + * Modifications to the Fishable objects will not be kept. + * + * @param test a Predicate giving the removal condition + */ + public void removeMatchingJunk(Predicate test); + + /** + * Remove WeightedRandomFishables from the 'treasure' results table. + * Modifications to the Fishable objects will not be kept. + * + * @param test a Predicate giving the removal condition + */ + public void removeMatchingTreasure(Predicate test); + + /** + * Get the item pulled up from a simulated fishing attempt. + * + * @param rand the Random instance to use + * @param baseChance roughly, a percentage chance (0-1) to + * get a fish + * @param fishingLuckEnchantmentLevel the value of {@link org.bukkit.enchantments.Enchantment#LUCK} + * on the fishing rod + * @param fishingSpeedEnchantmentLevel the value of {@link org.bukkit.enchantments.Enchantment#LURE} + * on the fishing rod + * @return the item fished + */ + public ItemStack getRandomFishable(Random rand, float baseChance, int fishingLuckEnchantmentLevel, int fishingSpeedEnchantmentLevel); + +} diff --git a/src/main/java/net/minecraftforge/cauldron/api/WeightedRandomFishable.java b/src/main/java/net/minecraftforge/cauldron/api/WeightedRandomFishable.java new file mode 100644 index 0000000..9441d6b --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/api/WeightedRandomFishable.java @@ -0,0 +1,65 @@ +package net.minecraftforge.cauldron.api; + +import org.bukkit.inventory.ItemStack; + +public class WeightedRandomFishable { + private ItemStack itemStack; + private int weight; + private boolean hasRandomEnchantments; + private float damageFraction; + + public WeightedRandomFishable(ItemStack itemStack, int weight) { + this.itemStack = itemStack; + this.weight = weight; + } + + /** + * Setting this value results in fished items having random damage when fished. The damage is in a triangular + * random distribution (think about rolling 2 dice), with the wide end at 100% and + * the narrow end at (100% - damageFraction). + * + * For use in a chaining constructor. + * + * @param damageFraction low boundary for random distribution + * @return this WeightedRandomFishable, for chaining + */ + public final WeightedRandomFishable withDamageFraction(float damageFraction) { + damageFraction = damageFraction; + return this; + } + + /** + * Mark this WeightedRandomFishable as receiving random enchantments. + * @return this WeightedRandomFishable, for chaining + */ + public final WeightedRandomFishable withRandomEnchantments() { + hasRandomEnchantments = true; + return this; + } + + /** + * Set whether this WeightedRandomFishable receives random enchantments. + * (Use this method if loading from another source, such as a config file.) + * @return this WeightedRandomFishable, for chaining + */ + public final WeightedRandomFishable withRandomEnchantments(boolean hasEnchants) { + hasRandomEnchantments = hasEnchants; + return this; + } + + public ItemStack getItemStack() { + return itemStack; + } + + public int getWeight() { + return weight; + } + + public boolean hasRandomEnchantments() { + return hasRandomEnchantments; + } + + public float getDamageFraction() { + return damageFraction; + } +} diff --git a/src/main/java/net/minecraftforge/cauldron/api/inventory/BukkitOreDictionary.java b/src/main/java/net/minecraftforge/cauldron/api/inventory/BukkitOreDictionary.java new file mode 100644 index 0000000..7071181 --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/api/inventory/BukkitOreDictionary.java @@ -0,0 +1,78 @@ +package net.minecraftforge.cauldron.api.inventory; + +import org.bukkit.Material; +import org.bukkit.inventory.ItemStack; + +import java.util.List; + +/** + * The Forge Ore Dictionary provides a way for multiple items to share a common + * identifier - for instance, "ingotCopper" - and be used interchangeably in + * crafting recipes. + *

+ * This class provides a read-only interface to the ore dictionary using Bukkit + * classes, instead of NMS classes. + */ +public interface BukkitOreDictionary { + /** + * If an item's damage is a wildcard, this will be returned for the item + * damage. + */ + public static final int WILDCARD_VALUE = Short.MAX_VALUE; + + /** + * Check the OreDictionaryEntry for a given name. The name can be later + * retrieved using {@link #getOreName(OreDictionaryEntry)}, and having an + * entry is required to call {@link #getDefinitions(OreDictionaryEntry)}. + * + * @param name name in the ore dictionary + * @return ore dictionary entry, or null if name is not present + */ + public OreDictionaryEntry getOreEntry(String name); + + /** + * Get the string name defined for the given OreDictionaryEntry. + *

+ * This is called by {@link OreDictionaryEntry#getName()}. + * + * @param entry ore dictionary entry + * @return ore dictionary name + */ + public String getOreName(OreDictionaryEntry entry); + + /** + * Get all of the OreDictionaryEntry objects registered to the given + * ItemStack. + * + * @param itemStack itemstack to check - amount is ignored + * @return immutable list of ore dictionary entries + */ + public List getOreEntries(ItemStack itemStack); + + /** + * Get all of the OreDictionaryEntry objects registered to the given + * material and no item damage. + * + * @param material material to check + * @return immutable list of ore dictionary entries + */ + public List getOreEntries(Material material); + + /** + * Get all of the ItemStacks registered to the given ore dictionary entry. + *

+ * Quantity should be ignored. + * + * @param entry ore dictionary entry + * @return immutable list of itemstacks + */ + public List getDefinitions(OreDictionaryEntry entry); + + /** + * Get all ore names in the dictionary. The returned list may contain + * multiple null values or duplicates. + * + * @return all ore dictionary names + */ + public List getAllOreNames(); +} diff --git a/src/main/java/net/minecraftforge/cauldron/api/inventory/OreDictionaryEntry.java b/src/main/java/net/minecraftforge/cauldron/api/inventory/OreDictionaryEntry.java new file mode 100644 index 0000000..1419b8b --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/api/inventory/OreDictionaryEntry.java @@ -0,0 +1,62 @@ +package net.minecraftforge.cauldron.api.inventory; + +import net.minecraftforge.cauldron.api.Cauldron; + +import java.util.ArrayList; +import java.util.List; + +/** + * An OreDictionaryEntry is an opaque reference to an entry in the Forge Ore + * Dictionary. This class has reference equality. + */ +public class OreDictionaryEntry { + private static List oreDictionaryEntries = new ArrayList(); + + /** + * Get an OreDictionaryEntry instance, using an instance cache to preserve + * reference equality. + * + * @param id opaque ore dictionary id + * @return object wrapper around id + */ + public static OreDictionaryEntry valueOf(int id) { + if (id < 0) throw new IllegalArgumentException("ore dictionary IDs are not negative"); + + while (oreDictionaryEntries.size() < id + 1) { + oreDictionaryEntries.add(new OreDictionaryEntry(oreDictionaryEntries.size())); + } + return oreDictionaryEntries.get(id); + } + + private int id; + private OreDictionaryEntry(int id) { + this.id = id; + } + + /** + * Get the opaque ID of this ore-dictionary entry. + * + * Plugins should not inspect the results of this call. Results may not be + * the same across multiple server startups. + * + * @return Opaque id number. + */ + public int getId() { + return id; + } + + /** + * Request the Ore Dictionary for the string identifier of this entry. + * + * @return ore dictionary string + * @see net.minecraftforge.cauldron.api.inventory.BukkitOreDictionary#getOreName(OreDictionaryEntry) + */ + public String getName() { + return Cauldron.getOreDictionary().getOreName(this); + } + + @Override + public String toString() { + return String.format("OreDictionary{id=%d,name=%s}", id, getName()); + } +} diff --git a/src/main/java/net/minecraftforge/cauldron/apiimpl/CauldronPluginInterface.java b/src/main/java/net/minecraftforge/cauldron/apiimpl/CauldronPluginInterface.java new file mode 100644 index 0000000..77a9c4a --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/apiimpl/CauldronPluginInterface.java @@ -0,0 +1,29 @@ +package net.minecraftforge.cauldron.apiimpl; + +import net.minecraftforge.cauldron.api.Cauldron; +import net.minecraftforge.cauldron.api.CauldronApi; +import net.minecraftforge.cauldron.api.Fishing; +import net.minecraftforge.cauldron.api.inventory.BukkitOreDictionary; +import net.minecraftforge.cauldron.apiimpl.inventory.OreDictionaryInterface; +import org.bukkit.Bukkit; +import org.bukkit.plugin.ServicePriority; + +public class CauldronPluginInterface implements CauldronApi { + private BukkitOreDictionary oreDictionary = new OreDictionaryInterface(); + private Fishing fishingInterface = new FishingInterface(); + + public void install() { + Cauldron.setInterface(this); + Bukkit.getServicesManager().register(CauldronApi.class, this, null, ServicePriority.Highest); + } + + @Override + public BukkitOreDictionary getOreDictionary() { + return oreDictionary; + } + + @Override + public Fishing getFishingInterface() { + return fishingInterface; + } +} diff --git a/src/main/java/net/minecraftforge/cauldron/apiimpl/FishingInterface.java b/src/main/java/net/minecraftforge/cauldron/apiimpl/FishingInterface.java new file mode 100644 index 0000000..bf9b9ed --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/apiimpl/FishingInterface.java @@ -0,0 +1,81 @@ +package net.minecraftforge.cauldron.apiimpl; + +import com.google.common.base.Predicate; +import net.minecraftforge.cauldron.api.Fishing; +import net.minecraftforge.cauldron.api.WeightedRandomFishable; +import net.minecraftforge.common.FishingHooks; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; + +import java.util.Random; + +public class FishingInterface implements Fishing { + private static net.minecraft.util.WeightedRandomFishable toNms(WeightedRandomFishable bukkit) { + net.minecraft.util.WeightedRandomFishable ret = + new net.minecraft.util.WeightedRandomFishable( + CraftItemStack.asNMSCopy(bukkit.getItemStack()), + bukkit.getWeight()).func_150709_a(bukkit.getDamageFraction()); + if (bukkit.hasRandomEnchantments()) { + ret.func_150707_a(); + } + return ret; + } + + private static WeightedRandomFishable toBukkit(net.minecraft.util.WeightedRandomFishable nms) { + return new WeightedRandomFishable(CraftItemStack.asBukkitCopy(nms.field_150711_b), nms.itemWeight) + .withDamageFraction(nms.field_150712_c) + .withRandomEnchantments(nms.field_150710_d); + } + + private static class PredicateProxy implements Predicate { + private Predicate bukkitPredicate; + + public PredicateProxy(Predicate predicate) { + this.bukkitPredicate = predicate; + } + + @Override + public boolean apply(net.minecraft.util.WeightedRandomFishable input) { + return bukkitPredicate.apply(toBukkit(input)); + } + } + + private static PredicateProxy toNms(Predicate predicate) { + return new PredicateProxy(predicate); + } + + @Override + public void addFish(WeightedRandomFishable fish) { + FishingHooks.addFish(toNms(fish)); + } + + @Override + public void addJunk(WeightedRandomFishable fish) { + FishingHooks.addJunk(toNms(fish)); + } + + @Override + public void addTreasure(WeightedRandomFishable fish) { + FishingHooks.addTreasure(toNms(fish)); + } + + @Override + public void removeMatchingFish(Predicate test) { + FishingHooks.removeFish(toNms(test)); + } + + @Override + public void removeMatchingJunk(Predicate test) { + FishingHooks.removeJunk(toNms(test)); + } + + @Override + public void removeMatchingTreasure(Predicate test) { + FishingHooks.removeTreasure(toNms(test)); + } + + @Override + public ItemStack getRandomFishable(Random rand, float baseChance, int fishingLuckEnchantmentLevel, int fishingSpeedEnchantmentLevel) { + return CraftItemStack.asCraftMirror(FishingHooks.getRandomFishable(rand, baseChance, fishingLuckEnchantmentLevel, fishingSpeedEnchantmentLevel)); + } +} diff --git a/src/main/java/net/minecraftforge/cauldron/apiimpl/inventory/OreDictionaryInterface.java b/src/main/java/net/minecraftforge/cauldron/apiimpl/inventory/OreDictionaryInterface.java new file mode 100644 index 0000000..b37bcec --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/apiimpl/inventory/OreDictionaryInterface.java @@ -0,0 +1,83 @@ +package net.minecraftforge.cauldron.apiimpl.inventory; + +import com.google.common.collect.ImmutableList; +import net.minecraftforge.cauldron.api.inventory.BukkitOreDictionary; +import net.minecraftforge.cauldron.api.inventory.OreDictionaryEntry; +import net.minecraftforge.oredict.OreDictionary; +import org.bukkit.Material; +import org.bukkit.craftbukkit.inventory.CraftItemStack; +import org.bukkit.inventory.ItemStack; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class OreDictionaryInterface implements BukkitOreDictionary { + private Map normalizedToCanonicalMap = null; + + private void initializeMap() { + normalizedToCanonicalMap = new HashMap(); + + for (String str : getAllOreNames()) { + if (str == null || str.isEmpty()) { + continue; + } + normalizedToCanonicalMap.put(Material.normalizeName(str), str); + } + } + + @Override + public OreDictionaryEntry getOreEntry(String name) { + if (normalizedToCanonicalMap == null) { + initializeMap(); + } + + String canonical = normalizedToCanonicalMap.get(Material.normalizeName(name)); + if (canonical == null) { + return null; + } + + return OreDictionaryEntry.valueOf(OreDictionary.getOreID(canonical)); + } + + @Override + public List getOreEntries(ItemStack itemStack) { + int[] ids = OreDictionary.getOreIDs(CraftItemStack.asNMSCopy(itemStack)); + + ImmutableList.Builder builder = ImmutableList.builder(); + for (int id : ids) { + builder.add(OreDictionaryEntry.valueOf(id)); + } + + return builder.build(); + } + + @Override + public List getOreEntries(Material material) { + return getOreEntries(new ItemStack(material)); + } + + @Override + public String getOreName(OreDictionaryEntry entry) { + return OreDictionary.getOreName(entry.getId()); + } + + @Override + public List getDefinitions(OreDictionaryEntry entry) { + @SuppressWarnings("deprecation") + List items = OreDictionary.getOres(entry.getId()); + + ImmutableList.Builder builder = ImmutableList.builder(); + for (net.minecraft.item.ItemStack nmsItem : items) { + builder.add(CraftItemStack.asCraftMirror(nmsItem)); + } + + return builder.build(); + } + + @Override + public List getAllOreNames() { + return Arrays.asList(OreDictionary.getOreNames()); + } +} diff --git a/src/main/java/net/minecraftforge/cauldron/block/CraftCustomContainer.java b/src/main/java/net/minecraftforge/cauldron/block/CraftCustomContainer.java new file mode 100644 index 0000000..24d979b --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/block/CraftCustomContainer.java @@ -0,0 +1,27 @@ +package net.minecraftforge.cauldron.block; + +import net.minecraft.inventory.IInventory; + +import org.bukkit.block.Block; +import org.bukkit.craftbukkit.CraftWorld; +import org.bukkit.craftbukkit.block.CraftBlockState; +import org.bukkit.craftbukkit.inventory.CraftInventory; +import org.bukkit.inventory.Inventory; +import org.bukkit.inventory.InventoryHolder; + +public class CraftCustomContainer extends CraftBlockState implements InventoryHolder { + private final CraftWorld world; + private final net.minecraft.inventory.IInventory container; + + public CraftCustomContainer(Block block) { + super(block); + world = (CraftWorld) block.getWorld(); + container = (IInventory)world.getTileEntityAt(getX(), getY(), getZ()); + } + + @Override + public Inventory getInventory() { + CraftInventory inventory = new CraftInventory(container); + return inventory; + } +} diff --git a/src/main/java/net/minecraftforge/cauldron/command/CauldronCommand.java b/src/main/java/net/minecraftforge/cauldron/command/CauldronCommand.java new file mode 100644 index 0000000..b29bdf2 --- /dev/null +++ b/src/main/java/net/minecraftforge/cauldron/command/CauldronCommand.java @@ -0,0 +1,258 @@ +package net.minecraftforge.cauldron.command; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import net.minecraft.server.MinecraftServer; +import net.minecraftforge.cauldron.CauldronHooks; +import net.minecraftforge.cauldron.configuration.BoolSetting; +import net.minecraftforge.cauldron.configuration.IntSetting; +import net.minecraftforge.cauldron.configuration.Setting; + +import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang.Validate; +import org.apache.commons.lang.math.NumberUtils; +import org.bukkit.ChatColor; +import org.bukkit.command.Command; +import org.bukkit.command.CommandSender; +import org.bukkit.util.StringUtil; + + +import com.google.common.collect.ImmutableList; + +public class CauldronCommand extends Command +{ + private static final List COMMANDS = ImmutableList.of("get", "set", "tick-interval", "save", "reload", "chunks", "heap"); + private static final List CHUNK_COMMANDS = ImmutableList.of("print", "dump"); + + public CauldronCommand() + { + super("cauldron"); + this.description = "Toggle certain Cauldron options"; + + this.usageMessage = "/cauldron [" + StringUtils.join(COMMANDS, '|') + "]

Ma>xzmj|d8Xr84k5kQ#8u%*@J%yU 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%0Djdp$yQ$B&pTndw_~ z6Vp?o>bDpRwi84pSvm1Lo*Q#LK>sxbxL%8=%mfx_>?~&q0zvAPe)yoSF>%7q1SkGYtuF0%LgysAL3Z4ky75uh$ zW}W!YU$aCd-Kz5^isl8Bn0Tt_Z6-uH$+uMJZoj@mHbg7Z?mKbZ6Z-B^^*k}1#IESQ z+^)1V!rE*N_$3X$wjBCtOj83WVP4bsyT`Rf|38_(E{xcTR%8f>54`_D=I=kB=KoW# z<)uX>jsHozhK^7UZzx0oS(HnNi!N?2s~*Wh$e((bGBlWUF_1g%sKkTx;QA1d+mm<5 zTxKSyu6oh)xV6#rn)~_V!_rfp944>KhfT1F>&}1s`aHS&ZKViHYEem)Jt=~7fGg0id!k!2KuDC#Y^eOsa;GeBY#Qz@Yvri(iAhj8=r+ghpu zLy^&GWExyKrcBlW3+K8yG@r~O28%69NyltGi z=HECj?2NW6?o$`v4^Wm_Sc{M<|0PJd5y&6ar&%tdKR>p&=Y*&Ja~_MV_=b+M6h?7_ zPm?>qgv`Mh`=x5GXi-m2KI^T&*F!J6iQOD7rX&dat&|nPK8LkbUxw(|kAUMJ1uraq z2W(ZCB7t@=H|M*Q0fB?OfsZwECfZ_C2&vY*?E)kN!1jbgnQudRgMD32>|6oW0<-dq zv&R69Cd|J~22{!ys%MO4P%Lh-0Gfj$XUZlXu5!hx(k9Ggvzg^LFGUl)sF|00m5-mC z>btl&xJcolCBK5N$?XxWOAAkJ{vth?J0aSa6l=^*&XElY)t>p)?(S-MqwMBa6o+eJ z*#m@2+Xp1ZASqvU9a@= za54I+l@qGuTUNOlQZwJ!6o(ZsOJ<=o(^-?O2-Eaed19!`0o2J5Y}%lqnJCFo0gXE! zwFDG3lFTL^`)dM!%zbgtipIhTDL^}Mh?u9}oooGhdnLV|G)Lcb!Yn*s!tKO46+d8 z*4~7B6j$RS_qSk}3N!V^%fhKT(tsEC9TpDR^g`LhM(vA0*?P#h=$#7b}f8vt;F5r+um` z`j8-P!{aD4>kOUi_Otv$z(Trz)xk|P(4ow01VZK+d=p`iC+6oCG?fk@7#Ra+u1eN*0b*P-}iW6f+xJ+BrF_1yc_XGLQ#LN~PUCEMt zUj_YlX*y2C52EISeA6i;$R9UrS!{5AWNi(0LQ>>7+#3XB~fF4ZNY(+$ThkhEpJ`cb;M#pvK_> zE8$NXG<;K*Dg0f#3_~#iKFrGfPwL&QNB$a8=rAJksy-)(zJ$C5);cI=1>}DptS3(Z zzJDa^=81I9>p2ft9CzE)HQ`fF)Dh^2vSp)WmfU?m9yXlf_W+cnQ*U#FWP%4@xbL8e z!hQ~Dxi7SqemAmXq=bVqZ%CTQ#=ZjoQ0InH3ro35W@^f7OuZqTofR}%Df}!`ihjDa zFOpTp4syqB(AocHFh?%mDNG+vZ)K8`IkQ5D4#Y7M?_n=QyC#KuWN2};ALrZK8|!PU zD$p~%^p!Qa&Kid62DPNKW{G3+{=QPD?*AEZO4NJCW>Ur{kV$`I_qoQB6&Y&!tzWEc zLkgO?VZmhD&_r~A!^L$8QNAcQ=1SH0T{X@d>*}TUQUNLz3U^ z4c#!oaJ)2KQkuG=sV;q&xt^4|k~G-?w|7@C(**0sD%JVdFc^1EwZxsT+6#u67vh1X zIb&-TK;*E5|gRX*S#SHv8P^ru?k}pvu}f zMA!Du_@T$MBXxSSWyi2i-RE3J@;qW@hZb|p<)A)lU7> zWImyofWDf2LjnPbKFYe99kw{)N1besK^h7J*g&1Q?IbG8AKz9eEPo)CxY^b~zrzqy zzS_a*pWEp>@0(zdUt%{q%LVj;Gz1jz$S=P4XMy8L1{QJ zw7j`wyJvqnJVgo^<-Yt35IN%XM-+hWJlUa{*fw^q zFKwVDzg3t9d&St+R8Tq*yTc!h2Awk*Eq3oSq=)krjdja zcH>DG#weYCEZ#+tc6S>R5B4iY0HBLu5O_-d8_j}L$~VPqXYhR)t|G<&ybanu^HsR) zsa+BGUVbT^nQ)Tn^Kd~ho&5&ySGrm4oBB=|4A52<-;wiZBu>(hs5q(2~`DvH^Wfjrjw5g|m5Zjno-_=S-Z zM3Rpx7Y{v-2mG3gyGgrK#y)JK|3%q3Hd)qa>9*3Uv~AnAZQHh8>8!ME+qP}ns$-$HgtH}&t0Qt{jgue|B0Ow-n1#x0^49%8 zu?cF?5+dQSbmuOa1g^FJ?r{R%K3@IHoFqL8;Qj(pgO0Bd}VXG>2d$>hnyd6S)RM- z>ygkg7{*`GPyWw_>9ug2qO6M($F-tb#7jdZtJ4Cx9&6d^)Z2P zH~zE8fs7>a%b*_$on-$PPMpIp10bXUAV`Qk*V#N6P$WO5?dEOOCp}5`?@E06Y!C%7 zZZIr3=`-Ues$}ZojY2Be#w$Zc;fO+;%7wEw&Iy<4`cUQa_G}Cs<}9V1EfTy{au&yp z^cd`5gtJ9EP+t|PHnS?F#QqrURb}0F&0X!-KPwEo!rh@yJ&RWb+QOHLvP#OZqj#&a zol5G&cIS-F1$0kf_aqG3bBF>_$n7XjsT{${O9}IU>qJBtQ&e)wMJo#HN=~8o!vV*P zVPWgI;5f091mI$zA6Nf0&VaaxQ7l*9l4!0bETK|DNKQXl+7~+?Lt`{fGHh404rkOW z36uOCs(`x8)NohH+{j-Du9!$OdR`wq?^tHC@|ikiRVXL6B&7S!!n^zD_sx09u|(mG z3>O@pVNu7ENnLs<#RHzpHEEG2Wb~W{mlaW*qPneih12oG;|MU@%NU#RL)2Ilpv?Ip zbWAPY;Gdu-!m}{`!Spsj5|(z|rYQe_ZI(QdENpQDFtk`^GsW2ZZu}4FE}icxc<28^Zg@=7vzW{evER=d}Bz} zu#qc8zeF(I&C~@<^62F#lmfb$B|ekXS|gKTOIffz5C8ux>}e=SPF00;M?P`uK+SfSml zr_)4vgdGUEc$lPo?Q=Flx#&Pe&wz4x!MH;p#A%%6`_i!Fk%2mx1BY_jkO;zi6Zp;F ze0+|%^V!`!DXOKbOQaFdq3CyvRurT$%3k8lw2Cb;dPUd8lGVG%GJ{Gn8#1C%E5$L43`j$!gfW#0l_5Br9z zu4E?9;xJg(!at}nJ2D1owq=JXQ$POLd_FUt@XjsE4Jk*blsqCvXr&<9k3MwPLyxX7fR+0PP2#Jgzu37QD}SdUA_f4w7AaF%057oa;j;cgCS2<4F?$G>+r zB`zjwTH-K=6kiaT$ri{Tl(I!0<=Fv;E`&6fLi%NvNok(sZG^phe>I^Cw5uC+0W{M- zK(4@p!x@^eFEpyarSpn0;rD>^?9$^kbL^RtKvXL!IWI5FGEPD}?{@zktvg2GMjW{o zlx0Lu`zrA^wroktYw{CcRMW3G4Cgfh{oaj-=a?~D2l0b56!DI?$N_DEYXL_8mO7_&H?X-QG;EeyGs%9cOKiJGNr`9I^%qKit*d)o zJ&S8WsXUw2l;9tW)a-IH_0F!`J>kmf?Eu#Mc7|AtZ zW?QVz0ZCe`{kH zbv}B?cZHB|;#9lD5od~rAg=FKpD{0m1Q^eJuzv3_HLeQ{${YA}O0@KhGQLSmRpN{` z>%+CmD@8Osm$Yuob;`B+>TYz#ZKZ-c2;^6YWX3x=fsoC`k)@<68%o5O2Vj zd_>%Ra)Hi+Z1WvrB9#$HUe9yPZ6H4%RH#X(s@PNE zgEexy*n^8i%e!EO87DXy-lbJyBkN(M{`#x>3(NE;x{P9}(=t5dZVnKj*$FA7B`kf_ zndykzU1Csu(@gim(vD8&fpg*CGqdRXls5D5+Kms|MJ#-2>qNHV2H4&<7ekZc_PLVj zGykt+Ls%!;r!gQ1pa6^xGXL(_@IOWYn+bp@K$rYQq%*S9kvuzisx2`b^N%313e+J| zafRqb)45BfT@A^2DYD5=_=<&cKJy#r6;1D}Zu$4g)|cEL zGW%71l+-ME7|MysF{_mtIp&-tEZ#ZV?Khje+;#YAUlAuEt+6Pm8_$}de!O>Q-%iI$-5WLEo!yUH0k)P(ZPKc zyRVAzlt88!cC{jqN#Ei|SegN@-%FHn^Yl%0vpN=2&{>%3_rQN}otdYp8)<>MdHGhB zKn9_vd-~b~x!AP8r0ZBBG1Q9cRS4D{c~(uhq0h&*+dMvU)}g|uja}g?>q05TjOcby z+cYr*TYz`nsw=qYJb@v^|6s?=->82h-NZ)9lwZ^lhLNyAljszVCaKYIkXdUr>T;LC zRQ;7k>)926 zs3>(57+Fs?_6M}F_emz}5GdSBUiHgdvkX}ez+CA-L~}Mv1p19Uh2@kq20I6bQrT=* zyAYo3GXI(e;U-n#VY8dRwmgPKuBX_xiy=&C9c$^Gxlbv#Y$>>`vVN7NoB4YsY)RH- zh0E3^_Wv@yIBq@yi~}?&hMexKUYi_~d z^%1Fi21{nc5oeo~agzJt$m-G`D1>F6vkK9Coen>N{uo&vYTNj8eshrC^c?_lfEWgH zKn@^GC?78n@zAqSdSB{Jv3eMW^fpvNon~cBXb6lcqojfqN#TfJ9c+SI7GCuwqb0H;n9g@6ij!a|5zUiZGEzAfZmmIAV=T1Q z=Qck=_ipNFz5bIGAJ2-9UB=h3{t;7r0+0i&*>h@x|0@S57y;w}a@1_K6qpnIj3j(A z^Y`nwK=l{YC4d~@0V{e)-0M!=qDjyAcv9c?7`149z$jq|0+0iU&5$e;gWk}OiY{LG z|F;~VJKRHD3;M?oZqy$?nEuU|`9G5Ya}{D$l)rfCByrJTYkR=s5wJo(D5=f^DFR8c zG*LGrOv4xkEF>7xDXi(&yl-H=M?=?)Zo0po!oJSnzw+@m6?6Yi{t0k?QAUI$VaommnscH3CoEqkDt^xaaw7eFp8D5vnS)q zU|`Y*_l1fp<#Xnfhh?h6<5>>T((3^GiJM5bQ`gDbICgq5r8l@t%8)Wocj8(<6^V_$ ziXFoR)D-uvZ{c+=TKej`lbM-84pS>|*=riClCDQ%9-8s6X042hO||7HKrVJ9OL^}j zm+81@_jNyHe7XHWM^Hp()}h(^!;)CCOu7fXioZ7+O7SEpoc_x!It?>`)>v9_^!oj@e?92P{i=bgv+a9h!s8+qRLuM$hn@bK$at=)sb#8 zm2)dVUrbR|x|j)r0{iHc!;s))cfY?v>WfpU4%)Gr_eYGi9RelFXzR zw1B%82e%aoZTfDIDejYDb5l!e-#eJT_n(z;^banXr+36bKfXs}e@hkomqUS%FM^VI z#}QZQ# znM&Yc6$inI4ihA`e1mnJkXrCHafl^(Q!J-IPJ0R|JsV&+LJvvl$r(;mHgMPyy#i%6 zC0Ao)#=RiJPK`+&AJD<92EW@$DI~}Li@y=qpz}9k%gJ^&Bq5KH()Pu@MlKa z6Xxm}U55hS{xaz&>&=XUDIE$0lz>R6qMiT<+aVG;YHna0Rf4@3Dyxb7id?l-W@1(=#w|`+v z*ZpKi>`Fdw$uw4d#m7K`BBuLL3*%zA&@9(%%`=flJ*sY-7O$~4$3kCtI*`j@ji6JZ zZQZ*zZG(BKbB3i{gcy?+(#31?!M{#T9RLCD@z}xB9tp(YKGhf3ozfj10GdBCu-d|K z5~9@qfvZ?oIhNsa{c+sjJHs@pN{O0w(f8+(nFia~WlGE3IyL0ZGxY4E*U;kp>^4Kt6UfTE^@FP>bEMI6R-H!neJzR~5`tg|1o^{+W`~lof3C ze5HpbUH=nqZn0zr^lB6Wojp8VvXGve%c3YdIl<4Fqg-3lQy2ohd~zm0FL~ErONafr zb(wbXJDW^ZZy#)-6SBPLuL>J3yBljUu|G>X%K~rL8xy#;*;CJYk!cK;O}W`f(z4bo ziwHG$X$c=LRXyIy=_}T5L>&;Y&%JO2b**!8dg0z#3{T8`Skf4_&-;}qjrgy_%+IH? zWLm`m`s`?&V>T&tN1B>!K?^L_m+5)>5wf*M{C94}Tz!FHOYly- zHHDT;ET^f~3%*sjeu)}F_M+-+k+o%1tFib*35KSYX2K<}W!BrR-=@fPz<;?sc0~|J z;mv_!=Wb8RMy{bZ#4HpEQ6$aZ5DI?gPs^c+^XIPiM_y36gAneHfiR9E*cVrCQh0K= zocf5jJloaWgnDC0xhTdw>p+V$Pbsm?&RfEXvjWLtC$NOrrB5#8y8nH<;@2z~iQtiD z_0(teOtHGBS)MYc9No(`ZJV7Ji=pX}$T3=*?04=ORPrTpFLWL;tCJsE?&w@WjfhKH z=#VIL1&6q-S$nOy?&qn);-WFP{^O#v%H1dRhayE@C>i>N*RA%Y{Q+q5O4w$g9u6OQ zEI=B(!OT(sE(_#H8Tc)VI~REj9rT_vz(7v>Y+ zLgV^>9@v%MxIZ3io1P#ly)lU43{MwQr`+tHT;cRh#jSWAt#y`}C7xypaHs4wp2g-CDb+T6eoQNm?V+nQ`Qepak=VFqO2j;43;+T@6GQVlyb{r=%|U;7hc6$?VW z-GuzW>gYFV9NSG9nOp~bWP;q!-SE|=Z%$%m6 zJFVk7Z9uW3POOCc}kAFQn{i0=RQX(E~n7G@I{%HEh5 z__QCv;c-=3FDZ}4B*(jZ#XwjKi~rq!lZGWbw(@TPJ~<%(v|8wYJE@A<*c-Yyll<%P z|6$dtfMzF<6&wY4%dz&;M7=ffe5DYJ_59Iz=Fa#tT z0U^(ieW2`hUJ5*k*Tl{2>lvSi=*w&Wx5MAeKPn7M1qSyeeXI1Ut&+=dYnirM!bX3h z9k!^Nx(q~R)^M&kR1^){Y`ad3m1`2^%Uhf@vE#176V8=>NeGoCxJ+v#n+fBv=Zov^ z*p#gpcd+WLvs-NKVK3Kour9^0M~VSJ^@?n#6g#ouKcJeA#Eb=D?1j1M{^H@;Z{(gh zNFYal|1DmTAQHNmi5har>igr?b+SQso7Hx*e8DSgb08+RL_b3P48P$-T!3ISwj5ca z_5pyZ^|8JHs9G?Rh$wERE;J#8xcr3$2~P10(NZ$gc5(0nd2DX3Nv4%CUF|GYt-kbE z?ukT^(d-ZCJOwig3YtA<@w6C$!{_h5mr^Qr0x47!ySpigSR^15@few-e3c)Z@sY($ zKu2myocHHx$gq|ugjywwRD2uR1pY6@j%|XDC*=s`ugdE*lD&?evg<@n9N4>fpG zSh!$~^(=c2RMDT93gOO?3(Dh|6WrC=X(#M-KRwtS>UJCG_V12- zD-qHUFh4PFwx!8*31U-nPLb?X9-T>hI)qx*2MNAxTk)2_sAUHV?;=`wVgH{7y&#l| zl$&U7G-e{*JD4cX&^R0*T4al?j5>m(@+ImR)l+uhjN4YdY2ckCa^)F^j8 z`D<9^GwSoj2H;Zzx?v1#%t#nxem%_>9=j?P3BkZ$n=41y1Cuojlc>pjG#;R+Wl6oL zwTXzypqHuan`iiorHw;20!#E6TEdY!g>RryymCw1@vh2k%i`FG_Ha4-7&8E1bsK(U znasUg^hTj1<7*^d^k-MmyD0!xj~LM)Q|J@kr*>~+>b`DhNlIesCx==2&=B`7!4@K2 z)F6*-1a8bOSJSHp%d?8tJi8@b`|=vz7cOT*bhK<_rpz;9;v124CChA2?WbImA(Nzj z?^}FczZFyGWoFBWM6)Ck0wYc`A<>@2IJ}ObTxT@tFx!b#)t3yy>ozXIgd+`c^7{Ij z1j2L1W%JF615N@sPqri66VUU@VN0yU$)BSL2x_fMC^0uISgy7!7&Z>b-O7t%S3-6$#{f=;VqrSwfVKSg6CA8@Au}EL>j@Sf{^7zzQ7WEp&*m z)GbnLU}HyUgbvuM?<)&RijQs`9~CY;lD=wI1Wo@Y3!ti6Q$C5%FHA_EmaxBj=;lN| z4XajsvmT+YBBHQMbkZ;DCjw}7kjPKw+>ww-6y6xYkVu=bZ;q%S^86=B$AkJY1FmWQ z1}H#Z9c#phOvUWH-8U{04ANaghNZ{FPN z*Jm){Q3fW}?Tn)mnvexKGHP~24AFfHm#A~fa~Yu!isH4^h*dE)=u^B9=iG|FziQ&b zTtaw+fB==iA>{L4rI5ePEogIyg`CLmfOUtY8)E#sjdTXg;g5Y_(>)7`wj#I{3B>OP zh&i%|Tvo*4?KrfFujQfrcN6_kzBUq%QH1}Z;~HCBZRYrZ$##jk-GL8V&=Kz}&~=aF z1?le0pE)6o^JT5$1R#zw^!QSU_ZFsok`}AR8fnp^`2_Vk&|plk9#WV|r#NXR_~1-1 z{<@4Yy6(3hSLz!E;Oc|;>6jA$uEtvz8WS+tMVx<0>VPjJ<14_Nu3iU)shcCl5%rR6 zBS^H>cvT67)0YTcMCFS)-nYl07Cnxcx*v;JD3p>P#CUI7BAj0!?oI(pXW_rM#&l*W zRPG#bUK^=YJTcg><4LaUd5H4@FKWu*m9T`>wA$T@s)S;VYR0qj-B|RX*LbA>Tq4gl ze~m~JB=m~}$>m}?^2VM$vhIAOkeG?EA-TG3YW$J=-!|G%mAro&0f03DV0w`LHz$Yx zkyo$V{i7>S9opRq|UrG+e@STP2Oz_$uLI8>f^6ee17ovQ^Vg5fJB0# zhF8q`fa3#aIReX4@(>Kin_p*hI$yWD+kHNLl#2ckcT_c)IkSG)n0G2ae3S}3#7Lo= z&M{8SX)~LBoc7$Nrc5b(+xZ*%cj=NNw37Ev2JUnPcQ<)P!meIO_=L%FhDa_#XiS{*Y0`lnhVu z$-q!gVh_)k(eGJ($Bd?Q2)nz0jjeQRXdTPgXco3wP2X+gwv6fMNY?0PjZ_iHM8_)R za5tLK6;I^#EeZ84pIeQa*CDey&JfwP0Zj;oAXlhsCvKJwaUD#?-#b@cWcvFCHb=uHM5@(t*{ zi`II}f|}ELgkDe0+cpOrRIqo+w3nGGYiUWmFkc7_w3Ddf(F72V9AOAC%Ko|D?mbxW z#HtC2w7&@Zk{YDDY@sx{WJjnSwx9Z*g4@$}mEL%{V^*9aT!}}w`S?rI6jK%WM0VjP zz6$qB9oD{0O|pPi&Ss_<7IK3ios!13=h)CHtBiK<{0;Bi_T~l%HAT%}q_t%Y<=4JZ zgC$nW$%|>Vl5FXXo6B$#w&ik*D|?&Fb|z&aH*^YeemW(fx!x=5M#}HXNK%i7-RAv! zM{nj{vU_j@eyt-|*8c2H8-oCBI&(kv?vpZo*laWQYTpL`CaEkz(f~Bvt|<`nYC_L=Cc&{vhX$ zQl^J4jXgM8bwvla1;G}CSURGA4DsR=>7!gdH7@yhmA!2+JpJ}Dgffrt;osY8$l4B? z*3aiuQ#e+%%q~UMQcMCp*2h4~EwOmB`Hq_V8c)9!pXw3ky${iQ#XX;XS$lnc`B!g! z0Q5ghqeTB{8l9eM$^Ea{(?&Gfs0094;{b3qws9txq45!~1TfdbAzi-FYqjYvO^lsKE9Bz4aFW;#g$IM_@Ex!e6!9y`=96#pkf zlOg!4+YQlr!}J~@^Tzh3@6FZA&dc-F$j#p;9iTqCR~12LrrO-9n}wZ}v8X0e=5&(@ zgu!^34qF!Mn6wnnhIs1>SyLD4(~ts#NY*5K=|6u=HY563#Rl#Nit{E?)--9T)_D0^ zRe7^#G&)Sp7TQ}(OEq}Y;}!j2OQMRQxlV!1yw_dL8{akD>FiFz2c=z(8=>LSV&~iH zS7b~QG<{vxWX>pm(^YDxSE2iXH9ON$JKVJ1--5iOQZS+$S5n=&WLPeqEA2(F;bQgy zM0vuZ3ISHInVewNcb-3t9ef78?ApkgP3DA}S}98m9*9s|lF+rOZ*!_j??)n*p<9Yn zx@1f&f4G*t6rveI(V+DS*%0@j&x4gqp?g`95&9mca&K%>A7RyZ$882&aQO#`n4EZp z#KILAFZIrroSN6~YY`>3xG>9#^Ueq8)hJ2KnzgDcFwRXnPDn)7kB?Nt^iWv*SuZkl zbY|u?snV_YO05Br2G$?j3)DyLwDqoCpi5Z=0{;`nGEX!O9d^Y0ecNvL???ybs%0o!W zYd&n#3#?)G;XvRRn`Vh8BW5_p!G)6$RZ5{*;!eqW;8j8V!tS)?ss+aU1^mSXP2`*?Hp< ziAQZs=4>4UCa-LP$P*}&D1ooUC_h6Z{zIAJmqQh^O^@+ql-snko(o?OY{ zHpWZhA8(AIb(QY6Sn}wC#^Z@>4gHXhyI;WHR)%j9j?81&L815qg9l`5eZwO2IPhy# zklf}vg1S+g1MA)S!~IiQ#$%2}W@t8`{Sid>^XM{k)OtmYvqWj-LK6Y>nEQSpk_ zQ!8*{lP)1Ii5@Gl=C@h8saMXof#JuIQBQd}9P#Cc0*@EJgX1S{cXxJXHf^eH+z_XY z<}bC7))Z6L_TW zm*HEJX$%HUiJ2VFbBA=TK#wr>D+5w&sFqDA*yZk#IvAUHIPI=%mS-fh?Ir57-4*5% z51r_a8Fn3cJ*m*;?*1&Xxtkd2E}J&zL?o`M{vZhv@|v4)dJp_&zF~$R`_tQr<0ChP zF5wCm7J0p~q<21VWOi^1jwq*6$(p7hx9l7a_s1Zq`9iWPK3}0ADo4sATo(o|ja%i%w12nwN4x`aCZ<%H~iWm&Asn<8fl-AwfBD zhx;$6qz|2nYa!M1`>zO;b}04i35CTv)p3P#e_Y3FogvS3KppXrFL2)710JpIA*Lde zP}PjJ>a3AI@RxCT1l+(vH=FyL-8HCL&_kD055qe;h^E1m3POl0H!_K@R(F5SdZ|=9 zLrD!_uc+1mZeTe?hqj)Eb|cNHfo|{ribB;5pAT^(SBpe6@J8-xOLuC`18+sT&vv<^ z+vvzti87{-dFl5(JNaa)Dy5!0DWYJ*kH{etos2-qK2&I;D1d`X7;sNbe0-5f*ix3z zQrWUnj4u)uO+cF__~WUUM9%=EZ<3Wm{+s^LsHYarZ7)kq6a9m%+9Axjhpb-6x%s9R zIuLLlr7UEV-0}5qLNGoSJ}vNON(3uQ7v-ZYT%A=QZy81qm**p&!S;I`HGX}dZ`9S= zO|U%FQMe}vrT3+-i zSZB|QuEw$@e(^gx&!n!dR+v^LT1uO)G!LQt7;ns#)pDGzJxG{zsqkLwC#rm)N&3$Nt4f_FE6`J&)gg zhB)}q{OMcZYTUuP1Kps8AFI3Px2QO3`oSFws{Fs>|4K%MM#5-%6JF9-guFZ2lq`p- z%O03OTVPA;Y_QpaAD^M@2jEnreoAe@1Sd6sStVQ1s0H3eers~Hsd2SgfpTY5hCrnJ zk|TzqJ>Fc}b1~1vB3GcgSz_j3cg@r)lZmh@&areNn{jIKjB7aHaI;S2P)B2xci0{| zb?l!w89)ozH+Q(ZPcc*f0Hx!XYOd5S6V2>Xokrv&m)?A#MQ*b@e5^Rha!KvduN{TG z9JWx`oIFpfW2f70 z$X1LMe6i%S+jEWkHoBH76nBE(!nCF{Zj_&3tfUc6;dxn>70A1GQys+_<0}B3Ys6cV z_B;n^MKa6%`*b|Vo-|i3B-#`{ia;;HQ)%KiHO3>gV!6(h#$N{*d_B6ASK+L!Tg&ME zu_hSZ#?!lqI&$&a2w+n2TBz9LGuL+MKj4Hcj`Y4XUB_di`lPX{ zs2_k;z1N|X6Zr4{)}r{K!_)PTGi49pOyT?Aj-`@z05T2u`G2@{vD$waQ{2wv^HJO* ztSw=Nx4YXqX-xw{+|WC;x3;%=arOp)kZ1%Tb=n<40!cwR`T)ihg54>)zrqBc<1<|| zT`xWMIa8ml{CeF$d7N?<7VONmv#Xix(j`|mP9?UpQy5B98-T=SW-6nGbJrn(a?uGd$&8oqR~!>gBdmX zQH2t*Y))|d;>BK$js8HN{IH_j=_!BQ@-1D2D();`1!pLw3{?c15kQHsfUjv5=jROf z^qs#bJ8>n+&)=$0g@CNW6tPSr7QMF_CJM5W&chUU60wlx8PTyPC`6@77P+}sb&LFB zPdOI%FsVhAqhZP;844_DJlU7yUU_#dJB&%fPNJG@W!Y8D0xe4NZM;(Aa~8RcO<*Tw zH5a2pn3$r(siM#({3!TJ!YX0$5m#c4QepH z<6aRinqgbE7V@YuE;@-z!yCE?8e8tF3QMSmX!L3}nk~h(-;KG5$0A4-kTZ`ZRsKr) zSf=Hq{3K+C4ojY2mVqT@>NqUnnYK@x&SZr#{sqAjXXp+{wk#^*%Fq*_0>e~UAU3b} ze8>v(4Gn+#=|US*gpNzVllux62euuqWahUN z-dD?6b42Mc)xJ1l&?}NNsO;K!Z=^@XKf{A_!vN=+R7=a>kall3u6%ey#fxc7Oe z7to?fiYVu&rb~&C_FyHoLLX#;l`ZI9_-qVAT^O8Tu$f9;umX3=Xsymax2M(YulYI# zP7t@Hxfx;FEvI+VA;umOBa_t4we+S#H4a%aKVK!S)nYT2hRm!}6)v`2&$P_>>?^G8a&!OQ{f1!uS8KsVP0=Z(LcjGmmc(EXXpi9BC&>GqE zam$E*P>+aZFxTqHoK>{@R5t#6woN9)F+6p)ER3bh4pvSvJ@UFwaWI(_2|cA)>B>ttC+Z+aP!ioE^3ETvJ9{G%eMT7#3fl${dj ze5cVR@i}6u!e6@t=TvoMn+I;?R6+t|;TG;Bac%kX%Cf6|UGa9!qyz6zgU}hpRsSlw z6sg)94qlIiK7W>ZnpXO->n1BFlI=}NSMMU zh3=N#1|;FuixEqpdz^jk2(CQvvUnS#QpMIuvRSRh*2;x)u(xNoThY641M zP0Jc&BVGOl#N7C9GVP7Fy*hm17jCXnJ(c{YCQq~hdh2IWb!@NY2o%W8Z zA>}fq5;c<)9$D8GFE^{w=D@97aX*@I0xKWd@lZVBw^$CE8ejbcK!!Q3sMRDOJM$z; zeSI(ajG1-MZG6UhG&0_Ymg$Q57I4ReOlLTs`ireQxY)P|A?-cHXxXFvIJHhHUS%`l zu+bx3vZ*te_0(?oLTnK;j6xg|r9c8HJZ4LsbFlxNst@|A4&5Iv!8PSiVJ)UIndt z(#3q%?gi-MjS_m82x>Wz+h5@I8Ir;>RYYOI4lUyKTCYpE7V7e@+ifo=&bxk$^z!44 ziT-`rSaJ67#ScJPL)XNQWvYy!6$^EciYahknx+3A?p&cm%C8UL&X9n~K=R+33jRmx zJozu`e8{r}nkr5x;Mw~-Q9x@a4na%kN92!40n(&os1Zgd8wZ>rh`KN^`Fdj@Y&0Gc z0fLH}x1W5V9EqSAN^u%PDgOzcYyJVxnm-a5KquTryKLp;jRUO#FWfQT&GKES zok#&wY6kc`CjHO(v6Sqdi?2k|-Db&V{RXi4;=2O}E6s2NC`weh1{s2NTaS7DUrXOS zWIDZWLslUpWsU41swzV#T~hQ~7#&G?0_%T#DT4SBYym+*Tc)cvtuX#j&*HO6ryMKf zh=bq(W#%nuvug#$4H=@N&I1X3=eq4Yp`8~+0hnQ8EyI;l7YR^I=zL;ieNa&v+->zjCzJ>+bna6wR*|z*pi7b81Kr?t+WrIQ$ z*U=VH)Shb@_f1tt8|hrM)T{RrJeRM~mQO>b(*lUU{u&jWtmR<3nM5bB_9C-XEyirk z{hVzKye8GUDu;3!?PC&3$4c%0b$nq$f1ipb4m?>O*lGH&g7h02^{(+1j#_sKxkE)H z3d;>5e~hc|zY5a$%1rq6j&RU-I+YGfUfgTJ(^(LhD4wf0liT`M!Ss1%4cL4JADJPe zl%5b`-yD7&k(Bes#~(s^aU?UI`fhCOABgQrM+z*c+pjp84drJ$IK8oJ-V`YjyrMj) z-mdIadVgQZ>R0u?A|ysQhGPg~p;D}&NaYqHq*ijEE$_Bx(-yb{qzU!|zv(ur*GZR99VBbk}HrCdHd`w2|R0$GDnp&Ed9gmWand>3#9h*Nh2ZLt>^}GIhrKNI0-kE4gAsJFuW!GxTvk%bq@ zPTNhrSSnu3fi*`Fow14f;O{u2GQr>B)*H5o0kk7?h>?_sxQ@MO5CuYFnbUg4OU-`{ zKF`z8=ERMpTvT8v2m_c(FubP3hNGxXx6MrcT;6PUrXoH#5}UMHdyeK;!d+^%zeK3= zepH=nuM;;rUyN-Oh_Vz$#~;;j7o|;<4+t{Z_DisdHFFeteUl9y*I=t26zX~@fc0*w zpMu0015kXfXn-QCLlV}d(gFDHR<3=@BT1B&udD4(MU|JbZ92Qs>b-gylP@omAu(;{ z1}H|}O3dVdW&V$$2BVD>G;Ry*jhJ|MzpgLkfbGe!JlWo1{V}}In%Y%y_gXxT{IgpqLnCelWLh%i&La&^jUS3)U zL8e&z$QtplKNf+B?5KQ>pP_OY!FmU8$$nu)p#2tZ@J8?kxy?d~q%~7vI0L~|BFZLY&d(f4QoJCV2w=pRQ*2IotX%G_x!;^po6^J|v?l>WL z6%`TU+~HctjR>8Ow&na4H_Ggs8ZjlE~aPEM>U0hOaZsaf&t7U%w403=Gh!^_Q<38`@So7X7 zy3%4yP&^JedhSQG5JD{27N1d+5pTs|wk_)*{?Jz5X4Dm+L1i6FBbG!P^LIJRL>oFk z5wZo%okYxm9JLUhWoI;XP1=p3HqN??xYFEQ=iXd^ZqFEPMItE(Nib5Q|43w)W^ZPf zKKr^lqhs3M>>N$?Mx9Sc3P+`6;tDO zwO7qKfozX)+8H&G#KL}0dBU9PfV5(GStTmAd(*+p?1;5KG`ja)IkNh0C!IXR+Hw>F zu`hQ`)T3v7qiM4Q5gJJBP!xfCY||m9Uot$VPiBwG799^hh6mv^;lWLfS`<>M{D?W3OmuzJK;)H*9ps`l z!b#}hAZ4%ZC8rp_c#x!kEeg5YOAi= zl=N_&MG9B>sUlhf{E*^{`KKVXaKs~`b18dpvf4jc&v}mevBSdA47O|B_YKYKpbm)x z+R|9ag(Bb=RxG_Gc1GJpyu^F3LeG|D;KnPpc7-@9xrsA*kM_R) zRV(~vq3VXo2mQ8`P>ru&ir6f4{a{@{n~x&KC!(ICSt7Cw>B0Q9IU<= zS#a5etu#+pA!E87oujgR-?^5$xwnegY4AtogYhyv1kp0rAypF@3 zERx5wW9mBVFQc?Hw#URcU6*~o7HzWvwHb`hZYV31w`vnPMfzlk+hsx?7idP*G`Zl+ zI0rY7Ciy<6AJ&|!QtI!TWf!Y_z#NdE+$3Ldm0$^nC+leKx?VL2&%3XOI<9k@NqYVkR*?h&3GZT*AA`f$U4=DbfQZ> zwXr+YfN0*n^u<#QA)`1u@xA~uoYa*;13nFFk=@YDFL{hTvr-T5$IW z?RMi(^N(8ynhioKi7P6JaEh{ABCO6rk62V!t{9)-J^I3syCu%I8{9)8&Qxt4_1?VW z*waLr1%9zhb3_lfw~vmjw?acpL<6^t%t6&?U8ZC$z;weyEeO0n&#zZt zZv6scAF!EP#6J4{&zoQ7d-@0MSNwaJWBm^>x1SN&yT4A|9sUCG^a9Q1_AyI@72noT zz0Soff+$T^%_s)U%r}J%Yg$UeHHSC6kGId)>sUQp5~@#(>(VUHtw39cn8MoXQmSiY zKG&&kkl4Ex!;UjgmFBlBR`0zJbh1VN<)9Lasse5VtFIAkg)*2GlWW}Mu!vu`<+32; z59{{Q8kjY-rEGuWyk%Q-JIG2V7WapR#0^XMKb*Z&bfi(cwwsPRwr$(CZ6_Vuw$-t1 z+qP}nwv&!}*N1b%C7@B7So&-=Qlyz6)!D+Hey*`bV{WqS0hA<&5D z)4~3p)FnVavQ5ctHVQd1|NQ2lCE_34EzE;A$s}A9H%C!&--7d3%lWOn$+q!PT#+C; zs=KgCub!NAx2~jWc-q)}kJp@hiDMrf)|=M-J1 zqo7<$xgF~9hTVsl*d?+*=)#uJUjI} zPJdTzELR;IV>}hg;43dOwjLmb_*fHRB`0g(QoUdZ^x`p<%La;oybw_U3*>@KN;(dT z@y3uVfoznT8D`WY_2R6}yzeV7&)l)lx{!`W3l@7MDgbmQRMf?;E{myaTtUga zs5BydX;@`asTtxo2RkoR0yIJDTwZ=cmvyXX^C~lsdcakmqSyT5&{5LMXMw*huuA{B zA`N?aev<5Xp;dn8xw2UOylg0|L&fj0x|nTcCTgLrMS>MJL@GSGoyNILXB#iI@#A&0 zo2=uy9N~<}*no>uBMFTG1Wt1AufwPUE_aISNLN(!;S$NV8CeXp(pzj-4BkV;>Ot6uUu;v8)s+f12j!xRcWdt zPiNA%Bg%-H(o#>6U+)Hx>SV>Y30f6$yQE$ViwXmF5nP@zIj5!rP3Z1b4wl%qTpYbp zs8Jr@m{XYOTk>o#KsGZg`9?gT=sYsZSBTD0uuaq_YAqcNd!Ql=7C@ zJBJUT&wTRSf^B90nSQ1u1F54w8|iYc5d%C-EO<8;waKk0E5 zl_P_|yI%6anoNGKrE{tib%NRAIHTEAcKOuhUX$3I9ALrTsMk$lF1@VC35e(l#DQ`w zR!gMbtWypM)J56P+|EIUfXJ?$mWc6)wk^^m-fFF8%Vs&hD6s;w3BYX+QE#*tT~1sh zKeSeN?+hDvvjPxZA(FT||KL-!W(l$uaJtZiMDet82EmLN`{9(Th*|Z?=Nb- zP^e@PgQ%hdO~DXvlVL)0Em6}8lLeyIhspcUse?cXA?t&80@f`N>5V~pTdd?gkoJ(U zb?GmZ*pwNC$Nqp5=Afm~hmctgm7@=Eao@@HwcSt53?oPryyO){t#}VnNyYE_ANPV0 zDYF~!;W}8kF+IamRw_pL=c2#zH{7F->HT!6wc}23qvA<6YH3dw9m&e^h}L>>&}D1? z{FhCCs?ajeEa2Gg;eR7R`1fK4Eb0F%(yLZepMn8c5>K>Jnmu1HpIbYtcD#Odzp}09 zYcO9;UHoIOFX?_SPymLA*Ci3267Ieif=+s0KoWSngQ*7pn}6MFcFSwVtw;H$`)_nC zdM%K-KQWe;+{794Gx+nNq?eX=f{nZsrc#!v_WikqQ^t7)Gc5VeWD6N5>(Lrv_R6WV zz2`r$NF@duwUkYPGnWa%41fuBzt{=4`Fb6|LS1uhLGsx~w+Q zlJD50Y>wx!W&gsf9@{me39kz!;xCdF*3gmo6yQSiNBOFiwMU#5hV4UP(8ige|LuU?%;FJlmIQ`r()So>9qAq#p!4adjD94%9m7^myDf?501 zXpskCSsl`80DzQe%0S`)qbgcb;BSU?}Fc9ax-tw^r!&#pvc0_mP;6*Q+=s^M&~s<(ae5 zFlmduei<)P!m|9Dc%79tfaw!R{}Lpzbw4(+`wNr1D<^x0jONUA*iEdYq;{7HJ$O5s z5Fy3CsR)}F$bwT6y-@*xRU|ocW?)WixHc$L5}&(GX{3zB`JDfu%=rjHm(&@3Ll_~H zT>fq0m9eWLxcXA;JrWg_<2aBO-149=qc$r0kA!azbIEu+eQP{N-=4ZPjK&da(fEdz zsu-3$F+r+^cTP5Qg#`1qmGU2Cq;&jMF4L(cP-5I*;(#yaT*&@m8Q{ys(n{wVvuvy@c@g)<3O@zeO~#MqrAHo3ei6+}c=CylP9g z)LZ#=#~N3;9GPf7VSjPPSjj*e(pDDTEEe%*N5ubfHaj>at<_yI5{9^}Qxv}58v5nx z!vB=&wv2XS?CQhG5;w|tFTIU%A+?>21?6J++TL;eo{e|sS?EsBJ)Ws2pZO4tMe_5H zep<>rIkQby{EIpi3=6qtN2a85&GX>++qBVSBLCb>QKFc-GEp#cib)aoy`}w8z&K`H zy^d2xe4S}VjQ1*+F+Pt9;c?d|m?F>*6j8+QKKxp5)>H*2k0cSw9gH}7X)o-uaH%Xx$)7Bn;+!O}O_|=6c9d-od^!;TG7>5A zsUj;9Z{$Thl$j#4(mjo(Sv+yhjQUXmUcLgY?-P%SW2~`u z8}J_}W=x!jP7!+j$%G~II!NM~V{)tIzTy@e@NyEg3g6r~eWoCC?TcYI-p_~uT%^?) zJ>f>)GOGGQ_4z9tE-7@T9q2PEI6@4LfIjvkX)n_pW>Obnw?NZD_X)-Tyq-c%=cF*F zB`1}~)tC*HwJ-%R`az=0Dkxd%d;-t+=SW`{?B{J$>OVMw*I-l@^op`xAzT|)H!tt( zSU!J2qS=e?Q&@K5N4yr^`gC`&_@Yg$7rL?zd#Nl(t8hB~`|&z`ReM*sHjnRXK@aq* zlUYE8%T*&zO)lLB>#Z$XxfQMeo>%YV7RdCE5y3IugyKm zaVoX-Hr{d)WaGCyJP0}Q{3Ao-vW*NoE2fluaupH@L&!b^ULhKui{t>bqNH-KS{Ef0 zViCn4WoRBnz(62+6h%lw0ZTvT zk4&fr)Yt;+`3cTM6Asih(wDZCNw9YQ$v-{hL1k~v& zDhE2kM~J@3q-|p2D|7fqjLub@|7T>J_hP_n%)ka zG)n$SM6zf)GvCM_j8NW9FzHJMR7`FYX#-<4eyj4WKU|4^*9sQ6q<46l6C9lNwP%|5 zZ7*vaBFnv-wP%rRa-BN%@BES&c{tMPD_LWY;T4_5otCPIc#u6_WXR^fpC+`J;9@%z zw1{CU5S@qPY0mTs+y24|A>w3op=$L#CH#P)u*iJME4pq%0TfJDe`5{8;Wv}M25&_k zWewKg*FJjxLVWZH-#sAM!^M2(qcD5tD&nzBg3f0s9_(=y+++UF$^YsUCaeUI5Y+u| zSnB^A7XD8};HH5iisCnTg9=wbejn$W+Bj_VBi7$g1_FHUjF1q^kf=Z5*p`O$vL8>bY~0;lbk`H$ zfRZpgLWJ>p;1%<7o2gNjC4*IFbs@i>HbVAgQxPCq+hJCeH#$>hmj& z7yh}qk9S-GX3TiUBfclO;(oXklFBs%M55)hkNrQ5X4|=7eRNYBN#xbY{ya@=K<}kJTAz>%I3VvE~wa zyal4`rVxR&l<%kfQ&>E@Rv%zm6uDPh_|4SWiD>$8Rb}_-LA|)ivI}qWo62F^APlHc z@}seWAZnR{*yAx%h_(*;m(KIywBRD^fFgwuXUUMz**^q}nw-h{iTTa-yT@2ILSqrJvZI^CO~WQEHL_?{4*qI zpl)*D*o^Fvscgf#+~SMMhgor2h!I#7d%Ak0gySz}EM&%Z6`h;HVv1a%Duk`b?VU3z zc`<)&ar4@$<-EJ+6hM4(=;383WIlro4HwNb@;p1d&6!=JKecdPHGZJ?yrbnAZg9-^ zg^BT94Tp9AnHvi8d8>>iTLPSfN z-MX(9WJL?&UKxQbr~waC!!gPxF8i^ScxDXuiqe*(9PFcwgzylcQIqjS$CXV!%2h6H z(HJ(9#|+@6pF8lDlPN50ftNgk(|;<{xx=}M8-3#&^D zZ5}rtopVOK+Yw-Q+{r}vZc4d?AY~pNT{hDcU`}7=ctL7p&uDOf!BmzHe&p`@DbmrQ z-t5|p-)FwwdxqEO#{1?<9*weq(*ZpvJIJ?+nlA}~1W7w#7d~7j>M(kw#W0&iF-Pm1 z8^+_zFT{~p6xnh>B!a=r{?Ja+EBf->1$ry>{{8d_3FutKN^Pp^TT@+K0fzD4x=Eh8fU6q#gESJ zZlJKH070j*1Ug9BMB0+nGZXl3iCPWVaW3@Q`?H=H=yv&NyvoypTg5^}+U%X`o*ul^ zc`-(sJz)@htVbAVj=?NfeTL;Ci!kMu9AwgL@Cd`^j0M%L_sX}vTuo1<%L$k#3reqI zM-wuO3lOXtTHfgoVXGdOzDir(9F=JpzfhHFrT*z|T%z~HYgpKr&8qDaln9|Le&I7S znby+Hv7&+vrfh7=7?MP-3S9Vrrj!w@cA!|M0S&p$MD*DfctFGRjV`~v{TA1PJj#90 z;8?gSn2~u3?wFCvPod5`xPDEm2&!V}lhHTZus8;)JmRy(9)tsmp%dhX-Q5xM%sP|k zj_i-L918q^Padd^2V4^9x#EC5RQ9+^{ooc57v%OM#DwCm7Nsd~Kw}Phi7pR{>`WK7 zyK}*|WoI&fIobohxRP#@L|PUucaR)jSu=YUac5NXBFk;qzz1%0F9vBz|5@K<$9#UjweZ_YjZ*M-tP>6`q;(>k5cdV*R% zdV`Lv3mbA^PU#<$33+Jx>PRX<_T0B?zw3OF-sDDJe?yE|4AhHZPcOQP5lfBh88w;9 z%8nZ{njqR)L^c&kjjtFRJ#-jANz#62&^Q*T{83GJgl6z# z_|XPD+?kJ)3D%Tdrq`y>7k#V~?r+tDN&`ec;?9^)zv${rN$^XIuLHnQXKkwylcZ@0>_q$x8`C@%ol}~I0{oSCG z63D6D5BP4U0V_2*7v%Vhu;r6BA@Fm~WM=rIe0jtvG`pCKl-qZ0agq)Be0L44&F z>GJ!eE=3+4U$xcxRq)bkv$oTjJi!h|HgF?|0R+%I)K$B}l@~-T&mAoZ)0PxB1Rr|u z571ngTH(Oi0OhvMJtxN_X9(B!=)rS^d4!X~3N=F-AbAiMr)eTOFD1kg{JL*q`_JIC zuW;c9W)8m}r?qu|uw52zZ5gXnvbI*Qr zVU1Dz>!V!Plqh#;LxXq2`M7vvy#wR^_IJvfXEt6LWicPs>_%cV=R%i5#RBnJIJ1I= zilu4XPO(2pPxWmI(vwLVZ8rj{3!Lt6c{ZoEUyhe6qUJ*i zmN}*AcHT*JHT&QsZ&;0B=!|MOrx!zd45$hNv*EF4QIGyF2^iPYnMKCe1@z@ zwa!(iajMdC>43$2GHjdn4@wd4l^^N*92qEP3?8WTzgwV}9MX$jmP0x*OZ#8Cb_~`` zP?_)ZKL|Usw@#6fe6qZ&=>LI1dY$WT8GR9ct!h~ZgPihrQ-5IYa3o;ZAhD4fZ- zN~kD}=onJfWR*d6;cEwPB@KL_iH=!74h#Qy*yOU6nQ&<*_!E-Jq%I@Bu-FyWKTg97 zLUC+=t(jwOe?6cZc67R8(ex*GAPc^qp?%G!iMKORY8@itfbOBO(}J%v^`*Znc-xHo z1?=G!hu4m~g}=$shZHK|6su4@o>v}TZ^%xjJ5uUQR+0QqhC8^RADZ8+&(6wc@v5xd zG1uSxyEy}1qEEhc&$DAEnjAR0Q#{1mJ2lcWH;)~#=Nt&xZv#c>=iAu|-`>B~c$dE% za1}n9?^*@6oJ28B^>=J7hTn7vNOY{mzu5nC<{zC^;co-n2090P*#D=ug6s{9tPIRd zXf13_?fy0T%gS)u0yCoEoDPzeCoqLcOs$lM7pOoWNIb*y#K@c`u00EHOb~((LFN+ z2m2d+5-NA`Dv={cni_gC2p|>$!Mh6%OsJ^jJ1l<0QxVtsFZG89WV5qPPyj>{unA)Q zpZ*yNjuti+&K9mFPXFEosY*H_0X(r>WenliHyiYdR~kq6LL70!LXUS6Ls*?0ZC-+}Y+V?h&!Gu{=h zcaxW{92?9xMU_*H*IN=$M=7vt?iFgu8ey3r2~TgXk+!MG_9AVi)LLm1g&G$J6T9j8Q92>6}QGh*aXH!C1u zL^Pw$dtQyTBqGj2PgyZS5lOu!XHeV6-E8{fogEEvYa-J0FSKh!nE>~9wmeF>q}iD3 zEZ?k-_xbn;=}VGlAWe#1TR)ict4wFerCVme5;!8Gc1!8e?5Mnk(;dzVDhR@}A^3z6 z(Fe+E&?|3DRhA|yidU;Rk2)a+D5>v?F+^D=hI5W^F=8XHF+L_oSE^>G7F)Hb>SweJ z=g2~cG$qt*k3odY}PQPgw!^PL|N)LW_=(1wAfxajE6o$?0l5yN)^8`Nq(w?X};G^Hp` z|JK%E@i8)6wj8(WI+S5csp*Z+XOP#c z>VE`&%%maH;SGm|3XMn8*h+GibWxdJ&L(JpqEp=9QI^|ic1R2*hH^w z3RINJXq48j(My7>rNk(#;*5>5K@Dol-!skZj8C|p+qMC7+mLx^QG_tm2_OTLE}h3} zkX2s&>{&RkHch?`bXZkLe+2ve7Wz_-V8<=4AVL|{$pAXwIB;aW{>U?yIkEl_aDN~c zRZ!f)D*iGTr@MzXy_R8lqB;tlk{F3o6j}_wI&s)>=#hc6ju2(tRV~^#$K27CpPHB z4&_keg7-WK-?Vbemht6g#F! z!kf%uK$nUqgOrbm^EWTA`!*1X61pM%ioM_5faZ4K3+`^W^y^36uG_6+DnV6zkGQ6y zAySy<9V$rrjvWM?g|QUT-&lh@u4(wJPy=yaHw zwDFhTsiQM`CeDqNab?qosD#sK86gg~<&nU{(MQ10E~lg2b_XJtZKsefa?70+nezuC zwgUtArF?Q;n$Lwa)tIn%X)tZJIrbqt>B{iuYh$hJW9v`KK&K3wIMPp}&v!KYxMF-V z1Q7SDfaf_7(--;we04nC0wb9JZ*e5b=5~&Ny4Zi46#pBa-6}_P$OL-GbW@ZV=g>=H zC7u5xPyD*=Nk~-Rt1m8-f)mKAS~wjfWZ%R;SwCV%cIJ^aC+f0%WhuX zF)Qu$_WBFiXPbqX*6cYVYxJs8eC#1D zAA_hQAgbP?@mJE2G?rppq=7-D{t_w(is>KZQh_aOczhj9{TZq1D@Qb;%d^hTw9v~~ z29s+Q6U*qZ;NWFO;80c&AI=yw1oRO?9l)eP6KqDEWOqaaaW5jE)oU`ZCk|oYq5RMlB0*Adqh z*4^2n)s$rf`Y_GB(A2&%{IQj-hk*`oG-Ln!v$=)2Osp$!rZ_(Fl$Xq z09KGsJ^(`-KNfY@;LB_%{B%Pyru`d^tUln8L0D#oa};^Llx+q-4@LTN$8d7;58!SX z^~g7eFVz4};phZ>Fb}C@#AD9?VQBvZFtp#v(`b&7KPJ6*^BoD&<@toDa=m@I33Gh@ zQq`;H{soxs2T2yv3d%^(6c6yUAjdb<5jDNin*bnfCZB^y4uZuvEDyc>5ig0z4-GOr zeI=eDw0nrn^VH$PV&)}p`@BC_1kd$`=ge@)e|q}kcOBVY*!@CJG(@Ati(Qh`to0NZ zlKiX%yyFUv8(%;SQ%6hxzYOiO+WODqS}POig|0}(f4MZZ01WMax-<*US^uj`)6FM= zaSRX^ga2>Hg#TX9|NQyC;^Ja8^*L$4EaXZmBywA@Dk1c=JsO1JLCsU}kRgkbGedbK5(~J5Rk&H~q-XQr8GHZpY}G^V7dnPF=VvZ9^I5wUJI=$7VZd2Y0{w3RZi*>3@148HX{ zK@i3}MavYNI*&FtH&L^7mOV$A&M3WPce>Ci;FhN|S6RqgWHS4=lF0rFA89975~h`O`Doo zEN2jxjKErWe5gWhPY4{m7Rrgs8+D?QXrN-{(v&6L^W@uRqR|Rr6yU&;TE^ThP$bYe-sK7t;)EHeg=yW)>5vW1y{Yd+ z(uFV}QN{-8dHunUciaQ zHkmNX3>fdbL4i@(ZEj8&KQ*ayFJeet6o@3}LdEBHLA)%+!wC(-C}mq{Yu0uF*Bna@ zKmXyRJq%{R-WG|)Xn18wb)~`l!L?>RoxZ)9k-w-$Lh6_uLaC%5pHR)+9;M(|on(c5 zLgTPAz)_*fWw)HW>UkVB1+xv;huXITR!0zygN9VcW|z|?XDR0CWiKjw?j2b#qCtZi zF%GDLqDN4l?L@572B-p@_o5cxmu_b zM6GlM6L}m}&b`HJisC{@#+?Wy--pLC^$*DHV$b=b05`>R3ShiKBd$3A$s@ECRs$x) z=#Ca@9d4+Q2Zt_bf_QDo5K*D5)NOS3YM+UrS(9ZTxC&Oc25~plyR&~oI{)VYPz5cyD_R0W^$kDA=GxcRI*+i$dl#V>l{Ivm|7N&=yjsI; z>W$DF2;sPOc{(IVyvq)&_4h_KDan#7=LbhH|HimAmodycHD~0c5_6K_w0yD>*R{eE ztt*LOnB}gNE@@VT3hMeC?&*y7uzgJTjs^Pg-?$>aXp}df;9I=e^DAV$`fG7#2w{(J z>BN8Wcwjyuy+EgnjThYcjIeCAHQN0#j{w!QmIPu9H5IoVGG@?&qp<2>| z8FsIitd8*B#Uk~Hy_dRsoS+y!-`G=C{H;Ff@Y_9*#>}sF?q~3I zsfP@WC!Fstm=q3wR8JBMpGZRVqQWJ~=P(_L)oJBbr3-j;Z+!Jt<_epf<5ptv3Ku^2 z-{bsSAr@Cyr-yMHVLdFxQTT-V3JG4ORJpD9k^o1BDCxhHqvgo zi964-vCBd%JO7R@LR0~xA$MfULJ06Uo}^KRtjO;f-(CZq0dzd9j}C|fU8@Kwo*>KP zi(s?J#ib&(T=wcoF1f8=A$~ODK$brA<0BFIZ}7N}7S(km+JTR16qDM8Y}2qF+8f2> z>qhn~mr;o9@!0gh+BI)iRvIiEYPJWeG#_a5E$a1-RS4dTJq}fPm38k_E0X_25n@ua zr(e|=4h{=7IPY!jj>p`MrHIl4=CD|6SQPT07?CFAkQ!#K2f8y!C%>I&S9YUFaSqsC z5*^*RYos1k$1(PVd&B+9HB@^0DwJeyrb-fKDLblen8))&Fy4jChqbWxBKnF4-(ydu z#hVu#xI0IbsL;a(%Gd8b!oN@w7P)r>#b3tb&~zgo!C0d|;G2=J9qQ3xe+}p7+C3iZ zB1TdV3E{k{jKb}2zxgXb#E{HUR_n0klWF^F= zpkFWHEEG%+X0YKXzOhvdXBh5qefxiiC)0T^Z+E_}fXk~8j#Cp$Ck<{jpD4@lZ zd=JksUP4&|o!g2hc62O~hNh0&gJgUAaca()Fkt0iE&_>L9^83UG(-Pt1p%xjFXd)s zwFN1ny1w15+Yq-E#WpF%l{XxE-2_YAiLlrhstBe5(nzV5ts=k4X|BDI6L04`BaHpypP-Cfr3?e&=;RmmYg#H6?veoCn=^kK zb3TbOA}LynLDjF%0GuiS?DCWY?`5)9PuG|Ia;atfYd<4?H$F#pm?OBzUzoF7}& zfxSl}1v&911mQj+zwf&v!emb{!G(0?V5qrK39tLdD0LR9&$r7Zg6C^;+E-5RN4JQ{ujPN-E;I@o zx^%7J@oV^94 zi#n{teX`$|eU8B+$}@-K%Gdp&?O{O*+D>jxm>WrH^ZOvsvu+GuZoRy3BN#w0Bb`KdwDH z(ieAtU&)iF(kN$7@jv47e;`}x9k)eJ@pq%i8A+U57IAtFnnm_#_x(q;4FwG*IDR_;`IRq$c-f~eb#9D3uTvMm1b2isRwY{{}RKaoNwbZwNLdr zx#K!l^_&*0ox2?2VTd@Cz1eF;@F(PSCV3bSK8q73Bu%f{wJ6P=ix(RWV@Che^aA`HqTgZ-pqlA1cI>}R!Q7?q@OwBm* z=_KA7^TNOH&nc?l%6xUAA3PbMsthZHm zJ0YFaDP7j}WL+=blx#?`qvaJ;>TR}-aD|XlOr)mvfUer}KfY^{V4U7?1QSO>gJi*+F0fvcW(PE?`Wcpx2D0$+^R{E&FM;m)|q7DZa8o{ZvKM=oUL=k?k{(J%{! zZ9QW0(c^>s+A|8|j_%qrbxWe5yXp{MP*pO(zpclmb}^gOHWFUgWbI9!+F*DMTj6bK z4O?p&xU5!C`AvfbEzdJt(Tg(kQMc?~_ z$_{9e-R^yYxch?S@CTTo!eY2SXNkf_^ldh=srb z>tr4F)Sd-k=2la-hj}5Ut><}6a$%ifmPpP>?+sy#0d9~s z6uee7bCa#b7TA!lm5YS|Bl?T$)C&5G>@kbKChdoj?dMKck@fifb~Xtr5`2L%ETr%< zv*LCeu8U6;ksEIm$i-<8FVbv1G66#!L)5hC1%*ywa>%&Cg(Ye~>SOqEA@c=mze}9LjZBNY#>n z)+jvI|2Klg;W@L7%3a8-n$I26e@1lY-EmoE&Z8s)in*1EGGwNv4KSJ#A45^*pV3J&|O^VuAIDeE|kd1CW zkckS-^-grY6q!-cpqSX55M8u!=2q+36rKvS+z7bww*=XFQ2}*lY+#JWp^+n%DYZ-y zTELgpbA_QD-WVAXa6#X;AqjaCIOJadamHtvg?jUN3h8?wJ~yd>72Q^2gkDj0Q7&Ez-vKV=5yd7uFXx-r^))}3s7n96 zSF&;b8)z{n6e%Yj_6dg{N31jFymazcJEuOnSA2VDk=uZxSOfCf z&vX1~a^APz;=^n0D(@OU@~Y-=GUX^U$d&07b$K`7euH14A$}nLxeef8O0WKhKT`s5 zWT@~zO-q$6%xq1Jg*==A>h1qF1Q@qnR6yaSPsB#fLjg|mAd>@ze2hcb2nG)QCmaU$ zUr_SHyoOWqwFZA!B&Tu#72QWnZwUJwY;!4t02FcG+ntXa?$<5C@At1o9)IFCBKzSB z%-AU6VWG)Olz*1RB5-GEd7iFgaMxm|Z1WAYYdmV-IT$)WE>5DhA82;n*IKkgl^?m_ zVRs>Tegz<;mGcwm^)u>JG915f9lzfJCs7rPKI!Rmhmd-;YgQ+LuF%9*5s=jxjQhoz z3+X!(92uOGDt!K`fJy*9{Ch;rQ1HucE2~Q{6R8Zo5dnCj=Y0IVx;(V6`NTdRITohW z%oWVmxG7(#v<}=VFHO&u(^E}3=GJ>N8a!99euxUh1C$X7!vj$fMloiRmhX9Sf+8K%JRKIvey*U2J9zT0q&-WB6CO0Ii>kn#TWrO z?Q%ua)hHn<6~e~%5d z!GK5E#utvu8v;v48RE**D{Kzx@?B_G1>PvZsn$@21$I$xxJrqe%bD>Gd z9((~4Ig{TMttlTyzUq^^34%aecd9`jkatYt7Z^Wj@fq4-pR7%M;H&yRd@r6mjQU4;?aT?9J=d%onpx`El@`w@YK9f0iC*#or&PR&C??_8qtBi)32kn5 zE@C?`8{${^xLet9k3wXRX!SkZfD5TDgRvNh_X%3hcg(5Q% zrkt>zdecCh02GM_NQg!V;@&@QFCV@SgaF|S$QP{V2ghMBa0o%N#7oremeXvz+l>sL zj}JeDK4k;2w4>-(QjfDFjS;FL=j6n3aR$J|zG8r#9ehJfK0 zn5Ut~?o>bX1exyebvOSWxoLPzSjVKw*<+iLQrQ`5!c}imx*e=~cB;-ruMN5(PGzMh zmBYxSHnZ~a0jLJO7OZzzt^2-#nX2fNTxHvQ#NJ$7tv8&SpRN>c^JW7R-53S1K}K1! z$_#E3>_LmafC13!Aae|I0!|+=;`*AFMMCLYXEM1{SxM``H*HZUwy{Iy1&wEHTBF!D zXsR_S(DexR{$J zlTjw7uy*jDX_O2ji7Te35nvWdIwanA=z(;rY!dUCSUq2~6&#Io7y=-s&?;U~nj@}i zb18C+w@giiouVmSNp7rCz0%9OQoWNhG>6wv0n7XDJPF1?+4337^cW=#FC)Ybs`Wvn zJ;f1rn7S~0l3Zsk)w!r;7tz#FzM(zjG+?k{e`SLDzgeI_yOEqVY{eOK(KQghrCa6TPTNI z14R8K&v(aML$(MN4z-F!1IG9H37@uq!yQj1DqN1`2Ql5-9Y2&x!|)iPj<=`OdViPv zol|g*_O><`?YB(8)!nwi{Y?v8j+omtp$^P^)&H$^v-so1ByjrnqNKBSsYz>KLMpjR zbc%1A%~?-!+k2ja&Lpj&P(wnx)4E(WxT2mDUR9!~nY|}q9JHgVAUj?gHUyeXR(a!h z*9}L)tHf7M!8sOKI*UAJOb5uOuU<@7S!LdRRb3Q>KFg?{uPWgfXvI>t$RwebAr9E+ z#hG@L-*G$63AYB5AuyRE&wyEynP#{aAa4MBx#}9^oUv&0HS;;s8tfLovzpESLngP( zC&ayH6KYUHdBe(M%TZ0DQ8o2F1n+72DbsV+a7RN9`drt@7K%?8EU#=(EQ94i zNh&@9{~U|PBA}oP;BWm&=@o1c-(+a~{a(T%zDuyove>Bmthjf2!oK$GC}EUze`45C zI{yJZVtchemacS(8xV3PKT8_`u{*i2$dKs?Y9^S8es;w9c#n z{;Ms?YZ#D(gqs=X6*sH3da5o~JzsBKpnDKCkP?N}{7bPirx$X}W*jjFk|u1p+^>DC znI&d?N!43`mONIA4h`>%u~h{Te!9!3{qs-Q#u{yt(mw)jF0&5w+$#mnrM6AF9wAkg z(1Z{HX2~B}Q<@z%M<-XVjS85OSKf@fuv;%O)U8~<%90~I0-A#ggdiZSb%tM08ORXu z6`VBoL2bYP@(6`P;C#95Agn-Ky+d;@Vo)KI4{mrruUvV1$n{|;T7e2FLpLUGI;jST z*%%9s;$5g|w}9S|D;Gv!4SEg{-w`4T=@4kN;%GmVkt+MF9=vaVG~6I|f@v47McL3O zh+jT?0m~=&j8&Xww8YCtOLX`B{ysC2wrhUyi+kKeH6!C@z!XL31O;x{F&??kx2Yfo zTV(4l=quqTDKADdTnnQdZp`J;8?>%xc#h$bq}HTfmZG%TWBRq&Ee2un!*8)k^R}p@ z7@&>fKoJEGTb3y=GEGQ}AqoYkTPD;tA3%dgMgi)Uox;n?tOJlh6hzQOQwFKA?}hSf-g^K$f9Qf}ve1{~y}kGB}QK*%Gv6p)F=vj21I9Gc!xA z7Be$5Ti9Y|W@ct)wwPJ6SX#~A`{wPvvoRam^wcpTo;b18(O9Zde^S5E z+HP7Jlx(~9*P>1jUaf&|Pm%lNL&0Rz=oBBK zq=~a9E0lV$@P@KnU`9X1pz@-bChyK1 zyHL8G+1@)Miz*`eQnl_lP*Hn`*X|qCk%@?t0Vs9qFSFix0dM9cHF4Jd?bk!q{j&?& z%0RrL?%Va!axBfx_gwiwYDu0QCDaPHOd4Oo{uLA!q298Fz`lGDfc!rO3ZD=HFgE&6 zNFZVOCnzZD$e}18@+_gFnH;IzkM&#gYXPDgJ4vZJX-Tea z=V&EX>MG?@de-#uyj7gStnKd?dGJ2iLvEpg>Jv4}pvN3RMh(W4b4e#Hj-%T9&{o#h z?(AyQ-I%ITR+I%?g%+oDY)viu7`vfE75p$hay|w9(YDPKV^Scxe6B4|V9xNg6Jsgi z2)&~-EnEd`3NUIskPWl^gB}d-9JcDiix3V2>tHfVO$e&*N-u6MU+zvIXVGo@yN@4X zY}T^)E+ZpFeRdk*v0C7eKK7wWJl7?=Ll6;?yx&;NgdB5O;Jp0riZMlf6;%kAQK~ld zssZyOAZ7`05hpJEm|6q!js|iQx+Fm&Wz`51kut&AMIw1NSZo|>9_xsNPvo%3dFZm#*yX;r9=8@@bJHA3% zR$SS#;VuLhCchEXo8(*tB(&gb&)fXe5HX`71{B@--z<%}%Eh~a-yODFSI~vFO6HHb zt}z)VH^F*Dqm+{5p-7XAQf7@{C3cqS6X{DP*tP{=;kIw?vs*_N6!JTSM;YJvW3wnn z_%%FLgs0J#?DNHhe0tu(^S$zyKKJB)5=MR0v@r=-%)Z=#tA$M=d&h=YE1;2YhI}Gf zpBl5#0nPqph7ou5qOtgnf3qKsZlDB1jt3cqQewR#v6V)=)>92$lHW`{d)C{&t-t>r zg2_>C!hVaz&Gyl@M3$)ECc5}TOF9|ngYYnd9oY`0uw4U5DWrhUcYI37c}2C3RZH#n z6+{BjB;WW{91D&Y0pCRMfH$e)51v_HUh&%%Qm9w1rEmw%8`h9^2XofB*8J0{Ph0G!S{ zTx23UF}EFNON4nEymy`ZP*^SxGbhtQvNOw3qE_(U>C9<0% zSh+EqnUXj-L{XGCfhDqh5F(lFZdz1nqO5UsxMCW4L$QuiPAtvR`d;da#(Z=*b#yR2 zRk8k9)H~0BvJo)JTF?BcMcNd%jaG{txh-wLgZ14kJQHr4AN#n4efrQev}_ZI%?l~#>0L|9=;Iz) z{+@IKh+$c1WWk%8E6ru9-iOuY8j?zfwL(!9K-gEILZgfo&u3kg$IwF2XlI|TCi^Kd zxJaGM!Gu*tyv-iarsqXcLjp1!E`O9GtT$J#2W!H#_xtlvLy`BR)qR^EfvuIXSur(7 zsg@JmpT@Y`-|5tClx%bJh&Tu1SZ1I1^1 z9APeU=jgW|vNkk5yA!G0b>oYKbowBPirP7aGFcZi173L&1GrF7CLn)kvIM<=RK@W( z3aUDi4iem8SDN-MD%as4d2nfasZ!&&Ygc+&AZ#zPD6l+I(-AdO*g+;E*j{u=H>24e_X|QxNmUu$#g1yvrN>kPu=FFUd8Y0P7 zX_hqNeyL*#TONx;(>TQTdHT784ZkkvdlO0e3(XM{5e*#{!CYmGr& zF9ijhNL6K0{fqqvQ=wu9N?C83`oyem68zHF_#MuDg?raB5F&YzkKejNeOe+#EkW|# z=nA>of?A&hy~19-YpH&zvl4lnq}^Dm^--glX)3fS*Ti&v&9pMMN|cFPD!@^~OQg6K zOCoH{eur+TU-m4n`deFxGuoVTYHqkl9ud$kjp)6_NaX%(fLEdXr7OJuo_Q-SpP}0b zhx#1X;7A!MN*$do=m*0bYSKFrjF?EmidTW(`#3k__Oq4tQ3#z^gEq#D~2ZQ~-VQBIqZMf$q%5^$wH~+S`|h?4FGa z0>@hqyYEJ>43XiF7U`5Xw!Os-lF`+_>raWF+j@QnbGJs=DYd?EYc6Y`IX~%m7fr>t zg-cB&(>G(q!$0akC9H);TZse`(!gY{sy1YL0Sh!oJl=_BCz9=8Dj?2jcb3X}?JFGF zwa=?M16dp5s+QmdJv(}9yH*d^kSnj3wEbPW&e|ZGx=C@HsS9|j7+ylCBJWXW$`iNFY1D^=IPt@sN@BRN!2&jp zGmreR$}tXVH`V)}v;E+@CDDC*{fDasm}4O4BC&$W(0gTB(_3vw;OiLJ2YT7326w=) zf1l=8rO5OES<$AJnYm4n+DTsF(zYYyNy{md_SWqMR1ki?f|rF%dth5onVqVvzM^Zh zkXqt~eJ2-*$ulZY%r?8K-N{4EcRj)Ho|&dqa)MgXlFvYZDKigFZ4b(H0WkNqMipu$ zUw^T}zR+LOIdk);XrlKEufT1w|AS7J*wZ&TX8QI;EbM%FH*M>=9D)1pBly)#gy$LL ze*UdjS}-t7ssd6f8DUZpMV`87KoZ%+^jy%@BCd>ZT|hp~EaNEonDEt-gOctF;$Jh* z?*OD(m(OxE`IB{5|34Bb{}C7)l>b5F^&KFNs|v!rz)NV1cLob0E0QOp#`y*!3Jzk; z3g{9I0iGZ_gGDHzN&1<76I^qIGD-9h77&nBGdm2qOs?;*bKPE_u04E#&m)w#aLN#y z+!g|1KdVx~YGuw#@xhim=X;`+iPZu(U^z?ChK-NSsJYrKpM+ZgRQ9WLqfYJiM@<>S zVSPvTM=VB${Ltm@;&q@ya2kt~ccJ4!Nc8WKuZBn2gV5=XhrfGZ{OO$y&>(S7K_|s8 znd#7Z!Ds!HrWt7LHxJv`^x%!}giv3f9zY+$NDRT`%~rDCgWU z0h>v6idzj~mosS#?smEMRoqVJ?lr2G(hC=81q^L*CFrx!9x^rDMoxp$o?J5eiR%#9{_pKly@k`(->Wf~Z)#rxJE8Ugy+h}Q_o@|wx zOlPSGqIN!(w@UlQy4&6e)zM4DM2iyRlKwUG$nNw zeB@;d?Id0N1&E$WjMZ}h>~nkpb)0WtZ6jt)M$@S5^n4o*Iy3$3lNL4@$xG=!;sqs8 zkpE64H;cRUt4dqWd(w21q7bX+z340In`J~D^|!B|ZQCy=Jc9+1yn;|DGQ5T4&M>qf zYFFJJPHVH7Mv6Q%aaN7+~L zD;$>RwRiX;>#o7$ScuP!R{=ZXDRZ!7y2sUYUA<@-?U>^COiCZU@;0VlC%HAnJZM5K8Yk$9w1jg zYhjSA;L)FC19!NuYl!s8BqTXW)iqEiJ)2RB7Q#@3cz=RuV-R=zh=h^A@Cd+Sp>$&& zkso1tQyO3hA%yMfx#}D)IUd%z9DZeWcAkS*e+lmHb=2j`rAfw@OlI3GFa89{eZs7&W3 zJ{$n|%i(io1^hf#REAFAWWI-j5JgUXTmhrTNtd2a-+|4L^|y z_+?hwjVPwsFL_v}NKy6u;sPmqq|q^WIsV9NQ?;a2W(bzA5I}a?8Yay#FkEn_R0Fwo0Q1zaecne4OQRu;T9=XkiNPi zpS0Qw+>sdF$-lDO+Cei7`!_yom~s);7u^d>Q49yEJ-8Cv^uP;d=$aA2nMXC&VAoL zcbB!97}lIK2XVB;)UfF;&Eu3r*kRB4*x|ko=nUR5*FXOei+e-Oqt{|OI}eiTM`2P@ zw2GFfJx?vLKwU4_E!PudGt}W-qpa8ouL_e?7P8l6;NLEL5VlA*aRY8v-~&zD2*OWrzq=Qm@Bjfb{$1W=#D*- zE*INXSsSNF75*XfYNI(yaf;Y=-Dp4a;p)s@%~@Yk3CdVSw|OdJeqD(j^pIg@PzKOObWhC4#* z7cv*nawa`6u}kH%SWw0;a|{jc-I84A?+e<+eiAB50|k-*9P0`6U#Zyh5Q8=s5uH)kJ2RE6vl zMN}1k`dwr*e|VvoBHUBfo3xg7-tQ=SC8LR<*m5JnrFes-ZEo!^-yXb91mgAIgOWtC|V-4IIhkcc(Q5PUr=rh~{=UoJ?`}RNUOH z+T!zstVRIwFPtwoop}L`iA__i5t}pf##R5Mu?elj#kTL)Pf&SlwRSpG{Cu?b5L;-W z!S=&mWlO6Cc*nT9X32N#;W~D-)YbZ60p(yQ3_?5gD3K28_-E-ZI zYRPPCHf=6?v>KP}R>6|&MYBej)WdU_k%tTEN$97qz_tK2_M&nh+UYIZ%tQuifQINq z^}f@=I9gqd!|xiySqc9ac)MHO30^V&t`IfRlYHvG>}*6r?LFGx`dPo*6|U{8l};fqB5W9T2P|K z5komDJo&Q@XM{(BXVZ}DOAvoU-EW^LgT7NT!W5=L48pugt1*HA(o!BW@^T#QU9XVR zS(if23anr4mQ${FvfmahR^baYT{4b;N?C~ECK7d^JN5=Uh?Yi0?!U-lE=`;L{vGS_ zWt<3kw~rFD+A`xr!W#=Jc94}#;g^1J!Fo#dt;sSgex z3Q$s;;Z}zbAsgU(oAY`&Gj++JDT%kJYKEPqZ{eM29DUQ_f-lr{_CT+htJ}g1W{U`EhH{xxft8rX%xY?Wuh0xJ zgjR~jk|q;hX!U=w-gs!BtynDeRkhnnV!OW;$$I6zUopAwiYNT~l`qND@FK(GGtJ^V zd_7#p=KXk^F#9sJZQ-}88&Vg+%Sb1r= zueGwKQxI_K_$=dp^%2E7SDAHlN@R^gAzxePu&`{1t^cgV(Qr-`AX}&lQg9rr<{c+2 zk!%C8-QU#x&GFNVk!(|iejdubBK)n$zSGylHb%LyJaW_t>J5p(!jS8&6+^QP;^M;I z@x}@EMKCHx34P6*u;j$qA3}nDsz$w^=jKOYOr>qGJ}8X**lC4KNdKvmrh*cjId7<5 zLL<0E5#3Jc$&%ewDuvSr}-kHMc{7Xjl``Lds#8Sqis##2=g zPr2gQ%1opSeTKzbpPh)L7966&Lm`iy>Bpj%&{j`OMyd+KOshY;CFLwWQU^XNlSfY> z-!W~ijU!eB`_2I-)f+*rPSfBN|H{#j46X8mW1dOAyBkLn74L91;&6$O3G=296pe0@ zukO~~X5yvg5}C5}h975eonI8yv3wMS;T0*Xh&>a>Gy-TT%=FO8Q=R9oO^a6_qnpGo zG-gp_Pcf!D#HIJF8M{6*nVJDOLMOW@oSL^ zj}iO`7?Fb;7440{w_{IXGdCArrfg%bNJ~+MDIA&NKE^}t=@c+?R3xud5b%@~;dW7R^hSa@6Wt_6$DeXW0|f(12ICOd z)EL@O!2TW%zZm*joWQz%Jmd#qaRDk|$(qm%EZ!cBFr4c^9`=HzaB@-i2<*LY36>|z zViNjB`7th~tb%}6VXcXKxmjCjrP5B9e>AePYvmPmZO<(}nCKjFT9_Jl;hvmK-EIL% zT8NxKOJv}V`uph$8V|!1+D0?meX`0gsP;9#++S`c4mfrl`QsIJve%x|c|kg6M^!s( z=m(=X9kQIO1GRNh{|4hC-OP3&!}y^uVARB0J~NTwL?cCft!Nkd2iP$es@0OB$ct{# z%FyR2y%2r;kHdtHQ*2)8KQer*fI8R#EpPIm&3eNR1AvE`WQUkM6Ui=~&aHw5S|!mS z@r1JD9Os+FMRKgN(FC))t9xR3;nhX0F0c41t&G|a81vt*9>d}T<733F&av*z_6{aL z*lzAIpDYE>r}NYKDo@Q>L8|r~iNbK@W2c26g774n)H8CAcNma%(C|ht6kXOF zz2}}cAixj&F{`mXZCe=gstq2k)i~%{HZ6CE_M1Y0RFmQ=g&I_mtzqaE1x`mEd78hS(<&&XESO6zPq2D|Z35Y8C5s2sCeFg<~OPGmY*~jAD*pCe|buM*UvHH^bnQ zx@0{rHFYy!Z?`uvchqXpiU=wK&OXWhpaWC?=_iycI?YLw*{Qp#K zhg&FwFg!bcD(zeK+-o;vB9YhmE-6O5vOnbNT~He%9e(vR20W!Bm*X~;OxdY&7P0J+ zvcW^g#UAp&Cb=}(xJx-_?m7ZUq0X*PVGr*;E02q^D7o#+RE?0_W-vQAWKa!={=gDRR9x zMK_Fdcx@q_Y+dN{(e3owzgW8He1MlT>{^D zTJFE8eTehEOSkBeUsI{U5h(c5jDgU;%jM6q1@&}+;1Lwji6t3cCXnUO`$ez?T=VbI zX-1mI1B#cS^14oTB$6+|wdK08i?yGb{q5yvosgeOrNoE3!D&gc_DegOxu^G}GcT-M z($7krC1~Vw=@idXyH)%sv|Vc3R(1Zezbc9de^+iZ&k}8}T%A}+!%HrEK|cYFH#sdq z3^tfQG|%!L5Pf8oP+=_#2GH_H-tlC1u)j3b9>xu#MmD-P*-7i8DX&lJVsRd|a2?@< z?8iB$toVo2k_YIqyGA)&i)CR`1tsw@c^)CY05Yz2!4&-Rm+`R_!p?X2*XiJUQPS5a z%>TrzQE>g-bq0yi^a}fX*ez|(;O55ylQw)%X%8z`JC^NS=jK@FTsWi#I1TshP#=~P z!ZZ&OM>3fQf^icVPzakva4833i;<-is7{bj0nFk1SEF0>BL3{uZgTR-d+$8A&^O)d zbt38dVOtg`hCjqeskTZ;(J0NSl6Z~sD&2>lSkvF4S1Gt>n1YJTYRb)~E=nxD#uhf% zy=s}rQI6a7jZ8i2A`Vw4sVuY`b}`g~8!0C6RwkI+%(*vle|M|x-pn${L;)xHN;6pS zDqH=`U94g@#yv|id^|f*oCGLP$cMorh|Y{A^_{k$D!OV`SJ-vVrDb>adFssiE;Y|` zR%jjTK<&MmAtEobX9H!n(_>AVXbTh*w9R6F^FPixS1G1^X2N4khh_}WehNeRL}mr; z4y>??IOd3yA5`^OTOwM-AX)&z9T>$8r5%+A7qo zO3QsLy4372u(!&V6-;TjLc-olOGZZ}&bWpe7zu>zz$DPr{lmK-Q8#s^R43Zo9r}Kz zBqA9fzetOj*iR(uzkA+~rd#wVaA!u>A?HUoe0=jXMIjVayyYXl3jKOUhg^(KIcE^# zTxeU1X<%-8wC&N=9Qyv;JA2%lWa%|eTJ_$!D0G#0uS+IpIP(ammPUKQKh*#AthM0KC3b-Xpe%zw5SVy>GUPsw zu%j*GgITTSjtvJ}TU#G+GCW9Syx*SQ141WbhK@9;4s4!M=Fs>o)ieRi-vb%ea!UI( zA*&Pd#bV`K?SX}5#22R{NxeQasY*4`#Ie5yk6aoUE;_(uN&l3pxUt_#evVHpUbek$ zV&KvU?aR9MDai)SaN)5On7h@M1?@2TiMt`ljX6WbLwqZ}59ZpY4WNo=Nz?Ix{32@L z8j5DgCWoFU)u%LJCKx?))cu~$NTcs)5G!a~AUGjo)0&tj=wRB(@+yiRudJ`EEyI^_M&6rKu z2McC%d`?01lqq4JMa}rc$;!T1IUA^K%uMuA@-+xJxd+2(wkW$&AMcD+I~R%htapb_ z=VxJkeuc*GI)YvMC6woK9UDg{$?6*QVFq`3iulJtV9f>96{*r{gy=b%s9Q#*&;!r< zxVl6#P->dkmeDd-R;zvbP#{2THhqJW*Y@IZ>nZ2f29WnF(G{`DL^#1sw9rWE`mUs< zAr6DA!?6G|a}|PC@-3wWokt8~PZmalE-q+DDrvpnT_};gk6Jp!ZZCquEMb+UK$scp z%396WV=7)fWprs?Yb7zp4)`~x2|k;}0=lCI|LYIF_Vg?5zB7(N6-GQfGPc3h|1owEzhf-TB_=*nmO zF=C(2aWDQMD%vMU5-W>|uj2!4yg74*_%wo-ju@$w(l z-JnuQ>ZHRcz?SiS4a)$9pkBR=>e&CSEL}3 zKg4A+73+#MvIsuJQ$s30|M(A#f&S9*i4Au2K;_NP_BY$lmYx4O1NMId)c*rx{sS9C zT#bOA|Jhh8o7x)z43&)Roy~woBne4+IOB z7cT6MB>3SJU%137?P2pv;;T=1moE!bX!MVjmk4c+%rt@^1?`56b%zT#&%>10$NO_G zUszSFn}XIF6T?{wB~>L-3MsV8Se;Dss`i#{!YJ{Wq(z&@5DDjJ#}@_96(e z*DH9zILG{`Xu@`0x4q=pwV0FBS0EUkQ0KHy%m(PHFhp-g{+Bp7X1~~~QFvr6zlqZz zluAc%NM_3?A!mYOX~U?6&N1?-cOF7sql{uY65%;e;DLoISY=xzxKsTdpXXta&rf2X zX#laS6$YYj8;(z`PieHxcq~iXX`C2XuTt27 zq5ZQFcKqJS2P(%(Cr(6?C^e~2VTHj`YNY9y0AR9-?3t%aWBVeFycy@TwnqgjnuMt% z!Zm;AbQz07p4NluIWGv`W?vWJ1G^KQ2J;soI#J27(e=%g6&8Q?Z-!~5l3cT9@#64UGxqUL6$zh87126bTqf&9=g=czD|g-=OkunpgO9r~(uIDq>M8mT<`C+JFH8B{#uSTylPro( zH&a}HN#~(@J}lexwgY9KC~1OQ;3SC(TR3ebl5Xl%5xJnKNcIQ#w#=-j3A7K$fJVNa zdV2x@b?Yi-=RfS$F-mv0J^C@-6C8(`@mp?0AMYRUKeB&^z}oot^Eke&@yJcO`y~kUM{&mI zCLPfe>9~d|Y9DQ0kSvbg-(CH982&Zzu57o2@8E>#-oDV(jhUI5#RjEL&RCw6u{R^; z&(zN869=(rH_6yXPN!LB6D$uPKQ+T_YBXzYsc{K?rbf;2o~&M)L|Egn)d!Y@gV8de zt_?cNH!1WQ1;?2Mk|k($s%HJH@#I*noP|Zp6qOjLUc87Lcb5AaavOsSwN!1{*XtDQ z@)YGOIhxvOmKUxCOJxEA0D?G&PYz(m&dX1R(F88NhyuC7YD+c;PLMD3qtH#B6SFYQ zHG>4Y7hF?K^}NyHHH*`tSxx7^9ivn+#ARaRHd8WZd)?+wl}gG5*uul+LX`lRO^lHX}GAn)78}hGlg>)*z#_N4CJgLPFkJ z!WlDUzKwZFrh-P>^spsCe;Keas6RP~OA-a&tyZfbxxbuk*~JF zV+!pi9K8mP4S%q+qvhDi8>`nHk@otFn?X6irY+6cXg~%x)y19a`vC-`QRyumTYDOa z9?Wg+0sxzlJM|qhY#8H`V|X>4kw%uf3^>llVrx7l+hpiv%Ex-q-dTr(Ee)*ap zdT^$(rOg7t^c_ivKFMFnok4Ob37#?PG9MkW{@p!1!2{ySFmp)wC_TsxhCf%>I6+8G z+q{d~%GbU*9!9}qCgH71I^_ld09qF9w4baqwc=^aYxXTTilb%F$EAN4V!&Cxq225S zo-XeUF(auX7*IslUh^Np?EFL!G>&ls?kd5JujTYd0*1zyw>&XeFR?s^8j zXErP-=l(}omdBr@*bTQM6y4?Jmm2iPN&Rg!;aEXPH7z!zlXP|FU&fwdB3M zNV_f@GIJR05XZxGKGB%r*9JowK^`L54?JWLWtuaE6UB!-x-x1V_-w@`!`C#LX{Os? zu6tduwYs@EnKkEx5}uBEn3D0xZokF`%TXi&kxwQ3fSm59MM9=5fD-5TU7s6gF$O&X z)dVAr@A(%ajg#<%k+bQEosny@%+=GBVQhj5%JmM9bR z)A9;1)eRW`a8-5(3)`s1r{=>3N-^3w0L8fYx)Gp;J^6OuL)JIYgWk`P?<^Y@`!E(GT}nN=bmSx9Lv-Xzpd zcxq(+O}sS!976J>J;>JUhK_l2zHT+6`1Y$tPA(n!sJ^|d(@IHG{+$gjeGrSs1(d<7 z)~_VH&>h4{Nky-QO(q`TG)r2TX~w0&%JW-=jr86x*1YmhX{Q>;qGq2V>Js?DalKZe zImh_36Yg)odUjyEY;4NOBqu~2w`D7ccQ585bX2nu=Z?zlI2iOOoa4c*J4v}h*4GnO z^np4_Z1pHx5!VSTvX8SxGdu@UHBGOxI)?m}G~XN!Bd;owSvN#IwG;dnPj@p6=}2!} z?%8Plw)&^Y(wknl|DEguckb4cR@!?oZjb#S%C`CyMb$gI=3CP;_C17p(1PctF>t1K zOMGd<(gOMvT7PXh&^l^z2jh^#Zy)TUddZ_ILbzJ@G^M_J>xxa@;k!XzaASlk{}7(# zciabkRsC}uu_XBMg9kX@NwRL@zwMEPe~8p9ET-7q#dwKR$^l|<#}_4 z2y_6ud>40>=-oVKPPY;1qe7;Y#`qmkfvEd|{JZD4UfVk8F4(Egis-yeNHCHEuN06! z!?(Ei0ZMe{Q%4ILIh1_=?O=UzjrMx57w*jpS1=({Fg66 z|0N*#2MIx<04<2tR3f)K_J5y=L1#x*2+@TLD7p*j8FH{omDIEG5vw&sxV z2QNK3-lKRM-lG6jv*I{PuiGAcqo;`rWY!SP0@SpWlR@f4W^3?iMI z?ybc${1TgqN?IN>-T160e4;&XP_xH|?oj;_S;XI+ z&Q?0u5|8{)kp)yLs3aV}3nU`e7jYq%B+wv2gB_9%>_n1*m_~<}<|4KBINGzQv>C(U z@r{*%wsmU>($-So5D{i!>|Lm49HeD&I~ULP>)=r{l_1GLx?=Tko|`XA)JzPi!2}hC zsAa{gge6#&{FmY?ZX-z7=OKuOzIIq%R?N!+;965NlpJ zVntUpYDUuN60(I)__UZydahWZ7@uG5=qsx)3lY{YT<#zFP(t;hzA5M1=vo|2%-nmq znT3grwG(lPqKn~8FLhIZ5}mEzpx?!w8~Z(96~yCGNYvz z=aK5IMM09}goPc<<`|t@R~TJc$2e;APY2*b7oqSisn&dY; z6FIFX5@Uc01`D>d{suDNx%fL89O>Xes`K+pg?pP!n};V^z0Vkhwvz=Yb9>Ebn=M^g zrP75w4qzJq`da0h2Vu7$s2sw!Omhv&rDsv(iJ~jVuFm|UA=mF7XTpPZN|AZ5%-tNN zzSX!icm0PEh&LGEg5rFkzZe}0fb9=9`zt2x>8M7|As9Zb9r+MW;y}MSq+})K9hY@5 zyK4sqvZhIVU9|K`tMEkwyrZT+(X$Sg8Xub7TKr@a zEPE!i#x0Dt`C~Q|^4UHW&F9e=e-i%60unI)nvN-BAa&%28-Nez4flKq$)jDrgp_9?20M5~djzvPO-&vEiH;FRXsqW|lSnZx3Rf&izq)r7=3%O*JV9DMxPAMZ9wq}0Nl zflIcp1>-fO{pBmC@Hf(9&I3Qj2!G#M7;>2KYTQTKm9Q#bTFs$Z)7%$J*M(|mR|s1Y zUW4^gi56v6Xj{02C0&K-572Ap18E>@0@A9y=HD}V<5CMZYKi+^`>P3?v&E#93c5Nf zK;cYwTC|Wgr@27|HNCW|SRpE04e;^3{_zMm=y1^?GfUDiACmqs!Ex!9>B2Kolr^RIEjdC8 zOllRUKq!Ul7l?kghPBUBszgx++kL#I0o93TJGroQt!AMDWJL+%(E;Qt{27QieX=u_ z8jVB%QoL(i1}y^3dn~3E0>NUc<{91sCVNFyb3Hm||YFcFhewvOHMqcGU}CU?nxYyj%&)Dt4=MNcXId zZ^cxXWcdxJ%+eVen9)qCE2a=4Ob#8T5cH?f(?i|~;lpC6uS4Hhp7yB zu8Ogo`rND}h8lH<{@Jf(O>EIZ{8WeP81592D&tB?T}{oE__J@<(gC@lDl=!+v|#vF z61YlBj9?JQ@ASJl7iJz{WMaZuoAM(&CS8p(giEiUZNHO>5}cgRXvE!;{Nq_?oxi436! zSc=A<-5L9ZE2BG@Qiwm({YsX2`^KI_vjAeDnzV#_tFmvB8~AVIf+DQqzd#vPQ=et0OLUn1 zG)7G2=W82FU7?N~rW?I#e{(YD>QG~!<4%4`Ga*ZIr)m^!Kud+{`1}l5p~E24Umx%l zGHQEceLGbwai!D&vGR&`1M?(45r=D67ik&iI#2k6WKQ}9kGf13PWC$r#B02kK}VPyk0FbM+ksxm&| zIdggh^@kL}JU!5*dBxG*{tUlewIQ{1@1+^gcPTQgxpv999>WN_ooJTsNi4ffU-Kux zrAdNGxVurz81$ckk;yE)0UB82Zpj77{3AlYdlwE2@V@4=;{R|>&BKim)0)JE@s6{A zs36PxIrq9O*8)#{hpRqhBd93>#i;&TP0${mdqo-UD%;Gx-=CRobi45w9?H3KTZt zfQ_*sSFAF8hc4gxSz@OKo@KFc@4$`Uq7oaqdd;;U(#2hysI(> zu|~5kL)jC3J)7RRwI967oV`4P_q1?E{+KTIVO`pukx?4A57e-UY^r)}wyxUcLvuj) zdD%Enl+u>oNv(F|URE)HUAq1CbGVL0(;K;fYqlnR(~WrSP*vN1QBqk3B5j3yPbu=p zi$LXJ&N6!lD$-j4ZrLv0zol;xnT_6dR*o@`_;7aeVc!;-Nkjg^dz)i+i@MIZJp0XO z3vxrtYbPL8ply8!ikQJC_W8FV546efBFRts7wR)4i2awsfrO!@(f@FQQlP9Q_c`i{$-FiAmkAJ&=c|rK1!fmu{J@^`^MwMB$rmJ*nOi;eMI2sWJE3Wq0pC^cA z(}tH4^J3hE6#5M*Q(OCiW0Z}+bVX3%wx95 zYK-E5)d5tpTFgG!zGTwzY9@2PKwHj8w7zkDf{+UNtiNQnS4|vfCm*H@joR8nQLv27 zBUhdzNNL z-dlZMX-bCb9m$3nVg@l79OMj!oH-X)WNiL`Td>zv9}62ptuyaCksl-%SViWFVQhA7w7s3A9@)Fo7#@svmy~?dvC0!m zz4eX(&$U$v&@NzjB1E~eg{D2G2l_4P8{E$r`9~Ro(d7u@9^zYzaWsit1bWZmD|IBs z@%d5=dp$S@RwNy}VFlthlw{A)MP7lQieNW~>SqQk<~r+dk;kbjV>;!auAUb+P`(@x zed(F>;5ePw08JTXYm{#Q^e2WI#gApQM1GOejjb9QVGK2EkXR})7jKRu7#7J}P!o@0 z)FhRs)#Jwew~8l}YBdI%S{O zDH8Q4gy)OjjF~Ho%JDbzGJnTc9G)iG4%5%7wzhn}kZ+Ur>GIf5ZOo?bmJ}+fm0mdH zu_iha(Rj`lU_g9LT3sm%=CtMU(!O;If;#NoZBew|00R!EBZcp_)n2rhW!lMUi8C6$ zEI!00ST7u+S2Bzv_-eA$z_tn9)X)#oYbv2tXu^)Xj+R6*4~`UK6OAVx4ek?4St2ik zVgxVgarQz)nP7j}@&thwT1p#mM14qBtgw+#V!kdyz2fCU1GXQ4`Itk#*LS|VOxQ54Otx8qZ6BbF@xFV@~E zywYyl8jWq+wr#s&+qP}nc2cozJE_>VE37#A^Zo1F`|P#OxmjzU`ON2iFXr7Gee}^r z>#es=lN3gEjB#0WGKR`mJC}Jh2~3B>{!WOOk6It@NxwVJf9oUE$#1-Cv;~vtQ zG>vneaT6S#_lWXZ*)W`Hu7f~__Y^q2O2W%-df%x4G5e8{8q?Y(oKOHw_%Z}xTkmqKW9ue7h z0AGrOb{*Ejg(^(hYu=Ndj~U)yyl1VyzfD+X>&9>Lu}?=kR8?Sq{&dCtY2~o@2S*Fm zdx2<&4QS=4rFMBe_xE|I-f#7;@hzi;T~S#eqt$5m2mqu+m=M6jqcjoYHuO9ig5Fb$ z&~=IMLNZ4je$c5%kPHJO_o-h+vU*RHs3C$;KI#LQq4n{7@qglEYSl}`?O@=s;-}CG zt}|QCcFf$Bu@Y4HlU!7}LIn7llk!8Pr0JYmh6&+H1nNN9zRHKqFqc7tzLk>g=UOShF=C zr;A+gUBdtKov;zUbu!~SMl=3@iP8VgsUCkpfG^mU`DUr=F~a;ZR4;&y{eUspK*I7& z^+3R{Oj~l3aVBY3vxtbi36aQzA^6=erk*vS@FoT5tjnnlxA*OCem|ctzhFQK6p&xD^`e#&07ep*h@nT0 z8qM1&Pr=nNP0Z2ew!jnX5I5YEV-G?82=akHd9Ibf5g&8jhsH zDe2QFUzwxUIAk@9GI~fmeJ-IwlOtfB7+l04p{s;$N`g7L?aqZTI+iPtiXNGfXaZQ3 z_=3}%^9s-~d0OS(%vESp^end2vAUbF1+c&lBo5L_ZW!wen)6`>$ha5=r?VQ&G_AX3 zXH@dbVk{0FupejpFN$68C5I+zVGpAX*4M9rYA`$`A5ONCFR@iM!LeG1O=NL0(Ps>@ zwi`tGe-6t9ODa`amAX#j!8l{0BQP2k`F!mOj6)2Fw({LgH!x@fqm6_{xySp&Iuqgm z=ss~j0U1gFb7xDKAd*0w|-sTII9pn$=G} zO{#ssH>xN$yp`^S%gfBcs0#tGN!FH2m|sMGvzR4CIk)gPagN?uBI`i7{Y-Hta)8CDAzCdI7Q}zXyn9O2iIZRiU71kR^P-j ziXrH2%tjeJP$PA=nGofXgcIeR!xpv^6sq6w5u9DW8%ArR%2AoN&z_@~XC7f7HMGfk zuXLo1r2*z=CmMq`0m%5N(dlC+3_5pM6Cz)BgpeNNp*o5crXi{Bo{8S#t@lYEg3ztH z&o)x(6k}B+Io<`v5Ev|?wJ}DNTfY@C1NJVP)#)f2?nPY>Jn!lVLV_JlT1&4GkMLqj zC^7yL1{=-d`jSS{it18xEKpU#sRLcx!R^y}! z_^rMTn=0t1;q^~2Z;3&G&~nwSeAQo{>~V%Ol?u2G6mo$1s9ziN{9H2OCJ@s@Y4yYMY!kZi43`kWBNBDRI>tgkoX;6uY9{m+CAf z#?QB9u2KjEJF^w&5U2d9qW+`~VxgAngKFTsl4rWfdyY*Z{$8MNe; zxy$G$3Np(ibza+Z<(N`bJtQ|(kK}3yiPLS6R=o9h*R+SO0oG|Ws$P3S$=$WNRk31_tNAAtk|V~$w1E`|MsLcZI#<`(F+^Fh6c-9)5&;c30?T=6Kz9je9^;%HNrZ_Mf%qY_no%Iay%imhQ46 z@aci;k^uVsk0#x}yazIwalvL^0iZs4YV(BK8-eE{@Pb{1!sDI~B6Z9m!m z_T1B+*?60z23X9O%D)_U0_UCOz8x<` z;AnCTmklmM8WnrL)vOmrE+jsZicZwHC8N-tcVjoOk}TliHbN(u2L&oVKm{n&a~CmS z8;Ng9T-Uky9$u5eNPCiySiYrL+9xYi+YOv6pEm07;JHzup-rFNVYiOK;Lhh7GBPtA z{gnw$XZfgy?${TpY|GA3QExylp{vu+$wZ;L2l0}g|5Zh|VCsj&J_#Tr2}q48a2(!7A(+>g^Q=cE}qE3R5g1%#yBQ zK%t2ce*&E8>#*P~2PFi~uOCaSs-c(Pu!}$B^RF^=i`GVo3GGqwcCG6D+#m$eK2gvS z>_fMvNLTU7)kUu-*3ds6tA?rBqOu>e=aWhPc0MQl%;#qkC0OJAWFc3KKlcZP1C%xn z=+($CG(3cZHET#e&Maz<`3&#FaTDG7JP`>J)Uy$w$Lob&PDUkVBgTpdE%`(FrQ5N- z(lrZ*&RYe2(GyNrM^F%k%57%T>Yb_@m4gvN1J0B{tG{A0R{YY9oSDWsF}w{&V$d{& zcm&!2?l@tteu6#eWIW{Y*qmShs=L*Q$14tpMj+#+2PD1X zTB=mj)QWLWfGP&|=!XNc0V!UKfSPjIGf}l4no0R6lf+-(;hR-XWt)l4j8HOpJFRvB zuUwTKs|I;W2cOx)R}oC)g)S`EQ_Uc(+LcKig`V8OVD=0n)nN0ASYdKVgBj%th~XC{ zBs;bF>G^aE#Bu{pO}h+)t+QlDab1^1JPvI;!kfvBdRx>K*f{}Tye{VFEq_=KP0UYd zs4V=PuHY$eM#m*QGfx5z8TlA!m3J##v(FpfFoSU5 zMq_q{^&E;o%a|fHH_0{@T}6M+q*l30+F}YsH!Poe6ul#O0=;{S)a<1>1j{(6e$jxeurk@xJg&12JFCs zG0C1%GTt%ZMnjP>f-P$Np%TOa!LPBf%S%bzG2iv%^G#ENO*_r(w~7 ze6PATn5jH+hha(@h-cRhSm!^Ty2@g}0c(W4UB*MV&YX2}Vzb9~e1s?@#@*p1ND{h+ z-!%zmVFnaa?nAZcO-DvI4SXoY^WrUNyZ0G!*e=tE4B6|z#q01T>q0Ls+3&B6%uKY(wUg+< z@;UVOne>-wU==UBhq|br`MQ`kRZD}%GPZs#%cZ)@i&Uz?aU&9WuX(*ksqV%CSyC0< zz;1k`1J}8}ouPu^@Y2&~LHo_XxblaKEQ&@`Sv<P8gY&Odaf_WWX}s`ca${9F=85h;HgLBWafRroxR)OOsGnZW<`S~ zjl>G_Nk(_QjQXH_Z)ZWxT8m?zR}M|Qw`YU57#l^OsHRUj1D08+b`+m*=95+PB%6H* z=3BsP=a_9OK3x_>xppDa;7pjrG`i|rUGLYva56(OgFc(tE9KTo;XaUY3p6Fk_ONnT zB?zz|>2jFQx=n8V16H^K?lg_7#oeYSLFUu~0f%GrdV|W}CF5{~oS6xZ?IQ4e-(er! zXKWSw$hS&sQ%6!e?65^qJznp+4^mr=&1{)|%~Y%7uJlJIV6iz}v}UnTS?ca_BCB+b zr89Lo1S=rT!4!PvTF3`Uu6JPFDC2VR5?6g!c4eNuKroXdeIW>vLlnF8m_uz~IaJG{ zLZA`gO8QHh@u%5&VqvKg{|-$$}BE*JLLW> zN4n8v4+tqk(-fT!O+COz0<$H}UEHFGMyD-%dBd}3N&D*1%|mH@_pYNuLB6P+%K^3b z3B`&sE1vFWaORvMn|q_Dika0KMYUljFp(gF)^Xt}6ND4lLfiXhp?tky7lu8nG=cq#r1E&pf$aRHR?ZY~w6qwMfVeQJvY-8B~k;SY~_5*EcZhm3vkn+AMoA zJ>Geu)b|)a8!eu2G`Z3`Zwp|X-H}|}b7vPtBh+U7+3Nu82IAlm`p{VBT_HB=leyc& zGpq~`(Ic!y(z_Xqc4$U!Q$84)!o8a!$J_ihv?qLYf^DGKlg{)2p{Bv!GvB;G;;>-D zMe8cqrXLPTf4c71|H;^L&tCc%0t?}BjYJ>Gp>kOerqG!Oi|+{?Yuw1y<@6Bti;Y6E4G?^fMhmL~r_!QxcQH zu+>tPh*~YJUL)qs{+u<)dP^?ti`dGa2-)Ze+5|%#b^5k?97QA{Ir2952nkg_&+S&3 z@h8ncS`m<;Xyf=7K2|bOvW>%!JtbRKzmXGm5s@V$B8n}`9f({Z(b0DuP3@|&YK_YN zn7r76JbNVNZ8vQWe-9zav#R3b&4!)E{psN|0331oa0>lZ+Jv>mLpt~=DlVCd%NIL^uP zgne5{WUA7gT*4(wu{_s7T5<4+)h{;xJ8@eu6SSg60C{TvT^04j zO3Xo1x3Kojo{QX$Sdm3qI|NHd$@ogGT-WRF5T!`fBz1ZdU!bB@6_*Ddw@S50e#5h6 z9GFhFvC=caER(XaPk0`|Gsus|%mwLK(*vdS%oB06uu0qM{OW0-a;>{2J2{2M_N@lT z--fsK3Ch?)qqJ|bSO(BzH3N3O#VfVxQk(k66J3`@0x#R(g{5%0ce1;Vat3CtBGjmI zEY@N8v~}9tmfx=rgt%jy&2w_ z*4V&2Bqsi0#nH$jipP+J5xt8#gHWx{DuPkC9)@9osVLqxeSHQaqq66Z+nu557)5kf z-3DVi6jWNTH56%QCmZuWoNS|;>;U2{Tv8mq2v+vIUE^z$=C1eomgg+lnO~87)Z?(k zo~*a=upo$|Fn&%#%&9S_w#qwlZWsLet+)aooQr>U_Tw4jH}fd|eC>3XmN$uY1KINz zy4Rlg>sJy7T3)21wF#=v$feEqb7u3eXFrV(<#9r5YFAp~ld1Qxw+-^sfz>TS4`STD zRz22E1nZ$kDo@sUW6r~`=LGH#3xGDC6DpII9mbv8u58Ifvu5&I;NQ)ox_6E-8pLjq zo_akb!@bv(y!h#!rNkOK{Fk{rJ-gP|N-WFiv6KziktmM|-Wyo?cU2-aHkj+pw;wtO z_g=$xU*P}D^DWQtSTucK#ZkYn<%0jwmHfYp-2b?)<;ZeF2{9sMKR&$&)ZPG~Esv;0 zri2HEsJjPZq&<_6#UFZbK*R4A43*`SKy!0*Pcg)uT*2iF#4)U-bWIpiC3iwxWwX7P zqMM1LN+-3cq&!&{spAMeC=Tx;#vVg*<(HO} z)!X*{mtyMNY#_`1H|-DfJzPZUfAyCrI~sh?9QmuG^1m3+|6Bea{Zh&g(JUd#_jgo? zR}5AZZAU>kOccQKp-9BYOEpnUOV(+~Atmvplt4j}T{Pp5r9Y3lp$0K!c}bCD{~QM+R)*f0KmrwMr`<}}3gs_hr+Rfuy?P3j7) zEi##JCuws40#+gf-m92Ck;kgLbBRc(Vk_5J0OhZ$e4Mis)rwD2LP&UK1*i^FMSu**w*$eD8Oi^H4$i)j~P*pm-{7VV5v0u`p zH(d3pOJ@7ozdM?V^%}~i`p$iPWH)ju+KDm>?W$Fg;0VBZUOZgvt#s| zp8b)2$0zZtF6mCe2ZTth_n)oI@N?>dB$LM&ey3K)$zCIuZZ?|Nmxd{k@;mR2CKlPHNZUGvDHS)jN>C`T z3xbg-AXzA{|M~>ILBjyUOzFdS5e&l6^V|Ys%#an(4jc5WZOXd--twABxq8~YZ`J}h z->(WToeO5tDAyuKU?c-63`LA7H{|M{1%{N4a;OnUx^1h_3TP>kp{^0Bs>8~w5>=Az$9Np8zEhU`P|I@_Vp@J&n(CaaQ!y7 zNt=ED1^xEQS$WWH`wb4>egZ~H{N0Du57oo`TL1!ZzeP{R{1zJVJB}&Jguq7 zi1ZCODC^Eygedc@_)#{vmS9gJLYxJq12v<9(9hkxx9_1)EEx+pS#@IAO3t39T)C_t z&>K6uMeT}u)36wo=LVx2a+x(5Mk-2yEb2nBXx`15l4IwU+j?S>$#+E9Qqngcl!$oA zkA*l=lNA1e?eUVXMI2J$8vbkgF-sD&er-haMok7va*4xJ=@f?N-sVS@pXjAQnHJ?8 zOjM<=QtAT}E24ut`J+`nAq?~1i67Z=K6cAH@N|T2-dryUin0#W+`xvFY0rIm8JGTKs^QZVfeR7k^V-PsdObD>KDs8q#h>zh z2ob(%>78itW5VL(1Ct!SX#z{4n{1r4yq*F^jwoe)sW9}=GGfBcN#L+N)Mhp!i!TK2 zJ&;vsemsn+voh({>8|YUl2c7r`i&y^U_cH>A!3jcw(75mk`+}RU=yA=2w9yJag=CJ zNUf;L#85F}{}?StbSYdg8I__)T}Nrz&&0Dyn>8$2Y6Cy$!l2I-iTU$~SK$-;qUZeR zXWdqE>qy0sY*_VOrUoB58N)?#1hPsF+~OT5bG6^_pO1iGbNxaNr^MO!*uWk0OrfNJ z84JuAB0G_tC#p?uOr@diaw61TEjO=8XL^nC~) z>}hF_zZ$KQ4J!h49a7eq)_Ww<)$cRZUFAYxsFTBoNt8cW?aHk+!$oyz`V2MoRmcS2 zs|Z(7J5VM?Lg>CqnM+I-q%6a9M2s#!6}OotHeA%X$yM+7KLB_5xu#(UH0f0haPP~N zHfjXtq}Vu8dcRR?A&HC_X`1OD$x|-awX_ZWxwEiv$JG%T{psd7%2G+c-f@sOV$Rio zoPE5_;XeuWr~Pe9J~poEZk0?)tZxJg* zLea#Q>fS3Ge|q({6Ila8%&w!&JN&HCE0E+vU!RaMPl2G7Fds0Pp(|JckgM!mAT~d} zwD!Od{a738Zlu4YL32ZUr4F&ro6kf6kJ^c;BQh!9_@1!IVyM}WHb7pKFKRG+W z5-LP7bfT__AwG04E+2g1FndKf8atO3rMKvpSW zOetV>%%*ql-Z>|iZ|)miJ}Mp4SxsGb?fkY2*%d5I2~JQJ1&yx~IiP7PpqQn0e}1<|cy8uy*fX@>!2 z!`Za+LM!^{NyLF;?Q$$Kj%6edckfvrw;QUvivEC~_k`ssBJ~pKfP1wIRCcsWbam42 z0U$T*67qp~o0{|!XEU=hPxhR<-SE$^C?yjS|A6LyzD5n0$U|l_!Hf0Y%<7ee%ywvY z1k(E-6~@0zP;g<>ox{Gd`_#8&hyC9J7|wP!7Di5g1B<_Px}iWN%@eZnf++pc?PH3F z_{IIoO0dO50i}?87V4u+#@tpdjTB!{d70+>@HgU^zpPtZq&LErWL-}lre5eyrd<6# zK0lEK;OH?NRr2!gH#uem{^oceV(e7nMagvPwBV6ZxG>F4(yVK zx*lS}=?k~wr6Y^zbRH>2OYcn^!MR@8*o9D8`Uztlwx{#wnSXT6k$o$wy!?HZg5MBh ze;N=5FD)uK{Sq*Ln*Cbbp!96rv@e(Cr(!8MskpRa1aGe^Q5QoJSF*}*^KXT&tlF+` z(lGW(_xOyaRhC=fBkC6|{O`B2Wa``FWh70Go0L>mg#;H#ptsEf)`Ac<^RGC}Klj7B zgN0Y+>Pj&F5IkH`1L{(?PD^J$9s+kJYq19Jq_ohy`ymR7?{(M5mScTy|lKSeU zdT7;C#%b6Rent8K)DKfENo}Dp)s@ch;2EOD_PFe26aFU_tSe*i(YUM(zLJbqYRC%< z{tmPPvIL0vkxiLf$$|-&O#!6q4a(loZqcn0$F4(TrV`z;IMtF1L&owPL2I*HVp?X` z=A{8I(m~;;JbgmJk1AuYGz6N(r;&S{M$Zndd*td+u&vB%5Z?`_-GWc|1Xu&6PHDFP zD)MbP27)X6zNYhhSI@cst=JYeu(tlIX72P~PChw`<8s*FLo7{3*j&jN494YD#p`h? zgHo;-!lP0o5@2vJ9PHq$3luuFGDCg?K?V;6!0#3zED;X@0)va4Yi=)AR;-*yO*T3K z0DF_YOG!HrfK?h8k{ejsRFpuIF9(|xu#A#XHp*lY;XqXnt50?@n+HPlioeOgHZxeX zv2LeHBC3pa4>fbdE)xscXRQQ_t9!(6hy*dXH4eC`$voeNUuBsiYG%+(Oi?5`CS5nh zZx2cl;s4lm$^tIn_Lh=VPd^_}#I~9!Gt8;;UWv!WcS^S_2n8LGSvdksT`x1r*hTfC zB7eu^6*4kIa0m)k8c=L?TQS|9y;jxIqT4{sa2!g94Z0^bIW*)cu&G>x=wXVz z*wV#u3j5PS+bHs>gnCpf*);v~ZCqb(<_7ucXJpK_Nc77jR%KBgEkI8Wfn(_%z{(ql z$LIl8oS)N8qVwwtBT5pe4tsRcg46gbquHM}} zN;{9pZ@9DKn78Y~91Nd|KPv8$7w;J*ucCjb?9H_HU((u-&~qDazHSiJ1FB%i!iennWY5)-Kl@pLDVr$UNYdJ5 zDU{UDRxWTX31OAQ&y{T@f>w3@xY0FMW**=wDv_J>E%NG&8xBeIoCSh&Dlw$r*E~tp ziU^*xMaXF%y>AFWCj@1gHn&crCZAQu5$5+%i~V-xD!r-a*{c|hc{pYSi%-%iA8wd@ z9nfZM9BlZ=v9hqyDa|a>nfhwl-*HoF#&&pDpQM#or#QdQTu?PFB!`CdOu^2Dq@LR8 z_v@<2Y?Z^g0Tm3r}0lI9_4!rUpCarB>b&o;-0|J;@F8y(0PyNFcgqAID#7z`a%&HbAz3gg4q&YFl{A z8+<9bK5JJFr8zUkmk$xQ;PkfE$rx1TYQ)UBa@%$ut|NSkb4*;EF3tNFDe8f;}4i)XKuG65dI z?iH>6X->d$IB_Hp3J~Xb)h5{{1icsN8~BweWkgD2V2rD05nUs|7b#3QQx(gE+0^b( z1K}hLe5|^XeqP~#Jn5r{K_}p-V1RVSk)FrfTk&Aw$H26$3B?A(8aUqhBpA4SUecNmb zx-d@k#fh$Q1>0U6wnlhYXjtm{=BvmVOqXEjyci+1kAdg@}b#D{7AoE$W&zKFxCL`1eer{sY%=&<=@t&r1JKLfY zpfQYC_Ij8)l3+)7le)#Lx3aD6Cwy&;i^@w7sEPPn0Nv^{0NWt*hkYPUOWTq z`uw9Gc#*PZ3i!o%55=rDx5gH(vc^|ZX4ZZ+Z9%)8F;{rcwXjdu%u#&avmpPG{|x!C zi~i4i8S6_R>GC(61^kAy|DLDce}~Us;wlnF7u)|Un)@$-mArw)-{Y*Sl{CI5*M58Y z34(ZDn&(Zpwj#A?%(6kyL7mn)qXxz5QCs+#nq1 zJ{Jiibj=Tjt{|qMRRIj`fK(RxUrU@q0xrX+a5 zZXgUKdPF;5q@9z}07rM96kVRy3?odrtp1P-s2aCDroukgl*6zK1hXFF6s#QSkO>Kb zX?UKse}fW>OwDsQ5&V&UaI&k6BGCFWS}Pj{S<$)VU6Y!D4^M3$i6YTq(}{;8wcKqN z9giJDa5C;7EfqMiH0JayNN3A$L1w(_6T(2PHd=^l1{gLkKu9N+>|&!av8C(r6$cY3bi$LRu^sCTZdWj#XbG@Zsf&?3b0yLbs~vm3oW)Jhnp!B(h@tIGA|>99b-8; z9bUjO@G$77+^;J;lo^BO*!lbTZ`g0Hl8PnmrZ6%%y{;Pn=*X!PG!6QHhMO7Qk15NmlFhRqc?`S?LP+<^sjtsA zH8vUz`|fn@whh=Vj>*{^3HFQk#Gu~PEk{YvrS>Bo7Tza5MA=b)EgDZ=i^A^4CN zr}BR>zZ(q7?|ao?UO04ITnP?P5zP3xu~EddXA~e#)?AYDj^cXVU!)VpirTUc$loh+P1SA zbv@dUZbc(*321H&6V?J0liNU2$kcf_xUdNtWPZi?Rjk+I30XwnD@38$>R^EvcR>fR zYS5E^nMlMHwWj%U;Cxf{WlvZ+-$4rcWtOszfEwxt*oyT)M~0xj1MD-PN0N{u<6!tH{<;7&%)&BG zv(Z~|_3(#1vkNlrCzPSp7c+Xg4yk* zCDOX+PP5Lr=uF_=^G!afxulttT16vNUq3nOI_$*5loZ$A)HEeXm{l}H$fdXgUz|b6 z?c6n_SNlkOM4%L1P%hzxgwL@jmYHWpe-s0-hpK`#(Wq#iw`mwz28+^WZK+0Qm#&}E zm_nht624IZ(2mZ}JSI6Utr#bgv(N{$gCvWKA#g@Sy39$ZxyB~-}5ED0Z4EmcG? zwHVDH6Qd}B*qxhCP4wiWKjFqXvjcTG*i!Xr>irS>(N@ zd9K-FCt1qkMRZ3)`xeaOLLY$30zr|j4+VAfUC0b78-&mUA8C&dM9>0NQMYwLJ@AWD zDr}w_)r*alh2|^y*whK#FaxPM9$JVPWKGmcy=gXKdHyN&Q?M2-v{+J1`O0o5+`jn% z_-ZKY9e9E-a!89u^eS6X{}7bH81I5+d&IuO&Q8+nY_so;L*sM~o4_G>kNHOIN9hMf z?Z$SlXQ4I8Pm9bs=Sgde%>Km~iR^0Yq%q8nAMjvjc+-Y;y8FZCH7ptoQIeF*kvx*PsjJDoZs%>t{e5EFRp!P-^yNM#Qj)tklu(pEajyR1LBK zr8>}&6DmRP$m(CTL(!`n{)iH@z~KoZGe@cvWIrW)2HPs!xN!%HwuAJm8tIK~&i!Dd z#q31o6?H@CFXNC?E=KpA!zmJ@JX4Ppg+~m;GzKk(X#nb=olu;Sh?xBG9OrKdbYp{A zd3Ly^9(i@C6x8RNdh;6o3H;C4H$UF`t@!)eWdChc`R`dUh}k*188{k$Hxvk2+ZkDX zzZG0eT>f^uuU6J@o0mt(g)X2F*}SN6fwxt6gI1+hlosX1tA{`5%w^d$WFg6Bad`Q` zw}{UBy!%b;dc2cCqF~jzc=%^*YV@=-?`-1p_xg|*N_tY5m!4hxei)Ae9kf8rj9q9V zsiYmHd(O2GY=zx%DY-&5#eM3&W|QgkSaFPQjsM|&Hpv1h_**)qd>z}EO1)!?hDX<% z7`B!}2Rj3Ipka4mdVN~8LM?J(m_VhzAL{z z(IRWRDZe;XPu_yrgekeOieT8wh7LNj^25om6P@x0eKYdQFmZ#0MSp`t<~wX>>u_V~cJ2wsRX#j6GpAj<+h**hE^AE`D$j ztYDB&(fe;{y2pE*Ki3eN$x2g+*Sk^zt=&{q7T+)j*KRy#2B5^3GwVryz>rG1ty1z7 z(>A5#fXO+=yWL_#%dv>=4TtKEs0CgN4tfe7JV=kF9iB4lnLn)s;jSkY|KLrIm_;iD zS=U{Ub6+$^u{Gvn7^?_c1FHeOz99Ii>#VM(^RO^TMjN56U5OvYUFO}dc_zHnHD98#o$4p>tvkbTJDOcdF-?x>RqsUNZC}4ivtI4aC=hkA z6Pg8VU;oE+?Z3LlVEQcgJ-<)AcW?jzlYfi$`hOC^KaIU0QL?bH|L!3B?=)uzo03|(RZDk5?uEP~kLU&VvDRf-7BIs_IIAIi?WC70TNMY9G!q_Afw_m_EYf15)-pY1Z7{**3S~MS zWZ+!Rtr`F}=(z>GRWaFWMX6yvb(QHj3eifqV4A|NMozH_ao+4x2P^uvb19w#F1D8z z$I4*wv=0-6elqSO;JzuUtaK`cey?bj7-VX|Eqm|f+L=2~gb^xmA4Y`~y!^cd^Wqg} zFk=2tZ?Y7znm)H~5xB51uh8WX(iEsx!k~F)eVy7)Z&Z)#iNLW9{iTIs!rkn(RB?d5jRyim_TX?sBBX(gZK(i;vEJuln4Eu~vy?;p%acK(Of2mV>j)llt!P!)!T6T@Bh^>`o!!=Nc*tzPlkvx| zTQS_E^im0pf!0~&EUt1`#p!%+i0+3?f@Y%7Tc){RhBVh+g*{@wnIe6n^cZf>L=^4( zBMt{B=MgFvo>mgnAg}hvxaMXMmSx^x8@FcpY8SS8wL8Gm#K5Z^tTo$F#0SzS71hpl z@Mq`Ule=<&KL16G7^~};KKvd0R^O_r|MV36{|N7DWi6#|YRdQ7`QljF}DHZ7Q-3XquyQ=9N#nWyF#p4k^nU6Di!=1uh&fOZ|>HA zv|{%W@etLWgDeL$x9P9yF4^<^awtcs#A65Q*G_K7edaqFpm6^rpR8rLK6ESpNKl0e zfbh-)6WTQ|c`t4YlL)nP7lMwPbF@c1f(v2@4ZYQVF*vPz%hJyaa zYn~L4T}oP29lz&?YAQj*=(~gnng=+LIe~CJTdMk1+De7U9}wh+=qeH2=fs}QNhE!y zzWA{U%Up}y1*u31by>r^;AAlA#A^3UAg8)p+$tB4-&0p9A%LtqQ>O>tqnVYX5?{t<8>X6 z)}>xAv6&Kp0B1-!+Y1i6p;B9GPuEhlTD-|Vq}%cxPn+&0KkEyAj&b;4D!Y~8TP-F{ zIlwV%P3@_&G-C2b5kK}c#c0=l={k6{t}2EYO?hjPN@cpZOhS8Sp`}lWZtP~idaP6| zQJ6BnlkGP6V88n>VVHJme(_Qy+5aEX-ZH4tHQ5?0D4dPEySux)ySuwP6j0d4-Q6kN zp|HZ;-Q6h)cOTB}zTezFGZPct_vemyf9=T3Cv)Y>wZL-;d+5LViFQiqHh5|eWp8hC z-Qan56-k&oDS+)!xp~Rtab9&S= z9Ty*4QB!z5c*Ox0pdO84y!oyeCDR7dbB+jA zZuV8-K2-biL`VJ5FM$Qa58?O69n0;&qZcPEjo2~DLN42iD5PTi-jh^V4o@q`JW;E{ zqdv!rK(ZC~M)y4_73Nypt;sKcUyl-&Wu9ezqCA=iU%p8FhtI@+s_fZC+7@;N4< z{>lc6M?`w?-6D4iZ?`0-4}%>94{u=*nH`)NiDFAfdIb|0peDE!gC%(VA~1TroK^w1T5OFb{Q zN&*39N$O&W<#%-oD)CblR!N&@D{wp1`BTt=dtD)8fX}uT#JJuWbbiBBE&uAp0ovUD zWkyPDsfp>RuFEud;o+fjW41fvg}e}7wZ2d6StsU6rT}i0p(ux(?`YDKF%w4=fe;SK z8qR?&>&?4a~NQumGy_dLI3#Xq_4wZD_E({wKVvR%b)}C5N|QXHJf&F_*;9n^}3Kj ziik`q*?WyP0Ym6wqjYTg!T0kPxCrgJ-Zi9Z@Foxjo(fwkiVd$=@a(q-=1GfXr;g%! zM%}vQ?6m#hGcGc(4MsC#g!g+2D79#d4MJL8-%Gae8d~pwPKukL=dPZx8IndSf5bQH z+t{mi;b>E2Xg`^5j9_*3fH=g=P;nv$E1 zngje3a`Mc|PA?-lzM7{S;c7D7zKuJ2#<&kyqUSn^)z0LWqud5LGpy%62Y`|I7_x-{ zGs1GH%BIkEI=^4i1zrdV)hNHqQc4WX*LDcz}gFWL*rPOIwo+ut0Z0>s}l@IQM6=TFf>jsLI${eb3j%?w2h*|>ggJM(Jp z+pE23^+tsWHC~GNmfN1cdHEV!vV~T?5!O3=bkKZE!1KzR4Q|3&iq$?rqP&PV*L0_m zO=2Ii;O%m6-Q-)SUBmoml0H79zt%O!7yIXkV%suY-?vnrb#@UL4ak(i-v9??hs?wq z3y4GOUNoa@BfVd$@+_FM<>r(v0h!FqnueatE8m6yE$^#Gr1NO`m+OR)ph3oWEq9#< zAyvapn9U1UWtMwMfnw_^POxIYWSNZdf+9owPj`@(F~Sf&Bt~3)qwx`CxeULT=VB>0 zxrGwh=2HDj>AE|$^vW8h{ncLgiJd`7AN^Frx)ZGuleA7o9{8$xi_;w@Bq z2eCK!2NZLe>`wWsgd{b)XEBJ@GqKJA9O6ZF{WkiC2V52?PeQx6P=GH|>5*qfFwQLv zIF^-UqaVybX8$deN^r<1!ahx`zwrse`M17njNMsJNeipAA-;8rBFY(>*nM?*7v_Uz zN`1i$`Ji$m5!Az8VR$iSM!rU$c8IRVKasO+t&CRyy_XJJqgJEpZwzfX3%x+4Dhx+f#Kgh{^PIxD&(@bsO5`@awzF2BrR zWlO9^e%Gl_O~TF%2ZiU;huBqZZsVsLmeIVBSE`|xrbBa6d5Ld%ZX&47%Nku44zoTHM;m$`my z=L2_{m2W9Cy_6&N1aZHz6^ zH#RI>jK^vdUTK!Y>hija0nnZGH=Dua}D$px>gF@e7O8bYKx}^-~HY zqaaync_hBuFD&BqsA0p3ASf9-$0~KDSZ7FQnLpC1Q|uo^iv(%#jUhQ@n6fTh3*&^Y zUz*8@)RoL~%1Lgr7K+(bG@-VuhjjI2n(O3P?#|*5Jz%$(lP)#xk1|I17~vz^326}= zdq&b6E43UZU0M2y4NadVoNGUKPIw#y2JjN_mgkUrN2F}myp8gE6iPnCn8EPjE;-TN zapc++_@P8OhNcK(YIJGW<7>RUhcpQ3y3Qo4L zb~r>ffI|WHICT?6Tl79k&(3%YYPnsJY{i1)J@wbA=X-eM9O+Z+T3U&eD_D1}mz7Wp za#+CAAbpwZ$N!iD|AIgs=i|NDKGTTsGmUKi!!-K4bk6?+1^N32|H!yss&)>uil~0{ zNlb0rj>Ozs%dVLrSf`!v{e)m9!qdSa7scyIJTmRKVtZY){XZXj9#;s=cR3sEyRWZ(wNSupf3=BP{%v#)x7^;}plKi7r1{nidugdoxv%Bjt;pbN> zlroA@ZFeG~#)esN4LX3VFffbpBZL8`fCK?l{GcX5jg&`B@;%0nSUj$U`B_kXe9Q*4+yOS1DNqU}yg%*E*=aX!S}4wxO_Xm#Wza%X zV=n3W$OuIWwjfX=E|6GAWf2cYbK~g<{CXBHTJDk7F2ZGuV;6flV{ux0_8<(QfEs zt@@%pXWD*C!yQ#R_S=D|5TU9i$J;gvg12%j9T!x{uATyGAtOvbE@t17wnameh+*?k zvQ5|7ITS_ZqK*ZTq@m4Pw)HP=aKYzlr7ysVIgug<%oKB3w~ta*EnxD>%||GyhcfpjuYyX@qj^whGEarl3>u zYNOWgTBgaGVJ6e!BR@~EkmnnFpeP=D!(=}RBdIpr~rmZhD5`SGq)%`Pb0*0+D@NlgrJ=7= zOK%-EED#W4FtDQveTrIvS!**WS=BNj zwt;-Gh}lE9W4<)wjjDOq&~A*f{$@1IObviY878ZXi%|2YA5OI#i&6{h91>KIEvotU zCTbYt5KQrW7n0^hRaWwWEWC=|2_6s$@*4us*m~sa601b~BY?Kvl>jNtrqE@w?68*0ffpG9YVg`M5&cJ2NMO5U9ucUUb_a(^98IT z^>oY7m$K4~v`j{`w&_UIvX)tRvs_u7O-3zBWMDD9CF(2p51BTphYjtJ)pZtszCS}( zX2+&lOS0f9A}VFwk%AdeAe9zgxIw3<>MU4l$&*Rip4ha zda?0azbs!oKJ`>2Z`3|EhA2p7K~I|0Z86@#MkCtpVcunPZW#$ZqVP>+d{R>(>3Z!6 zqRiuBIYS+DBG|V5UUBh*w*drw_|}{L2Zd=NIpDfE*Jdq8MA~#%(6jo~JUQdUsa|vB zH_NHeZpmKGaBTzm?f9(b*2L%fU^bN3 zcOn=pHVbxH^shlRaAOBh;4~fVj21jzjC1a?!o3z@6)HpY@8fWATZd>!26y4&RwIeo z!wVDuj_f>6#=p2=?Xn)0F|Y2cjm7v**VNv3`{^+D9!DdwyZ**J7wOhVX!uN-*w4;G z=s)Z{{sm1-PWrFK3UDhRMYtUXlo%>dt-qOACLWsqSGO#H>(6hj=8y1|Lj$?Y5fLRCL=zf>Qe*o)J>*_{Agj7xAohm z**YMDE5wv3L_onFbYcktkp*5V>QbS1u;qe0v6p<^1QbuGOhUpn+F5Ab?u8Y*MY=b?_rHh_G@YIBI&dw`>W+WAq6!%887}=ECrykYt(RB}B zCa;0J#r6~cC2AF_?Cdec&Ks*TBs+IXrL-4%t?L;GdamDWPb@Pc`F%C!y@T0QscUA5 z+xLW(B_lD!0rOp0oZ!>L^|yS~HpGO&2?wHgeYmLNlxbaFhLy(`Ejz*4keZgeuPOix zyCPReE0C#PzRX)OH(3*m*=))p(CCI=jqB0En$|N3XT=A8sIxH9H@~1@m7q>pm5;bmQTNAJZ-J!@9KQZ2u z4$UWVJG0WCUcEoQF!rSF)W;YTkz?q#0hcBh#NFzhQik&2tY``!Mj>*B5Px|i4yp=w zmKXw79AaQFeyO&y@8|GJ z;J6mzp9%lWc;9%VO=1MphMdD4x7Y!CYS-MB3;lxeW^rUffBPAr;3~?6$p$$5E9Il~ zd`jxiXR!(REH?k%nae-^+W&LkRGjo*%qHLmbbw&J^!`2wk}9zjqA;f?A(S-~nd-c< zapR?Msu@&drj|{EOb?G!fSPvTUuL9cD-BwKxXy|RqqY~a4@)1nxBE*M1OgzWb={0g zj`MVETq)Dz#s!8M;6XACmJz`wrw}W`F0_%bJaya4F#|F|BVRE4+W(M)lLORHkr^~N zTFrmdM>lLj=`F9w0J8AcAsq|6s=$YQH(^tlH7YB3|!c1C|kmHn6KH%7G!Qpwqb}5%6Rsbx7qtl zT~Gcf@81^is_~%lEUYz#ODH$|7c(q`{D%5XVGI>({(ADGMMzhD#58axoVD^ z;2fP6%H-~>?Yk_$xB8F(L5(895(V7@fV6kma0AJ>RV9v1@0X02UB#woZR<-Gt+nx` z>E@F7?5ds0g%{^lNous)q(8?D!NfByy-N&vr(~T?*;-{E>!W6~Uxf45d=c{w5xP13 z>=I*B+w~`!*ap)Zyjb~I=Hb{kTt7Kvt;NlhpzMp`npAhmlurwNMBTo^h90mL`fs5> zhd70sTMTEAA`tKeUF|p=NBK)kVR+x{AVtGGO~cUd!SGp_Rq`Yj#?wbgq}@Q}KWez% z<8K2I+R;Q6yvm{+tNZ|p+em-tqFp_xoi(}2g7FOFjDA*UJ+O+GBLT6AzU47RU}os{ zvOJ!gB0WpoGu3Gj0pb)w2AF|i}S{=l z0D?t28-=I#m>HY<2ya`uUUk2kcrNh~7VMWYl}f#`0Odb zX>zz+jl6JpvnPzh6aNEo%bwThoT51;lt<||gInC3KH|RD;22UhTD02lJbUIwih;Wdu zr^=mL;~uj-?+Az8*NgO1W;bc5mbU>Q;;ut|a=}^< zEV4=<8M`xpHlJfBfHrkGGyFb&$(rvTXfFO?SNQE}Ta~_rvW0UX?B_!@a7~j&QR4wi zdB_b|tTl3yGKaClF|>cr??HC4QXun{3xh{F+@q(KV!e){i-K-o&sR^zvdl+txi<%; zrNnY9tf4}7?W(AL6UKl0_GJ5)l5`7QrcchLB1JqF5XovzwrT0l``c_sS?1qhpuw=HF(o@|4D-64I}~vn!ySUnR&s1(vM3ofS+7{F$Fq+a^#b2)Ft}ai*MCi%-4B`B(JIKnEUtD}qgtwqk%IpMFS}m+|G zZhio?+=wH7^)mhAZ>xo7H&joj&xm{Y+;;tEm5%klcMAWYdNm}aG*_rjKUbAPy$Lp} zeX9%ZN0iJ!Wy;_2Z3mbQyO*qFlU*JQ^!8ss5`4R5zB2D2fc zMmtpX__6vA_gc2d`HA@HmL?v@J{Tb%U6QUH2Ts+@OS5Qct1Ayb0i&j!1IOa=nBrri zFa#BF0LjWU&b&6UECmi##Mf0@$_PRWSP8F-bzYG-bXm+gXiH+V9Ckp^yT*B_U!*oo z87tB&j?Zr8vj2SZA|(R69$v?stq_L!HCU^P-CEvZvqxOgP|MiIsKk5$t~+UjtbwWg zEEo(>_%Nw%2q6d2N!`6h3j#;^fP1RI=-%_TUb9&Jhz-YU6m^VmA z^b}dTv?GK}m7~CO@*zKQ9#-udj`x&V?CwIFzPm-sGOB9u~u;!I7(M{&m01$LW5s)`ZPc-Vd!XSMdceWAEN-vKe& z4`1W;LQkR8Cgo{q_jiAYGcIwMT(7$rZXobPz0slPhG5F+2|q)%HdUFw0sZadAg*+i{y*uBe@RyCZu6AZee#@td@{WLvp8n^ zM;w1LoBwjpem4)VmRiJ&^`yZs&GZyi?I`dhv}F7~8Zo+74=}3wB=aMn`6nW17mMYq zeY$nk|4G+_mKLnMHnQNJ+t_-LdvNXiczi_@6ez)>XE%9C-th1I{a9r^_mGL7YCiVq zci_xdAA$l2f}!L_8ngR7)b}elW?%83jC7@Uv!yzPxxO<+d08Ucti2{mQxCSt)f6or z7Vzt->F?!n!=n8oQ$mpsfr`a=v*q6_4j7f)=sQ^ijhHR1Is4isb}3jq`>5nu!*^m; z9rRHFya3=j&Dv?EiUc5ZaU$=fd>b`4zr%T+as1@EF+hYfD>OzQs63`$8W{#D zv>x-@MZuUzcgEE4*6+riv*?~brOpiq!iRJ9V_kr(2i9$G2Tg7 zdBN~*vkBeGKzLockCHI?7HR#nhvUZ{d>^?Q(^rv}v?0B9lVuzBHo~O@3(f=)vs*~E3{gX04W zij9)mM361hlqzVg`z{ZefwT8)hy1rlmq@FHxwQ2n0!VlQr{ol)9Zx^WAjZK$uUz~t zC5%8wksLfAZ@-r%Yf98}DO#knAIPee_erk74+lv11dpsr8`Kq%m*&wE1xmHaZ@oFA z#P|MRhM9yagaY;lL2!%SkbE;wg0mWDlS&wW9t#%o89ar}29V*-T-sw9d+bURCb^*w zQPzD;$xnvh0B;vgV~`L8*33J3plpW z?C*XNP=u*a{FK*ir20+!YnX!CPnpO-K7Oc-1#2}DruE?uaf#@Wr5gaX5VbYtqa*LF((1#E5%^XKE@E;>w4nWG0Lddbs^h5e5U1hDos8Jdd zo1SxJ`Aj}ddOyAIeI6*<)q=5`f88seY34U-YZYB|YiKrQKjIGW{%O05$8yPg@)-UW zK;X%|wT=%&Tu$ng1wyYm)`ye4r52x1Bo{?#NgPT#TPPDg|4_pu3K&q)1S*l`Ve~B3 z6$q{gNZ^S_3r1gH$@@*;IfF8@tF?@{dIkHDFi1@>`Hs0I(5bY|D8cFxnzkRJ1+1Xh zkSoTgc78ubDebUc4j_eIhzLwxlH(f31T_TrlEF=~5xQ>!S9Omf$;F5)=uF0oNQ}SEiPTazM|g3Y4auQwmN0)*vi_ z+K{GGX5uc?tUaVVZc-f*agLzn6)HvpHpN{ zMj>ZzriH_CDbu??X=K00$OG2f*>*I;C)xy$8@W74wS#3d!})&IZA3u!#RuFxX3N7X z=QN})mYQn<3C6^q4&IRrJqewGWxsVP%1?(JHYh2=@GHF1b|WF&$u)>lOT(;xe_zlJ z){>``N(WfU=Xg~D+W)Nm?26mxR6PY9;Kj8!xNKPjG4j)dODjN|W~ca@c|FHw}gp0}9n0Uy0(F=onQ*~8Erm$I!}%8z<6R_$KW^*YZY^khGN z;7WLBH^)zn@h*xKzM&Y6-?5axRcZFAD76lGW#WE?(c zV+eX2ab6QCc?Egky2DQst@X(SKEjT0hi$g-QqP^QkEHw|SGjiaDadpBtt02(ZgLMZ zKWYX1{XakmgNXZ-2j*fLWx0!W7E}l7smW7ot;3U!u*r?`eVQjiGFR_)rw%7?r4gfy zw!gnBmylDJEfs&QZWnT80_aI^c?w&SB|^?jAeQkkNb-r4?5PAnG2L1pI18~%B$RYn zJYs6BArxZAjQR36eSd=gW`mCbd8FnQie9+Ow8Xbme-r)-s`uCoioojdmS-!~=vUB< zc8l`6Dec?E!V-7b;&_hnh9*bwjy+@6>kqI|z=o&+0%!}GkN^ZJw$X8f%mkr$pCaR6 zUds!xFYfe_^!E&JNCRIF;)_HRKn69|&5u$D(F1ERb9ITWyhF%8HvdD}pwVs&eisC- z(AV1`gh;L>`TMc`I`Y@29FeX1q)bzY#LwUpE~O(9d(j>44|b#<$Il~K7S$0dso!!0%*3<@LG`69yNzk^rJ^GE!I?aEvVy%m2cn=RWp;&970D$3e5X<7v=hx%=rVt?BJ!slw)njHgH;b>&(fJ%O zv#+tve+S2Lff1upu!^3{F(LY{kXCcn zX?TS@rp%~>GVkFF*RCQ39F8`eHL!5pGHCFW#NHJt#UXl@t44H_#?Z5e^ActXhOR;x zeL4=G@~N17u{tAnn^F_LCXXZyN)VQmGLh8k2}=-C)#^vx!7_tpB8vp#Nqwt4JkDnaYeoi6C<1Q$@7u`PQ;F$nFhxU<(iiE&P+5+`9ACgInQ7<0`HjPR^|}5QpK!8nhFWhUf!k`Zy)HhXAuF=5 zeaxu|=24sP##B8BgMrH&%c#@hLoU%Me{I)DZV$wkoNK_0;U$D}{RLoJXw)1f^r9HWLu}e1M%?pADn*^jIv0ZOvIb$FiH{P zIc#QNN5Eu$w#PUK(?)M4bse8U)2!c_Q%uxwpz7;CkV;~ji*}U=!;B)#76pIj)<5Eu`smf<-|=xMcS0tE!V+kxpCvTHzn zlr8ZCR#5J6xKa9~Dr!F>aHM*A4o4Ju%r!wZ2@Tbs5Qii)hiBl7g;!GGH834>@^YW_ z3k;80K~$;AF&~^zB$6}@v%)5qG}4p^IRkJBif*gmxjtkuH}fTCMunH>NrVICSD2u% z14yLmqC77?8<}?T^nJc8dyMHaw&}@v-|tR?f9;uH-R>SyK3@@q&)NCkBy_mBx;cLe z;)z%qS=oQGIsVQs`fsJY3AKO1;F0RTsXzVN6_p}W0&OEb%9gY{)Fgw213PKQifFam zNAwZ>f&}_4kcD=GI-fqZar_$Asl>6p923)B4zswnTF28@a=SYHzQzr?1UR!XA5DCl ztnJV${4{Nqpmtw$iKcACyRJri>U0$`VT2(ufH>K0v}$kGp<5H8)N`4Qx5;qjhbEfl z6%p)X+9+q@H3nw? z)IF}BDWF-v%c%3FB=Nq$ksgLaG=#gn4aZS%+mX`_@&p&*2YlA5^ZYJ)DKr7hw{cuj zM?6io=HI&7j`c{;Su-+wbo|RgArg&wiq(QWAF;X!>2{01s+( zFAU}bK9gn6%Fs4Hd~fYz8$#k$}1MRlN-q?zVWjd?Y?ls=0bo#G;#4zW{;{ zg`>B~x|q{rl_#tYHT7@(f9A)7M|orYid%^sgT)v!l)5qU*&2Rj6wY-%1USMRquc** z#PWDVt&V6PqJf2?OWP!cVsN{bk7?iH$*Sp5H?O ztdQC3g`D})auLaPRQD>ABuzG3B{2W=2alU*}{PzeV|34}Ck5_0y(?S(j z4fWmJysx+3($OgGDPpl~XveBT$UkGyYDQJsn?v@XL#($7YTjU0X zIeb<5Vc&vUnSGe}iVLn!ac><@Q##>?JTx863w~My-~!iCSToV8!qEqx`{Gpoh7xN- zIn2jv1hJPNR+je-ZL|G0O(?aQIw01(LPuj^2DLP8uuVhPLNBE0gU4z1HI6GTEH+5< zC${`ar61dPYYDlH*rp_Lj_$1Wi*3WV$@3))wsa>FY&k%GCcK6D=)Dt;+#D1QWdk+Q zgq|-a@}I&@erOV+owK+Q?Tz4q@>tPcpuIK?Wo@B#7`FHNv3jkRxdB{!FqT6Ut{MC3 zl_A5K^Y1jPt8CQU=X$x=Zfinx%G?^ko8+knW053J#;-Uums&D%9BeO9=TbfGb!DKb zH6!c{H+iU;UUmHD2SNkrFwzZSE78sfuf`ftE5;gSdCn2T4>8!cOLz&#E0pEwqCNT~ z%S+hdKgoO7wTQGd`MQ6)a zB872Q)XAGDZTB)$TfumQ-v<3ETLlL-*>%d`V88WJKd9C2P;a!)^qjA?+1Tj3*u&XX zMW4Y)muSXe+|&^wycqd|+f&oB7J&V7{VjOtH52}ouaQ@>XIxeFEV3p3%^tUxWo&)| zijG!sV4Lw6A2)&?#Ek$XS^YYnSyq0 z?m~!%Jth03q()OWwL8fRz+z7_<}5i4)FGIk$U{nDpQD0D)}%C-pwgtNx@xNn!$<$U z6Ff7Rj6O^Jiw9-F#IX`mVz0$YjX?x+>OfIL^PGa>^1csUK&u<=&-U2vI#dxwrt3_i zV?89rE-H9tWq+hfV0J-vx0N!~4;oE|y#NVW9yC;)7zi8BN3q?uBAaMesiS9&jtH%F zP6~n}m}Ra{Q}&y|3T?G)1MLZ5x|;GYl8kM+k=!TSxQ)YA^qh8|@&TA^80LJIv*b~8ox8G!H{`$0N<)?M`+7bcPgw@+SGuF;2Ru|L+ep>t|#>48_EkF2a{~bRG-94Aqfr~g4 zem8Q!wh(>C7=721a<)D%tqXoM5j%FzA?{X}7q48OMn;uyGS;1;TolzZzmEc4e5nzE zK|Ez zHp85S{vjUjgSFTjYEH_A=U~tn=^U!LshP{Y7^f1-$(-&? z7^E>*P=^)XU!$p~{x=aJ0#Y67H!yArn{FQyZa&z}BQ@$26dVb}zIp-NEycXn2R%Ng z%^$Y^GVA*^&AWg}160rc7I((xLgY!qEl96L!)vVj(_WgIJ(wg9v^Hj;uL7 zHYP^p$P{iN+su}kDBh&xV*1sE?~j@s1V0U(Ew>!g*`fVGb@`)?X?b6ThTG9^D%rQ$ z%tIyez7q%o``V2^@y+J;uIeh>RvZuS8+8UceIze$+0$)R;f(muS&Wy{r1-veG+&jC zdZ3*=fXv$54Am6wzj&8Q>;yj$TVJZMJavL>JwZ!xr#e((@C$6O@i_|ZwKVyIWj+!J zoq$v$+46%CSanUKiIiSzL>Zq_)SV$VKWJ$0!;3)Cf>=Hi<>IW-D~4usCe)`=C($OT z__9jb3>7V|N>$yJ-Z7oP#r56AbQjb2$lei+e+nmua09F6i{&YEr-8Zbx8xvEmlN=Y zm_GV&T^~kZ88j(9Dohai=@^&4tTE|uSGB1}svB1T9v6`0;M)Tw@CC)gKWkMf!0u*9 ztL_rC#pb0U%)o28u3JVew$%;3Yxu?s(MrTWbF(XNiIhF_2R(gR_&xNP)W+3VEm4TF zY@u%WvK&C=2<=6EeJDZiHv|b$l_RE}b1m$C6g|$=Ru% zrfQLa|7#WYBEP0mV6HrNfn!^tQc6KDxiHBGRv zxvD4FeXvffZPvk=Yaljm*D;_^K z%mp+ps#!8Cns``zOzkybPQE{|KIlpuyW~YNWI;{z4p611&pVJ&EV9jNZo%~Wg!DI^ z_v5@n<~h*ssHw~c_e)M5HSJ$&GfRq-%R`Gx4~5G$5nSSG)L77d_O7lXQO-VV;=EDL zH5>WbhFV`YlRLnBwOhK(R4?SKR9K{Q5R0!6nhhzrXEZ}rZ@)Bs>k7Z{uqHpBf$uRs zV+6!^CB0G%8;HM0X2cw5bLdli;9U!le!yOLEdst3-fjC_`;&fPT>DdeFq}b|0T+LG zHu{<2(J`a&${V;~hfP}Q;cmRcl^*o+ADvA(0XVZ)Tp_J;p%GguXLn(zNxKFt-bI zj6KzE<@p8YUuV(&#}mSknnC|TWc=^xv-qF)Et&mpcA##ca2}Kc zf*A#Ee)4Jo<>KY0g1fUGLwdRz_w@B1G|z!x{=uRl{a*>XC5X&b3QJUZRqGmgKFQKk z>x*4}ACJ(4{VKo-)uB+Q7JSlrC}pa-ES#n|;%VwJDU5J>8G2R5S?Sb{>%vN9iZ+5( zL%=485||h5?DoRrcZyN*#C)HK&PCz=y{xrb%vH9jj5-$E@r3WuUO;tn=7HMvSioMZ z&KiMNK{9P9O}kx7OFyDMXHoPR;M__V$kmjq_Rh`5*v7b~3L;{>%J}5K%zH5TM$35AlFlmBpKS10 z{#Q0y(e!NwH>N|g=oW_}dKCUq@-4yVlhM3!N?1Yd0zh`Jcd zt|0x1rx?s=1B*+z$Um4eO}8J#=UIj4vPuR-2Aa8y4!%GO-~72zQeT{}33QyU77M5% zX(F4jj#8Q5{!Zr8DIVV={DksYKB2t-bx8e_*H^6ikCQ1J3O1&ErhG7Ih9qM`H><3D zHnkAdCS_6=q`XezA+6TxEVk=nYKB*6?I;aq3*>|gL_77 z29TC}R;?>1iVdAtANkT3NmVb8-?nKz1!E)$MJ5d{_kFL8Hzry=2>Zs!oVx~hiK#PZ zy9`L2gM`s;6g!t(FR}y;pEaC1-bnzjeOGWbH`EYae+K(bedgiiYCW?VVzqzmE3meS zVvji3d8vQB&-iC%;ty0$;YN433BCy&mo?Y~0;*mr-d9QGuA-!0MFx^F>SzzcHbIRX z%z^uXtz6v&t-Rd{t!&*9PbfB9Bh}qS9^oBASFx9A`-k9T+#^SghegGgA)65DQ!~lq z3LO51@r%e+$p)o*;)@hoIjxsy2fZ8-tE1M6N)+i5@vn5V)Wh-ovCfCteE;+C z^e-^kuwU1-?Q^;($Nus~_Mx&B zglt^qCK#dVz($tUU)|mGxme_LqM;tsdeC>fxC`}*xo~+oIeOlB&=*G379urpo@zf@ zcbWR6`%SjS9=&&b7=2lIRL!gAtD>7Nub?IgpB%jxE#NDmsb@i|k~Uz$)__TZwf1HoK!Z4 zEvx#ieYm)ILsI+ZuXYlk(|xqu6{5_b$meG^DU84iy16q4JFlQA5pyG5&UY!VK9qw0 z2*wL*3$M`R{L>|D05fA$(ZXVNe$}{bR^%sr#&JelJv5jG-SnPy8Omn8Ew9Fsab1b) zsI9yNaT`7w;te=Vg7**e{%Fs3!F2EtC2BU787ooh|BJSF43aEN*G0>=ZQHhOW}&-m zvx{AJb=kIU+qP|6T{tyo=ES~x?zul^N8E^vl^K!i*ZQ#D=lvewRuH3cKDzQtySzp; zXaTr$smxNHhW2WO3YQifXzTTJ$eENG7p4f;+q7jLq}JrftYnX2T0jb&ytOb{J7Tn^ zLl&7Efqtb>D{=Q;@~tTKWU@rh&{q-@a`X-9zto2H9DP;EmJ<1MqHA$hG1^K|G}^K+ zTBhJf0g^G8Cv59La_2HcO$sf&SMY!tIYdhl2eowYb0NgLI5Iwdq2+7*T8fJe(^WG4tY2vcr{W%Df0z7k)AR zy;&6j5|$cf$*VRdBVL4k<|^1M>4Sop4|H^`oZA7}mH7aN<|R=)s*M@9<7N4r1*&FgI_{K-%RDQH%3$7+9gnbs3`E)qaRn z44@#>AG!NenM^!KpF6GUnx9Dc&8);s5NHu`6$#~I{5h#jF~tdcsUS!0ltm_RuJx+M z+y6o`O`E`qB`caOJ-&f1DeZsP9yRs{cSBy!h+ShxUiQ}VrvO(rm1?x9@vTj|lN`No zK7~c`GF5z%d}PS%3YCQ8KP(1qH*71FEZ&jwyGv|uk(WJ9{7dGNMQlmssU;t6nn8;1 zaZqEb%6i(>2zoD>y9qK{%QY2YWZ%)_QEp!iNr|yXX5ynRJ2#W>!@6tc{;qNS%qT^{ z^8uS-ed>j9TQGcgp4wR5^B zRX-!T9_wAmJfUaB3Sb{igMZ92q|D!Eg~DkOD(SW?PdGI^RFm)9_>o`T#Ka6r)u! z7ZR)&R^B1CYgvR45F3==rWn~OV&gzxrK+QAmwfaQeC_40lNd6bEiAV&cf*AmT6Z2I zd8o+X8Fe%APlD=QCGamGc2&6^)F72!U-S$}UpATFu{A7Q?E@{=5$y z)C+0xV%`ObSP$uDUb^~*V(7@726GEVKwh!8G_Zf7imF&5F*8YM5+&GiR=?)iz;-^Z~L7tA9Xv1z+Zz`eSeXdnlV>)`F$Rxhu} z!zxSpZus!k;>KsES&_LfB~5-h2|~lJJ1WtQ;E|4cYAm)rsYLl4wAYcsG1Q*u39an{mFA#lIv6cPjVPmL%MF5Wz?0=dPBba?I*z!u>w)${ zbV>1hd%^NiB>j){M8>>#&jL=Rrctg97C(^HpvHsU6oz;xDO7Zp%ZwdwpVzWM_J$t| zB-w;JQfb;;e?rW$2ChCecs8m1wxN}8k(NkTy?jP5_Cfv(L~{Pd-xi% z5-2@B-*ju!bRSvA>3wRvOa&42qMLA@Cu|O#pFy>3^lMTEfFA0I>FjsOFf}^`E+YBe ze*-N^^75D;2s=0V^`GR3VuxZKlRb$P4!Tgs*DLU=^@no+4 zTeAvViMCQih-rJy;Q9mMPdlXTazg~Q>ViUzjjrhs<9hhI8avoMx47 zG;m=}!K#$VvM4-tHutu6!sUnkVCj6&;*>U@IQd;fM#f$c+9#WYZneBvD_E)AV)n-Rxz#7LJ^aby$t=u>ER~jlFu2&u*W12G! zs1nK=JkSws@NOjlDvccl4NOf67qn>wEXlK{iUpp7u3>FPSA(++7-~Dw*p7(P`3UT~ zKh$i$EniVA560y(HJNm}#vZi&G+uE??%?SX?DAC+NQgsfqy!@KsXSRs81pVv#`MKk z>qP5x5xQYG*EyiyS)D(?Im>rz;qruqwR(w%$Zmhd6kMZ9rmvm2`z2J+fK6*nE~ zavOibQPHn`)gd8`bFmc28*RG=Y_RS-#bX$_?ajDtBWr zp*`~be6%~{9r%ur%$NI>G3E>B)o#o!W9CT|MB_dvCNWD@Td3}7~vgv_H?Hdcf0ohqg}WwFp7>-XZ=3|`@YOz-7RP?SP4NbV?* z?#JXvfMdTp8+i4Odi$;+hD+(b`*$h};!dMJZQQl7V>E%69(8jGr&=^%A)Q82vczo_ zYv-jFhx-e97~4KJ%O9k~7jMnCe6@f3zu^8qELp1DrxxSBvDwdW0+ZbTs4|u}u($s{ zdH%n-bE?aJGcUeFS!{}xBuedtze#5D2Dg+QmiN%MLvB9sOKA2)b={A>zr0@Z{stjny#VAo7@{??&D)qKodXb( zE&I^{SStvpeQ^ALB81lA17`L=?_~2=8-mn%_KvLd|5REq1;-mcO24M;uni+6J(amm zObQ9U&p%y6ji&ou!g#lD_#R}Y5xNIsI|tHflzAK~Z7*SGAwVZe#0lFRHdC*%puG)S z^UIM=GHq7!z{vzmY#5Dvkzc0mI)R`T(IFM8pDj19RQ4SYDu*}K1lR=UZvc@quKV-^ zDLc7m_-`>{^8Y9dhC`?Mq3(c=id_(6vhpIii<7ofK{|b@1x% zk|u9E-RsLgt`519(xZOFPCLO_qi!~%+TO%q&oa@we>a9vCY{3tP~o(>_sEt{e}K?@ z2>s<&a13Z@CaaF=XlnXQjgDeW;q8B?r1Jqf*#pj$tp&B+!H_Q99Kr`7lNUklF%4Os zY+9ac)kM=E_15*E)-FhpHcl+XD5WQJz`HuHNQ>_H8W>R zjT=RgNMl%{Iq;bxi>nogr&@{AAW0O&dQp*Y3X-G(lX`>YkGzBY*WCXHDnwP-f8{^} z0y_A1bNSCwHvgs5{U;RM)P>X{6-V`R4ZvCZTk zTtSwZzD`}|xro=*#jVN3x^6!*X)5UnpVRjI;*5Y3a03N~WDGyw{~>|(>1Up*+;d~9 zNTS<6^!vg}{6M^)`3D=CZIxcLgRuUUKP*`uu**VF`dTD#>gvkM}Pr(wb_` zLJolWWOH!^MIWENZ+As$VH@+e;PpXVisOV;8TD^<9GiF$EXEA7$KWBQm78Dr5`sKu zj`LUd5|P2!SU50Ge@$HLRPj;L6%S&gl^RGfpqMIm?h1~(i_#`2AS=b-c^2o#|y6CcQ zKfwF_1$Jq{p)>1PzWvU?n@B88)>hSlQUkAGAZR;HNHb;3joinHFyu%l7Sb5~4hrgK zvjmK!R4%swZL0EJYD`c5zEWEtEd^MRNVxaeX{|M$DFB$AOrjW^+)33Oztj7_kdRS6 z-JF(*Xsj&tTEa48eZ~&b4$}o^Rl>${k;t7^hl=gvp%U>fE8vKa#G(0lp-$-jEDEDA z4fNko%XSTBTz4RpMcq`jp9A5n&}N{;Ce^y#6Oe({8_jI<#<# z#TL-JE+CFu93$#qmUD=|Ad()T27Z?aU3~Wj3f-hPY8~q>>Irm}fC&zHVPb-#Hm;p2 zwf<^>Y0$2hDwAI(nls6wKchz?A09Z9>Ok_U$ehh(PH{=c)}kX43U*s?fHzwjmxt6R zC8ZY$XB8gD4O?~Aj{uU-@Ogc>KnJ16`n7tQTT?rm70ieMABOH@H()TpYo0>u*#YV~ z;_ny`NcN=T0HP=1?$)iSW&UGLvDn+(x5)DoTivu;=$p4!WC1yu2O89m4~BRP8DcnF z${=mSVwMO;^&q$F1#VL{Z2YX2(%xRonTng_r1$D*lLpc+as=?SL+_P5VI#y3^O#@X zwwps|U&0v`-o}QNF-7$Nf+CO~PEh8>kDyQWb1f>QOc_|**MeIb;S0fzCLZ?v= z$g`kXwLWwJU+dSm?T`IrIa*sXe*e&0-`FE%_sCLEcm532QH&K2?0iOf>XIrR9L!L$ zBbq@$#xY!5Z@ffn;At!vU0}L}mR;ZZDVJnu*p|tFX<}(^zVrZGi)N#vb(xq*@!&+R zS2&OE%x<`mv6A%&JxkpAo*7zFAhHXGWvO)XmDR++^S+$T>D5 z4?~f*&cX>hzR|ak9%OuvrrAo6h=MUDf;$N-W+;%290oU_){;^#N849CeJ*;+dwxx$ zTNmP#!K@p88tEJ6MzH0ByU8#&iBI*zE2(NJn{E8)P1<^APALKjZ{9+>4KfF=JVlQv zno*gXE}_!Cr|4(V%BU@qFoL3-4ZJ&PES+T1UJJ+gP@e)KD}CZY(Cxi+zM#cKz8vk5 zMmJVG+lxcdpo&=78)Q_$CuJ>O@owY%{7jhO97@=WS=to}0=x)imGkHU!Hu?uLb2J& zuOgTIWtEw@`865t{Q6+HVyjoFC?_V2FdhfP-3!(XeKVdE6c6O{IzC`q=;=s!5i&gc z)+Xt_HT1;dyHw~O9vkBi;auQ8=*Oh{E5i!au-bK5q=Hg*Nwc^Q8e@a$tb(I)RJaUW$7U5oI$Wfg@@sw9PhoKji7P% zsq@Viej(t!6yxL@fr5>T%gOXvIHh!$?(I2#h`c_&vu9Q0#5_Jq>Xw!(ZAPgp)y7X{ zNZImh>bfQMsK4mk{1kTBMVVyXOP-b{LyMpgiF3GYPqQLPTHQ>J*zKwy7Iwcggiw1b zS%oOK4!%@?8>rn({p~3;#}qYg0*=oIkWi~XmLF#{kJgmu>z=x2uF~Qh%YIK1&i;j# zKu+oStBRF=(2h8hwnYW+E+zLsNKG5eAyKfa-WX6+6L8sJRT`R!*-s2dRNy+{c!Q!_ zc)!;{7F`+#y6S(nQ%DSpUW@t!;#W{E1vXMwm1Z;CU2W}nQ`dnP$E!(7Okr#b9nx9< z+X`H5S6>~4KD!e}QI18H+tndziq?^S&mM{{sz&O>6p);vVrERPJp3q9l8E$B>g}qJ zO+CXX!`WKJcp;N!ljK~aR(?}v!WX3(pwIgEvI8Q|(9Eu&e}$Fi+PvA}2GHS(T|F8V z8bg$ZzaeKA9_(VDpR5xSx8||q@5Q(@#xfj3JVY94W%-5AjE`WZeVeL;{diW(yhkzSP9VH3+t*#FntSZMyu?^ z#LN;HYcm?FvL@sH17s$ZN$~GQdkIm6Ut3lWls!o|OZH9XBL%VgFe#Npt?+iVQntft z>Ee+NaWe=!c2m4CzQIi$!i3h^N3u`ZXSbV_T^scLpG=WdcbcF+O;X61chuZQQ4QwS zQ;-2dwL%hD@$pI2LGxE2lX4xTk-i27$3R{1;emZr=l}%4HMI%D54N&f&=0N z0%_C&$9x~VH5BBbk_n)gzdZ%YQixY@;J=Tqh_lI7F5yWpDdbo1EfDEhI}9>PL9IAD z_({CY)*o;{LZ1(`d8(&9g}qO+jE=pLh=**M?TGevJ_gX!hWGaorQ*5T(nfH?gj0v4 z2-L2rdoZx7WwjHaX__Y)R3ppto z6-g|+$iJJ&6Pu}z2B{5w*e9+fJ-v|T)sx?TkVQ*>A-lH<$hiy9K3C$_U&7pjBvvCH zzJU}9wJsc5gZKe*yJ(fF-nl8*UJ21W+wrCrHdT>cb-%m+WrRAi3gM!XFsj~uGmg>( z6AZ5#UrD_S;=6{ndPvK7hIRF=^svjPsWz%EXH6m*9#wjli6>@ZSE4fSB>eUpNO%(sCwt3jP zDt30rY|jHQ{h#GK6ec%$N4g~=>(e}sd`f=598@Dtw)6e+`*rS%zVRYVUwd9>uC#?u zS1~k_&ok}es~pgUe^4AYJZTf0j_y7li(r0#q&sonE~)b1A!m6m=Tl8CNN76_EAQ_R zUC$MEcyr{n0O;}4nmj1l9Y+fzQ>A^KAe0p9q(y`M8yWRsD0yWLyN94_ITSj>wsB_h zLNBpF8bQkYuCgcoqKQl|E4yp=euV;HkdOtHV9IJ*TW#orH-!4(-;HldS}Daa(}H$= zKazw&Q;1VWF0XKvZ@Ai~bx9?^UiM@Qc$A|l%@i$1_%rL@nbR`FFlz>lgUntIB^Svu2~PpV4RiU zQCMoU^4i*d6@KnzlVh=yvyd?FUa2zli6{E7*fxU3wnF&6ms(`^wa7W%+^Oy0E1(NO zv7O1X7_IA%7mNfFYB<;|8J3aSEN}Xoqy-WFOdm$h9h?xX&hIf+Ab!6kO5hV}@RK(- zp*>s|6Zq`8aeo$=y%LbrG3^)#YATB1M5ABErG;@~SRIIrA3*$sbMFtaBFvG#A?8xd zTPXX1tu*9D@8|^iGRUsAXyRNG!VSEarT#>-bs;bydLZxEbiT?Jwm{|D4atU!+$?)hd3;3O+nh+HWq2`^Pq`UmW<0 z$~r&XXz?}W9-)^SkBA~%3P%B5_==Rje_@{zd7=!#aw%A>$-pWULQ6*RAm`IT?g-QD zBdOoSfViUqWo4)m7Mq?KO*%Z(n#Ktz$j%Ovhi^{C>4^{y7M0imOtZttp?e91ZYWR1Z{NB4>g5}E5v5%+%i|u1VdUA93Z7U; zl_TDvznOTH$FG$c$$-!gK~iJX1}3K|BJzuu7Mdy7gVE zErCHb?fxf6dTWQ=!JQQw*MfDM0KX4rjzOF9pk3Z!@PT;6i_)MCn>y=`t15ym>ApSg zQDXJZuzn(+*;KWI9V?tpzcn z?W_2(pFT=m*#tfAK{8R-HABtf;R z?us`^ANsV7ml-H4Ti(ep5#~H1Hudr!0GE{y9P{>nsl2&FvRh*Nx?0LRZ3Dafv;-q( z6}3ivyI_B3G=Q8<4<9(Odyq)8VO~7JeuOiZ&x5%CmG9dgiPU|4;{CwZY*}nhT6_+n z#yLq6X+RRgB`L-zL~q1uZP>IRw?PERug7aFo6hpA>3i`Gg%>^{lfU3w=-(2>mx5JE zM3}D&)8uX~h$SY8qpPPa49-0^*U9JaN~D)Y(^QU8pv{@fdejSZs{`s>!*f$10I3A= z(~qrE0-W^?4b&_zG;G-maqxpy&`XcMZjN#tOBvI9%ulVpX>-uEUbH59X%3L3qV&=s zyjnaP!e>gTJYblRf!)YF9bwLwrT}Cv%_ZAH^@eqGdYj0lW!qwSqC3;I%!AphJOUeq zV1aA7*{jS^aV z7%O*VWv4JsVx_zz6?$JXN{35etW)8#8G@q021#@7%UZY+H)U$ZF?E=&tg;6kIrX0% z3pK;=Mp1VxNu^i`vcwCh(k)}=J_f;jO=1*PggIN;-=9*szd>V-KhV>-OT$qKqf5Q@ zLe|pgW5pekhUS_)WmDSfl5~65Z2MhWD+8TxTgy^I+?nUdx_@3mF$#`dJ+&#@wj|zW z(>V8}*D~_QYYf6(%^u&pMFA3z2oB+oXGr_v33FsxSnVE&PSrV{p_*;fO>n#3rzMBn z@3)w3uQMm{(fN!5+l4*LVXg+(q3o`+CV9!}+8J6D^Tk(SKh}{3#vKWt$7y_Qyz+R6 zHaV#(>3#fFXe6NEZseXsgU2V>^2{#`W^ZyQGhQLHj@;2+!_*9%RKjeu0liIl^7ZQT zI8BEZdh0L^v6JHIYnB#H={l>2wsV8ewlsEjP!aVx?xfc+wXU*1Vr0M=4uQjxGUGAH z)@j1;_;Vt!hvdHYsnBI*AN(%1E?wM6>YdT5bJZqAKITH(K^ zKjfC^==a9WnYiHv_Fxx4SUE0vJDaizPygOGyklea>PolO6mK`YYeV_!+R-4C-BA2; z%4!42vwjcl6&ION`C=?UuH2K>@gfz;Z1#4;Hk@5zy)2Aw4oJ3cdMue}5>Q_Qm^-XP z)ELoTv=FnebL7F>q|XeU+^=vHE2M|C*<3Cdo##~A%v<2D!>vt0VB2Ii#8=8{@9CEp zoF`!LF7l|Bg3{d9&roG^OUU*YPvh*~OT6@@yKB};IK}B{hLAl&d(3=&xZ8q4%ib`? zGLPLj?{H`9Ru6vZ_!B;8l$aHIFyv*apS8AlFqCG=rcWQ}-u_!cdgblr3C6bqjQ?8! zrt=@Q;bn}i{@INbHa4*T&O~)0`*#i4zyA0?WW2_INx_2iXk}v~e!GcR0wU@ba4kED zF~l{cz?2D-FAM0B^y)U%-ysFuiPK8HddyJ37sRr>ZY8n1SCiP3m?Y*Xc%6>YS+}{J zrc&pBba#IM#SDe^1bCVAH_mkiU&`bDnjXh2Kq=;5h5{`XT5S~FPPYBIG0Kk(7ci6j z!EHqm}QeW^{+S9W1+R)`OgmCeme5E3onH$joHFhf@3q^Fo@ zq!S=roN{7PHX)C-N`-=r({jq2Sn;r~z9|D5Z+g*Q>8GT)nf2Ur zR$^8kG4N)cjkfWWXX;~)gtT^dovchMS2R&>KCmSClWm2R+aFfAU)WF$l+vw7z46Cj zDp68-?F$Gr%ZVBa{nUO%EC$d3Syd5fqa001#5oZ7DH*-zB1X*n9fkbBcH!*17(KM{kp!$X6@yL;*rVr zPc(Deqj5n*U>ee_!c!JEO+Gt=OXm!#RQm?bAv^H2*X5?0VD^))sl4RiFYe2Gk6CGP zCyVyScI`bx-b};@A4Rs40u&lDT`v7Koj2b3vE@AI5?^A*r}&j>Qf^4vl!k-*Y$0an z^4{RTcF$fK4IpRN6CheOLbJ|3{i7F1Tqm8-`;msZTv`G)SH@qbXp9k$+uxfcMqs1= z&S)RKkKTvROLFc! zn6|B;PfFUiTquPnTaZ7>8(Wm&PbNT6lLN^#lW0cLxJ9A6kwRqd%hq)jXKEUI%JbTd zuuEn(H#|mL6TbKe%oSk=$@cS4J(?43+oN^xjICSf6{CH8{+s=v{DjD?_%~ZI`8$M5 z`~RQi_|LP0MomqpZ=>zcDPZf!lTJ=hM>wv)Xi+M^896Ehzd(;z1W6*uV_b8H2NA;z-E@>1 z={%tr6wBKl&P%p2LQhVzne|sMTkBCWe-oKzaAiJKd}n|j zwBG5ixbJX-TdXon#Hv;8gov2nO zRJK-U!gV6!huP~(TSOUj1)qN(TNe(|l>f}VptRS!7SxAJhfo#NuQSFGMWZTA`iXWS z93eNMe+GnBtFJKH{E(4@z@%|`CgV!I67s>a19?J)J;>igZmcfVPi##26BmJ1?Bj?S z4Nq9458s5V@H08?L3YO-4>dO5RnO+0O%jEh8F(_sduZYt&X#bb)5y+ImIK%i>uY5R z4p`wFsx0!fa?UwIBuiViU6bKd zlkG%2@I+j*3Q3Xl_J3qqX`C=0l!iz2+3bT0U*m%-sBZ|gh&Wb>GLq!40oYa4&>$G3 z^^;FioX3S%MdA#qY{0>_<`y-WpyLm7yZdTNjvNY;#Gi+qWp%A~7n+?3Z%b@ckH^Xk zG~}1AAh~yS+1Z2-WLj`SBCO!{og}vQSZ17s0M?lU4HcCR^#Q!W6C&+iGdfa-J5gIc z{Rb5WVNEKzI$XUYFptxiO&4;WA``H)J1CZS(_GFej;^D#V&%ltG>~*>X!I0}7~;sX zRJ=yQAMpE3ibb$Q(ss~f#k1Lzhfx%T9e)ZEqO!egV+eY62l%pI3%1EF>CTXdxw`}& z5nu%kMs?m)LUbN74smPH#--yhfHtdY=y7W%$=C7c_OmL5V6}Vm+&alI!DYMpuohyi zE4~5~AGdQ{eMIg^RSK$3EB*!s|1p;F9!eryc|w+dEaz{0C3Q_|rN2dnXkmZbC^!lt zW(hUf2O1ypNg~L0c(@>EzzJej1a9?Dv_IigWB%#=$9loadxrw)ipZwyS2n*X^zEI;iH!)$TjoF*)1*A;(9Ci&$|EGV( zOo)-4^woQCSSDKM6C)RP?@WoY7fY5aOlCvOLK{S09vG>Ke+1Iw$RA2a*4y87e@>^o z{K>NByx$zh2*Ud=BMZTOMX=BxrURkT#UeqOWMCN|B~QmFrOb z?lIEn1!22{mB95gmgXVr5j(GUI|A;pm$!|GgPQV6c$ww1umt1D2&JS;5D&RY=|%1- zX1>JSv;QBAhJT#uW;oOmWPdXnO#Wl5_y1QZ^{+izZS&ij1?@8!gud~;EJp(jxfacM zR|P;M)w5t7Bc&?Zv1U8WQjVKF5lg>FF4Gs)0zEyIgE8ya!f@?y?{HR` z46ChP1g3F<$wwhA2<&Z!P!bL_&;uQSO#$$$dlfNFb;Pql7yE3kEd9FD^_{#FYSnKC z_j2y7qJjEho^gKIS{+D->iT4DK6}?%d+0#I7-k|jh0w1y#^(*m zGCx@aX1k|>#~EX+Wl^oQ%N%`X)X|T$&(7PgWkqDe5m)9lIw+OXWMy zKR&}^Wg9lX$gH>S2$MwlaC-14q}VIHpB~Vbzl|1W2a!nfY?+j0qnxDCNWEP}=B_}X@%LBb>>k{$4d;z@7qPQADmQg&^O089 zw717C@5#y|rZD1Oi^v=3oU4=>S#_~*&NIK^>GcW!Tlk8?8&-g%fqVFn7(0|`i-hA_ z;33T@+lP1POo}*~?15e{oCSVLp+=OdE?Ggj5(++9JZrYYUvbpq3FaZ3g8s!B8VfGm zVZA(?8OpC5LYU{~Xa?(;XK0An^1>S=C$e^E<_Z^YNb{a;h&S= zMQPj;L>Q@pgCgA=r1cLbdeY6+d?iMLf2+osm*i;MK>}LjY_hbO!j$~Lpt^Z4l zGv=oHqPSgCIs0#fEGRwvLlIYjAV=2R%=utiE+>rvrL@4x@U41yL#-)L9c~W3P-2fM zp}=hYS$u`~Af`FXTi&cXm|tIBYKl{Q&kCJiB-h7*$ExbV6uXakcQL!sH;!o+`6@_j zjx4LyE2v#t(IOw>I``EBZ~ArNy|3?`M0}AlHs68L=25y2;gE&9&MkgANOcdgmJ|d4 zX!e<^b9jPtpYDG%0LT}kaRvq48}wk8#!Gex)izQ*xN^`}-Sy&#wvU1l-)mH6GuoieK{eyT9NiBUT@DS>dchnsi{jf3*8?+ckq+ z0$`)FU;}2B(aRq#!DMzfon0(_VwsAJTH)_^`|_&53mp&6gr%nyG|LJdEk3uw2Y_Hg zAdw15LePsoGtIzo(Vw1Vzbcq$t(WYaqo}fI)6uHF#8v7uB~vGc(yA+kXtjbq!82;{ zB-IiWzQAP#Z$&t4+Fg}2u)avO*&`-b42c3NVe%VS6jO&a`BR?EA8j^n>t>im6-Ab# z-uay#1?RR1bGw-7mmfi7!|ep1)S+&Kk{f$~6YuA6jJ}{OXnU_6NHPW!)7G~B1Wgfd{qfyyv(%USXt!>?n zUo})A*Sa&epukBxrC^GeG%yhQwrnpLMn0r3y8gB)I&c4OAl2G0#e8GuH{(tFu>)t8 z9MJbe!4|7~47b%*Bq`R)D}4|NZMoKNgpZcNXdSW(ZkH!}mFxHAO0P@Vc>F#9rDntl zc;3s@p45M9^d95`s(-|uo#Z6UTV)Du&|hW6mcN zjV?!dmL@#TmW~)DpW?|=?E%hDOU@`}FKDaNsH+mUs0#9OKE18mhd8wxBRtt7>|7X_ z(yOy`Vz$(EK~}M#_u)p4(8DNIp1LO2CHCIEi+{SK_Rag)5?Ip7xI=1Q4!UwReRC~h z;a?UE-s?jqJ(mg>wEB~E7_?m0`!@HB&eo{wEWOYswF=XPtp9@M`#-J7ho=ec`#2qm8vB@ew@OusLlG#0h@Tb zJ7H}dpxQ>OdErT{G5+`W;#9F@>fHB`|6}--|7Sz5YGiI=>|$+V{C|zt{wA}_fPE*R z{CJ(eWNdM}mWir&J^by@MYKXWVjP}Atmo%kcx%nT_d5h--c}bb;HR)UKg^lu_5Jw= zXb)U*Amxt>b2HAN!mXDCuLJ2PX}MXXatuvJQ{{T7fI6_-OwU90u#PrgBTcr$=zA=@ zW}?2;wmZ3oy~%sWNd=v6C)lEM2nSyCY^E>CI(UWena2A3h!$<%x^iVM9tVJzhF~>o zY!1w4NW6F<7Nf}MMw^|v&yO^K8Xs}%Muazj^lZe%%h6CD7Q9EIbm1(a+xa(L@NXDp z+{N#*`s;h`@c%~-P~Ohg!r9J|Owz@`(fFTLMW))g;SHZ~K+34?#Jv4E|KC?o|yUHMpA5DX)8e zpKYh3`)fo(;7G%0gFK8Icmco+d~xnFUa={(GzXpzqSrjh8VATSdQ-Kav-P~&h94xb zTRAgR@B+^28Ah|!TmD!Y(>oRk96;7VOa?o69I}0<>GEZR6MudFIA}ToE?*LXDi}+Y zEi#;V$(#jyXiQRq_7A{uKRlJ}2p+sq>e3z^Z z<)mkoOU-huHwFC)`lFWC6=rvEM)DTh#h`+b=hN_~He7t_-RBYJI`^t;QgB2|!5#>M zl~Qa1@gr-=22XsZbIN_{DvjL)c1b*-nd3x#aWISuS%vEU);d4oGyklE;gu?e@ng z2bx3Ew}*Ck;p_|!=!MeUEG}&TLXv*2(xtf(sY)1ykF>8Z{$O3Rue@)!q6QCvTV&Fl zL-yr|o=Ns(DlEyqK`D1QG6$0al%qxQF>O(|N%0Cy0ACa=^bYW%d4^VHnS&{Y$R*>Z zpRQ59%3Jj+5ysEvnqlk0Mp;TIR2+>b!-W5R!_hK#^o~IR0^+6lPszpqS}*@xDV^Go zYIx#UpQgt!kdo3QC&a=ka^|CchfI=Us)ODpH$daWlaPA;-n zijgI@km3*Nqj;{Ah!ER+6CRF2$rK-Zh1$;o+fq%zu&Ke)kv^(f^yk-t&F?m0V*`1I z)@v#*Itb~)*~if@=20|W?Vq}*8Mz;(?NXBNo@b3s6|LFVob<9qefYL&u*L%-wJkWs zQQX53@U_Ym96duI`ClqUxa=TTY8|on@neujC9A4P69W`Ee~j4`tTL9_tcE&mGL0H*cr5 zmNUd!NC$p~HEP5E;_!dl5@#K8OR`*~FxO}}rd{Jjsdi0yz1&UdS(x)BP|%ntBf?)) zWWMbbh0QnMbfx%<;8cOxPO=>UcR|5KEDsOY(4@40vNCXhsc=83M1fJJH2H_D8BS8C zm@z%p7MT$sPouUH+9?{l0JOaAJV|{TIUnqr=s+?dm04Tjn#w;}5(<+5&*))5g?%*- zaxWQKrk@eYh|m~IfU0THkF-`M?^b2QYcw|JowYk?c##;!g_4kXmMJ<3M;*SJJ2~;L zx}*iJOF5e!opNBUX(05dc~4dN23)CsVMJs1!!L7r1J0N7cHsl|cG6^WYyy(105Z-# zZhPw>PpT#HWpYXMq}LRn_i$|(C{<4~TGRy|t<;t7N1Ccx0S;lj6IP-E6>R{cM7#mp zSGmB?t00(C(pb-CvmDdarO!E$qP$f@hIU!djHcxTxjKUlAChF>lR_4+PQ^n?U=?*@ zGtwc>VeCY?Gf2H6y~~rh8jO%f7NYXR(TgrUg&>Y~X_k`vi(*zX?j8W(!IX672q#m& zQ-|SN$8(7OJx##OG|(!c!?n219p5`sHLu05O3d37DXC*NfK98f8w#7y5RrnmS}SkX z!n%PJ-B`HR*)nj^me98*D!sW_Hb~2noKDpS<_PJ`(jo(S?0Lwnxktl(Y&j>dEh>pX zAbpg;C5V<=6yNZ<)mF62(!1>Gz^_pf=niUz$^u!`|LL|R@lnCM!i&S3uS_c#iDTHm zH$>y(5*O>;r@v9=>R5dy{_}9*9q!Y=HSNc4)DkfhW@PPNNaL(c-w4| zEZx!fyY)2-#(h>jF8bqfOLSLv14OX5W;)+Mr9;T9Ls%G1dP*oZ?#JCddABI1Hw!Tf zs`J8rnAbFDT%yj~OSH8Hoz+_({^~?S;%Ro!7z_#HaLeBnh~qtq_f?0fnEo9V*3VE- zRc!KRY1j~M#+)h@j`9~0o4W##uVfiKmlf$E0|7|(=@K4=d2Tf7`$q;n zZmoQcbK0oXi_?8*p{r`In6E@t7Kl=-jnoN z{ntyZ`k$NXSe~py&(QQtkZB?=Hr{eMDU9rLkb{_g#4Nk$=XVb(16g4lGeEN7)cNle zkw3!f{FGQBgz?Ag54fHZRfCxm;J(gG5|kylyY|`xNNL#fXi$-FTVwjO@Dmz{!XPa( z;+J&7O4+YK+@d5Q>b#;srr}q-$W6gIUbV+}TfrY`XJf7}5j^nyDnK}o(YX3|aTJ#c z86oQDgJ0@Ai5h)44$8_h;A^_b$Mq+8`vaoFelpSvD`fL4= z6Kze2h8L%w7FVqeTR~$L!#Az>W>`<$DyQqT8+E~#DV9+^m(LSuv%w&bDH|TjvM`!v ztF$`cBXJNGG=fP_g;vSu%h=~$3rP{qkr3u8hk|_O zJ?*omCBd;rSVKK;{q%Qw^+KEjx=uP)o^q9rIK9xgo^X|pG~Ii|^he$54;^FQc@jg> zHR^PhwctG@=eG=FWc$(>r@tBG0+4!V)?6md)5?87Y6gcI2I~6CJELxueZqbf3dA-qB~6rAz+$0nYgv(kfrOQ!TFYWV2bi;g z(h^LwJmHLB2?w6E0cU}ZKyEAB&XD;*w10k1L;8v)0zBEXKosSZ z;EexffNPt+0iuz?v-B%f66=kLC@YBt+Zme=ogtm@{4RX@CBdEMx4c{V^?Y>|=8dW6 z@o+|zi$>Yy+!6(L0V4@o#KRfJOAE!l+0P;?HE zl*CPcw($XvJ21fikpJ=&ey*M|K_pNi&rW`MFiq$`N%j;vt4I&Hrym|Ej4WL%;Feiz zitzf`J_7mAuWvtkKI`@o@1%%?eb>xP{>XgwF?ja+bZ6J8C0i#rNm1uno2s03UGe7D zG~0Rk=GNfUSAf31-tc$@?kP|6yp4t-!MN!yS2atPPZ&TqO!o~OQ9rvC4--S9i~yOOn3__l7eU3zPF_ zDvRzXb-7kp{uzXE)+`Smt!Mu1FckJYBXpFktca>LxMFSmj5{l|!&V#Dih>AmqQn5L z+FZHX+_{{H-Oc?YNBqoREYhvr%Y$|~v1{fjft)%4W0JQNH}`C%y;(BjcYcx2ugsZe zvIkJ;4>1wJ_!&mB2T14-8IkVTnd=lW&2kQR8zZR&tZ1Ln-I}d~|3%t6MOOl5>)NT< zwr$(CZLQd@*cIEhZKq<}w(V3>@k#IA`~0VSod2T78Dp*6b+N`b`Of)F|Jb#ZeC65M zv3%XqW#gY#YPcZuXq9#>>Ra6EdLZ+snn?xy$L(Z%9tmh9cFi$U&MkOYjaQ>-wi4pW zXjsMS1ulQCB%*XpFg-?D#0z>cgOQEtqS%&&%9Vnk2PC$GS9>)vGBFG5%ax+0qL3$9 zhb?|x+haYVME*e+X}ta@ct=@3_#0n!DdFXWeMM)puCvUjvVtA7HFlHbH3otbj!Y4HcioqZQSaJH3s3DCL8e>z8Z7>L5|5Y zJNPj6QzD}k>xVH#hC7BVn``mnLHkR5#+p8DviwAd(J;f-nk5|?yxqw+!F=3i)Rf!= zt`?CV-kRb!k+I%FsHLx4bNI;*gY8V!Qb0(;LO;6L~|iXbVF8 zm5j+7%G!@#w-$0&_Lk?8oXrS-zu@tm%>`8<{#;d0G>3n%Q}>{@~M(G5XZJ9z(afE$+xJ4ej#VGkMY9s8* z)jf(Q-uTh5$dTh-3mxm(VG(NpZ*yAvs&C3YtY;!L)9?EHL||y=AtbZM;?IM@{>@99 z;pq!Tt?#GKdzVSuOKP?6C&hc0H|M)XmG7t9`;k~3o1aRIddg$j3#+HwGZ2cG?2ist zxSFFTex;tfXYRK|r>dWKsw^h%=T&Y8FAh8%yK$Krws>M&(dxF!2&J{rcbl~SGba2W z0gJ1GR+DvCFiL0QA(MhRlY{H?k$23YT^xI6Fsu3Kj9&&oIOvK<_WHf%z`39P;3x6? zg8abLqN$0!l_db~dTO+ZR30jlI0GVL9*d3K@oz#=Y%$J+H+>)`L}b z;qfCOXB>&zK&TWuqYG0=B$~I}XzG|%N z>|U~P|JvOU?HK-+Un$+fS}xaE*N`64G(d53D&$J$2}WDo7LL)dr7sy_>X;fkP-y?i zHZY?WS;?6lcWAhgl2)V{@|e}?L+e)ZwR}FRQz*BA7gsh#Y1>H)lhq1QYQP<808TtK zQ5~bUA+BW7v-8KgtW0gTh{GvV0%tT>Hq74yRa!=24l8y#-_3fa!`Y-3SGRiLv-OMC z3D>EZF&_e^Zd&>1v!)9jwj% zL`>4C>bFL7$r+Yv-IoiXM}@$vxND-1g5<6~Xi@P$WB58SUHWpxX!u31_t5T{ zbc2fg&iU;U$FY_=<9ccFbNbBjbM*s%IxxlkUN6kTy(lzbJzqmR-=WL+jA8%4lY8xW zf+tUVapH$IWsx?486L~7>)r%AVivtwNAqpRVNdBSRHqls zwmGUECZ3G9O`CA)j(T4j9#s6IYPodJY)*&Iklu8+AnRr@tT>aQP=R`bJp(yGw6)-O)FsX{XL~6~za3?D2Bj&$a^6_u* zS9lPb+x2i5&kll{r08RAutw-EDem$-2wcpD>%2QlQws~#eR_GuN{Qov%@;yHhw8SWa2NT*A>mELWwHz56>ZdF-Z`vqPJ;Cp>f~ zw=*rLxX_?6ppQ~2VYrS%^M6kCH3fFwM9@}lq$=&sq3`uzDPm7H$nCR* zrakA!_;(I|x&>Kg*==yHbqxDSQ;vxpv;M43O>9YEkVvNoVZmD2NZ56KpP8Lz)nmeY zh4jCI_)Za&Iv(c+PcEJkRmV<*^`5qRuC3A+WwZ_+gLTl|Ag9)guwYYPj<0Cn7}&px zh0;qeV3=Fyvu$rLOJI3}1j`c}SlhD3z`rho4TBAVi-iFG)c+P%c`yL** z*CTWsAGhzGbXp+$VaD78Yr^{I*RM??hF@+hxtcndJKAzo8J}kfZ@bL}b zeM`mbZ@f~hE^_mq?%@$u<_iDrD*S7c>#msDU;Dc$>?_FoB z7<{*d5x?m8I4u;)3B?5SrH7Q03SSLnqxlKNCFevDQFc-~<+OfZCv@`lY8Wh?w%(?T z8r}9G?1nN=-@GAFrX@*^Vok@Y7>F9vx^@Xf!H4Hz|B?tKOR)#@hRx5Ww@p6^*u zH`U=)nP)9o;XPC`q_lY`OTblUlFf$A25&MIAG9rRi`UjN%*F<98QeAP8&E&Y;Pgco zzG$ZzYdhJ4oqo!PIpKROw5U!9b;hh)1`E+$is1{JhmAg_s_js=N3_VI z4!I+-!a%!1E7cJXg6RxcZMbNsWKorO;-If#d?d%4=T&9Y?j^06&)nzH%~&#U6W61t z{5m=d4z(`R4zmQ;XhEezWKPN)L6D8)df+CNhRERFox_eT_NlET9bMZ=lIE4)xFEiE zzo+4j2Dwu-+XF)r<&LjtrkxBa@!c*^CeDdxGS65ipkQA4 zi!E;Ur&{MSy7*IpThC&ZusHc={5m1nV|{K|XX@|R>|=<}A>{jYp;h&+Q>x6qi}Scg zxAdFhi)Z{p@Yjs#Lwi}GE9Lbbxt0gx{d(;)#J@gU3j7{P#BZ&C9Q;3p{ma?^pU?K6 z%Kx`2C~9hK?*#Z3IsQl97_<9+$3EFRAf3l&kmeLW01km=gUZ?AM1#hVQrsC&YNUpRW_5pq z?(kuGCV-7F<&F$ml!=bOt4Fg{&YRSYMNRA0z8Xab&km>*{L)@EtKSl%$dYdYgbEJJ zR%+(ye$LFb&caBnUQM}=%Z``TG@0w5a;6bj^G!*qr9L+sxgmf)O>wx(;9!Z38Ix3U z|B*V>Bmu zSMv6gIAA&{*+D>(l(UZ8I78r;J#-15N4W5(6$4-T1NXC{wq~GU*C!~XG}geG zue(I8YmrBZD)SaNjqP)fYUz@8Q?qOjySd%LbVPs{)L%h(@*AH(_V-;OYR-!Rmo_Y{iw|J*qT#BWZ|m^5^8S1wz5e!6hG;c|1w*#2_=Ko_L2gTbBgT&JsUB*|&HzpFAe zb?#7oNWps6C6U;Y^=hfkw0jRTy?C>~u$*bODP=1@`V&yuQe!&&tlZ%7wnF3mFesB(Y``H=3Fv4HHB( z@Ps)dyiH16RyhL37&7BJduN?0?Z7=Xtyp73dm06iMnzhzRe5uTrayLhwOQa+CHR0m z*;li?UlpHo<>@E-hM^KGVa~#&%{wSdjo$RxmhCU#ChTVp z5_Llz8qv=pJ#4a8WMXj|)tOLmv(M0ra^4s9PF#F+F#TQ)vH9mOIM;ZV`TIamqICoi zTE+udlrA;$(@X1hW^EveUhQP-96oChQNMi?y4JRa+4b0wtZT?xzf?)i{)WDbv&rHZjvjbwzN8JjDS@?TitQeL1*U zSV8psafJj{E`ih@3Xy;@RJS2m_q{HxHH-rXl}Hj?kWP;)Dh^ngt#8yQ64l0t_&X=@ zA$0CdAh97I861e9!A4-U3q?MT()0<3wr}Z`!X!#li7xHxYeOu|?HcfV1z|@JP%>Ni zu5GH|LL!M+mrs;`vMk^i!t$sZ_FIKi{Y;{r7}i%BHE8YOGuRNSS5v~`imZP~`Z)2d zv8&9T>D8*_kCwUE%5Nl5lENU}F^cOC0ESU~nHb5DmC{IKXMJc&LcdwJ)JDWA%;WF= z{L-G6D$HlBM+hHwV%m(|zbCpmXLQH6>O`S>WL)0<9;lW0!cYR@oUF#usmO5rMvol$ zdMe86ldI}RW}- zE~%a}KJKU@L^e*PnS0zcIzi9@76nV$F zc+FA6C)y>rAS4EmuBwr`w+b?Tj|<<9#VIIasge7jzMDIn`O<}f=;G-Xzay*sEgrog zMUN1==Ltq<3UYNscO18Ktii^0Z3phLO-eApGMDo`Y#mcZ=X_#AQ3o_6z2y;j?5FU~ z*bg|hylQ9@c?b2}m+t@Dg50>qFd6T6%GM9{pKj#*Ys&V&hj{+~a<}H>|GJbm@&!^H zteme~<)oze!?GO}QPffli4^GvT<~kb+?A^`chk_^G5W8~Xv*z^J8eMrH_pD_wqk zb!CgC(^don7P(*DfZ7K0q_={!-iemZ!J1fnYa9LJCawmYO8yuS=0Lwxu*{hn3om!a zc6YyT6xbhBj@ICDkTQS;e-Pd_;m?q@?KGl65)mq3 z{3y=wmLizG$}*(>)3_$O1gpRl9qlb-*53hx>i24+Z1vM!J*U7FR=SNt)mVC$l|noX zOkid^u^Hy36hdW1wx-G?J@6L6mkm+CX$3Ag-FWgELSsZpwkx?(x>Qs}spmc{U-H@5 zl8X_ykcX-(NoX5aS+wmsD2No!Hd8RH(^9p$SSh?vH~v^n_Z9$V-NzzJDByI!UsA*l-4tW zeePXk`h{#-D$$8j+40nY9sHW*-KlOnSbnaH zbM9rf$GE^I&p8SG`HmRh`$XEFEMtK<2h;?3n)CYQNG%Zh$_`j-!~s)Hw^8`HtP3{L zWxrR3SbjMLm*2de;6Gk}08;VqnqQt7(K+KT+EDb|a|v9Xe^%in+-M${yc8XY?hEvO zTshv%FNm66AKtZhnYQ~u>vmjAMY^-N*t@pK;RQZE%yr@S`Tc8^WevK0%p8>ATXMF<74NsE9&{Ldn~96=jEsfix-x6}5b z3H&v7iNE(hBNC5bZX)z`bcrrX_a^sD_oKVRVl`L-D^W!lg4w0lT0 z7#HS}EK6MI@fS*ve&WfMnv?8lqjO|gq*~rB6XiJIEi{lZhJbNc*r{qnt2UM1fGcn! zm$1-MGj7t`U>YSJuA$1n-WF9pn3S6FY|cih!YHJrNdH1MW3H+&?44!OT6eN(9BXwV zEv1k_R#|wz^dDL})HI0F`K28w1IeVSz&Yt)*pT!G`Iu#rw+Jg^VU$r1>N%tiG15d8 zz$B8)lD7uB!zJ|&o{+sSe-U@A7$t48qs}eHon&az#cP`Jx|$Rc14Y}+Dj>0r(|Kricaze@c=p*PWSkvXggA-iA}GWaJ`J;E1CeI z%I;rv%KkgXfhhhttbTSIWWHupXg^|4uyNNtnIwSi8kXNui)RR1jgaw&_IUFme|Bn- zQ|ms%51(U8$j&;QVfjmdW(j#Bovy~s{r3<5OgP3n2(sKZv3MSPnduUl`^Q#W$sW)E zZBFJi;!_u2IV$(2v~@_U7ihy7H*D3f+bmjyu4PqpVafzP^jW%3Z{yWC2F8Qt9utoo z1;mOwEENr>VIrC0Ysd;A;mRm>8}wGnp&~{o3fJcjWJMiC17Qn^(9xMhSe{>@DMZ+D zaR9)li{mhxsIt^4AkOlo@#gSZnc8H?O!(3=E8Y>hK9EIPJvGSraR_Ct2j~PVg(es% z1ky$1sS-1FE;17KVaa4pUYDDlCiY^gJ&GpqnHmrJ-S6BxB@Am+Uqm&Fn!F+i)V4~~ z+F8L(h88rYurXfL4|1Yj`10jPND#6&+^04E&%Ax$iSD|FyxekU!7b)!gvN|xm6T7DfGwEjWP3VrG zN8|NG+?_u^rc}*C()p~fFKU_}Gf}Ogi@ZEhRuF|tfgO9I?zJ9~GC zEi>m-5Fy0;5xqD?iHC$akSzBMfSt3zmvl9#Ok4N__F?A9$79K@2GxL^NPt{a#=R#A zUb#=AsmB)eGag`r1-^9=QcuDh(FIXiQE7E9?pW7xzQ8FosDdK?eE^;&2fi?#a&Q3& zcgSUNcAr25Wew_8EXN0@!ZAU-qYjMEJv~v4?l=?ID1NRqEWo1FtHL%tP z=^lABCh3KGKCNTS_*jReeZS`r<+Rx>&WxcDud)h9APh+xYn1iNX)OtU!^0-VN`xaC zO#?Nr9d)*gpZLXHOSJOjjv z8c-@#pv=H1*^cL4>FI=_T~_pN3y`s&+=tjP`el{}Lwe-)`Y1x%4Ut6mz(?56N7oZR zbTh)C@{?)EYoEa^*h9|Z#{nacW_QxSj1$9_kvq;2N7|A4EX7H<=hY6^f zPM~YL=$`v3vt71k97+@9uBpJw>Q&s1nPOM`W*FWZ^MAjk{9d+aTnoIDv^AV`?DnB5ov| zu$Mp14^Vd3PpWt#RsWhnw^9D36P$Xn=@m`+=vQga8XhD%miz}v%!;hQ1a>1 z`fbX2oZp99&1%{+Hgun_?4I-APE6xC zKsddAcdwzp+kpSsNVAHmldGk%DXEGJz{T{R|4Xr|+&^H)e6GIGk$x` zcs=KM&G;<5Jbf%^0AZnG4qtTFTbhW^vz5lz@W^km2X8pIuRqgfdh0*vtsLrWb8N{~ zn!%sv?4?6v4t&gmla<>3T3GfWc1V?Kj|V z%g$uv2t}p)*+~S9BPR1P1x*A)z@k8)59OUFze^Wuc8}y$Ri#WEj!hLGnVt>P1Sby} zaT!oevJ9f%4<$Gx^)-82Hs`U(^1sLK*UJq&O_7Vxr*m`0hWO%M3qy{e;+Cu}+Jr9H z#E`1srS>#+1D1Is_`(A?<#$oTU%N>f$P8nTI(P3Sqx~NusDsXl>q?V8vW5xH2`D01#8bX3+NUax~>SW_73RD1sBq z+0a7wS!-#q;e}8VJM#;4MBISHRUa)*p?c}iy0AS#9CXBlMTmh=s9#wh!3ZUakFz8e zo$SZ<&DQLzGVO*mTZ z_xsny24)H&UOXX5-&7fBA#&6ZDQ4QRc&)e&=2B%n z`tYBM`Tin(HJ!BiR!8rPlcH(i{6An@gEFwYXf^w6a_4YtpXjFZ1W=@L*IEFn)vPR3 zk{%exj=~qgn%$RwGpbB-;#%qNC5we`!}`yl%KvRt|1_uM_z7tcCe)CxM=J)aE*d+% zCc+rK_A=B;MM_lAPQ=Y(V@%}|3g$6XZ#E2me+06es39342jD#c3a*zKx6zHa2^xQT zc(4v7YK#Ui{2()Y(P7d0`@K!YIBq;=SwIG9gf64fm~dzXG|_CvT_s@(Dp>16I0y?QNZizdcGr+f#<+Eo;Q>Ro? z-k42RFQW{9CIJiX^iJRE>Eh`AZR}*qYJIy{G=n(6sPkc$OTa^BIh`UPB(>J8IXp&^ z84`o{#OgQqsA)`VPySn!UTzvI)RN)|>^v?~`5}4AGBu6EBnTIu28p&sW&7Uln*(z|XpuVf}Fu!#+%`#`D9^PK>o5=0( zzeyk0Svo-E|5)SrR_yryqfnq?>f!=0vN8Q9ZRWq7UgFgEg5&q%Q+6#m8>qH6^ig3F zuv9!FA7MT@bcBCSL7*gK;Kp#(d^K+8dXL z63O_n<;>3Q>4$?iK5Ul8htJ-bc;&;*tgBxU+OrF=?bD`srDI8jvY@tF&YV%pyhMqh zxR?S|4OpRBwQmS;V-+~39G2vkQBviSUgo%Jd7Rh-8ucu1;qUE467iYoY$CkAr*F6M{Ce_TY%vT8U%KDelJt0J^8nUp?_!}JIfs%UWboNvj364!gR_sB!L}d4noFBbd3N1ba2ECWNkq0E04pWX0=o zq24+2N4HY@9Y0-r-uJeZ*@NzhWY%t}^P{S}2cdJyWkfUZ&QEgaCR}KZ7*gKa_I;83 zU@HZP=%q530Z9)diC5sByx{aSidZq~Ioxgg16#OxUT1+(PXY2b8W(YE&d5QBngzTp z^deJqM0S*=5Z3Mf<1~8jUkQbsoL7UA7-z_b;={_pyu-_m`>#mm4)nVzceebv3-hT| z_FVPkyoG%Yfuqq;wcLO7rjkBQlwbKe5VV-l7&5LW17%-Nvt+#w?8EKn=>~CIRkJM5 zz>M~T40*#$?-2gAEJRk8AsYC8fqmamSL{D~ftI!oHm0hUwx+U{wwB+lBT}aSff^O7 z+Wtd1_HC(7%0aWDx+zdoID>Jhwhs#?UN(}9@TKf4%Z)L%#i(&Ryq12~%J9dOd+Zb# z=k#LL>@pJe9J`+6dz-wRoWA^g|MQ2(pID!?PhVMDFCW= z($M_%@n^m9dJIW;Jf<*aq%q`xa%LDwK&5h~5u`aOMX)tAJs^aL*x5|;f zC~n-u3-5ZApz5`67b2&wn$nKt@E4Sw;s$1iiH%ZM+lr|}sfy!_fuZD+Rg{*Akz$-_ z8t2Vp!6*wY*v38Z6i2NgJPd3xe++#DFj)}}xSL+HVqWgcb=ovCL)X+(AXSW4TkWjZ z<8H0)if$@Tg5poyOm>e!Mw8R!s?-t@8IJY=h`TgElf-A~)tzV`ahX+=ifA*8s^pW< z(DqRS^B`mEPl?f1vq*B_Q0xAEhK*{xYZt_$$)t5gbqqL}=k*xfvJKmj-HZO#O6?HK z&VDN!*BVdnfrd5}rk~PFV%S9I<{^~*;XyXu{-n)aN%zvTg?I(={gn0UQZx&GqQvd* zOvBF3BWaUU1jgKMffu>nPbwJ)gDL79apdjd#=R1*mfhhxg9+WTK|VKD*N};%l3oG@o!NZDk|mVOXh|Pz&DO0&1jdQ0ft+4x{rovd z$V4U5&SK)yodVBCgcY9|fi#-W)gnc?zWFM5|0a@wC+zZ3{X?SurdWvlzgo$EJ8QKw zALB*%@f!wn=9N}{oXlnC1u<5Y$JAyiE)9PX#vj|tAfvuHMOx4?0$)HE(xuJ#>U zP1m}@hvG5ErIlH>Ha0%wavOVm{l1_GL(G9y%B$M#hs6t}vSUh`RhTai@r#gcWo4>DU`_wnnB-Rk90e?^^OLR9%;_5X# z|D1P8Zo!cA+DM2YU<1AqYa_9tMy%~+6QGCEZ8++aks!c_vI)|d_QDb%OK+Z(CGWnJ zis;39O0M4gE65ZQ0CWy!M(x0cdceyL3Hl^QbC@A7-2qHDWDeEjiEUERc&)p9r%Xkd z0+u1)MPvY#*J;BTwcN)(PL7dvnN!(9+fKcO*Og7wrZQ}ukZiq$mkbrHJW!>INCP5A z&F!nbE7C?>RPe5=+3m~(SB29S5ySo0VM-7sBfZmZmsvaQf_*lEX7UfVg$R%H2e2BT z1!mt2XsL}%amphfyo@wOG3ueff_qygpxLR~lUepfduRuh1|i8N8%4`#WDbHnc_WtS zhn^CaaQ)Zgl+3myP;?kHYgTy}0aJz+_Y_;Q9G5LjYTXViW5}K7W}lwbLXo8w&iIzp zA&&te68#ovW6>y)!76DcS?D`IKB!`7sH$IAv&@jR7ZS9~Cy(bjT!v{xVY4Vc=WL)1 zuQ@4Fxx9sZe;)*_X-rd&0i^|wmwGy&Oh zzHV#g$GVb6d1ZP^1e0xfZSKO$MJpnL;RIWmkxqG2aK78QB*hNJh0RG4aKz#t#^VP= zNuiNc2qZqq-c5n0q?KCxDN0}hb2+1i@Ott2xOSqR&X1T?WBCloRZ~Q$T*Fs0IY+ox z;93d%{g{N@3YE)=zl-?-h31VmV}rCsSl>aSYe_@~MliF>V!VYk;-2xfeVT+tb{u9x zYt#OUcBtWhx^L6R-Z(l&$hdEkmO$pVTTaGx2hj8Oqm1_nZ#M=WGD)pA`j>XeDMyzM zI@W}Y*~J$UA*AwZ;dL31*MRZAp7=$3-2Yp~geyj{oc;}k7{>wv68e9$#DCghwdQ}_ z3;9eXrL9py9bzHI_JX9$+R7@R$N_U^HwtLnOt|c`YUrCf=KbF2i|l&VzpgX-uZ6yw ztK2c+Fsj{BZvvjgbPoINx1F!;$?HPDZC4EcvA;5XN!?ZaI=P$6*b1fEZ}Vr}MMNFt zO-mU+CrRJbd961>j+$K4%L9s#SX9IpWz%B-m5QjeO*AX5T%E?Gw=h@ZV8`%_^?9Oj`N{Gd>2muyTUAS+Y#Pw(;)<&f&!LBAsEofOC zOeTbz21Xt|uo4-JB0E#H&Z5j6%2Z3X8%l&g_#QRT9c@L^q30+FU5 z?}>o2LQ|vf-OP+7axS-c1a9mLUtqnyJLFGYKw$D@eEVw7HzqoHinC9jq)ex8Em@|bzFGMmRno({RU_IdBjX* z_^Kn*0A*jw1F(EkErw&U>Y}xz?B+Vs*?90$lkHWuq)FjAU2qi z>oM1~G$I;cPis|odHG1CYN90p)OipwgGOav?$QW zV&yVXIKYFjs9gablL}Guo03uSbLmV+m3eVkB)Fv)WWjo0!(q(#G93V%slEW0kdbK{ z5@cN>6_AuDu!m)_1@&C$M9P`vL@nb9Ef=dI$Ro1R;jOsEIvVBuq)RG#PL}cHq$Wx# zkV6OZjZ9=-D*^^o)0oicM)_s*(!l7+cS!#VY--4gv?=d+twztXhaCc7-^sq52V;aw zv5kWcG>!ybUJ<^6^Q&JzLzBMH#3&5>n-(^nbtU+{swDxzD7-5z@M?mF-W4e>$Aq|5 zdxE$Hg3hm3tTRV8!=rd=L#Qb>4EQA(0}gFvQWBJ>e>rj{P(~$D7yeM@fEmk$L2ZD- zZ1#Ibg%mo{P9WLBiPKOlp(?X*_hl7aO3y(Rqmo(g)3bRTR7`HgV|TikGAR{2s`kA| zV0cM3X)zD-g3&M zrbzfPF0!(3J*X@sgtQqcUVybJ4!pEUmUV}PYYS-)6+^32O^~xoDV^$3D>U2sC>&28 zfy(@?V(BT&M_w`?2E7jHkKR{pN7k@x1J-Da&~Q~5Y6hiHft+T}kBB6#tsQ{_&c=bE z*IuyUnSwcgaroyU@6V8PUkwA6RW~3CfmuN}(2J)Mw014? zJlz*w5zv>+$3Yv{f#PP_1~Pz3AtsLSKFli+f#5;k3Go~ubKs+z#keoE#m)@&Ld%+D zzyN&<;;xvK9}4N$XDc*BLi_3|OsMhhM3~ASGIBCf=pG0)(r6QY|5mqt(bB~`##30J zIA2Fubo-=X+R$h**F{6?w3LV>NUtv+ACc<8LK0Regx=Z~^?PgPZ>hNOUuyk@TWEcA zbWCR_jP4F2uIZ8@PyClfI*39`KB8;ofWQbwvxxPbzD{Dnn|eD`99n~JRqx&#NRnEk zOf4*lR?s&u5!0mUzXS}!1bfDC1p6p~1S>2t1iAV8t8ZK%axz57%CRgI%oDB6%}k8W zhsMkpE=4H7m6Xp?cBLC7lF@1IVVM*tR*^OpD|K7(L(oG{xR^-UwG)?(kGkbC)i{x; zI&1hw@$?>G1Yhqdsou6pP$qqo%wDpGtmnATW;D;4*wkX1C4N8Mc4~g74{^%I0dX;Q z%xm%3+1Nneeq?H;0A$37MX+1OwD*T6n$5&N;I*D$tVoNmpd0uz8tEfI})?!`FyMUK@Na; z%+t=`2jRJY0Xg}VG=8?~q&mXB7@v4k^4q~vYY&_4g|pVtn`m0Lqy^Ho;86B_a#sRs zT|tqvg{2u8m260FaGWoL3}62a_V}*s;&~g&zLkO#w9*=~Gt^#OA9gxQ<;U;0n-!{x{=e5AW- z1r$G?$G0sx@%XP<;mmhsg?=(IKy1= zWhdbKTyUk^V)GCr7P^fs-s+pKIg2cIW_0PCEJ|>q4D!OCfl~8V`be&{1$Z$|^V*v%d)w#>lkzT7n;oZef_+^XOtWNraj>1l&aFD48UA^4Cxa$ z7O~m7hyT_P7e1Tr;^bbrO35TEiq>#=l)iRG`>7}QRb#?g>-_71hSibBNoJN%!rMk8 zPr_a_^G17SVY}@xIBjvW&1w+mcKMG!bnf%H2(Qb5%FI%sUDdQ$Y@`xYe$ zt6V|)4U5Oh#Zypc+GegiLZZ0A;T_!Zpi^6TP8HX0E~Hcjsoe@B65VoJ=~n!#R10O1JNGBKP_!c{?V%WpCZ&U5$0Pa zu_s67j%He3O(o0>Uwt-Z4AKm(XULw;EIRwGo^3Y~t3(-5;4LUctLA<1i=cQj(*+7y zR8INK>#fU6A=hh%FS~Y!-y1kiM9olPjl&MBy;*Ca+-xF7rG>0hO~TY?reRE@8w=r#1Q`%;0h-VZr#6kxpr2ZTA=K0Br2oMq3z`UOv=tZ1 zsb#n__*aZk%TPJq9&{KbI6U800sT{N-W3nK0C;a?BPl? zWQGwL{YoVVG|-YR5bV6AR_SY9aw-lPme{4quu@%UX)h?ZbqA~Sil_z7qjD=wx)Ysm z){6Qb4YYdD+M`0B1f6l;vq5ISFgJBcM_0)1*{8)~*;l8{pY(rR%dZ96C`MdhjgCf7FYE>D%x1eZ9 zGj~Ch9-YlnC<%Yd%T&6R#phBs67iA~q@6S|#4s3GRWB1QXeIsjZ+7+ z$?#Mev$R;O234~zUzs;Igc${ujHZr^SdJry>e#F!4VqH8TCN6c1;B5ZPrrCsIt+t^ z+sL`V4-NI-)b`}+DWQtsCsJn+mNMe|g_Cs}sIbd7o^fMG1&X6!5S2mRn*)pU&we^ItqBN0nCcEF)$M`6fr8=gcV zE%?Yw-RBr%Kc($yXZ`E|@^dUjZ7hXtECo%d>W~qF&h&!QNvn|HuoGwJ4?SaN+i7K}tZb-WU{iA;>*~^8@ z5$rS>CPuQ;>~qz|1L66stoTy1HLq6YK`K zJgY;-Z7KNIibP}A8j8& zIPWkb-hOf3VSHYqAG||UyaOJ*p#c~{ZrMidN*tphjKSlrV>m_4maMca{qH3QGlw_- z>O>Z1KGm+ir3M7J|CFlue{&-LT|cW!I4>w7e&VZF5sKaf8Fj!Idft#BGM11g&6;Zc zV-ToeuovyxArBUUlM%NK7(@gdJOqX1wh*(MA~MJjVp0(PEl16*k} z%>k@ML-?Sh-pX|QvEn7-L=9KQt}-VR0c2xun@wb=b(3&s;YLTieSr~Vrl*~!DZAmQ z5)l}MenD)TX;b=B@~puWoEjOJC3CGdt^_zeALVDI7=`WvB+W-(H%`ej1c-EH7b*hRa@1XIDNoX^PCw@0f)CQ>ypMXl|T2@p3M)0cB7_hs1L+P&m z>HU_TOCJD#Y<>u(CigY;@rjVWMDi)dKp7H4Qb)QKWK}3F@gtP%nK(1c+ZT($=S=;0 z!cVYgcLtz}i(x@CMv|akf@YG?*Ar+>6&Hh_wa7`N05xfA)pHYK8q#Fi`s9?ATFp=5 z5^|z5qLnr40DdA_SB^q*ThWrfgGL9YFr5#BJ9hT#Pr0wufY|LHpC#or>{^NZ<~*GY z*jRFqNBdWSKzpm%zWs_~&vPxi1(+jK`PPW2vDJfQx|a;ElD#Ze?+r>Wbp){F1DFLb+eaNKJtIt3Y?UEuRVDpj1?z41>4$bn-lRv=xsvVU5Xv?8 z9*67jM7iqHnLYGM3~kd>-9uGX?!VTQCzFZEhJdNiyP~EIN)|7cHKWLMYel`1oj{bT zdMysa0c0dKMnOwyB3-@8MF$pJ$P_DQTt^^D+oDE5G#wCiPpa$`Bt4k0EY)`E2qbPu zTtpyFa*EevV?ITTQditnu^^YnTpr33uCRtM;jDib!F{Y`7nfH{(S3M^55K`|I4vWe z*MwL;RIZc?`P4J{q~upNk#%m8mt7IcrL${HLS9b;`@M{jP}(*L$GN<5nM=8px)PG&n|Ed`o=f@O(#vbl1J*NC7 zt2Sgde`U+8DG%sw7ffs{KJJQMGS8@uf=|KkK1Le6mR*(dON(c8x(pJb5qt(dm36|K z8W_6<7+nJ*RO5~M%z~Zf%q^TeVh(|(?d>LfhTERoR(W3Oq-ld!v%C?y+{|?B%$(Nl z)5mo*MG)Z^^$HPWh$*xG;FI|4&7onFy^(Z?Lfz{U6e|E|7?P?id(wBPPbqHmtsP=t z-yU!M%?akOk*)|9?xDK4n3;PtOl{j$JoK6lElPwxoBjT+7pdW$_$Bf!u1|mKXFUH| zPWJz)X8-h}(eXRdz(T0QGfd7)pB5f#FqEQ+7+X!mNvNp8@i>7R(GzvilhcFOQEQby z=Rh76=d|LJHtPZa(=W%F4?LkS@19>k{_L!X)5IgCzkSAqQ5r|nB*ST=qRpnI#p>bp z5+H502#x1b>zj!0fRN5nJjYO1kUDV`L@oGMiGL2cCU7Cfy!nZ=Ee|`|37iOeb%;5;QmYT33S$SrKViQC>Nlu}l+#PQ7#UG2hoC z<8T$~DjJvTO$py6M4$J;3!4&>OjXN(*7NkeydK!GKrRno#Vv2G%0%iyE)f_-+$PPe zGXD8;C5rS=YNMiRa+HgB~)Mf1RBxq-Od!dVlaz5t#UvH5_!v66ef#Yu6i5& z1+81Asm6znR{DbMhrh4tLOaYj<*l6As`FEpbM8Y{YNy}V$18{-J`b!;NGZYDgL8R- zo)lJ#t)^}Tnobe#N|Pjp*o*rr;2?Fl=^n1B11lYAInqC{)^O#TBhp3uQPgWh9%z2 z4mg9v-vvNEGl`)x^HZr|Q1=j)WC&;1kgKs7Jn6P$S&i|dkJ0mXFwgwHh*J=XO2A*0 z7jv_Gp{KS2EfTO^dFIEnk04ftnhZi3p{KyLT@iWyLi80p2uq>Kx*s=P0&eHYUFHwh3(EW!}Ucg!)}RfuC$BPdabM5 z_UuZFfo3|}dj+R7>}lk9%q$^vRI>f7sdcnZ4?A5^vs%4V4h=#B?D|hSH^uhr`0uMD z#_#<7J@T8za3ddUQ^&N_{zKqJz5FSi^sJYsdTc*_GiBlUyv^qwLynu~&1v`ge$F(@ z%6NDG9XtMY>z5r<%SwLQT$A^8yZd9x-&;A;_GWczT5Wc> zHSU=oBJQ^Lj7<6PqV3?^f}gReQyZK)=TI|r|IYn;jpM9$Oc;FLP4{Tcb2^f1qkXIc z4xZ?Ful8vd3j^~F&ebJb`^v@-tTEN$^YcI6gN&TCUtF%`_+UW=-_HI+5B5E;`S-~8 zsT1Qq-S1Mq+w~v#PfxZHM%xV$_!W@JUL`qw;6Y$S5M6dnPAu_ zlXSjw-+PU-!TGnq`F+GXKS1gmgfI1l8$W4EL%sc19z7ape0Jx&V~?|Tr8TRj-Cd(z#nz99wBNcS=jM=mCjb0% zI{NuPNJ9T&ak*W~$s+~2mUc6IK7d@pm;y*>+To5mMZ@o81-mhfU0Y4RBD2jm-D&+VC}sQHwD^;kuO*d>$&uGOsGWG|?9!}+qfgIG zv~2N2(%&_1QP3+{VNm$w>M zd+^2FtxFEv9xnemK4@db=={azJF}Zltue>!*}CEVkL&lI^i}s%yu4MLpG|tqw(T_} z`eqm1Taz}=TKjX~hzduquP7JT=|Z>ZY2A)^Wh||m-?UMGsark&@oy$sBpT<+^#U4( z2i9NueerpRGlsoGhHY-FUoZJVyV;2!wizsU%s;vESnY%E>!-Yzba?ix_Kqq6{mw*r zn!k^7jCGvtX1?LTeUleCyIO2?is)8jPn>k%p@0^Cy_@tI+H7%jvm@E#@~+lA)cD@p z)D`~zw?npj%ztsS&9KC~mX7NlwCq1VK3DtLX#cTu=T+Fg9L}&>&XC?7Vl^bN;;+TM zk6(iIu9lD2+*t3sD(F+?1K$(2J6Ozkm;R&CwNuo&l^)yDKBYo1jaDU-pkQM5D9NJ! z@6ZcFY2lO58?6k__xLu zeDI1uqXDK~mwbXh4{mC(YHLj6=a$b$G;F(WN9Vs)=j^f{Wi+XE+?rVi$%7kRZ?aAI zK#N;%b^iqA?OL^D-JqF+^CO$*PdT@5Nwn@e8-rVCuZ=NZ+Rj0@;CSK#@I18xO;-RdtQ~4Xm*HfbO!(@;|HA zY+gU&OC8@O>uN;|(phmZC9(clqoaq*7+bwFn0{bU-)YY-ImeEw@T6vLrIT)TZ`{fs zY?T>Tz1p30&shsPbg2=Wyx;A>72i)oHB<2@VB zo;xCl@oJhQeJ%i#QyG~m!&3y z2A%1?*~4;6hmY@bdXUK`t!a`ae0eDvlcrJFE|nwrQd4Z_I{_Qjp(&@^XvuV zZr|#y-J(id&s{GceogP6p1<|u_E*=JrCth6AF{4V-9S>K-o8I&F-GtDrL~829L`sHsef<5!aA24*0H_YI>+)rJ8$dM@=b<6 z4y-xHe8YD8F=gl*&4+YOZZHY9S0%$O%{@hS8iXGsQ1d>}|IP)zgeYwU-2 zqk0_Q@i=4P@jH98&aRMLd3`+bl`f)1f6ptwQdHUXOXOcSze+U#lOz{VqPWolXOHNtv^AJg0Zt6_EX|{K%}z4ePrX z40_Tb%Vn+4?_UpU9n3pCJ*e~7to0K%1)bAOshLqZ<4^6N4xTc(3@XO}D<*(QJ6Vf+XH9RsT%W ze?FDZUvXP`KB<25itz=D+B9x#FzfuusJYWTYWY}iiAyOvro)w1DF#WmYnMG^7@+?z zymo7OAEy;%T_$dAS5~^cj$X&*4O?a3NwM0#`%b5zMHlT;_cUGi=I^yeGpCpBb;qgZ z!F}F6=jhJStF)o@inwb!E+?D6y1TT`kO&X`E9HAXh)mSq`?pQ~+0`4^UR#`M_Or45 z{JM81`i(f%fAY^B4Qkp4?Z2MtQ*}_iAF)<@Z{+!Heo!gC&r0}pW0GDisd3gZegCTq zaW$XESQz97Z(V$;Qk{&eH$rbYuGWcnZ=YM&zQv7iCS{Wc``2_SyEMOCK$3sXnmMDN z_v`bn0!<;vzrOjTf|N47GWuu+v zn+}+Fz3i&|MxP?G;+?mBc#^ztUh>H6TlQbP);YoNQpT91o}D^Bakg;o6ndslvgQiA z6OF#s-D%LOb=;?A=eqPx8Ru%h>{i832_0V;IxlsIt(`e3s71Tak@pL_RDPQ%UtB5n zp#9iQ-|D7z_!&D~e_u>e_Ib(WgvD(aX8$>CyR(ArM9Eu|7h27qwf|9mSZwtgV}JPX zd0_eSd&unN=e2Z}r8dj&ceekeX>FQ(wG7yF*-le>?(pQrj_YRo3|P_TO4^f;zmiuj zaPFNlJjx+sMq|I=|cViGRbZn)aUP zKfl>N`C|J~Qx+Z6wV3;2>iPWej1C5m*WVj?|B&~u`ynr%Tkc%&Yf82-;FHu-(|XK{neUKro6+_=30MS>elnDv~JJ*MAsEl zTMW2)-?!_aq2+Dzq_;iq?LLvZtK)?J32XJThv`^NX^KX^88gyaNhqvE@doJjmbjLcR`>fek zTekHzUT5+qVpqYqAgxuIdizH==xw>aps{O5`_T?Y=VsoS6Moz%Q>%OCH@^YXUwrK8 zza#3;jey(9*#q{c^v!x*E!YDtGuz*7p5Cg0lz|B$K7V4OhrHeHQzjhZqaA&#yiy-Tzw<=4ST%gMPlUig*}5p&2L=Ky`@+8dWA-{jO_fcPFd{U*slFs z>y_^Nb_PtE_+-yiz}Odf(0@r1j)I230p4ua{?) zk#&6dwlRM{_bssg@L~Tby&a!tJ=YIu9bUbayuqNQ4OgH2UE{{KDnF}vf;+ZG1zm$hfaxmU+;)x0o!*Oq19t^CsNv@t(Xb-DG00e#1r z?tN~YGsm)DQq>9Ja`{7tlYeY`^n5t=OLzMQb($=(dHAc<`1$S=9Ih|@exg_CvMqEdNnC|M0~z51(Ic+iJ<&`~|0y{>e3+FPled{yva8tnTD4 zUyf$nGtK$B?83L1QEMEYmbq?H_1B&!S9W|^UL_;*xmNn(IvXahZaHxE+4a@7EO|T7 z`fY6Xjg0pLuX=m^T5NCBW8OgBooCvOlHLe7z1O?ohK}QF=h~x2em1E(IA~|J<_!!M zH~Td-V&BlK{i1I~j5(J5uBF%5^hZOh{%ddib^6$2(or9N-#mETze3gt_ce8|?(GFl zPyc;m{c&QgMjl@Ac0)Y$Tx|8P*aq6hc)<)o(|`~5V=Me9c=c+~Igj2O{N}XnAJwK$ z%cRyL+TZ>@rdgww)&~QQetCX>{#>7|-@5L7%9QP)VF*3BhK5UgbLJ7RqW{y;Ff07e z`i1HrB^fPg-O93}Mt$~Q%4pQo=sxP%gu!~5Ww5riLI0iaH|r9=xiS1M{F{AcA-umG ze}(V28xX(Uo%-$mGMRs{l=z72B7}^!q>s2##;HwwWOB(Lfxjk17D{}}&GXhI##~tO zH~Idc#>BT$dA}tI4VA$GOBjkk?XfQ89rdQS)F#rnnc~GdgD*A4H z_~swM-?f%TN>F)MJWwa)g{~~L za`C_1Av)4V77_+_fFT1n%CN)8@mOgT$&jxvy#XZ#KHP;s@rLzT!6;6lfT$Ek_5{IT zrC}mpe=$4?K4=I)-3XX6FncZxrf*;bJBX6Wy`>S6a0wr`ZE&Dq{U1j$Q`9TMVKPMx z7$0!sjF3c-t?$ILaub;rfpuX^6siAz5XFT}&f)iC!R(b`UwQMQ57vhddMp26uL$43 zK<+R{GmHUq?(ef*?qS>5bOJw`;(KY)bxE8~BUuW%3Y7B;L?dQnT1Q79n7z z5$4tkvOEias0EnVl0X=%Cjx=n24~hI0IW2?oE{O?S3&Gu13R=K0OnLz4iF%byGSD8 zHL#*xO(hxO#zn+{m1a0{q(RH^@cnLZMM_(OA*QA{hF08$c<~WIV5K2qd;g9)3J@(7 zAnc9BK@{%qD#;RGYP?|cHC7tJXU{d`l>p(T0O4sO4x$aWB{X{=2&^M2&^Ah{p2}1XdbiyZ*!qEdU}D5)>Jj zC!oAhmLQ5Zj`rLT9rhy#tTe=N*RDraKnuMNAY=>e(o7TtPe?dCKnz%Eh8edeOy39$ zcNG{KnTulJiHLq>v)Q(Rm1gJ~Fs>JqsctGT)M_b;fhQmWnjr?PG{ZNK8U0t5$e?8@ zih(B{V%!k}R+_=^(eBRmp;a7!K8lQoPpw2Tbl{H3S<#3AE6t#F+sd~OG>V1_43Z9_ z7&>w@tXPd0u+j``wr|mvLC^gQx=+#$zpX?ubmC@6Nka@+X$HMr6)pWB9vg!{NQR?u zrGSV8(V3g!=sU!Km1Y=`={Bo3*x@DAi|vTsQ`SoqL$A=nHz`Z%xiSo1vaJ&Eg?6Gh=HlLbYEc{BGbaNFda1kqrnX&zs?T>T)BIKz%@GI2XOh@x>T z+;UQqN&d`45Lju5eD8K~z6KB&E$Bg)JFLtK4-RfK=K^1*b5_r&|(E zDKktEL4-82a7w=<1DM=FpT|mn{!_y3FMHtAM&JeV^DQJwKW{4?DTxZ^`@H2}^m(lG z=lkthp0pkY63^hL1@YH6l`8$bU1(HD(QW)C{qa2-<**F`EB$rnE1ssFkRnIGz{ZOB zy5UHHU+*gkj*_~Kw2un)WrqITap3NZScbC@~oPI%TRUUfL`NbB_!@nEHSuAX`0%%q7K5NYH@cJxXyJYKSqkwp&W z#yMZ}9cvz}G*0&+4-cIv5of_FF*yCCk{|&%w|gKQtTc}4)Fb~I0FE|<6IlvxS)&|B zX#x0ZB>Fs7`tvJYqqil4V>UvXBD*xhb%H-H2`(ys__Fu6d58ro&Eob}GjR*F`aJj{ zOO2|V1hep#<~1K80<1K_@^e#y#=y9w8jMSN5KTvWvj_qkSdEK>K23Rj-mF|68?0Dq zpz^WfrU!$2ZorlPWEcB5MFbEmN4QAB`UOS?6b_!an@?{KM1++la^Kl*;*+_t`z5Q0NnT6FyYdWLJQ(;+5e4zloQPIaYPjK}lT9n30qs(yL`O6i0>2!z;vf;R26>fz8QM>}8B5h^SJTo^> zau5+#ny8N1z)byf>{!v7A6ar<9C&U z^p*vN@-Gp$iTuDO5Ulj)(+{nEH$f|0=>%}ct4~)5d}w{3;jG)2FMNEF%YT$k#z!A z8lzEA-c@S|#&xhNZ%$ww$`y#g{qboX(Z{jUA74}1f9`sS`&aNoCP?dir5|@2F$%`3 zyhUTeQ1pGQ^!FFTT|#@I3-bg6kh_Lj!PKUbP8EM2_ZN=RVBYDvP16tzRvPC16<_yg zh{fm79LTBdF5iU0aJ%AE-Op?sV5Ps_HTrZi6v`TJ;D_9_^81(aue0ZRCBb}o+EnKY z3xJgdNW44oybb*MW-y!~m%Kjy77oyBL@>g+j2EfbcZ=pvQDPWQ1i}mW zA!jHTR8;zT#YZ(tn!LU^zkm$~tTe*dqc-K^pkK1BOivvztfUmdT@omd4vdfr8r!~k zh)A%~BvylCn+HGv!A#kbEn`$w%i5Rfb3{xcA z4pavpT!J66qX;z-!k}zXr$sFKK34ksN0$57+6s-~qe6qYR!{i%dHbqvYY_rg8ez%e zox3+cX8H~(fn1EgP+trJ>e>on3&1exE>4SZS#G1zM?V0cs{d zk<(^z-9$k}u#1?27MUyOASSFd)A%);Pb>f?rgA5fL0m5}Os=v>0Twc;{EKxPR+>iJ z!E5nu$jo6t)QfOih@BW3R8bcJ@%5P&?GO@H8tL)mo$L3Oh&0YY9VDLdW{*J#2`i0s zB+Y925kQJju+lsyb&z<*pl(wT5>^_iqP;=b(Grn1^-%|jXE)~Xtq2J#jpW*K-NI2| zp?rvJauV;9iyBDWJzdx}1ca3a>NojTr>&46^A!^03=dI2@}j`zhMD{g!C<9fzAkTQ zk`G<(NHe+?oz+(a3^%}HlizGp$66fV6dXEQx~TRCW=F>vs71+2J~Yfxl^HYKLFLK_6u{>$0`YjFg|22Zb%Zt$BB76aXAlh=cSX;Q(#D}vfU$w~%hpN50AQMe4F-e@2WZD4f>Cg#+;HoWG*^k8KH9X@KWj-=5D0fD6!P zkO0?Wgahzwn}1}E0I<>kYs&SDW>yM!f(yt2N0qU{0bt%LQVv&2J3)Gsz{S$V-`*sW zWZ}`w_nwFfD^2yb-qVG8;FEIDS&%zPG$*J|#T_SqV-XKlnkPv!{QW23v48;(xgZoe zMK}-4cjNrYjZ$SDLcvO-RGgn<#f*6BfoaGJ z*I?HUvC^MEl>aqV6B?2)v}AG*$xyiYPFc4aDGQ5cPA!(0O$!^1M>j-(l_qenuxis9 z=uNJ`oFh5Qw0oIw0&WY8@I&9nN`K#}@$VJoAu{KI6UY^Sm1_iipINl#nPZdBL0`v8 zf4%LLZ#SMo7(yXQx&O@uLaT!lw!-d0|rGaK; z{hMk5Knc*I$XSU)Ff*VmpA^P(gc&xH+ejyNYZ%`)xtt_~gq21*p}Xx}D?nnNrzMeW z4~RfQm&bcaMoKXpx7%t~E6auwRvM}Q`GJ=w0Zz>-bk4hRNH`Mr_nUP_-^WUS|L%zg zjUGT4Uxn|J_1l_bO1}?=kVP|-$2@6ot|{7$ft3cxtl!oQCKolTgI~yAFa4}?fIzrh zllPqbs@~}HSn1F2ZS(rbX81g_afw`i?~^9*^W4VY5sp5N_5Y76ZV;+pRCzEPgu0~j zecV?9*8>n6gSzTAV8aaSw2<=bfB*lBXk*a3+*@t(Ai(;-GZ%~KVIip-JN>ik4=!C$Q=QOHw1p1dY-4Gk<^`5hyp83;XNv0*?BNQ z83l^STOuiVCXXv@LKIkO3PZ2dSmy5M@emEj@p2je^bSX+> z^&yQ#Jy(SWHa15wSMI=OaNj679Bhi@HC7j6Z8nav(s=V~S8KK&W(WF0VkKt?I=oT| zPY_ifYea>Wrtvx*Km>%92GZ@bwPhw$0jpcn z`wZ+piUZl)z}!pTAYGOgFBp$Oj{4G@Ps~soY)FC6hILb0Vg^C zPkD}#hyX}?eDf*Q=OG}hG*E2gi|gUb8k-?ElR#lLR0rbeMH}x&Kv-#@>i>_Q{uJo9iJA0SGsG-Y_W_akObojFBL9#LFVS9MBekRKHZ zF9FEqGM+5$P}YDAGORS*8>wIas^HW80Ov-S@K3!`fWvRZl+X$atH%D#5Fl0>(5g>G zPv(H?uZR5&9=mD`C+D_eXd}<6^+zqD~dmEz}RR6h?NFh zb+mE=Xqp<#qjvoX;~6zoAJ8Wh@*8@MqVOpoZqgNLh!iVLYHzETQxO^o3`3|!vc9?c zr0gvn+;H38AvmlwoSx5`8xGJR>cMq;KBO7p>M^DL0Y@fAEg0%jmQH}Tj~W=VZ5b<# z`KdvK$4T(E9&{Ma1ZHMi)iK%ZSNJ?CU+;0*3ejPu>5kT`@F4+`^)l$z$*TT)hti_s zxm)m&1mR(&@&3MCGBB}3ydSV4tE!Jl*Op}? zBevOMrRnNCy7zr9&_yZO?o#hkqT|`X)zcZ#VWsKh*B^$zg`~pl3?@B$%C(f}c(x08 zL?Ak>G+ka)!>q+%y95Q>8F`ix9nW3@$qGb=m8M&ynZ0viiF8%_mJ(e@?p{rP8qr~; z>DJABdTl4rWhvOM(!f%pEi0s_QJ1142l*77L0w>7wzY#dFdl^P(ogPo2eJghXH z+&XL03P^VI0FRs^aG9ez9y4L4Jl_q>Mr>GVw(Cm_SLuRpdxH6#h%uSlV%6FDNMn_w zjjB|WZ5LQ+G_TjzoA(3S5ilLOj&UYlEi~RlJhly@!b(%Q#|}uX0@D@2F!xGM+22i6 zor;;~Q8JA;X8;1jN`oEs=+Za`W+x_qxyVA;87@IrHOCbV`<2k`*o^3~(sagmQ*sWp z1e3v4kak3zC9PJS&P(baBIP@Oef%oI!de`QnMuEKr0z`(pYK zCsrElTkEM=!O(4$g;h|}bh&WFyQ=ZVT-|2J^sCG^8zqGQMj=A1G@*CMC7#aq%n^{;irzfg-$QFeu@aO(uDdeSGNMcYTSh~h1}7(JXa0ENLY~fkL2CxYpq?I zZ7Nu4vazQ2kIIAXrofpllI+2|QXu20oIEWM8CIICSG#xv?GnlCKb8U+&#aTL4=CP2KA1F?N@7)s@MEA%FJF&8loabcyodUu@Q7X?i=8~T5;U^@LxEiPH8 zzmj~H{0X69rP1#9u4HNhCJTTt^CYs#s^4m(2}~mgYZ|jn0V~Zo*<@&yt-v@I+)6UK zYm`&Rt&I5uX65re5F=Ka(KYjARDE!9RmjSN2s;L9mL8)(gWeg5V6oD$-3@dOR|bQ+ zDLB1s1$AMCX69G(5F=Ka@#Es|-_aiv0G~5S^ZslMv zsD>H9k#+MIJvHHqif8V0Q{f?^!%EXFXk__qI+(7d!XT(oRW<2&HZj*KSBGuISZS(9 zI~z4BxhSn{s5%vMPp*;_*t|Ic!%Bl0JX`ZV1X_b)QQDxEnqUIkYo8cIh?ORsH}bq| zCJ-tXrN8T_NhmP=4O)W;vC@PeUb~%UuKrXkN;@|wEkc3D3_g!gvC^orTemxp24gA~ zrQaK=hblDnjn6}bSZTr(_m>9Dbio*fxwD7xqKc|zOh0*Gq?9?05al1Bq{YlLtjjiK ztTbTV%DS1oVDD5fMIYeWo0!8coA}M$VQJc3T3am7R?aH!IB~x4- zAd-S-z;x&aqQFX1)VGUyQ8Go)AdwV2%kdX}A_}ZD#fFK;x;U5U5uG6-DR`FM?=`5; zHdL%Mh2|HFVGsZsNw6u3Y$2P5ilg9erMZrX0V~a5b2&`{7int1sSPSwxQ-CapnRMA zPZ`3%N@FBiblrCo5V}GqL|)s!3{E~P>wpRyD#m~t<@mN(RZK)ISZS7ejgB@ChNj9a zhLG>`oP(oB;#s(zV|)UUV5Lc{SI$d&3s%VmtB_~lrw529;pQ-Zi8!#*95-}-Hqn8u z&KjmD$$JXY;8r4m7J*x}0!K2>Nbx@Kg^$W%{T~HhPNCi~Z&)_Gq`Ar2SpYf z3>V`P$Md#s+{nIVj@6|tI|f6K{pK4pg#re8@lq zfRzSWf682^7Q_N`EggBnc_f@gQ~t-3AZ$qnt4#c@C3G@k!b&q8{kQh=CP-p`VIN1& zB8SumQ$2}Nhlx8{Cu~7PSZSh7{V%TW3(?vdqJq5T<3+6MMBF?EI;L!z$4c|O3`w8N zT&=MiCX>ihYD*`I=Wz-hEtN-My{ok&yuo2Jpw}VI;}s_!2i8#8 z5aKpZ`@V<=E6ua7*MgJGbA8vrJmjglax+!s;il=k5z%0!X);FzMyEjX4}j!PhVu;A zT`0DRvEwr(_8FOhh_KQ`L7hjey$Jqd&he4{S^$?Fs!GIdq3C?XgO%oqUy}AX23Tf5 z8z+Ys`W^5k(k%Y3owBAtB)dZ@B;#gavPvw> zaWI~|lR6*qV5NEDUe!yw3U;Xl9R*odb=sl|4|nKXI)F&9(j+eeUz|A%mSK(!l9m~~ zT?~nHU}%ukPkGe5E!T(*Wvnz$>$nLi%yT~$P+pN4klCy*yoEC{>;f;z28QsRV*cG6 z(O{)%wnmoOZ4Q3w0DdAjwEW&Dh6ZXKYe|IEk0pvwR%X0 z8ssE$&GpeMb>Wn!q5i`V9afr7vVXvj9xzHdt}x6Ee5X1ccM=Mij(D)rJUL0PeuRUy zn5P)XtuUH!d%f@~23Igl%!ZBDz4rYgSk zl!W@pLVEf7N+TlBlkMyXi<|IaA|k{}6V`mXs9r@dSx=~u$*MH1oJxdVGC7?4S90Ue zpO=UVD@~PrsKZL;;M_Whd2+vSYaKPHP=s+CORsWsHomaZSi_esuKNFSh?-!z7??*X`eD> zduYHWYYjBK=gZ~w3tHZ_&)UXAGO*~97F=suFmA2x5lQ&l}FMJ+` z*AvO+amqwpQf~Y0UxKKx(p1k|{r=S$(#mM4G{`xcPVh{-3SB~B)WLv=8|tM_3)WOv zX{hm|_G}&mPHhPXHp#7#C!4AT#U>P9G_8IJ4J(aiotn4I5W;U{7kY|ha!XavxQ*oW z8IfS6NgDQcxdGR>YPf=-NYA~61|iaO%;5k3p)5Dln1Gh7=djXHnR)|$F@>uM^ipI` zUSOjd6mumFug4yHTChl1X{6aHEj4qY-Svm;MNVqXwO0j++c>SOTe2irX%gRhm-aI? z#Xtya^2wqMaH4RJfjMvm#toC)q!kN;m4;cT;S~3c2_Iqs4Gsn;@h|?G8+TxNu+lvD|Mani1Ly2&898&k7v3-y z=pba3A|CDtp70paV5MmubvL5SDum}{?a@s;vnW_;lrg=s%C>-@*$6>H4pM$hPzi+{m@AE)H=V6m zEUYw^O_`-b;ZgvNCXfTk5@Y5RHL2Fdm@(K*vQU!GY7%g5pLx z)4nTBzybM6C$aR!s<|mnJOW{>H;@Sqx#)g8mu%;rG=J{nG5Y-LD56b@;slb zD$W1##LX4+0&!ubxxRR9?y(BE?176M0JU7GE*Ce|tcu-PYhk6S8%>r6Us&5muV$ZJz;);i?FY*UO{ar0zsLOfV$ zp1D`X=P?7YUkZK5_;uoWc$@vhD+mQEjk0av{&Lx1n#<6<$Yk9RE+Q9e8bHC;;ftVm zUl0^l8fu1rq{A|RY6nncvi66!3Dtn&cG(}}9&CfhN+Xq9-Kq*)u%KZIK~0XrhHe*$ z#O@v9eH^*64T8Z+!yNsyb{5=0!QQn%)*!BMEJ~Dp5Dd3nOhzFTtTf6kuQE%kz}(bm znAsq=I(ObH4uzY+Vi97%N;8b|em-ji3`(bhNyzif%hCifM8v{XopM>IEDD}hVD61& z_p;h4zn#_n2_h>}YMybKYe<)cK;{W4x+O7RJ3L(o8N0ER+c4oRd$K``l{SpI+g~l_ zv9>{w_sH9-yId6Xd3a~S&pS4ZXLHc{^#}ngjnHkyw$}~80?a+Ig1NTgg5Xs9b@HoV8r`LLik>sGHnRDu*Z6dGDNP@&J)w zrAdYjtl0n_ZqYD>SSLx2=cqu!6G5HITC*(`L?n2R;hqaFO{HowV?jM!;4Yv*Q26pQ+#P zvSICnmFC-ZaPNp4;H?&rnaJJjD?h8u$8D~^w-F9j8Yf`6fmRy`p!r}j@p7#%?Gjt3Kx+LLmyPi9&zz?E9_X$d+{wRvKpal``2~AdoM^ zk_1`xb^NUo47YPyIU^LTG)m&2%%*V8Qo|c!g*-TOv0Qm!ZOR4PB`TPwyzp3oK(Nvv zN1C+x2=A6@=m88_;Y4Z+1aX!5@lM^2IE@gn(gWaQFm?NKbn_fW#0=F}! zRwA0mC)~-dbkk5Cnpi2HEp3xAPnD#_(qJK?a$DXb^6D9Ed|0SZR#lZW_n)!5;OX z&60t!y`De}rWfW0xSfRnu+jjt);Hc}0fF%pAjqEYEtFJ(dOij~X<&S-Z_frOR+{72 z)mK-UH^pj0BP9=(gutyQf;eE?k-yX}j5jQF91#Xq8YA!T3CELA7!7Yo_bAgFi^Sme zNwWk5ft7|ZHST!R4Q#O~l2~bg7xj-ZAKheX^!B=J~xBF9%)c4lY4n)_7Kfs z9~cbBuB3j&cDeDCVLPrOG^{k*nZvtJFiWF~XalWF1C6IyohU$PSZTEUJLl)eLT}>> zLml$6P7AwIK;sVaCpM03bHhr5ImiDV{0nUM2H?mmh;>~=gL%s(p%Eix@{r;lj`{U2T0lBqTqmTgW7^ zzMn9PkT40+DqHU?A=W#NGt)7kQ}=OZ@~;p4yElu@EDRS+FZuNZM3*c9yg&m>f!(UVf6WlApRRyfo|D9mI*XI45&y*4VhaKes}aw;r~d zk%uIYjx8-trT2h8`->p47Kdbvd1b{qZxd*|!Enp=P{NqErk5V1@LRz@HF9Aa71rXs zj8S739N0P^`po;VT0ovdkikK?(s4e!GASTX4I&XMR+{yc%gu|aVA}xb-^nc!QA^Zg zDpd8 zw;<`Pf&nr~lmfkq5RaBf#8VOZ=)1BphLt9&qi1-kBM>pW+eo5EaK2wSS?tTaQaTXLukMEHG(aB`3vby6Hdgc-bK zjCh0%itafgG^{jQ%X^9c%pqx3gk@K9TTs2TYM?P&wz+-wMuwoU(oi4QY#DwFvSvH5 z7kQ?5+XXeDlplAi^Af>frQt&RUTtX(?XL|~ZDexDg{PkcrK`e#BAkhjNN`)Ng|0gr zWmsvj*Ro^LXCTTi0311lioK==Sn-3P{BG^m76D?V0S%U(Ts07y0kf1&cFIgoa!b*O+v+eWKT0-qG9trDlR20S_d5=aU@Mdk}EN-u@t?R*tI#wFul+$vz z=a97?!TcAw&`|rOK#0gd|0vi7#v44RgAfK*8spr|YI8n-iH%H#|*nVKu<&RmDN;-k9DztH^4ov zAwH}$Uzxav{>vaHnOCgIuDXSG>GAQr0xtQ60I|}5D%@@+2C$$v`#& zvC@ER9r9-E1weh61tl%m4vr%TsKPiRkn}K5+L>yH0I|}56O(hEGn0GFYu024dKr`& zAP?V?V8n-&=6l~fZv)(YTLPbXjZ)*|8G~tMdt-`_fpVkYY6Il^P$<)#Pc<5Fb{WFKL_;}t0 z*Pej*u+n@7J1%)ta{L8Zlo}t;%iuMW5g%5XFJtH)hmTOsXu=(P z8PQ>-=^7-r^6Uz&w;7CN$d`O;cTt;8`5Z$~z+kpd9NG{~4^mI41 z@py+kV;3MYtTb7d{Z)f^f#J-6jO=$ct<@r9Uh0AUfJz^cPI`m@vC@E+EvKAiUI=fY z09fCy^ZYY`$=8qqO&+Wte} z0901Am96v}MKw+d*;#FWhSmg2PI~*rbpSS{a@9&9Y%?Ivz|$7E`l=)j<K6fE6w;d?U_#oFt&#k2$J#DMzt9QKGoQK24ciYGp5U(nmU1t zGawAfmuefr@`UQCg?)v+h*6+H``kjXSZUaVDkn^0z@S+Q2F>1~F09bKD#4}_HZZZ$ zj34`%PGsH?*MKUE+$Vc^k6MfZUJ)PP8?j-f*_P^it%LW6HMT3T=^rQ+HlDg_UN~aI zO0$I@IQgh#wsD6`g^g#%YV|V2hLvVBksPT9?_g-8K(ZkRZLg1(1{-&=cQOZ&VWr8+ zO&UpLgn5#4B{-L)Oocj7jSLtG*HH+5QM_6TqQpv5hISb+7H*5xXbpLK2vIKF zyj+@;0*z{V9pPf7al707_|Y7Ux>LcZA=lN%6`HGU>-n+)ij}5x4f{5)66ETkFc={R z>=kaQL&@?fpDXgVM|fCiyd3L#`9GnyhJ`Jvww`!LZM>oan>+bL#UnnfG~bs#qcvuL z`Cwj+8ZN!Or#4>%H`nG0eym%u(p=RWUd(<{V%d7_p*mawUKhX6520bD(VQ2Y|HrHy zDVD9(pR0`~u{Qr?N1G%pYJt7Hd@*%IGEcA z4>}_XtTcshdQt)`duwcm3Y0vd9#dBo1sloS9B+ps4y-gsh}>UyCs^Yh%#o4Scw#D) z!&(|Fi{`b4?k+@um8Q70<4`5o_^Z(!C`fBOX(oz7i8bopMjTjaj^20mXToBp#uo63 zIZ-a=TMFdhc13ryQEXshr9VD#^G&;L(Er|7n68v|5b|+bX@svd)DKP%IfaD4F*3NA z8NCRid?&42AB2XLM$ivrU9!UZTLgFB}bHL-NbW5m{|w{B#Iq5-UlgBmtItu}@3ki#ig)PMY@0{g3 zhje2qqQOejJl}rQXD672+1^af8jo;Mkp}N@l=|7jp>b|QWv3uCtTdX*k*a1;A8J&F zEzaZ-?Pzz^(70K?Tt_TeX%_E-9_i1(VG>A1q|;LS31%rukj(ylKBpPg4`$mJR+=VZ zNdBTsuuMxh4oF(&%K+7AxGmE$6tQ5XSuz*4FQ*Ry#9Z}Awsm8PYAniM&1hOSoV5>D znyGxaqd9ZiNEeuTCU5SV<13zt_kxd3%@7J!8s(c;t!!pm?G^ML7s z*QnKq2P@4JK2<9n?#cELt!eR zC=Z-D?+_B!;z-OopMSV>1oQM>ci5y(-ZI%XLIot^iIWn1R(Pa3$w1DAGuGl%%*vj& zSLTgGs8b`ML?d6h(~41*iq~`7tq>4a8Ypx~$5D%6&v^qQ`ckEz;{^eQMujN3YWKJV zAz-Bu+@ygYx&p!rc=Uxldh%eJPy}X^gc6LaGZ6+>8l&d9%#>)rmMeVEslBY~#U7!xXg3pTZo4nF#)S?j{LBi3x+tkOL!?Um4Om0+C>)Nro8P$X@`-bO>9roRMu1 zLIQFIJl6Po3!g!@yPDA<>b8;I6yHvGAW7jq89o zu+kj&*X0gf4>oZGCy|BBhlAodl-nhK2;#v?^BmL4>(&_xtMxF(Bzf{u#q%gH9g^b^ z4_2Bd_w=Seoxwg)kY~v8<&@*%cp!B71_uYXArP!INR^l4UOq3JH6i!K>7No0;uQ%G z&_YvJerdw_EX0MC=JNk@cNMewY$!A;vbO4bMs+S_FTCFQfvB+3R5!b}%X?fRRnj@t zsn`iYo<*@&^`qEEkCmnxXi>KBY#1?Iu1!}r56_FH;!e!p9S{aq8sk*{$5RpDuHUdH zfXsubnW8b2oXf10fLO57EFri2EfSz@<-_(ik|pk@NET)g6~gy+Q}g491uM;>J?!ZM zCX}CpZOEl)`F#~wBH${SqIMQ64UvXM@|NdT*$59SjkiMAtz9@o&nk!>(p0A(s)olM zLVYTYW+NFZ&C<8d5J%?n(|(W|$(m>OOK~i2BSuMmc}~m+4?rYXX_8|-d)68Z9fk#T z7-WL(0B>+9pH2S1=3x&yNyK64gIo)6pgd8*&=8MEZ!*0F? zzOw+qV5MO`fBsnaJS3Z)Fb_b&{P?a446mb3)`@1D5Z2-_%%sGQ*8BRc2S+W3*(~yI zn414ogyC^l;he!1S<{V za^lmROh_<|!9rwxT&98$5C>+!D+y*Vyyh#r%A_I=tTe}r8~c@)az8lfhzctO6A`Nd6QAf|Uljk!e;#0;w0SrKbiB|LO?=VP}ja5mG<& z)T+{(+RLUO9;`HvQKPB{uR+ptgv%z#;62t*JP)^BOur)ztTe};Uu)Jn0LL9jzO9KB z=%>vDa|H5^x!cuS%*F^-8e!4x^%Gp69ajeTSP}@MTM0#g`3P$+8=(L^d9`r5YGgd3z)Dlx?(y?ZZKg1QD|N^TMe{DAD4?k1w#De9hyp83 zk?_>=$X{^AJZQA!7&6gX2u0CKSFZ?mtxM>VU}A+OY>;3r&c$?v7F#OxWzriAf~Z9D z!&U{Z5)4$>{cUN5K(H1EVY!?8f>;4Y+Lp)e% zp0*#4R2~E^2i9@LFT~`&5goe=l zWQ2v4#xn4q)Y}Ax0M|_ElpF0K9;<{1Ds1R)E+Y=CG{=AqldB(uZ2--nnUUtn9Vm)J z@i_v%GUnH3goTyH(#+dGh}jNQ4Z3Rbj6&JL>S8I4@=C_>Z1cxT!`ZB^7-$A?GvP7~ zvJ$Q?Q4@~ak#(#Q6jmDQ?zOzryTFlE!I9)RYNb>hRMA@wd=Bik5aD2@ajtzFT#dOC zN*lT|Z=xSf9;qr$FS%S2Ta?pPWLX=o(%HF3>wRM9083-+r^rX%xRVkH**PeAt z+3>T8rvgEkAeWZ$P+zqoy=t|a5SZNq}=(f)Hz)+C@ zL>AYB$BKecGIOc@U=7QGmF5Vzl|Q5fa4^qJkSTT61d$w3Auy9*W(UjXLOoWq>{=EM zD-D;mt?@DDOxkQ1x{~vACX-cx<91iGW{3nUO`<#Yt1Y|^uHgrBE@U39HC+@5TX8B) z2A$mz4pthcdxX#Z{ou8#kVnaz8LG_@kK-vF4a@4%qPE8}^4z;NZO8`JZCH!bF@^B@ z>c4%AA+A@$^b45;TFoyVx)K~&SQ{^mLu^=!voW>t)`hnQr$J}v2C0;sgV+}@o=s?= zC-&IFS_~^qb=cEGuOEcg<4*Lf>-_}LR3#XvuYv;A2%AJJP#a4mVI%X zL}TFLrt|l7b+FP{<*bjjjDwQTtTo;EhHO(Ai`zjns20K_9tTc`OnIoBhA((e56f4h9ilz}7&%d(~6jmB4BmGkI z4lw%sT%VpO=ygsk6t|=5w%y5^1}jY=|Fqv&55}D3U?T~6(d@;m;wTCi<&=A?`(%WK zl}4Jds^P(Ekho_+DuxT#`Xjzz=}4fb}5KZgU=%3LLlHCfD7?Mj2KbZS>wtuHC?;@V+b6 z7r%X~8k(4=7S;zLI;=F^zpuAy#RJ`9=#R;pLl(bKjSd~4fvpXNsY`j}?Olu*vC@n$ zV~$o11jchkEX=nHkLVN03pHo>>tTgJRF|qT80OoUuEVAwW)lv_YJG`uV z9buWU(oBcyyuVu(I>__T_Q)e`M|D+W5^AkM3lJGrn#{)VnUkAj8mF8P{y;I|CFxVLwQjoI?9btcx zNEdSOaR*q`5JZQSrrR?prQBr*dTld$Y%#5kSUPTs4jmt`KEz5>)T;3Dz8uCDfwky) zgbh8!Qs4?odAPsIeZf*;rKzfvT~yr=B5M^iK+<#34(d{2N^YBd)6Zt&YCw| z4s=_fxAq~r#R4al>BN_#I-L+ERvL3)%R19~!d`>wUFZx}#zj?3Zllc&d&wFND@_wx zYs>wIkSHwSI3+prxN@jC8g}OyTJz?{(U_9M;$Wq5%3Sw9G6j4X2uNgl&+=0NhnWK5 z$y8OhA{wm4X_%SD%bw=GlYs{ASfXfl`m0D&(#3OybBhhGAsVd3X_&di&VOpwa|W83 z3bvUwN<|u;tLEB#Lo`^6(=fK_I$oMF7HBdQY-1UsB27t8Ar#ui#^etGdbK{aq<=Pb4D;zMHUA!Q7SUwI-R?L`2`~= ztTfa;d8;?fRR9iPEb{uCQ?Y7739Vlummox}G~)M*5uS?yu_E+;Q=b&kzz;8tKD>DI=JZ#LNXdQp?Bmro~9Zgck~~!L@ZcomW`(@`UgUj>;)3aV2c=97G zos#E?tkYCOR0shP&4!Frixu+jv(Ei%pAA%w0&XtyN@yzh%4faCw% z5TE)W2&^P3!?`z3oUygjtJYxJ}Q*G$AO#a zf~lXdOSw*V`xhk0T0AV5NnC?;-%d!YycD~+&kl>2gKyVP`rD6aZO5CX&t za|<1B6z48Q5Lju5f`t1$wgQAHL@~K{Z2miu5Uu!HlX0bTtUs{Q9NGUGdpH3{C*UBD z1I+m#mV?_RE|U-iR+{4V=cU8HL0anqE+Huz=ZmD^$t*)QBMPiEg+ck&%{~Ezy#j^o zi%5!+W*`bT@JuW~6j*7Bj_(uNTmy?W?5Lju5G{-NMO(8gw6d?3}iG$#=#O_fD0xJ!%=xjq99e|jm01@{` z97IV|FNHyIdJ%%aN<*yb_NhE`VTfYRdh|~m1kY2G*AF8ItTaSt2lFiErW;Mj6=e6{ zwQNNp6=YH3`4a?zm4;Y6Ri{q{fLN*Ej!?h~&BbpE8TX zPZc13YKep3c^R^t1%kjzLwH|J+F}b3%p2UKJ3K3hgW!4ovHb=Fft7}sn`1X*2|zrD zm>>uHuPTXyU>>cH3V{=L?CE#q_qW(xLS$HJvMaeZ_o5+#4TU^P)`?H`#F4Qq(BbzB zj12IWc}2>3j{)}mgt)NMTrJ**#KwZf;6W^k>!`jsE}zg4nP1?@K&BYMjNE;2bPp{y zrm@mo$)Prjmchh`zbjptEi(|s#f>m&w+@Sdl}3pB_S-cPT&4>yBO`jExnP7y8FRfD zH$?2uiYx?H8lpw5_-GUGPfKW4WdG|Ahw%iAlbI}sAb1|;p534lOM#W9_+hZ9@+~mM z6oo3_j-^Nn9$Tz%L=;$Q3fIo(-@XS5=7C(&7Jpldq~Iw7w#g6$R+_@ovPSco;1OK~ zk92P*l7goWIGTVcu+kJUa+^9Iz!usH6kA}Mtf;u)DFocV>auZBqevK9xy6BFmO_1KueN<(N~aS53P5cOc$hO|Vey*LP->hP8Yg1|~cbUG9p zzYtPI7ljhlv9~w~p6W2i2SH$^A>J?Fdm#!S>=huIxrl?{sSdx6Ll9VLh{Q()<0b*b zScU5FgPS-Ap6XD0BZ9z6LzHhbt`l=5k`=@Rx$)tYr#J|AsWb@6E~k(%p4TaAWFQ=@ zG>&%rakckAiPOS^E^(s!io)TpE}G^e1gtbdvV5yq7P!O>W(mowD5FD#AUI270)1uv za!FV~psyrYz)hXLRoQ0Sx=?ALGtu=d3Ls9H+d9e3Ae$lt0R@HzN&T36OYr6*zT(Ss z52C?J(>y9Dzoa?@jJLwFbirs9X<+fhR_ZHbYcf7G-@6D6D~;Bt!GJ~G0V^8TbjZa+ z`Iu5b;|{5ae+UdK4YuECvFjk%Ojo@Ty?SCaMKv&Pmbk{%*l5B^vuuqXn^hf*B!#tT zawX@&d=*$C_;#@-McJ_j~&}WEXiT2nT+fX3Bp;JgOoxd``}7MgO#Qk*4kUr z4QPfd(41YaA`MUNbSD?lU{#=r9uUjCotg{VL&@t!2Ch<(rY&FNdZll`#tl}QXIrOj z?%N;>`9SQDzOq=SDi3!QfA5HBu+lUG4tG2;9%!yZ2Tszo-KZiBPj#m=4AEevX@+cQ z8kGmWIt5(@>8pyHRitUp=c`)N5f4_H=WkCt=lfutYYM*d+NLTGx38M-Kr~osnvr!| zIA(%%d|~SZ>8lw#RixpmKdo*e8mu%;N4ve(4uEZjf^EnHc)RziNYg6013(r8XSnj0B_7vZ=o)wwoF zEd?}guz86H3@Z)Rte4hSX5Qhy-p&F%s^e?p!Hc^)BtR+d6b%G-f_q37SV*#Av%!j& zLUDI@cbDQ$(c(}X3WeenFW-Cb06%m>HKo$%$b=pXXZ|Fs?3?Y z%On`S8s)I!92M8^TxU7w>=t~aoNwZ&l*N_m+3Z-p$$grBpGiJ-w!_TZ%xdYW=Wc86 z3p7%W)}itRKP66#L!ZhuI$sXN1X?lu(Xb~;TGi!9Io{vPw)edYycEZ&8l*4sh+AQ057!PqUKg-=Z?s$yAX`|h0CD2GYTKmySR$5@Q4t)v*gE!Rp(BEZRV+&Ilk<4zwbH^}r;+B*NzyWJ|5T z>;aJLppomX03+pKN$ErjOoFKuws^tVP*5wLEuA_vNjYDRYpaeb zA3UjCneQTs-8aXl-HBDJ2^Lb$;y3X8jpfKPD&N4BQ{c%z8e{pof6%4~nkXnpImMY& z`!6MdZ~I^>k{_>3^w}td?x{$`4go;Q0oK*@+mHwV8Jz$EzZeJ5*|7}0EdWS4z?p3o z%PLjHJu#ceSA=)ON^BtguI%H&y?r}|JM0004&_hHkwgj8D~Fr%U3%3`NjcK0N!B{b z$HEgiReTMOXB??&mjJuJrF(=WG|=MeX3x^Xf{2t8rS|K)Cnt=Q6N6jcDpX8toTx#l zrD1SHxO$;fF_gC3Zfz!bNIB2Rc5N=V1kXb7$nWy*#H--0&rC$8H4Lyjtjgzuv_X#c z6Ck7rA!df~c1LcoC-OXYOM%%SB`wA3N zjxs3g>@7A#=BWK}+;OU4A7w$%nc5M-pB zY{Z3(!8F6jGv0q?+#u^|GdSaoOPWn}ds5D`dDZOjGH`kC@A+5YHieQbU*w>RglC(bd(PycHs!l^$J8XNVqq04%(e_;+0?_m+(qz_a=z@{)>*g0f{) z_2XB`#tA@D4%lN@oMKjQVzE8WZ&Yu(6Q^C(t>rndIlDi!`HT2rFgm2aZAeK5}mz0xhkx70G%qQ z1-pmD2%I)r2Y-P^%F&8u%+P)Z?1pcivgJ!=yXR=ib6MJK-TMeOQqHzzcF`^+v3x<= znFW&y5uULrt7JMI*5(^LU+|G~zFm29{gf8nsw5KRCH#$Ep7CM&(#D!_RA7;EtV=IS z*WClGB=9!*C7NdaJj9~MICW;zh0g>XDW_{zc;LrQa5yE`A=3>Q97A+E>8g$Ca;qbi zl+y(+oiIt+Al^Xfro5VO@Jr0lY4_{F3WAN4vnB4=|HftvhYX0l^3*VDlxJ)hrLITA z`5=Ku%JEvf+P`=s@J7Jx{H4Xos&O9T(amMokoQLlNKy{D{GIp5`tZJsSfj}I9?ncM z0a+_leZD(tA*B=S{@ozRNI6-9Os_9L09i?=32ewz6J+&m4&@tN(mGh%_2OR@aHJg0 z@$czdB@u=97v$F-|Cr%EoHj@LSl;UJB;_0xHJEs%iW^Dr~>QA zZ-d5LZV;my`{KJcOxJ?~hLpo}jh%GB)S8;oA?z1Cp#1)O4}^XbsPazpKsrm8 zBGUyBDF^y<`|N`u-vmnhn|UCeI~Kls1rR9*iZyoL@NWZM*lixDg!Z6o{FeYCwO$*IMk)ENXk_btX59!>!=$I_8>eQqhs86#D+mt%{l88@ooqh0r(?Htx2`?#d zNIA}=s@-3H2m7?d7?YpE$bHxhj`c zBCLvV@iH(#<5V*8LA^yQ1Qls?D&;cQq}Ox1#KkL>tMMGT{G!W<z@O%^-npdUkh}{Ho)U^7h-*d)KQV`bBwBMs7dl4a4p0#JbZ~ z(LO0}e{ZLI8v@aO9?Vj5`y*}{ZeJ&~-5e*{C*|!QE}pl6vWYF=)PC8!hTGSPWY4#X z_DOmB`Ob~$)*tOB!?=(WN{{awZl8)Os#}9`_tg@FMUGe!>$*nD_&=zwLCVpZM9kio z99YV`V{(S@%)=N!(;hRq3JNe%4%T#Y;Tg(nt~MO=$kEO3nI~Y{L{)zhM5LT(NXUgV z%GbnuV?!@*8~VR7Ol08M%VPo~C{j6wSH_9?av_+cg+s}+(A1CaVMLv<>Me~O&jk)C z$0;0dc}3-FW(!P;atbERXTvz;)2ek8$0jrB7oYx;zJTi7q@1l+x0^rSfSHzKlP;$Z z7JDTzwt@)v)?w53r6m?YM#{-L?1nR*Hs zQVuh#wAaW>2ve=F=8$)#g^&?7w0aNs#zj=Stq0CKBMSqtlcRy~^|4f-IgeY4=>4)P+>9Cgntb%*)u& zju@~7F+iT@8s{)fFiMD&Z@Q%1Qnd0MKD zE4`8R(q35g8B)%5FiGx-*WfcfG1JQNIZF{wxwLyP_6$Kq%Bcz@&H3vMjQ8#s?=n@( z;vQ1zjQG_11QjW#`f<|6q6a~A8|z3pGEOh)8I`uBN+d6$_8%!{>N9tcPdhMmbGrTb z+mD8sqQ8{nqCTKnDZxX^dB$z-cR~5+ZyWfNY@?o)Oz}iIx}J|WZ7Y~aIa8Yg!x#F& zMlBHw3tYX(Ih1fF3Ia5-CS&zPWRq zq%hKCWXfeDm8fkPiJkQ5hs>$(1raGHDz)j$t}qyBo6~eQx4wHsx*P3fIf|+yjFe;C z+z?vp6%eXmKPyjX9UHlcq3tloLIngVho~_=dy6(1aJi)!k|9zeYDsgW5ZbN(y-T!C z%3H5rKjr9+IA2PMkSy<9>xLO>-5OdipjSh?)n>OkdaDoE>5b=)cLfe9$5}S~b=HyS zkv-T`$hFh0x|_vu`9^)>#KlxMA>~lP?Y{)zm1nPUc-lc8Kh=Ahg{o=MTgVq|DTqip z(STONUamopDHYxFB-($FS)zJa)caY&1GRmr!azYq%Bd0;`StA!Ob*MC*p*XiV}3SE zW$;PF`bz~GDMu?e`f%>!IEy=v(|36r_F$w*G;KQ#$WmPOCsGbGBH{Y(N;T{#*h)@* zC!B2vCbEV|o8Z5eK=MI5x^i4iUK#+2XJTI%otpbQT z81FK~`UUPm=q&tv{}m9V9AeU!Su3jp!ruwPZ?St2I=S$lCzMyagOo!oJk|;C zKeu>07+(4bYZp1v)nDr#hta(u zM9PVV#@$oCFNmIkNS-)vY%@b-sGjXXUjaqRq3(q=E%X>rXRxc1Cxo59nSwH2#rAfg zKqKX7JNm`zrabILVlaZgC#w7FEY!EqwcXF*@W3aZ!K81vS1{hkf{NBJ1t8T61$Qt`A25}oO)+h##R%1KhsDA=zGMig#T zv0Bnb#kDS?qS_0f6-yXMfah!IYz~)q&hDt=ZL7i ztz%g@i~}t4);rG)_c)MyqmZoc!>8s7BvOvl+;_(E?(iI?SXQpN+Kp6`fsA|PQZL+F zLejQT%JP*}8Q>0mXVkXh zkw=1%loJjt<$qjBaV~%r<>4AXzNds=!>%^pr4&`v0YS?7?#>*uX9oBRIfauq-^Cc8 z&LsZ6o!}$oe05GFTJQjT2c7snCXO*ao$YACp@NT;^R3@{DE$)fRRdq3G)n3vk1;-H z=hUBRGp!cTq#U}^v0pwu26S#j!2k)`k?Ma6t?j4z&kJNyj-2jUi^_i@a974+uDyhO zBklhXSsS=cuBz(5BIUp%w;g!C8FS#mEPNg;lPRWvwdvZ_5_F`T&hq2@%E}9rz2LU; zEZsb}dvwtc&5T~_4ha)JL%AgoWuURa)`d*q23I&I7Kn=05yIolrZ`^S{^ z*L4JR`6@-KA3S7peVu#GeE~UbcHj;7RB zmuzT#brxukF@WVhEmzDuTJ(j)H`pR8toIZbY^2fIlnQJ6mbn=$@Hfrj#K1%wo2tZC)2jr?LmTzlyeO(wP<`3SZp}XlI3jG z#46^w^b={3otf&bKqKX7rS5IsTM}rAu_lz?T&Q2e12hBav`E0**{Z1{fiyax;%$o$ z&OJ8-5oD@U4(oXx_W)f748LH(Ldsdbi@mW@c8to-m$AJj1Z1OQ8i7Z z%`vrbb=5&gIY-;(OKK=j^Z3C*&} z4uOlT=CMTrgOp?ZwlVG0X~3w6b*g;oW$)@HhPExPoDdMC9O6URRsT_dxQ!tqr=?nl zx(7j3pf22_z}On9dysOV%rA=+836a#i+Mq=>GQL@2UIQC5@HE;xTtNeuto5Ya-KAa z(>$ID17$!j$#1J?k1)%l-CgbC)>N%S%4x1w3Tj#mG|KlSg~Q>sG_RyTMXp;L~zCy37#wxM&Tb#9`edmGwsi5-CTz|8QLT zy+AtUH11;$^8iWPv#aN=t$H>o2ddF7Y~2C?eT0qV+aTHT2!_G@ILs369oV}LeU z=LkVY%E@Ldtk*~R7Ec$vb14@_Nl zZ*IxqwYjGMEx1TI*NoFY?7e{nbN>8%i8F78TU^=*JId5ieTbAJEJ&GPsyBQ{`6R7; zq;YbYF$9P59nq@60pa0IY_;$PU;v)BP|L5ip^mo~P^27cc*7D`rU7UmY$Ff;#w$I7 z(nh*AR3MRZqb}i5n(s-;jPE31qdkzDZXjRKNSJe5<7Z% zI!n9R5C|S@2(NCnhdW$<1T0?l`l|Dga+U&n`sAtr7JsnFbpR{38)m5+U<4)mjfN@; zDMv~7s$>e~ZTk4w@V0>#%x4t*FOjxFc& zhMshbtX60s9!3eUEAdg?m{;o+XbID}`X9L|{wY-x)xk(P+^ytO=FEYM7b(Jbg7MC{ z1E+1C#>twg1f-l`yl>fun^E)p06+3TdvVhUL0CXww}8%;g4WPZHf@R@i?&cHNIAu= zYK^C-hWi}Dk6dE+?v@b>`YvSTN0+rh>a-9bq#Wc+#Rk79pE=%uu_bTKJKQk@5**;@ zWV4586SNs12uL|W#=B)pKS7?dnm2zsxXlA21bB+Nv(DE_f|rQqNqO_rX4_sLK`$tm zxMTxNd}X+K-BQ?oCj|j1CrG$?O8h)nY)(T;RDO(M*&E{o+8r<_b4%41NqPH?cO9>K z8Uf=3rXP9xo$0fo_AQ+wf&=V$Jjr409AS$H$7)lh zZDO&9SVIGXUC>Rj2s%K6jY>~s_3&cqy7bz^1h+$`w5DBMy2ihN3RMdQqFY!?84jmu}MFk zjbB!3TgoJpHq4b+ZPbBC%3+GNm~k;1f`hMA13k+IVY>W}gXCQ{Cn@k6~q zOEKpa#GEJRpxagRgh|^mLJTRU<;MKz3MrSgP70LLDxme7)3d z)iFuRVJkLHG74{;dS&(D$>284JcrdD1#N#6T%?@q$AI1kOJQZ)DF;t_hITa1r8^dS zj}B5zMaq%(b*`DXA|}I@IEI(kqjB(xnd<|F$PaiK&V3HwBzQ|;m_f3kZfT6ewPA?Y*r0!z~#MaYajSEebQ)FK1uZ04Hl!L_SIjya7$XW#pJ2_*& zq_6uR)vcD`Ab2jaGupO!cU&Nma-=>NiY-;@1cEa2l7-R(-A2;J$e1xi?IKc+F|u#% zg>T?0eK6(9B@0J~8^bX0Hh%3f0)mu7)I5_e@B+H0FYF;W~D_}@DOog>W3hV{U8^Fj> z{lg4%FuuL4I)^5w4+|br&hy9TGK;36V_qPyEuSK#n`??kd$8X6N1%{$l;KzEG*K=; z3;>Q?{T6SDVHA2_QFrPMnQB)(mNYtvvJ7qX`uk;NKynDvog7f#EHg}^ejdVM#S~LL z0$+~Dr%=D?H<9bl{<{SdX>=rI{W(4;UW?O+WXloBGu~ZMwa!1RW`-t2ue$u`zI; z-dKOjWrUlyxJ{>xadwcvAmtcohOGUmCk!+i>sq zAU$?;|6O_Q`~=)aK1>VP?+!>atEHzl#mm!zf|OI_T71#=5NqClt?#ceWzHpZNG_~n<>W}8 z>xNp#;eD{hVGE5q5^$A+FA*$=NI6lx5o1mUf#ykSK3lK7X`V>iLe(Y;9#YOTJkil& zYhj@*V3ISDw!h5rD0z61i`1rS9?@IvH&Ra3``fUj`svM-8<9XtEiJO68Ho~1eVJH6JK8Nm(sCG;XQuj z*?CRE?}B%Xumc+jy}Bh`*0Y44bGF!tWS)cR z?0c`|6JVqqtowJHPAl(;pFn7qzn6ABg~wppj{bK8fkn!(_HTVND=P;75iCXJOnPV< z6Ic!H7Naiqv4Ky32zgR(lVv$1$VfTakE>evDBo06p0$>3HY95dkm-CTrN9$GM#{-nzD|Ck5y;9pk(J32 z17td1eyWgqlo~NeIa$1()w)l|z-*2szg!XjESKkG+9R`FfZ!tKT(?Wl>i-_rDvs5z zoGpEl$4xG6hyiN_1SyC3*sAU2pAb%`z(DeTs8m7Y5LniJeI#8QX52*qL&{-R$7|-N zWEPZj4|$82sIXfwx^wcp&w_%KQ+(IxNYM~b)OMnnThvVoofx#bbX{l~RKwNUg}%>ED)flS-`PB>&aF%yoCVU?b&h{|^2$q4MQ}V_>T0g8Rort8>W2H zOnHAz-lGkx?*>C;frvIo$+m)nlymI8|E%zP1ivL1V{!uVyGHJFgnKKmB3nX(kQdRd zfr!krRv#khNI9LOeVqYHRoi-4Nv7-OA47CH@u~AUK}X8zsx6$IZ57r>Bh&LS_)D{x zq0{cyUvrFA{fm^do!|20*fxy8WQbaFt=9CmX4s5e6D+iJoXSMXnNC%`o+c2z83tdI zcfRWbOfYF1r_w0_Ldro35BvAdPB?uwgmpPFVGS}4f*g(N;~{!+yhE1ps!d2a%HWmF ztN)6ADu!4o*WCWp$v8?AyTxK;yoFU2G^CuS;HEvfyqB+yuB#q8qW5G5-L&|CD z{&c*0YWU4ur=EK2FiE4czu0(F(2#PPK1)+hQ!;&}5Dn%1MNlu3G`>MW^=v`-e5zhi z$btA1)X_!CxpF>#{$V<}PJ^qNv=YholSwYz+X%8MXR86h2moq@nrqJU1qCN5=iGSV z>W2^LO}y31?r{9j-y|o61J`iz779304%d40x{bvV6rKW3J_sIzuWq_73yUm$iXNis z+k$k;pwb-|K%^Wf_L~W9mCunzpjYL>?QFwL0;!)^wz#%c-WLLml%vf$Q-5!Bpw$GL zd>JRs2$N{Wy{vSGiRx$|-5sSEjkGzQcmQPu)HHZ+#HY6vt3JaT){Np=HDg) zpmM)M-SO$3>R3k$K2pxN{=@LN{~|`@cZv}c7I?;IU`y3|lYk@TaA~gme)B5e@Ubmc zWb|T*c{pwN8gWhVkaC`a3%mDM>S>hg>he-E?@D)g)PhYtubLTqk~-!{IY_d{o3yug0HE`vu z@^FDg%CSzw8u2Oztdt51Px(Q+`@22HqE6KF@qkMLkdy;nTx32jg({k)hErZHyDuP5i;ec zSmqz|5KG%ui^2sIDTg}NHCvY>u$A({s=8`XYk0XG`&9XKKh7PqG#GmnwzR<#v=d;Y9Bjd)UIluf z@1~>gmEM_(6l>n^*sSb%E9(6uJpkHFgupg^2D7qk;h=#Sf`3jR~?;{ zV_n>nV7@;lqu-n^d)!NE3QHU1W=nxW%2C?Q_~3sEUX>DFC6Bo=X-uJrC7?Et*D?V_ z%7N}ScvMm?;es#8N4VS5n*vfoz3S$!XU7z$1sf@6Tac>khXZh@n@;ZZb7s%jbSKE1 z{|YQpjVPSuE`iEShzO>fEH9W@pcr_x<2e%Q4l+WA4}7?$fBD z6Ek%%9;QQjSsTm0o4_LFSotbX2(ARI0l<$BUj-xjS#HmRqtd!&$%LNTl6ob zU0Ns*NjYMxKAqOw0pbWC%B$WRHDVA^+s7Ur7l5Q3@UMVM_mo<$Cb)+s=ZOl|i7`NJ zymv1I9x2Cbv35wyrLbQc#09x*>0v|9@m$BPgc)b4LzI;BHC%M2vGP<&Z}7>*FdzM6 zici~m87m7qQcm|*#&+wTV&JC1o=YCMv6_2C=i-sI{GA0CDd$>vKiM_qeO6yQ1}&e+ z`M2?i%g9t+Zj68<<#2gNx0vu2aFZ}1)kIv5PkG{Nv z)TBI6S9S3i%XQ66aGcrdKp^FK<&renb_|<}O2}}@6`5T_Ji@~QTH9#-@(U_bPL=U; zU^(Sk(2uy+Bkx)#J3OO`{I01s+UQ0Cjg+GmJ3DIYHMkj;e++F+KhM#^_1@E)(@UU{ za^BRoRXUGCpXGe;erq@1eMjvbpa z!PzciB9N!4!?=KL;2b^LqRl({3Jz4RW5jfhzXRNgO?96)@3kCD?yAyZkyUVB@IEr5u6r`Nu<)9^*yCapVJQh_<%8zGUX@o+g zP?ZCAZH6X!=Bi_mlrv;_dEvr#v_Be4#ex#U)m4TWw41lo6U~$I=C6I6Rjm{PQztYp zXOnNNHQao-H+?Tj-xd)L0Yl1R{uy3s(pK1_4Q3d5yC1UA4Vb7K{`xdSX9^lpPV=$i zyOR$=^E3QZe(0tD7B^_3-HUKpqB3>AKqBQxMb^ErO#qT|Xec8c+U^OG&cW)^M*@kI zBP9&ET7EK+7C0eo+2sk6PWkV)6!X*}Maq%>^WM@cKLTK8OdRq;WyKy(kQ8^)jm$?& z3oud+Hum>L&5I!)Ivt-4m-E_X4|)KmJ^HV-6F{UKXkndBoqM74HlXulpra?<1q!o; zTU-#bX_5IoxIDMea1YH%Z^KYUSN@OtolvIR~?54ITzPQq=OuJ(7{~qiM)U)et}%`)d5Dz+fU`Qp_{Vco(%^1 zKtA3bL+#rGLc^7BD_DY}VzsN+SjyKDOr+77lxMj<@1OR35}16@P4f5UZTCE4iWa{$ z9`lKOr7Lu|AS8`WsJznkWSu=o`5;&)?1kkz+U|dOLa5!31MUkVQcg7ZMUi@aV6)BG z1IUl69e-+!$YQAy5N-)_Iqt_MS)h6pDJSur{GhP~B&|UrAB48)DW@noVCsk&*bWxNen{SaY{_GUBKju?X{c+{ zRNoVGL6bL`^D(J8L zhKRxu1Dn|VaXCD+v+JjxdlnWrq#UPL*CNBV0p}s+R5^RKxu6l8=2*_Fj}KXblyVHz zh%~XOH5s@!*297qU3H%%`n8#$Bjt2Ulm7DR9q4i*2FV$sOGRRaPTRGn^%HEQoUPCK zl=m9L$>)Pjj*X>DxX-4|v3!x>ApOdLW4lTD{cwOC^;hnw+y~NDUVoO>#PZ7EwYBIoDhwFZS*@YB_J34@O|g37*`3esP5q3K`swptx+D0G_QqI#k^M*LTVnpS2DlnW{))-G{sLc`Jumsgax;ofmuWk+1 z{mkC+m%=cl9OzTK8tbpYK+5f6c~#iAk};rg8HL|o}k#}1o1~L_aJmK zP8-rLRlS0gL;ROAXFTOefPwG~*%Ddnx(A_?V>(b?K#+2XT{F`5i32P2LkN{2zOU~d zgwDsF<#V>GJrsYSi_nwI!l9Ow}oeW__i|1G{VcCQr-&to<+oa7V6^N7rrGI&URC>TX z!;c)s7I!uTE@z2->@(|*rR-yq`BRy`w5QAlSJdB9HLhLdLfO`4a$92d5A2vxqztB+hI|^#_Sj1 z2&fer7NJwU@@S{PAmtcdecF8J1`Hc8Fo2EimJ8{Fyb27%73UVeZe zAms$*v*ulP3j}GgrIc+jvacHiI#YVxC4zvI6ReK-aclt)Omwor_5p4X=sXb9_M{*n z!p7lL`jO*g@XJ%Cdp{yWZITlH%_!q%G>XhZECVF2wf?hoaXUt z7wuQ=5@0tFJoauC1f-l`c(b%ks=#gQI|Yw2^V}fN2_9!}2m(@0kUZYp_%%VGoFK?U z_vivQ2y}wSop{?+FCgUvWv7fgToeRDoO+?%VmAnMg2&4Of`F70#A!37=R6GCyLq@D z{<+jRfwmvUX(HMu@x?W6D>Mb6fmS5W}i=@l*&u?d(cJlDcbb|=3wesLU7{fY9ZRwBDhF7 zSNQb-598s?(Hpag{M_N+hfHy459VQ`1PUofd9%4&?$0ohlI6%BwJlOM^3_ioK+#=` zZjZG?^%YXy_JEPT4>Q4W%R03^^0cA0bzI|kKG8NQZ+qjt#Iq{kk?WCodMlswd;fFR zNZZ;LzuG{wOv+oXIBQw^WN^qG7_M^o47=~D<=}|$E-u37;~t`UQr`Ui@*8p!Ay$W>=$+({ zfFR`%pQr5E9fDps<DQnElECL1W~)^^eXf{wM%QIl#vnkCMGd$pzQYtIyX2KLE=U?%!fg?D zBoXyi*suQ*?UVBM3#Ln%uq3R|1!bWHq`;jwz0vlye|ySnlYVX8IgOqzs&yrez9frY z>!B8hlt+)abxa+2q{D0MR{#99J&{MB{O*?qS8)2a7q>-a$GhXQy_&Xghi_<5LtF&X z{)K0RiiSx!K)1kbH~PZdV-c6-!S`JrSHG|V;2&lQbn$5Nipc_jlp~yIQ0ZJl1VIO; zE4gCnj~`qi)Pmvhax=b=6b`p*VzFC-Y_)Vp;?7-yhLqEku5je~?-}s1t0LSW{R+E9 zqunPb?g|7_j_~51&-*r*x5qeD{Y|Us8bJvL7KfiLB)}S49|1v|<4Msys#B73jvP5h z1u0SS4u0gdbj@b2IE;nGpzUIqkaB`#CzE9834~`uW3k~;tGO$JCc#0Gp;0FrL*tY5 zD}Zx6@R8y{(!{BCmMvj+Whrm%VUf#w3dOykTAXxBq2u2S3u$J5Zg&Z50=y5xcJ>X8 zHe1DJ3$~y_-8=Fh)YC3s7dJqOhxDsCM7VlZHs5LshH4S8$rYF*QyVl#6jxnKFKeK! zvppcJi#0GHxT-BAEC7eYdgo6|nhJA~a=c>KcRg;6^Kx(OeC6d#>-28oX^)z%eFX$5 zhsbu~*O0Za&udIza>-+YoJJvVI*E>>GfG#z_UMHmBIQKm`o3sz7)1D>6C1~AzITU6 z+a~WboKXFkloNQjF4%Pk2wpkaBwta31WJxS+*|p(Ax}%K_>8lp}bxDZfjJjkgdR2oyx67SW{g{;V ztZ3s?sXhAZJ21)birD+R!(*biUUn2{q#SKrt)c0zAuwjd`dr>El^N^?ns#5s9w7io zIY5tHeTymUALm)4!x)1Ab#0-Y!@W%yC-r*4M#|ZyR=H6AH2UnN(;QoHf_rQrG~`LS zFAE}4PW0rjB*T`VyVg0)W36VmL!{kbCB6s(QciH>bdyTkuzPugANdfo{t|-(#x^q5 z@|;o!6)6XKnY#1CYsjdSgE{0)CHY(W7u+JZ#G*uU6~agHss|xp0q}f{Bzf-Kwzlr)}u7CvahT zei*#XEhgZmS;RlT(SUZPWf|UJ)sg7Hg;m`>gv^wfOp|+*AmlhnPoMZf`G#5v~QdT6?x=EG_J86)kX=u0+ zTh+7$E5}0(BkY#i0X+hY>|Kww6Y!)Q{$hg9bCoY4_#z7?!~b&je*%wRHK3E_E4p6N z_UbPJo|MC{FFf`8g#bT+td&)={Dt%XFYwwqS}(*S`HbMnO*5q0BuTdj5>ig`^We1=TEk|3uvuft zW`pm$Nn(0Al$OXyPs`tnYqqemunMeAS#5sqUJ<3{`SygI|kYlm>IWcG+NH)SW=7?cO#1QJs^N7{0dsotJWBz02i! zv$n%Edc*Yc+b3PzYCGyJrY;txeye(f1F`lSeGqwpop4B_V=4C~yB7&;as$yd3_(iv z*dg!SF$rN+>tzW<|JXvCbV1E}kiW&=!y0JOe^0kVZ_$0EoYCgvomn|~i;pobPxR+L z#w6o6tQdK>y!$*sNXiN8_O=%Ih*R1QnCxZ3D*weGp-$b?gr|a#loQ6TK49&ia6jcU zrShA)E4|X_q|Vf_7R~kb`&rw93({UxhY2a?i!-Zwkr4P`5j<8Xf5GQ*CQ+L`a%^hbu5^STB;|w`PnEZB!ty39>?hyH+)=~~VN|ft zMyfeWAdzyUvu6gEcm>ywjlHORzI3vvCrIi;Uh4Otwb@!85NxEJ?eMrB$K!%)8s6}d zYw_}x^ngtps87nv>VPEWKv|Pca}0yAen*^;({#ftxCP{}g;)c1j{8TH5g?=-WXprt z$riwg%3~19<^7h*?toMc2o6>Yne{f+GusOoQV!E#=r9Ls0^ zGZO=$1|N~PUl5~}cXQ+=%9C)nkkrJdvYzaSiw4@=cqrR7b;Oc#o@Gx@*LngI4T6c} z#bk{L_jzL0Co^(aQ{qPA1?%us|W@C?9<8q|6Ky<+i(w z68k4JC^{GKfBOBp+CiioWlKbwUfqGBe4a^0ar85TqH_a()GL8P%2DpzDz|JsmO@K0 zb;~H_2bw|AdB>y5{2QuONI6RGqVLB~MdxJ0s!T@l8)62fl=cYnKPpg2Im(p_kAh6XnwCYPp>^&XM#@KOz-Op5K<1Z z`o*6Q(;-+?K(J^n?Qi-VatEY#P&eV-zCi(DxbK9jCYJ4v{1ge=7EgEhX55$Nnd<+IB5o@~(8z*%>Yc*klJSyl)lQckqcFK-#;HGnCI9db1Lbj}l^CIR6(>+&9F z1r;f$DmQ*e&}7(X0X$7U_PKS@eJXc0RYTtiGEz==g@-+T_ef=uU$4p<{#L_ z5)=_^2{N27nVS8c>i47^abTiGnJ>Wazrc8MPBY6@cM$90JJPs#=3OHKnLBL{TUuS< zkaC(F_k9>?gEzSJo0Vs`4cWj!t zs6Zv#nOg`PQjYUJw9DAv5YV3DN4{r% zIi5Q>#%=`cyYWEnM^a9cIV^$w1IB0~3<=pd&*Hm7Lub|g%Io>s#yJ=7FBONB|-XXSMdqqr`N?E;(^_H?eyl4u@{_LuCH*mA~L2 zhy{q-oe}H_@XF*8H33uI@QjT`0&cqHDpuNEeki&hRlJ22dLy?)VN5JFsYVaawA!`m%UQf!g x+Lm3Mb09+fVyDk8J}u<|mQJY@75bAltP>C85Th~f%((ey$M*WYBCbq({U1%L!7l&+ literal 0 HcmV?d00001 diff --git a/src/main/java/jline/AnsiWindowsTerminal.java b/src/main/java/jline/AnsiWindowsTerminal.java new file mode 100644 index 0000000..a638036 --- /dev/null +++ b/src/main/java/jline/AnsiWindowsTerminal.java @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2009 the original author(s). + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * MODIFICATIONS: methods to deal with wrapping the output stream. + */ + +package jline; + +import org.fusesource.jansi.AnsiConsole; +import org.fusesource.jansi.AnsiOutputStream; +import org.fusesource.jansi.WindowsAnsiOutputStream; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; + +/** + * ANSI-supported {@link WindowsTerminal}. + * + * @since 2.0 + */ +public class AnsiWindowsTerminal + extends WindowsTerminal +{ + private final boolean ansiSupported = detectAnsiSupport(); + + @Override + public OutputStream wrapOutIfNeeded(OutputStream out) { + return wrapOutputStream(out); + } + + /** + * Returns an ansi output stream handler. We return whatever was + * passed if we determine we cannot handle ansi based on Kernel32 calls. + * + * @return an @{link AltWindowAnsiOutputStream} instance or the passed + * stream. + */ + private static OutputStream wrapOutputStream(final OutputStream stream) { + String os = System.getProperty("os.name"); + if( os.startsWith("Windows") ) { + // On windows we know the console does not interpret ANSI codes.. + try { + return new WindowsAnsiOutputStream(stream); + } catch (Throwable ignore) { + // this happens when JNA is not in the path.. or + // this happens when the stdout is being redirected to a file. + } + // Use the ANSIOutputStream to strip out the ANSI escape sequences. + return new AnsiOutputStream(stream); + } + return stream; + } + + private static boolean detectAnsiSupport() { + AnsiConsole.systemInstall(); // CraftBukkit - install Windows JNI library + OutputStream out = AnsiConsole.wrapOutputStream(new ByteArrayOutputStream()); + try { + out.close(); + } + catch (Exception e) { + // ignore; + } + return out instanceof WindowsAnsiOutputStream; + } + + public AnsiWindowsTerminal() throws Exception { + super(); + } + + @Override + public boolean isAnsiSupported() { + return ansiSupported; + } + + @Override + public boolean hasWeirdWrap() { + return false; + } +} diff --git a/src/main/java/jline/internal/TerminalLineSettings.java b/src/main/java/jline/internal/TerminalLineSettings.java new file mode 100644 index 0000000..b4b2409 --- /dev/null +++ b/src/main/java/jline/internal/TerminalLineSettings.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 2002-2007, Marc Prud'hommeaux. All rights reserved. + * + * This software is distributable under the BSD license. See the terms of the + * BSD license in the documentation provided with this software. + */ + +package jline.internal; + +import java.io.ByteArrayOutputStream; +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.text.MessageFormat; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Provides access to terminal line settings via stty. + * + * @author Marc Prud'hommeaux + * @author Dale Kemp + * @author Jason Dillon + * @author Jean-Baptiste Onofré + * @since 2.0 + */ +public final class TerminalLineSettings +{ + public static final String JLINE_STTY = "jline.stty"; + + public static final String DEFAULT_STTY = "stty"; + + public static final String JLINE_SH = "jline.sh"; + + public static final String DEFAULT_SH = "sh"; + + private String sttyCommand; + + private String shCommand; + + private String config; + + private long configLastFetched; + + public TerminalLineSettings() throws IOException, InterruptedException { + sttyCommand = Configuration.getString(JLINE_STTY, DEFAULT_STTY); + shCommand = Configuration.getString(JLINE_SH, DEFAULT_SH); + config = get("-a"); + configLastFetched = System.currentTimeMillis(); + + Log.debug("Config: ", config); + + // sanity check + if (config.length() == 0) { + throw new IOException(MessageFormat.format("Unrecognized stty code: {0}", config)); + } + } + + public String getConfig() { + return config; + } + + public void restore() throws IOException, InterruptedException { + set("sane"); + } + + public String get(final String args) throws IOException, InterruptedException { + return stty(args); + } + + public void set(final String args) throws IOException, InterruptedException { + stty(args); + } + + /** + *