From ef58a94bf31868c4b53218474f0be04c1cd93d97 Mon Sep 17 00:00:00 2001 From: Lorenz Date: Wed, 17 Aug 2022 03:05:34 +0200 Subject: moving packets around --- .../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 ++ 41 files changed, 4426 insertions(+) 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 (limited to 'src/main/java/at/hannibal2/skyhanni/features') 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, +