From ef58a94bf31868c4b53218474f0be04c1cd93d97 Mon Sep 17 00:00:00 2001 From: Lorenz Date: Wed, 17 Aug 2022 03:05:34 +0200 Subject: moving packets around --- .../at/hannibal2/skyhanni/ItemRenderBackground.kt | 47 -- .../java/at/hannibal2/skyhanni/SkyHanniMod.java | 47 +- .../java/at/hannibal2/skyhanni/bazaar/BazaarApi.kt | 59 --- .../skyhanni/bazaar/BazaarBestSellMethod.kt | 79 --- .../at/hannibal2/skyhanni/bazaar/BazaarData.kt | 3 - .../hannibal2/skyhanni/bazaar/BazaarDataGrabber.kt | 113 ---- .../hannibal2/skyhanni/bazaar/BazaarOrderHelper.kt | 87 ---- .../java/at/hannibal2/skyhanni/chat/ChatFilter.kt | 301 ----------- .../java/at/hannibal2/skyhanni/chat/ChatManager.kt | 51 -- .../at/hannibal2/skyhanni/chat/NewChatFilter.kt | 18 - .../at/hannibal2/skyhanni/chat/PlayerChatFilter.kt | 90 ---- .../skyhanni/chat/PlayerMessageChannel.kt | 10 - .../skyhanni/damageindicator/BossFinder.kt | 569 --------------------- .../hannibal2/skyhanni/damageindicator/BossType.kt | 70 --- .../skyhanni/damageindicator/DamageCounter.kt | 10 - .../damageindicator/DamageIndicatorManager.kt | 544 -------------------- .../skyhanni/damageindicator/EntityData.kt | 22 - .../skyhanni/damageindicator/EntityResult.kt | 8 - .../skyhanni/damageindicator/OldDamage.kt | 4 - .../java/at/hannibal2/skyhanni/data/ApiData.kt | 90 ++++ .../java/at/hannibal2/skyhanni/data/HypixelData.kt | 106 ++++ .../skyhanni/data/ItemRenderBackground.kt | 47 ++ .../at/hannibal2/skyhanni/data/ScoreboardData.kt | 48 ++ .../at/hannibal2/skyhanni/data/repo/RepoManager.kt | 172 +++++++ .../at/hannibal2/skyhanni/data/repo/RepoUtils.kt | 102 ++++ .../skyhanni/diana/GriffinBurrowFinder.kt | 159 ------ .../skyhanni/dungeon/DungeonBossMessages.kt | 51 -- .../skyhanni/dungeon/DungeonChatFilter.kt | 224 -------- .../hannibal2/skyhanni/dungeon/DungeonCleanEnd.kt | 130 ----- .../at/hannibal2/skyhanni/dungeon/DungeonData.kt | 46 -- .../skyhanni/dungeon/DungeonDeathCounter.kt | 97 ---- .../dungeon/DungeonHighlightClickedBlocks.kt | 99 ---- .../skyhanni/dungeon/DungeonMilestoneDisplay.kt | 96 ---- .../skyhanni/events/PlayerSendChatEvent.kt | 2 +- .../skyhanni/events/RepositoryReloadEvent.kt | 2 +- .../hannibal2/skyhanni/features/ButtonOnPause.kt | 51 ++ .../skyhanni/features/CurrentPetDisplay.kt | 47 ++ .../skyhanni/features/ExpBottleOnGroundHider.kt | 19 + .../skyhanni/features/SummoningSoulsName.kt | 135 +++++ .../skyhanni/features/anvil/AnvilCombineHelper.kt | 82 +++ .../skyhanni/features/bazaar/BazaarApi.kt | 59 +++ .../features/bazaar/BazaarBestSellMethod.kt | 79 +++ .../skyhanni/features/bazaar/BazaarData.kt | 3 + .../skyhanni/features/bazaar/BazaarDataGrabber.kt | 113 ++++ .../skyhanni/features/bazaar/BazaarOrderHelper.kt | 87 ++++ .../hannibal2/skyhanni/features/chat/ChatFilter.kt | 301 +++++++++++ .../skyhanni/features/chat/ChatManager.kt | 51 ++ .../skyhanni/features/chat/NewChatFilter.kt | 18 + .../skyhanni/features/chat/PlayerChatFilter.kt | 90 ++++ .../skyhanni/features/chat/PlayerMessageChannel.kt | 10 + .../features/damageindicator/BossFinder.kt | 569 +++++++++++++++++++++ .../skyhanni/features/damageindicator/BossType.kt | 70 +++ .../features/damageindicator/DamageCounter.kt | 10 + .../damageindicator/DamageIndicatorManager.kt | 544 ++++++++++++++++++++ .../features/damageindicator/EntityData.kt | 22 + .../features/damageindicator/EntityResult.kt | 8 + .../skyhanni/features/damageindicator/OldDamage.kt | 4 + .../skyhanni/features/diana/GriffinBurrowFinder.kt | 159 ++++++ .../features/dungeon/DungeonBossMessages.kt | 51 ++ .../skyhanni/features/dungeon/DungeonChatFilter.kt | 224 ++++++++ .../skyhanni/features/dungeon/DungeonCleanEnd.kt | 130 +++++ .../skyhanni/features/dungeon/DungeonData.kt | 46 ++ .../features/dungeon/DungeonDeathCounter.kt | 97 ++++ .../dungeon/DungeonHighlightClickedBlocks.kt | 99 ++++ .../features/dungeon/DungeonMilestoneDisplay.kt | 96 ++++ .../skyhanni/features/fishing/SeaCreature.kt | 18 + .../features/fishing/SeaCreatureManager.kt | 64 +++ .../fishing/SeaCreatureMessageShortener.kt | 24 + .../features/fishing/TrophyFishMessages.kt | 71 +++ .../features/items/HideNotClickableItems.kt | 416 +++++++++++++++ .../features/items/ItemDisplayOverlayFeatures.kt | 121 +++++ .../skyhanni/features/items/VanillaItemManager.kt | 53 ++ .../items/abilitycooldown/ItemAbilityCooldown.kt | 215 ++++++++ .../items/abilitycooldown/WitherImpactDetection.kt | 74 +++ .../nether/ashfang/AshfangFreezeCooldown.kt | 43 ++ .../nether/ashfang/AshfangNextResetCooldown.kt | 53 ++ .../at/hannibal2/skyhanni/fishing/SeaCreature.kt | 18 - .../skyhanni/fishing/SeaCreatureManager.kt | 64 --- .../fishing/SeaCreatureMessageShortener.kt | 24 - .../skyhanni/fishing/TrophyFishMessages.kt | 71 --- .../skyhanni/inventory/anvil/AnvilCombineHelper.kt | 83 --- .../skyhanni/items/HideNotClickableItems.kt | 416 --------------- .../skyhanni/items/ItemDisplayOverlayFeatures.kt | 121 ----- .../hannibal2/skyhanni/items/VanillaItemManager.kt | 54 -- .../items/abilitycooldown/ItemAbilityCooldown.kt | 215 -------- .../items/abilitycooldown/WitherImpactDetection.kt | 74 --- .../java/at/hannibal2/skyhanni/misc/ApiData.kt | 90 ---- .../at/hannibal2/skyhanni/misc/ButtonOnPause.kt | 51 -- .../hannibal2/skyhanni/misc/CurrentPetDisplay.kt | 47 -- .../skyhanni/misc/ExpBottleOnGroundHider.kt | 19 - .../java/at/hannibal2/skyhanni/misc/HypixelData.kt | 106 ---- .../at/hannibal2/skyhanni/misc/ScoreboardData.kt | 48 -- .../hannibal2/skyhanni/misc/SummoningSoulsName.kt | 135 ----- .../misc/nether/ashfang/AshfangFreezeCooldown.kt | 43 -- .../nether/ashfang/AshfangNextResetCooldown.kt | 53 -- .../skyhanni/mixinhooks/GuiContainerHook.kt | 61 --- .../mixinhooks/NetHandlerPlayClientHook.kt | 9 - .../skyhanni/mixinhooks/NetworkManagerHook.kt | 10 - .../skyhanni/mixinhooks/RenderItemHook.kt | 33 -- .../skyhanni/mixinhooks/RenderManagerHook.kt | 25 - .../render/BlockRendererDispatcherHook.kt | 25 - .../skyhanni/mixins/hooks/GuiContainerHook.kt | 61 +++ .../mixins/hooks/NetHandlerPlayClientHook.kt | 9 + .../skyhanni/mixins/hooks/NetworkManagerHook.kt | 10 + .../skyhanni/mixins/hooks/RenderItemHook.kt | 33 ++ .../skyhanni/mixins/hooks/RenderManagerHook.kt | 25 + .../hooks/render/BlockRendererDispatcherHook.kt | 25 + .../transformers/MixinNetHandlerPlayClient.java | 2 +- .../mixins/transformers/MixinNetworkManager.java | 2 +- .../mixins/transformers/MixinRenderItem.java | 2 +- .../mixins/transformers/MixinRenderManager.java | 2 +- .../mixins/transformers/gui/MixinGuiContainer.java | 2 +- .../java/at/hannibal2/skyhanni/repo/RepoManager.kt | 172 ------- .../java/at/hannibal2/skyhanni/repo/RepoUtils.kt | 102 ---- .../at/hannibal2/skyhanni/utils/LorenzUtils.kt | 2 +- 115 files changed, 5189 insertions(+), 5184 deletions(-) delete mode 100644 src/main/java/at/hannibal2/skyhanni/ItemRenderBackground.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/bazaar/BazaarApi.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/bazaar/BazaarBestSellMethod.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/bazaar/BazaarData.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/bazaar/BazaarDataGrabber.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/bazaar/BazaarOrderHelper.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/chat/ChatFilter.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/chat/ChatManager.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/chat/NewChatFilter.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/chat/PlayerChatFilter.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/chat/PlayerMessageChannel.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/damageindicator/BossFinder.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/damageindicator/BossType.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/damageindicator/DamageCounter.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/damageindicator/DamageIndicatorManager.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/damageindicator/EntityData.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/damageindicator/EntityResult.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/damageindicator/OldDamage.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/data/ApiData.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/data/ItemRenderBackground.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/data/ScoreboardData.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/data/repo/RepoUtils.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/diana/GriffinBurrowFinder.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/dungeon/DungeonBossMessages.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/dungeon/DungeonChatFilter.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/dungeon/DungeonCleanEnd.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/dungeon/DungeonData.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/dungeon/DungeonDeathCounter.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/dungeon/DungeonHighlightClickedBlocks.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/dungeon/DungeonMilestoneDisplay.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/ButtonOnPause.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/CurrentPetDisplay.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/ExpBottleOnGroundHider.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/SummoningSoulsName.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/anvil/AnvilCombineHelper.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarBestSellMethod.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarData.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataGrabber.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarOrderHelper.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/chat/ChatManager.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/chat/NewChatFilter.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/chat/PlayerChatFilter.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/chat/PlayerMessageChannel.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossFinder.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossType.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageCounter.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageIndicatorManager.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/damageindicator/EntityData.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/damageindicator/EntityResult.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/damageindicator/OldDamage.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/diana/GriffinBurrowFinder.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonBossMessages.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonData.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonHighlightClickedBlocks.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestoneDisplay.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreature.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureMessageShortener.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/fishing/TrophyFishMessages.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/items/HideNotClickableItems.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/items/ItemDisplayOverlayFeatures.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/items/VanillaItemManager.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/items/abilitycooldown/ItemAbilityCooldown.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/items/abilitycooldown/WitherImpactDetection.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/fishing/SeaCreature.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/fishing/SeaCreatureManager.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/fishing/SeaCreatureMessageShortener.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/fishing/TrophyFishMessages.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/inventory/anvil/AnvilCombineHelper.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/items/HideNotClickableItems.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/items/ItemDisplayOverlayFeatures.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/items/VanillaItemManager.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/items/abilitycooldown/ItemAbilityCooldown.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/items/abilitycooldown/WitherImpactDetection.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/misc/ApiData.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/misc/ButtonOnPause.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/misc/CurrentPetDisplay.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/misc/ExpBottleOnGroundHider.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/misc/HypixelData.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/misc/ScoreboardData.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/misc/SummoningSoulsName.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/misc/nether/ashfang/AshfangFreezeCooldown.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/misc/nether/ashfang/AshfangNextResetCooldown.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/mixinhooks/GuiContainerHook.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/mixinhooks/NetHandlerPlayClientHook.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/mixinhooks/NetworkManagerHook.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/mixinhooks/RenderItemHook.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/mixinhooks/RenderManagerHook.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/mixinhooks/render/BlockRendererDispatcherHook.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiContainerHook.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetHandlerPlayClientHook.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetworkManagerHook.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/mixins/hooks/RenderItemHook.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/mixins/hooks/RenderManagerHook.kt create mode 100644 src/main/java/at/hannibal2/skyhanni/mixins/hooks/render/BlockRendererDispatcherHook.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/repo/RepoManager.kt delete mode 100644 src/main/java/at/hannibal2/skyhanni/repo/RepoUtils.kt (limited to 'src/main/java') diff --git a/src/main/java/at/hannibal2/skyhanni/ItemRenderBackground.kt b/src/main/java/at/hannibal2/skyhanni/ItemRenderBackground.kt deleted file mode 100644 index bd30ed597..000000000 --- a/src/main/java/at/hannibal2/skyhanni/ItemRenderBackground.kt +++ /dev/null @@ -1,47 +0,0 @@ -package at.hannibal2.skyhanni - -import at.hannibal2.skyhanni.events.RenderRealOverlayEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraft.client.Minecraft -import net.minecraft.client.gui.Gui -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.item.ItemStack -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class ItemRenderBackground { - - companion object { - - val map = mutableMapOf() - val mapTime = mutableMapOf() - - var ItemStack.background: Int - get() { - if (System.currentTimeMillis() > mapTime.getOrDefault(this, 0) + 100) return -1 - return map.getOrDefault(this, -1) - } - set(value) { - map[this] = value - mapTime[this] = System.currentTimeMillis() - } - } - - - @SubscribeEvent - fun renderOverlayLol(event: RenderRealOverlayEvent) { - val stack = event.stack - if (LorenzUtils.inSkyblock) { - if (stack != null) { - val color = stack.background - if (color != -1) { - GlStateManager.pushMatrix() - GlStateManager.translate(0f, 0f, 110 + Minecraft.getMinecraft().renderItem.zLevel) - val x = event.x - val y = event.y - Gui.drawRect(x, y, x + 16, y + 16, color) - GlStateManager.popMatrix() - } - } - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java index 848d45421..c614cba01 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java @@ -1,27 +1,34 @@ package at.hannibal2.skyhanni; -import at.hannibal2.skyhanni.bazaar.BazaarApi; -import at.hannibal2.skyhanni.bazaar.BazaarBestSellMethod; -import at.hannibal2.skyhanni.bazaar.BazaarOrderHelper; -import at.hannibal2.skyhanni.chat.ChatFilter; -import at.hannibal2.skyhanni.chat.ChatManager; -import at.hannibal2.skyhanni.chat.NewChatFilter; -import at.hannibal2.skyhanni.chat.PlayerChatFilter; import at.hannibal2.skyhanni.config.Features; import at.hannibal2.skyhanni.config.gui.commands.Commands; -import at.hannibal2.skyhanni.damageindicator.DamageIndicatorManager; -import at.hannibal2.skyhanni.dungeon.*; -import at.hannibal2.skyhanni.fishing.SeaCreatureManager; -import at.hannibal2.skyhanni.fishing.SeaCreatureMessageShortener; -import at.hannibal2.skyhanni.fishing.TrophyFishMessages; -import at.hannibal2.skyhanni.inventory.anvil.AnvilCombineHelper; -import at.hannibal2.skyhanni.items.HideNotClickableItems; -import at.hannibal2.skyhanni.items.ItemDisplayOverlayFeatures; -import at.hannibal2.skyhanni.items.abilitycooldown.ItemAbilityCooldown; -import at.hannibal2.skyhanni.misc.*; -import at.hannibal2.skyhanni.misc.nether.ashfang.AshfangFreezeCooldown; -import at.hannibal2.skyhanni.misc.nether.ashfang.AshfangNextResetCooldown; -import at.hannibal2.skyhanni.repo.RepoManager; +import at.hannibal2.skyhanni.data.ApiData; +import at.hannibal2.skyhanni.data.HypixelData; +import at.hannibal2.skyhanni.data.ItemRenderBackground; +import at.hannibal2.skyhanni.data.ScoreboardData; +import at.hannibal2.skyhanni.data.repo.RepoManager; +import at.hannibal2.skyhanni.features.ButtonOnPause; +import at.hannibal2.skyhanni.features.CurrentPetDisplay; +import at.hannibal2.skyhanni.features.ExpBottleOnGroundHider; +import at.hannibal2.skyhanni.features.SummoningSoulsName; +import at.hannibal2.skyhanni.features.anvil.AnvilCombineHelper; +import at.hannibal2.skyhanni.features.bazaar.BazaarApi; +import at.hannibal2.skyhanni.features.bazaar.BazaarBestSellMethod; +import at.hannibal2.skyhanni.features.bazaar.BazaarOrderHelper; +import at.hannibal2.skyhanni.features.chat.ChatFilter; +import at.hannibal2.skyhanni.features.chat.ChatManager; +import at.hannibal2.skyhanni.features.chat.NewChatFilter; +import at.hannibal2.skyhanni.features.chat.PlayerChatFilter; +import at.hannibal2.skyhanni.features.damageindicator.DamageIndicatorManager; +import at.hannibal2.skyhanni.features.dungeon.*; +import at.hannibal2.skyhanni.features.fishing.SeaCreatureManager; +import at.hannibal2.skyhanni.features.fishing.SeaCreatureMessageShortener; +import at.hannibal2.skyhanni.features.fishing.TrophyFishMessages; +import at.hannibal2.skyhanni.features.items.HideNotClickableItems; +import at.hannibal2.skyhanni.features.items.ItemDisplayOverlayFeatures; +import at.hannibal2.skyhanni.features.items.abilitycooldown.ItemAbilityCooldown; +import at.hannibal2.skyhanni.features.nether.ashfang.AshfangFreezeCooldown; +import at.hannibal2.skyhanni.features.nether.ashfang.AshfangNextResetCooldown; import at.hannibal2.skyhanni.test.LorenzTest; import com.google.gson.Gson; import com.google.gson.GsonBuilder; diff --git a/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarApi.kt b/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarApi.kt deleted file mode 100644 index cbebe951c..000000000 --- a/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarApi.kt +++ /dev/null @@ -1,59 +0,0 @@ -package at.hannibal2.skyhanni.bazaar - -import at.hannibal2.skyhanni.utils.LorenzUtils - -class BazaarApi { - - companion object { - private val bazaarMap = mutableMapOf() - - fun isBazaarInventory(inventoryName: String): Boolean { - if (inventoryName.contains(" ➜ ") && !inventoryName.contains("Museum")) return true - if (BazaarOrderHelper.isBazaarOrderInventory(inventoryName)) return true - - return when (inventoryName) { - "Your Bazaar Orders" -> true - "How many do you want?" -> true - "How much do you want to pay?" -> true - "Confirm Buy Order" -> true - "Confirm Instant Buy" -> true - "At what price are you selling?" -> true - "Confirm Sell Offer" -> true - "Order options" -> true - - else -> false - } - } - - fun getCleanBazaarName(name: String): String { - if (name.endsWith(" Gemstone")) { - return name.substring(6) - } - if (name.startsWith("§")) { - return name.substring(2) - } - - return name - } - - fun getBazaarDataForName(name: String): BazaarData { - if (bazaarMap.containsKey(name)) { - val bazaarData = bazaarMap[name] - if (bazaarData != null) { - return bazaarData - } - LorenzUtils.error("Bazaar data is null for item '$name'") - } - throw Error("no bz data found for name '$name'") - } - - fun isBazaarItem(name: String): Boolean { - val bazaarName = getCleanBazaarName(name) - return bazaarMap.containsKey(bazaarName) - } - } - - init { - BazaarDataGrabber(bazaarMap).start() - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarBestSellMethod.kt b/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarBestSellMethod.kt deleted file mode 100644 index 56c264312..000000000 --- a/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarBestSellMethod.kt +++ /dev/null @@ -1,79 +0,0 @@ -package at.hannibal2.skyhanni.bazaar - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.GuiContainerEvent -import at.hannibal2.skyhanni.utils.GuiRender.renderString -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.NumberUtil -import net.minecraft.client.gui.inventory.GuiChest -import net.minecraft.inventory.ContainerChest -import net.minecraftforge.client.event.GuiScreenEvent -import net.minecraftforge.fml.common.eventhandler.EventPriority -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class BazaarBestSellMethod { - - companion object { - private var textToRender = "" - } - - @SubscribeEvent - fun onBackgroundDrawn(event: GuiContainerEvent.CloseWindowEvent) { - textToRender = "" - } - - @SubscribeEvent - fun onGuiDrawEvent(event: GuiScreenEvent.DrawScreenEvent.Post) { - if (!isEnabled()) return - textToRender = getNewText(event) - } - - private fun getNewText(event: GuiScreenEvent.DrawScreenEvent.Post): String { - try { - if (event.gui !is GuiChest) return "" - val chest = (event.gui as GuiChest).inventorySlots as ContainerChest - - val inv = chest.lowerChestInventory ?: return "" - - val buyInstantly = inv.getStackInSlot(10) - if (buyInstantly == null || buyInstantly.displayName != "§aBuy Instantly") return "" - val bazaarItem = inv.getStackInSlot(13) ?: return "" - var name = bazaarItem.displayName - name = BazaarApi.getCleanBazaarName(name) - val data = BazaarApi.getBazaarDataForName(name) - - var having = 0 - for (slot in chest.inventorySlots) { - if (slot == null) continue - if (slot.slotNumber == slot.slotIndex) continue - if (slot.stack == null) continue - val stack = slot.stack - val displayName = stack.displayName - if (BazaarApi.getCleanBazaarName(displayName) == name) { - having += stack.stackSize - } - } - - if (having <= 0) return "" - - val totalDiff = (data.buyPrice - data.sellPrice) * having - val result = NumberUtil.format(totalDiff.toInt()) - - return "§b$name§f sell difference: §e$result coins" - } catch (e: Error) { - e.printStackTrace() - return "" - } - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - fun renderOverlay(event: GuiScreenEvent.BackgroundDrawnEvent) { - if (!isEnabled()) return - - SkyHanniMod.feature.bazaar.bestSellMethodPos.renderString(textToRender) - } - - private fun isEnabled(): Boolean { - return LorenzUtils.inSkyblock && SkyHanniMod.feature.bazaar.bestSellMethod - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarData.kt b/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarData.kt deleted file mode 100644 index 01300e67c..000000000 --- a/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarData.kt +++ /dev/null @@ -1,3 +0,0 @@ -package at.hannibal2.skyhanni.bazaar - -data class BazaarData(val apiName: String, val itemName: String, val sellPrice: Double, val buyPrice: Double) \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarDataGrabber.kt b/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarDataGrabber.kt deleted file mode 100644 index 1f2f1171a..000000000 --- a/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarDataGrabber.kt +++ /dev/null @@ -1,113 +0,0 @@ -package at.hannibal2.skyhanni.bazaar - -import at.hannibal2.skyhanni.utils.APIUtil -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.round -import kotlin.concurrent.fixedRateTimer - -internal class BazaarDataGrabber(private var bazaarMap: MutableMap) { - - companion object { - private val itemNames = mutableMapOf() - - private var lastData = "" - var lastTime = 0L - var blockNoChange = false - var currentlyUpdating = false - } - - private fun loadItemNames(): Boolean { - currentlyUpdating = true - try { - val itemsData = APIUtil.getJSONResponse("https://api.hypixel.net/resources/skyblock/items") - for (element in itemsData["items"].asJsonArray) { - val jsonObject = element.asJsonObject - val name = jsonObject["name"].asString - val id = jsonObject["id"].asString - itemNames[id] = name - } - currentlyUpdating = false - return true - } catch (e: Throwable) { - e.printStackTrace() - LorenzUtils.error("Error while trying to read bazaar item list from api: " + e.message) - currentlyUpdating = false - return false - } - } - - fun start() { - fixedRateTimer(name = "skyhanni-bazaar-update", period = 1000L) { - if (!LorenzUtils.inSkyblock) { - return@fixedRateTimer - } - - if (currentlyUpdating) { - LorenzUtils.error("Bazaar update took too long! Error?") - return@fixedRateTimer - } - - if (itemNames.isEmpty()) { - if (!loadItemNames()) { - return@fixedRateTimer - } - } - checkIfUpdateNeeded() - } - } - - private fun checkIfUpdateNeeded() { - if (lastData != "") { - if (System.currentTimeMillis() - lastTime > 9_000) { - blockNoChange = true - } else { - if (blockNoChange) { - return - } - } - } - - currentlyUpdating = true - updateBazaarData() - currentlyUpdating = false - } - - private fun updateBazaarData() { - val bazaarData = APIUtil.getJSONResponse("https://api.hypixel.net/skyblock/bazaar") - if (bazaarData.toString() != lastData) { - lastData = bazaarData.toString() - lastTime = System.currentTimeMillis() - } - - val products = bazaarData["products"].asJsonObject - - for (entry in products.entrySet()) { - val apiName = entry.key - - if (apiName == "ENCHANTED_CARROT_ON_A_STICK") continue - if (apiName == "BAZAAR_COOKIE") continue - - val itemData = entry.value.asJsonObject - - val itemName = itemNames.getOrDefault(apiName, null) - if (itemName == null) { - LorenzUtils.error("Bazaar item name is null for '$apiName'! Restart to fix this problem!") - continue - } - - val sellPrice: Double = try { - itemData["sell_summary"].asJsonArray[0].asJsonObject["pricePerUnit"].asDouble.round(1) - } catch (e: Exception) { - 0.0 - } - val buyPrice: Double = try { - itemData["buy_summary"].asJsonArray[0].asJsonObject["pricePerUnit"].asDouble.round(1) - } catch (e: Exception) { - 0.0 - } - - val data = BazaarData(apiName, itemName, sellPrice, buyPrice) - bazaarMap[itemName] = data - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarOrderHelper.kt b/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarOrderHelper.kt deleted file mode 100644 index eec055253..000000000 --- a/src/main/java/at/hannibal2/skyhanni/bazaar/BazaarOrderHelper.kt +++ /dev/null @@ -1,87 +0,0 @@ -package at.hannibal2.skyhanni.bazaar - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.GuiContainerEvent -import at.hannibal2.skyhanni.utils.ItemUtils.getLore -import at.hannibal2.skyhanni.utils.LorenzColor -import at.hannibal2.skyhanni.utils.RenderUtils.highlight -import net.minecraft.client.gui.inventory.GuiChest -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.inventory.ContainerChest -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import org.lwjgl.opengl.GL11 - -class BazaarOrderHelper { - - companion object { - fun isBazaarOrderInventory(inventoryName: String): Boolean = when (inventoryName) { - "Your Bazaar Orders" -> true - "Co-op Bazaar Orders" -> true - else -> false - } - } - - @SubscribeEvent - fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { - if (!SkyHanniMod.feature.bazaar.orderHelper) return - if (event.gui !is GuiChest) return - val guiChest = event.gui - val chest = guiChest.inventorySlots as ContainerChest - val inventoryName = chest.lowerChestInventory.displayName.unformattedText.trim() - - if (!isBazaarOrderInventory(inventoryName)) return - val lightingState = GL11.glIsEnabled(GL11.GL_LIGHTING) - GlStateManager.disableLighting() - GlStateManager.color(1f, 1f, 1f, 1f) - - out@ for (slot in chest.inventorySlots) { - if (slot == null) continue - if (slot.slotNumber != slot.slotIndex) continue - if (slot.stack == null) continue - - val stack = slot.stack - val displayName = stack.displayName - val isSelling = displayName.startsWith("§6§lSELL§7: ") - val isBuying = displayName.startsWith("§a§lBUY§7: ") - if (!isSelling && !isBuying) continue - - val text = displayName.split("§7: ")[1] - val name = BazaarApi.getCleanBazaarName(text) - val data = BazaarApi.getBazaarDataForName(name) - val buyPrice = data.buyPrice - val sellPrice = data.sellPrice - - val itemLore = stack.getLore() - for (line in itemLore) { - if (line.startsWith("§7Filled:")) { - if (line.endsWith(" §a§l100%!")) { - slot highlight LorenzColor.GREEN - continue@out - } - } - } - for (line in itemLore) { - if (line.startsWith("§7Price per unit:")) { - var text = line.split(": §6")[1] - text = text.substring(0, text.length - 6) - text = text.replace(",", "") - val price = text.toDouble() - if (isSelling) { - if (buyPrice < price) { - slot highlight LorenzColor.GOLD - continue@out - } - } else { - if (sellPrice > price) { - slot highlight LorenzColor.GOLD - continue@out - } - } - - } - } - } - - if (lightingState) GlStateManager.enableLighting() - } -} diff --git a/src/main/java/at/hannibal2/skyhanni/chat/ChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/chat/ChatFilter.kt deleted file mode 100644 index 7efbf2ff6..000000000 --- a/src/main/java/at/hannibal2/skyhanni/chat/ChatFilter.kt +++ /dev/null @@ -1,301 +0,0 @@ -package at.hannibal2.skyhanni.chat - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class ChatFilter { - - @SubscribeEvent - fun onChatMessage(event: LorenzChatEvent) { - if (!LorenzUtils.isOnHypixel) return - - val blockReason = block(event.message) - if (blockReason != "") { - event.blockedReason = blockReason - } - } - - private fun block(message: String): String = when { - message.startsWith("§aYou are playing on profile: §e") -> "profile"//TODO move into own class - lobby(message) && SkyHanniMod.feature.chat.hypixelHub -> "lobby" - empty(message) && SkyHanniMod.feature.chat.empty -> "empty" - warping(message) && SkyHanniMod.feature.chat.warping -> "warping" - welcome(message) && SkyHanniMod.feature.chat.welcome -> "welcome" - guild(message) && SkyHanniMod.feature.chat.others -> "guild" - killCombo(message) && SkyHanniMod.feature.chat.others -> "kill_combo" - bazaarAndAHMiniMessages(message) && SkyHanniMod.feature.chat.others -> "bz_ah_minis" - watchdogAnnouncement(message) && SkyHanniMod.feature.chat.others -> "watchdog" - slayer(message) && SkyHanniMod.feature.chat.others -> "slayer" - slayerDrop(message) && SkyHanniMod.feature.chat.others -> "slayer_drop" - uselessDrop(message) && SkyHanniMod.feature.chat.others -> "useless_drop" - uselessNotification(message) && SkyHanniMod.feature.chat.others -> "useless_notification" - party(message) && SkyHanniMod.feature.chat.others -> "party" - money(message) && SkyHanniMod.feature.chat.others -> "money" - winterIsland(message) && SkyHanniMod.feature.chat.others -> "winter_island" - uselessWarning(message) && SkyHanniMod.feature.chat.others -> "useless_warning" - friendJoin(message) && SkyHanniMod.feature.chat.others -> "friend_join" - annoyingSpam(message) && SkyHanniMod.feature.chat.others -> "annoying_spam" - - - else -> "" - } - - //TODO split into others - private fun annoyingSpam(message: String): Boolean { - if (message.matchRegex("§7Your Implosion hit (.*) for §r§c(.*) §r§7damage.")) return true - if (message.matchRegex("§7Your Molten Wave hit (.*) for §r§c(.*) §r§7damage.")) return true - if (message == "§cThere are blocks in the way!") return true - if (message == "§aYour Blessing enchant got you double drops!") return true - if (message == "§cYou can't use the wardrobe in combat!") return true - if (message == "§6§lGOOD CATCH! §r§bYou found a §r§fFish Bait§r§b.") return true - if (message == "§6§lGOOD CATCH! §r§bYou found a §r§aGrand Experience Bottle§r§b.") return true - if (message == "§6§lGOOD CATCH! §r§bYou found a §r§aBlessed Bait§r§b.") return true - if (message == "§6§lGOOD CATCH! §r§bYou found a §r§fDark Bait§r§b.") return true - if (message == "§6§lGOOD CATCH! §r§bYou found a §r§fLight Bait§r§b.") return true - if (message == "§6§lGOOD CATCH! §r§bYou found a §r§aHot Bait§r§b.") return true - if (message == "§6§lGOOD CATCH! §r§bYou found a §r§fSpooky Bait§r§b.") return true - - return false - } - - private fun friendJoin(message: String): Boolean { - return when { - message.matchRegex("§aFriend > §r(.*) §r§e(joined|left).") -> { - true - } - else -> false - } - - } - - private fun uselessNotification(message: String): Boolean { - return when { - message == "§eYour previous §r§6Plasmaflux Power Orb §r§ewas removed!" -> true - - message == "§aYou used your §r§6Mining Speed Boost §r§aPickaxe Ability!" -> true - message == "§cYour Mining Speed Boost has expired!" -> true - message == "§a§r§6Mining Speed Boost §r§ais now available!" -> true - - else -> false - } - } - - private fun uselessWarning(message: String): Boolean = when { - message == "§cYou are sending commands too fast! Please slow down." -> true//TODO prevent in the future - message == "§cYou can't use this while in combat!" -> true - message == "§cYou can not modify your equipped armor set!" -> true - message == "§cPlease wait a few seconds between refreshing!" -> true - message == "§cThis item is not salvageable!" -> true//prevent in the future - message == "§cPlace a Dungeon weapon or armor piece above the anvil to salvage it!" -> true - message == "§cWhoa! Slow down there!" -> true - message == "§cWait a moment before confirming!" -> true - message == "§cYou need to be out of combat for 3 seconds before opening the SkyBlock Menu!" -> true//TODO prevent in the future - - else -> false - } - - private fun uselessDrop(message: String): Boolean { - when { - message.matchRegex("§6§lRARE DROP! §r§aEnchanted Ender Pearl (.*)") -> return true - - message.matchRegex("§6§lRARE DROP! §r§fCarrot (.*)") -> return true - message.matchRegex("§6§lRARE DROP! §r§fPotato (.*)") -> return true - - message.matchRegex("§6§lRARE DROP! §r§9Machine Gun Bow (.*)") -> return true - message.matchRegex("§6§lRARE DROP! §r§5Earth Shard (.*)") -> return true - message.matchRegex("§6§lRARE DROP! §r§5Zombie Lord Chestplate (.*)") -> return true - } - - return false - } - - private fun winterIsland(message: String): Boolean = when { - message.matchRegex(" §r§f☃ §r§7§r(.*) §r§7mounted a §r§fSnow Cannon§r§7!") -> true - - else -> false - } - - private fun money(message: String): Boolean { - if (isBazaar(message)) return true - if (isAuctionHouse(message)) return true - - return false - } - - private fun isAuctionHouse(message: String): Boolean { - if (message == "§b-----------------------------------------------------") return true - if (message == "§eVisit the Auction House to collect your item!") return true - - return false - } - - private fun isBazaar(message: String): Boolean { - if (message.matchRegex("§eBuy Order Setup! §r§a(.*)§r§7x (.*) §r§7for §r§6(.*) coins§r§7.")) return true - if (message.matchRegex("§eSell Offer Setup! §r§a(.*)§r§7x (.*) §r§7for §r§6(.*) coins§r§7.")) return true - if (message.matchRegex("§cCancelled! §r§7Refunded §r§6(.*) coins §r§7from cancelling buy order!")) return true - if (message.matchRegex("§cCancelled! §r§7Refunded §r§a(.*)§r§7x (.*) §r§7from cancelling sell offer!")) return true - - return false - } - - private fun party(message: String): Boolean { - if (message == "§9§m-----------------------------") return true - if (message == "§9§m-----------------------------------------------------") return true - - return false - } - - private fun slayerDrop(message: String): Boolean { - //Revenant - if (message.matchRegex("§b§lRARE DROP! §r§7\\(§r§f§r§9Revenant Viscera§r§7\\) (.*)")) return true - if (message.matchRegex("§b§lRARE DROP! §r§7\\(§r§f§r§7(.*)x §r§f§r§9Foul Flesh§r§7\\) (.*)")) return true - if (message.matchRegex("§b§lRARE DROP! §r§7\\(§r§f§r§9Foul Flesh§r§7\\) (.*)")) return true - if (message.matchRegex("§6§lRARE DROP! §r§5Golden Powder (.*)")) return true - if (message.matchRegex("§9§lVERY RARE DROP! §r§7\\(§r§f§r§2(.*) Pestilence Rune I§r§7\\) (.*)")) { - LorenzUtils.debug("check regex for this blocked message!") - return true - } - if (message.matchRegex("§5§lVERY RARE DROP! §r§7\\(§r§f§r§5Revenant Catalyst§r§7\\) (.*)")) return true - if (message.matchRegex("§5§lVERY RARE DROP! §r§7\\(§r§f§r§9Undead Catalyst§r§7\\) (.*)")) return true - - //Enderman - if (message.matchRegex("§b§lRARE DROP! §r§7\\(§r§f§r§7(.*)x §r§f§r§aTwilight Arrow Poison§r§7\\) (.*)")) return true - if (message.matchRegex("§9§lVERY RARE DROP! §r§7\\(§r§fMana Steal I§r§7\\) (.*)")) return true - if (message.matchRegex("§5§lVERY RARE DROP! §r§7\\(§r§f§r§5Sinful Dice§r§7\\) (.*)")) return true - if (message.matchRegex("§9§lVERY RARE DROP! §r§7\\(§r§f§r§9Null Atom§r§7\\) (.*)")) return true - if (message.matchRegex("§9§lVERY RARE DROP! §r§7\\(§r§f§r§5Transmission Tuner§r§7\\) (.*)")) return true - if (message.matchRegex("§9§lVERY RARE DROP! §r§7\\(§r§fMana Steal I§r§7\\) (.*)")) return true - if (message.matchRegex("§9§lVERY RARE DROP! §r§7\\(§r§f§r§5◆ Endersnake Rune I§r§7\\) (.*)")) return true - if (message.matchRegex("§d§lCRAZY RARE DROP! §r§7\\(§r§f§r§fPocket Espresso Machine§r§7\\) (.*)")) return true - if (message.matchRegex("§5§lVERY RARE DROP! §r§7\\(§r§f§r§5◆ End Rune I§r§7\\) (.*)")) return true - - return false - } - - private fun slayer(message: String): Boolean { - //start - if (message.matchRegex(" §r§5§lSLAYER QUEST STARTED!")) return true - if (message.matchRegex(" §5§l» §7Slay §c(.*) Combat XP §7worth of (.*)§7.")) return true - - //end - if (message.matchRegex(" §r§a§lSLAYER QUEST COMPLETE!")) return true - if (message == " §r§6§lNICE! SLAYER BOSS SLAIN!") return true - if (message.matchRegex(" §r§e(.*)Slayer LVL 9 §r§5- §r§a§lLVL MAXED OUT!")) return true - if (message.matchRegex(" §r§5§l» §r§7Talk to Maddox to claim your (.*) Slayer XP!")) return true - - - if (message == "§eYou received kill credit for assisting on a slayer miniboss!") return true - - if (message == "§e✆ Ring... ") return true - if (message == "§e✆ Ring... Ring... ") return true - if (message == "§e✆ Ring... Ring... Ring... ") return true - - return false - } - - private fun watchdogAnnouncement(message: String): Boolean = when { - message == "§4[WATCHDOG ANNOUNCEMENT]" -> true - message.matchRegex("§fWatchdog has banned §r§c§l(.*)§r§f players in the last 7 days.") -> true - message.matchRegex("§fStaff have banned an additional §r§c§l(.*)§r§f in the last 7 days.") -> true - message == "§cBlacklisted modifications are a bannable offense!" -> true - else -> false - } - - private fun bazaarAndAHMiniMessages(message: String): Boolean = when (message) { - "§7Putting item in escrow...", - "§7Putting goods in escrow...", - "§7Putting coins in escrow...", - - //Auction House - "§7Setting up the auction...", - "§7Processing purchase...", - "§7Claiming order...", - "§7Processing bid...", - "§7Claiming BIN auction...", - - //Bazaar - "§7Submitting sell offer...", - "§7Submitting buy order...", - "§7Executing instant sell...", - "§7Executing instant buy...", - - //Bank - "§8Depositing coins...", - "§8Withdrawing coins..." -> true - else -> false - } - - private fun killCombo(message: String): Boolean { - //§a§l+5 Kill Combo §r§8+§r§b3% §r§b? Magic Find - return when { - message.matchRegex("§.§l\\+(.*) Kill Combo §r§8\\+(.*)") -> true - message.matchRegex("§cYour Kill Combo has expired! You reached a (.*) Kill Combo!") -> true - else -> false - } - } - - private fun lobby(message: String): Boolean = when { - //player join - message.matchRegex("(.*) §6joined the lobby!") -> true - message.matchRegex(" §b>§c>§a>§r (.*) §6joined the lobby!§r §a<§c<§b<") -> true - - //mystery box - message.matchRegex("§b✦ §r(.*) §r§7found a §r§e(.*) §r§bMystery Box§r§7!") -> true - message.matchRegex("§b✦ §r(.*) §r§7found (a|an) §r(.*) §r§7in a §r§aMystery Box§r§7!") -> true - - //prototype - message.contains("§r§6§lWelcome to the Prototype Lobby§r") -> true - message == " §r§f§l➤ §r§6You have reached your Hype limit! Add Hype to Prototype Lobby minigames by right-clicking with the Hype Diamond!" -> true - - //hypixel tournament notifications - message.contains("§r§e§6§lHYPIXEL§e is hosting a §b§lBED WARS DOUBLES§e tournament!") -> true - message.contains("§r§e§6§lHYPIXEL BED WARS DOUBLES§e tournament is live!") -> true - - //other - message.contains("§aYou are still radiating with §bGenerosity§r§a!") -> true - else -> false - } - - private fun guild(message: String): Boolean = when { - message.matchRegex("§2Guild > (.*) §r§e(joined|left).") -> true - message.matchRegex("§aYou earned §r§2(.*) GEXP §r§afrom playing SkyBlock!") -> true - message.matchRegex("§aYou earned §r§2(.*) GEXP §r§a\\+ §r§e(.*) Event EXP §r§afrom playing SkyBlock!") -> true - message == "§b§m-----------------------------------------------------" -> true - else -> false - } - - private fun welcome(message: String): Boolean = message == "§eWelcome to §r§aHypixel SkyBlock§r§e!" - - private fun warping(message: String): Boolean = when { - message.matchRegex("§7Sending to server (.*)\\.\\.\\.") -> true - message.matchRegex("§7Request join for Hub (.*)\\.\\.\\.") -> true - message.matchRegex("§7Request join for Dungeon Hub #(.*)\\.\\.\\.") -> true - message == "§7Warping..." -> true - message == "§7Warping you to your SkyBlock island..." -> true - message == "§7Warping using transfer token..." -> true - - //visiting other players - message == "§7Finding player..." -> true - message == "§7Sending a visit request..." -> true - - //warp portals on public islands (canvas room - flower house, election room - community center, void sepulture - the end) - message.matchRegex("§dWarped to (.*)§r§d!") -> true - else -> false - } - - private fun empty(message: String): Boolean = when (message) { - "§8 §r§8 §r§1 §r§3 §r§3 §r§7 §r§8 ", - - "§f §r§f §r§1 §r§0 §r§2 §r§4§r§f §r§f §r§2 §r§0 §r§4 §r§8§r§0§r§1§r§0§r§1§r§2§r§f§r§f§r§0§r§1§r§3§r§4§r§f§r§f§r§0§r§1§r§5§r§f§r§f§r§0§r§1§r§6§r§f§r§f§r§0§r§1§r§8§r§9§r§a§r§b§r§f§r§f§r§0§r§1§r§7§r§f§r§f§r§3 §r§9 §r§2 §r§0 §r§0 §r§1§r§3 §r§9 §r§2 §r§0 §r§0 §r§2§r§3 §r§9 §r§2 §r§0 §r§0 §r§3§r§0§r§0§r§1§r§f§r§e§r§0§r§0§r§2§r§f§r§e§r§0§r§0§r§3§r§4§r§5§r§6§r§7§r§8§r§f§r§e§r§3 §r§6 §r§3 §r§6 §r§3 §r§6 §r§e§r§3 §r§6 §r§3 §r§6 §r§3 §r§6 §r§d", - - "§f §r§r§r§f §r§r§r§1 §r§r§r§0 §r§r§r§2 §r§r§r§f §r§r§r§f §r§r§r§2 §r§r§r§0 §r§r§r§4 §r§r§r§3 §r§r§r§9 §r§r§r§2 §r§r§r§0 §r§r§r§0 §r§r§r§3 §r§r§r§9 §r§r§r§2 §r§r§r§0 §r§r§r§0 §r§r§r§3 §r§r§r§9 §r§r§r§2 §r§r§r§0 §r§r§r§0 ", - - "", - "§f", - "§c" -> true - else -> false - } -} diff --git a/src/main/java/at/hannibal2/skyhanni/chat/ChatManager.kt b/src/main/java/at/hannibal2/skyhanni/chat/ChatManager.kt deleted file mode 100644 index c189caa3d..000000000 --- a/src/main/java/at/hannibal2/skyhanni/chat/ChatManager.kt +++ /dev/null @@ -1,51 +0,0 @@ -package at.hannibal2.skyhanni.chat - -import at.hannibal2.skyhanni.events.LorenzActionBarEvent -import at.hannibal2.skyhanni.utils.LorenzLogger -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.events.PacketEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraft.network.play.server.S02PacketChat -import net.minecraftforge.fml.common.eventhandler.EventPriority -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class ChatManager { - - private val loggerAll = LorenzLogger("chat/filter_all") - private val loggerFiltered = LorenzLogger("chat/filter_blocked") - private val loggerAllowed = LorenzLogger("chat/filter_allowed") - private val loggerFilteredTypes = mutableMapOf() - - @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true) - fun onChatPacket(event: PacketEvent.ReceiveEvent) { - val packet = event.packet - if (packet !is S02PacketChat) return - val messageComponent = packet.chatComponent - - val message = LorenzUtils.stripVanillaMessage(messageComponent.formattedText) - if (packet.type.toInt() == 2) { - val actionBarEvent = LorenzActionBarEvent(message) - actionBarEvent.postAndCatch() - } else { - - val chatEvent = LorenzChatEvent(message, messageComponent) - chatEvent.postAndCatch() - - val blockReason = chatEvent.blockedReason.uppercase() - if (blockReason != "") { - event.isCanceled = true - loggerFiltered.log("[$blockReason] $message") - loggerAll.log("[$blockReason] $message") - loggerFilteredTypes.getOrPut(blockReason) { LorenzLogger("chat/filter_blocked/$blockReason") } - .log(message) - return - } - - if (!message.startsWith("§f{\"server\":\"")) { - loggerAllowed.log(message) - loggerAll.log("[allowed] $message") - } - - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/chat/NewChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/chat/NewChatFilter.kt deleted file mode 100644 index b72f4fd4b..000000000 --- a/src/main/java/at/hannibal2/skyhanni/chat/NewChatFilter.kt +++ /dev/null @@ -1,18 +0,0 @@ -package at.hannibal2.skyhanni.chat - -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class NewChatFilter { - - @SubscribeEvent - fun onChatMessage(event: LorenzChatEvent) { - if (!LorenzUtils.isOnHypixel) return - -// val blockReason = block(event.message) -// if (blockReason != "") { -// event.blockedReason = blockReason -// } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/chat/PlayerChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/chat/PlayerChatFilter.kt deleted file mode 100644 index dde648a55..000000000 --- a/src/main/java/at/hannibal2/skyhanni/chat/PlayerChatFilter.kt +++ /dev/null @@ -1,90 +0,0 @@ -package at.hannibal2.skyhanni.chat - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.events.PlayerSendChatEvent -import at.hannibal2.skyhanni.utils.LorenzLogger -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.removeColor -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class PlayerChatFilter { - - @SubscribeEvent - fun onChatMessage(event: LorenzChatEvent) { - if (!LorenzUtils.isOnHypixel) return - if (!SkyHanniMod.feature.chat.playerMessages) return - - if (shouldBlock(event.message)) { - event.blockedReason = "player_chat" - } - } - - val loggerPlayerChat = LorenzLogger("chat/player") - - fun shouldBlock(originalMessage: String): Boolean { - val split: List = if (originalMessage.contains("§7§r§7: ")) { - originalMessage.split("§7§r§7: ") - } else if (originalMessage.contains("§f: ")) { - originalMessage.split("§f: ") - } else { - return false - } - - var rawName = split[0] - val message = split[1] - - val channel: PlayerMessageChannel - if (rawName.startsWith("§9Party §8> ")) { - channel = PlayerMessageChannel.PARTY - rawName = rawName.substring(12) - } else if (rawName.startsWith("§2Guild > ")) { - channel = PlayerMessageChannel.GUILD - rawName = rawName.substring(10) - } else if (rawName.startsWith("§bCo-op > ")) { - channel = PlayerMessageChannel.COOP - rawName = rawName.substring(10) - } else { - channel = PlayerMessageChannel.ALL - } - - val nameSplit = rawName.split(" ") - val first = nameSplit[0] - - val last = nameSplit.last() - val name = if (last.endsWith("]")) { - nameSplit[nameSplit.size - 2] - } else { - last - } - - if (first != name) { - if (!first.contains("VIP") && !first.contains("MVP")) { - //TODO support yt + admin - return false - } - } - - send(channel, name.removeColor(), message.removeColor()) - return true - } - - private fun send(channel: PlayerMessageChannel, name: String, message: String) { - loggerPlayerChat.log("[$channel] $name: $message") - val event = PlayerSendChatEvent(channel, name, message) - event.postAndCatch() - - if (event.cancelledReason != "") { - loggerPlayerChat.log("cancelled: " + event.cancelledReason) - } else { - val finalMessage = event.message - if (finalMessage != message) { - loggerPlayerChat.log("message changed: $finalMessage") - } - - val prefix = channel.prefix - LorenzUtils.chat("$prefix §b$name §f$finalMessage") - } - } - -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/chat/PlayerMessageChannel.kt b/src/main/java/at/hannibal2/skyhanni/chat/PlayerMessageChannel.kt deleted file mode 100644 index 826b490de..000000000 --- a/src/main/java/at/hannibal2/skyhanni/chat/PlayerMessageChannel.kt +++ /dev/null @@ -1,10 +0,0 @@ -package at.hannibal2.skyhanni.chat - -enum class PlayerMessageChannel(val prefix: String) { - - ALL("§fA>"), - ALL_ADVERTISEMENT("§8A>"), - PARTY("§9P>"), - GUILD("§2G>"), - COOP("§bCC>"), -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/damageindicator/BossFinder.kt b/src/main/java/at/hannibal2/skyhanni/damageindicator/BossFinder.kt deleted file mode 100644 index 37cb085d1..000000000 --- a/src/main/java/at/hannibal2/skyhanni/damageindicator/BossFinder.kt +++ /dev/null @@ -1,569 +0,0 @@ -package at.hannibal2.skyhanni.damageindicator - -import at.hannibal2.skyhanni.dungeon.DungeonData -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth -import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex -import at.hannibal2.skyhanni.utils.LorenzVec -import at.hannibal2.skyhanni.utils.getLorenzVec -import net.minecraft.client.Minecraft -import net.minecraft.client.entity.EntityOtherPlayerMP -import net.minecraft.entity.Entity -import net.minecraft.entity.EntityLiving -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.boss.EntityDragon -import net.minecraft.entity.boss.EntityWither -import net.minecraft.entity.item.EntityArmorStand -import net.minecraft.entity.monster.* -import net.minecraft.entity.passive.EntityHorse -import net.minecraft.entity.passive.EntityWolf -import net.minecraft.util.AxisAlignedBB -import java.util.* - -class BossFinder { - - //F1 - private var floor1bonzo1 = false - private var floor1bonzo1SpawnTime = 0L - private var floor1bonzo2 = false - private var floor1bonzo2SpawnTime = 0L - - //F2 - private var floor2summons1 = false - private var floor2summons1SpawnTime = 0L - private var floor2summonsDiedOnce = mutableListOf() - private var floor2secondPhase = false - private var floor2secondPhaseSpawnTime = 0L - - //F3 - private var floor3GuardianShield = false - private var floor3GuardianShieldSpawnTime = 0L - private var guardians = mutableListOf() - private var floor3Professor = false - private var floor3ProfessorSpawnTime = 0L - private var floor3ProfessorGuardianPrepare = false - private var floor3ProfessorGuardianPrepareSpawnTime = 0L - private var floor3ProfessorGuardian = false - private var floor3ProfessorGuardianEntity: EntityGuardian? = null - - //F5 - private var floor5lividEntity: EntityOtherPlayerMP? = null - private var floor5lividEntitySpawnTime = 0L - - //F6 - private var floor6Giants = false - private var floor6GiantsSpawnTime = 0L - private var floor6GiantsSeparateDelay = mutableMapOf() - private var floor6Sadan = false - private var floor6SadanSpawnTime = 0L - - internal fun tryAdd(entity: EntityLivingBase): EntityResult? { - if (LorenzUtils.inDungeons) { - if (DungeonData.isOneOf("F1", "M1")) { - if (floor1bonzo1) { - if (entity is EntityOtherPlayerMP) { - if (entity.name == "Bonzo ") { - return EntityResult(floor1bonzo1SpawnTime) - } - } - } - if (floor1bonzo2) { - if (entity is EntityOtherPlayerMP) { - if (entity.name == "Bonzo ") { - return EntityResult(floor1bonzo2SpawnTime, finalDungeonBoss = true) - } - } - } - } - - if (DungeonData.isOneOf("F2", "M2")) { - if (entity.name == "Summon ") { - if (entity is EntityOtherPlayerMP) { - if (floor2summons1) { - if (!floor2summonsDiedOnce.contains(entity)) { - if (entity.health.toInt() != 0) { - return EntityResult(floor2summons1SpawnTime) - } else { - floor2summonsDiedOnce.add(entity) - } - } - } - if (floor2secondPhase) { - return EntityResult(floor2secondPhaseSpawnTime) - } - } - } - - if (floor2secondPhase) { - if (entity is EntityOtherPlayerMP) { - //TODO only show scarf after (all/at least x) summons are dead? - val result = entity.name == "Scarf " - if (result) { - return EntityResult(floor2secondPhaseSpawnTime, finalDungeonBoss = true) - } - } - } - } - - if (DungeonData.isOneOf("F3", "M3")) { - if (entity is EntityGuardian) { - if (floor3GuardianShield) { - if (guardians.size == 4) { - var totalHealth = 0 - for (guardian in guardians) { - totalHealth += guardian.health.toInt() - } - if (totalHealth == 0) { - floor3GuardianShield = false - guardians.clear() - } - } else { - findGuardians() - } - if (guardians.contains(entity)) { - return EntityResult(floor3GuardianShieldSpawnTime, true) - } - } - } - - if (floor3Professor) { - if (entity is EntityOtherPlayerMP) { - if (entity.name == "The Professor") { - return EntityResult( - floor3ProfessorSpawnTime, - floor3ProfessorSpawnTime + 1_000 > System.currentTimeMillis() - ) - } - } - } - if (floor3ProfessorGuardianPrepare) { - if (entity is EntityOtherPlayerMP) { - if (entity.name == "The Professor") { - return EntityResult(floor3ProfessorGuardianPrepareSpawnTime, true) - } - } - } - - if (entity is EntityGuardian) { - if (floor3ProfessorGuardian) { - if (entity == floor3ProfessorGuardianEntity) { - return EntityResult(finalDungeonBoss = true) - } - } - } - } - - if (DungeonData.isOneOf("F4", "M4")) { - if (entity is EntityGhast) { - return EntityResult(bossType = BossType.DUNGEON_F4_THORN, - ignoreBlocks = true, - finalDungeonBoss = true) - } - - } - - if (DungeonData.isOneOf("F5", "M5")) { - if (entity is EntityOtherPlayerMP) { - if (entity == floor5lividEntity) { - return EntityResult(floor5lividEntitySpawnTime, true, finalDungeonBoss = true) - } - } - } - - if (DungeonData.isOneOf("F6", "M6")) { - if (entity is EntityGiantZombie && !entity.isInvisible) { - if (floor6Giants && entity.posY > 68) { - val extraDelay = checkExtraF6GiantsDelay(entity) - return EntityResult( - floor6GiantsSpawnTime + extraDelay, - floor6GiantsSpawnTime + extraDelay + 1_000 > System.currentTimeMillis() - ) - } - - if (floor6Sadan) { - return EntityResult(floor6SadanSpawnTime, finalDungeonBoss = true) - } - } - } - } else { - - val maxHealth = entity.baseMaxHealth.toInt() - if (entity is EntityBlaze) { - if (entity.name != "Dinnerbone") { - if (entity.hasNameTagWith(2, "§e﴾ §8[§7Lv200§8] §l§8§lAshfang§r ")) { - if (maxHealth == 50_000_000) { - return EntityResult(bossType = BossType.NETHER_ASHFANG) - } - //Derpy - if (maxHealth == 100_000_000) { - return EntityResult(bossType = BossType.NETHER_ASHFANG) - } - } - } - } - if (entity is EntitySkeleton) { - if (entity.hasNameTagWith(5, "§e﴾ §8[§7Lv200§8] §l§8§lBladesoul§r ")) { - return EntityResult(bossType = BossType.NETHER_BLADESOUL) - } - } - if (entity is EntityOtherPlayerMP) { - if (entity.name == "Mage Outlaw") { - return EntityResult(bossType = BossType.NETHER_MAGE_OUTLAW) - } - if (entity.name == "DukeBarb ") { - return EntityResult(bossType = BossType.NETHER_BARBARIAN_DUKE) - } - } - if (entity is EntityWither) { - if (entity.hasNameTagWith(4, "§8[§7Lv100§8] §c§5Vanquisher§r ")) { - return EntityResult(bossType = BossType.NETHER_VANQUISHER) - } - } - if (entity is EntityEnderman) { - if (entity.hasNameTagWith(3, "§c☠ §bVoidgloom Seraph ")) { - when (maxHealth) { - 300_000, 600_000 -> { - return EntityResult(bossType = BossType.SLAYER_ENDERMAN_1) - } - 15_000_000, 30_000_000 -> { - return EntityResult(bossType = BossType.SLAYER_ENDERMAN_2) - } - 66_666_666, 66_666_666 * 2 -> { - return EntityResult(bossType = BossType.SLAYER_ENDERMAN_3) - } - 300_000_000, 600_000_000 -> { - return EntityResult(bossType = BossType.SLAYER_ENDERMAN_4) - } - } - } - } - if (entity is EntityDragon) { - //TODO testing and make right and so - return EntityResult(bossType = BossType.END_ENDER_DRAGON) - } - if (entity is EntityIronGolem) { - //TODO testing - if (entity.hasNameTagWith(3, "§e﴾ §8[§7Lv100§8] §lEndstone Protector§r ")) { - return EntityResult(bossType = BossType.END_ENDSTONE_PROTECTOR, ignoreBlocks = true) - } - } - if (entity is EntityZombie) { - if (entity.hasNameTagWith(2, "§c☠ §bRevenant Horror")) { - when (maxHealth) { - 500, 1_000 -> { - return EntityResult(bossType = BossType.SLAYER_ZOMBIE_1) - } - 20_000, 40_000 -> { - return EntityResult(bossType = BossType.SLAYER_ZOMBIE_2) - } - 400_000, 800_000 -> { - return EntityResult(bossType = BossType.SLAYER_ZOMBIE_3) - } - 1_500_000, 3_000_000 -> { - return EntityResult(bossType = BossType.SLAYER_ZOMBIE_4) - } - } - } - if (entity.hasNameTagWith(2, "§c☠ §fAtoned Horror ")) { - if (maxHealth == 10_000_000 || maxHealth == 20_000_000) { - return EntityResult(bossType = BossType.SLAYER_ZOMBIE_5) - } - } - } - if (entity is EntityMagmaCube) { - if (entity.hasNameTagWith(15, "§e﴾ §8[§7Lv500§8] §l§4§lMagma Boss§r ")) { - if (maxHealth == 200_000_000) { - return EntityResult(bossType = BossType.NETHER_MAGMA_BOSS, ignoreBlocks = true) - } - //Derpy - if (maxHealth == 400_000_000) { - return EntityResult(bossType = BossType.NETHER_MAGMA_BOSS, ignoreBlocks = true) - } - } - } - if (entity is EntityHorse) { - if (entity.hasNameTagWith(15, "§8[§7Lv100§8] §c§6Headless Horseman§r ")) { - if (maxHealth == 3_000_000) { - return EntityResult(bossType = BossType.HUB_HEADLESS_HORSEMAN) - } - //Derpy - if (maxHealth == 6_000_000) { - return EntityResult(bossType = BossType.HUB_HEADLESS_HORSEMAN) - } - } - } - if (entity is EntityBlaze) { - if (entity.hasNameTagWith(2, "§c☠ §bInferno Demonlord ")) { - when (maxHealth) { - 2_500_000, 5_000_000 -> { - return EntityResult(bossType = BossType.SLAYER_BLAZE_1) - } - } - } - } - if (entity is EntitySpider) { - if (entity.hasNameTagWith(1, "§5☠ §4Tarantula Broodfather ")) { - when (maxHealth) { - 740, 1_500 -> { - return EntityResult(bossType = BossType.SLAYER_SPIDER_1) - } - 30_000, 60_000 -> { - return EntityResult(bossType = BossType.SLAYER_SPIDER_2) - } - 900_000, 1_800_000 -> { - return EntityResult(bossType = BossType.SLAYER_SPIDER_3) - } - 2_400_000, 4_800_000 -> { - return EntityResult(bossType = BossType.SLAYER_SPIDER_4) - } - } - } - } - if (entity is EntityWolf) { - if (entity.hasNameTagWith(1, "§c☠ §fSven Packmaster ")) { - when (maxHealth) { - 2_000, 4_000 -> { - return EntityResult(bossType = BossType.SLAYER_WOLF_1) - } - 40_000, 80_000 -> { - return EntityResult(bossType = BossType.SLAYER_WOLF_2) - } - 750_000, 1_500_000 -> { - return EntityResult(bossType = BossType.SLAYER_WOLF_3) - } - 2_000_000, 4_000_000 -> { - return EntityResult(bossType = BossType.SLAYER_WOLF_4) - } - } - } - } - } - - return null - } - - private fun checkExtraF6GiantsDelay(entity: EntityGiantZombie): Long { - val uuid = entity.uniqueID - - if (floor6GiantsSeparateDelay.contains(uuid)) { - return floor6GiantsSeparateDelay[uuid]!! - } - - val middle = LorenzVec(-8, 0, 56) - - val loc = entity.getLorenzVec() - - var pos = 0 - - //first - if (loc.x > middle.x && loc.z > middle.z) { - pos = 2 - } - - //second - if (loc.x > middle.x && loc.z < middle.z) { - pos = 3 - } - - //third - if (loc.x < middle.x && loc.z < middle.z) { - pos = 0 - } - - //fourth - if (loc.x < middle.x && loc.z > middle.z) { - pos = 1 - } - - val extraDelay = 900L * pos - floor6GiantsSeparateDelay[uuid] = extraDelay - - return extraDelay - } - - fun handleChat(message: String) { - if (LorenzUtils.inDungeons) { - when (message) { - //F1 - "§c[BOSS] Bonzo§r§f: Gratz for making it this far, but I’m basically unbeatable." -> { - floor1bonzo1 = true - floor1bonzo1SpawnTime = System.currentTimeMillis() + 11_250 - } - - "§c[BOSS] Bonzo§r§f: Oh noes, you got me.. what ever will I do?!" -> { - floor1bonzo1 = false - } - - "§c[BOSS] Bonzo§r§f: Oh I'm dead!" -> { - floor1bonzo2 = true - floor1bonzo2SpawnTime = System.currentTimeMillis() + 4_200 - } - - "§c[BOSS] Bonzo§r§f: Alright, maybe I'm just weak after all.." -> { - floor1bonzo2 = false - } - - //F2 - "§c[BOSS] Scarf§r§f: ARISE, MY CREATIONS!" -> { - floor2summons1 = true - floor2summons1SpawnTime = System.currentTimeMillis() + 3_500 - } - - "§c[BOSS] Scarf§r§f: Those toys are not strong enough I see." -> { - floor2summons1 = false - } - - "§c[BOSS] Scarf§r§f: Don't get too excited though." -> { - floor2secondPhase = true - floor2secondPhaseSpawnTime = System.currentTimeMillis() + 6_300 - } - - "§c[BOSS] Scarf§r§f: Whatever..." -> { - floor2secondPhase = false - } - - //F3 - "§c[BOSS] The Professor§r§f: I was burdened with terrible news recently..." -> { - floor3GuardianShield = true - floor3GuardianShieldSpawnTime = System.currentTimeMillis() + 16_400 - } - - "§c[BOSS] The Professor§r§f: Even if you took my barrier down, I can still fight." -> { - floor3GuardianShield = false - } - - "§c[BOSS] The Professor§r§f: Oh? You found my Guardians one weakness?" -> { - floor3Professor = true - floor3ProfessorSpawnTime = System.currentTimeMillis() + 10_300 - } - - "§c[BOSS] The Professor§r§f: I see. You have forced me to use my ultimate technique." -> { - floor3Professor = false - - floor3ProfessorGuardianPrepare = true - floor3ProfessorGuardianPrepareSpawnTime = System.currentTimeMillis() + 10_500 - } - - "§c[BOSS] The Professor§r§f: The process is irreversible, but I'll be stronger than a Wither now!" -> { - floor3ProfessorGuardian = true - } - - "§c[BOSS] The Professor§r§f: What?! My Guardian power is unbeatable!" -> { - floor3ProfessorGuardian = false - } - - - //F5 - "§c[BOSS] Livid§r§f: This Orb you see, is Thorn, or what is left of him." -> { - floor5lividEntity = findLivid() - floor5lividEntitySpawnTime = System.currentTimeMillis() + 13_000 - } - - //F6 - "§c[BOSS] Sadan§r§f: ENOUGH!" -> { - floor6Giants = true - floor6GiantsSpawnTime = System.currentTimeMillis() + 7_400 - } - - "§c[BOSS] Sadan§r§f: You did it. I understand now, you have earned my respect." -> { - floor6Giants = false - floor6Sadan = true - floor6SadanSpawnTime = System.currentTimeMillis() + 32_500 - } - - "§c[BOSS] Sadan§r§f: NOOOOOOOOO!!! THIS IS IMPOSSIBLE!!" -> { - floor6Sadan = false - } - } - - if (message.matchRegex("§c\\[BOSS] (.*) Livid§r§f: Impossible! How did you figure out which one I was\\?!")) { - floor5lividEntity = null - } - } - } - - fun handleNewEntity(entity: Entity) { - if (LorenzUtils.inDungeons) { - if (floor3ProfessorGuardian) { - if (entity is EntityGuardian) { - if (floor3ProfessorGuardianEntity == null) { - floor3ProfessorGuardianEntity = entity - floor3ProfessorGuardianPrepare = false - } - } - } - } - } - - private fun findGuardians() { - guardians.clear() - - for (entity in Minecraft.getMinecraft().theWorld.loadedEntityList) { - if (entity is EntityGuardian) { - - val maxHealth = entity.baseMaxHealth.toInt() - - //F3 - if (maxHealth == 1_000_000 || maxHealth == 1_200_000) { - guardians.add(entity) - } - - //F3 Derpy - if (maxHealth == 2_000_000 || maxHealth == 2_400_000) { - guardians.add(entity) - } - - //M3 - if (maxHealth == 240_000_000 || maxHealth == 280_000_000) { - guardians.add(entity) - } - - //M3 Derpy - if (maxHealth == 120_000_000 || maxHealth == 140_000_000) { - guardians.add(entity) - } - } - } - } - - private fun findLivid(): EntityOtherPlayerMP? { - for (entity in Minecraft.getMinecraft().theWorld.loadedEntityList) { - if (entity is EntityOtherPlayerMP) { - if (entity.name == "Livid ") { - return entity - } - } - } - - return null - } -} - -fun EntityLiving.hasNameTagWith( - y: Int, - contains: String, - debugRightEntity: Boolean = false, - consumer: (EntityArmorStand) -> Unit = {}, - inaccuracy: Double = 1.6, - debugWrongEntity: Boolean = false, -): Boolean { - val center = getLorenzVec().add(0, y, 0) - val a = center.add(-inaccuracy, -inaccuracy - 3, -inaccuracy).toBlocPos() - val b = center.add(inaccuracy, inaccuracy + 3, inaccuracy).toBlocPos() - val alignedBB = AxisAlignedBB(a, b) - val clazz = EntityArmorStand::class.java - val found = worldObj.getEntitiesWithinAABB(clazz, alignedBB) - return found.any { - val result = it.name.contains(contains) - if (debugWrongEntity && !result) { - println("wrong entity in aabb: '" + it.name + "'") - } - if (debugRightEntity && result) { - println("mob: " + center.printWithAccuracy(2)) - println("nametag: " + it.getLorenzVec().printWithAccuracy(2)) - println("accuracy: " + it.getLorenzVec().subtract(center).printWithAccuracy(3)) - } - if (result) consumer(it) - result - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/damageindicator/BossType.kt b/src/main/java/at/hannibal2/skyhanni/damageindicator/BossType.kt deleted file mode 100644 index dc467cbb9..000000000 --- a/src/main/java/at/hannibal2/skyhanni/damageindicator/BossType.kt +++ /dev/null @@ -1,70 +0,0 @@ -package at.hannibal2.skyhanni.damageindicator - -enum class BossType(val fullName: String, val bossTypeToggle: Int, val shortName: String = fullName) { - GENERIC_DUNGEON_BOSS("Generic Dungeon boss", 0),//TODO split into different bosses - - //Nether Mini Bosses - NETHER_BLADESOUL("§8Bladesoul", 1), - NETHER_MAGMA_BOSS("§4Magma Boss", 1), - NETHER_ASHFANG("§cAshfang", 1), - NETHER_BARBARIAN_DUKE("§eBarbarian Duke", 1), - NETHER_MAGE_OUTLAW("§5Mage Outlaw", 1), - - NETHER_VANQUISHER("§5Vanquisher", 2), - - END_ENDSTONE_PROTECTOR("§cEndstone Protector", 3), - END_ENDER_DRAGON("Ender Dragon", 4),//TODO fix totally - - SLAYER_ZOMBIE_1("§aRevenant Horror 1", 5, "§aRev 1"), - SLAYER_ZOMBIE_2("§eRevenant Horror 2", 5, "§eRev 2"), - SLAYER_ZOMBIE_3("§cRevenant Horror 3", 5, "§cRev 3"), - SLAYER_ZOMBIE_4("§4Revenant Horror 4", 5, "§4Rev 4"), - SLAYER_ZOMBIE_5("§5Revenant Horror 5", 5, "§5Rev 5"), - - SLAYER_SPIDER_1("§aTarantula Broodfather 1", 6, "§aTara 1"), - SLAYER_SPIDER_2("§eTarantula Broodfather 2", 6, "§eTara 2"), - SLAYER_SPIDER_3("§cTarantula Broodfather 3", 6, "§cTara 3"), - SLAYER_SPIDER_4("§4Tarantula Broodfather 4", 6, "§4Tara 4"), - - SLAYER_WOLF_1("§aSven Packmaster 1", 7, "§aSven 1"), - SLAYER_WOLF_2("§eSven Packmaster 2", 7, "§eSven 2"), - SLAYER_WOLF_3("§cSven Packmaster 3", 7, "§cSven 3"), - SLAYER_WOLF_4("§4Sven Packmaster 4", 7, "§4Sven 4"), - - SLAYER_ENDERMAN_1("§aVoidgloom Seraph 1", 8, "§aVoid 1"), - SLAYER_ENDERMAN_2("§eVoidgloom Seraph 2", 8, "§eVoid 2"), - SLAYER_ENDERMAN_3("§cVoidgloom Seraph 3", 8, "§cVoid 3"), - SLAYER_ENDERMAN_4("§4Voidgloom Seraph 4", 8, "§4Void 4"), - - SLAYER_BLAZE_1("§aInferno Demonlord 1", 9, "§aInferno 1"), - - HUB_HEADLESS_HORSEMAN("§6Headless Horseman", 10), - - DUNGEON_F1("", 11), - DUNGEON_F2("", 12), - DUNGEON_F3("", 13), - DUNGEON_F4_THORN("§cThorn", 14), - DUNGEON_F5("", 15), - DUNGEON_F("", 16), - DUNGEON_75("", 17), - - //TODO arachne - - //TODO corelone - //TODO bal - - - /** - * TODO dungeon mini bosses - * shadow assassin - * lost adventurer - * frozen adventurer - * king midas - * silverfish 2b one tap - deathmite outside trap - * in blood room: bonzo, scarf, ?? - * f7 blood room giants - * - */ - - //TODO diana mythological creatures -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/damageindicator/DamageCounter.kt b/src/main/java/at/hannibal2/skyhanni/damageindicator/DamageCounter.kt deleted file mode 100644 index 92566a018..000000000 --- a/src/main/java/at/hannibal2/skyhanni/damageindicator/DamageCounter.kt +++ /dev/null @@ -1,10 +0,0 @@ -package at.hannibal2.skyhanni.damageindicator - -class DamageCounter { - - var currentDamage = 0L - var currentHealing = 0L - var oldDamages = mutableListOf() - var firstTick = 0L - -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/damageindicator/DamageIndicatorManager.kt b/src/main/java/at/hannibal2/skyhanni/damageindicator/DamageIndicatorManager.kt deleted file mode 100644 index fa7dbb530..000000000 --- a/src/main/java/at/hannibal2/skyhanni/damageindicator/DamageIndicatorManager.kt +++ /dev/null @@ -1,544 +0,0 @@ -package at.hannibal2.skyhanni.damageindicator - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.dungeon.DungeonData -import at.hannibal2.skyhanni.events.DamageIndicatorFinalBossEvent -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.misc.ScoreboardData -import at.hannibal2.skyhanni.test.LorenzTest -import at.hannibal2.skyhanni.utils.* -import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth -import at.hannibal2.skyhanni.utils.LorenzUtils.between -import at.hannibal2.skyhanni.utils.LorenzUtils.removeColor -import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.entity.EntityLivingBase -import net.minecraft.entity.item.EntityArmorStand -import net.minecraft.entity.monster.EntityEnderman -import net.minecraft.entity.monster.EntityMagmaCube -import net.minecraft.entity.monster.EntityZombie -import net.minecraft.entity.passive.EntityWolf -import net.minecraftforge.client.event.RenderLivingEvent -import net.minecraftforge.client.event.RenderWorldLastEvent -import net.minecraftforge.event.entity.EntityJoinWorldEvent -import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.EventPriority -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent -import java.text.DecimalFormat -import java.util.* -import java.util.regex.Pattern -import kotlin.math.max - -class DamageIndicatorManager { - - var data = mutableMapOf() - private var bossFinder: BossFinder? = null - private val decimalFormat = DecimalFormat("0.0") - private val maxHealth = mutableMapOf() - private val damagePattern = Pattern.compile("✧?(\\d+[⚔+✧❤♞☄✷ﬗ]*)") - - @SubscribeEvent - fun onWorldLoad(event: WorldEvent.Load) { - bossFinder = BossFinder() - data.clear() - } - - @SubscribeEvent(receiveCanceled = true) - fun onChatMessage(event: LorenzChatEvent) { - bossFinder?.handleChat(event.message) - } - - @SubscribeEvent - fun onWorldRender(event: RenderWorldLastEvent) { - if (!SkyHanniMod.feature.damageIndicator.enabled) return - - GlStateManager.disableDepth() - GlStateManager.disableCull() - - val player = Minecraft.getMinecraft().thePlayer - - //TODO config to define between 100ms and 5 sec - for (uuid in data.filter { System.currentTimeMillis() > it.value.timeLastTick + if (it.value.dead) 3_000 else 100 } - .map { it.key }) { - data.remove(uuid) - } - - for (data in data.values) { - tickDamage(data.damageCounter) - if (!data.ignoreBlocks) { - if (!player.canEntityBeSeen(data.entity)) continue - } - if (data.bossType.bossTypeToggle !in SkyHanniMod.feature.damageIndicator.bossesToShow) continue - - val entity = data.entity - - var healthText = data.healthText - val delayedStart = data.delayedStart - if (delayedStart != -1L) { - if (delayedStart > System.currentTimeMillis()) { - val delay = delayedStart - System.currentTimeMillis() - healthText = formatDelay(delay) - } - } - - val partialTicks = event.partialTicks - - val location = if (data.dead && data.deathLocation != null) { - data.deathLocation!! - } else { - val loc = LorenzVec( - RenderUtils.interpolate(entity.posX, entity.lastTickPosX, partialTicks), - RenderUtils.interpolate(entity.posY, entity.lastTickPosY, partialTicks) + 0.5f, - RenderUtils.interpolate(entity.posZ, entity.lastTickPosZ, partialTicks) - ) - if (data.dead) data.deathLocation = loc - loc - } - - if (!data.healthLineHidden) { - RenderUtils.drawLabel(location, healthText, partialTicks, true, 6f) - } - - var bossName = when (SkyHanniMod.feature.damageIndicator.bossName) { - 0 -> "" - 1 -> data.bossType.fullName - 2 -> data.bossType.shortName - else -> data.bossType.fullName - } - - if (data.namePrefix.isNotEmpty()) { - bossName = data.namePrefix + bossName - } - if (data.nameSuffix.isNotEmpty()) { - bossName += data.nameSuffix - } - - RenderUtils.drawLabel(location, bossName, partialTicks, true, 3.9f, -9.0f) - - if (SkyHanniMod.feature.damageIndicator.showDamageOverTime) { - var diff = 13f - val currentDamage = data.damageCounter.currentDamage - val currentHealing = data.damageCounter.currentHealing - if (currentDamage != 0L || currentHealing != 0L) { - val formatDamage = "§c" + NumberUtil.format(currentDamage) - val formatHealing = "§a+" + NumberUtil.format(currentHealing) - val finalResult = if (currentHealing == 0L) { - formatDamage - } else if (currentDamage == 0L) { - formatHealing - } else { - "$formatDamage §7/ $formatHealing" - } - RenderUtils.drawLabel(location, finalResult, partialTicks, true, 3.9f, diff) - diff += 9f - } - for (damage in data.damageCounter.oldDamages) { - val formatDamage = "§c" + NumberUtil.format(damage.damage) + "/s" - val formatHealing = "§a+" + NumberUtil.format(damage.healing) + "/s" - val finalResult = if (damage.healing == 0L) { - formatDamage - } else if (damage.damage == 0L) { - formatHealing - } else { - "$formatDamage §7/ $formatHealing" - } - RenderUtils.drawLabel(location, finalResult, partialTicks, true, 3.9f, diff) - diff += 9f - } - } - - } - GlStateManager.enableDepth() - GlStateManager.enableCull() - } - - private fun tickDamage(damageCounter: DamageCounter) { - val now = System.currentTimeMillis() - if (damageCounter.currentDamage != 0L || damageCounter.currentHealing != 0L) { - if (damageCounter.firstTick == 0L) { - damageCounter.firstTick = now - } - - if (now > damageCounter.firstTick + 1_000) { - damageCounter.oldDamages.add(OldDamage(now, damageCounter.currentDamage, damageCounter.currentHealing)) - damageCounter.firstTick = 0L - damageCounter.currentDamage = 0 - damageCounter.currentHealing = 0 - } - } - damageCounter.oldDamages.removeIf { now > it.time + 5_000 } - } - - private fun formatDelay(delay: Long): String { - val color = when { - delay < 1_000 -> LorenzColor.DARK_PURPLE - delay < 3_000 -> LorenzColor.LIGHT_PURPLE - - else -> LorenzColor.WHITE - } - val d = (delay * 1.0) / 1000 - return color.getChatColor() + decimalFormat.format(d) - } - - @SubscribeEvent - fun onTickEvent(event: TickEvent.ClientTickEvent) { - if (!LorenzUtils.inSkyblock) return - for (entity in Minecraft.getMinecraft().theWorld.loadedEntityList) { - if (entity is EntityLivingBase) { - checkEntity(entity) - } - } - } - - private fun checkEntity(entity: EntityLivingBase) { - try { - val entityData = grabData(entity) ?: return - if (LorenzUtils.inDungeons) { - checkFinalBoss(entityData.finalDungeonBoss, entity.entityId) - } - - val biggestHealth = getMaxHealthFor(entity) - - val health = entity.health.toInt() - val maxHealth: Int - - if (biggestHealth == 0) { - val currentMaxHealth = entity.baseMaxHealth.toInt() - maxHealth = max(currentMaxHealth, health) - setMaxHealth(entity, maxHealth) - } else { - maxHealth = biggestHealth - } - - var calcHealth = health - var calcMaxHealth = maxHealth - entityData.namePrefix = "" - entityData.nameSuffix = "" - var customHealthText = "" - - //TODO implement - if (!entityData.dead) { - - if (entityData.bossType == BossType.DUNGEON_F4_THORN) { - if (DungeonData.isOneOf("F4")) { - calcHealth = when (health) { - 300_000, 600_000 -> 4 - 222_000, 444_000 -> 3 - 144_000, 288_000 -> 2 - 66_000, 132_000 -> 1 - 0 -> 0 - else -> { - LorenzUtils.error("Unexpected health of thorn in f4! (${ - LorenzUtils.formatDouble(LorenzUtils.formatDouble( - health.toDouble()).toDouble()) - })") - return - } - } - calcMaxHealth = 4 - } else if (DungeonData.isOneOf("M4")) { - calcHealth = when (health) { - //TODO test all non derpy values! - 1_800_000 / 2, 1_800_000 -> 6 - 1_494_000 / 2, 1_494_000 -> 5 - 1_188_000 / 2, 1_188_000 -> 4 - 882_000 / 2, 882_000 -> 3 - 576_000 / 2, 576_000 -> 2 - 270_000 / 2, 270_000 -> 1 - 0 -> 0 - else -> { - LorenzTest.enabled = true - LorenzTest.text = "thorn has ${LorenzUtils.formatDouble(health.toDouble())} hp!" - LorenzUtils.error("Unexpected health of thorn in m4! (${ - LorenzUtils.formatDouble(LorenzUtils.formatDouble( - health.toDouble()).toDouble()) - })") - return - } - } - calcMaxHealth = 4 - } - } - - if (entityData.bossType == BossType.SLAYER_ENDERMAN_1 || - entityData.bossType == BossType.SLAYER_ENDERMAN_2 || - entityData.bossType == BossType.SLAYER_ENDERMAN_3 || - entityData.bossType == BossType.SLAYER_ENDERMAN_4 - ) { - var statePrefix = "" - //Hides the damage indicator when in hit phase or in laser phase - if (entity is EntityEnderman) { - entity.hasNameTagWith(3, " Hit", consumer = { - val name = it.name.removeColor() - - val maxHits = when (entityData.bossType) { - BossType.SLAYER_ENDERMAN_1 -> 15 - BossType.SLAYER_ENDERMAN_2 -> 30 - BossType.SLAYER_ENDERMAN_3 -> 60 - BossType.SLAYER_ENDERMAN_4 -> 100 - else -> 100 - } - val hits = name.between("Seraph ", " Hit").toInt() - val color = percentageColor(hits, maxHits) - - customHealthText = color.getChatColor() + "$hits Hits" - }) - if (entity.ridingEntity != null) { - val ticksAlive = entity.ridingEntity.ticksExisted.toLong() - //TODO more tests, more exact values, better logic? idk make this working perfectly pls -// val remainingTicks = 8 * 20 - ticksAlive - val remainingTicks = (8.9 * 20).toLong() - ticksAlive - customHealthText = formatDelay(remainingTicks * 50) - } - } - - when (entityData.bossType) { - BossType.SLAYER_ENDERMAN_4 -> { - val step = maxHealth / 6 - calcMaxHealth = step - if (health > step * 5) { - calcHealth -= step * 5 - statePrefix = "§c1/6 " - } else if (health > step * 4) { - calcHealth -= step * 4 - statePrefix = "§e2/6 " - } else if (health > step * 3) { - calcHealth -= step * 3 - statePrefix = "§e3/6 " - } else if (health > step * 2) { - calcHealth -= step * 2 - statePrefix = "§e4/6 " - } else if (health > step) { - calcHealth -= step - statePrefix = "§e5/6 " - } else { - calcHealth = health - statePrefix = "§a6/6 " - } - } - BossType.SLAYER_ENDERMAN_1, - BossType.SLAYER_ENDERMAN_2, - BossType.SLAYER_ENDERMAN_3, - -> { - val step = maxHealth / 3 - - calcMaxHealth = step - if (health > step * 2) { - calcHealth -= step * 2 - statePrefix = "§c1/3 " - } else if (health > step) { - calcHealth -= step - statePrefix = "§e2/3 " - } else { - calcHealth = health - statePrefix = "§a3/3 " - } - - } - else -> {} - } - entityData.namePrefix = statePrefix + entityData.namePrefix - } - if (entityData.bossType == BossType.NETHER_MAGMA_BOSS) { - if (entity is EntityMagmaCube) { - val slimeSize = entity.slimeSize - entityData.namePrefix = when (slimeSize) { - 24 -> "§c1/6" - 22 -> "§e2/6" - 20 -> "§e3/6" - 18 -> "§e4/6" - 16 -> "§e5/6" - else -> { - calcMaxHealth = 10_000_000 - "§a6/6" - } - } + " §f" - - //hide while in the middle - val position = entity.getLorenzVec() - entityData.healthLineHidden = position.x == -368.0 && position.z == -804.0 - - for (line in ScoreboardData.sidebarLinesRaw) { - if (line.contains("▎")) { - val color: String - if (line.startsWith("§7")) { - color = "§7" - } else if (line.startsWith("§e")) { - color = "§e" - } else if (line.startsWith("§6") || line.startsWith("§a") || line.startsWith("§c")) { - calcHealth = 0 - break - } else { - LorenzUtils.error("unknown magma boss health sidebar format!") - break - } - - val text = line.replace("\uD83C\uDF81" + color, "") - val max = 25.0 - val length = text.split("§e", "§7")[1].length - val missing = (health.toDouble() / max) * length - calcHealth = (health - missing).toInt() - } - } - } - } - if (entityData.bossType == BossType.SLAYER_ZOMBIE_5) { - if (entity is EntityZombie) { - entity.hasNameTagWith(3, "§fBoom!", consumer = { - val ticksAlive = entity.ticksExisted % (20 * 5) - val remainingTicks = (5 * 20).toLong() - ticksAlive - val format = formatDelay(remainingTicks * 50) - //TODO fix -// entityData.nameSuffix = " §lBOOM - $format" - entityData.nameSuffix = " §lBOOM!" - }) - } - } - if (entityData.bossType == BossType.SLAYER_WOLF_3 || - entityData.bossType == BossType.SLAYER_WOLF_4 - ) { - if (entity is EntityWolf) { - if (entity.hasNameTagWith(2, "§bCalling the pups!")) { - customHealthText = "Pups!" - } - } - } - } - - if (health == 0) { - customHealthText = "§cDead" - entityData.dead = true - } - - if (data.containsKey(entity.uniqueID)) { - val lastHealth = data[entity.uniqueID]!!.lastHealth - val bossType = entityData.bossType - if (SkyHanniMod.feature.damageIndicator.healingMessage) { - checkHealed(health, lastHealth, bossType) - } - checkDamage(entityData, health, lastHealth, bossType) - } - - entityData.lastHealth = health - if (customHealthText.isNotEmpty()) { - entityData.healthText = customHealthText - } else { - val color = percentageColor(calcHealth, calcMaxHealth) - entityData.healthText = color.getChatColor() + NumberUtil.format(calcHealth) - } - entityData.timeLastTick = System.currentTimeMillis() - data[entity.uniqueID] = entityData - - } catch (e: Throwable) { - e.printStackTrace() - } - } - - private fun checkDamage(entityData: EntityData, health: Int, lastHealth: Int, bossType: BossType) { - val damage = lastHealth - health - val healing = health - lastHealth - if (damage > 0) { - val damageCounter = entityData.damageCounter - damageCounter.currentDamage += damage - } - if (healing > 0) { - //Hide auto heal every 10 ticks (with rounding errors) - if ((healing == 15_000 || healing == 15_001) && bossType == BossType.SLAYER_ZOMBIE_5) return - - val damageCounter = entityData.damageCounter - damageCounter.currentHealing += healing - - } - } - - private fun percentageColor( - have: Int, - max: Int, - ): LorenzColor { - val percentage = have.toDouble() / max.toDouble() - return when { - percentage > 0.9 -> LorenzColor.DARK_GREEN - percentage > 0.75 -> LorenzColor.GREEN - percentage > 0.5 -> LorenzColor.YELLOW - percentage > 0.25 -> LorenzColor.GOLD - else -> LorenzColor.RED - } - } - - private fun checkHealed(health: Int, lastHealth: Int, bossType: BossType) { - val healed = health - lastHealth - if (healed <= 0) return - - //Hide auto heal every 10 ticks (with rounding errors) - if ((healed == 15_000 || healed == 15_001) && bossType == BossType.SLAYER_ZOMBIE_5) return - - val formatLastHealth = NumberUtil.format(lastHealth) - val formatHealth = NumberUtil.format(health) - val healedFormat = NumberUtil.format(healed) - - - val bossName = when (SkyHanniMod.feature.damageIndicator.bossName) { - 2 -> bossType.shortName - else -> bossType.fullName - } - - //TODO fix rounding error (25+4=30) - println(bossName + " §healed for $healed❤ ($lastHealth -> $health)") - LorenzUtils.chat("$bossName §ehealed for §a$healedFormat❤ §8(§e$formatLastHealth -> $formatHealth§8)") - } - - private fun grabData(entity: EntityLivingBase): EntityData? { - if (data.contains(entity.uniqueID)) return data[entity.uniqueID] - - val entityResult = bossFinder?.tryAdd(entity) ?: return null - return EntityData( - entity, - entityResult.ignoreBlocks, - entityResult.delayedStart, - entityResult.finalDungeonBoss, - entityResult.bossType - ) - } - - private fun checkFinalBoss(finalBoss: Boolean, id: Int) { - if (finalBoss) { - DamageIndicatorFinalBossEvent(id).postAndCatch() - } - } - - private fun setMaxHealth(entity: EntityLivingBase, currentMaxHealth: Int) { - maxHealth[entity.uniqueID!!] = currentMaxHealth - } - - private fun getMaxHealthFor(entity: EntityLivingBase): Int { - return maxHealth.getOrDefault(entity.uniqueID!!, 0) - } - - @SubscribeEvent - fun onWorldRender(event: EntityJoinWorldEvent) { - bossFinder?.handleNewEntity(event.entity) - } - - @SubscribeEvent(priority = EventPriority.HIGHEST) - fun onRenderLiving(e: RenderLivingEvent.Specials.Pre) { - if (!SkyHanniMod.feature.damageIndicator.hideDamageSplash) return - - val entity = e.entity - if (entity.ticksExisted > 300 || entity !is EntityArmorStand) return - if (!entity.hasCustomName()) return - if (entity.isDead) return - val strippedName = entity.customNameTag.removeColor() - val damageMatcher = damagePattern.matcher(strippedName) - if (damageMatcher.matches()) { - if (data.values.any { - val distance = it.entity.getLorenzVec().distance(entity.getLorenzVec()) - val found = distance < 4.5 - found - }) { - e.isCanceled = true - } - } - } - -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/damageindicator/EntityData.kt b/src/main/java/at/hannibal2/skyhanni/damageindicator/EntityData.kt deleted file mode 100644 index f1514ae93..000000000 --- a/src/main/java/at/hannibal2/skyhanni/damageindicator/EntityData.kt +++ /dev/null @@ -1,22 +0,0 @@ -package at.hannibal2.skyhanni.damageindicator - -import at.hannibal2.skyhanni.utils.LorenzVec -import net.minecraft.entity.EntityLivingBase - -class EntityData( - val entity: EntityLivingBase, - var ignoreBlocks: Boolean, - var delayedStart: Long, - val finalDungeonBoss: Boolean, - val bossType: BossType, - val damageCounter: DamageCounter = DamageCounter(), - - var lastHealth: Int = 0, - var healthText: String = "", - var timeLastTick: Long = 0, - var healthLineHidden: Boolean = false, - var namePrefix: String = "", - var nameSuffix: String = "", - var dead: Boolean = false, - var deathLocation: LorenzVec? = null, -) \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/damageindicator/EntityResult.kt b/src/main/java/at/hannibal2/skyhanni/damageindicator/EntityResult.kt deleted file mode 100644 index d3710a73d..000000000 --- a/src/main/java/at/hannibal2/skyhanni/damageindicator/EntityResult.kt +++ /dev/null @@ -1,8 +0,0 @@ -package at.hannibal2.skyhanni.damageindicator - -class EntityResult( - val delayedStart: Long = -1L, - val ignoreBlocks: Boolean = false, - val finalDungeonBoss: Boolean = false, - val bossType: BossType = BossType.GENERIC_DUNGEON_BOSS, -) \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/damageindicator/OldDamage.kt b/src/main/java/at/hannibal2/skyhanni/damageindicator/OldDamage.kt deleted file mode 100644 index de5070a01..000000000 --- a/src/main/java/at/hannibal2/skyhanni/damageindicator/OldDamage.kt +++ /dev/null @@ -1,4 +0,0 @@ -package at.hannibal2.skyhanni.damageindicator - -class OldDamage(val time: Long, val damage: Long, val healing: Long) { -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/data/ApiData.kt b/src/main/java/at/hannibal2/skyhanni/data/ApiData.kt new file mode 100644 index 000000000..9e47d5d0f --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/ApiData.kt @@ -0,0 +1,90 @@ +package at.hannibal2.skyhanni.data + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.ProfileApiDataLoadedEvent +import at.hannibal2.skyhanni.events.ProfileJoinEvent +import at.hannibal2.skyhanni.utils.APIUtil +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraft.client.Minecraft +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class ApiData { + + private var currentProfileName = "" + + @SubscribeEvent + fun onStatusBar(event: LorenzChatEvent) { + val message = event.message + if (message.startsWith("§aYour new API key is §r§b")) { + SkyHanniMod.feature.hidden.apiKey = message.substring(26) + LorenzUtils.chat("§b[SkyHanni] A new API Key has been detected and installed") + + if (currentProfileName != "") { + updateApiData() + } + } + } + + @SubscribeEvent + fun onStatusBar(event: ProfileJoinEvent) { + currentProfileName = event.name + updateApiData() + } + + private fun updateApiData() { + val uuid = Minecraft.getMinecraft().thePlayer.uniqueID.toString().replace("-", "") + + val apiKey = SkyHanniMod.feature.hidden.apiKey + + if (apiKey.isEmpty()) { + LorenzUtils.error("SkyHanni has no API Key set. Type /api new to reload.") + return + } + + val url = "https://api.hypixel.net/player?key=$apiKey&uuid=$uuid" + + val jsonObject = APIUtil.getJSONResponse(url) + + if (!jsonObject["success"].asBoolean) { + val cause = jsonObject["cause"].asString + if (cause == "Invalid API key") { + LorenzUtils.error("SkyHanni got an API error: Invalid API key! Type /api new to reload.") + return + } else { + throw RuntimeException("API error for url '$url': $cause") + } + } + + val player = jsonObject["player"].asJsonObject + val stats = player["stats"].asJsonObject + val skyblock = stats["SkyBlock"].asJsonObject + val profiles = skyblock["profiles"].asJsonObject + for (entry in profiles.entrySet()) { + val asJsonObject = entry.value.asJsonObject + val name = asJsonObject["cute_name"].asString + val profileId = asJsonObject["profile_id"].asString + if (currentProfileName == name.lowercase()) { + loadProfile(uuid, profileId) + return + } + } + } + + private fun loadProfile(playerUuid: String, profileId: String) { + val apiKey = SkyHanniMod.feature.hidden.apiKey + val url = "https://api.hypixel.net/skyblock/profile?key=$apiKey&profile=$profileId" + + val jsonObject = APIUtil.getJSONResponse(url) + + val profile = jsonObject["profile"].asJsonObject + val members = profile["members"].asJsonObject + for (entry in members.entrySet()) { + if (entry.key == playerUuid) { + val profileData = entry.value.asJsonObject + ProfileApiDataLoadedEvent(profileData).postAndCatch() + + } + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt b/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt new file mode 100644 index 000000000..f9c0af979 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/HypixelData.kt @@ -0,0 +1,106 @@ +package at.hannibal2.skyhanni.data + +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.PacketEvent +import at.hannibal2.skyhanni.events.ProfileJoinEvent +import at.hannibal2.skyhanni.utils.LorenzUtils.removeColor +import net.minecraft.client.Minecraft +import net.minecraft.network.play.server.S38PacketPlayerListItem +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import net.minecraftforge.fml.common.network.FMLNetworkEvent + +class HypixelData { + + companion object { + var hypixel = false + var skyblock = false + var dungeon = false + } + + @SubscribeEvent + fun onConnect(event: FMLNetworkEvent.ClientConnectedToServerEvent) { + hypixel = Minecraft.getMinecraft().runCatching { + !event.isLocal && (thePlayer?.clientBrand?.lowercase()?.contains("hypixel") + ?: currentServerData?.serverIP?.lowercase()?.contains("hypixel") ?: false) + }.onFailure { it.printStackTrace() }.getOrDefault(false) + } + + val areaRegex = Regex("§r§b§l(?[\\w]+): §r§7(?[\\w ]+)§r") + + @SubscribeEvent + fun onTabUpdate(event: PacketEvent.ReceiveEvent) { + if (dungeon || !hypixel || event.packet !is S38PacketPlayerListItem || + (event.packet.action != S38PacketPlayerListItem.Action.UPDATE_DISPLAY_NAME && + event.packet.action != S38PacketPlayerListItem.Action.ADD_PLAYER) + ) return + event.packet.entries.forEach { playerData -> + val name = playerData?.displayName?.formattedText ?: playerData?.profile?.name ?: return@forEach + areaRegex.matchEntire(name)?.let { result -> + dungeon = skyblock && result.groups["area"]?.value == "Dungeon" + return@forEach + } + } + } + + @SubscribeEvent + fun onWorldChange(event: WorldEvent.Load) { + skyblock = false + dungeon = false + } + + @SubscribeEvent + fun onDisconnect(event: FMLNetworkEvent.ClientDisconnectionFromServerEvent) { + hypixel = false + skyblock = false + dungeon = false + } + + @SubscribeEvent + fun onStatusBar(event: LorenzChatEvent) { + if (!hypixel) return + + val message = event.message.removeColor().lowercase() + + if (message.startsWith("your profile was changed to:")) { + val stripped = message.replace("your profile was changed to:", "").replace("(co-op)", "").trim() + ProfileJoinEvent(stripped).postAndCatch() + } + if (message.startsWith("you are playing on profile:")) { + val stripped = message.replace("you are playing on profile:", "").replace("(co-op)", "").trim() + ProfileJoinEvent(stripped).postAndCatch() + + } + } + + var timerTick = 0 + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (!hypixel) return + if (event.phase != TickEvent.Phase.START) return + + timerTick++ + + if (timerTick % 5 != 0) return + + val newState = checkScoreboard() + if (newState == skyblock) return + + skyblock = newState + } + + private fun checkScoreboard(): Boolean { + val minecraft = Minecraft.getMinecraft() + val world = minecraft.theWorld ?: return false + + val sidebarObjective = world.scoreboard.getObjectiveInDisplaySlot(1) ?: return false + + val displayName = sidebarObjective.displayName + + return displayName.removeColor().contains("SKYBLOCK") + + } + +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/data/ItemRenderBackground.kt b/src/main/java/at/hannibal2/skyhanni/data/ItemRenderBackground.kt new file mode 100644 index 000000000..bff39fc8c --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/ItemRenderBackground.kt @@ -0,0 +1,47 @@ +package at.hannibal2.skyhanni.data + +import at.hannibal2.skyhanni.events.RenderRealOverlayEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.Gui +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.item.ItemStack +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class ItemRenderBackground { + + companion object { + + val map = mutableMapOf() + val mapTime = mutableMapOf() + + var ItemStack.background: Int + get() { + if (System.currentTimeMillis() > mapTime.getOrDefault(this, 0) + 100) return -1 + return map.getOrDefault(this, -1) + } + set(value) { + map[this] = value + mapTime[this] = System.currentTimeMillis() + } + } + + + @SubscribeEvent + fun renderOverlayLol(event: RenderRealOverlayEvent) { + val stack = event.stack + if (LorenzUtils.inSkyblock) { + if (stack != null) { + val color = stack.background + if (color != -1) { + GlStateManager.pushMatrix() + GlStateManager.translate(0f, 0f, 110 + Minecraft.getMinecraft().renderItem.zLevel) + val x = event.x + val y = event.y + Gui.drawRect(x, y, x + 16, y + 16, color) + GlStateManager.popMatrix() + } + } + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/data/ScoreboardData.kt b/src/main/java/at/hannibal2/skyhanni/data/ScoreboardData.kt new file mode 100644 index 000000000..179635250 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/ScoreboardData.kt @@ -0,0 +1,48 @@ +package at.hannibal2.skyhanni.data + +import at.hannibal2.skyhanni.utils.LorenzUtils.removeColor +import net.minecraft.client.Minecraft +import net.minecraft.scoreboard.Score +import net.minecraft.scoreboard.ScorePlayerTeam +import net.minecraftforge.fml.common.eventhandler.EventPriority +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent + +class ScoreboardData { + + companion object { + var sidebarLines: List = emptyList() + var sidebarLinesRaw: List = emptyList() + } + + @SubscribeEvent(priority = EventPriority.HIGHEST) + fun onTick(event: TickEvent.ClientTickEvent) { + if (event.phase != TickEvent.Phase.START) return + + val list = fetchScoreboardLines() + sidebarLines = list.map { cleanSB(it) }.reversed() + sidebarLinesRaw = list.reversed() + } + + private fun cleanSB(scoreboard: String): String { + return scoreboard.removeColor().toCharArray().filter { it.code in 21..126 }.joinToString(separator = "") + } + + fun fetchScoreboardLines(): List { + val scoreboard = Minecraft.getMinecraft().theWorld?.scoreboard ?: return emptyList() + val objective = scoreboard.getObjectiveInDisplaySlot(1) ?: return emptyList() + var scores = scoreboard.getSortedScores(objective) + val list = scores.filter { input: Score? -> + input != null && input.playerName != null && !input.playerName + .startsWith("#") + } + scores = if (list.size > 15) { + list.drop(15) + } else { + list + } + return scores.map { + ScorePlayerTeam.formatPlayerName(scoreboard.getPlayersTeam(it.playerName), it.playerName) + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt b/src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt new file mode 100644 index 000000000..8351991ab --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/repo/RepoManager.kt @@ -0,0 +1,172 @@ +package at.hannibal2.skyhanni.data.repo + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.RepositoryReloadEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import com.google.gson.Gson +import com.google.gson.GsonBuilder +import com.google.gson.JsonObject +import net.minecraft.client.Minecraft +import org.apache.commons.io.FileUtils +import java.io.* +import java.net.URL +import java.nio.charset.StandardCharsets +import java.util.concurrent.CompletableFuture +import java.util.concurrent.atomic.AtomicBoolean + +class RepoManager(private val configLocation: File) { + val gson: Gson = GsonBuilder().setPrettyPrinting().create() + private var latestRepoCommit: String? = null + private val repoLocation: File = File(configLocation, "repo") + + fun loadRepoInformation() { + atomicShouldManuallyReload.set(true) + if (SkyHanniMod.feature.apiData.repoAutoUpdate) { + fetchRepository().thenRun(this::reloadRepository) + } else { + reloadRepository() + } + } + + private val atomicShouldManuallyReload = AtomicBoolean(false)//TODO FIX + + fun updateRepo() { + atomicShouldManuallyReload.set(true) + fetchRepository(true).thenRun { this.reloadRepository("Repo updated successful :)") } + } + + fun reloadLocalRepo() { + atomicShouldManuallyReload.set(true) + reloadRepository("Repo loaded from local files successful :)") + } + + private fun fetchRepository(command: Boolean = false): CompletableFuture { + return CompletableFuture.supplyAsync { + try { + val currentCommitJSON: JsonObject? = getJsonFromFile(File(configLocation, "currentCommit.json")) + latestRepoCommit = null + try { + InputStreamReader(URL(getCommitApiUrl()).openStream()) + .use { inReader -> + val commits: JsonObject = gson.fromJson(inReader, JsonObject::class.java) + latestRepoCommit = commits["sha"].asString + } + } catch (e: Exception) { + e.printStackTrace() + } + if (latestRepoCommit == null || latestRepoCommit!!.isEmpty()) return@supplyAsync false + if (File(configLocation, "repo").exists()) { + if (currentCommitJSON != null && currentCommitJSON["sha"].asString == latestRepoCommit) { + if (command) { + LorenzUtils.chat("§e[SkyHanni] §7The repo is already up to date!") + atomicShouldManuallyReload.set(false) + } + return@supplyAsync false + } + } + RepoUtils.recursiveDelete(repoLocation) + repoLocation.mkdirs() + val itemsZip = File(repoLocation, "sh-repo-main.zip") + try { + itemsZip.createNewFile() + } catch (e: IOException) { + return@supplyAsync false + } + val url = URL(getDownloadUrl(latestRepoCommit)) + val urlConnection = url.openConnection() + urlConnection.connectTimeout = 15000 + urlConnection.readTimeout = 30000 + try { + urlConnection.getInputStream().use { `is` -> + FileUtils.copyInputStreamToFile( + `is`, + itemsZip + ) + } + } catch (e: IOException) { + e.printStackTrace() + System.err.println("Failed to download SkyHanni Repo! Please report this issue to the mod creator") + if (command) { + LorenzUtils.error("An error occurred while trying to reload the repo! See logs for more info.") + } + return@supplyAsync false + } + RepoUtils.unzipIgnoreFirstFolder( + itemsZip.absolutePath, + repoLocation.absolutePath + ) + if (currentCommitJSON == null || currentCommitJSON["sha"].asString != latestRepoCommit) { + val newCurrentCommitJSON = JsonObject() + newCurrentCommitJSON.addProperty("sha", latestRepoCommit) + try { + writeJson(newCurrentCommitJSON, File(configLocation, "currentCommit.json")) + } catch (ignored: IOException) { + } + } + } catch (e: Exception) { + e.printStackTrace() + } + true + } + } + + private fun reloadRepository(answerMessage: String = ""): CompletableFuture { + val comp = CompletableFuture() + if (!atomicShouldManuallyReload.get()) return comp + Minecraft.getMinecraft().addScheduledTask { + try { + RepositoryReloadEvent(repoLocation, gson).postAndCatch() + comp.complete(null) + if (answerMessage.isNotEmpty()) { + LorenzUtils.chat("§e[SkyHanni] §a$answerMessage") + } + } catch (e: java.lang.Exception) { + comp.completeExceptionally(e) + LorenzUtils.error("An error occurred while trying to reload the repo! See logs for more info.") + } + } + return comp + } + + /** + * Parses a file in to a JsonObject. + */ + private fun getJsonFromFile(file: File?): JsonObject? { + try { + BufferedReader( + InputStreamReader( + FileInputStream(file), + StandardCharsets.UTF_8 + ) + ).use { reader -> + return gson.fromJson(reader, JsonObject::class.java) + } + } catch (e: java.lang.Exception) { + return null + } + } + + private fun getCommitApiUrl(): String { + val repoUser = "hannibal00212" + val repoName = "SkyHanni-REPO" + val repoBranch = "main" + return String.format("https://api.github.com/repos/%s/%s/commits/%s", repoUser, repoName, repoBranch) + } + + private fun getDownloadUrl(commitId: String?): String { + val repoUser = "hannibal00212" + val repoName = "SkyHanni-REPO" + return String.format("https://github.com/%s/%s/archive/%s.zip", repoUser, repoName, commitId) + } + + @Throws(IOException::class) + fun writeJson(json: JsonObject?, file: File) { + file.createNewFile() + BufferedWriter( + OutputStreamWriter( + FileOutputStream(file), + StandardCharsets.UTF_8 + ) + ).use { writer -> writer.write(gson.toJson(json)) } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/data/repo/RepoUtils.kt b/src/main/java/at/hannibal2/skyhanni/data/repo/RepoUtils.kt new file mode 100644 index 000000000..969b526cc --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/repo/RepoUtils.kt @@ -0,0 +1,102 @@ +package at.hannibal2.skyhanni.data.repo + +import com.google.gson.Gson +import com.google.gson.JsonObject +import java.io.* +import java.nio.charset.StandardCharsets +import java.nio.file.Files +import java.util.zip.ZipInputStream + +object RepoUtils { + + fun recursiveDelete(file: File) { + if (file.isDirectory && !Files.isSymbolicLink(file.toPath())) { + for (child in file.listFiles()) { + recursiveDelete(child) + } + } + file.delete() + } + + /** + * Modified from https://www.journaldev.com/960/java-unzip-file-example + */ + fun unzipIgnoreFirstFolder(zipFilePath: String, destDir: String) { + val dir = File(destDir) + // create output directory if it doesn't exist + if (!dir.exists()) dir.mkdirs() + val fis: FileInputStream + //buffer for read and write data to file + val buffer = ByteArray(1024) + try { + fis = FileInputStream(zipFilePath) + val zis = ZipInputStream(fis) + var ze = zis.nextEntry + while (ze != null) { + if (!ze.isDirectory) { + var fileName = ze.name + fileName = fileName.substring(fileName.split("/").toTypedArray()[0].length + 1) + val newFile = File(destDir + File.separator + fileName) + //create directories for sub directories in zip + File(newFile.parent).mkdirs() + if (!isInTree(dir, newFile)) { + throw RuntimeException( + "SkyHanni detected an invalid zip file. This is a potential security risk, please report this on the SkyHanni discord." + ) + } + val fos = FileOutputStream(newFile) + var len: Int + while (zis.read(buffer).also { len = it } > 0) { + fos.write(buffer, 0, len) + } + fos.close() + } + //close this ZipEntry + zis.closeEntry() + ze = zis.nextEntry + } + //close last ZipEntry + zis.closeEntry() + zis.close() + fis.close() + } catch (e: IOException) { + e.printStackTrace() + } + } + + @Throws(IOException::class) + private fun isInTree(rootDirectory: File, file: File): Boolean { + var rootDirectory = rootDirectory + var file: File? = file + file = file!!.canonicalFile + rootDirectory = rootDirectory.canonicalFile + while (file != null) { + if (file == rootDirectory) return true + file = file.parentFile + } + return false + } + + fun getConstant(repoLocation: File, constant: String, gson: Gson): JsonObject? { + return getConstant(repoLocation, constant, gson, JsonObject::class.java) + } + + private fun getConstant(repo: File, constant: String, gson: Gson, clazz: Class?): T? { + if (repo.exists()) { + val jsonFile = File(repo, "constants/$constant.json") + try { + BufferedReader( + InputStreamReader( + FileInputStream(jsonFile), + StandardCharsets.UTF_8 + ) + ).use { reader -> + return gson.fromJson(reader, clazz) + } + } catch (e: Exception) { + return null + } + } + return null + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/diana/GriffinBurrowFinder.kt b/src/main/java/at/hannibal2/skyhanni/diana/GriffinBurrowFinder.kt deleted file mode 100644 index bdbda2e50..000000000 --- a/src/main/java/at/hannibal2/skyhanni/diana/GriffinBurrowFinder.kt +++ /dev/null @@ -1,159 +0,0 @@ -package at.hannibal2.skyhanni.diana - -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.events.PacketEvent -import at.hannibal2.skyhanni.test.GriffinUtils.draw3DLine -import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypoint -import at.hannibal2.skyhanni.utils.* -import at.hannibal2.skyhanni.utils.ItemUtils.cleanName -import net.minecraft.client.Minecraft -import net.minecraft.entity.item.EntityArmorStand -import net.minecraft.network.play.server.S29PacketSoundEffect -import net.minecraft.network.play.server.S2APacketParticles -import net.minecraftforge.client.event.RenderWorldLastEvent -import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.EventPriority -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent -import java.util.* - -class GriffinBurrowFinder { - - private var ticks = 0 - val list = mutableListOf() - var lastArrowLine: Line? = null - - @SubscribeEvent - fun onClientTick(event: ClientTickEvent?) { - if (!LorenzUtils.inSkyblock) return - ticks++ - if (ticks % 5 == 0) { - checkEntities() - } - } - - @SubscribeEvent - fun onWorldChange(event: WorldEvent.Load) { - lastArrowLine = null - } - - @SubscribeEvent - fun onChatMessage(event: LorenzChatEvent) { - val message = event.message - if (message.startsWith("§eYou dug out a Griffin Burrow!") || - message == "§eYou finished the Griffin burrow chain! §r§7(4/4)" - ) { - lastArrowLine = null - } - } - - @SubscribeEvent - fun onWorldRender(event: RenderWorldLastEvent) { - if (lastArrowLine != null) { - var start = lastArrowLine!!.start - val y = (LocationUtils.playerLocation().y - 1) - start = LorenzVec(start.x, y, start.z) - val direction = lastArrowLine!!.direction - - event.drawWaypoint(start, LorenzColor.WHITE) - val nextPoint = start.add(direction.multiply(10)) -// event.drawWaypoint(nextPoint, LorenzColor.YELLOW) - - event.draw3DLine(start, start.add(direction.multiply(400)), LorenzColor.YELLOW, 3, true) - } - } - - var lastHarpTime = 0L - var lastHarpPitch = 0f - var lastHarpDistance = 0.0 - - @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true) - fun onChatPacket(event: PacketEvent.ReceiveEvent) { - val packet = event.packet - if (packet is S2APacketParticles) { - val x = packet.xCoordinate - val y = packet.yCoordinate - val z = packet.zCoordinate - val distance = LorenzVec(x, y, z).distance(LocationUtils.playerLocation()) - if (distance < 20) { -// LorenzDebug.log("") -// LorenzDebug.log("S2APacketParticles close") -// var particleType = packet.particleType -// var particleID = particleType.particleID -// LorenzDebug.log("particleType: $particleType") -// LorenzDebug.log("particleID: $particleID") -// LorenzDebug.log("distance: $distance") -// LorenzDebug.log("") - - } else { -// LorenzDebug.log("S2APacketParticles far") - } - } - if (packet is S29PacketSoundEffect) { - val x = packet.x - val y = packet.y - val z = packet.z - val distance = LorenzVec(x, y, z).distance(LocationUtils.playerLocation()) - if (distance < 20) { - val soundName = packet.soundName - val pitch = packet.pitch - val volume = packet.volume - if (soundName == "game.player.hurt" && volume == 0f) return - - if (soundName == "note.harp") { - - LorenzDebug.log("harp pitch: $pitch") - LorenzDebug.log("distance: $distance") - val now = System.currentTimeMillis() - if (lastHarpTime != 0L) { - LorenzDebug.log("") - val diffTime = now - lastHarpTime - LorenzDebug.log("diffTime: $diffTime") - val diffPitch = pitch - lastHarpPitch - LorenzDebug.log("diffPitch: $diffPitch") - val diffDistance = distance - lastHarpDistance - LorenzDebug.log("diffDistance: $diffDistance") - } - lastHarpTime = now - lastHarpPitch = pitch - lastHarpDistance = distance - LorenzDebug.log("") - return - } - - LorenzDebug.log("") - LorenzDebug.log("S29PacketSoundEffect close") - - LorenzDebug.log("soundName: $soundName") - LorenzDebug.log("pitch: $pitch") - LorenzDebug.log("volume: $volume") - LorenzDebug.log("") - } else { -// LorenzDebug.log("S29PacketSoundEffect far") - } - } - } - - private fun checkEntities() { - val playerLocation = LocationUtils.playerLocation() - for (entity in Minecraft.getMinecraft().theWorld.loadedEntityList) { - if (list.contains(entity.uniqueID)) continue - if (entity !is EntityArmorStand) continue - val distance = entity.getLorenzVec().distance(playerLocation) - if (distance > 10) continue - - - val itemStack = entity.inventory[0] ?: continue - if (itemStack.cleanName() != "Arrow") continue - - val rotationYaw = entity.rotationYaw - val direction = LorenzVec.getFromYawPitch(rotationYaw.toDouble(), 0.0) - - lastArrowLine = Line(entity.getLorenzVec(), direction) - list.add(entity.uniqueID) - LorenzDebug.log("distance: $distance") - } - } - - class Line(val start: LorenzVec, val direction: LorenzVec) -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonBossMessages.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonBossMessages.kt deleted file mode 100644 index 0dbfbd732..000000000 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonBossMessages.kt +++ /dev/null @@ -1,51 +0,0 @@ -package at.hannibal2.skyhanni.dungeon - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class DungeonBossMessages { - - @SubscribeEvent - fun onChatMessage(event: LorenzChatEvent) { - if (!LorenzUtils.inSkyblock) return - - if (!SkyHanniMod.feature.chat.dungeonBossMessages) return - - if (isBoss(event.message)) { - event.blockedReason = "dungeon_boss" - } - } - - private fun isBoss(message: String): Boolean { - when { - message.matchRegex("§([cd4])\\[BOSS] (.*)") -> { - when { - message.contains(" The Watcher§r§f: ") -> return true - message.contains(" Bonzo§r§f: ") -> return true - message.contains(" Scarf§r§f:") -> return true - message.contains("Professor§r§f") -> return true - message.contains(" Livid§r§f: ") || message.contains(" Enderman§r§f: ") -> return true - message.contains(" Thorn§r§f: ") -> return true - message.contains(" Sadan§r§f: ") -> return true - message.contains(" Maxor§r§c: ") -> return true - message.contains(" Storm§r§c: ") -> return true - message.contains(" Goldor§r§c: ") -> return true - message.contains(" Necron§r§c: ") -> return true - message.contains(" §r§4§kWither King§r§c:") -> return true - - message.endsWith(" Necron§r§c: That is enough, fool!") -> return true - message.endsWith(" Necron§r§c: Adventurers! Be careful of who you are messing with..") -> return true - message.endsWith(" Necron§r§c: Before I have to deal with you myself.") -> return true - } - } - - //M7 - Dragons - message == "§cThe Crystal withers your soul as you hold it in your hands!" -> return true - message == "§cIt doesn't seem like that is supposed to go there." -> return true - } - return false - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonChatFilter.kt deleted file mode 100644 index 7f1f2d938..000000000 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonChatFilter.kt +++ /dev/null @@ -1,224 +0,0 @@ -package at.hannibal2.skyhanni.dungeon - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class DungeonChatFilter { - - @SubscribeEvent - fun onChatMessage(event: LorenzChatEvent) { - if (!LorenzUtils.inSkyblock) return - - if (!SkyHanniMod.feature.chat.dungeonMessages) return - - val blockReason = block(event.message) - if (blockReason != "") { - event.blockedReason = "dungeon_$blockReason" - } - } - - private fun block(message: String): String { - when { - isPrepare(message) -> return "prepare" - isStart(message) -> return "start" - } - - if (!LorenzUtils.inDungeons) return "" - - return when { - isKey(message) -> "key" - isDoor(message) -> "door" - isPickup(message) -> "pickup" - isReminder(message) -> "reminder" - isBuff(message) -> "buff" - isNotPossible(message) -> "not_possible" - isDamage(message) -> "damage" - isAbility(message) -> "ability" - isPuzzle(message) -> "puzzle" - isEnd(message) -> "end" - - else -> "" - } - } - - private fun isDoor(message: String): Boolean = message == "§cThe §r§c§lBLOOD DOOR§r§c has been opened!" - - private fun isEnd(message: String): Boolean = when { - message.matchRegex("(.*) §r§eunlocked §r§d(.*) Essence §r§8x(.*)§r§e!") -> true - message.matchRegex(" §r§d(.*) Essence §r§8x(.*)") -> true - message.endsWith(" Experience §r§b(Team Bonus)") -> true - else -> false - } - - private fun isAbility(message: String): Boolean = when { - message == "§a§r§6Guided Sheep §r§ais now available!" -> true - message.matchRegex("§7Your Guided Sheep hit §r§c(.*) §r§7enemy for §r§c(.*) §r§7damage.") -> true - message == "§6Rapid Fire§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!" -> true - message == "§6Castle of Stone§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!" -> true - - - message.matchRegex("§a§lBUFF! §fYou were splashed by (.*) §fwith §r§cHealing VIII§r§f!") -> true - message.matchRegex("§aYou were healed for (.*) health by (.*)§a!") -> true - message.matchRegex("§aYou gained (.*) HP worth of absorption for 3s from §r(.*)§r§a!") -> true - message.matchRegex("§c(.*) §r§epicked up your (.*) Orb!") -> true - message.matchRegex("§cThis ability is on cooldown for (.*)s.") -> true - message.matchRegex("§a§l(.*) healed you for (.*) health!") -> true - message.matchRegex("§eYour bone plating reduced the damage you took by §r§c(.*)§r§e!") -> true - message.matchRegex("(.*) §r§eformed a tether with you!") -> true - message.matchRegex("§eYour tether with (.*) §r§ehealed you for §r§a(.*) §r§ehealth.") -> true - message.matchRegex("§7Your Implosion hit §r§c(.*) §r§7enemy for §r§c(.*) §r§7damage.") -> true - - message.matchRegex("§eYour §r§6Spirit Pet §r§ehealed (.*) §r§efor §r§a(.*) §r§ehealth!") -> true - message.matchRegex("§eYour §r§6Spirit Pet §r§ehit (.*) enemy for §r§c(.*) §r§edamage.") -> true - - message == "§dCreeper Veil §r§aActivated!" -> true - message == "§dCreeper Veil §r§cDe-activated!" -> true - message.matchRegex("§cYou need at least (.*) mana to activate this!") -> true - - message.matchRegex( - "§eYou were healed for §r§a(.*)§r§e health by §r(.*)§r§e's §r§9Healing Bow§r§e and " + "gained §r§c\\+(.*) Strength§r§e for 10 seconds." - ) -> true - message.matchRegex("(.*)§r§a granted you §r§c(.*) §r§astrength for §r§e20 §r§aseconds!") -> true - - message.matchRegex("§eYour fairy healed §r§ayourself §r§efor §r§a(.*) §r§ehealth!") -> true - message.matchRegex("§eYour fairy healed §r(.*) §r§efor §r§a(.*) §r§ehealth!") -> true - message.matchRegex("(.*) fairy healed you for §r§a(.*) §r§ehealth!") -> true - - else -> false - } - - private fun isDamage(message: String): Boolean = when { - message == "§cMute silenced you!" -> true - message.matchRegex("(.*) §r§aused §r(.*) §r§aon you!") -> true - message.matchRegex("§cThe (.*)§r§c struck you for (.*) damage!") -> true - message.matchRegex("§cThe (.*) hit you for (.*) damage!") -> true - message.matchRegex("§7(.*) struck you for §r§c(.*)§r§7 damage.") -> true - message.matchRegex("(.*) hit you for §r§c(.*)§r§7 damage.") -> true - message.matchRegex("(.*) hit you for §r§c(.*)§r§7 true damage.") -> true - message.matchRegex("§7(.*) exploded, hitting you for §r§c(.*)§r§7 damage.") -> true - message.matchRegex("(.*)§r§c hit you with §r(.*) §r§cfor (.*) damage!") -> true - message.matchRegex("(.*)§r§a struck you for §r§c(.*)§r§a damage!") -> true - message.matchRegex("(.*)§r§c struck you for (.*)!") -> true - - message.matchRegex("§7The Mage's Magma burnt you for §r§c(.*)§r§7 true damage.") -> true - - message.matchRegex("§7Your (.*) hit §r§c(.*) §r§7(enemy|enemies) for §r§c(.*) §r§7damage.") -> true - else -> false - } - - private fun isNotPossible(message: String): Boolean = when (message) { - "§cYou cannot hit the silverfish while it's moving!", - "§cYou cannot move the silverfish in that direction!", - "§cThere are blocks in the way!", - "§cThis chest has already been searched!", - "§cThis lever has already been used.", - "§cYou cannot do that in this room!", - "§cYou do not have the key for this door!", - "§cYou have already opened this dungeon chest!", - "§cYou cannot use abilities in this room!", - "§cA mystical force in this room prevents you from using that ability!" -> true - - else -> false - } - - private fun isBuff(message: String): Boolean = when { - message.matchRegex("§6§lDUNGEON BUFF! (.*) §r§ffound a §r§dBlessing of (.*)§r§f!(.*)") -> true - message.matchRegex("§6§lDUNGEON BUFF! §r§fYou found a §r§dBlessing of (.*)§r§f!(.*)") -> true - message.matchRegex("§6§lDUNGEON BUFF! §r§fA §r§dBlessing of (.*)§r§f was found! (.*)") -> true - message.matchRegex("§eA §r§a§r§dBlessing of (.*)§r§e was picked up!") -> true - message.matchRegex("(.*) §r§ehas obtained §r§a§r§dBlessing of (.*)§r§e!") -> true - message.matchRegex(" §r§7(Grants|Granted) you §r§a(.*) Strength §r§7and §r§a(.*) Crit Damage§r§7.") -> true - message.matchRegex(" §r§7(Grants|Granted) you §r§a(.*) Defense §r§7and §r§a+(.*) Damage§r§7.") -> true - message.matchRegex(" §r§7(Grants|Granted) you §r§a(.*) HP §r§7and §r§a+(.*)% §r§7health regeneration.") -> true - message.matchRegex(" §r§7(Grants|Granted) you §r§a(.*) Intelligence §r§7and §r§a+(.*)? Speed§r§7.") -> true - message.matchRegex(" §r§7Granted you §r§a+(.*) HP§r§7, §r§a(.*) Defense§r§7, §r§a(.*) Intelligence§r§7, and §r§a(.*) Strength§r§7.") -> true - message == "§a§lBUFF! §fYou have gained §r§cHealing V§r§f!" -> true - else -> false - } - - private fun isPuzzle(message: String): Boolean = when { - message.matchRegex("§a§lPUZZLE SOLVED! (.*) §r§ewasn't fooled by §r§c(.*)§r§e! §r§4G§r§co§r§6o§r§ed§r§a §r§2j§r§bo§r§3b§r§5!") -> true - message.matchRegex("§a§lPUZZLE SOLVED! (.*) §r§etied Tic Tac Toe! §r§4G§r§co§r§6o§r§ed§r§a §r§2j§r§bo§r§3b§r§5!") -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fThough I sit stationary in this prison that is §r§cThe Catacombs§r§f, my knowledge knows no bounds." -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fProve your knowledge by answering 3 questions and I shall reward you in ways that transcend time!" -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fAnswer incorrectly, and your moment of ineptitude will live on for generations." -> true - -// message == "§4[STATUE] Oruo the Omniscient§r§f: §r§f2 questions §r§fleft...and§r§f you will have proven your worth to me!" -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§f2 questions left... Then you will have proven your worth to me!" -> true - - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fOne more question!" -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fI bestow upon you all the power of a hundred years!" -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fYou've already proven enough to me! No need to press more of my buttons!" -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fI've had enough of you and your party fiddling with my buttons. Scram!" -> true - message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fEnough! My buttons are not to be pressed with such lack of grace!" -> true - message.matchRegex("§4\\[STATUE] Oruo the Omniscient§r§f: §r(.*) §r§fthinks the answer is §r§6 . §r(.*)§r§f! §r§fLock in your party's answer in my Chamber!") -> true - else -> false - } - - private fun isKey(message: String): Boolean = when { - message.matchRegex("(.*) §r§ehas obtained §r§a§r§6§r§8Wither Key§r§e!") -> true - message.matchRegex("(.*) opened a §r§8§lWITHER §r§adoor!") -> true - message.matchRegex("(.*) §r§ehas obtained §r§a§r§c§r§cBlood Key§r§e!") -> true - message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Beating Heart§r§e!") -> true - message == "§5A shiver runs down your spine..." -> true - message == "§eA §r§a§r§6§r§8Wither Key§r§e was picked up!" -> true - message == "§eA §r§a§r§c§r§cBlood Key§r§e was picked up!" -> true - - else -> false - } - - private fun isReminder(message: String): Boolean = when (message) { - "§e§lRIGHT CLICK §r§7on §r§7a §r§8WITHER §r§7door§r§7 to open it. This key can only be used to open §r§a1§r§7 door!", - "§e§lRIGHT CLICK §r§7on §r§7the §r§cBLOOD DOOR§r§7 to open it. This key can only be used to open §r§a1§r§7 door!" -> true - - else -> false - } - - private fun isPickup(message: String): Boolean = when { - message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Superboom TNT§r§e!") -> true - message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Superboom TNT §r§8x2§r§e!") -> true - message.matchRegex("§6§lRARE DROP! §r§9Hunk of Blue Ice §r§b\\(+(.*)% Magic Find!\\)") -> true - message.matchRegex("(.*) §r§ehas obtained §r§a§r§6Revive Stone§r§e!") -> true - message.matchRegex("(.*) §r§ffound a §r§dWither Essence§r§f! Everyone gains an extra essence!") -> true - message == "§fYou found a §r§dWither Essence§r§f! Everyone gains an extra essence!" -> true - message.matchRegex("§d(.*) the Fairy§r§f: You killed me! Take this §r§6Revive Stone §r§fso that my death is not in vain!") -> true - message.matchRegex("§d(.*) the Fairy§r§f: You killed me! I'll revive you so that my death is not in vain!") -> true - message.matchRegex("§d(.*) the Fairy§r§f: You killed me! I'll revive your friend §r(.*) §r§fso that my death is not in vain!") -> true - message.matchRegex("§d(.*) the Fairy§r§f: Have a great life!") -> true - message.matchRegex( - "§c(.*) §r§eYou picked up a Ability Damage Orb from (.*) §r§ehealing you for §r§c(.*) §r§eand granting you +§r§c(.*)% §r§eAbility Damage for §r§b10 §r§eseconds." - ) -> true - message.matchRegex( - "§c(.*) §r§eYou picked up a Damage Orb from (.*) §r§ehealing you for §r§c(.*) §r§eand granting you +§r§c(.*)% §r§eDamage for §r§b10 §r§eseconds." - ) -> true - message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Premium Flesh§r§e!") -> true - message.matchRegex("§6§lRARE DROP! §r§9Beating Heart §r§b(.*)") -> true - else -> false - } - - private fun isStart(message: String): Boolean = when { - message == "§e[NPC] §bMort§f: §rHere, I found this map when I first entered the dungeon." -> true - message == "§e[NPC] §bMort§f: §rYou should find it useful if you get lost." -> true - message == "§e[NPC] §bMort§f: §rGood luck." -> true - message == "§e[NPC] §bMort§f: §rTalk to me to change your class and ready up." -> true - - //§a[Berserk] §r§fMelee Damage §r§c48%§r§f -> §r§a88% - //§a[Berserk] §r§fWalk Speed §r§c38§r§f -> §r§a68 - message.matchRegex("§a(.*) §r§f(.*) §r§c(.*)§r§f -> §r§a(.*)") -> true - else -> false - } - - private fun isPrepare(message: String): Boolean = when { - message == "§aYour active Potion Effects have been paused and stored. They will be restored when you leave Dungeons! You are not allowed to use existing Potion Effects while in Dungeons." -> true - message.matchRegex("(.*) has started the dungeon countdown. The dungeon will begin in 1 minute.") -> true - message.matchRegex("§e[NPC] §bMort§f: §rTalk to me to change your class and ready up.") -> true - message.matchRegex("(.*) §a is now ready!") -> true - message.matchRegex("§aDungeon starts in (.*) seconds.") -> true - message == "§aDungeon starts in 1 second." -> true - message == "§aYou can no longer consume or splash any potions during the remainder of this Dungeon run!" -> true - else -> false - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonCleanEnd.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonCleanEnd.kt deleted file mode 100644 index f668fc22d..000000000 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonCleanEnd.kt +++ /dev/null @@ -1,130 +0,0 @@ -package at.hannibal2.skyhanni.dungeon - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.CheckRenderEntityEvent -import at.hannibal2.skyhanni.events.DamageIndicatorFinalBossEvent -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.events.PacketEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex -import net.minecraft.client.Minecraft -import net.minecraft.client.entity.EntityOtherPlayerMP -import net.minecraft.entity.item.EntityArmorStand -import net.minecraft.entity.monster.EntityGuardian -import net.minecraft.network.play.server.S1CPacketEntityMetadata -import net.minecraft.network.play.server.S2APacketParticles -import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class DungeonCleanEnd { - - private var bossDone = false - private var chestsSpawned = false - private var lastBossId: Int = -1 - - @SubscribeEvent - fun onChatMessage(event: LorenzChatEvent) { - if (!LorenzUtils.inDungeons) return - if (!SkyHanniMod.feature.dungeon.cleanEnd) return - - val message = event.message - - if (message.matchRegex("([ ]*)§r§c(The|Master Mode) Catacombs §r§8- §r§eFloor (.*)")) { - chestsSpawned = true - } - } - - private fun shouldBlock(): Boolean { - if (!LorenzUtils.inDungeons) return false - if (!SkyHanniMod.feature.dungeon.cleanEnd) return false - - if (!bossDone) return false - - return true - } - - @SubscribeEvent - fun onWorldChange(event: WorldEvent.Load) { - bossDone = false - chestsSpawned = false - lastBossId = -1 - } - - @SubscribeEvent - fun onBossDead(event: DamageIndicatorFinalBossEvent) { - if (!LorenzUtils.inDungeons) return - if (bossDone) return - - if (lastBossId == -1) { - lastBossId = event.id - } - } - - @SubscribeEvent - fun onHealthUpdatePacket(event: PacketEvent.ReceiveEvent) { - if (!LorenzUtils.inDungeons) return - if (!SkyHanniMod.feature.dungeon.cleanEnd) return - - if (bossDone) return - if (lastBossId == -1) return - - val packet = event.packet - if (packet !is S1CPacketEntityMetadata) return - if (packet.entityId != lastBossId) return - - for (watchableObject in packet.func_149376_c()) { - if (watchableObject.dataValueId == 6) { - val health = watchableObject.`object` as Float - if (health < 1) { - val dungeonFloor = DungeonData.dungeonFloor - LorenzUtils.chat("§eFloor $dungeonFloor done!") - bossDone = true - } - } - } - } - - @SubscribeEvent - fun onCheckRender(event: CheckRenderEntityEvent<*>) { - if (!shouldBlock()) return - - val entity = event.entity - - if (entity == Minecraft.getMinecraft().thePlayer) return - - if (SkyHanniMod.feature.dungeon.cleanEndF3IgnoreGuardians) { - if (DungeonData.isOneOf("F3", "M3")) { - if (entity is EntityGuardian) { - if (entity.entityId != lastBossId) { - if (Minecraft.getMinecraft().thePlayer.isSneaking) { - return - } - } - } - } - } - - if (chestsSpawned) { - if (entity is EntityArmorStand) { - if (!entity.hasCustomName()) { - return - } - } - if (entity is EntityOtherPlayerMP) { - return - } - } - - event.isCanceled = true - } - - @SubscribeEvent - fun onReceivePacket(event: PacketEvent.ReceiveEvent) { - if (!shouldBlock()) return - - - if (event.packet is S2APacketParticles) { - event.isCanceled = true - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonData.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonData.kt deleted file mode 100644 index eedf664a3..000000000 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonData.kt +++ /dev/null @@ -1,46 +0,0 @@ -package at.hannibal2.skyhanni.dungeon - -import at.hannibal2.skyhanni.events.DungeonEnterEvent -import at.hannibal2.skyhanni.misc.ScoreboardData -import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent - -class DungeonData { - - companion object { - var dungeonFloor: String? = null - - fun isOneOf(vararg floors: String): Boolean { - for (floor in floors) { - if (dungeonFloor == floor) { - return true - } - } - - return false - } - } - - @SubscribeEvent - fun onTick(event: TickEvent.ClientTickEvent) { - if (event.phase != TickEvent.Phase.START) return - if (LorenzUtils.inDungeons) { - if (dungeonFloor == null) { - for (line in ScoreboardData.sidebarLines) { - if (line.contains("The Catacombs (")) { - dungeonFloor = line.substringAfter("(").substringBefore(")") - DungeonEnterEvent(dungeonFloor!!).postAndCatch() - break - } - } - } - } - } - - @SubscribeEvent - fun onWorldChange(event: WorldEvent.Load) { - dungeonFloor = null - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonDeathCounter.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonDeathCounter.kt deleted file mode 100644 index eae6535da..000000000 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonDeathCounter.kt +++ /dev/null @@ -1,97 +0,0 @@ -package at.hannibal2.skyhanni.dungeon - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.DungeonEnterEvent -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.utils.GuiRender.renderString -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex -import net.minecraftforge.client.event.RenderGameOverlayEvent -import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class DungeonDeathCounter { - - private var textToRender = "" - private var deaths = 0 - - private fun isDeathMessage(message: String): Boolean = when { - message.matchRegex("§c ☠ §r§7You were killed by (.*)§r§7 and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r§7(.*) was killed by (.*) and became a ghost§r§7.") -> true - - message.matchRegex("§c ☠ §r§7You were crushed and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r§7§r(.*)§r§7 was crushed and became a ghost§r§7.") -> true - - message.matchRegex("§c ☠ §r§7You died to a trap and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r(.*)§r§7 died to a trap and became a ghost§r§7.") -> true - - message.matchRegex("§c ☠ §r§7You burnt to death and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r(.*)§r§7 burnt to death and became a ghost§r§7.") -> true - - message.matchRegex("§c ☠ §r§7You died and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r(.*)§r§7 died and became a ghost§r§7.") -> true - - message.matchRegex("§c ☠ §r§7You suffocated and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r§7§r(.*)§r§7 suffocated and became a ghost§r§7.") -> true - - message.matchRegex("§c ☠ §r§7You died to a mob and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r(.*)§7 died to a mob and became a ghost§r§7.") -> true - - message.matchRegex("§c ☠ §r§7You fell into a deep hole and became a ghost§r§7.") -> true - message.matchRegex("§c ☠ §r(.*)§r§7 fell into a deep hole and became a ghost§r§7.") -> true - - message.matchRegex("§c ☠ §r§(.*)§r§7 disconnected from the Dungeon and became a ghost§r§7.") -> true - - message.matchRegex("§c ☠ §r§7(.*)§r§7 fell to their death with help from §r(.*)§r§7 and became a ghost§r§7.") -> true - - else -> false - } - - @SubscribeEvent(receiveCanceled = true) - fun onChatPacket(event: LorenzChatEvent) { - if (!isEnabled()) return - - if (isDeathMessage(event.message)) { - deaths++ - LorenzUtils.chat("§c§l$deaths. DEATH!") - update() - } - } - - private fun update() { - if (deaths == 0) { - textToRender = "" - return - } - - val color = when (deaths) { - 1, 2 -> "§e" - 3 -> "§c" - else -> "§4" - } - textToRender = color + "Deaths: $deaths" - } - - @SubscribeEvent - fun onDungeonStart(event: DungeonEnterEvent) { - deaths = 0 - update() - } - - @SubscribeEvent - fun onWorldChange(event: WorldEvent.Load) { - deaths = 0 - update() - } - - @SubscribeEvent - fun renderOverlay(event: RenderGameOverlayEvent.Post) { - if (!isEnabled()) return - - SkyHanniMod.feature.dungeon.deathCounterPos.renderString(DungeonMilestoneDisplay.color + textToRender) - } - - private fun isEnabled(): Boolean { - return LorenzUtils.inDungeons && SkyHanniMod.feature.dungeon.deathCounter - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonHighlightClickedBlocks.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonHighlightClickedBlocks.kt deleted file mode 100644 index ff0ca6931..000000000 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonHighlightClickedBlocks.kt +++ /dev/null @@ -1,99 +0,0 @@ -package at.hannibal2.skyhanni.dungeon - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.events.PacketEvent -import at.hannibal2.skyhanni.utils.* -import at.hannibal2.skyhanni.utils.BlockUtils.getBlockAt -import at.hannibal2.skyhanni.utils.RenderUtils.drawColor -import at.hannibal2.skyhanni.utils.RenderUtils.drawString -import net.minecraft.init.Blocks -import net.minecraft.network.play.client.C08PacketPlayerBlockPlacement -import net.minecraftforge.client.event.RenderWorldLastEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class DungeonHighlightClickedBlocks { - - private val blocks = mutableListOf() - private var colorIndex = 0 - private val colors = listOf(LorenzColor.YELLOW, LorenzColor.AQUA, LorenzColor.GREEN, LorenzColor.LIGHT_PURPLE) - - private fun getNextColor(): LorenzColor { - var id = colorIndex + 1 - if (id == colors.size) id = 0 - colorIndex = id - return colors[colorIndex] - } - - @SubscribeEvent - fun onChatMessage(event: LorenzChatEvent) { - if (!SkyHanniMod.feature.dungeon.highlightClickedBlocks) return - if (!LorenzUtils.inDungeons) return - - if (event.message == "§cYou hear the sound of something opening...") { - event.blockedReason = "dungeon_highlight_clicked_block" - } - } - - @SubscribeEvent - fun onSendPacket(event: PacketEvent.SendEvent) { - if (!SkyHanniMod.feature.dungeon.highlightClickedBlocks) return - if (!LorenzUtils.inDungeons) return -// TODO add -// if (DungeonAPI.inBossRoom) return - if (event.packet !is C08PacketPlayerBlockPlacement || event.packet.stack == null) return - - val position = event.packet.position.toLorenzVec() - - if (blocks.any { it.position == position }) return - - val type: ClickedBlockType = when (position.getBlockAt()) { - Blocks.chest, Blocks.trapped_chest -> ClickedBlockType.CHEST - Blocks.lever -> ClickedBlockType.LEVER - Blocks.skull -> ClickedBlockType.WITHER_ESSENCE - else -> return - } - - if (type == ClickedBlockType.WITHER_ESSENCE) { - val text = BlockUtils.getSkinFromSkull(position.toBlocPos()) - if (text != "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQ" + - "ubmV0L3RleHR1cmUvYzRkYjRhZGZhOWJmNDhmZjVkNDE3M" + - "DdhZTM0ZWE3OGJkMjM3MTY1OWZjZDhjZDg5MzQ3NDlhZjRjY2U5YiJ9fX0=" - ) { - return - } - } - -// if (nearWaterRoom() && type == ClickedBlockType.LEVER) return - - val color = getNextColor() - val displayText = color.getChatColor() + "Clicked " + type.display - blocks.add(ClickedBlock(position, displayText, color, System.currentTimeMillis())) - } - - @SubscribeEvent - fun onWorldRender(event: RenderWorldLastEvent) { - if (!SkyHanniMod.feature.dungeon.highlightClickedBlocks) return - if (!LorenzUtils.inDungeons) return - - blocks.removeAll { System.currentTimeMillis() > it.time + 3000 } - blocks.forEach { - event.drawColor(it.position, it.color) - event.drawString(it.position.add(0.5, 0.5, 0.5), it.displayText, true) - } - } - - class ClickedBlock(val position: LorenzVec, val displayText: String, val color: LorenzColor, val time: Long) - - enum class ClickedBlockType(val display: String) { - LEVER("Lever"), - CHEST("Chest"), - WITHER_ESSENCE("Wither Essence"), - } - -// private fun nearWaterRoom(): Boolean { -// val playerLoc = -// LocationUtils.getPlayerLocation().add(LocationUtils.getPlayerLookingAtDirection().multiply(2)).add(0, 2, 0) -// return WaterBoardSolver.waterRoomDisplays.any { it.distance(playerLoc) < 3 } -// } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonMilestoneDisplay.kt b/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonMilestoneDisplay.kt deleted file mode 100644 index 96bfba678..000000000 --- a/src/main/java/at/hannibal2/skyhanni/dungeon/DungeonMilestoneDisplay.kt +++ /dev/null @@ -1,96 +0,0 @@ -package at.hannibal2.skyhanni.dungeon - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.DungeonEnterEvent -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.utils.GuiRender.renderString -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex -import net.minecraftforge.client.event.RenderGameOverlayEvent -import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import kotlin.concurrent.fixedRateTimer - -class DungeonMilestoneDisplay { - - - companion object { - private var textToRender = "" - var color = "" - var currentMilestone = 0 - var timeReached = 0L - - fun isMilestoneMessage(message: String): Boolean = when { - message.matchRegex("§e§l(.*) Milestone §r§e.§r§7: You have dealt §r§c(.*)§r§7 Total Damage so far! §r§a(.*)") -> true - message.matchRegex("§e§lArcher Milestone §r§e.§r§7: You have dealt §r§c(.*)§r§7 Ranged Damage so far! §r§a(.*)") -> true - message.matchRegex("§e§lHealer Milestone §r§e.§r§7: You have healed §r§a(.*)§r§7 Damage so far! §r§a(.*)") -> true - message.matchRegex("§e§lTank Milestone §r§e.§r§7: You have tanked and dealt §r§c(.*)§r§7 Total Damage so far! §r§a(.*)s") -> true - - else -> false - } - } - - init { - fixedRateTimer(name = "dungeon-milestone-display", period = 200) { - if (!isEnabled()) return@fixedRateTimer - checkVisibility() - } - } - - private fun checkVisibility() { - if (currentMilestone >= 3) { - if (System.currentTimeMillis() > timeReached + 3_000) - if (textToRender != "") { - textToRender = textToRender.substring(1) - } - } - } - - @SubscribeEvent(receiveCanceled = true) - fun onChatPacket(event: LorenzChatEvent) { - if (!isEnabled()) return - - if (isMilestoneMessage(event.message)) { - event.blockedReason = "dungeon_milestone" - currentMilestone++ - update() - } - } - - private fun update() { - if (currentMilestone > 3) return - if (currentMilestone == 3) { - timeReached = System.currentTimeMillis() - } - - color = when (currentMilestone) { - 0, 1 -> "§c" - 2 -> "§e" - else -> "§a" - } - textToRender = "Current Milestone: $currentMilestone" - } - - @SubscribeEvent - fun onWorldChange(event: WorldEvent.Load) { - textToRender = "" - currentMilestone = 0 - } - - @SubscribeEvent - fun onDungeonStart(event: DungeonEnterEvent) { - currentMilestone = 0 - update() - } - - @SubscribeEvent - fun renderOverlay(event: RenderGameOverlayEvent.Post) { - if (!isEnabled()) return - - SkyHanniMod.feature.dungeon.milestoneDisplayPos.renderString(color + textToRender) - } - - private fun isEnabled(): Boolean { - return LorenzUtils.inDungeons && SkyHanniMod.feature.dungeon.showMilestoneDisplay - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/events/PlayerSendChatEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/PlayerSendChatEvent.kt index 4ce9db1a8..1776b2bd0 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/PlayerSendChatEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/PlayerSendChatEvent.kt @@ -1,6 +1,6 @@ package at.hannibal2.skyhanni.events -import at.hannibal2.skyhanni.chat.PlayerMessageChannel +import at.hannibal2.skyhanni.features.chat.PlayerMessageChannel class PlayerSendChatEvent( diff --git a/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt index 841133ae9..f2c610e04 100644 --- a/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt +++ b/src/main/java/at/hannibal2/skyhanni/events/RepositoryReloadEvent.kt @@ -1,6 +1,6 @@ package at.hannibal2.skyhanni.events -import at.hannibal2.skyhanni.repo.RepoUtils +import at.hannibal2.skyhanni.data.repo.RepoUtils import com.google.gson.Gson import com.google.gson.JsonObject import java.io.File diff --git a/src/main/java/at/hannibal2/skyhanni/features/ButtonOnPause.kt b/src/main/java/at/hannibal2/skyhanni/features/ButtonOnPause.kt new file mode 100644 index 000000000..4e85f4399 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/ButtonOnPause.kt @@ -0,0 +1,51 @@ +package at.hannibal2.skyhanni.features + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.gui.config.ConfigEditor +import at.hannibal2.skyhanni.config.gui.core.GuiScreenElementWrapper +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraft.client.gui.GuiButton +import net.minecraft.client.gui.GuiIngameMenu +import net.minecraftforge.client.event.GuiScreenEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class ButtonOnPause { + private val buttonId = System.nanoTime().toInt() + + @SubscribeEvent + fun onGuiAction(event: GuiScreenEvent.ActionPerformedEvent.Post) { + if (!LorenzUtils.isOnHypixel) return + + if (SkyHanniMod.feature.misc.configButtonOnPause && event.gui is GuiIngameMenu && event.button.id == buttonId) { + SkyHanniMod.screenToOpen = GuiScreenElementWrapper( + ConfigEditor( + SkyHanniMod.feature + ) + ) + } + } + + @SubscribeEvent + fun onGuiInitPost(event: GuiScreenEvent.InitGuiEvent.Post) { + if (!LorenzUtils.isOnHypixel) return + + if (SkyHanniMod.feature.misc.configButtonOnPause && event.gui is GuiIngameMenu) { + val x = event.gui.width - 105 + val x2 = x + 100 + var y = event.gui.height - 22 + var y2 = y + 20 + val sorted = event.buttonList.sortedWith { a, b -> b.yPosition + b.height - a.yPosition + a.height } + for (button in sorted) { + val otherX = button.xPosition + val otherX2 = button.xPosition + button.width + val otherY = button.yPosition + val otherY2 = button.yPosition + button.height + if (otherX2 > x && otherX < x2 && otherY2 > y && otherY < y2) { + y = otherY - 20 - 2 + y2 = y + 20 + } + } + event.buttonList.add(GuiButton(buttonId, x, 0.coerceAtLeast(y), 100, 20, "SkyHanni")) + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/CurrentPetDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/CurrentPetDisplay.kt new file mode 100644 index 000000000..f0e8e033e --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/CurrentPetDisplay.kt @@ -0,0 +1,47 @@ +package at.hannibal2.skyhanni.features + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.utils.GuiRender.renderString +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.between +import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex +import net.minecraftforge.client.event.RenderGameOverlayEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class CurrentPetDisplay { + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + if (!LorenzUtils.inSkyblock) return + + var blocked = false + + val message = event.message + if (message.matchRegex("§aYou summoned your §r(.*)§r§a!")) { + SkyHanniMod.feature.hidden.currentPet = message.between("your §r", "§r§a") + blocked = true + } + if (message.matchRegex("§cAutopet §eequipped your §7(.*)§e! §a§lVIEW RULE")) { + SkyHanniMod.feature.hidden.currentPet = message.between("] ", "§e!") + blocked = true + } + if (message.matchRegex("§aYou despawned your §r(.*)§r§a!")) { + SkyHanniMod.feature.hidden.currentPet = "" + blocked = true + } + + if (blocked && SkyHanniMod.feature.misc.petDisplay) { + event.blockedReason = "pets" + } + } + + @SubscribeEvent + fun renderOverlay(event: RenderGameOverlayEvent.Post) { + if (!LorenzUtils.inSkyblock) return + + if (!SkyHanniMod.feature.misc.petDisplay) return + + SkyHanniMod.feature.misc.petDisplayPos.renderString(SkyHanniMod.feature.hidden.currentPet) + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/ExpBottleOnGroundHider.kt b/src/main/java/at/hannibal2/skyhanni/features/ExpBottleOnGroundHider.kt new file mode 100644 index 000000000..c9e2b4bf4 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/ExpBottleOnGroundHider.kt @@ -0,0 +1,19 @@ +package at.hannibal2.skyhanni.features + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.CheckRenderEntityEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraft.entity.item.EntityXPOrb +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class ExpBottleOnGroundHider { + @SubscribeEvent + fun onCheckRender(event: CheckRenderEntityEvent<*>) { + if (!LorenzUtils.inSkyblock) return + if (!SkyHanniMod.feature.misc.hideExpBottles) return + + if (event.entity is EntityXPOrb) { + event.isCanceled = true + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/SummoningSoulsName.kt b/src/main/java/at/hannibal2/skyhanni/features/SummoningSoulsName.kt new file mode 100644 index 000000000..478cdc100 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/SummoningSoulsName.kt @@ -0,0 +1,135 @@ +package at.hannibal2.skyhanni.features + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.features.damageindicator.hasNameTagWith +import at.hannibal2.skyhanni.test.GriffinJavaUtils +import at.hannibal2.skyhanni.utils.ItemUtils.getSkullTexture +import at.hannibal2.skyhanni.utils.LocationUtils +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzVec +import at.hannibal2.skyhanni.utils.RenderUtils.drawString +import at.hannibal2.skyhanni.utils.getLorenzVec +import net.minecraft.client.Minecraft +import net.minecraft.entity.EntityLiving +import net.minecraft.entity.item.EntityArmorStand +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import java.util.concurrent.atomic.AtomicReference + +class SummoningSoulsName { + + var tick = 0 + val texture = + "ewogICJ0aW1lc3RhbXAiIDogMTYwMTQ3OTI2NjczMywKICAicHJvZmlsZUlkIiA6ICJmMzA1ZjA5NDI0NTg0ZjU" + + "4YmEyYjY0ZjAyZDcyNDYyYyIsCiAgInByb2ZpbGVOYW1lIiA6ICJqcm9ja2EzMyIsCiAgInNpZ25hdH" + + "VyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgI" + + "nVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS81YWY0MDM1ZWMwZGMx" + + "NjkxNzc4ZDVlOTU4NDAxNzAyMjdlYjllM2UyOTQzYmVhODUzOTI5Y2U5MjNjNTk4OWFkIgogICAgfQogIH0KfQ" + + val souls = mutableMapOf() + val mobsLastLocation = mutableMapOf() + val mobsName = mutableMapOf() + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (!isEnabled()) return + + tick++ + //TODO use packets instead of this + if (tick % 1 == 0) { + check() + } + } + + private fun check() { + val minecraft = Minecraft.getMinecraft() + val world = minecraft.theWorld + for (entity in world.loadedEntityList) { + if (souls.contains(entity)) continue + + if (entity is EntityArmorStand) { + if (isSoul(entity)) { + val soulLocation = entity.getLorenzVec() + + val map = mutableMapOf() + for ((mob, loc) in mobsLastLocation) { + val distance = loc.distance(soulLocation) + map[mob] = distance + } + + val nearestMob = GriffinJavaUtils.sortByValueAsc(map).firstNotNullOfOrNull { it.key } + if (nearestMob != null) { +// val mobDistance = nearestMob.getLorenzVec().add(0.0, -1.4375, 0.0) +// val distance = mobDistance.distance(soulLocation) +// val diff = mobDistance.add(soulLocation.multiply(-1)) + +// println(" ") +// println("mobDistance: $mobDistance") +// println("soulLocation: $soulLocation") +// println("diff: $diff") +// LorenzUtils.chat("distance: $distance") + val name = mobsName[nearestMob]!! +// LorenzUtils.chat("maybe its $name") + souls[entity] = name + } + + } + } + } + + for (entity in world.loadedEntityList) { + + if (entity is EntityLiving) { + val boo = AtomicReference() + if (entity.hasNameTagWith(2, "§c❤", consumer = { + if (!it.name.contains("§e0")) { + boo.set(it.name) + } + })) { + val name = boo.get() + if (name != null) { + mobsLastLocation[entity] = entity.getLorenzVec() + mobsName[entity] = name + } + } + } + } + + souls.keys.removeIf { it !in world.loadedEntityList } + //TODO fix overhead! +// mobs.keys.removeIf { it !in world.loadedEntityList } + } + + @SubscribeEvent + fun onWorldRender(event: RenderWorldLastEvent) { + if (!isEnabled()) return + + val playerLocation = LocationUtils.playerEyeLocation() + for ((entity, name) in souls) { + val vec = entity.getLorenzVec() + if (LocationUtils.canSee(playerLocation, vec.add(0.0, 2.0, 0.0))) { + event.drawString(vec.add(0.0, 2.5, 0.0), name, true) + } + } + } + + private fun isSoul(entity: EntityArmorStand): Boolean { + for (stack in entity.inventory) { + if (stack != null) { + val skullTexture = stack.getSkullTexture() + if (skullTexture != null) { + if (skullTexture == texture) { + return true + } + } + } + } + + return false + } + + private fun isEnabled(): Boolean { + return LorenzUtils.inSkyblock && SkyHanniMod.feature.misc.summonSoulDisplay + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/anvil/AnvilCombineHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/anvil/AnvilCombineHelper.kt new file mode 100644 index 000000000..251c4e7a6 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/anvil/AnvilCombineHelper.kt @@ -0,0 +1,82 @@ +package at.hannibal2.skyhanni.features.anvil + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.LorenzColor +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.RenderUtils.highlight +import net.minecraft.client.gui.inventory.GuiChest +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.inventory.ContainerChest +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import org.lwjgl.opengl.GL11 + +class AnvilCombineHelper { + + @SubscribeEvent + fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { + if (!LorenzUtils.inSkyblock) return + if (!SkyHanniMod.feature.inventory.anvilCombineHelper) return + + if (event.gui !is GuiChest) return + val guiChest = event.gui + val chest = guiChest.inventorySlots as ContainerChest + val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() + + if (chestName != "Anvil") return + + val matchLore = mutableListOf() +// var compareItem: ItemStack? = null + + for (slot in chest.inventorySlots) { + if (slot == null) continue + + if (slot.slotNumber != slot.slotIndex) continue + if (slot.stack == null) continue + + if (slot.slotNumber == 29) { +// slot highlight LorenzColor.GREEN + val lore = slot.stack.getLore() +// compareItem = slot.stack + matchLore.addAll(lore) + break +// } else if (slot.slotIndex == 29) { +// slot highlight LorenzColor.YELLOW + } + } + + val lightingState = GL11.glIsEnabled(GL11.GL_LIGHTING) + GlStateManager.disableLighting() + GlStateManager.color(1f, 1f, 1f, 1f) + + if (matchLore.isEmpty()) return + + for (slot in chest.inventorySlots) { + if (slot == null) continue + + if (slot.slotNumber == slot.slotIndex) continue + if (slot.stack == null) continue + + + if (matchLore == slot.stack.getLore()) { + slot highlight LorenzColor.GREEN + } + +// if (compareItem == slot.stack) { +// slot highlight LorenzColor.GREEN +// } else if (compareItem.metadata == slot.stack.metadata) { +// slot highlight LorenzColor.YELLOW +// } + +// if (slot.slotNumber == 3) { +//// slot highlight LorenzColor.GREEN +//// } else if (slot.slotIndex == 4) { +//// slot highlight LorenzColor.YELLOW +//// } +// } + + if (lightingState) GlStateManager.enableLighting() + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt new file mode 100644 index 000000000..3de78206b --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt @@ -0,0 +1,59 @@ +package at.hannibal2.skyhanni.features.bazaar + +import at.hannibal2.skyhanni.utils.LorenzUtils + +class BazaarApi { + + companion object { + private val bazaarMap = mutableMapOf() + + fun isBazaarInventory(inventoryName: String): Boolean { + if (inventoryName.contains(" ➜ ") && !inventoryName.contains("Museum")) return true + if (BazaarOrderHelper.isBazaarOrderInventory(inventoryName)) return true + + return when (inventoryName) { + "Your Bazaar Orders" -> true + "How many do you want?" -> true + "How much do you want to pay?" -> true + "Confirm Buy Order" -> true + "Confirm Instant Buy" -> true + "At what price are you selling?" -> true + "Confirm Sell Offer" -> true + "Order options" -> true + + else -> false + } + } + + fun getCleanBazaarName(name: String): String { + if (name.endsWith(" Gemstone")) { + return name.substring(6) + } + if (name.startsWith("§")) { + return name.substring(2) + } + + return name + } + + fun getBazaarDataForName(name: String): BazaarData { + if (bazaarMap.containsKey(name)) { + val bazaarData = bazaarMap[name] + if (bazaarData != null) { + return bazaarData + } + LorenzUtils.error("Bazaar data is null for item '$name'") + } + throw Error("no bz data found for name '$name'") + } + + fun isBazaarItem(name: String): Boolean { + val bazaarName = getCleanBazaarName(name) + return bazaarMap.containsKey(bazaarName) + } + } + + init { + BazaarDataGrabber(bazaarMap).start() + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarBestSellMethod.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarBestSellMethod.kt new file mode 100644 index 000000000..c4afc33fc --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarBestSellMethod.kt @@ -0,0 +1,79 @@ +package at.hannibal2.skyhanni.features.bazaar + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.utils.GuiRender.renderString +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.NumberUtil +import net.minecraft.client.gui.inventory.GuiChest +import net.minecraft.inventory.ContainerChest +import net.minecraftforge.client.event.GuiScreenEvent +import net.minecraftforge.fml.common.eventhandler.EventPriority +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class BazaarBestSellMethod { + + companion object { + private var textToRender = "" + } + + @SubscribeEvent + fun onBackgroundDrawn(event: GuiContainerEvent.CloseWindowEvent) { + textToRender = "" + } + + @SubscribeEvent + fun onGuiDrawEvent(event: GuiScreenEvent.DrawScreenEvent.Post) { + if (!isEnabled()) return + textToRender = getNewText(event) + } + + private fun getNewText(event: GuiScreenEvent.DrawScreenEvent.Post): String { + try { + if (event.gui !is GuiChest) return "" + val chest = (event.gui as GuiChest).inventorySlots as ContainerChest + + val inv = chest.lowerChestInventory ?: return "" + + val buyInstantly = inv.getStackInSlot(10) + if (buyInstantly == null || buyInstantly.displayName != "§aBuy Instantly") return "" + val bazaarItem = inv.getStackInSlot(13) ?: return "" + var name = bazaarItem.displayName + name = BazaarApi.getCleanBazaarName(name) + val data = BazaarApi.getBazaarDataForName(name) + + var having = 0 + for (slot in chest.inventorySlots) { + if (slot == null) continue + if (slot.slotNumber == slot.slotIndex) continue + if (slot.stack == null) continue + val stack = slot.stack + val displayName = stack.displayName + if (BazaarApi.getCleanBazaarName(displayName) == name) { + having += stack.stackSize + } + } + + if (having <= 0) return "" + + val totalDiff = (data.buyPrice - data.sellPrice) * having + val result = NumberUtil.format(totalDiff.toInt()) + + return "§b$name§f sell difference: §e$result coins" + } catch (e: Error) { + e.printStackTrace() + return "" + } + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + fun renderOverlay(event: GuiScreenEvent.BackgroundDrawnEvent) { + if (!isEnabled()) return + + SkyHanniMod.feature.bazaar.bestSellMethodPos.renderString(textToRender) + } + + private fun isEnabled(): Boolean { + return LorenzUtils.inSkyblock && SkyHanniMod.feature.bazaar.bestSellMethod + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarData.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarData.kt new file mode 100644 index 000000000..b43cb1eb3 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarData.kt @@ -0,0 +1,3 @@ +package at.hannibal2.skyhanni.features.bazaar + +data class BazaarData(val apiName: String, val itemName: String, val sellPrice: Double, val buyPrice: Double) \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataGrabber.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataGrabber.kt new file mode 100644 index 000000000..324f180de --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarDataGrabber.kt @@ -0,0 +1,113 @@ +package at.hannibal2.skyhanni.features.bazaar + +import at.hannibal2.skyhanni.utils.APIUtil +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.round +import kotlin.concurrent.fixedRateTimer + +internal class BazaarDataGrabber(private var bazaarMap: MutableMap) { + + companion object { + private val itemNames = mutableMapOf() + + private var lastData = "" + var lastTime = 0L + var blockNoChange = false + var currentlyUpdating = false + } + + private fun loadItemNames(): Boolean { + currentlyUpdating = true + try { + val itemsData = APIUtil.getJSONResponse("https://api.hypixel.net/resources/skyblock/items") + for (element in itemsData["items"].asJsonArray) { + val jsonObject = element.asJsonObject + val name = jsonObject["name"].asString + val id = jsonObject["id"].asString + itemNames[id] = name + } + currentlyUpdating = false + return true + } catch (e: Throwable) { + e.printStackTrace() + LorenzUtils.error("Error while trying to read bazaar item list from api: " + e.message) + currentlyUpdating = false + return false + } + } + + fun start() { + fixedRateTimer(name = "skyhanni-bazaar-update", period = 1000L) { + if (!LorenzUtils.inSkyblock) { + return@fixedRateTimer + } + + if (currentlyUpdating) { + LorenzUtils.error("Bazaar update took too long! Error?") + return@fixedRateTimer + } + + if (itemNames.isEmpty()) { + if (!loadItemNames()) { + return@fixedRateTimer + } + } + checkIfUpdateNeeded() + } + } + + private fun checkIfUpdateNeeded() { + if (lastData != "") { + if (System.currentTimeMillis() - lastTime > 9_000) { + blockNoChange = true + } else { + if (blockNoChange) { + return + } + } + } + + currentlyUpdating = true + updateBazaarData() + currentlyUpdating = false + } + + private fun updateBazaarData() { + val bazaarData = APIUtil.getJSONResponse("https://api.hypixel.net/skyblock/bazaar") + if (bazaarData.toString() != lastData) { + lastData = bazaarData.toString() + lastTime = System.currentTimeMillis() + } + + val products = bazaarData["products"].asJsonObject + + for (entry in products.entrySet()) { + val apiName = entry.key + + if (apiName == "ENCHANTED_CARROT_ON_A_STICK") continue + if (apiName == "BAZAAR_COOKIE") continue + + val itemData = entry.value.asJsonObject + + val itemName = itemNames.getOrDefault(apiName, null) + if (itemName == null) { + LorenzUtils.error("Bazaar item name is null for '$apiName'! Restart to fix this problem!") + continue + } + + val sellPrice: Double = try { + itemData["sell_summary"].asJsonArray[0].asJsonObject["pricePerUnit"].asDouble.round(1) + } catch (e: Exception) { + 0.0 + } + val buyPrice: Double = try { + itemData["buy_summary"].asJsonArray[0].asJsonObject["pricePerUnit"].asDouble.round(1) + } catch (e: Exception) { + 0.0 + } + + val data = BazaarData(apiName, itemName, sellPrice, buyPrice) + bazaarMap[itemName] = data + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarOrderHelper.kt b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarOrderHelper.kt new file mode 100644 index 000000000..18822e7c2 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarOrderHelper.kt @@ -0,0 +1,87 @@ +package at.hannibal2.skyhanni.features.bazaar + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.LorenzColor +import at.hannibal2.skyhanni.utils.RenderUtils.highlight +import net.minecraft.client.gui.inventory.GuiChest +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.inventory.ContainerChest +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import org.lwjgl.opengl.GL11 + +class BazaarOrderHelper { + + companion object { + fun isBazaarOrderInventory(inventoryName: String): Boolean = when (inventoryName) { + "Your Bazaar Orders" -> true + "Co-op Bazaar Orders" -> true + else -> false + } + } + + @SubscribeEvent + fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { + if (!SkyHanniMod.feature.bazaar.orderHelper) return + if (event.gui !is GuiChest) return + val guiChest = event.gui + val chest = guiChest.inventorySlots as ContainerChest + val inventoryName = chest.lowerChestInventory.displayName.unformattedText.trim() + + if (!isBazaarOrderInventory(inventoryName)) return + val lightingState = GL11.glIsEnabled(GL11.GL_LIGHTING) + GlStateManager.disableLighting() + GlStateManager.color(1f, 1f, 1f, 1f) + + out@ for (slot in chest.inventorySlots) { + if (slot == null) continue + if (slot.slotNumber != slot.slotIndex) continue + if (slot.stack == null) continue + + val stack = slot.stack + val displayName = stack.displayName + val isSelling = displayName.startsWith("§6§lSELL§7: ") + val isBuying = displayName.startsWith("§a§lBUY§7: ") + if (!isSelling && !isBuying) continue + + val text = displayName.split("§7: ")[1] + val name = BazaarApi.getCleanBazaarName(text) + val data = BazaarApi.getBazaarDataForName(name) + val buyPrice = data.buyPrice + val sellPrice = data.sellPrice + + val itemLore = stack.getLore() + for (line in itemLore) { + if (line.startsWith("§7Filled:")) { + if (line.endsWith(" §a§l100%!")) { + slot highlight LorenzColor.GREEN + continue@out + } + } + } + for (line in itemLore) { + if (line.startsWith("§7Price per unit:")) { + var text = line.split(": §6")[1] + text = text.substring(0, text.length - 6) + text = text.replace(",", "") + val price = text.toDouble() + if (isSelling) { + if (buyPrice < price) { + slot highlight LorenzColor.GOLD + continue@out + } + } else { + if (sellPrice > price) { + slot highlight LorenzColor.GOLD + continue@out + } + } + + } + } + } + + if (lightingState) GlStateManager.enableLighting() + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt new file mode 100644 index 000000000..4dc106249 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt @@ -0,0 +1,301 @@ +package at.hannibal2.skyhanni.features.chat + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class ChatFilter { + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + if (!LorenzUtils.isOnHypixel) return + + val blockReason = block(event.message) + if (blockReason != "") { + event.blockedReason = blockReason + } + } + + private fun block(message: String): String = when { + message.startsWith("§aYou are playing on profile: §e") -> "profile"//TODO move into own class + lobby(message) && SkyHanniMod.feature.chat.hypixelHub -> "lobby" + empty(message) && SkyHanniMod.feature.chat.empty -> "empty" + warping(message) && SkyHanniMod.feature.chat.warping -> "warping" + welcome(message) && SkyHanniMod.feature.chat.welcome -> "welcome" + guild(message) && SkyHanniMod.feature.chat.others -> "guild" + killCombo(message) && SkyHanniMod.feature.chat.others -> "kill_combo" + bazaarAndAHMiniMessages(message) && SkyHanniMod.feature.chat.others -> "bz_ah_minis" + watchdogAnnouncement(message) && SkyHanniMod.feature.chat.others -> "watchdog" + slayer(message) && SkyHanniMod.feature.chat.others -> "slayer" + slayerDrop(message) && SkyHanniMod.feature.chat.others -> "slayer_drop" + uselessDrop(message) && SkyHanniMod.feature.chat.others -> "useless_drop" + uselessNotification(message) && SkyHanniMod.feature.chat.others -> "useless_notification" + party(message) && SkyHanniMod.feature.chat.others -> "party" + money(message) && SkyHanniMod.feature.chat.others -> "money" + winterIsland(message) && SkyHanniMod.feature.chat.others -> "winter_island" + uselessWarning(message) && SkyHanniMod.feature.chat.others -> "useless_warning" + friendJoin(message) && SkyHanniMod.feature.chat.others -> "friend_join" + annoyingSpam(message) && SkyHanniMod.feature.chat.others -> "annoying_spam" + + + else -> "" + } + + //TODO split into others + private fun annoyingSpam(message: String): Boolean { + if (message.matchRegex("§7Your Implosion hit (.*) for §r§c(.*) §r§7damage.")) return true + if (message.matchRegex("§7Your Molten Wave hit (.*) for §r§c(.*) §r§7damage.")) return true + if (message == "§cThere are blocks in the way!") return true + if (message == "§aYour Blessing enchant got you double drops!") return true + if (message == "§cYou can't use the wardrobe in combat!") return true + if (message == "§6§lGOOD CATCH! §r§bYou found a §r§fFish Bait§r§b.") return true + if (message == "§6§lGOOD CATCH! §r§bYou found a §r§aGrand Experience Bottle§r§b.") return true + if (message == "§6§lGOOD CATCH! §r§bYou found a §r§aBlessed Bait§r§b.") return true + if (message == "§6§lGOOD CATCH! §r§bYou found a §r§fDark Bait§r§b.") return true + if (message == "§6§lGOOD CATCH! §r§bYou found a §r§fLight Bait§r§b.") return true + if (message == "§6§lGOOD CATCH! §r§bYou found a §r§aHot Bait§r§b.") return true + if (message == "§6§lGOOD CATCH! §r§bYou found a §r§fSpooky Bait§r§b.") return true + + return false + } + + private fun friendJoin(message: String): Boolean { + return when { + message.matchRegex("§aFriend > §r(.*) §r§e(joined|left).") -> { + true + } + else -> false + } + + } + + private fun uselessNotification(message: String): Boolean { + return when { + message == "§eYour previous §r§6Plasmaflux Power Orb §r§ewas removed!" -> true + + message == "§aYou used your §r§6Mining Speed Boost §r§aPickaxe Ability!" -> true + message == "§cYour Mining Speed Boost has expired!" -> true + message == "§a§r§6Mining Speed Boost §r§ais now available!" -> true + + else -> false + } + } + + private fun uselessWarning(message: String): Boolean = when { + message == "§cYou are sending commands too fast! Please slow down." -> true//TODO prevent in the future + message == "§cYou can't use this while in combat!" -> true + message == "§cYou can not modify your equipped armor set!" -> true + message == "§cPlease wait a few seconds between refreshing!" -> true + message == "§cThis item is not salvageable!" -> true//prevent in the future + message == "§cPlace a Dungeon weapon or armor piece above the anvil to salvage it!" -> true + message == "§cWhoa! Slow down there!" -> true + message == "§cWait a moment before confirming!" -> true + message == "§cYou need to be out of combat for 3 seconds before opening the SkyBlock Menu!" -> true//TODO prevent in the future + + else -> false + } + + private fun uselessDrop(message: String): Boolean { + when { + message.matchRegex("§6§lRARE DROP! §r§aEnchanted Ender Pearl (.*)") -> return true + + message.matchRegex("§6§lRARE DROP! §r§fCarrot (.*)") -> return true + message.matchRegex("§6§lRARE DROP! §r§fPotato (.*)") -> return true + + message.matchRegex("§6§lRARE DROP! §r§9Machine Gun Bow (.*)") -> return true + message.matchRegex("§6§lRARE DROP! §r§5Earth Shard (.*)") -> return true + message.matchRegex("§6§lRARE DROP! §r§5Zombie Lord Chestplate (.*)") -> return true + } + + return false + } + + private fun winterIsland(message: String): Boolean = when { + message.matchRegex(" §r§f☃ §r§7§r(.*) §r§7mounted a §r§fSnow Cannon§r§7!") -> true + + else -> false + } + + private fun money(message: String): Boolean { + if (isBazaar(message)) return true + if (isAuctionHouse(message)) return true + + return false + } + + private fun isAuctionHouse(message: String): Boolean { + if (message == "§b-----------------------------------------------------") return true + if (message == "§eVisit the Auction House to collect your item!") return true + + return false + } + + private fun isBazaar(message: String): Boolean { + if (message.matchRegex("§eBuy Order Setup! §r§a(.*)§r§7x (.*) §r§7for §r§6(.*) coins§r§7.")) return true + if (message.matchRegex("§eSell Offer Setup! §r§a(.*)§r§7x (.*) §r§7for §r§6(.*) coins§r§7.")) return true + if (message.matchRegex("§cCancelled! §r§7Refunded §r§6(.*) coins §r§7from cancelling buy order!")) return true + if (message.matchRegex("§cCancelled! §r§7Refunded §r§a(.*)§r§7x (.*) §r§7from cancelling sell offer!")) return true + + return false + } + + private fun party(message: String): Boolean { + if (message == "§9§m-----------------------------") return true + if (message == "§9§m-----------------------------------------------------") return true + + return false + } + + private fun slayerDrop(message: String): Boolean { + //Revenant + if (message.matchRegex("§b§lRARE DROP! §r§7\\(§r§f§r§9Revenant Viscera§r§7\\) (.*)")) return true + if (message.matchRegex("§b§lRARE DROP! §r§7\\(§r§f§r§7(.*)x §r§f§r§9Foul Flesh§r§7\\) (.*)")) return true + if (message.matchRegex("§b§lRARE DROP! §r§7\\(§r§f§r§9Foul Flesh§r§7\\) (.*)")) return true + if (message.matchRegex("§6§lRARE DROP! §r§5Golden Powder (.*)")) return true + if (message.matchRegex("§9§lVERY RARE DROP! §r§7\\(§r§f§r§2(.*) Pestilence Rune I§r§7\\) (.*)")) { + LorenzUtils.debug("check regex for this blocked message!") + return true + } + if (message.matchRegex("§5§lVERY RARE DROP! §r§7\\(§r§f§r§5Revenant Catalyst§r§7\\) (.*)")) return true + if (message.matchRegex("§5§lVERY RARE DROP! §r§7\\(§r§f§r§9Undead Catalyst§r§7\\) (.*)")) return true + + //Enderman + if (message.matchRegex("§b§lRARE DROP! §r§7\\(§r§f§r§7(.*)x §r§f§r§aTwilight Arrow Poison§r§7\\) (.*)")) return true + if (message.matchRegex("§9§lVERY RARE DROP! §r§7\\(§r§fMana Steal I§r§7\\) (.*)")) return true + if (message.matchRegex("§5§lVERY RARE DROP! §r§7\\(§r§f§r§5Sinful Dice§r§7\\) (.*)")) return true + if (message.matchRegex("§9§lVERY RARE DROP! §r§7\\(§r§f§r§9Null Atom§r§7\\) (.*)")) return true + if (message.matchRegex("§9§lVERY RARE DROP! §r§7\\(§r§f§r§5Transmission Tuner§r§7\\) (.*)")) return true + if (message.matchRegex("§9§lVERY RARE DROP! §r§7\\(§r§fMana Steal I§r§7\\) (.*)")) return true + if (message.matchRegex("§9§lVERY RARE DROP! §r§7\\(§r§f§r§5◆ Endersnake Rune I§r§7\\) (.*)")) return true + if (message.matchRegex("§d§lCRAZY RARE DROP! §r§7\\(§r§f§r§fPocket Espresso Machine§r§7\\) (.*)")) return true + if (message.matchRegex("§5§lVERY RARE DROP! §r§7\\(§r§f§r§5◆ End Rune I§r§7\\) (.*)")) return true + + return false + } + + private fun slayer(message: String): Boolean { + //start + if (message.matchRegex(" §r§5§lSLAYER QUEST STARTED!")) return true + if (message.matchRegex(" §5§l» §7Slay §c(.*) Combat XP §7worth of (.*)§7.")) return true + + //end + if (message.matchRegex(" §r§a§lSLAYER QUEST COMPLETE!")) return true + if (message == " §r§6§lNICE! SLAYER BOSS SLAIN!") return true + if (message.matchRegex(" §r§e(.*)Slayer LVL 9 §r§5- §r§a§lLVL MAXED OUT!")) return true + if (message.matchRegex(" §r§5§l» §r§7Talk to Maddox to claim your (.*) Slayer XP!")) return true + + + if (message == "§eYou received kill credit for assisting on a slayer miniboss!") return true + + if (message == "§e✆ Ring... ") return true + if (message == "§e✆ Ring... Ring... ") return true + if (message == "§e✆ Ring... Ring... Ring... ") return true + + return false + } + + private fun watchdogAnnouncement(message: String): Boolean = when { + message == "§4[WATCHDOG ANNOUNCEMENT]" -> true + message.matchRegex("§fWatchdog has banned §r§c§l(.*)§r§f players in the last 7 days.") -> true + message.matchRegex("§fStaff have banned an additional §r§c§l(.*)§r§f in the last 7 days.") -> true + message == "§cBlacklisted modifications are a bannable offense!" -> true + else -> false + } + + private fun bazaarAndAHMiniMessages(message: String): Boolean = when (message) { + "§7Putting item in escrow...", + "§7Putting goods in escrow...", + "§7Putting coins in escrow...", + + //Auction House + "§7Setting up the auction...", + "§7Processing purchase...", + "§7Claiming order...", + "§7Processing bid...", + "§7Claiming BIN auction...", + + //Bazaar + "§7Submitting sell offer...", + "§7Submitting buy order...", + "§7Executing instant sell...", + "§7Executing instant buy...", + + //Bank + "§8Depositing coins...", + "§8Withdrawing coins..." -> true + else -> false + } + + private fun killCombo(message: String): Boolean { + //§a§l+5 Kill Combo §r§8+§r§b3% §r§b? Magic Find + return when { + message.matchRegex("§.§l\\+(.*) Kill Combo §r§8\\+(.*)") -> true + message.matchRegex("§cYour Kill Combo has expired! You reached a (.*) Kill Combo!") -> true + else -> false + } + } + + private fun lobby(message: String): Boolean = when { + //player join + message.matchRegex("(.*) §6joined the lobby!") -> true + message.matchRegex(" §b>§c>§a>§r (.*) §6joined the lobby!§r §a<§c<§b<") -> true + + //mystery box + message.matchRegex("§b✦ §r(.*) §r§7found a §r§e(.*) §r§bMystery Box§r§7!") -> true + message.matchRegex("§b✦ §r(.*) §r§7found (a|an) §r(.*) §r§7in a §r§aMystery Box§r§7!") -> true + + //prototype + message.contains("§r§6§lWelcome to the Prototype Lobby§r") -> true + message == " §r§f§l➤ §r§6You have reached your Hype limit! Add Hype to Prototype Lobby minigames by right-clicking with the Hype Diamond!" -> true + + //hypixel tournament notifications + message.contains("§r§e§6§lHYPIXEL§e is hosting a §b§lBED WARS DOUBLES§e tournament!") -> true + message.contains("§r§e§6§lHYPIXEL BED WARS DOUBLES§e tournament is live!") -> true + + //other + message.contains("§aYou are still radiating with §bGenerosity§r§a!") -> true + else -> false + } + + private fun guild(message: String): Boolean = when { + message.matchRegex("§2Guild > (.*) §r§e(joined|left).") -> true + message.matchRegex("§aYou earned §r§2(.*) GEXP §r§afrom playing SkyBlock!") -> true + message.matchRegex("§aYou earned §r§2(.*) GEXP §r§a\\+ §r§e(.*) Event EXP §r§afrom playing SkyBlock!") -> true + message == "§b§m-----------------------------------------------------" -> true + else -> false + } + + private fun welcome(message: String): Boolean = message == "§eWelcome to §r§aHypixel SkyBlock§r§e!" + + private fun warping(message: String): Boolean = when { + message.matchRegex("§7Sending to server (.*)\\.\\.\\.") -> true + message.matchRegex("§7Request join for Hub (.*)\\.\\.\\.") -> true + message.matchRegex("§7Request join for Dungeon Hub #(.*)\\.\\.\\.") -> true + message == "§7Warping..." -> true + message == "§7Warping you to your SkyBlock island..." -> true + message == "§7Warping using transfer token..." -> true + + //visiting other players + message == "§7Finding player..." -> true + message == "§7Sending a visit request..." -> true + + //warp portals on public islands (canvas room - flower house, election room - community center, void sepulture - the end) + message.matchRegex("§dWarped to (.*)§r§d!") -> true + else -> false + } + + private fun empty(message: String): Boolean = when (message) { + "§8 §r§8 §r§1 §r§3 §r§3 §r§7 §r§8 ", + + "§f §r§f §r§1 §r§0 §r§2 §r§4§r§f §r§f §r§2 §r§0 §r§4 §r§8§r§0§r§1§r§0§r§1§r§2§r§f§r§f§r§0§r§1§r§3§r§4§r§f§r§f§r§0§r§1§r§5§r§f§r§f§r§0§r§1§r§6§r§f§r§f§r§0§r§1§r§8§r§9§r§a§r§b§r§f§r§f§r§0§r§1§r§7§r§f§r§f§r§3 §r§9 §r§2 §r§0 §r§0 §r§1§r§3 §r§9 §r§2 §r§0 §r§0 §r§2§r§3 §r§9 §r§2 §r§0 §r§0 §r§3§r§0§r§0§r§1§r§f§r§e§r§0§r§0§r§2§r§f§r§e§r§0§r§0§r§3§r§4§r§5§r§6§r§7§r§8§r§f§r§e§r§3 §r§6 §r§3 §r§6 §r§3 §r§6 §r§e§r§3 §r§6 §r§3 §r§6 §r§3 §r§6 §r§d", + + "§f §r§r§r§f §r§r§r§1 §r§r§r§0 §r§r§r§2 §r§r§r§f §r§r§r§f §r§r§r§2 §r§r§r§0 §r§r§r§4 §r§r§r§3 §r§r§r§9 §r§r§r§2 §r§r§r§0 §r§r§r§0 §r§r§r§3 §r§r§r§9 §r§r§r§2 §r§r§r§0 §r§r§r§0 §r§r§r§3 §r§r§r§9 §r§r§r§2 §r§r§r§0 §r§r§r§0 ", + + "", + "§f", + "§c" -> true + else -> false + } +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/ChatManager.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatManager.kt new file mode 100644 index 000000000..f222705cb --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatManager.kt @@ -0,0 +1,51 @@ +package at.hannibal2.skyhanni.features.chat + +import at.hannibal2.skyhanni.events.LorenzActionBarEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.PacketEvent +import at.hannibal2.skyhanni.utils.LorenzLogger +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraft.network.play.server.S02PacketChat +import net.minecraftforge.fml.common.eventhandler.EventPriority +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class ChatManager { + + private val loggerAll = LorenzLogger("chat/filter_all") + private val loggerFiltered = LorenzLogger("chat/filter_blocked") + private val loggerAllowed = LorenzLogger("chat/filter_allowed") + private val loggerFilteredTypes = mutableMapOf() + + @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true) + fun onChatPacket(event: PacketEvent.ReceiveEvent) { + val packet = event.packet + if (packet !is S02PacketChat) return + val messageComponent = packet.chatComponent + + val message = LorenzUtils.stripVanillaMessage(messageComponent.formattedText) + if (packet.type.toInt() == 2) { + val actionBarEvent = LorenzActionBarEvent(message) + actionBarEvent.postAndCatch() + } else { + + val chatEvent = LorenzChatEvent(message, messageComponent) + chatEvent.postAndCatch() + + val blockReason = chatEvent.blockedReason.uppercase() + if (blockReason != "") { + event.isCanceled = true + loggerFiltered.log("[$blockReason] $message") + loggerAll.log("[$blockReason] $message") + loggerFilteredTypes.getOrPut(blockReason) { LorenzLogger("chat/filter_blocked/$blockReason") } + .log(message) + return + } + + if (!message.startsWith("§f{\"server\":\"")) { + loggerAllowed.log(message) + loggerAll.log("[allowed] $message") + } + + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/NewChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/NewChatFilter.kt new file mode 100644 index 000000000..bf73917aa --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/NewChatFilter.kt @@ -0,0 +1,18 @@ +package at.hannibal2.skyhanni.features.chat + +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class NewChatFilter { + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + if (!LorenzUtils.isOnHypixel) return + +// val blockReason = block(event.message) +// if (blockReason != "") { +// event.blockedReason = blockReason +// } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerChatFilter.kt new file mode 100644 index 000000000..1a1047501 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerChatFilter.kt @@ -0,0 +1,90 @@ +package at.hannibal2.skyhanni.features.chat + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.PlayerSendChatEvent +import at.hannibal2.skyhanni.utils.LorenzLogger +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.removeColor +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class PlayerChatFilter { + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + if (!LorenzUtils.isOnHypixel) return + if (!SkyHanniMod.feature.chat.playerMessages) return + + if (shouldBlock(event.message)) { + event.blockedReason = "player_chat" + } + } + + val loggerPlayerChat = LorenzLogger("chat/player") + + fun shouldBlock(originalMessage: String): Boolean { + val split: List = if (originalMessage.contains("§7§r§7: ")) { + originalMessage.split("§7§r§7: ") + } else if (originalMessage.contains("§f: ")) { + originalMessage.split("§f: ") + } else { + return false + } + + var rawName = split[0] + val message = split[1] + + val channel: PlayerMessageChannel + if (rawName.startsWith("§9Party §8> ")) { + channel = PlayerMessageChannel.PARTY + rawName = rawName.substring(12) + } else if (rawName.startsWith("§2Guild > ")) { + channel = PlayerMessageChannel.GUILD + rawName = rawName.substring(10) + } else if (rawName.startsWith("§bCo-op > ")) { + channel = PlayerMessageChannel.COOP + rawName = rawName.substring(10) + } else { + channel = PlayerMessageChannel.ALL + } + + val nameSplit = rawName.split(" ") + val first = nameSplit[0] + + val last = nameSplit.last() + val name = if (last.endsWith("]")) { + nameSplit[nameSplit.size - 2] + } else { + last + } + + if (first != name) { + if (!first.contains("VIP") && !first.contains("MVP")) { + //TODO support yt + admin + return false + } + } + + send(channel, name.removeColor(), message.removeColor()) + return true + } + + private fun send(channel: PlayerMessageChannel, name: String, message: String) { + loggerPlayerChat.log("[$channel] $name: $message") + val event = PlayerSendChatEvent(channel, name, message) + event.postAndCatch() + + if (event.cancelledReason != "") { + loggerPlayerChat.log("cancelled: " + event.cancelledReason) + } else { + val finalMessage = event.message + if (finalMessage != message) { + loggerPlayerChat.log("message changed: $finalMessage") + } + + val prefix = channel.prefix + LorenzUtils.chat("$prefix §b$name §f$finalMessage") + } + } + +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerMessageChannel.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerMessageChannel.kt new file mode 100644 index 000000000..7d65f47ce --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/PlayerMessageChannel.kt @@ -0,0 +1,10 @@ +package at.hannibal2.skyhanni.features.chat + +enum class PlayerMessageChannel(val prefix: String) { + + ALL("§fA>"), + ALL_ADVERTISEMENT("§8A>"), + PARTY("§9P>"), + GUILD("§2G>"), + COOP("§bCC>"), +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossFinder.kt b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossFinder.kt new file mode 100644 index 000000000..a0895c753 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossFinder.kt @@ -0,0 +1,569 @@ +package at.hannibal2.skyhanni.features.damageindicator + +import at.hannibal2.skyhanni.features.dungeon.DungeonData +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth +import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex +import at.hannibal2.skyhanni.utils.LorenzVec +import at.hannibal2.skyhanni.utils.getLorenzVec +import net.minecraft.client.Minecraft +import net.minecraft.client.entity.EntityOtherPlayerMP +import net.minecraft.entity.Entity +import net.minecraft.entity.EntityLiving +import net.minecraft.entity.EntityLivingBase +import net.minecraft.entity.boss.EntityDragon +import net.minecraft.entity.boss.EntityWither +import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.entity.monster.* +import net.minecraft.entity.passive.EntityHorse +import net.minecraft.entity.passive.EntityWolf +import net.minecraft.util.AxisAlignedBB +import java.util.* + +class BossFinder { + + //F1 + private var floor1bonzo1 = false + private var floor1bonzo1SpawnTime = 0L + private var floor1bonzo2 = false + private var floor1bonzo2SpawnTime = 0L + + //F2 + private var floor2summons1 = false + private var floor2summons1SpawnTime = 0L + private var floor2summonsDiedOnce = mutableListOf() + private var floor2secondPhase = false + private var floor2secondPhaseSpawnTime = 0L + + //F3 + private var floor3GuardianShield = false + private var floor3GuardianShieldSpawnTime = 0L + private var guardians = mutableListOf() + private var floor3Professor = false + private var floor3ProfessorSpawnTime = 0L + private var floor3ProfessorGuardianPrepare = false + private var floor3ProfessorGuardianPrepareSpawnTime = 0L + private var floor3ProfessorGuardian = false + private var floor3ProfessorGuardianEntity: EntityGuardian? = null + + //F5 + private var floor5lividEntity: EntityOtherPlayerMP? = null + private var floor5lividEntitySpawnTime = 0L + + //F6 + private var floor6Giants = false + private var floor6GiantsSpawnTime = 0L + private var floor6GiantsSeparateDelay = mutableMapOf() + private var floor6Sadan = false + private var floor6SadanSpawnTime = 0L + + internal fun tryAdd(entity: EntityLivingBase): EntityResult? { + if (LorenzUtils.inDungeons) { + if (DungeonData.isOneOf("F1", "M1")) { + if (floor1bonzo1) { + if (entity is EntityOtherPlayerMP) { + if (entity.name == "Bonzo ") { + return EntityResult(floor1bonzo1SpawnTime) + } + } + } + if (floor1bonzo2) { + if (entity is EntityOtherPlayerMP) { + if (entity.name == "Bonzo ") { + return EntityResult(floor1bonzo2SpawnTime, finalDungeonBoss = true) + } + } + } + } + + if (DungeonData.isOneOf("F2", "M2")) { + if (entity.name == "Summon ") { + if (entity is EntityOtherPlayerMP) { + if (floor2summons1) { + if (!floor2summonsDiedOnce.contains(entity)) { + if (entity.health.toInt() != 0) { + return EntityResult(floor2summons1SpawnTime) + } else { + floor2summonsDiedOnce.add(entity) + } + } + } + if (floor2secondPhase) { + return EntityResult(floor2secondPhaseSpawnTime) + } + } + } + + if (floor2secondPhase) { + if (entity is EntityOtherPlayerMP) { + //TODO only show scarf after (all/at least x) summons are dead? + val result = entity.name == "Scarf " + if (result) { + return EntityResult(floor2secondPhaseSpawnTime, finalDungeonBoss = true) + } + } + } + } + + if (DungeonData.isOneOf("F3", "M3")) { + if (entity is EntityGuardian) { + if (floor3GuardianShield) { + if (guardians.size == 4) { + var totalHealth = 0 + for (guardian in guardians) { + totalHealth += guardian.health.toInt() + } + if (totalHealth == 0) { + floor3GuardianShield = false + guardians.clear() + } + } else { + findGuardians() + } + if (guardians.contains(entity)) { + return EntityResult(floor3GuardianShieldSpawnTime, true) + } + } + } + + if (floor3Professor) { + if (entity is EntityOtherPlayerMP) { + if (entity.name == "The Professor") { + return EntityResult( + floor3ProfessorSpawnTime, + floor3ProfessorSpawnTime + 1_000 > System.currentTimeMillis() + ) + } + } + } + if (floor3ProfessorGuardianPrepare) { + if (entity is EntityOtherPlayerMP) { + if (entity.name == "The Professor") { + return EntityResult(floor3ProfessorGuardianPrepareSpawnTime, true) + } + } + } + + if (entity is EntityGuardian) { + if (floor3ProfessorGuardian) { + if (entity == floor3ProfessorGuardianEntity) { + return EntityResult(finalDungeonBoss = true) + } + } + } + } + + if (DungeonData.isOneOf("F4", "M4")) { + if (entity is EntityGhast) { + return EntityResult(bossType = BossType.DUNGEON_F4_THORN, + ignoreBlocks = true, + finalDungeonBoss = true) + } + + } + + if (DungeonData.isOneOf("F5", "M5")) { + if (entity is EntityOtherPlayerMP) { + if (entity == floor5lividEntity) { + return EntityResult(floor5lividEntitySpawnTime, true, finalDungeonBoss = true) + } + } + } + + if (DungeonData.isOneOf("F6", "M6")) { + if (entity is EntityGiantZombie && !entity.isInvisible) { + if (floor6Giants && entity.posY > 68) { + val extraDelay = checkExtraF6GiantsDelay(entity) + return EntityResult( + floor6GiantsSpawnTime + extraDelay, + floor6GiantsSpawnTime + extraDelay + 1_000 > System.currentTimeMillis() + ) + } + + if (floor6Sadan) { + return EntityResult(floor6SadanSpawnTime, finalDungeonBoss = true) + } + } + } + } else { + + val maxHealth = entity.baseMaxHealth.toInt() + if (entity is EntityBlaze) { + if (entity.name != "Dinnerbone") { + if (entity.hasNameTagWith(2, "§e﴾ §8[§7Lv200§8] §l§8§lAshfang§r ")) { + if (maxHealth == 50_000_000) { + return EntityResult(bossType = BossType.NETHER_ASHFANG) + } + //Derpy + if (maxHealth == 100_000_000) { + return EntityResult(bossType = BossType.NETHER_ASHFANG) + } + } + } + } + if (entity is EntitySkeleton) { + if (entity.hasNameTagWith(5, "§e﴾ §8[§7Lv200§8] §l§8§lBladesoul§r ")) { + return EntityResult(bossType = BossType.NETHER_BLADESOUL) + } + } + if (entity is EntityOtherPlayerMP) { + if (entity.name == "Mage Outlaw") { + return EntityResult(bossType = BossType.NETHER_MAGE_OUTLAW) + } + if (entity.name == "DukeBarb ") { + return EntityResult(bossType = BossType.NETHER_BARBARIAN_DUKE) + } + } + if (entity is EntityWither) { + if (entity.hasNameTagWith(4, "§8[§7Lv100§8] §c§5Vanquisher§r ")) { + return EntityResult(bossType = BossType.NETHER_VANQUISHER) + } + } + if (entity is EntityEnderman) { + if (entity.hasNameTagWith(3, "§c☠ §bVoidgloom Seraph ")) { + when (maxHealth) { + 300_000, 600_000 -> { + return EntityResult(bossType = BossType.SLAYER_ENDERMAN_1) + } + 15_000_000, 30_000_000 -> { + return EntityResult(bossType = BossType.SLAYER_ENDERMAN_2) + } + 66_666_666, 66_666_666 * 2 -> { + return EntityResult(bossType = BossType.SLAYER_ENDERMAN_3) + } + 300_000_000, 600_000_000 -> { + return EntityResult(bossType = BossType.SLAYER_ENDERMAN_4) + } + } + } + } + if (entity is EntityDragon) { + //TODO testing and make right and so + return EntityResult(bossType = BossType.END_ENDER_DRAGON) + } + if (entity is EntityIronGolem) { + //TODO testing + if (entity.hasNameTagWith(3, "§e﴾ §8[§7Lv100§8] §lEndstone Protector§r ")) { + return EntityResult(bossType = BossType.END_ENDSTONE_PROTECTOR, ignoreBlocks = true) + } + } + if (entity is EntityZombie) { + if (entity.hasNameTagWith(2, "§c☠ §bRevenant Horror")) { + when (maxHealth) { + 500, 1_000 -> { + return EntityResult(bossType = BossType.SLAYER_ZOMBIE_1) + } + 20_000, 40_000 -> { + return EntityResult(bossType = BossType.SLAYER_ZOMBIE_2) + } + 400_000, 800_000 -> { + return EntityResult(bossType = BossType.SLAYER_ZOMBIE_3) + } + 1_500_000, 3_000_000 -> { + return EntityResult(bossType = BossType.SLAYER_ZOMBIE_4) + } + } + } + if (entity.hasNameTagWith(2, "§c☠ §fAtoned Horror ")) { + if (maxHealth == 10_000_000 || maxHealth == 20_000_000) { + return EntityResult(bossType = BossType.SLAYER_ZOMBIE_5) + } + } + } + if (entity is EntityMagmaCube) { + if (entity.hasNameTagWith(15, "§e﴾ §8[§7Lv500§8] §l§4§lMagma Boss§r ")) { + if (maxHealth == 200_000_000) { + return EntityResult(bossType = BossType.NETHER_MAGMA_BOSS, ignoreBlocks = true) + } + //Derpy + if (maxHealth == 400_000_000) { + return EntityResult(bossType = BossType.NETHER_MAGMA_BOSS, ignoreBlocks = true) + } + } + } + if (entity is EntityHorse) { + if (entity.hasNameTagWith(15, "§8[§7Lv100§8] §c§6Headless Horseman§r ")) { + if (maxHealth == 3_000_000) { + return EntityResult(bossType = BossType.HUB_HEADLESS_HORSEMAN) + } + //Derpy + if (maxHealth == 6_000_000) { + return EntityResult(bossType = BossType.HUB_HEADLESS_HORSEMAN) + } + } + } + if (entity is EntityBlaze) { + if (entity.hasNameTagWith(2, "§c☠ §bInferno Demonlord ")) { + when (maxHealth) { + 2_500_000, 5_000_000 -> { + return EntityResult(bossType = BossType.SLAYER_BLAZE_1) + } + } + } + } + if (entity is EntitySpider) { + if (entity.hasNameTagWith(1, "§5☠ §4Tarantula Broodfather ")) { + when (maxHealth) { + 740, 1_500 -> { + return EntityResult(bossType = BossType.SLAYER_SPIDER_1) + } + 30_000, 60_000 -> { + return EntityResult(bossType = BossType.SLAYER_SPIDER_2) + } + 900_000, 1_800_000 -> { + return EntityResult(bossType = BossType.SLAYER_SPIDER_3) + } + 2_400_000, 4_800_000 -> { + return EntityResult(bossType = BossType.SLAYER_SPIDER_4) + } + } + } + } + if (entity is EntityWolf) { + if (entity.hasNameTagWith(1, "§c☠ §fSven Packmaster ")) { + when (maxHealth) { + 2_000, 4_000 -> { + return EntityResult(bossType = BossType.SLAYER_WOLF_1) + } + 40_000, 80_000 -> { + return EntityResult(bossType = BossType.SLAYER_WOLF_2) + } + 750_000, 1_500_000 -> { + return EntityResult(bossType = BossType.SLAYER_WOLF_3) + } + 2_000_000, 4_000_000 -> { + return EntityResult(bossType = BossType.SLAYER_WOLF_4) + } + } + } + } + } + + return null + } + + private fun checkExtraF6GiantsDelay(entity: EntityGiantZombie): Long { + val uuid = entity.uniqueID + + if (floor6GiantsSeparateDelay.contains(uuid)) { + return floor6GiantsSeparateDelay[uuid]!! + } + + val middle = LorenzVec(-8, 0, 56) + + val loc = entity.getLorenzVec() + + var pos = 0 + + //first + if (loc.x > middle.x && loc.z > middle.z) { + pos = 2 + } + + //second + if (loc.x > middle.x && loc.z < middle.z) { + pos = 3 + } + + //third + if (loc.x < middle.x && loc.z < middle.z) { + pos = 0 + } + + //fourth + if (loc.x < middle.x && loc.z > middle.z) { + pos = 1 + } + + val extraDelay = 900L * pos + floor6GiantsSeparateDelay[uuid] = extraDelay + + return extraDelay + } + + fun handleChat(message: String) { + if (LorenzUtils.inDungeons) { + when (message) { + //F1 + "§c[BOSS] Bonzo§r§f: Gratz for making it this far, but I’m basically unbeatable." -> { + floor1bonzo1 = true + floor1bonzo1SpawnTime = System.currentTimeMillis() + 11_250 + } + + "§c[BOSS] Bonzo§r§f: Oh noes, you got me.. what ever will I do?!" -> { + floor1bonzo1 = false + } + + "§c[BOSS] Bonzo§r§f: Oh I'm dead!" -> { + floor1bonzo2 = true + floor1bonzo2SpawnTime = System.currentTimeMillis() + 4_200 + } + + "§c[BOSS] Bonzo§r§f: Alright, maybe I'm just weak after all.." -> { + floor1bonzo2 = false + } + + //F2 + "§c[BOSS] Scarf§r§f: ARISE, MY CREATIONS!" -> { + floor2summons1 = true + floor2summons1SpawnTime = System.currentTimeMillis() + 3_500 + } + + "§c[BOSS] Scarf§r§f: Those toys are not strong enough I see." -> { + floor2summons1 = false + } + + "§c[BOSS] Scarf§r§f: Don't get too excited though." -> { + floor2secondPhase = true + floor2secondPhaseSpawnTime = System.currentTimeMillis() + 6_300 + } + + "§c[BOSS] Scarf§r§f: Whatever..." -> { + floor2secondPhase = false + } + + //F3 + "§c[BOSS] The Professor§r§f: I was burdened with terrible news recently..." -> { + floor3GuardianShield = true + floor3GuardianShieldSpawnTime = System.currentTimeMillis() + 16_400 + } + + "§c[BOSS] The Professor§r§f: Even if you took my barrier down, I can still fight." -> { + floor3GuardianShield = false + } + + "§c[BOSS] The Professor§r§f: Oh? You found my Guardians one weakness?" -> { + floor3Professor = true + floor3ProfessorSpawnTime = System.currentTimeMillis() + 10_300 + } + + "§c[BOSS] The Professor§r§f: I see. You have forced me to use my ultimate technique." -> { + floor3Professor = false + + floor3ProfessorGuardianPrepare = true + floor3ProfessorGuardianPrepareSpawnTime = System.currentTimeMillis() + 10_500 + } + + "§c[BOSS] The Professor§r§f: The process is irreversible, but I'll be stronger than a Wither now!" -> { + floor3ProfessorGuardian = true + } + + "§c[BOSS] The Professor§r§f: What?! My Guardian power is unbeatable!" -> { + floor3ProfessorGuardian = false + } + + + //F5 + "§c[BOSS] Livid§r§f: This Orb you see, is Thorn, or what is left of him." -> { + floor5lividEntity = findLivid() + floor5lividEntitySpawnTime = System.currentTimeMillis() + 13_000 + } + + //F6 + "§c[BOSS] Sadan§r§f: ENOUGH!" -> { + floor6Giants = true + floor6GiantsSpawnTime = System.currentTimeMillis() + 7_400 + } + + "§c[BOSS] Sadan§r§f: You did it. I understand now, you have earned my respect." -> { + floor6Giants = false + floor6Sadan = true + floor6SadanSpawnTime = System.currentTimeMillis() + 32_500 + } + + "§c[BOSS] Sadan§r§f: NOOOOOOOOO!!! THIS IS IMPOSSIBLE!!" -> { + floor6Sadan = false + } + } + + if (message.matchRegex("§c\\[BOSS] (.*) Livid§r§f: Impossible! How did you figure out which one I was\\?!")) { + floor5lividEntity = null + } + } + } + + fun handleNewEntity(entity: Entity) { + if (LorenzUtils.inDungeons) { + if (floor3ProfessorGuardian) { + if (entity is EntityGuardian) { + if (floor3ProfessorGuardianEntity == null) { + floor3ProfessorGuardianEntity = entity + floor3ProfessorGuardianPrepare = false + } + } + } + } + } + + private fun findGuardians() { + guardians.clear() + + for (entity in Minecraft.getMinecraft().theWorld.loadedEntityList) { + if (entity is EntityGuardian) { + + val maxHealth = entity.baseMaxHealth.toInt() + + //F3 + if (maxHealth == 1_000_000 || maxHealth == 1_200_000) { + guardians.add(entity) + } + + //F3 Derpy + if (maxHealth == 2_000_000 || maxHealth == 2_400_000) { + guardians.add(entity) + } + + //M3 + if (maxHealth == 240_000_000 || maxHealth == 280_000_000) { + guardians.add(entity) + } + + //M3 Derpy + if (maxHealth == 120_000_000 || maxHealth == 140_000_000) { + guardians.add(entity) + } + } + } + } + + private fun findLivid(): EntityOtherPlayerMP? { + for (entity in Minecraft.getMinecraft().theWorld.loadedEntityList) { + if (entity is EntityOtherPlayerMP) { + if (entity.name == "Livid ") { + return entity + } + } + } + + return null + } +} + +fun EntityLiving.hasNameTagWith( + y: Int, + contains: String, + debugRightEntity: Boolean = false, + consumer: (EntityArmorStand) -> Unit = {}, + inaccuracy: Double = 1.6, + debugWrongEntity: Boolean = false, +): Boolean { + val center = getLorenzVec().add(0, y, 0) + val a = center.add(-inaccuracy, -inaccuracy - 3, -inaccuracy).toBlocPos() + val b = center.add(inaccuracy, inaccuracy + 3, inaccuracy).toBlocPos() + val alignedBB = AxisAlignedBB(a, b) + val clazz = EntityArmorStand::class.java + val found = worldObj.getEntitiesWithinAABB(clazz, alignedBB) + return found.any { + val result = it.name.contains(contains) + if (debugWrongEntity && !result) { + println("wrong entity in aabb: '" + it.name + "'") + } + if (debugRightEntity && result) { + println("mob: " + center.printWithAccuracy(2)) + println("nametag: " + it.getLorenzVec().printWithAccuracy(2)) + println("accuracy: " + it.getLorenzVec().subtract(center).printWithAccuracy(3)) + } + if (result) consumer(it) + result + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossType.kt b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossType.kt new file mode 100644 index 000000000..0bae4bbbd --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/BossType.kt @@ -0,0 +1,70 @@ +package at.hannibal2.skyhanni.features.damageindicator + +enum class BossType(val fullName: String, val bossTypeToggle: Int, val shortName: String = fullName) { + GENERIC_DUNGEON_BOSS("Generic Dungeon boss", 0),//TODO split into different bosses + + //Nether Mini Bosses + NETHER_BLADESOUL("§8Bladesoul", 1), + NETHER_MAGMA_BOSS("§4Magma Boss", 1), + NETHER_ASHFANG("§cAshfang", 1), + NETHER_BARBARIAN_DUKE("§eBarbarian Duke", 1), + NETHER_MAGE_OUTLAW("§5Mage Outlaw", 1), + + NETHER_VANQUISHER("§5Vanquisher", 2), + + END_ENDSTONE_PROTECTOR("§cEndstone Protector", 3), + END_ENDER_DRAGON("Ender Dragon", 4),//TODO fix totally + + SLAYER_ZOMBIE_1("§aRevenant Horror 1", 5, "§aRev 1"), + SLAYER_ZOMBIE_2("§eRevenant Horror 2", 5, "§eRev 2"), + SLAYER_ZOMBIE_3("§cRevenant Horror 3", 5, "§cRev 3"), + SLAYER_ZOMBIE_4("§4Revenant Horror 4", 5, "§4Rev 4"), + SLAYER_ZOMBIE_5("§5Revenant Horror 5", 5, "§5Rev 5"), + + SLAYER_SPIDER_1("§aTarantula Broodfather 1", 6, "§aTara 1"), + SLAYER_SPIDER_2("§eTarantula Broodfather 2", 6, "§eTara 2"), + SLAYER_SPIDER_3("§cTarantula Broodfather 3", 6, "§cTara 3"), + SLAYER_SPIDER_4("§4Tarantula Broodfather 4", 6, "§4Tara 4"), + + SLAYER_WOLF_1("§aSven Packmaster 1", 7, "§aSven 1"), + SLAYER_WOLF_2("§eSven Packmaster 2", 7, "§eSven 2"), + SLAYER_WOLF_3("§cSven Packmaster 3", 7, "§cSven 3"), + SLAYER_WOLF_4("§4Sven Packmaster 4", 7, "§4Sven 4"), + + SLAYER_ENDERMAN_1("§aVoidgloom Seraph 1", 8, "§aVoid 1"), + SLAYER_ENDERMAN_2("§eVoidgloom Seraph 2", 8, "§eVoid 2"), + SLAYER_ENDERMAN_3("§cVoidgloom Seraph 3", 8, "§cVoid 3"), + SLAYER_ENDERMAN_4("§4Voidgloom Seraph 4", 8, "§4Void 4"), + + SLAYER_BLAZE_1("§aInferno Demonlord 1", 9, "§aInferno 1"), + + HUB_HEADLESS_HORSEMAN("§6Headless Horseman", 10), + + DUNGEON_F1("", 11), + DUNGEON_F2("", 12), + DUNGEON_F3("", 13), + DUNGEON_F4_THORN("§cThorn", 14), + DUNGEON_F5("", 15), + DUNGEON_F("", 16), + DUNGEON_75("", 17), + + //TODO arachne + + //TODO corelone + //TODO bal + + + /** + * TODO dungeon mini bosses + * shadow assassin + * lost adventurer + * frozen adventurer + * king midas + * silverfish 2b one tap - deathmite outside trap + * in blood room: bonzo, scarf, ?? + * f7 blood room giants + * + */ + + //TODO diana mythological creatures +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageCounter.kt new file mode 100644 index 000000000..84bc7d50a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageCounter.kt @@ -0,0 +1,10 @@ +package at.hannibal2.skyhanni.features.damageindicator + +class DamageCounter { + + var currentDamage = 0L + var currentHealing = 0L + var oldDamages = mutableListOf() + var firstTick = 0L + +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageIndicatorManager.kt b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageIndicatorManager.kt new file mode 100644 index 000000000..ddfaed4cf --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/DamageIndicatorManager.kt @@ -0,0 +1,544 @@ +package at.hannibal2.skyhanni.features.damageindicator + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.ScoreboardData +import at.hannibal2.skyhanni.events.DamageIndicatorFinalBossEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.features.dungeon.DungeonData +import at.hannibal2.skyhanni.test.LorenzTest +import at.hannibal2.skyhanni.utils.* +import at.hannibal2.skyhanni.utils.LorenzUtils.baseMaxHealth +import at.hannibal2.skyhanni.utils.LorenzUtils.between +import at.hannibal2.skyhanni.utils.LorenzUtils.removeColor +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.entity.EntityLivingBase +import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.entity.monster.EntityEnderman +import net.minecraft.entity.monster.EntityMagmaCube +import net.minecraft.entity.monster.EntityZombie +import net.minecraft.entity.passive.EntityWolf +import net.minecraftforge.client.event.RenderLivingEvent +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.event.entity.EntityJoinWorldEvent +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.EventPriority +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent +import java.text.DecimalFormat +import java.util.* +import java.util.regex.Pattern +import kotlin.math.max + +class DamageIndicatorManager { + + var data = mutableMapOf() + private var bossFinder: BossFinder? = null + private val decimalFormat = DecimalFormat("0.0") + private val maxHealth = mutableMapOf() + private val damagePattern = Pattern.compile("✧?(\\d+[⚔+✧❤♞☄✷ﬗ]*)") + + @SubscribeEvent + fun onWorldLoad(event: WorldEvent.Load) { + bossFinder = BossFinder() + data.clear() + } + + @SubscribeEvent(receiveCanceled = true) + fun onChatMessage(event: LorenzChatEvent) { + bossFinder?.handleChat(event.message) + } + + @SubscribeEvent + fun onWorldRender(event: RenderWorldLastEvent) { + if (!SkyHanniMod.feature.damageIndicator.enabled) return + + GlStateManager.disableDepth() + GlStateManager.disableCull() + + val player = Minecraft.getMinecraft().thePlayer + + //TODO config to define between 100ms and 5 sec + for (uuid in data.filter { System.currentTimeMillis() > it.value.timeLastTick + if (it.value.dead) 3_000 else 100 } + .map { it.key }) { + data.remove(uuid) + } + + for (data in data.values) { + tickDamage(data.damageCounter) + if (!data.ignoreBlocks) { + if (!player.canEntityBeSeen(data.entity)) continue + } + if (data.bossType.bossTypeToggle !in SkyHanniMod.feature.damageIndicator.bossesToShow) continue + + val entity = data.entity + + var healthText = data.healthText + val delayedStart = data.delayedStart + if (delayedStart != -1L) { + if (delayedStart > System.currentTimeMillis()) { + val delay = delayedStart - System.currentTimeMillis() + healthText = formatDelay(delay) + } + } + + val partialTicks = event.partialTicks + + val location = if (data.dead && data.deathLocation != null) { + data.deathLocation!! + } else { + val loc = LorenzVec( + RenderUtils.interpolate(entity.posX, entity.lastTickPosX, partialTicks), + RenderUtils.interpolate(entity.posY, entity.lastTickPosY, partialTicks) + 0.5f, + RenderUtils.interpolate(entity.posZ, entity.lastTickPosZ, partialTicks) + ) + if (data.dead) data.deathLocation = loc + loc + } + + if (!data.healthLineHidden) { + RenderUtils.drawLabel(location, healthText, partialTicks, true, 6f) + } + + var bossName = when (SkyHanniMod.feature.damageIndicator.bossName) { + 0 -> "" + 1 -> data.bossType.fullName + 2 -> data.bossType.shortName + else -> data.bossType.fullName + } + + if (data.namePrefix.isNotEmpty()) { + bossName = data.namePrefix + bossName + } + if (data.nameSuffix.isNotEmpty()) { + bossName += data.nameSuffix + } + + RenderUtils.drawLabel(location, bossName, partialTicks, true, 3.9f, -9.0f) + + if (SkyHanniMod.feature.damageIndicator.showDamageOverTime) { + var diff = 13f + val currentDamage = data.damageCounter.currentDamage + val currentHealing = data.damageCounter.currentHealing + if (currentDamage != 0L || currentHealing != 0L) { + val formatDamage = "§c" + NumberUtil.format(currentDamage) + val formatHealing = "§a+" + NumberUtil.format(currentHealing) + val finalResult = if (currentHealing == 0L) { + formatDamage + } else if (currentDamage == 0L) { + formatHealing + } else { + "$formatDamage §7/ $formatHealing" + } + RenderUtils.drawLabel(location, finalResult, partialTicks, true, 3.9f, diff) + diff += 9f + } + for (damage in data.damageCounter.oldDamages) { + val formatDamage = "§c" + NumberUtil.format(damage.damage) + "/s" + val formatHealing = "§a+" + NumberUtil.format(damage.healing) + "/s" + val finalResult = if (damage.healing == 0L) { + formatDamage + } else if (damage.damage == 0L) { + formatHealing + } else { + "$formatDamage §7/ $formatHealing" + } + RenderUtils.drawLabel(location, finalResult, partialTicks, true, 3.9f, diff) + diff += 9f + } + } + + } + GlStateManager.enableDepth() + GlStateManager.enableCull() + } + + private fun tickDamage(damageCounter: DamageCounter) { + val now = System.currentTimeMillis() + if (damageCounter.currentDamage != 0L || damageCounter.currentHealing != 0L) { + if (damageCounter.firstTick == 0L) { + damageCounter.firstTick = now + } + + if (now > damageCounter.firstTick + 1_000) { + damageCounter.oldDamages.add(OldDamage(now, damageCounter.currentDamage, damageCounter.currentHealing)) + damageCounter.firstTick = 0L + damageCounter.currentDamage = 0 + damageCounter.currentHealing = 0 + } + } + damageCounter.oldDamages.removeIf { now > it.time + 5_000 } + } + + private fun formatDelay(delay: Long): String { + val color = when { + delay < 1_000 -> LorenzColor.DARK_PURPLE + delay < 3_000 -> LorenzColor.LIGHT_PURPLE + + else -> LorenzColor.WHITE + } + val d = (delay * 1.0) / 1000 + return color.getChatColor() + decimalFormat.format(d) + } + + @SubscribeEvent + fun onTickEvent(event: TickEvent.ClientTickEvent) { + if (!LorenzUtils.inSkyblock) return + for (entity in Minecraft.getMinecraft().theWorld.loadedEntityList) { + if (entity is EntityLivingBase) { + checkEntity(entity) + } + } + } + + private fun checkEntity(entity: EntityLivingBase) { + try { + val entityData = grabData(entity) ?: return + if (LorenzUtils.inDungeons) { + checkFinalBoss(entityData.finalDungeonBoss, entity.entityId) + } + + val biggestHealth = getMaxHealthFor(entity) + + val health = entity.health.toInt() + val maxHealth: Int + + if (biggestHealth == 0) { + val currentMaxHealth = entity.baseMaxHealth.toInt() + maxHealth = max(currentMaxHealth, health) + setMaxHealth(entity, maxHealth) + } else { + maxHealth = biggestHealth + } + + var calcHealth = health + var calcMaxHealth = maxHealth + entityData.namePrefix = "" + entityData.nameSuffix = "" + var customHealthText = "" + + //TODO implement + if (!entityData.dead) { + + if (entityData.bossType == BossType.DUNGEON_F4_THORN) { + if (DungeonData.isOneOf("F4")) { + calcHealth = when (health) { + 300_000, 600_000 -> 4 + 222_000, 444_000 -> 3 + 144_000, 288_000 -> 2 + 66_000, 132_000 -> 1 + 0 -> 0 + else -> { + LorenzUtils.error("Unexpected health of thorn in f4! (${ + LorenzUtils.formatDouble(LorenzUtils.formatDouble( + health.toDouble()).toDouble()) + })") + return + } + } + calcMaxHealth = 4 + } else if (DungeonData.isOneOf("M4")) { + calcHealth = when (health) { + //TODO test all non derpy values! + 1_800_000 / 2, 1_800_000 -> 6 + 1_494_000 / 2, 1_494_000 -> 5 + 1_188_000 / 2, 1_188_000 -> 4 + 882_000 / 2, 882_000 -> 3 + 576_000 / 2, 576_000 -> 2 + 270_000 / 2, 270_000 -> 1 + 0 -> 0 + else -> { + LorenzTest.enabled = true + LorenzTest.text = "thorn has ${LorenzUtils.formatDouble(health.toDouble())} hp!" + LorenzUtils.error("Unexpected health of thorn in m4! (${ + LorenzUtils.formatDouble(LorenzUtils.formatDouble( + health.toDouble()).toDouble()) + })") + return + } + } + calcMaxHealth = 4 + } + } + + if (entityData.bossType == BossType.SLAYER_ENDERMAN_1 || + entityData.bossType == BossType.SLAYER_ENDERMAN_2 || + entityData.bossType == BossType.SLAYER_ENDERMAN_3 || + entityData.bossType == BossType.SLAYER_ENDERMAN_4 + ) { + var statePrefix = "" + //Hides the damage indicator when in hit phase or in laser phase + if (entity is EntityEnderman) { + entity.hasNameTagWith(3, " Hit", consumer = { + val name = it.name.removeColor() + + val maxHits = when (entityData.bossType) { + BossType.SLAYER_ENDERMAN_1 -> 15 + BossType.SLAYER_ENDERMAN_2 -> 30 + BossType.SLAYER_ENDERMAN_3 -> 60 + BossType.SLAYER_ENDERMAN_4 -> 100 + else -> 100 + } + val hits = name.between("Seraph ", " Hit").toInt() + val color = percentageColor(hits, maxHits) + + customHealthText = color.getChatColor() + "$hits Hits" + }) + if (entity.ridingEntity != null) { + val ticksAlive = entity.ridingEntity.ticksExisted.toLong() + //TODO more tests, more exact values, better logic? idk make this working perfectly pls +// val remainingTicks = 8 * 20 - ticksAlive + val remainingTicks = (8.9 * 20).toLong() - ticksAlive + customHealthText = formatDelay(remainingTicks * 50) + } + } + + when (entityData.bossType) { + BossType.SLAYER_ENDERMAN_4 -> { + val step = maxHealth / 6 + calcMaxHealth = step + if (health > step * 5) { + calcHealth -= step * 5 + statePrefix = "§c1/6 " + } else if (health > step * 4) { + calcHealth -= step * 4 + statePrefix = "§e2/6 " + } else if (health > step * 3) { + calcHealth -= step * 3 + statePrefix = "§e3/6 " + } else if (health > step * 2) { + calcHealth -= step * 2 + statePrefix = "§e4/6 " + } else if (health > step) { + calcHealth -= step + statePrefix = "§e5/6 " + } else { + calcHealth = health + statePrefix = "§a6/6 " + } + } + BossType.SLAYER_ENDERMAN_1, + BossType.SLAYER_ENDERMAN_2, + BossType.SLAYER_ENDERMAN_3, + -> { + val step = maxHealth / 3 + + calcMaxHealth = step + if (health > step * 2) { + calcHealth -= step * 2 + statePrefix = "§c1/3 " + } else if (health > step) { + calcHealth -= step + statePrefix = "§e2/3 " + } else { + calcHealth = health + statePrefix = "§a3/3 " + } + + } + else -> {} + } + entityData.namePrefix = statePrefix + entityData.namePrefix + } + if (entityData.bossType == BossType.NETHER_MAGMA_BOSS) { + if (entity is EntityMagmaCube) { + val slimeSize = entity.slimeSize + entityData.namePrefix = when (slimeSize) { + 24 -> "§c1/6" + 22 -> "§e2/6" + 20 -> "§e3/6" + 18 -> "§e4/6" + 16 -> "§e5/6" + else -> { + calcMaxHealth = 10_000_000 + "§a6/6" + } + } + " §f" + + //hide while in the middle + val position = entity.getLorenzVec() + entityData.healthLineHidden = position.x == -368.0 && position.z == -804.0 + + for (line in ScoreboardData.sidebarLinesRaw) { + if (line.contains("▎")) { + val color: String + if (line.startsWith("§7")) { + color = "§7" + } else if (line.startsWith("§e")) { + color = "§e" + } else if (line.startsWith("§6") || line.startsWith("§a") || line.startsWith("§c")) { + calcHealth = 0 + break + } else { + LorenzUtils.error("unknown magma boss health sidebar format!") + break + } + + val text = line.replace("\uD83C\uDF81" + color, "") + val max = 25.0 + val length = text.split("§e", "§7")[1].length + val missing = (health.toDouble() / max) * length + calcHealth = (health - missing).toInt() + } + } + } + } + if (entityData.bossType == BossType.SLAYER_ZOMBIE_5) { + if (entity is EntityZombie) { + entity.hasNameTagWith(3, "§fBoom!", consumer = { + val ticksAlive = entity.ticksExisted % (20 * 5) + val remainingTicks = (5 * 20).toLong() - ticksAlive + val format = formatDelay(remainingTicks * 50) + //TODO fix +// entityData.nameSuffix = " §lBOOM - $format" + entityData.nameSuffix = " §lBOOM!" + }) + } + } + if (entityData.bossType == BossType.SLAYER_WOLF_3 || + entityData.bossType == BossType.SLAYER_WOLF_4 + ) { + if (entity is EntityWolf) { + if (entity.hasNameTagWith(2, "§bCalling the pups!")) { + customHealthText = "Pups!" + } + } + } + } + + if (health == 0) { + customHealthText = "§cDead" + entityData.dead = true + } + + if (data.containsKey(entity.uniqueID)) { + val lastHealth = data[entity.uniqueID]!!.lastHealth + val bossType = entityData.bossType + if (SkyHanniMod.feature.damageIndicator.healingMessage) { + checkHealed(health, lastHealth, bossType) + } + checkDamage(entityData, health, lastHealth, bossType) + } + + entityData.lastHealth = health + if (customHealthText.isNotEmpty()) { + entityData.healthText = customHealthText + } else { + val color = percentageColor(calcHealth, calcMaxHealth) + entityData.healthText = color.getChatColor() + NumberUtil.format(calcHealth) + } + entityData.timeLastTick = System.currentTimeMillis() + data[entity.uniqueID] = entityData + + } catch (e: Throwable) { + e.printStackTrace() + } + } + + private fun checkDamage(entityData: EntityData, health: Int, lastHealth: Int, bossType: BossType) { + val damage = lastHealth - health + val healing = health - lastHealth + if (damage > 0) { + val damageCounter = entityData.damageCounter + damageCounter.currentDamage += damage + } + if (healing > 0) { + //Hide auto heal every 10 ticks (with rounding errors) + if ((healing == 15_000 || healing == 15_001) && bossType == BossType.SLAYER_ZOMBIE_5) return + + val damageCounter = entityData.damageCounter + damageCounter.currentHealing += healing + + } + } + + private fun percentageColor( + have: Int, + max: Int, + ): LorenzColor { + val percentage = have.toDouble() / max.toDouble() + return when { + percentage > 0.9 -> LorenzColor.DARK_GREEN + percentage > 0.75 -> LorenzColor.GREEN + percentage > 0.5 -> LorenzColor.YELLOW + percentage > 0.25 -> LorenzColor.GOLD + else -> LorenzColor.RED + } + } + + private fun checkHealed(health: Int, lastHealth: Int, bossType: BossType) { + val healed = health - lastHealth + if (healed <= 0) return + + //Hide auto heal every 10 ticks (with rounding errors) + if ((healed == 15_000 || healed == 15_001) && bossType == BossType.SLAYER_ZOMBIE_5) return + + val formatLastHealth = NumberUtil.format(lastHealth) + val formatHealth = NumberUtil.format(health) + val healedFormat = NumberUtil.format(healed) + + + val bossName = when (SkyHanniMod.feature.damageIndicator.bossName) { + 2 -> bossType.shortName + else -> bossType.fullName + } + + //TODO fix rounding error (25+4=30) + println(bossName + " §healed for $healed❤ ($lastHealth -> $health)") + LorenzUtils.chat("$bossName §ehealed for §a$healedFormat❤ §8(§e$formatLastHealth -> $formatHealth§8)") + } + + private fun grabData(entity: EntityLivingBase): EntityData? { + if (data.contains(entity.uniqueID)) return data[entity.uniqueID] + + val entityResult = bossFinder?.tryAdd(entity) ?: return null + return EntityData( + entity, + entityResult.ignoreBlocks, + entityResult.delayedStart, + entityResult.finalDungeonBoss, + entityResult.bossType + ) + } + + private fun checkFinalBoss(finalBoss: Boolean, id: Int) { + if (finalBoss) { + DamageIndicatorFinalBossEvent(id).postAndCatch() + } + } + + private fun setMaxHealth(entity: EntityLivingBase, currentMaxHealth: Int) { + maxHealth[entity.uniqueID!!] = currentMaxHealth + } + + private fun getMaxHealthFor(entity: EntityLivingBase): Int { + return maxHealth.getOrDefault(entity.uniqueID!!, 0) + } + + @SubscribeEvent + fun onWorldRender(event: EntityJoinWorldEvent) { + bossFinder?.handleNewEntity(event.entity) + } + + @SubscribeEvent(priority = EventPriority.HIGHEST) + fun onRenderLiving(e: RenderLivingEvent.Specials.Pre) { + if (!SkyHanniMod.feature.damageIndicator.hideDamageSplash) return + + val entity = e.entity + if (entity.ticksExisted > 300 || entity !is EntityArmorStand) return + if (!entity.hasCustomName()) return + if (entity.isDead) return + val strippedName = entity.customNameTag.removeColor() + val damageMatcher = damagePattern.matcher(strippedName) + if (damageMatcher.matches()) { + if (data.values.any { + val distance = it.entity.getLorenzVec().distance(entity.getLorenzVec()) + val found = distance < 4.5 + found + }) { + e.isCanceled = true + } + } + } + +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/damageindicator/EntityData.kt b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/EntityData.kt new file mode 100644 index 000000000..a28c6822a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/EntityData.kt @@ -0,0 +1,22 @@ +package at.hannibal2.skyhanni.features.damageindicator + +import at.hannibal2.skyhanni.utils.LorenzVec +import net.minecraft.entity.EntityLivingBase + +class EntityData( + val entity: EntityLivingBase, + var ignoreBlocks: Boolean, + var delayedStart: Long, + val finalDungeonBoss: Boolean, + val bossType: BossType, + val damageCounter: DamageCounter = DamageCounter(), + + var lastHealth: Int = 0, + var healthText: String = "", + var timeLastTick: Long = 0, + var healthLineHidden: Boolean = false, + var namePrefix: String = "", + var nameSuffix: String = "", + var dead: Boolean = false, + var deathLocation: LorenzVec? = null, +) \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/damageindicator/EntityResult.kt b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/EntityResult.kt new file mode 100644 index 000000000..a17adf309 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/EntityResult.kt @@ -0,0 +1,8 @@ +package at.hannibal2.skyhanni.features.damageindicator + +class EntityResult( + val delayedStart: Long = -1L, + val ignoreBlocks: Boolean = false, + val finalDungeonBoss: Boolean = false, + val bossType: BossType = BossType.GENERIC_DUNGEON_BOSS, +) \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/damageindicator/OldDamage.kt b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/OldDamage.kt new file mode 100644 index 000000000..5cdb95aca --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/damageindicator/OldDamage.kt @@ -0,0 +1,4 @@ +package at.hannibal2.skyhanni.features.damageindicator + +class OldDamage(val time: Long, val damage: Long, val healing: Long) { +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/diana/GriffinBurrowFinder.kt b/src/main/java/at/hannibal2/skyhanni/features/diana/GriffinBurrowFinder.kt new file mode 100644 index 000000000..d98f46100 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/diana/GriffinBurrowFinder.kt @@ -0,0 +1,159 @@ +package at.hannibal2.skyhanni.features.diana + +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.PacketEvent +import at.hannibal2.skyhanni.test.GriffinUtils.draw3DLine +import at.hannibal2.skyhanni.test.GriffinUtils.drawWaypoint +import at.hannibal2.skyhanni.utils.* +import at.hannibal2.skyhanni.utils.ItemUtils.cleanName +import net.minecraft.client.Minecraft +import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.network.play.server.S29PacketSoundEffect +import net.minecraft.network.play.server.S2APacketParticles +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.EventPriority +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent +import java.util.* + +class GriffinBurrowFinder { + + private var ticks = 0 + val list = mutableListOf() + var lastArrowLine: Line? = null + + @SubscribeEvent + fun onClientTick(event: ClientTickEvent?) { + if (!LorenzUtils.inSkyblock) return + ticks++ + if (ticks % 5 == 0) { + checkEntities() + } + } + + @SubscribeEvent + fun onWorldChange(event: WorldEvent.Load) { + lastArrowLine = null + } + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + val message = event.message + if (message.startsWith("§eYou dug out a Griffin Burrow!") || + message == "§eYou finished the Griffin burrow chain! §r§7(4/4)" + ) { + lastArrowLine = null + } + } + + @SubscribeEvent + fun onWorldRender(event: RenderWorldLastEvent) { + if (lastArrowLine != null) { + var start = lastArrowLine!!.start + val y = (LocationUtils.playerLocation().y - 1) + start = LorenzVec(start.x, y, start.z) + val direction = lastArrowLine!!.direction + + event.drawWaypoint(start, LorenzColor.WHITE) + val nextPoint = start.add(direction.multiply(10)) +// event.drawWaypoint(nextPoint, LorenzColor.YELLOW) + + event.draw3DLine(start, start.add(direction.multiply(400)), LorenzColor.YELLOW, 3, true) + } + } + + var lastHarpTime = 0L + var lastHarpPitch = 0f + var lastHarpDistance = 0.0 + + @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true) + fun onChatPacket(event: PacketEvent.ReceiveEvent) { + val packet = event.packet + if (packet is S2APacketParticles) { + val x = packet.xCoordinate + val y = packet.yCoordinate + val z = packet.zCoordinate + val distance = LorenzVec(x, y, z).distance(LocationUtils.playerLocation()) + if (distance < 20) { +// LorenzDebug.log("") +// LorenzDebug.log("S2APacketParticles close") +// var particleType = packet.particleType +// var particleID = particleType.particleID +// LorenzDebug.log("particleType: $particleType") +// LorenzDebug.log("particleID: $particleID") +// LorenzDebug.log("distance: $distance") +// LorenzDebug.log("") + + } else { +// LorenzDebug.log("S2APacketParticles far") + } + } + if (packet is S29PacketSoundEffect) { + val x = packet.x + val y = packet.y + val z = packet.z + val distance = LorenzVec(x, y, z).distance(LocationUtils.playerLocation()) + if (distance < 20) { + val soundName = packet.soundName + val pitch = packet.pitch + val volume = packet.volume + if (soundName == "game.player.hurt" && volume == 0f) return + + if (soundName == "note.harp") { + + LorenzDebug.log("harp pitch: $pitch") + LorenzDebug.log("distance: $distance") + val now = System.currentTimeMillis() + if (lastHarpTime != 0L) { + LorenzDebug.log("") + val diffTime = now - lastHarpTime + LorenzDebug.log("diffTime: $diffTime") + val diffPitch = pitch - lastHarpPitch + LorenzDebug.log("diffPitch: $diffPitch") + val diffDistance = distance - lastHarpDistance + LorenzDebug.log("diffDistance: $diffDistance") + } + lastHarpTime = now + lastHarpPitch = pitch + lastHarpDistance = distance + LorenzDebug.log("") + return + } + + LorenzDebug.log("") + LorenzDebug.log("S29PacketSoundEffect close") + + LorenzDebug.log("soundName: $soundName") + LorenzDebug.log("pitch: $pitch") + LorenzDebug.log("volume: $volume") + LorenzDebug.log("") + } else { +// LorenzDebug.log("S29PacketSoundEffect far") + } + } + } + + private fun checkEntities() { + val playerLocation = LocationUtils.playerLocation() + for (entity in Minecraft.getMinecraft().theWorld.loadedEntityList) { + if (list.contains(entity.uniqueID)) continue + if (entity !is EntityArmorStand) continue + val distance = entity.getLorenzVec().distance(playerLocation) + if (distance > 10) continue + + + val itemStack = entity.inventory[0] ?: continue + if (itemStack.cleanName() != "Arrow") continue + + val rotationYaw = entity.rotationYaw + val direction = LorenzVec.getFromYawPitch(rotationYaw.toDouble(), 0.0) + + lastArrowLine = Line(entity.getLorenzVec(), direction) + list.add(entity.uniqueID) + LorenzDebug.log("distance: $distance") + } + } + + class Line(val start: LorenzVec, val direction: LorenzVec) +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonBossMessages.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonBossMessages.kt new file mode 100644 index 000000000..e8f569b4d --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonBossMessages.kt @@ -0,0 +1,51 @@ +package at.hannibal2.skyhanni.features.dungeon + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class DungeonBossMessages { + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + if (!LorenzUtils.inSkyblock) return + + if (!SkyHanniMod.feature.chat.dungeonBossMessages) return + + if (isBoss(event.message)) { + event.blockedReason = "dungeon_boss" + } + } + + private fun isBoss(message: String): Boolean { + when { + message.matchRegex("§([cd4])\\[BOSS] (.*)") -> { + when { + message.contains(" The Watcher§r§f: ") -> return true + message.contains(" Bonzo§r§f: ") -> return true + message.contains(" Scarf§r§f:") -> return true + message.contains("Professor§r§f") -> return true + message.contains(" Livid§r§f: ") || message.contains(" Enderman§r§f: ") -> return true + message.contains(" Thorn§r§f: ") -> return true + message.contains(" Sadan§r§f: ") -> return true + message.contains(" Maxor§r§c: ") -> return true + message.contains(" Storm§r§c: ") -> return true + message.contains(" Goldor§r§c: ") -> return true + message.contains(" Necron§r§c: ") -> return true + message.contains(" §r§4§kWither King§r§c:") -> return true + + message.endsWith(" Necron§r§c: That is enough, fool!") -> return true + message.endsWith(" Necron§r§c: Adventurers! Be careful of who you are messing with..") -> return true + message.endsWith(" Necron§r§c: Before I have to deal with you myself.") -> return true + } + } + + //M7 - Dragons + message == "§cThe Crystal withers your soul as you hold it in your hands!" -> return true + message == "§cIt doesn't seem like that is supposed to go there." -> return true + } + return false + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt new file mode 100644 index 000000000..470e50e5a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonChatFilter.kt @@ -0,0 +1,224 @@ +package at.hannibal2.skyhanni.features.dungeon + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class DungeonChatFilter { + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + if (!LorenzUtils.inSkyblock) return + + if (!SkyHanniMod.feature.chat.dungeonMessages) return + + val blockReason = block(event.message) + if (blockReason != "") { + event.blockedReason = "dungeon_$blockReason" + } + } + + private fun block(message: String): String { + when { + isPrepare(message) -> return "prepare" + isStart(message) -> return "start" + } + + if (!LorenzUtils.inDungeons) return "" + + return when { + isKey(message) -> "key" + isDoor(message) -> "door" + isPickup(message) -> "pickup" + isReminder(message) -> "reminder" + isBuff(message) -> "buff" + isNotPossible(message) -> "not_possible" + isDamage(message) -> "damage" + isAbility(message) -> "ability" + isPuzzle(message) -> "puzzle" + isEnd(message) -> "end" + + else -> "" + } + } + + private fun isDoor(message: String): Boolean = message == "§cThe §r§c§lBLOOD DOOR§r§c has been opened!" + + private fun isEnd(message: String): Boolean = when { + message.matchRegex("(.*) §r§eunlocked §r§d(.*) Essence §r§8x(.*)§r§e!") -> true + message.matchRegex(" §r§d(.*) Essence §r§8x(.*)") -> true + message.endsWith(" Experience §r§b(Team Bonus)") -> true + else -> false + } + + private fun isAbility(message: String): Boolean = when { + message == "§a§r§6Guided Sheep §r§ais now available!" -> true + message.matchRegex("§7Your Guided Sheep hit §r§c(.*) §r§7enemy for §r§c(.*) §r§7damage.") -> true + message == "§6Rapid Fire§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!" -> true + message == "§6Castle of Stone§r§a is ready to use! Press §r§6§lDROP§r§a to activate it!" -> true + + + message.matchRegex("§a§lBUFF! §fYou were splashed by (.*) §fwith §r§cHealing VIII§r§f!") -> true + message.matchRegex("§aYou were healed for (.*) health by (.*)§a!") -> true + message.matchRegex("§aYou gained (.*) HP worth of absorption for 3s from §r(.*)§r§a!") -> true + message.matchRegex("§c(.*) §r§epicked up your (.*) Orb!") -> true + message.matchRegex("§cThis ability is on cooldown for (.*)s.") -> true + message.matchRegex("§a§l(.*) healed you for (.*) health!") -> true + message.matchRegex("§eYour bone plating reduced the damage you took by §r§c(.*)§r§e!") -> true + message.matchRegex("(.*) §r§eformed a tether with you!") -> true + message.matchRegex("§eYour tether with (.*) §r§ehealed you for §r§a(.*) §r§ehealth.") -> true + message.matchRegex("§7Your Implosion hit §r§c(.*) §r§7enemy for §r§c(.*) §r§7damage.") -> true + + message.matchRegex("§eYour §r§6Spirit Pet §r§ehealed (.*) §r§efor §r§a(.*) §r§ehealth!") -> true + message.matchRegex("§eYour §r§6Spirit Pet §r§ehit (.*) enemy for §r§c(.*) §r§edamage.") -> true + + message == "§dCreeper Veil §r§aActivated!" -> true + message == "§dCreeper Veil §r§cDe-activated!" -> true + message.matchRegex("§cYou need at least (.*) mana to activate this!") -> true + + message.matchRegex( + "§eYou were healed for §r§a(.*)§r§e health by §r(.*)§r§e's §r§9Healing Bow§r§e and " + "gained §r§c\\+(.*) Strength§r§e for 10 seconds." + ) -> true + message.matchRegex("(.*)§r§a granted you §r§c(.*) §r§astrength for §r§e20 §r§aseconds!") -> true + + message.matchRegex("§eYour fairy healed §r§ayourself §r§efor §r§a(.*) §r§ehealth!") -> true + message.matchRegex("§eYour fairy healed §r(.*) §r§efor §r§a(.*) §r§ehealth!") -> true + message.matchRegex("(.*) fairy healed you for §r§a(.*) §r§ehealth!") -> true + + else -> false + } + + private fun isDamage(message: String): Boolean = when { + message == "§cMute silenced you!" -> true + message.matchRegex("(.*) §r§aused §r(.*) §r§aon you!") -> true + message.matchRegex("§cThe (.*)§r§c struck you for (.*) damage!") -> true + message.matchRegex("§cThe (.*) hit you for (.*) damage!") -> true + message.matchRegex("§7(.*) struck you for §r§c(.*)§r§7 damage.") -> true + message.matchRegex("(.*) hit you for §r§c(.*)§r§7 damage.") -> true + message.matchRegex("(.*) hit you for §r§c(.*)§r§7 true damage.") -> true + message.matchRegex("§7(.*) exploded, hitting you for §r§c(.*)§r§7 damage.") -> true + message.matchRegex("(.*)§r§c hit you with §r(.*) §r§cfor (.*) damage!") -> true + message.matchRegex("(.*)§r§a struck you for §r§c(.*)§r§a damage!") -> true + message.matchRegex("(.*)§r§c struck you for (.*)!") -> true + + message.matchRegex("§7The Mage's Magma burnt you for §r§c(.*)§r§7 true damage.") -> true + + message.matchRegex("§7Your (.*) hit §r§c(.*) §r§7(enemy|enemies) for §r§c(.*) §r§7damage.") -> true + else -> false + } + + private fun isNotPossible(message: String): Boolean = when (message) { + "§cYou cannot hit the silverfish while it's moving!", + "§cYou cannot move the silverfish in that direction!", + "§cThere are blocks in the way!", + "§cThis chest has already been searched!", + "§cThis lever has already been used.", + "§cYou cannot do that in this room!", + "§cYou do not have the key for this door!", + "§cYou have already opened this dungeon chest!", + "§cYou cannot use abilities in this room!", + "§cA mystical force in this room prevents you from using that ability!" -> true + + else -> false + } + + private fun isBuff(message: String): Boolean = when { + message.matchRegex("§6§lDUNGEON BUFF! (.*) §r§ffound a §r§dBlessing of (.*)§r§f!(.*)") -> true + message.matchRegex("§6§lDUNGEON BUFF! §r§fYou found a §r§dBlessing of (.*)§r§f!(.*)") -> true + message.matchRegex("§6§lDUNGEON BUFF! §r§fA §r§dBlessing of (.*)§r§f was found! (.*)") -> true + message.matchRegex("§eA §r§a§r§dBlessing of (.*)§r§e was picked up!") -> true + message.matchRegex("(.*) §r§ehas obtained §r§a§r§dBlessing of (.*)§r§e!") -> true + message.matchRegex(" §r§7(Grants|Granted) you §r§a(.*) Strength §r§7and §r§a(.*) Crit Damage§r§7.") -> true + message.matchRegex(" §r§7(Grants|Granted) you §r§a(.*) Defense §r§7and §r§a+(.*) Damage§r§7.") -> true + message.matchRegex(" §r§7(Grants|Granted) you §r§a(.*) HP §r§7and §r§a+(.*)% §r§7health regeneration.") -> true + message.matchRegex(" §r§7(Grants|Granted) you §r§a(.*) Intelligence §r§7and §r§a+(.*)? Speed§r§7.") -> true + message.matchRegex(" §r§7Granted you §r§a+(.*) HP§r§7, §r§a(.*) Defense§r§7, §r§a(.*) Intelligence§r§7, and §r§a(.*) Strength§r§7.") -> true + message == "§a§lBUFF! §fYou have gained §r§cHealing V§r§f!" -> true + else -> false + } + + private fun isPuzzle(message: String): Boolean = when { + message.matchRegex("§a§lPUZZLE SOLVED! (.*) §r§ewasn't fooled by §r§c(.*)§r§e! §r§4G§r§co§r§6o§r§ed§r§a §r§2j§r§bo§r§3b§r§5!") -> true + message.matchRegex("§a§lPUZZLE SOLVED! (.*) §r§etied Tic Tac Toe! §r§4G§r§co§r§6o§r§ed§r§a §r§2j§r§bo§r§3b§r§5!") -> true + message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fThough I sit stationary in this prison that is §r§cThe Catacombs§r§f, my knowledge knows no bounds." -> true + message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fProve your knowledge by answering 3 questions and I shall reward you in ways that transcend time!" -> true + message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fAnswer incorrectly, and your moment of ineptitude will live on for generations." -> true + +// message == "§4[STATUE] Oruo the Omniscient§r§f: §r§f2 questions §r§fleft...and§r§f you will have proven your worth to me!" -> true + message == "§4[STATUE] Oruo the Omniscient§r§f: §r§f2 questions left... Then you will have proven your worth to me!" -> true + + message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fOne more question!" -> true + message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fI bestow upon you all the power of a hundred years!" -> true + message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fYou've already proven enough to me! No need to press more of my buttons!" -> true + message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fI've had enough of you and your party fiddling with my buttons. Scram!" -> true + message == "§4[STATUE] Oruo the Omniscient§r§f: §r§fEnough! My buttons are not to be pressed with such lack of grace!" -> true + message.matchRegex("§4\\[STATUE] Oruo the Omniscient§r§f: §r(.*) §r§fthinks the answer is §r§6 . §r(.*)§r§f! §r§fLock in your party's answer in my Chamber!") -> true + else -> false + } + + private fun isKey(message: String): Boolean = when { + message.matchRegex("(.*) §r§ehas obtained §r§a§r§6§r§8Wither Key§r§e!") -> true + message.matchRegex("(.*) opened a §r§8§lWITHER §r§adoor!") -> true + message.matchRegex("(.*) §r§ehas obtained §r§a§r§c§r§cBlood Key§r§e!") -> true + message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Beating Heart§r§e!") -> true + message == "§5A shiver runs down your spine..." -> true + message == "§eA §r§a§r§6§r§8Wither Key§r§e was picked up!" -> true + message == "§eA §r§a§r§c§r§cBlood Key§r§e was picked up!" -> true + + else -> false + } + + private fun isReminder(message: String): Boolean = when (message) { + "§e§lRIGHT CLICK §r§7on §r§7a §r§8WITHER §r§7door§r§7 to open it. This key can only be used to open §r§a1§r§7 door!", + "§e§lRIGHT CLICK §r§7on §r§7the §r§cBLOOD DOOR§r§7 to open it. This key can only be used to open §r§a1§r§7 door!" -> true + + else -> false + } + + private fun isPickup(message: String): Boolean = when { + message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Superboom TNT§r§e!") -> true + message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Superboom TNT §r§8x2§r§e!") -> true + message.matchRegex("§6§lRARE DROP! §r§9Hunk of Blue Ice §r§b\\(+(.*)% Magic Find!\\)") -> true + message.matchRegex("(.*) §r§ehas obtained §r§a§r§6Revive Stone§r§e!") -> true + message.matchRegex("(.*) §r§ffound a §r§dWither Essence§r§f! Everyone gains an extra essence!") -> true + message == "§fYou found a §r§dWither Essence§r§f! Everyone gains an extra essence!" -> true + message.matchRegex("§d(.*) the Fairy§r§f: You killed me! Take this §r§6Revive Stone §r§fso that my death is not in vain!") -> true + message.matchRegex("§d(.*) the Fairy§r§f: You killed me! I'll revive you so that my death is not in vain!") -> true + message.matchRegex("§d(.*) the Fairy§r§f: You killed me! I'll revive your friend §r(.*) §r§fso that my death is not in vain!") -> true + message.matchRegex("§d(.*) the Fairy§r§f: Have a great life!") -> true + message.matchRegex( + "§c(.*) §r§eYou picked up a Ability Damage Orb from (.*) §r§ehealing you for §r§c(.*) §r§eand granting you +§r§c(.*)% §r§eAbility Damage for §r§b10 §r§eseconds." + ) -> true + message.matchRegex( + "§c(.*) §r§eYou picked up a Damage Orb from (.*) §r§ehealing you for §r§c(.*) §r§eand granting you +§r§c(.*)% §r§eDamage for §r§b10 §r§eseconds." + ) -> true + message.matchRegex("(.*) §r§ehas obtained §r§a§r§9Premium Flesh§r§e!") -> true + message.matchRegex("§6§lRARE DROP! §r§9Beating Heart §r§b(.*)") -> true + else -> false + } + + private fun isStart(message: String): Boolean = when { + message == "§e[NPC] §bMort§f: §rHere, I found this map when I first entered the dungeon." -> true + message == "§e[NPC] §bMort§f: §rYou should find it useful if you get lost." -> true + message == "§e[NPC] §bMort§f: §rGood luck." -> true + message == "§e[NPC] §bMort§f: §rTalk to me to change your class and ready up." -> true + + //§a[Berserk] §r§fMelee Damage §r§c48%§r§f -> §r§a88% + //§a[Berserk] §r§fWalk Speed §r§c38§r§f -> §r§a68 + message.matchRegex("§a(.*) §r§f(.*) §r§c(.*)§r§f -> §r§a(.*)") -> true + else -> false + } + + private fun isPrepare(message: String): Boolean = when { + message == "§aYour active Potion Effects have been paused and stored. They will be restored when you leave Dungeons! You are not allowed to use existing Potion Effects while in Dungeons." -> true + message.matchRegex("(.*) has started the dungeon countdown. The dungeon will begin in 1 minute.") -> true + message.matchRegex("§e[NPC] §bMort§f: §rTalk to me to change your class and ready up.") -> true + message.matchRegex("(.*) §a is now ready!") -> true + message.matchRegex("§aDungeon starts in (.*) seconds.") -> true + message == "§aDungeon starts in 1 second." -> true + message == "§aYou can no longer consume or splash any potions during the remainder of this Dungeon run!" -> true + else -> false + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt new file mode 100644 index 000000000..01950688a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonCleanEnd.kt @@ -0,0 +1,130 @@ +package at.hannibal2.skyhanni.features.dungeon + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.CheckRenderEntityEvent +import at.hannibal2.skyhanni.events.DamageIndicatorFinalBossEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.PacketEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex +import net.minecraft.client.Minecraft +import net.minecraft.client.entity.EntityOtherPlayerMP +import net.minecraft.entity.item.EntityArmorStand +import net.minecraft.entity.monster.EntityGuardian +import net.minecraft.network.play.server.S1CPacketEntityMetadata +import net.minecraft.network.play.server.S2APacketParticles +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class DungeonCleanEnd { + + private var bossDone = false + private var chestsSpawned = false + private var lastBossId: Int = -1 + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + if (!LorenzUtils.inDungeons) return + if (!SkyHanniMod.feature.dungeon.cleanEnd) return + + val message = event.message + + if (message.matchRegex("([ ]*)§r§c(The|Master Mode) Catacombs §r§8- §r§eFloor (.*)")) { + chestsSpawned = true + } + } + + private fun shouldBlock(): Boolean { + if (!LorenzUtils.inDungeons) return false + if (!SkyHanniMod.feature.dungeon.cleanEnd) return false + + if (!bossDone) return false + + return true + } + + @SubscribeEvent + fun onWorldChange(event: WorldEvent.Load) { + bossDone = false + chestsSpawned = false + lastBossId = -1 + } + + @SubscribeEvent + fun onBossDead(event: DamageIndicatorFinalBossEvent) { + if (!LorenzUtils.inDungeons) return + if (bossDone) return + + if (lastBossId == -1) { + lastBossId = event.id + } + } + + @SubscribeEvent + fun onHealthUpdatePacket(event: PacketEvent.ReceiveEvent) { + if (!LorenzUtils.inDungeons) return + if (!SkyHanniMod.feature.dungeon.cleanEnd) return + + if (bossDone) return + if (lastBossId == -1) return + + val packet = event.packet + if (packet !is S1CPacketEntityMetadata) return + if (packet.entityId != lastBossId) return + + for (watchableObject in packet.func_149376_c()) { + if (watchableObject.dataValueId == 6) { + val health = watchableObject.`object` as Float + if (health < 1) { + val dungeonFloor = DungeonData.dungeonFloor + LorenzUtils.chat("§eFloor $dungeonFloor done!") + bossDone = true + } + } + } + } + + @SubscribeEvent + fun onCheckRender(event: CheckRenderEntityEvent<*>) { + if (!shouldBlock()) return + + val entity = event.entity + + if (entity == Minecraft.getMinecraft().thePlayer) return + + if (SkyHanniMod.feature.dungeon.cleanEndF3IgnoreGuardians) { + if (DungeonData.isOneOf("F3", "M3")) { + if (entity is EntityGuardian) { + if (entity.entityId != lastBossId) { + if (Minecraft.getMinecraft().thePlayer.isSneaking) { + return + } + } + } + } + } + + if (chestsSpawned) { + if (entity is EntityArmorStand) { + if (!entity.hasCustomName()) { + return + } + } + if (entity is EntityOtherPlayerMP) { + return + } + } + + event.isCanceled = true + } + + @SubscribeEvent + fun onReceivePacket(event: PacketEvent.ReceiveEvent) { + if (!shouldBlock()) return + + + if (event.packet is S2APacketParticles) { + event.isCanceled = true + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonData.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonData.kt new file mode 100644 index 000000000..1ae704653 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonData.kt @@ -0,0 +1,46 @@ +package at.hannibal2.skyhanni.features.dungeon + +import at.hannibal2.skyhanni.data.ScoreboardData +import at.hannibal2.skyhanni.events.DungeonEnterEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent + +class DungeonData { + + companion object { + var dungeonFloor: String? = null + + fun isOneOf(vararg floors: String): Boolean { + for (floor in floors) { + if (dungeonFloor == floor) { + return true + } + } + + return false + } + } + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (event.phase != TickEvent.Phase.START) return + if (LorenzUtils.inDungeons) { + if (dungeonFloor == null) { + for (line in ScoreboardData.sidebarLines) { + if (line.contains("The Catacombs (")) { + dungeonFloor = line.substringAfter("(").substringBefore(")") + DungeonEnterEvent(dungeonFloor!!).postAndCatch() + break + } + } + } + } + } + + @SubscribeEvent + fun onWorldChange(event: WorldEvent.Load) { + dungeonFloor = null + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt new file mode 100644 index 000000000..70709bc7f --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonDeathCounter.kt @@ -0,0 +1,97 @@ +package at.hannibal2.skyhanni.features.dungeon + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.DungeonEnterEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.utils.GuiRender.renderString +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex +import net.minecraftforge.client.event.RenderGameOverlayEvent +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class DungeonDeathCounter { + + private var textToRender = "" + private var deaths = 0 + + private fun isDeathMessage(message: String): Boolean = when { + message.matchRegex("§c ☠ §r§7You were killed by (.*)§r§7 and became a ghost§r§7.") -> true + message.matchRegex("§c ☠ §r§7(.*) was killed by (.*) and became a ghost§r§7.") -> true + + message.matchRegex("§c ☠ §r§7You were crushed and became a ghost§r§7.") -> true + message.matchRegex("§c ☠ §r§7§r(.*)§r§7 was crushed and became a ghost§r§7.") -> true + + message.matchRegex("§c ☠ §r§7You died to a trap and became a ghost§r§7.") -> true + message.matchRegex("§c ☠ §r(.*)§r§7 died to a trap and became a ghost§r§7.") -> true + + message.matchRegex("§c ☠ §r§7You burnt to death and became a ghost§r§7.") -> true + message.matchRegex("§c ☠ §r(.*)§r§7 burnt to death and became a ghost§r§7.") -> true + + message.matchRegex("§c ☠ §r§7You died and became a ghost§r§7.") -> true + message.matchRegex("§c ☠ §r(.*)§r§7 died and became a ghost§r§7.") -> true + + message.matchRegex("§c ☠ §r§7You suffocated and became a ghost§r§7.") -> true + message.matchRegex("§c ☠ §r§7§r(.*)§r§7 suffocated and became a ghost§r§7.") -> true + + message.matchRegex("§c ☠ §r§7You died to a mob and became a ghost§r§7.") -> true + message.matchRegex("§c ☠ §r(.*)§7 died to a mob and became a ghost§r§7.") -> true + + message.matchRegex("§c ☠ §r§7You fell into a deep hole and became a ghost§r§7.") -> true + message.matchRegex("§c ☠ §r(.*)§r§7 fell into a deep hole and became a ghost§r§7.") -> true + + message.matchRegex("§c ☠ §r§(.*)§r§7 disconnected from the Dungeon and became a ghost§r§7.") -> true + + message.matchRegex("§c ☠ §r§7(.*)§r§7 fell to their death with help from §r(.*)§r§7 and became a ghost§r§7.") -> true + + else -> false + } + + @SubscribeEvent(receiveCanceled = true) + fun onChatPacket(event: LorenzChatEvent) { + if (!isEnabled()) return + + if (isDeathMessage(event.message)) { + deaths++ + LorenzUtils.chat("§c§l$deaths. DEATH!") + update() + } + } + + private fun update() { + if (deaths == 0) { + textToRender = "" + return + } + + val color = when (deaths) { + 1, 2 -> "§e" + 3 -> "§c" + else -> "§4" + } + textToRender = color + "Deaths: $deaths" + } + + @SubscribeEvent + fun onDungeonStart(event: DungeonEnterEvent) { + deaths = 0 + update() + } + + @SubscribeEvent + fun onWorldChange(event: WorldEvent.Load) { + deaths = 0 + update() + } + + @SubscribeEvent + fun renderOverlay(event: RenderGameOverlayEvent.Post) { + if (!isEnabled()) return + + SkyHanniMod.feature.dungeon.deathCounterPos.renderString(DungeonMilestoneDisplay.color + textToRender) + } + + private fun isEnabled(): Boolean { + return LorenzUtils.inDungeons && SkyHanniMod.feature.dungeon.deathCounter + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonHighlightClickedBlocks.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonHighlightClickedBlocks.kt new file mode 100644 index 000000000..4af9d5efd --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonHighlightClickedBlocks.kt @@ -0,0 +1,99 @@ +package at.hannibal2.skyhanni.features.dungeon + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.PacketEvent +import at.hannibal2.skyhanni.utils.* +import at.hannibal2.skyhanni.utils.BlockUtils.getBlockAt +import at.hannibal2.skyhanni.utils.RenderUtils.drawColor +import at.hannibal2.skyhanni.utils.RenderUtils.drawString +import net.minecraft.init.Blocks +import net.minecraft.network.play.client.C08PacketPlayerBlockPlacement +import net.minecraftforge.client.event.RenderWorldLastEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class DungeonHighlightClickedBlocks { + + private val blocks = mutableListOf() + private var colorIndex = 0 + private val colors = listOf(LorenzColor.YELLOW, LorenzColor.AQUA, LorenzColor.GREEN, LorenzColor.LIGHT_PURPLE) + + private fun getNextColor(): LorenzColor { + var id = colorIndex + 1 + if (id == colors.size) id = 0 + colorIndex = id + return colors[colorIndex] + } + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + if (!SkyHanniMod.feature.dungeon.highlightClickedBlocks) return + if (!LorenzUtils.inDungeons) return + + if (event.message == "§cYou hear the sound of something opening...") { + event.blockedReason = "dungeon_highlight_clicked_block" + } + } + + @SubscribeEvent + fun onSendPacket(event: PacketEvent.SendEvent) { + if (!SkyHanniMod.feature.dungeon.highlightClickedBlocks) return + if (!LorenzUtils.inDungeons) return +// TODO add +// if (DungeonAPI.inBossRoom) return + if (event.packet !is C08PacketPlayerBlockPlacement || event.packet.stack == null) return + + val position = event.packet.position.toLorenzVec() + + if (blocks.any { it.position == position }) return + + val type: ClickedBlockType = when (position.getBlockAt()) { + Blocks.chest, Blocks.trapped_chest -> ClickedBlockType.CHEST + Blocks.lever -> ClickedBlockType.LEVER + Blocks.skull -> ClickedBlockType.WITHER_ESSENCE + else -> return + } + + if (type == ClickedBlockType.WITHER_ESSENCE) { + val text = BlockUtils.getSkinFromSkull(position.toBlocPos()) + if (text != "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQ" + + "ubmV0L3RleHR1cmUvYzRkYjRhZGZhOWJmNDhmZjVkNDE3M" + + "DdhZTM0ZWE3OGJkMjM3MTY1OWZjZDhjZDg5MzQ3NDlhZjRjY2U5YiJ9fX0=" + ) { + return + } + } + +// if (nearWaterRoom() && type == ClickedBlockType.LEVER) return + + val color = getNextColor() + val displayText = color.getChatColor() + "Clicked " + type.display + blocks.add(ClickedBlock(position, displayText, color, System.currentTimeMillis())) + } + + @SubscribeEvent + fun onWorldRender(event: RenderWorldLastEvent) { + if (!SkyHanniMod.feature.dungeon.highlightClickedBlocks) return + if (!LorenzUtils.inDungeons) return + + blocks.removeAll { System.currentTimeMillis() > it.time + 3000 } + blocks.forEach { + event.drawColor(it.position, it.color) + event.drawString(it.position.add(0.5, 0.5, 0.5), it.displayText, true) + } + } + + class ClickedBlock(val position: LorenzVec, val displayText: String, val color: LorenzColor, val time: Long) + + enum class ClickedBlockType(val display: String) { + LEVER("Lever"), + CHEST("Chest"), + WITHER_ESSENCE("Wither Essence"), + } + +// private fun nearWaterRoom(): Boolean { +// val playerLoc = +// LocationUtils.getPlayerLocation().add(LocationUtils.getPlayerLookingAtDirection().multiply(2)).add(0, 2, 0) +// return WaterBoardSolver.waterRoomDisplays.any { it.distance(playerLoc) < 3 } +// } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestoneDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestoneDisplay.kt new file mode 100644 index 000000000..8feeb9a5c --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonMilestoneDisplay.kt @@ -0,0 +1,96 @@ +package at.hannibal2.skyhanni.features.dungeon + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.DungeonEnterEvent +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.utils.GuiRender.renderString +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex +import net.minecraftforge.client.event.RenderGameOverlayEvent +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.concurrent.fixedRateTimer + +class DungeonMilestoneDisplay { + + + companion object { + private var textToRender = "" + var color = "" + var currentMilestone = 0 + var timeReached = 0L + + fun isMilestoneMessage(message: String): Boolean = when { + message.matchRegex("§e§l(.*) Milestone §r§e.§r§7: You have dealt §r§c(.*)§r§7 Total Damage so far! §r§a(.*)") -> true + message.matchRegex("§e§lArcher Milestone §r§e.§r§7: You have dealt §r§c(.*)§r§7 Ranged Damage so far! §r§a(.*)") -> true + message.matchRegex("§e§lHealer Milestone §r§e.§r§7: You have healed §r§a(.*)§r§7 Damage so far! §r§a(.*)") -> true + message.matchRegex("§e§lTank Milestone §r§e.§r§7: You have tanked and dealt §r§c(.*)§r§7 Total Damage so far! §r§a(.*)s") -> true + + else -> false + } + } + + init { + fixedRateTimer(name = "dungeon-milestone-display", period = 200) { + if (!isEnabled()) return@fixedRateTimer + checkVisibility() + } + } + + private fun checkVisibility() { + if (currentMilestone >= 3) { + if (System.currentTimeMillis() > timeReached + 3_000) + if (textToRender != "") { + textToRender = textToRender.substring(1) + } + } + } + + @SubscribeEvent(receiveCanceled = true) + fun onChatPacket(event: LorenzChatEvent) { + if (!isEnabled()) return + + if (isMilestoneMessage(event.message)) { + event.blockedReason = "dungeon_milestone" + currentMilestone++ + update() + } + } + + private fun update() { + if (currentMilestone > 3) return + if (currentMilestone == 3) { + timeReached = System.currentTimeMillis() + } + + color = when (currentMilestone) { + 0, 1 -> "§c" + 2 -> "§e" + else -> "§a" + } + textToRender = "Current Milestone: $currentMilestone" + } + + @SubscribeEvent + fun onWorldChange(event: WorldEvent.Load) { + textToRender = "" + currentMilestone = 0 + } + + @SubscribeEvent + fun onDungeonStart(event: DungeonEnterEvent) { + currentMilestone = 0 + update() + } + + @SubscribeEvent + fun renderOverlay(event: RenderGameOverlayEvent.Post) { + if (!isEnabled()) return + + SkyHanniMod.feature.dungeon.milestoneDisplayPos.renderString(color + textToRender) + } + + private fun isEnabled(): Boolean { + return LorenzUtils.inDungeons && SkyHanniMod.feature.dungeon.showMilestoneDisplay + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreature.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreature.kt new file mode 100644 index 000000000..c2b452cbe --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreature.kt @@ -0,0 +1,18 @@ +package at.hannibal2.skyhanni.features.fishing + +data class SeaCreature( + val displayName: String, + val fishingExperience: Int, + val chatColor: String, + val rare: Boolean, +) { + + override fun toString(): String { + return chatColor + rare() + displayName + } + + private fun rare(): String { + return if (rare) "§l" else "" + } +} + diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt new file mode 100644 index 000000000..c61b8dd8a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureManager.kt @@ -0,0 +1,64 @@ +package at.hannibal2.skyhanni.features.fishing + +import at.hannibal2.skyhanni.events.RepositoryReloadEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class SeaCreatureManager { + + @SubscribeEvent + fun onRepoReload(event: RepositoryReloadEvent) { + seaCreatureMap.clear() + var counter = 0 + + try { + val data = event.getConstant("SeaCreatures")!! + + for (variant in data.entrySet().map { it.value.asJsonObject }) { + val chatColor = variant["chat_color"].asString + for ((displayName, value) in variant["sea_creatures"].asJsonObject.entrySet()) { + val seaCreature = value.asJsonObject + val chatMessage = seaCreature["chat_message"].asString + val fishingExperience = seaCreature["fishing_experience"].asInt + + val rare = if (seaCreature.has("rare")) { + seaCreature["rare"].asBoolean + } else false + + seaCreatureMap[chatMessage] = SeaCreature(displayName, fishingExperience, chatColor, rare) + counter++ + } + } + LorenzUtils.debug("loaded $counter sea creatures from repo") + +// seaCreatures.asJsonArray.map { it.asJsonObject }.forEach { +// val displayName = it["display_name"].asString +// val chatMessage = it["chat_message"].asString +// val fishingExperience = it["fishing_experience"].asInt +// val variantName = it["variant"].asString +// val special = it["special"].asBoolean +// +// val variant = try { +// FishingVariant.fromString(variantName) +// } catch (e: FishingVariantNotFoundException) { +// LorenzUtils.error("Error loading Sea Creature '$displayName': " + e.message) +// return +// } +// +// seaCreatureMap[chatMessage] = SeaCreature(displayName, fishingExperience, variant, special) +// } + + } catch (e: Exception) { + e.printStackTrace() + LorenzUtils.error("error in RepositoryReloadEvent") + } + } + + companion object { + val seaCreatureMap = mutableMapOf() + + fun getSeaCreature(message: String): SeaCreature? { + return seaCreatureMap.getOrDefault(message, null) + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureMessageShortener.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureMessageShortener.kt new file mode 100644 index 000000000..21703d227 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/SeaCreatureMessageShortener.kt @@ -0,0 +1,24 @@ +package at.hannibal2.skyhanni.features.fishing + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class SeaCreatureMessageShortener { + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + if (!LorenzUtils.inSkyblock) return + if (!SkyHanniMod.feature.fishing.shortenFishingMessage) return + + val seaCreature = SeaCreatureManager.getSeaCreature(event.message) + if (seaCreature != null) { + event.blockedReason = "sea_create_caught" + LorenzUtils.chat("§9You caught a $seaCreature§9!") + if (seaCreature.fishingExperience == 0) { + LorenzUtils.debug("no fishing exp set for " + seaCreature.displayName) + } + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/fishing/TrophyFishMessages.kt b/src/main/java/at/hannibal2/skyhanni/features/fishing/TrophyFishMessages.kt new file mode 100644 index 000000000..a87433762 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/fishing/TrophyFishMessages.kt @@ -0,0 +1,71 @@ +package at.hannibal2.skyhanni.features.fishing + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.ProfileApiDataLoadedEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.between +import at.hannibal2.skyhanni.utils.LorenzUtils.removeColor +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class TrophyFishMessages { + + private val map = mutableMapOf() + + @SubscribeEvent + fun onProfileDataLoad(event: ProfileApiDataLoadedEvent) { + val profileData = event.profileData + + map.clear() + val trophyFishes = profileData["trophy_fish"].asJsonObject + for ((rawName, value) in trophyFishes.entrySet()) { + val rarity = when { + rawName.endsWith("_bronze") -> "bronze" + rawName.endsWith("_silver") -> "silver" + rawName.endsWith("_gold") -> "gold" + rawName.endsWith("_diamond") -> "diamond" + else -> continue + } + val text = rawName.replace("_", "") + val displayName = text.substring(0, text.length - rarity.length) + + val amount = value.asInt + +// LorenzDebug.log("$rarity: $displayName: $amount") + val name = rarity + "_" + displayName + map[name] = amount +// LorenzDebug.log("loaded trophy: $name = $amount") + } + } + + @SubscribeEvent + fun onStatusBar(event: LorenzChatEvent) { + if (!LorenzUtils.inSkyblock) return + if (!SkyHanniMod.feature.fishing.trophyCounter) return + + val message = event.message + if (message.startsWith("§6§lTROPHY FISH! §r§bYou caught a")) { + var displayName = if (message.contains(" a §r")) message.between(" a §r", "§r §r") else message.between(" an §r", "§r §r") + if (displayName.contains("§k")) { + displayName = displayName.replace("§k", "") + displayName = displayName.replace("Obfuscated", "Obfuscated Fish") + } + val rarity = message.between("§r §r", "§b.").lowercase().replace("§l", "") + + val name = (rarity + "_" + displayName).removeColor().lowercase().replace(" ", "") + val amount = map.getOrDefault(name, 0) + 1 + map[name] = amount + event.blockedReason = "trophy_fish" + + if (amount == 1) { + LorenzUtils.chat("§6TROPHY FISH! §c§lFIRST §r$rarity $displayName") + } else { + if (rarity.contains("bronze")) { + if (SkyHanniMod.feature.fishing.trophyFishBronzeHider) return + } + LorenzUtils.chat("§6TROPHY FISH! §7$amount. §r$rarity $displayName") + } +// LorenzDebug.log("new trophy: $name = $amount") + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/items/HideNotClickableItems.kt b/src/main/java/at/hannibal2/skyhanni/features/items/HideNotClickableItems.kt new file mode 100644 index 000000000..c3b4a398d --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/items/HideNotClickableItems.kt @@ -0,0 +1,416 @@ +package at.hannibal2.skyhanni.features.items + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.ItemRenderBackground.Companion.background +import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.events.RepositoryReloadEvent +import at.hannibal2.skyhanni.features.bazaar.BazaarApi +import at.hannibal2.skyhanni.utils.* +import at.hannibal2.skyhanni.utils.ItemUtils.cleanName +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.LorenzUtils.removeColor +import com.google.gson.JsonObject +import net.minecraft.client.Minecraft +import net.minecraft.client.gui.inventory.GuiChest +import net.minecraft.inventory.ContainerChest +import net.minecraft.item.ItemStack +import net.minecraftforge.event.entity.player.ItemTooltipEvent +import net.minecraftforge.fml.common.eventhandler.EventPriority +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class HideNotClickableItems { + + private var hideReason = "" + + private var lastClickTime = 0L + private var bypassUntil = 0L + + private val hideNpcSellFilter = MultiFilter() + private val hideInStorageFilter = MultiFilter() + private val tradeNpcFilter = MultiFilter() + private val itemsToSalvage = mutableListOf() + private val hidePlayerTradeFilter = MultiFilter() + private val notAuctionableFilter = MultiFilter() + + @SubscribeEvent + fun onRepoReload(event: RepositoryReloadEvent) { + try { + val hideNotClickableItems = event.getConstant("HideNotClickableItems")!! + hideNpcSellFilter.load(hideNotClickableItems["hide_npc_sell"].asJsonObject) + hideInStorageFilter.load(hideNotClickableItems["hide_in_storage"].asJsonObject) + tradeNpcFilter.load(event.getConstant("TradeNpcs")!!) + updateSalvageList(hideNotClickableItems) + hidePlayerTradeFilter.load(hideNotClickableItems["hide_player_trade"].asJsonObject) + notAuctionableFilter.load(hideNotClickableItems["not_auctionable"].asJsonObject) + + } catch (e: Exception) { + e.printStackTrace() + LorenzUtils.error("error in RepositoryReloadEvent") + } + } + + private fun updateSalvageList(hideNotClickableItems: JsonObject) { + itemsToSalvage.clear() + val salvage = hideNotClickableItems["salvage"].asJsonObject + itemsToSalvage.addAll(salvage.asJsonObject["items"].asJsonArray.map { it.asString }) + for (armor in salvage.asJsonObject["armor"].asJsonArray.map { it.asString }) { + itemsToSalvage.add("$armor Helmet") + itemsToSalvage.add("$armor Chestplate") + itemsToSalvage.add("$armor Leggings") + itemsToSalvage.add("$armor Boots") + } + } + + @SubscribeEvent + fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { + if (!LorenzUtils.inSkyblock) return + if (isDisabled()) return + if (event.gui !is GuiChest) return + val guiChest = event.gui + val chest = guiChest.inventorySlots as ContainerChest + val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() + + for (slot in chest.inventorySlots) { + if (slot == null) continue + + if (slot.slotNumber == slot.slotIndex) continue + if (slot.stack == null) continue + + if (hide(chestName, slot.stack)) { + val color = LorenzColor.DARK_GRAY.addOpacity(160) + slot.stack.background = color.rgb + } + } + } + + @SubscribeEvent(priority = EventPriority.LOWEST) + fun onTooltip(event: ItemTooltipEvent) { + if (isDisabled()) return + if (event.toolTip == null) return + val guiChest = Minecraft.getMinecraft().currentScreen + if (guiChest !is GuiChest) return + val chest = guiChest.inventorySlots as ContainerChest + val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() + + val stack = event.itemStack + if (ItemUtils.getItemsInOpenChest().contains(stack)) return + if (!ItemUtils.getItemsInInventory().contains(stack)) return + + if (hide(chestName, stack)) { + val first = event.toolTip[0] + event.toolTip.clear() + event.toolTip.add("§7" + first.removeColor()) + event.toolTip.add("") + if (hideReason == "") { + event.toolTip.add("§4No hide reason!") + LorenzUtils.warning("Not hide reason for not clickable item!") + } else { + event.toolTip.add("§c$hideReason") + } + } + } + + @SubscribeEvent + fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) { + if (isDisabled()) return + if (event.gui !is GuiChest) return + val guiChest = event.gui + val chest = guiChest.inventorySlots as ContainerChest + val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() + + val slot = event.slot ?: return + + if (slot.slotNumber == slot.slotIndex) return + if (slot.stack == null) return + + val stack = slot.stack + + if (hide(chestName, stack)) { + event.isCanceled = true + + if (System.currentTimeMillis() > lastClickTime + 5_000) { + lastClickTime = System.currentTimeMillis() + } + return + } + } + + private fun isDisabled(): Boolean { + if (bypassUntil > System.currentTimeMillis()) return true + + return !SkyHanniMod.feature.inventory.hideNotClickableItems + } + + private fun hide(chestName: String, stack: ItemStack): Boolean { + hideReason = "" + return when { + hideNpcSell(chestName, stack) -> true + hideInStorage(chestName, stack) -> true + hideSalvage(chestName, stack) -> true + hidePlayerTrade(chestName, stack) -> true + hideBazaarOrAH(chestName, stack) -> true + hideAccessoryBag(chestName, stack) -> true + hideSackOfSacks(chestName, stack) -> true + hideFishingBag(chestName, stack) -> true + hidePotionBag(chestName, stack) -> true + hidePrivateIslandChest(chestName, stack) -> true + hideAttributeFusion(chestName, stack) -> true + hideYourEquipment(chestName, stack) -> true + else -> false + } + } + + private fun hideYourEquipment(chestName: String, stack: ItemStack): Boolean { + if (!chestName.startsWith("Your Equipment")) return false + + val list = listOf( + "HELMET", + "CHESTPLATE", + "LEGGINGS", + "BOOTS", + + "NECKLACE", + "CLOAK", + "BELT", + "GLOVES", + "BRACELET" + ) + for (type in list) { + if (stack.getLore().any { it.contains("§l") && it.contains(type) }) {//todo use item api + return false + } + } + + if (isSkyBlockMenuItem(stack)) { + hideReason = "The SkyBlock Menu cannot be put into the potion bag!" + return true + } + + hideReason = "This item cannot be put into your equipment!" + return true + } + + private fun hideAttributeFusion(chestName: String, stack: ItemStack): Boolean { + if (!chestName.startsWith("Attribute Fusion")) return false + + if (ItemUtils.hasAttributes(stack)) return false + + hideReason = "This item has no attributes!" + return true + } + + private fun hidePrivateIslandChest(chestName: String, stack: ItemStack): Boolean { + if (chestName != "Chest" && chestName != "Large Chest") return false + //TODO make check if player is on private island + + if (!ItemUtils.isSoulBound(stack)) return false + + hideReason = "This item cannot be stored into a chest!" + return true + } + + private fun hidePotionBag(chestName: String, stack: ItemStack): Boolean { + if (!chestName.startsWith("Potion Bag")) return false + + if (isSkyBlockMenuItem(stack)) { + hideReason = "The SkyBlock Menu cannot be put into the potion bag!" + return true + } + + if (stack.cleanName().endsWith(" Potion")) return false + + hideReason = "This item is not a potion!" + return true + } + + private fun hideFishingBag(chestName: String, stack: ItemStack): Boolean { + if (!chestName.startsWith("Fishing Bag")) return false + + if (isSkyBlockMenuItem(stack)) { + hideReason = "The SkyBlock Menu cannot be put into the fishing bag!" + return true + } + + if (stack.getLore().any { it.removeColor() == "Fishing Bait" }) { + return false + } + hideReason = "This item is not a fishing bait!" + return true + } + + private fun hideSackOfSacks(chestName: String, stack: ItemStack): Boolean { + if (!chestName.startsWith("Sack of Sacks")) return false + + val name = stack.cleanName() + if (ItemUtils.isSack(name)) return false + if (isSkyBlockMenuItem(stack)) return false + + hideReason = "This item is not a sack!" + return true + } + + private fun hideAccessoryBag(chestName: String, stack: ItemStack): Boolean { + if (!chestName.startsWith("Accessory Bag")) return false + + if (stack.getLore().any { it.contains("ACCESSORY") }) return false + if (isSkyBlockMenuItem(stack)) return false + + hideReason = "This item is not an accessory!" + return true + } + + private fun hidePlayerTrade(chestName: String, stack: ItemStack): Boolean { + if (!chestName.startsWith("You ")) return false + + if (ItemUtils.isCoopSoulBound(stack)) { + hideReason = "Soulbound items cannot be traded!" + return true + } + + if (isSkyBlockMenuItem(stack)) { + hideReason = "The SkyBlock Menu cannot be traded!" + return true + } + + val name = stack.cleanName() + + if (ItemUtils.isSack(name)) { + hideReason = "Sacks cannot be traded!" + return true + } + + val result = hidePlayerTradeFilter.match(name) + LorenzDebug.log("hidePlayerTradeList filter result for '$name': $result") + + if (result) hideReason = "This item cannot be traded!" + return result + } + + private fun hideNpcSell(chestName: String, stack: ItemStack): Boolean { + if (!tradeNpcFilter.match(chestName)) return false + + var name = stack.cleanName() + val size = stack.stackSize + val amountText = " x$size" + if (name.endsWith(amountText)) { + name = name.substring(0, name.length - amountText.length) + } + + if (isSkyBlockMenuItem(stack)) { + hideReason = "The SkyBlock Menu cannot be sold at the NPC!" + return true + } + + if (!ItemUtils.isRecombobulated(stack)) { + if (hideNpcSellFilter.match(name)) return false + + val id = stack.getInternalName() + if (VanillaItemManager.isVanillaItem(id) && !stack.isItemEnchanted) { + return false + } + } + + hideReason = "This item should not be sold at the NPC!" + return true + } + + private fun hideInStorage(chestName: String, stack: ItemStack): Boolean { + if (!chestName.contains("Ender Chest") && !chestName.contains("Backpack") && chestName != "Storage") return false + + if (isSkyBlockMenuItem(stack)) { + hideReason = "The SkyBlock Menu cannot be put into the storage!" + return true + } + + val name = stack.cleanName() + + if (ItemUtils.isSack(name)) { + hideReason = "Sacks cannot be put into the storage!" + return true + } + + val result = hideInStorageFilter.match(name) + + if (result) hideReason = "Bags cannot be put into the storage!" + return result + } + + private fun hideSalvage(chestName: String, stack: ItemStack): Boolean { + if (chestName != "Salvage Item") return false + + if (ItemUtils.isRecombobulated(stack)) { + hideReason = "This item should not be salvaged! (Recombobulated)" + return true + } + for (line in stack.getLore()) { + if (line.contains("LEGENDARY DUNGEON")) { + hideReason = "This item should not be salvaged! (Legendary)" + return true + } + } + + if (isSkyBlockMenuItem(stack)) { + hideReason = "The SkyBlock Menu cannot be salvaged!" + return true + } + + val name = stack.cleanName() + for (item in itemsToSalvage) { + if (name.endsWith(item)) { + return false + } + } + + hideReason = "This item cannot be salvaged!" + return true + } + + private fun hideBazaarOrAH(chestName: String, stack: ItemStack): Boolean { + val bazaarInventory = BazaarApi.isBazaarInventory(chestName) + + val auctionHouseInventory = + chestName == "Co-op Auction House" || chestName == "Auction House" || chestName == "Create BIN Auction" || chestName == "Create Auction" + if (!bazaarInventory && !auctionHouseInventory) return false + + + + if (isSkyBlockMenuItem(stack)) { + if (bazaarInventory) hideReason = "The SkyBlock Menu is not a Bazaar Product!" + if (auctionHouseInventory) hideReason = "The SkyBlock Menu cannot be auctioned!" + return true + } + + val displayName = stack.displayName + if (bazaarInventory != BazaarApi.isBazaarItem(displayName)) { + if (bazaarInventory) hideReason = "This item is not a Bazaar Product!" + if (auctionHouseInventory) hideReason = "Bazaar Products cannot be auctioned!" + + return true + } + + if (isNotAuctionable(stack)) return true + + return false + } + + private fun isNotAuctionable(stack: ItemStack): Boolean { + if (ItemUtils.isCoopSoulBound(stack)) { + hideReason = "Soulbound items cannot be auctioned!" + return true + } + + val name = stack.cleanName() + + if (ItemUtils.isSack(name)) { + hideReason = "Sacks cannot be auctioned!" + return true + } + + val result = notAuctionableFilter.match(name) + if (result) hideReason = "This item cannot be auctioned!" + return result + } + + private fun isSkyBlockMenuItem(stack: ItemStack): Boolean = stack.getInternalName() == "SKYBLOCK_MENU" +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/items/ItemDisplayOverlayFeatures.kt b/src/main/java/at/hannibal2/skyhanni/features/items/ItemDisplayOverlayFeatures.kt new file mode 100644 index 000000000..1ad9aa39b --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/items/ItemDisplayOverlayFeatures.kt @@ -0,0 +1,121 @@ +package at.hannibal2.skyhanni.features.items + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.GuiRenderItemEvent +import at.hannibal2.skyhanni.utils.ItemUtils +import at.hannibal2.skyhanni.utils.ItemUtils.cleanName +import at.hannibal2.skyhanni.utils.ItemUtils.getLore +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.between +import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex +import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.item.ItemStack +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class ItemDisplayOverlayFeatures { + + @SubscribeEvent + fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.Post) { + val item = event.stack ?: return + + if (!LorenzUtils.inSkyblock || item.stackSize != 1) return + + val stackTip = getStackTip(item) + + if (stackTip.isNotEmpty()) { + GlStateManager.disableLighting() + GlStateManager.disableDepth() + GlStateManager.disableBlend() + event.fontRenderer.drawStringWithShadow( + stackTip, + (event.x + 17 - event.fontRenderer.getStringWidth(stackTip)).toFloat(), + (event.y + 9).toFloat(), + 16777215 + ) + GlStateManager.enableLighting() + GlStateManager.enableDepth() + } + + } + + private fun getStackTip(item: ItemStack): String { + val name = item.cleanName() + + if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(0)) { + when (name) { + "First Master Star" -> return "1" + "Second Master Star" -> return "2" + "Third Master Star" -> return "3" + "Fourth Master Star" -> return "4" + "Fifth Master Star" -> return "5" + } + } + + if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(1)) { + if (name.matchRegex("(.*)Master Skull - Tier .")) { + return name.substring(name.length - 1) + } + } + + if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(2)) { + if (name.contains("Golden ") || name.contains("Diamond ")) { + when { + name.contains("Bonzo") -> return "1" + name.contains("Scarf") -> return "2" + name.contains("Professor") -> return "3" + name.contains("Thorn") -> return "4" + name.contains("Livid") -> return "5" + name.contains("Sadan") -> return "6" + name.contains("Necron") -> return "7" + } + } + } + + if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(3)) { + if (name.startsWith("New Year Cake (")) { + return "§b" + name.between("(Year ", ")") + } + } + + if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(4)) { + if (ItemUtils.isPet(name)) { + val level = name.between("Lvl ", "] ").toInt() + if (level != ItemUtils.maxPetLevel(name)) { + return "$level" + } + } + } + + if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(5)) { + if (name.contains(" Minion ")) { + if (item.getLore().any { it.contains("Place this minion") }) { + val array = name.split(" ") + val last = array[array.size - 1] + return last.romanToDecimal().toString() + } + } + } + + if (SkyHanniMod.feature.inventory.displaySackName) { + if (ItemUtils.isSack(name)) { + //TODO fix this and replace other +// val sackName = grabSackName(name) + val split = name.split(" ") + val sackName = split[split.size - 2] + return (if (name.contains("Enchanted")) "§5" else "") + sackName.substring(0, 2) + } + } + + return "" + } + +// private fun grabSackName(name: String): String { +// val split = name.split(" ") +// val text = split[0] +// for (line in arrayOf("Large", "Medium", "Small", "Enchanted")) { +// if (text == line) return grabSackName(name.substring(text.length + 1)) +// } +// return text +// } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/items/VanillaItemManager.kt b/src/main/java/at/hannibal2/skyhanni/features/items/VanillaItemManager.kt new file mode 100644 index 000000000..f138d9c23 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/items/VanillaItemManager.kt @@ -0,0 +1,53 @@ +package at.hannibal2.skyhanni.features.items + +import com.google.gson.GsonBuilder +import com.google.gson.JsonObject +import java.io.BufferedReader +import java.io.File +import java.io.FileInputStream +import java.io.InputStreamReader +import java.nio.charset.StandardCharsets + +class VanillaItemManager { + private val gson = GsonBuilder().setPrettyPrinting().create() + + companion object { + private val vanillaItems: MutableList = ArrayList() + + fun isVanillaItem(internalName: String): Boolean { + return vanillaItems.contains(internalName) + } + } + + init { + load() + } + + private fun load() { + vanillaItems.clear() + val itemDirectory = File("config/notenoughupdates/repo/items") + if (!itemDirectory.isDirectory) return + val files = itemDirectory.listFiles() ?: return + for (file in files) { + val jsonObject = getJsonFromFile(file) + if (jsonObject != null) { + if (jsonObject.has("vanilla") && jsonObject["vanilla"].asBoolean) { + val name = file.name + val internalName = name.split(".")[0] + vanillaItems.add(internalName) + } + } + } + + } + + private fun getJsonFromFile(file: File): JsonObject? { + try { + BufferedReader(InputStreamReader(FileInputStream(file), + StandardCharsets.UTF_8 + )).use { reader -> return gson.fromJson(reader, JsonObject::class.java) } + } catch (e: Exception) { + return null + } + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/items/abilitycooldown/ItemAbilityCooldown.kt b/src/main/java/at/hannibal2/skyhanni/features/items/abilitycooldown/ItemAbilityCooldown.kt new file mode 100644 index 000000000..0d094c4b4 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/items/abilitycooldown/ItemAbilityCooldown.kt @@ -0,0 +1,215 @@ +package at.hannibal2.skyhanni.features.items.abilitycooldown + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.data.ItemRenderBackground.Companion.background +import at.hannibal2.skyhanni.events.GuiRenderItemEvent +import at.hannibal2.skyhanni.events.LorenzActionBarEvent +import at.hannibal2.skyhanni.utils.ItemUtils +import at.hannibal2.skyhanni.utils.ItemUtils.cleanName +import at.hannibal2.skyhanni.utils.LorenzColor +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.between +import net.minecraft.client.Minecraft +import net.minecraft.client.renderer.GlStateManager +import net.minecraft.item.ItemStack +import net.minecraftforge.common.MinecraftForge +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent + +class ItemAbilityCooldown { + + var lastAbility = "" + var tick = 0 + val items = mutableMapOf() + val witherImpactDetection = WitherImpactDetection(this) + + init { + MinecraftForge.EVENT_BUS.register(witherImpactDetection) + } + + fun clickWitherImpact() { + Ability.WITHER_IMPACT.click() + } + + @SubscribeEvent + fun onActionBar(event: LorenzActionBarEvent) { + if (!isEnabled()) return + + val message: String = event.message + if (message.contains(" (§6")) { + if (message.contains("§b) ")) { + val name: String = message.between(" (§6", "§b) ") + if (name == lastAbility) return + lastAbility = name + for (ability in Ability.values()) { + if (ability.abilityName == name) { + click(ability) + return + } + } + return + } + } + lastAbility = "" + } + + private fun isEnabled(): Boolean { + return LorenzUtils.inSkyblock && SkyHanniMod.feature.abilities.itemAbilityCooldown + } + + private fun click(ability: Ability) { +// if (ability.isActive()) return + if (!ability.actionBarDetection) return + ability.click() + } + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (!isEnabled()) return + + tick++ + if (tick % 2 == 0) { + checkHotbar() + } + } + + private fun checkHotbar() { + items.clear() + for ((stack, slot) in ItemUtils.getItemsInInventoryWithSlots(true)) { +// val inHotbar = slot in 36..43 + + val itemName: String = stack.cleanName() + val ability = hasAbility(itemName) + if (ability != null) { + + if (ability.isOnCooldown()) { + val duration: Long = ability.lastClick + ability.getCooldown() - System.currentTimeMillis() + val color = if (duration < 600) LorenzColor.RED else LorenzColor.YELLOW + items[stack] = ItemText(color, ability.getDurationText(), true) + } else { + items[stack] = ItemText(LorenzColor.GREEN, "R", false) + } + } + } + + } + + @SubscribeEvent + fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.Post) { + if (!isEnabled()) return + + val item = event.stack ?: return + if (item.stackSize != 1) return + + var stackTip = "" + + val guiOpen = Minecraft.getMinecraft().currentScreen != null + val itemText = items.filter { it.key == item } + .firstNotNullOfOrNull { it.value } ?: return + if (guiOpen && !itemText.onCooldown) return + + val color = itemText.color + stackTip = color.getChatColor() + itemText.text + + if (SkyHanniMod.feature.abilities.itemAbilityCooldownBackground) { + var opacity = 130 + if (color == LorenzColor.GREEN) { + opacity = 80 + } + item.background = color.addOpacity(opacity).rgb + } + + if (stackTip.isNotEmpty()) { + GlStateManager.disableLighting() + GlStateManager.disableDepth() + GlStateManager.disableBlend() + //TODO add option to change the size + event.fontRenderer.drawStringWithShadow( + stackTip, + (event.x + 17 - event.fontRenderer.getStringWidth(stackTip)).toFloat(), + (event.y + 9).toFloat(), + 16777215 + ) + GlStateManager.enableLighting() + GlStateManager.enableDepth() + } + } + + private fun hasAbility(itemName: String): Ability? { + for (ability in Ability.values()) { + for (name in ability.itemNames) { + if (itemName.contains(name)) { + return ability + } + } + } + return null + } + + enum class Ability( + val abilityName: String, + val cooldownInSeconds: Long, + vararg val itemNames: String, + var lastClick: Long = 0L, + val actionBarDetection: Boolean = true, + ) { + //TODO add into repo + ATOMSPLIT("Soulcry", 4, "Atomsplit Katana", "Vorpal Katana", "Voidedge Katana"), + WITHER_IMPACT("Wither Impact", 5, "Hyperion", "Scylla", "Valkyrie", "Astrea", actionBarDetection = false), + + HEAL_1("Small Heal", 7, "Wand of Healing"), + HEAL_2("Medium Heal", 7, "Wand of Mending"), + HEAL_3("Big Heal", 7, "Wand of Restoration"), + HEAL_4("Huge Heal", 7, "Wand of Atonement"), + + ICE_SPRAY("Ice Spray", 5, "Ice Spray Wand"), + GYRO("Gravity Storm", 30, "Gyrokinetic Wand"), + GIANTS_SWORD("Giant's Slam", 30, "Giant's Sword"), + + STAR_FALL("Starfall", 2, "Starlight Wand"), + VODOO_DOLL("Acupuncture", 5, "Voodoo Doll"), + INK_WAND("Ink Bomb", 30, "Ink Wand"), + GOLEM_SWORD("Iron Punch", 3, "Golem Sword"), + EMBER_ROD("Fire Blast", 30, "Ember Rod"), + ENDER_BOW("Ender Warp", 30, "Ender Bow"), + + LIVID_DAGGER("Throw", 5, "Livid Dagger"), + WEIRD_TUBA("Howl", 20, "Weird Tuba"), + + ENDSTONE_SWORD("Extreme Focus", 5, "End Stone Sword"), + PIGMAN_SWORD("Burning Souls", 5, "Pigman Sword"), + + SOULWARD("Soulward", 20, "Soul Esoward"), + ECHO("Echo", 3, "Ancestral Spade"), + + FIRE_VEIL("Fire Veil", 5, "Fire Veil Wand"), + //TODO add new crimson isle weapons + + ; + + fun click() { + lastClick = System.currentTimeMillis() + } + + fun isOnCooldown(): Boolean = lastClick + getCooldown() > System.currentTimeMillis() + + fun getCooldown(): Long = cooldownInSeconds * 1000 + + fun getDurationText(): String { + var duration: Long = lastClick + getCooldown() - System.currentTimeMillis() + return if (duration < 1600) { + duration /= 100 + var d = duration.toDouble() + d /= 10.0 + LorenzUtils.formatDouble(d) + } else { + duration /= 1000 + duration++ + LorenzUtils.formatInteger(duration.toInt()) + } + } + + } + + class ItemText(val color: LorenzColor, val text: String, val onCooldown: Boolean) +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/items/abilitycooldown/WitherImpactDetection.kt b/src/main/java/at/hannibal2/skyhanni/features/items/abilitycooldown/WitherImpactDetection.kt new file mode 100644 index 000000000..da0d5068c --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/items/abilitycooldown/WitherImpactDetection.kt @@ -0,0 +1,74 @@ +package at.hannibal2.skyhanni.features.items.abilitycooldown + +import at.hannibal2.skyhanni.events.PacketEvent +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraft.client.Minecraft +import net.minecraft.init.Items +import net.minecraft.item.ItemStack +import net.minecraft.nbt.NBTTagCompound +import net.minecraft.nbt.NBTTagList +import net.minecraft.network.play.client.C08PacketPlayerBlockPlacement +import net.minecraft.network.play.server.S1CPacketEntityMetadata +import net.minecraft.network.play.server.S2APacketParticles +import net.minecraft.util.EnumParticleTypes +import net.minecraftforge.common.util.Constants +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent + +/** + * Taken from Skytils under AGPL 3.0 + * Modified + * https://github.com/Skytils/SkytilsMod/blob/1.x/LICENSE.md + * @author Skytils + */ +class WitherImpactDetection(private val itemAbilityCooldown: ItemAbilityCooldown) { + + val S2APacketParticles.type: EnumParticleTypes + get() = this.particleType + var lastShieldUse = -1L + var lastShieldClick = 0L + + @SubscribeEvent + fun onReceivePacket(event: PacketEvent.ReceiveEvent) { + val mc = Minecraft.getMinecraft() + if (!LorenzUtils.inSkyblock || mc.theWorld == null) return + + event.packet.apply { + + if (this is S1CPacketEntityMetadata && lastShieldClick != -1L && entityId == mc.thePlayer?.entityId && System.currentTimeMillis() - lastShieldClick <= 500 && func_149376_c()?.any { it.dataValueId == 17 } == true) { + lastShieldUse = System.currentTimeMillis() + lastShieldClick = -1 + itemAbilityCooldown.clickWitherImpact() + } + } + } + + @SubscribeEvent + fun onSendPacket(event: PacketEvent.SendEvent) { + val mc = Minecraft.getMinecraft() + if (!LorenzUtils.inSkyblock || lastShieldUse != -1L || mc.thePlayer?.heldItem == null) return + if (event.packet is C08PacketPlayerBlockPlacement && mc.thePlayer.heldItem.item == Items.iron_sword && getExtraAttributes( + mc.thePlayer.heldItem + )?.getTagList("ability_scroll", Constants.NBT.TAG_STRING)?.asStringSet() + ?.contains("WITHER_SHIELD_SCROLL") == true + ) { + lastShieldClick = System.currentTimeMillis() + } + } + + @SubscribeEvent + fun onTick(event: TickEvent.ClientTickEvent) { + if (lastShieldUse != -1L) { + val diff = ((lastShieldUse + 5000 - System.currentTimeMillis()) / 1000f) + if (diff < 0) lastShieldUse = -1 + } + } + + private fun getExtraAttributes(item: ItemStack?): NBTTagCompound? { + return if (item == null || !item.hasTagCompound()) { + null + } else item.getSubCompound("ExtraAttributes", false) + } + + private fun NBTTagList.asStringSet() = (0..tagCount()).mapTo(hashSetOf()) { getStringTagAt(it) } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt new file mode 100644 index 000000000..7cc7b54a3 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangFreezeCooldown.kt @@ -0,0 +1,43 @@ +package at.hannibal2.skyhanni.features.nether.ashfang + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.utils.GuiRender.renderString +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex +import net.minecraftforge.client.event.RenderGameOverlayEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import java.text.DecimalFormat + +class AshfangFreezeCooldown { + + var lastHit = 0L + + @SubscribeEvent + fun onChatMessage(event: LorenzChatEvent) { + if (!isEnabled()) return + + val message = event.message + if (message.matchRegex("§cAshfang Follower's Cryogenic Blast hit you for (.*) damage!")) { + lastHit = System.currentTimeMillis() + } + } + + @SubscribeEvent + fun renderOverlay(event: RenderGameOverlayEvent.Post) { + if (!isEnabled()) return + val duration = System.currentTimeMillis() - lastHit + val maxDuration = 3_000 + + val remainingLong = maxDuration - duration + if (remainingLong > 0) { + val remaining = (remainingLong.toFloat() / 1000) + val format = DecimalFormat("0.0").format(remaining + 0.1) + SkyHanniMod.feature.abilities.ashfangFreezeCooldownPos.renderString("§cAshfang Freeze: §a${format}s") + } + } + + private fun isEnabled(): Boolean { + return LorenzUtils.inSkyblock && SkyHanniMod.feature.abilities.ashfangFreezeCooldown + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt new file mode 100644 index 000000000..59a98552a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/nether/ashfang/AshfangNextResetCooldown.kt @@ -0,0 +1,53 @@ +package at.hannibal2.skyhanni.features.nether.ashfang + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.utils.GuiRender.renderString +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraft.client.Minecraft +import net.minecraft.entity.item.EntityArmorStand +import net.minecraftforge.client.event.RenderGameOverlayEvent +import net.minecraftforge.event.world.WorldEvent +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent +import java.text.DecimalFormat + +class AshfangNextResetCooldown { + + private var spawnTime = 1L + + @SubscribeEvent + fun renderOverlay(event: ClientTickEvent) { + if (!isEnabled()) return + + if (Minecraft.getMinecraft().theWorld.loadedEntityList.any { + it is EntityArmorStand && it.posY > 145 && + (it.name.contains("§c§9Ashfang Acolyte§r") || it.name.contains("§c§cAshfang Underling§r")) + }) { + spawnTime = System.currentTimeMillis() + } + } + + @SubscribeEvent + fun renderOverlay(event: RenderGameOverlayEvent.Post) { + if (!isEnabled()) return + if (spawnTime == -1L) return + + val remainingTime = spawnTime + 46_100 - System.currentTimeMillis() + if (remainingTime > 0) { + val remaining = (remainingTime.toFloat() / 1000) + val format = DecimalFormat("0.0").format(remaining + 0.1) + SkyHanniMod.feature.abilities.ashfangNextResetCooldownPos.renderString("§cAshfang next reset in: §a${format}s") + } else { + spawnTime = -1 + } + } + + @SubscribeEvent + fun renderOverlay(event: WorldEvent.Load) { + spawnTime = -1 + } + + private fun isEnabled(): Boolean { + return LorenzUtils.inSkyblock && SkyHanniMod.feature.abilities.ashfangNextResetCooldown + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/fishing/SeaCreature.kt b/src/main/java/at/hannibal2/skyhanni/fishing/SeaCreature.kt deleted file mode 100644 index 935d415f3..000000000 --- a/src/main/java/at/hannibal2/skyhanni/fishing/SeaCreature.kt +++ /dev/null @@ -1,18 +0,0 @@ -package at.hannibal2.skyhanni.fishing - -data class SeaCreature( - val displayName: String, - val fishingExperience: Int, - val chatColor: String, - val rare: Boolean, -) { - - override fun toString(): String { - return chatColor + rare() + displayName - } - - private fun rare(): String { - return if (rare) "§l" else "" - } -} - diff --git a/src/main/java/at/hannibal2/skyhanni/fishing/SeaCreatureManager.kt b/src/main/java/at/hannibal2/skyhanni/fishing/SeaCreatureManager.kt deleted file mode 100644 index eec0dd781..000000000 --- a/src/main/java/at/hannibal2/skyhanni/fishing/SeaCreatureManager.kt +++ /dev/null @@ -1,64 +0,0 @@ -package at.hannibal2.skyhanni.fishing - -import at.hannibal2.skyhanni.events.RepositoryReloadEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class SeaCreatureManager { - - @SubscribeEvent - fun onRepoReload(event: RepositoryReloadEvent) { - seaCreatureMap.clear() - var counter = 0 - - try { - val data = event.getConstant("SeaCreatures")!! - - for (variant in data.entrySet().map { it.value.asJsonObject }) { - val chatColor = variant["chat_color"].asString - for ((displayName, value) in variant["sea_creatures"].asJsonObject.entrySet()) { - val seaCreature = value.asJsonObject - val chatMessage = seaCreature["chat_message"].asString - val fishingExperience = seaCreature["fishing_experience"].asInt - - val rare = if (seaCreature.has("rare")) { - seaCreature["rare"].asBoolean - } else false - - seaCreatureMap[chatMessage] = SeaCreature(displayName, fishingExperience, chatColor, rare) - counter++ - } - } - LorenzUtils.debug("loaded $counter sea creatures from repo") - -// seaCreatures.asJsonArray.map { it.asJsonObject }.forEach { -// val displayName = it["display_name"].asString -// val chatMessage = it["chat_message"].asString -// val fishingExperience = it["fishing_experience"].asInt -// val variantName = it["variant"].asString -// val special = it["special"].asBoolean -// -// val variant = try { -// FishingVariant.fromString(variantName) -// } catch (e: FishingVariantNotFoundException) { -// LorenzUtils.error("Error loading Sea Creature '$displayName': " + e.message) -// return -// } -// -// seaCreatureMap[chatMessage] = SeaCreature(displayName, fishingExperience, variant, special) -// } - - } catch (e: Exception) { - e.printStackTrace() - LorenzUtils.error("error in RepositoryReloadEvent") - } - } - - companion object { - val seaCreatureMap = mutableMapOf() - - fun getSeaCreature(message: String): SeaCreature? { - return seaCreatureMap.getOrDefault(message, null) - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/fishing/SeaCreatureMessageShortener.kt b/src/main/java/at/hannibal2/skyhanni/fishing/SeaCreatureMessageShortener.kt deleted file mode 100644 index 4fc3a1f12..000000000 --- a/src/main/java/at/hannibal2/skyhanni/fishing/SeaCreatureMessageShortener.kt +++ /dev/null @@ -1,24 +0,0 @@ -package at.hannibal2.skyhanni.fishing - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class SeaCreatureMessageShortener { - - @SubscribeEvent - fun onChatMessage(event: LorenzChatEvent) { - if (!LorenzUtils.inSkyblock) return - if (!SkyHanniMod.feature.fishing.shortenFishingMessage) return - - val seaCreature = SeaCreatureManager.getSeaCreature(event.message) - if (seaCreature != null) { - event.blockedReason = "sea_create_caught" - LorenzUtils.chat("§9You caught a $seaCreature§9!") - if (seaCreature.fishingExperience == 0) { - LorenzUtils.debug("no fishing exp set for " + seaCreature.displayName) - } - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/fishing/TrophyFishMessages.kt b/src/main/java/at/hannibal2/skyhanni/fishing/TrophyFishMessages.kt deleted file mode 100644 index f8cd19191..000000000 --- a/src/main/java/at/hannibal2/skyhanni/fishing/TrophyFishMessages.kt +++ /dev/null @@ -1,71 +0,0 @@ -package at.hannibal2.skyhanni.fishing - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.events.ProfileApiDataLoadedEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.between -import at.hannibal2.skyhanni.utils.LorenzUtils.removeColor -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class TrophyFishMessages { - - private val map = mutableMapOf() - - @SubscribeEvent - fun onProfileDataLoad(event: ProfileApiDataLoadedEvent) { - val profileData = event.profileData - - map.clear() - val trophyFishes = profileData["trophy_fish"].asJsonObject - for ((rawName, value) in trophyFishes.entrySet()) { - val rarity = when { - rawName.endsWith("_bronze") -> "bronze" - rawName.endsWith("_silver") -> "silver" - rawName.endsWith("_gold") -> "gold" - rawName.endsWith("_diamond") -> "diamond" - else -> continue - } - val text = rawName.replace("_", "") - val displayName = text.substring(0, text.length - rarity.length) - - val amount = value.asInt - -// LorenzDebug.log("$rarity: $displayName: $amount") - val name = rarity + "_" + displayName - map[name] = amount -// LorenzDebug.log("loaded trophy: $name = $amount") - } - } - - @SubscribeEvent - fun onStatusBar(event: LorenzChatEvent) { - if (!LorenzUtils.inSkyblock) return - if (!SkyHanniMod.feature.fishing.trophyCounter) return - - val message = event.message - if (message.startsWith("§6§lTROPHY FISH! §r§bYou caught a")) { - var displayName = if (message.contains(" a §r")) message.between(" a §r", "§r §r") else message.between(" an §r", "§r §r") - if (displayName.contains("§k")) { - displayName = displayName.replace("§k", "") - displayName = displayName.replace("Obfuscated", "Obfuscated Fish") - } - val rarity = message.between("§r §r", "§b.").lowercase().replace("§l", "") - - val name = (rarity + "_" + displayName).removeColor().lowercase().replace(" ", "") - val amount = map.getOrDefault(name, 0) + 1 - map[name] = amount - event.blockedReason = "trophy_fish" - - if (amount == 1) { - LorenzUtils.chat("§6TROPHY FISH! §c§lFIRST §r$rarity $displayName") - } else { - if (rarity.contains("bronze")) { - if (SkyHanniMod.feature.fishing.trophyFishBronzeHider) return - } - LorenzUtils.chat("§6TROPHY FISH! §7$amount. §r$rarity $displayName") - } -// LorenzDebug.log("new trophy: $name = $amount") - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/inventory/anvil/AnvilCombineHelper.kt b/src/main/java/at/hannibal2/skyhanni/inventory/anvil/AnvilCombineHelper.kt deleted file mode 100644 index 03405090b..000000000 --- a/src/main/java/at/hannibal2/skyhanni/inventory/anvil/AnvilCombineHelper.kt +++ /dev/null @@ -1,83 +0,0 @@ -package at.hannibal2.skyhanni.inventory.anvil - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.GuiContainerEvent -import at.hannibal2.skyhanni.utils.ItemUtils.getLore -import at.hannibal2.skyhanni.utils.LorenzColor -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.RenderUtils.highlight -import net.minecraft.client.gui.inventory.GuiChest -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.inventory.ContainerChest -import net.minecraft.item.ItemStack -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import org.lwjgl.opengl.GL11 - -class AnvilCombineHelper { - - @SubscribeEvent - fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { - if (!LorenzUtils.inSkyblock) return - if (!SkyHanniMod.feature.inventory.anvilCombineHelper) return - - if (event.gui !is GuiChest) return - val guiChest = event.gui - val chest = guiChest.inventorySlots as ContainerChest - val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() - - if (chestName != "Anvil") return - - val matchLore = mutableListOf() -// var compareItem: ItemStack? = null - - for (slot in chest.inventorySlots) { - if (slot == null) continue - - if (slot.slotNumber != slot.slotIndex) continue - if (slot.stack == null) continue - - if (slot.slotNumber == 29) { -// slot highlight LorenzColor.GREEN - val lore = slot.stack.getLore() -// compareItem = slot.stack - matchLore.addAll(lore) - break -// } else if (slot.slotIndex == 29) { -// slot highlight LorenzColor.YELLOW - } - } - - val lightingState = GL11.glIsEnabled(GL11.GL_LIGHTING) - GlStateManager.disableLighting() - GlStateManager.color(1f, 1f, 1f, 1f) - - if (matchLore.isEmpty()) return - - for (slot in chest.inventorySlots) { - if (slot == null) continue - - if (slot.slotNumber == slot.slotIndex) continue - if (slot.stack == null) continue - - - if (matchLore == slot.stack.getLore()) { - slot highlight LorenzColor.GREEN - } - -// if (compareItem == slot.stack) { -// slot highlight LorenzColor.GREEN -// } else if (compareItem.metadata == slot.stack.metadata) { -// slot highlight LorenzColor.YELLOW -// } - -// if (slot.slotNumber == 3) { -//// slot highlight LorenzColor.GREEN -//// } else if (slot.slotIndex == 4) { -//// slot highlight LorenzColor.YELLOW -//// } -// } - - if (lightingState) GlStateManager.enableLighting() - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/items/HideNotClickableItems.kt b/src/main/java/at/hannibal2/skyhanni/items/HideNotClickableItems.kt deleted file mode 100644 index 323fb2254..000000000 --- a/src/main/java/at/hannibal2/skyhanni/items/HideNotClickableItems.kt +++ /dev/null @@ -1,416 +0,0 @@ -package at.hannibal2.skyhanni.items - -import at.hannibal2.skyhanni.ItemRenderBackground.Companion.background -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.bazaar.BazaarApi -import at.hannibal2.skyhanni.events.GuiContainerEvent -import at.hannibal2.skyhanni.events.RepositoryReloadEvent -import at.hannibal2.skyhanni.utils.* -import at.hannibal2.skyhanni.utils.ItemUtils.cleanName -import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName -import at.hannibal2.skyhanni.utils.ItemUtils.getLore -import at.hannibal2.skyhanni.utils.LorenzUtils.removeColor -import com.google.gson.JsonObject -import net.minecraft.client.Minecraft -import net.minecraft.client.gui.inventory.GuiChest -import net.minecraft.inventory.ContainerChest -import net.minecraft.item.ItemStack -import net.minecraftforge.event.entity.player.ItemTooltipEvent -import net.minecraftforge.fml.common.eventhandler.EventPriority -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class HideNotClickableItems { - - private var hideReason = "" - - private var lastClickTime = 0L - private var bypassUntil = 0L - - private val hideNpcSellFilter = MultiFilter() - private val hideInStorageFilter = MultiFilter() - private val tradeNpcFilter = MultiFilter() - private val itemsToSalvage = mutableListOf() - private val hidePlayerTradeFilter = MultiFilter() - private val notAuctionableFilter = MultiFilter() - - @SubscribeEvent - fun onRepoReload(event: RepositoryReloadEvent) { - try { - val hideNotClickableItems = event.getConstant("HideNotClickableItems")!! - hideNpcSellFilter.load(hideNotClickableItems["hide_npc_sell"].asJsonObject) - hideInStorageFilter.load(hideNotClickableItems["hide_in_storage"].asJsonObject) - tradeNpcFilter.load(event.getConstant("TradeNpcs")!!) - updateSalvageList(hideNotClickableItems) - hidePlayerTradeFilter.load(hideNotClickableItems["hide_player_trade"].asJsonObject) - notAuctionableFilter.load(hideNotClickableItems["not_auctionable"].asJsonObject) - - } catch (e: Exception) { - e.printStackTrace() - LorenzUtils.error("error in RepositoryReloadEvent") - } - } - - private fun updateSalvageList(hideNotClickableItems: JsonObject) { - itemsToSalvage.clear() - val salvage = hideNotClickableItems["salvage"].asJsonObject - itemsToSalvage.addAll(salvage.asJsonObject["items"].asJsonArray.map { it.asString }) - for (armor in salvage.asJsonObject["armor"].asJsonArray.map { it.asString }) { - itemsToSalvage.add("$armor Helmet") - itemsToSalvage.add("$armor Chestplate") - itemsToSalvage.add("$armor Leggings") - itemsToSalvage.add("$armor Boots") - } - } - - @SubscribeEvent - fun onBackgroundDrawn(event: GuiContainerEvent.BackgroundDrawnEvent) { - if (!LorenzUtils.inSkyblock) return - if (isDisabled()) return - if (event.gui !is GuiChest) return - val guiChest = event.gui - val chest = guiChest.inventorySlots as ContainerChest - val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() - - for (slot in chest.inventorySlots) { - if (slot == null) continue - - if (slot.slotNumber == slot.slotIndex) continue - if (slot.stack == null) continue - - if (hide(chestName, slot.stack)) { - val color = LorenzColor.DARK_GRAY.addOpacity(160) - slot.stack.background = color.rgb - } - } - } - - @SubscribeEvent(priority = EventPriority.LOWEST) - fun onTooltip(event: ItemTooltipEvent) { - if (isDisabled()) return - if (event.toolTip == null) return - val guiChest = Minecraft.getMinecraft().currentScreen - if (guiChest !is GuiChest) return - val chest = guiChest.inventorySlots as ContainerChest - val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() - - val stack = event.itemStack - if (ItemUtils.getItemsInOpenChest().contains(stack)) return - if (!ItemUtils.getItemsInInventory().contains(stack)) return - - if (hide(chestName, stack)) { - val first = event.toolTip[0] - event.toolTip.clear() - event.toolTip.add("§7" + first.removeColor()) - event.toolTip.add("") - if (hideReason == "") { - event.toolTip.add("§4No hide reason!") - LorenzUtils.warning("Not hide reason for not clickable item!") - } else { - event.toolTip.add("§c$hideReason") - } - } - } - - @SubscribeEvent - fun onSlotClick(event: GuiContainerEvent.SlotClickEvent) { - if (isDisabled()) return - if (event.gui !is GuiChest) return - val guiChest = event.gui - val chest = guiChest.inventorySlots as ContainerChest - val chestName = chest.lowerChestInventory.displayName.unformattedText.trim() - - val slot = event.slot ?: return - - if (slot.slotNumber == slot.slotIndex) return - if (slot.stack == null) return - - val stack = slot.stack - - if (hide(chestName, stack)) { - event.isCanceled = true - - if (System.currentTimeMillis() > lastClickTime + 5_000) { - lastClickTime = System.currentTimeMillis() - } - return - } - } - - private fun isDisabled(): Boolean { - if (bypassUntil > System.currentTimeMillis()) return true - - return !SkyHanniMod.feature.inventory.hideNotClickableItems - } - - private fun hide(chestName: String, stack: ItemStack): Boolean { - hideReason = "" - return when { - hideNpcSell(chestName, stack) -> true - hideInStorage(chestName, stack) -> true - hideSalvage(chestName, stack) -> true - hidePlayerTrade(chestName, stack) -> true - hideBazaarOrAH(chestName, stack) -> true - hideAccessoryBag(chestName, stack) -> true - hideSackOfSacks(chestName, stack) -> true - hideFishingBag(chestName, stack) -> true - hidePotionBag(chestName, stack) -> true - hidePrivateIslandChest(chestName, stack) -> true - hideAttributeFusion(chestName, stack) -> true - hideYourEquipment(chestName, stack) -> true - else -> false - } - } - - private fun hideYourEquipment(chestName: String, stack: ItemStack): Boolean { - if (!chestName.startsWith("Your Equipment")) return false - - val list = listOf( - "HELMET", - "CHESTPLATE", - "LEGGINGS", - "BOOTS", - - "NECKLACE", - "CLOAK", - "BELT", - "GLOVES", - "BRACELET" - ) - for (type in list) { - if (stack.getLore().any { it.contains("§l") && it.contains(type) }) {//todo use item api - return false - } - } - - if (isSkyBlockMenuItem(stack)) { - hideReason = "The SkyBlock Menu cannot be put into the potion bag!" - return true - } - - hideReason = "This item cannot be put into your equipment!" - return true - } - - private fun hideAttributeFusion(chestName: String, stack: ItemStack): Boolean { - if (!chestName.startsWith("Attribute Fusion")) return false - - if (ItemUtils.hasAttributes(stack)) return false - - hideReason = "This item has no attributes!" - return true - } - - private fun hidePrivateIslandChest(chestName: String, stack: ItemStack): Boolean { - if (chestName != "Chest" && chestName != "Large Chest") return false - //TODO make check if player is on private island - - if (!ItemUtils.isSoulBound(stack)) return false - - hideReason = "This item cannot be stored into a chest!" - return true - } - - private fun hidePotionBag(chestName: String, stack: ItemStack): Boolean { - if (!chestName.startsWith("Potion Bag")) return false - - if (isSkyBlockMenuItem(stack)) { - hideReason = "The SkyBlock Menu cannot be put into the potion bag!" - return true - } - - if (stack.cleanName().endsWith(" Potion")) return false - - hideReason = "This item is not a potion!" - return true - } - - private fun hideFishingBag(chestName: String, stack: ItemStack): Boolean { - if (!chestName.startsWith("Fishing Bag")) return false - - if (isSkyBlockMenuItem(stack)) { - hideReason = "The SkyBlock Menu cannot be put into the fishing bag!" - return true - } - - if (stack.getLore().any { it.removeColor() == "Fishing Bait" }) { - return false - } - hideReason = "This item is not a fishing bait!" - return true - } - - private fun hideSackOfSacks(chestName: String, stack: ItemStack): Boolean { - if (!chestName.startsWith("Sack of Sacks")) return false - - val name = stack.cleanName() - if (ItemUtils.isSack(name)) return false - if (isSkyBlockMenuItem(stack)) return false - - hideReason = "This item is not a sack!" - return true - } - - private fun hideAccessoryBag(chestName: String, stack: ItemStack): Boolean { - if (!chestName.startsWith("Accessory Bag")) return false - - if (stack.getLore().any { it.contains("ACCESSORY") }) return false - if (isSkyBlockMenuItem(stack)) return false - - hideReason = "This item is not an accessory!" - return true - } - - private fun hidePlayerTrade(chestName: String, stack: ItemStack): Boolean { - if (!chestName.startsWith("You ")) return false - - if (ItemUtils.isCoopSoulBound(stack)) { - hideReason = "Soulbound items cannot be traded!" - return true - } - - if (isSkyBlockMenuItem(stack)) { - hideReason = "The SkyBlock Menu cannot be traded!" - return true - } - - val name = stack.cleanName() - - if (ItemUtils.isSack(name)) { - hideReason = "Sacks cannot be traded!" - return true - } - - val result = hidePlayerTradeFilter.match(name) - LorenzDebug.log("hidePlayerTradeList filter result for '$name': $result") - - if (result) hideReason = "This item cannot be traded!" - return result - } - - private fun hideNpcSell(chestName: String, stack: ItemStack): Boolean { - if (!tradeNpcFilter.match(chestName)) return false - - var name = stack.cleanName() - val size = stack.stackSize - val amountText = " x$size" - if (name.endsWith(amountText)) { - name = name.substring(0, name.length - amountText.length) - } - - if (isSkyBlockMenuItem(stack)) { - hideReason = "The SkyBlock Menu cannot be sold at the NPC!" - return true - } - - if (!ItemUtils.isRecombobulated(stack)) { - if (hideNpcSellFilter.match(name)) return false - - val id = stack.getInternalName() - if (VanillaItemManager.isVanillaItem(id) && !stack.isItemEnchanted) { - return false - } - } - - hideReason = "This item should not be sold at the NPC!" - return true - } - - private fun hideInStorage(chestName: String, stack: ItemStack): Boolean { - if (!chestName.contains("Ender Chest") && !chestName.contains("Backpack") && chestName != "Storage") return false - - if (isSkyBlockMenuItem(stack)) { - hideReason = "The SkyBlock Menu cannot be put into the storage!" - return true - } - - val name = stack.cleanName() - - if (ItemUtils.isSack(name)) { - hideReason = "Sacks cannot be put into the storage!" - return true - } - - val result = hideInStorageFilter.match(name) - - if (result) hideReason = "Bags cannot be put into the storage!" - return result - } - - private fun hideSalvage(chestName: String, stack: ItemStack): Boolean { - if (chestName != "Salvage Item") return false - - if (ItemUtils.isRecombobulated(stack)) { - hideReason = "This item should not be salvaged! (Recombobulated)" - return true - } - for (line in stack.getLore()) { - if (line.contains("LEGENDARY DUNGEON")) { - hideReason = "This item should not be salvaged! (Legendary)" - return true - } - } - - if (isSkyBlockMenuItem(stack)) { - hideReason = "The SkyBlock Menu cannot be salvaged!" - return true - } - - val name = stack.cleanName() - for (item in itemsToSalvage) { - if (name.endsWith(item)) { - return false - } - } - - hideReason = "This item cannot be salvaged!" - return true - } - - private fun hideBazaarOrAH(chestName: String, stack: ItemStack): Boolean { - val bazaarInventory = BazaarApi.isBazaarInventory(chestName) - - val auctionHouseInventory = - chestName == "Co-op Auction House" || chestName == "Auction House" || chestName == "Create BIN Auction" || chestName == "Create Auction" - if (!bazaarInventory && !auctionHouseInventory) return false - - - - if (isSkyBlockMenuItem(stack)) { - if (bazaarInventory) hideReason = "The SkyBlock Menu is not a Bazaar Product!" - if (auctionHouseInventory) hideReason = "The SkyBlock Menu cannot be auctioned!" - return true - } - - val displayName = stack.displayName - if (bazaarInventory != BazaarApi.isBazaarItem(displayName)) { - if (bazaarInventory) hideReason = "This item is not a Bazaar Product!" - if (auctionHouseInventory) hideReason = "Bazaar Products cannot be auctioned!" - - return true - } - - if (isNotAuctionable(stack)) return true - - return false - } - - private fun isNotAuctionable(stack: ItemStack): Boolean { - if (ItemUtils.isCoopSoulBound(stack)) { - hideReason = "Soulbound items cannot be auctioned!" - return true - } - - val name = stack.cleanName() - - if (ItemUtils.isSack(name)) { - hideReason = "Sacks cannot be auctioned!" - return true - } - - val result = notAuctionableFilter.match(name) - if (result) hideReason = "This item cannot be auctioned!" - return result - } - - private fun isSkyBlockMenuItem(stack: ItemStack): Boolean = stack.getInternalName() == "SKYBLOCK_MENU" -} diff --git a/src/main/java/at/hannibal2/skyhanni/items/ItemDisplayOverlayFeatures.kt b/src/main/java/at/hannibal2/skyhanni/items/ItemDisplayOverlayFeatures.kt deleted file mode 100644 index 30428157f..000000000 --- a/src/main/java/at/hannibal2/skyhanni/items/ItemDisplayOverlayFeatures.kt +++ /dev/null @@ -1,121 +0,0 @@ -package at.hannibal2.skyhanni.items - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.GuiRenderItemEvent -import at.hannibal2.skyhanni.utils.ItemUtils -import at.hannibal2.skyhanni.utils.ItemUtils.cleanName -import at.hannibal2.skyhanni.utils.ItemUtils.getLore -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.between -import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex -import at.hannibal2.skyhanni.utils.NumberUtil.romanToDecimal -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.item.ItemStack -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class ItemDisplayOverlayFeatures { - - @SubscribeEvent - fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.Post) { - val item = event.stack ?: return - - if (!LorenzUtils.inSkyblock || item.stackSize != 1) return - - val stackTip = getStackTip(item) - - if (stackTip.isNotEmpty()) { - GlStateManager.disableLighting() - GlStateManager.disableDepth() - GlStateManager.disableBlend() - event.fontRenderer.drawStringWithShadow( - stackTip, - (event.x + 17 - event.fontRenderer.getStringWidth(stackTip)).toFloat(), - (event.y + 9).toFloat(), - 16777215 - ) - GlStateManager.enableLighting() - GlStateManager.enableDepth() - } - - } - - private fun getStackTip(item: ItemStack): String { - val name = item.cleanName() - - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(0)) { - when (name) { - "First Master Star" -> return "1" - "Second Master Star" -> return "2" - "Third Master Star" -> return "3" - "Fourth Master Star" -> return "4" - "Fifth Master Star" -> return "5" - } - } - - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(1)) { - if (name.matchRegex("(.*)Master Skull - Tier .")) { - return name.substring(name.length - 1) - } - } - - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(2)) { - if (name.contains("Golden ") || name.contains("Diamond ")) { - when { - name.contains("Bonzo") -> return "1" - name.contains("Scarf") -> return "2" - name.contains("Professor") -> return "3" - name.contains("Thorn") -> return "4" - name.contains("Livid") -> return "5" - name.contains("Sadan") -> return "6" - name.contains("Necron") -> return "7" - } - } - } - - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(3)) { - if (name.startsWith("New Year Cake (")) { - return "§b" + name.between("(Year ", ")") - } - } - - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(4)) { - if (ItemUtils.isPet(name)) { - val level = name.between("Lvl ", "] ").toInt() - if (level != ItemUtils.maxPetLevel(name)) { - return "$level" - } - } - } - - if (SkyHanniMod.feature.inventory.itemNumberAsStackSize.contains(5)) { - if (name.contains(" Minion ")) { - if (item.getLore().any { it.contains("Place this minion") }) { - val array = name.split(" ") - val last = array[array.size - 1] - return last.romanToDecimal().toString() - } - } - } - - if (SkyHanniMod.feature.inventory.displaySackName) { - if (ItemUtils.isSack(name)) { - //TODO fix this and replace other -// val sackName = grabSackName(name) - val split = name.split(" ") - val sackName = split[split.size - 2] - return (if (name.contains("Enchanted")) "§5" else "") + sackName.substring(0, 2) - } - } - - return "" - } - -// private fun grabSackName(name: String): String { -// val split = name.split(" ") -// val text = split[0] -// for (line in arrayOf("Large", "Medium", "Small", "Enchanted")) { -// if (text == line) return grabSackName(name.substring(text.length + 1)) -// } -// return text -// } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/items/VanillaItemManager.kt b/src/main/java/at/hannibal2/skyhanni/items/VanillaItemManager.kt deleted file mode 100644 index 2997de20c..000000000 --- a/src/main/java/at/hannibal2/skyhanni/items/VanillaItemManager.kt +++ /dev/null @@ -1,54 +0,0 @@ -package at.hannibal2.skyhanni.items - -import at.hannibal2.skyhanni.utils.LorenzDebug -import com.google.gson.GsonBuilder -import com.google.gson.JsonObject -import java.io.BufferedReader -import java.io.File -import java.io.FileInputStream -import java.io.InputStreamReader -import java.nio.charset.StandardCharsets - -class VanillaItemManager { - private val gson = GsonBuilder().setPrettyPrinting().create() - - companion object { - private val vanillaItems: MutableList = ArrayList() - - fun isVanillaItem(internalName: String): Boolean { - return vanillaItems.contains(internalName) - } - } - - init { - load() - } - - private fun load() { - vanillaItems.clear() - val itemDirectory = File("config/notenoughupdates/repo/items") - if (!itemDirectory.isDirectory) return - val files = itemDirectory.listFiles() ?: return - for (file in files) { - val jsonObject = getJsonFromFile(file) - if (jsonObject != null) { - if (jsonObject.has("vanilla") && jsonObject["vanilla"].asBoolean) { - val name = file.name - val internalName = name.split(".")[0] - vanillaItems.add(internalName) - } - } - } - - } - - private fun getJsonFromFile(file: File): JsonObject? { - try { - BufferedReader(InputStreamReader(FileInputStream(file), - StandardCharsets.UTF_8 - )).use { reader -> return gson.fromJson(reader, JsonObject::class.java) } - } catch (e: Exception) { - return null - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/items/abilitycooldown/ItemAbilityCooldown.kt b/src/main/java/at/hannibal2/skyhanni/items/abilitycooldown/ItemAbilityCooldown.kt deleted file mode 100644 index 7ddf1d2a5..000000000 --- a/src/main/java/at/hannibal2/skyhanni/items/abilitycooldown/ItemAbilityCooldown.kt +++ /dev/null @@ -1,215 +0,0 @@ -package at.hannibal2.skyhanni.items.abilitycooldown - -import at.hannibal2.skyhanni.ItemRenderBackground.Companion.background -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.GuiRenderItemEvent -import at.hannibal2.skyhanni.events.LorenzActionBarEvent -import at.hannibal2.skyhanni.utils.ItemUtils -import at.hannibal2.skyhanni.utils.ItemUtils.cleanName -import at.hannibal2.skyhanni.utils.LorenzColor -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.between -import net.minecraft.client.Minecraft -import net.minecraft.client.renderer.GlStateManager -import net.minecraft.item.ItemStack -import net.minecraftforge.common.MinecraftForge -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent - -class ItemAbilityCooldown { - - var lastAbility = "" - var tick = 0 - val items = mutableMapOf() - val witherImpactDetection = WitherImpactDetection(this) - - init { - MinecraftForge.EVENT_BUS.register(witherImpactDetection) - } - - fun clickWitherImpact() { - Ability.WITHER_IMPACT.click() - } - - @SubscribeEvent - fun onActionBar(event: LorenzActionBarEvent) { - if (!isEnabled()) return - - val message: String = event.message - if (message.contains(" (§6")) { - if (message.contains("§b) ")) { - val name: String = message.between(" (§6", "§b) ") - if (name == lastAbility) return - lastAbility = name - for (ability in Ability.values()) { - if (ability.abilityName == name) { - click(ability) - return - } - } - return - } - } - lastAbility = "" - } - - private fun isEnabled(): Boolean { - return LorenzUtils.inSkyblock && SkyHanniMod.feature.abilities.itemAbilityCooldown - } - - private fun click(ability: Ability) { -// if (ability.isActive()) return - if (!ability.actionBarDetection) return - ability.click() - } - - @SubscribeEvent - fun onTick(event: TickEvent.ClientTickEvent) { - if (!isEnabled()) return - - tick++ - if (tick % 2 == 0) { - checkHotbar() - } - } - - private fun checkHotbar() { - items.clear() - for ((stack, slot) in ItemUtils.getItemsInInventoryWithSlots(true)) { -// val inHotbar = slot in 36..43 - - val itemName: String = stack.cleanName() - val ability = hasAbility(itemName) - if (ability != null) { - - if (ability.isOnCooldown()) { - val duration: Long = ability.lastClick + ability.getCooldown() - System.currentTimeMillis() - val color = if (duration < 600) LorenzColor.RED else LorenzColor.YELLOW - items[stack] = ItemText(color, ability.getDurationText(), true) - } else { - items[stack] = ItemText(LorenzColor.GREEN, "R", false) - } - } - } - - } - - @SubscribeEvent - fun onRenderItemOverlayPost(event: GuiRenderItemEvent.RenderOverlayEvent.Post) { - if (!isEnabled()) return - - val item = event.stack ?: return - if (item.stackSize != 1) return - - var stackTip = "" - - val guiOpen = Minecraft.getMinecraft().currentScreen != null - val itemText = items.filter { it.key == item } - .firstNotNullOfOrNull { it.value } ?: return - if (guiOpen && !itemText.onCooldown) return - - val color = itemText.color - stackTip = color.getChatColor() + itemText.text - - if (SkyHanniMod.feature.abilities.itemAbilityCooldownBackground) { - var opacity = 130 - if (color == LorenzColor.GREEN) { - opacity = 80 - } - item.background = color.addOpacity(opacity).rgb - } - - if (stackTip.isNotEmpty()) { - GlStateManager.disableLighting() - GlStateManager.disableDepth() - GlStateManager.disableBlend() - //TODO add option to change the size - event.fontRenderer.drawStringWithShadow( - stackTip, - (event.x + 17 - event.fontRenderer.getStringWidth(stackTip)).toFloat(), - (event.y + 9).toFloat(), - 16777215 - ) - GlStateManager.enableLighting() - GlStateManager.enableDepth() - } - } - - private fun hasAbility(itemName: String): Ability? { - for (ability in Ability.values()) { - for (name in ability.itemNames) { - if (itemName.contains(name)) { - return ability - } - } - } - return null - } - - enum class Ability( - val abilityName: String, - val cooldownInSeconds: Long, - vararg val itemNames: String, - var lastClick: Long = 0L, - val actionBarDetection: Boolean = true, - ) { - //TODO add into repo - ATOMSPLIT("Soulcry", 4, "Atomsplit Katana", "Vorpal Katana", "Voidedge Katana"), - WITHER_IMPACT("Wither Impact", 5, "Hyperion", "Scylla", "Valkyrie", "Astrea", actionBarDetection = false), - - HEAL_1("Small Heal", 7, "Wand of Healing"), - HEAL_2("Medium Heal", 7, "Wand of Mending"), - HEAL_3("Big Heal", 7, "Wand of Restoration"), - HEAL_4("Huge Heal", 7, "Wand of Atonement"), - - ICE_SPRAY("Ice Spray", 5, "Ice Spray Wand"), - GYRO("Gravity Storm", 30, "Gyrokinetic Wand"), - GIANTS_SWORD("Giant's Slam", 30, "Giant's Sword"), - - STAR_FALL("Starfall", 2, "Starlight Wand"), - VODOO_DOLL("Acupuncture", 5, "Voodoo Doll"), - INK_WAND("Ink Bomb", 30, "Ink Wand"), - GOLEM_SWORD("Iron Punch", 3, "Golem Sword"), - EMBER_ROD("Fire Blast", 30, "Ember Rod"), - ENDER_BOW("Ender Warp", 30, "Ender Bow"), - - LIVID_DAGGER("Throw", 5, "Livid Dagger"), - WEIRD_TUBA("Howl", 20, "Weird Tuba"), - - ENDSTONE_SWORD("Extreme Focus", 5, "End Stone Sword"), - PIGMAN_SWORD("Burning Souls", 5, "Pigman Sword"), - - SOULWARD("Soulward", 20, "Soul Esoward"), - ECHO("Echo", 3, "Ancestral Spade"), - - FIRE_VEIL("Fire Veil", 5, "Fire Veil Wand"), - //TODO add new crimson isle weapons - - ; - - fun click() { - lastClick = System.currentTimeMillis() - } - - fun isOnCooldown(): Boolean = lastClick + getCooldown() > System.currentTimeMillis() - - fun getCooldown(): Long = cooldownInSeconds * 1000 - - fun getDurationText(): String { - var duration: Long = lastClick + getCooldown() - System.currentTimeMillis() - return if (duration < 1600) { - duration /= 100 - var d = duration.toDouble() - d /= 10.0 - LorenzUtils.formatDouble(d) - } else { - duration /= 1000 - duration++ - LorenzUtils.formatInteger(duration.toInt()) - } - } - - } - - class ItemText(val color: LorenzColor, val text: String, val onCooldown: Boolean) -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/items/abilitycooldown/WitherImpactDetection.kt b/src/main/java/at/hannibal2/skyhanni/items/abilitycooldown/WitherImpactDetection.kt deleted file mode 100644 index 4bc2939fd..000000000 --- a/src/main/java/at/hannibal2/skyhanni/items/abilitycooldown/WitherImpactDetection.kt +++ /dev/null @@ -1,74 +0,0 @@ -package at.hannibal2.skyhanni.items.abilitycooldown - -import at.hannibal2.skyhanni.events.PacketEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraft.client.Minecraft -import net.minecraft.init.Items -import net.minecraft.item.ItemStack -import net.minecraft.nbt.NBTTagCompound -import net.minecraft.nbt.NBTTagList -import net.minecraft.network.play.client.C08PacketPlayerBlockPlacement -import net.minecraft.network.play.server.S1CPacketEntityMetadata -import net.minecraft.network.play.server.S2APacketParticles -import net.minecraft.util.EnumParticleTypes -import net.minecraftforge.common.util.Constants -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent - -/** - * Taken from Skytils under AGPL 3.0 - * Modified - * https://github.com/Skytils/SkytilsMod/blob/1.x/LICENSE.md - * @author Skytils - */ -class WitherImpactDetection(private val itemAbilityCooldown: ItemAbilityCooldown) { - - val S2APacketParticles.type: EnumParticleTypes - get() = this.particleType - var lastShieldUse = -1L - var lastShieldClick = 0L - - @SubscribeEvent - fun onReceivePacket(event: PacketEvent.ReceiveEvent) { - val mc = Minecraft.getMinecraft() - if (!LorenzUtils.inSkyblock || mc.theWorld == null) return - - event.packet.apply { - - if (this is S1CPacketEntityMetadata && lastShieldClick != -1L && entityId == mc.thePlayer?.entityId && System.currentTimeMillis() - lastShieldClick <= 500 && func_149376_c()?.any { it.dataValueId == 17 } == true) { - lastShieldUse = System.currentTimeMillis() - lastShieldClick = -1 - itemAbilityCooldown.clickWitherImpact() - } - } - } - - @SubscribeEvent - fun onSendPacket(event: PacketEvent.SendEvent) { - val mc = Minecraft.getMinecraft() - if (!LorenzUtils.inSkyblock || lastShieldUse != -1L || mc.thePlayer?.heldItem == null) return - if (event.packet is C08PacketPlayerBlockPlacement && mc.thePlayer.heldItem.item == Items.iron_sword && getExtraAttributes( - mc.thePlayer.heldItem - )?.getTagList("ability_scroll", Constants.NBT.TAG_STRING)?.asStringSet() - ?.contains("WITHER_SHIELD_SCROLL") == true - ) { - lastShieldClick = System.currentTimeMillis() - } - } - - @SubscribeEvent - fun onTick(event: TickEvent.ClientTickEvent) { - if (lastShieldUse != -1L) { - val diff = ((lastShieldUse + 5000 - System.currentTimeMillis()) / 1000f) - if (diff < 0) lastShieldUse = -1 - } - } - - private fun getExtraAttributes(item: ItemStack?): NBTTagCompound? { - return if (item == null || !item.hasTagCompound()) { - null - } else item.getSubCompound("ExtraAttributes", false) - } - - private fun NBTTagList.asStringSet() = (0..tagCount()).mapTo(hashSetOf()) { getStringTagAt(it) } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/misc/ApiData.kt b/src/main/java/at/hannibal2/skyhanni/misc/ApiData.kt deleted file mode 100644 index b0437e852..000000000 --- a/src/main/java/at/hannibal2/skyhanni/misc/ApiData.kt +++ /dev/null @@ -1,90 +0,0 @@ -package at.hannibal2.skyhanni.misc - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.events.ProfileApiDataLoadedEvent -import at.hannibal2.skyhanni.events.ProfileJoinEvent -import at.hannibal2.skyhanni.utils.APIUtil -import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraft.client.Minecraft -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class ApiData { - - private var currentProfileName = "" - - @SubscribeEvent - fun onStatusBar(event: LorenzChatEvent) { - val message = event.message - if (message.startsWith("§aYour new API key is §r§b")) { - SkyHanniMod.feature.hidden.apiKey = message.substring(26) - LorenzUtils.chat("§b[SkyHanni] A new API Key has been detected and installed") - - if (currentProfileName != "") { - updateApiData() - } - } - } - - @SubscribeEvent - fun onStatusBar(event: ProfileJoinEvent) { - currentProfileName = event.name - updateApiData() - } - - private fun updateApiData() { - val uuid = Minecraft.getMinecraft().thePlayer.uniqueID.toString().replace("-", "") - - val apiKey = SkyHanniMod.feature.hidden.apiKey - - if (apiKey.isEmpty()) { - LorenzUtils.error("SkyHanni has no API Key set. Type /api new to reload.") - return - } - - val url = "https://api.hypixel.net/player?key=$apiKey&uuid=$uuid" - - val jsonObject = APIUtil.getJSONResponse(url) - - if (!jsonObject["success"].asBoolean) { - val cause = jsonObject["cause"].asString - if (cause == "Invalid API key") { - LorenzUtils.error("SkyHanni got an API error: Invalid API key! Type /api new to reload.") - return - } else { - throw RuntimeException("API error for url '$url': $cause") - } - } - - val player = jsonObject["player"].asJsonObject - val stats = player["stats"].asJsonObject - val skyblock = stats["SkyBlock"].asJsonObject - val profiles = skyblock["profiles"].asJsonObject - for (entry in profiles.entrySet()) { - val asJsonObject = entry.value.asJsonObject - val name = asJsonObject["cute_name"].asString - val profileId = asJsonObject["profile_id"].asString - if (currentProfileName == name.lowercase()) { - loadProfile(uuid, profileId) - return - } - } - } - - private fun loadProfile(playerUuid: String, profileId: String) { - val apiKey = SkyHanniMod.feature.hidden.apiKey - val url = "https://api.hypixel.net/skyblock/profile?key=$apiKey&profile=$profileId" - - val jsonObject = APIUtil.getJSONResponse(url) - - val profile = jsonObject["profile"].asJsonObject - val members = profile["members"].asJsonObject - for (entry in members.entrySet()) { - if (entry.key == playerUuid) { - val profileData = entry.value.asJsonObject - ProfileApiDataLoadedEvent(profileData).postAndCatch() - - } - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/misc/ButtonOnPause.kt b/src/main/java/at/hannibal2/skyhanni/misc/ButtonOnPause.kt deleted file mode 100644 index 68ae8a93c..000000000 --- a/src/main/java/at/hannibal2/skyhanni/misc/ButtonOnPause.kt +++ /dev/null @@ -1,51 +0,0 @@ -package at.hannibal2.skyhanni.misc - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.config.gui.config.ConfigEditor -import at.hannibal2.skyhanni.config.gui.core.GuiScreenElementWrapper -import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraft.client.gui.GuiButton -import net.minecraft.client.gui.GuiIngameMenu -import net.minecraftforge.client.event.GuiScreenEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class ButtonOnPause { - private val buttonId = System.nanoTime().toInt() - - @SubscribeEvent - fun onGuiAction(event: GuiScreenEvent.ActionPerformedEvent.Post) { - if (!LorenzUtils.isOnHypixel) return - - if (SkyHanniMod.feature.misc.configButtonOnPause && event.gui is GuiIngameMenu && event.button.id == buttonId) { - SkyHanniMod.screenToOpen = GuiScreenElementWrapper( - ConfigEditor( - SkyHanniMod.feature - ) - ) - } - } - - @SubscribeEvent - fun onGuiInitPost(event: GuiScreenEvent.InitGuiEvent.Post) { - if (!LorenzUtils.isOnHypixel) return - - if (SkyHanniMod.feature.misc.configButtonOnPause && event.gui is GuiIngameMenu) { - val x = event.gui.width - 105 - val x2 = x + 100 - var y = event.gui.height - 22 - var y2 = y + 20 - val sorted = event.buttonList.sortedWith { a, b -> b.yPosition + b.height - a.yPosition + a.height } - for (button in sorted) { - val otherX = button.xPosition - val otherX2 = button.xPosition + button.width - val otherY = button.yPosition - val otherY2 = button.yPosition + button.height - if (otherX2 > x && otherX < x2 && otherY2 > y && otherY < y2) { - y = otherY - 20 - 2 - y2 = y + 20 - } - } - event.buttonList.add(GuiButton(buttonId, x, 0.coerceAtLeast(y), 100, 20, "SkyHanni")) - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/misc/CurrentPetDisplay.kt b/src/main/java/at/hannibal2/skyhanni/misc/CurrentPetDisplay.kt deleted file mode 100644 index 9266dd4f5..000000000 --- a/src/main/java/at/hannibal2/skyhanni/misc/CurrentPetDisplay.kt +++ /dev/null @@ -1,47 +0,0 @@ -package at.hannibal2.skyhanni.misc - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.utils.GuiRender.renderString -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.between -import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex -import net.minecraftforge.client.event.RenderGameOverlayEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class CurrentPetDisplay { - - @SubscribeEvent - fun onChatMessage(event: LorenzChatEvent) { - if (!LorenzUtils.inSkyblock) return - - var blocked = false - - val message = event.message - if (message.matchRegex("§aYou summoned your §r(.*)§r§a!")) { - SkyHanniMod.feature.hidden.currentPet = message.between("your §r", "§r§a") - blocked = true - } - if (message.matchRegex("§cAutopet §eequipped your §7(.*)§e! §a§lVIEW RULE")) { - SkyHanniMod.feature.hidden.currentPet = message.between("] ", "§e!") - blocked = true - } - if (message.matchRegex("§aYou despawned your §r(.*)§r§a!")) { - SkyHanniMod.feature.hidden.currentPet = "" - blocked = true - } - - if (blocked && SkyHanniMod.feature.misc.petDisplay) { - event.blockedReason = "pets" - } - } - - @SubscribeEvent - fun renderOverlay(event: RenderGameOverlayEvent.Post) { - if (!LorenzUtils.inSkyblock) return - - if (!SkyHanniMod.feature.misc.petDisplay) return - - SkyHanniMod.feature.misc.petDisplayPos.renderString(SkyHanniMod.feature.hidden.currentPet) - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/misc/ExpBottleOnGroundHider.kt b/src/main/java/at/hannibal2/skyhanni/misc/ExpBottleOnGroundHider.kt deleted file mode 100644 index 119160c4f..000000000 --- a/src/main/java/at/hannibal2/skyhanni/misc/ExpBottleOnGroundHider.kt +++ /dev/null @@ -1,19 +0,0 @@ -package at.hannibal2.skyhanni.misc - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.CheckRenderEntityEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraft.entity.item.EntityXPOrb -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent - -class ExpBottleOnGroundHider { - @SubscribeEvent - fun onCheckRender(event: CheckRenderEntityEvent<*>) { - if (!LorenzUtils.inSkyblock) return - if (!SkyHanniMod.feature.misc.hideExpBottles) return - - if (event.entity is EntityXPOrb) { - event.isCanceled = true - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/misc/HypixelData.kt b/src/main/java/at/hannibal2/skyhanni/misc/HypixelData.kt deleted file mode 100644 index 177917900..000000000 --- a/src/main/java/at/hannibal2/skyhanni/misc/HypixelData.kt +++ /dev/null @@ -1,106 +0,0 @@ -package at.hannibal2.skyhanni.misc - -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.events.PacketEvent -import at.hannibal2.skyhanni.events.ProfileJoinEvent -import at.hannibal2.skyhanni.utils.LorenzUtils.removeColor -import net.minecraft.client.Minecraft -import net.minecraft.network.play.server.S38PacketPlayerListItem -import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent -import net.minecraftforge.fml.common.network.FMLNetworkEvent - -class HypixelData { - - companion object { - var hypixel = false - var skyblock = false - var dungeon = false - } - - @SubscribeEvent - fun onConnect(event: FMLNetworkEvent.ClientConnectedToServerEvent) { - hypixel = Minecraft.getMinecraft().runCatching { - !event.isLocal && (thePlayer?.clientBrand?.lowercase()?.contains("hypixel") - ?: currentServerData?.serverIP?.lowercase()?.contains("hypixel") ?: false) - }.onFailure { it.printStackTrace() }.getOrDefault(false) - } - - val areaRegex = Regex("§r§b§l(?[\\w]+): §r§7(?[\\w ]+)§r") - - @SubscribeEvent - fun onTabUpdate(event: PacketEvent.ReceiveEvent) { - if (dungeon || !hypixel || event.packet !is S38PacketPlayerListItem || - (event.packet.action != S38PacketPlayerListItem.Action.UPDATE_DISPLAY_NAME && - event.packet.action != S38PacketPlayerListItem.Action.ADD_PLAYER) - ) return - event.packet.entries.forEach { playerData -> - val name = playerData?.displayName?.formattedText ?: playerData?.profile?.name ?: return@forEach - areaRegex.matchEntire(name)?.let { result -> - dungeon = skyblock && result.groups["area"]?.value == "Dungeon" - return@forEach - } - } - } - - @SubscribeEvent - fun onWorldChange(event: WorldEvent.Load) { - skyblock = false - dungeon = false - } - - @SubscribeEvent - fun onDisconnect(event: FMLNetworkEvent.ClientDisconnectionFromServerEvent) { - hypixel = false - skyblock = false - dungeon = false - } - - @SubscribeEvent - fun onStatusBar(event: LorenzChatEvent) { - if (!hypixel) return - - val message = event.message.removeColor().lowercase() - - if (message.startsWith("your profile was changed to:")) { - val stripped = message.replace("your profile was changed to:", "").replace("(co-op)", "").trim() - ProfileJoinEvent(stripped).postAndCatch() - } - if (message.startsWith("you are playing on profile:")) { - val stripped = message.replace("you are playing on profile:", "").replace("(co-op)", "").trim() - ProfileJoinEvent(stripped).postAndCatch() - - } - } - - var timerTick = 0 - - @SubscribeEvent - fun onTick(event: TickEvent.ClientTickEvent) { - if (!hypixel) return - if (event.phase != TickEvent.Phase.START) return - - timerTick++ - - if (timerTick % 5 != 0) return - - val newState = checkScoreboard() - if (newState == skyblock) return - - skyblock = newState - } - - private fun checkScoreboard(): Boolean { - val minecraft = Minecraft.getMinecraft() - val world = minecraft.theWorld ?: return false - - val sidebarObjective = world.scoreboard.getObjectiveInDisplaySlot(1) ?: return false - - val displayName = sidebarObjective.displayName - - return displayName.removeColor().contains("SKYBLOCK") - - } - -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/misc/ScoreboardData.kt b/src/main/java/at/hannibal2/skyhanni/misc/ScoreboardData.kt deleted file mode 100644 index 51bf32e56..000000000 --- a/src/main/java/at/hannibal2/skyhanni/misc/ScoreboardData.kt +++ /dev/null @@ -1,48 +0,0 @@ -package at.hannibal2.skyhanni.misc - -import at.hannibal2.skyhanni.utils.LorenzUtils.removeColor -import net.minecraft.client.Minecraft -import net.minecraft.scoreboard.Score -import net.minecraft.scoreboard.ScorePlayerTeam -import net.minecraftforge.fml.common.eventhandler.EventPriority -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent - -class ScoreboardData { - - companion object { - var sidebarLines: List = emptyList() - var sidebarLinesRaw: List = emptyList() - } - - @SubscribeEvent(priority = EventPriority.HIGHEST) - fun onTick(event: TickEvent.ClientTickEvent) { - if (event.phase != TickEvent.Phase.START) return - - val list = fetchScoreboardLines() - sidebarLines = list.map { cleanSB(it) }.reversed() - sidebarLinesRaw = list.reversed() - } - - private fun cleanSB(scoreboard: String): String { - return scoreboard.removeColor().toCharArray().filter { it.code in 21..126 }.joinToString(separator = "") - } - - fun fetchScoreboardLines(): List { - val scoreboard = Minecraft.getMinecraft().theWorld?.scoreboard ?: return emptyList() - val objective = scoreboard.getObjectiveInDisplaySlot(1) ?: return emptyList() - var scores = scoreboard.getSortedScores(objective) - val list = scores.filter { input: Score? -> - input != null && input.playerName != null && !input.playerName - .startsWith("#") - } - scores = if (list.size > 15) { - list.drop(15) - } else { - list - } - return scores.map { - ScorePlayerTeam.formatPlayerName(scoreboard.getPlayersTeam(it.playerName), it.playerName) - } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/misc/SummoningSoulsName.kt b/src/main/java/at/hannibal2/skyhanni/misc/SummoningSoulsName.kt deleted file mode 100644 index 4cb1a90ae..000000000 --- a/src/main/java/at/hannibal2/skyhanni/misc/SummoningSoulsName.kt +++ /dev/null @@ -1,135 +0,0 @@ -package at.hannibal2.skyhanni.misc - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.damageindicator.hasNameTagWith -import at.hannibal2.skyhanni.test.GriffinJavaUtils -import at.hannibal2.skyhanni.utils.ItemUtils.getSkullTexture -import at.hannibal2.skyhanni.utils.LocationUtils -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzVec -import at.hannibal2.skyhanni.utils.RenderUtils.drawString -import at.hannibal2.skyhanni.utils.getLorenzVec -import net.minecraft.client.Minecraft -import net.minecraft.entity.EntityLiving -import net.minecraft.entity.item.EntityArmorStand -import net.minecraftforge.client.event.RenderWorldLastEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent -import java.util.concurrent.atomic.AtomicReference - -class SummoningSoulsName { - - var tick = 0 - val texture = - "ewogICJ0aW1lc3RhbXAiIDogMTYwMTQ3OTI2NjczMywKICAicHJvZmlsZUlkIiA6ICJmMzA1ZjA5NDI0NTg0ZjU" + - "4YmEyYjY0ZjAyZDcyNDYyYyIsCiAgInByb2ZpbGVOYW1lIiA6ICJqcm9ja2EzMyIsCiAgInNpZ25hdH" + - "VyZVJlcXVpcmVkIiA6IHRydWUsCiAgInRleHR1cmVzIiA6IHsKICAgICJTS0lOIiA6IHsKICAgICAgI" + - "nVybCIgOiAiaHR0cDovL3RleHR1cmVzLm1pbmVjcmFmdC5uZXQvdGV4dHVyZS81YWY0MDM1ZWMwZGMx" + - "NjkxNzc4ZDVlOTU4NDAxNzAyMjdlYjllM2UyOTQzYmVhODUzOTI5Y2U5MjNjNTk4OWFkIgogICAgfQogIH0KfQ" - - val souls = mutableMapOf() - val mobsLastLocation = mutableMapOf() - val mobsName = mutableMapOf() - - @SubscribeEvent - fun onTick(event: TickEvent.ClientTickEvent) { - if (!isEnabled()) return - - tick++ - //TODO use packets instead of this - if (tick % 1 == 0) { - check() - } - } - - private fun check() { - val minecraft = Minecraft.getMinecraft() - val world = minecraft.theWorld - for (entity in world.loadedEntityList) { - if (souls.contains(entity)) continue - - if (entity is EntityArmorStand) { - if (isSoul(entity)) { - val soulLocation = entity.getLorenzVec() - - val map = mutableMapOf() - for ((mob, loc) in mobsLastLocation) { - val distance = loc.distance(soulLocation) - map[mob] = distance - } - - val nearestMob = GriffinJavaUtils.sortByValueAsc(map).firstNotNullOfOrNull { it.key } - if (nearestMob != null) { -// val mobDistance = nearestMob.getLorenzVec().add(0.0, -1.4375, 0.0) -// val distance = mobDistance.distance(soulLocation) -// val diff = mobDistance.add(soulLocation.multiply(-1)) - -// println(" ") -// println("mobDistance: $mobDistance") -// println("soulLocation: $soulLocation") -// println("diff: $diff") -// LorenzUtils.chat("distance: $distance") - val name = mobsName[nearestMob]!! -// LorenzUtils.chat("maybe its $name") - souls[entity] = name - } - - } - } - } - - for (entity in world.loadedEntityList) { - - if (entity is EntityLiving) { - val boo = AtomicReference() - if (entity.hasNameTagWith(2, "§c❤", consumer = { - if (!it.name.contains("§e0")) { - boo.set(it.name) - } - })) { - val name = boo.get() - if (name != null) { - mobsLastLocation[entity] = entity.getLorenzVec() - mobsName[entity] = name - } - } - } - } - - souls.keys.removeIf { it !in world.loadedEntityList } - //TODO fix overhead! -// mobs.keys.removeIf { it !in world.loadedEntityList } - } - - @SubscribeEvent - fun onWorldRender(event: RenderWorldLastEvent) { - if (!isEnabled()) return - - val playerLocation = LocationUtils.playerEyeLocation() - for ((entity, name) in souls) { - val vec = entity.getLorenzVec() - if (LocationUtils.canSee(playerLocation, vec.add(0.0, 2.0, 0.0))) { - event.drawString(vec.add(0.0, 2.5, 0.0), name, true) - } - } - } - - private fun isSoul(entity: EntityArmorStand): Boolean { - for (stack in entity.inventory) { - if (stack != null) { - val skullTexture = stack.getSkullTexture() - if (skullTexture != null) { - if (skullTexture == texture) { - return true - } - } - } - } - - return false - } - - private fun isEnabled(): Boolean { - return LorenzUtils.inSkyblock && SkyHanniMod.feature.misc.summonSoulDisplay - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/misc/nether/ashfang/AshfangFreezeCooldown.kt b/src/main/java/at/hannibal2/skyhanni/misc/nether/ashfang/AshfangFreezeCooldown.kt deleted file mode 100644 index 1a413d0bf..000000000 --- a/src/main/java/at/hannibal2/skyhanni/misc/nether/ashfang/AshfangFreezeCooldown.kt +++ /dev/null @@ -1,43 +0,0 @@ -package at.hannibal2.skyhanni.misc.nether.ashfang - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.LorenzChatEvent -import at.hannibal2.skyhanni.utils.GuiRender.renderString -import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.matchRegex -import net.minecraftforge.client.event.RenderGameOverlayEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import java.text.DecimalFormat - -class AshfangFreezeCooldown { - - var lastHit = 0L - - @SubscribeEvent - fun onChatMessage(event: LorenzChatEvent) { - if (!isEnabled()) return - - val message = event.message - if (message.matchRegex("§cAshfang Follower's Cryogenic Blast hit you for (.*) damage!")) { - lastHit = System.currentTimeMillis() - } - } - - @SubscribeEvent - fun renderOverlay(event: RenderGameOverlayEvent.Post) { - if (!isEnabled()) return - val duration = System.currentTimeMillis() - lastHit - val maxDuration = 3_000 - - val remainingLong = maxDuration - duration - if (remainingLong > 0) { - val remaining = (remainingLong.toFloat() / 1000) - val format = DecimalFormat("0.0").format(remaining + 0.1) - SkyHanniMod.feature.abilities.ashfangFreezeCooldownPos.renderString("§cAshfang Freeze: §a${format}s") - } - } - - private fun isEnabled(): Boolean { - return LorenzUtils.inSkyblock && SkyHanniMod.feature.abilities.ashfangFreezeCooldown - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/misc/nether/ashfang/AshfangNextResetCooldown.kt b/src/main/java/at/hannibal2/skyhanni/misc/nether/ashfang/AshfangNextResetCooldown.kt deleted file mode 100644 index 7f8373448..000000000 --- a/src/main/java/at/hannibal2/skyhanni/misc/nether/ashfang/AshfangNextResetCooldown.kt +++ /dev/null @@ -1,53 +0,0 @@ -package at.hannibal2.skyhanni.misc.nether.ashfang - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.utils.GuiRender.renderString -import at.hannibal2.skyhanni.utils.LorenzUtils -import net.minecraft.client.Minecraft -import net.minecraft.entity.item.EntityArmorStand -import net.minecraftforge.client.event.RenderGameOverlayEvent -import net.minecraftforge.event.world.WorldEvent -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent -import net.minecraftforge.fml.common.gameevent.TickEvent.ClientTickEvent -import java.text.DecimalFormat - -class AshfangNextResetCooldown { - - private var spawnTime = 1L - - @SubscribeEvent - fun renderOverlay(event: ClientTickEvent) { - if (!isEnabled()) return - - if (Minecraft.getMinecraft().theWorld.loadedEntityList.any { - it is EntityArmorStand && it.posY > 145 && - (it.name.contains("§c§9Ashfang Acolyte§r") || it.name.contains("§c§cAshfang Underling§r")) - }) { - spawnTime = System.currentTimeMillis() - } - } - - @SubscribeEvent - fun renderOverlay(event: RenderGameOverlayEvent.Post) { - if (!isEnabled()) return - if (spawnTime == -1L) return - - val remainingTime = spawnTime + 46_100 - System.currentTimeMillis() - if (remainingTime > 0) { - val remaining = (remainingTime.toFloat() / 1000) - val format = DecimalFormat("0.0").format(remaining + 0.1) - SkyHanniMod.feature.abilities.ashfangNextResetCooldownPos.renderString("§cAshfang next reset in: §a${format}s") - } else { - spawnTime = -1 - } - } - - @SubscribeEvent - fun renderOverlay(event: WorldEvent.Load) { - spawnTime = -1 - } - - private fun isEnabled(): Boolean { - return LorenzUtils.inSkyblock && SkyHanniMod.feature.abilities.ashfangNextResetCooldown - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/mixinhooks/GuiContainerHook.kt b/src/main/java/at/hannibal2/skyhanni/mixinhooks/GuiContainerHook.kt deleted file mode 100644 index 6f2c5c03e..000000000 --- a/src/main/java/at/hannibal2/skyhanni/mixinhooks/GuiContainerHook.kt +++ /dev/null @@ -1,61 +0,0 @@ -package at.hannibal2.skyhanni.mixinhooks - -import at.hannibal2.skyhanni.events.GuiContainerEvent -import at.hannibal2.skyhanni.events.GuiContainerEvent.CloseWindowEvent -import at.hannibal2.skyhanni.events.GuiContainerEvent.SlotClickEvent -import net.minecraft.client.gui.inventory.GuiContainer -import net.minecraft.inventory.Slot -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo - -class GuiContainerHook(guiAny: Any) { - - val gui: GuiContainer - - init { - gui = guiAny as GuiContainer - } - - fun closeWindowPressed(ci: CallbackInfo) { - if (CloseWindowEvent(gui, gui.inventorySlots).postAndCatch()) ci.cancel() - } - - fun backgroundDrawn(mouseX: Int, mouseY: Int, partialTicks: Float, ci: CallbackInfo) { - GuiContainerEvent.BackgroundDrawnEvent( - gui, - gui.inventorySlots, - mouseX, - mouseY, - partialTicks - ).postAndCatch() - } - - fun foregroundDrawn(mouseX: Int, mouseY: Int, partialTicks: Float, ci: CallbackInfo) { - GuiContainerEvent.ForegroundDrawnEvent(gui, gui.inventorySlots, mouseX, mouseY, partialTicks).postAndCatch() - } - - fun onDrawSlot(slot: Slot, ci: CallbackInfo) { - if (GuiContainerEvent.DrawSlotEvent.Pre( - gui, - gui.inventorySlots, - slot - ).postAndCatch() - ) ci.cancel() - } - - fun onDrawSlotPost(slot: Slot, ci: CallbackInfo) { - GuiContainerEvent.DrawSlotEvent.Post(gui, gui.inventorySlots, slot).postAndCatch() - } - - fun onMouseClick(slot: Slot?, slotId: Int, clickedButton: Int, clickType: Int, ci: CallbackInfo) { - if ( - SlotClickEvent( - gui, - gui.inventorySlots, - slot, - slotId, - clickedButton, - clickType - ).postAndCatch() - ) ci.cancel() - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/mixinhooks/NetHandlerPlayClientHook.kt b/src/main/java/at/hannibal2/skyhanni/mixinhooks/NetHandlerPlayClientHook.kt deleted file mode 100644 index 57511d618..000000000 --- a/src/main/java/at/hannibal2/skyhanni/mixinhooks/NetHandlerPlayClientHook.kt +++ /dev/null @@ -1,9 +0,0 @@ -package at.hannibal2.skyhanni.mixinhooks - -import at.hannibal2.skyhanni.events.PacketEvent -import net.minecraft.network.Packet -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo - -fun onSendPacket(packet: Packet<*>, ci: CallbackInfo) { - if (PacketEvent.SendEvent(packet).postAndCatch()) ci.cancel() -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/mixinhooks/NetworkManagerHook.kt b/src/main/java/at/hannibal2/skyhanni/mixinhooks/NetworkManagerHook.kt deleted file mode 100644 index 44746cfbf..000000000 --- a/src/main/java/at/hannibal2/skyhanni/mixinhooks/NetworkManagerHook.kt +++ /dev/null @@ -1,10 +0,0 @@ -package at.hannibal2.skyhanni.mixinhooks - -import at.hannibal2.skyhanni.events.PacketEvent -import io.netty.channel.ChannelHandlerContext -import net.minecraft.network.Packet -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo - -fun onReceivePacket(context: ChannelHandlerContext, packet: Packet<*>, ci: CallbackInfo) { - if (PacketEvent.ReceiveEvent(packet).postAndCatch()) ci.cancel() -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/mixinhooks/RenderItemHook.kt b/src/main/java/at/hannibal2/skyhanni/mixinhooks/RenderItemHook.kt deleted file mode 100644 index ae21c622b..000000000 --- a/src/main/java/at/hannibal2/skyhanni/mixinhooks/RenderItemHook.kt +++ /dev/null @@ -1,33 +0,0 @@ -package at.hannibal2.skyhanni.mixinhooks - -import at.hannibal2.skyhanni.events.GuiRenderItemEvent -import at.hannibal2.skyhanni.events.RenderRealOverlayEvent -import net.minecraft.client.gui.FontRenderer -import net.minecraft.item.ItemStack -import net.minecraft.util.ResourceLocation -import org.spongepowered.asm.mixin.injection.callback.CallbackInfo - -val RES_ITEM_GLINT = ResourceLocation("textures/misc/enchanted_item_glint.png") - -var skipGlint = false - -fun renderItemOverlayPost( - fr: FontRenderer, - stack: ItemStack?, - xPosition: Int, - yPosition: Int, - text: String?, - ci: CallbackInfo -) { - GuiRenderItemEvent.RenderOverlayEvent.Post( - fr, - stack, - xPosition, - yPosition, - text - ).postAndCatch() -} - -fun renderItemReturn(stack: ItemStack, x: Int, y: Int, ci: CallbackInfo) { - RenderRealOverlayEvent(stack, x, y).postAndCatch() -} diff --git a/src/main/java/at/hannibal2/skyhanni/mixinhooks/RenderManagerHook.kt b/src/main/java/at/hannibal2/skyhanni/mixinhooks/RenderManagerHook.kt deleted file mode 100644 index a183a0caa..000000000 --- a/src/main/java/at/hannibal2/skyhanni/mixinhooks/RenderManagerHook.kt +++ /dev/null @@ -1,25 +0,0 @@ -package at.hannibal2.skyhanni.mixinhooks - -import at.hannibal2.skyhanni.events.CheckRenderEntityEvent -import net.minecraft.client.renderer.culling.ICamera -import net.minecraft.entity.Entity -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable - -fun shouldRender( - entityIn: Entity, - camera: ICamera, - camX: Double, - camY: Double, - camZ: Double, - cir: CallbackInfoReturnable -) { - if ( - CheckRenderEntityEvent( - entityIn, - camera, - camX, - camY, - camZ - ).postAndCatch() - ) cir.returnValue = false -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/mixinhooks/render/BlockRendererDispatcherHook.kt b/src/main/java/at/hannibal2/skyhanni/mixinhooks/render/BlockRendererDispatcherHook.kt deleted file mode 100644 index d04e248ea..000000000 --- a/src/main/java/at/hannibal2/skyhanni/mixinhooks/render/BlockRendererDispatcherHook.kt +++ /dev/null @@ -1,25 +0,0 @@ -//package at.hannibal2.skyhanni.mixinhooks.render -// -//import at.hannibal2.skyhanni.events.RenderBlockInWorldEvent -//import net.minecraft.block.state.IBlockState -//import net.minecraft.client.renderer.BlockRendererDispatcher -//import net.minecraft.client.resources.model.IBakedModel -//import net.minecraft.util.BlockPos -//import net.minecraft.world.IBlockAccess -//import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable -// -//fun modifyGetModelFromBlockState( -// blockRendererDispatcher: Any, -// state: IBlockState?, -// worldIn: IBlockAccess, -// pos: BlockPos?, -// cir: CallbackInfoReturnable -//) { -// (blockRendererDispatcher as BlockRendererDispatcher).apply { -// val event = RenderBlockInWorldEvent(state, worldIn, pos) -// event.postAndCatch() -// if (event.state !== state) { -// cir.returnValue = blockModelShapes.getModelForState(event.state) -// } -// } -//} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiContainerHook.kt b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiContainerHook.kt new file mode 100644 index 000000000..d4287f074 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/GuiContainerHook.kt @@ -0,0 +1,61 @@ +package at.hannibal2.skyhanni.mixins.hooks + +import at.hannibal2.skyhanni.events.GuiContainerEvent +import at.hannibal2.skyhanni.events.GuiContainerEvent.CloseWindowEvent +import at.hannibal2.skyhanni.events.GuiContainerEvent.SlotClickEvent +import net.minecraft.client.gui.inventory.GuiContainer +import net.minecraft.inventory.Slot +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo + +class GuiContainerHook(guiAny: Any) { + + val gui: GuiContainer + + init { + gui = guiAny as GuiContainer + } + + fun closeWindowPressed(ci: CallbackInfo) { + if (CloseWindowEvent(gui, gui.inventorySlots).postAndCatch()) ci.cancel() + } + + fun backgroundDrawn(mouseX: Int, mouseY: Int, partialTicks: Float, ci: CallbackInfo) { + GuiContainerEvent.BackgroundDrawnEvent( + gui, + gui.inventorySlots, + mouseX, + mouseY, + partialTicks + ).postAndCatch() + } + + fun foregroundDrawn(mouseX: Int, mouseY: Int, partialTicks: Float, ci: CallbackInfo) { + GuiContainerEvent.ForegroundDrawnEvent(gui, gui.inventorySlots, mouseX, mouseY, partialTicks).postAndCatch() + } + + fun onDrawSlot(slot: Slot, ci: CallbackInfo) { + if (GuiContainerEvent.DrawSlotEvent.Pre( + gui, + gui.inventorySlots, + slot + ).postAndCatch() + ) ci.cancel() + } + + fun onDrawSlotPost(slot: Slot, ci: CallbackInfo) { + GuiContainerEvent.DrawSlotEvent.Post(gui, gui.inventorySlots, slot).postAndCatch() + } + + fun onMouseClick(slot: Slot?, slotId: Int, clickedButton: Int, clickType: Int, ci: CallbackInfo) { + if ( + SlotClickEvent( + gui, + gui.inventorySlots, + slot, + slotId, + clickedButton, + clickType + ).postAndCatch() + ) ci.cancel() + } +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetHandlerPlayClientHook.kt b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetHandlerPlayClientHook.kt new file mode 100644 index 000000000..b18d80613 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetHandlerPlayClientHook.kt @@ -0,0 +1,9 @@ +package at.hannibal2.skyhanni.mixins.hooks + +import at.hannibal2.skyhanni.events.PacketEvent +import net.minecraft.network.Packet +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo + +fun onSendPacket(packet: Packet<*>, ci: CallbackInfo) { + if (PacketEvent.SendEvent(packet).postAndCatch()) ci.cancel() +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetworkManagerHook.kt b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetworkManagerHook.kt new file mode 100644 index 000000000..b9265587a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/NetworkManagerHook.kt @@ -0,0 +1,10 @@ +package at.hannibal2.skyhanni.mixins.hooks + +import at.hannibal2.skyhanni.events.PacketEvent +import io.netty.channel.ChannelHandlerContext +import net.minecraft.network.Packet +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo + +fun onReceivePacket(context: ChannelHandlerContext, packet: Packet<*>, ci: CallbackInfo) { + if (PacketEvent.ReceiveEvent(packet).postAndCatch()) ci.cancel() +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/RenderItemHook.kt b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/RenderItemHook.kt new file mode 100644 index 000000000..48d98fb5d --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/RenderItemHook.kt @@ -0,0 +1,33 @@ +package at.hannibal2.skyhanni.mixins.hooks + +import at.hannibal2.skyhanni.events.GuiRenderItemEvent +import at.hannibal2.skyhanni.events.RenderRealOverlayEvent +import net.minecraft.client.gui.FontRenderer +import net.minecraft.item.ItemStack +import net.minecraft.util.ResourceLocation +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo + +val RES_ITEM_GLINT = ResourceLocation("textures/misc/enchanted_item_glint.png") + +var skipGlint = false + +fun renderItemOverlayPost( + fr: FontRenderer, + stack: ItemStack?, + xPosition: Int, + yPosition: Int, + text: String?, + ci: CallbackInfo +) { + GuiRenderItemEvent.RenderOverlayEvent.Post( + fr, + stack, + xPosition, + yPosition, + text + ).postAndCatch() +} + +fun renderItemReturn(stack: ItemStack, x: Int, y: Int, ci: CallbackInfo) { + RenderRealOverlayEvent(stack, x, y).postAndCatch() +} diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/RenderManagerHook.kt b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/RenderManagerHook.kt new file mode 100644 index 000000000..3e3283662 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/RenderManagerHook.kt @@ -0,0 +1,25 @@ +package at.hannibal2.skyhanni.mixins.hooks + +import at.hannibal2.skyhanni.events.CheckRenderEntityEvent +import net.minecraft.client.renderer.culling.ICamera +import net.minecraft.entity.Entity +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable + +fun shouldRender( + entityIn: Entity, + camera: ICamera, + camX: Double, + camY: Double, + camZ: Double, + cir: CallbackInfoReturnable +) { + if ( + CheckRenderEntityEvent( + entityIn, + camera, + camX, + camY, + camZ + ).postAndCatch() + ) cir.returnValue = false +} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/hooks/render/BlockRendererDispatcherHook.kt b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/render/BlockRendererDispatcherHook.kt new file mode 100644 index 000000000..d04e248ea --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/mixins/hooks/render/BlockRendererDispatcherHook.kt @@ -0,0 +1,25 @@ +//package at.hannibal2.skyhanni.mixinhooks.render +// +//import at.hannibal2.skyhanni.events.RenderBlockInWorldEvent +//import net.minecraft.block.state.IBlockState +//import net.minecraft.client.renderer.BlockRendererDispatcher +//import net.minecraft.client.resources.model.IBakedModel +//import net.minecraft.util.BlockPos +//import net.minecraft.world.IBlockAccess +//import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable +// +//fun modifyGetModelFromBlockState( +// blockRendererDispatcher: Any, +// state: IBlockState?, +// worldIn: IBlockAccess, +// pos: BlockPos?, +// cir: CallbackInfoReturnable +//) { +// (blockRendererDispatcher as BlockRendererDispatcher).apply { +// val event = RenderBlockInWorldEvent(state, worldIn, pos) +// event.postAndCatch() +// if (event.state !== state) { +// cir.returnValue = blockModelShapes.getModelForState(event.state) +// } +// } +//} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinNetHandlerPlayClient.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinNetHandlerPlayClient.java index 0d48fae00..bd4107369 100644 --- a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinNetHandlerPlayClient.java +++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinNetHandlerPlayClient.java @@ -1,6 +1,6 @@ package at.hannibal2.skyhanni.mixins.transformers; -import at.hannibal2.skyhanni.mixinhooks.NetHandlerPlayClientHookKt; +import at.hannibal2.skyhanni.mixins.hooks.NetHandlerPlayClientHookKt; import net.minecraft.client.multiplayer.WorldClient; import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.network.Packet; diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinNetworkManager.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinNetworkManager.java index d67243a8c..459da17a1 100644 --- a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinNetworkManager.java +++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinNetworkManager.java @@ -1,6 +1,6 @@ package at.hannibal2.skyhanni.mixins.transformers; -import at.hannibal2.skyhanni.mixinhooks.NetworkManagerHookKt; +import at.hannibal2.skyhanni.mixins.hooks.NetworkManagerHookKt; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.SimpleChannelInboundHandler; import net.minecraft.network.NetworkManager; diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinRenderItem.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinRenderItem.java index 9e41c5ba9..ebd3161ce 100644 --- a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinRenderItem.java +++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinRenderItem.java @@ -1,6 +1,6 @@ package at.hannibal2.skyhanni.mixins.transformers; -import at.hannibal2.skyhanni.mixinhooks.RenderItemHookKt; +import at.hannibal2.skyhanni.mixins.hooks.RenderItemHookKt; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.renderer.entity.RenderItem; import net.minecraft.item.ItemStack; diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinRenderManager.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinRenderManager.java index 122c7732e..e36b87195 100644 --- a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinRenderManager.java +++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/MixinRenderManager.java @@ -1,6 +1,6 @@ package at.hannibal2.skyhanni.mixins.transformers; -import at.hannibal2.skyhanni.mixinhooks.RenderManagerHookKt; +import at.hannibal2.skyhanni.mixins.hooks.RenderManagerHookKt; import net.minecraft.client.renderer.culling.ICamera; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.entity.Entity; diff --git a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/gui/MixinGuiContainer.java b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/gui/MixinGuiContainer.java index 57add8571..3331c393f 100644 --- a/src/main/java/at/hannibal2/skyhanni/mixins/transformers/gui/MixinGuiContainer.java +++ b/src/main/java/at/hannibal2/skyhanni/mixins/transformers/gui/MixinGuiContainer.java @@ -1,6 +1,6 @@ package at.hannibal2.skyhanni.mixins.transformers.gui; -import at.hannibal2.skyhanni.mixinhooks.GuiContainerHook; +import at.hannibal2.skyhanni.mixins.hooks.GuiContainerHook; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.inventory.GuiContainer; import net.minecraft.inventory.Slot; diff --git a/src/main/java/at/hannibal2/skyhanni/repo/RepoManager.kt b/src/main/java/at/hannibal2/skyhanni/repo/RepoManager.kt deleted file mode 100644 index eea0f83bd..000000000 --- a/src/main/java/at/hannibal2/skyhanni/repo/RepoManager.kt +++ /dev/null @@ -1,172 +0,0 @@ -package at.hannibal2.skyhanni.repo - -import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.events.RepositoryReloadEvent -import at.hannibal2.skyhanni.utils.LorenzUtils -import com.google.gson.Gson -import com.google.gson.GsonBuilder -import com.google.gson.JsonObject -import net.minecraft.client.Minecraft -import org.apache.commons.io.FileUtils -import java.io.* -import java.net.URL -import java.nio.charset.StandardCharsets -import java.util.concurrent.CompletableFuture -import java.util.concurrent.atomic.AtomicBoolean - -class RepoManager(private val configLocation: File) { - val gson: Gson = GsonBuilder().setPrettyPrinting().create() - private var latestRepoCommit: String? = null - private val repoLocation: File = File(configLocation, "repo") - - fun loadRepoInformation() { - atomicShouldManuallyReload.set(true) - if (SkyHanniMod.feature.apiData.repoAutoUpdate) { - fetchRepository().thenRun(this::reloadRepository) - } else { - reloadRepository() - } - } - - private val atomicShouldManuallyReload = AtomicBoolean(false)//TODO FIX - - fun updateRepo() { - atomicShouldManuallyReload.set(true) - fetchRepository(true).thenRun { this.reloadRepository("Repo updated successful :)") } - } - - fun reloadLocalRepo() { - atomicShouldManuallyReload.set(true) - reloadRepository("Repo loaded from local files successful :)") - } - - private fun fetchRepository(command: Boolean = false): CompletableFuture { - return CompletableFuture.supplyAsync { - try { - val currentCommitJSON: JsonObject? = getJsonFromFile(File(configLocation, "currentCommit.json")) - latestRepoCommit = null - try { - InputStreamReader(URL(getCommitApiUrl()).openStream()) - .use { inReader -> - val commits: JsonObject = gson.fromJson(inReader, JsonObject::class.java) - latestRepoCommit = commits["sha"].asString - } - } catch (e: Exception) { - e.printStackTrace() - } - if (latestRepoCommit == null || latestRepoCommit!!.isEmpty()) return@supplyAsync false - if (File(configLocation, "repo").exists()) { - if (currentCommitJSON != null && currentCommitJSON["sha"].asString == latestRepoCommit) { - if (command) { - LorenzUtils.chat("§e[SkyHanni] §7The repo is already up to date!") - atomicShouldManuallyReload.set(false) - } - return@supplyAsync false - } - } - RepoUtils.recursiveDelete(repoLocation) - repoLocation.mkdirs() - val itemsZip = File(repoLocation, "sh-repo-main.zip") - try { - itemsZip.createNewFile() - } catch (e: IOException) { - return@supplyAsync false - } - val url = URL(getDownloadUrl(latestRepoCommit)) - val urlConnection = url.openConnection() - urlConnection.connectTimeout = 15000 - urlConnection.readTimeout = 30000 - try { - urlConnection.getInputStream().use { `is` -> - FileUtils.copyInputStreamToFile( - `is`, - itemsZip - ) - } - } catch (e: IOException) { - e.printStackTrace() - System.err.println("Failed to download SkyHanni Repo! Please report this issue to the mod creator") - if (command) { - LorenzUtils.error("An error occurred while trying to reload the repo! See logs for more info.") - } - return@supplyAsync false - } - RepoUtils.unzipIgnoreFirstFolder( - itemsZip.absolutePath, - repoLocation.absolutePath - ) - if (currentCommitJSON == null || currentCommitJSON["sha"].asString != latestRepoCommit) { - val newCurrentCommitJSON = JsonObject() - newCurrentCommitJSON.addProperty("sha", latestRepoCommit) - try { - writeJson(newCurrentCommitJSON, File(configLocation, "currentCommit.json")) - } catch (ignored: IOException) { - } - } - } catch (e: Exception) { - e.printStackTrace() - } - true - } - } - - private fun reloadRepository(answerMessage: String = ""): CompletableFuture { - val comp = CompletableFuture() - if (!atomicShouldManuallyReload.get()) return comp - Minecraft.getMinecraft().addScheduledTask { - try { - RepositoryReloadEvent(repoLocation, gson).postAndCatch() - comp.complete(null) - if (answerMessage.isNotEmpty()) { - LorenzUtils.chat("§e[SkyHanni] §a$answerMessage") - } - } catch (e: java.lang.Exception) { - comp.completeExceptionally(e) - LorenzUtils.error("An error occurred while trying to reload the repo! See logs for more info.") - } - } - return comp - } - - /** - * Parses a file in to a JsonObject. - */ - private fun getJsonFromFile(file: File?): JsonObject? { - try { - BufferedReader( - InputStreamReader( - FileInputStream(file), - StandardCharsets.UTF_8 - ) - ).use { reader -> - return gson.fromJson(reader, JsonObject::class.java) - } - } catch (e: java.lang.Exception) { - return null - } - } - - private fun getCommitApiUrl(): String { - val repoUser = "hannibal00212" - val repoName = "SkyHanni-REPO" - val repoBranch = "main" - return String.format("https://api.github.com/repos/%s/%s/commits/%s", repoUser, repoName, repoBranch) - } - - private fun getDownloadUrl(commitId: String?): String { - val repoUser = "hannibal00212" - val repoName = "SkyHanni-REPO" - return String.format("https://github.com/%s/%s/archive/%s.zip", repoUser, repoName, commitId) - } - - @Throws(IOException::class) - fun writeJson(json: JsonObject?, file: File) { - file.createNewFile() - BufferedWriter( - OutputStreamWriter( - FileOutputStream(file), - StandardCharsets.UTF_8 - ) - ).use { writer -> writer.write(gson.toJson(json)) } - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/repo/RepoUtils.kt b/src/main/java/at/hannibal2/skyhanni/repo/RepoUtils.kt deleted file mode 100644 index efe656e1c..000000000 --- a/src/main/java/at/hannibal2/skyhanni/repo/RepoUtils.kt +++ /dev/null @@ -1,102 +0,0 @@ -package at.hannibal2.skyhanni.repo - -import com.google.gson.Gson -import com.google.gson.JsonObject -import java.io.* -import java.nio.charset.StandardCharsets -import java.nio.file.Files -import java.util.zip.ZipInputStream - -object RepoUtils { - - fun recursiveDelete(file: File) { - if (file.isDirectory && !Files.isSymbolicLink(file.toPath())) { - for (child in file.listFiles()) { - recursiveDelete(child) - } - } - file.delete() - } - - /** - * Modified from https://www.journaldev.com/960/java-unzip-file-example - */ - fun unzipIgnoreFirstFolder(zipFilePath: String, destDir: String) { - val dir = File(destDir) - // create output directory if it doesn't exist - if (!dir.exists()) dir.mkdirs() - val fis: FileInputStream - //buffer for read and write data to file - val buffer = ByteArray(1024) - try { - fis = FileInputStream(zipFilePath) - val zis = ZipInputStream(fis) - var ze = zis.nextEntry - while (ze != null) { - if (!ze.isDirectory) { - var fileName = ze.name - fileName = fileName.substring(fileName.split("/").toTypedArray()[0].length + 1) - val newFile = File(destDir + File.separator + fileName) - //create directories for sub directories in zip - File(newFile.parent).mkdirs() - if (!isInTree(dir, newFile)) { - throw RuntimeException( - "SkyHanni detected an invalid zip file. This is a potential security risk, please report this on the SkyHanni discord." - ) - } - val fos = FileOutputStream(newFile) - var len: Int - while (zis.read(buffer).also { len = it } > 0) { - fos.write(buffer, 0, len) - } - fos.close() - } - //close this ZipEntry - zis.closeEntry() - ze = zis.nextEntry - } - //close last ZipEntry - zis.closeEntry() - zis.close() - fis.close() - } catch (e: IOException) { - e.printStackTrace() - } - } - - @Throws(IOException::class) - private fun isInTree(rootDirectory: File, file: File): Boolean { - var rootDirectory = rootDirectory - var file: File? = file - file = file!!.canonicalFile - rootDirectory = rootDirectory.canonicalFile - while (file != null) { - if (file == rootDirectory) return true - file = file.parentFile - } - return false - } - - fun getConstant(repoLocation: File, constant: String, gson: Gson): JsonObject? { - return getConstant(repoLocation, constant, gson, JsonObject::class.java) - } - - private fun getConstant(repo: File, constant: String, gson: Gson, clazz: Class?): T? { - if (repo.exists()) { - val jsonFile = File(repo, "constants/$constant.json") - try { - BufferedReader( - InputStreamReader( - FileInputStream(jsonFile), - StandardCharsets.UTF_8 - ) - ).use { reader -> - return gson.fromJson(reader, clazz) - } - } catch (e: Exception) { - return null - } - } - return null - } -} \ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt index c84660caf..c4bc912ee 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzUtils.kt @@ -1,6 +1,6 @@ package at.hannibal2.skyhanni.utils -import at.hannibal2.skyhanni.misc.HypixelData +import at.hannibal2.skyhanni.data.HypixelData import net.minecraft.client.Minecraft import net.minecraft.entity.EntityLivingBase import net.minecraft.entity.SharedMonsterAttributes -- cgit