diff options
21 files changed, 370 insertions, 83 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 0628286b1..4022db3b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,17 @@ # SkyHanni - Change Log +## Version 0.7.1 + +### Misc +- Added hiding the flame particles when using the Fire Veil Wand ability + +### Fixes +- Fixed enchanted books in bazaar + + ## Version 0.7 - Dungeon and Colored Highlight -## New Dungeon Features +### New Dungeon Features - Added highlight deathmites in dungeon in red color - Added hide Superboom TNT laying around in dungeon - Added hide Blessings laying around in dungeon @@ -22,7 +31,7 @@ - Added highlight corrupted mobs in purple color - Added command /shmarkplayer (marking a player with yellow color) - Added highlight slayer miniboss in blue color -- Added option to hide the death messages of other players, except for players who are close to the player, inside dungeon or doing a Kuudra fight. +- Added option to hide the death messages of other players, except for players who are close to the player, inside dungeon or during a Kuudra fight. - Added highlight the enderman slayer Yang Glyph (Beacon) in red color (supports beacon in hand and beacon flying) ### Fixes diff --git a/FEATURES.md b/FEATURES.md index 32d9f7acf..d813239f4 100644 --- a/FEATURES.md +++ b/FEATURES.md @@ -18,7 +18,7 @@ + Dungeon Boss Message hider (includes The Watcher as well) - Option to hide the Skyblock Level from the chat messages, - Option to change the way the Skyblock Level gets displayed in the chat (only working when skyblock level and fancy player message format are enabled) -- Option to hide the death messages of other players, except for players who are close to the player, inside dungeon or doing a Kuudra fight. +- Option to hide the death messages of other players, except for players who are close to the player, inside dungeon or during a Kuudra fight. ## Dungeon - Clicked Blocks (Showing the block behind walls AFTER clicked on a chest, wither essence or a lever) @@ -47,14 +47,16 @@ - Added compact star counter on all items (not only on items with dungeon stars and master stars but also on crimson armors, cloaks and fishing rods) - RNG meter features (in the catacombs RNG meter inventory show the dungeon floor number and highlight floors without a drop selected and highlighting the selected drop in the RNG meter inventory for slayer or catacombs) -## Item Cooldown +## Item Abilities - Show the cooldown of items in the inventory - Option to change the item background according to the cooldown +- Hiding the flame particles when using the Fire Veil Wand ability. ## Summoning Mobs +- Summoning Soul Display (Show the name of dropped soul laying on the ground, not working in dungeon when Skytils' "Hide Non-Starred Mobs Nametags" is enabled) - Option to hide the nametag of your spawned summoning mobs - Option to mark the own summoning mobs in green -- Summoning mob display (Show the health of your spawned summoning mobs listed in an extra GUI element and hiding the corresponding spawning/despawning chat messages) +- Summoning Mob Display (Show the health of your spawned summoning mobs listed in an extra GUI element and hiding the corresponding spawning/despawning chat messages) ## Ashfang @@ -99,7 +101,6 @@ - Allow to copy, paste, and mark selected text in signs (not visual, but it's working still) - Pet Display (showing the currently selected pet as GUI element, without any fancy XP or level or percentage, but with auto-pet support) - Hiding exp Bottles lying on the ground -- Summon Soul Display (show the name of a dropped soul, not working in dungeon when Skytils' "Hide Non-Starred Mobs Nametags" is enabled) - Fixing Skytils custom Damage Splash - Gui element showing the real time - Highlight the voidling extremist in pink color diff --git a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java index 353a00614..51dcd490a 100644 --- a/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java +++ b/src/main/java/at/hannibal2/skyhanni/SkyHanniMod.java @@ -60,7 +60,8 @@ public class SkyHanniMod { registerEvent(new SeaCreatureManager()); registerEvent(new ItemRenderBackground()); registerEvent(new EntityData()); - registerEvent(new EntityMovementHelper()); + registerEvent(new EntityMovementData()); + registerEvent(new ItemClickData()); registerEvent(new BazaarOrderHelper()); registerEvent(new ChatFilter()); @@ -107,6 +108,7 @@ public class SkyHanniMod { registerEvent(new DungeonHideItems()); registerEvent(new DungeonCopilot()); registerEvent(new EndermanSlayerBeacon()); + registerEvent(new FireVeilWandParticles()); Commands.init(); diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Abilities.java b/src/main/java/at/hannibal2/skyhanni/config/features/Abilities.java index b9a69ed8c..4e93679d4 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Abilities.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Abilities.java @@ -17,6 +17,12 @@ public class Abilities { public boolean itemAbilityCooldownBackground = false; @Expose + @ConfigOption(name = "Summoning Soul Display", desc = "Show the name of dropped summoning souls laying on the ground. " + + "§cNot working in Dungeon if Skytils' 'Hide Non-Starred Mobs Nametags' feature is enabled!") + @ConfigEditorBoolean + public boolean summoningSoulDisplay = false; + + @Expose @ConfigOption(name = "Summoning Mob", desc = "") @ConfigEditorAccordion(id = 0) public boolean summoningMob = false; @@ -44,4 +50,9 @@ public class Abilities { @ConfigEditorBoolean @ConfigAccordionId(id = 0) public boolean summoningMobColored = false; + + @Expose + @ConfigOption(name = "Fire Veil Particles", desc = "Hiding the flame particles when using the Fire Veil Wand ability.") + @ConfigEditorBoolean + public boolean fireVeilWandHider = false; } diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Chat.java b/src/main/java/at/hannibal2/skyhanni/config/features/Chat.java index 3fe253cc0..f674680bc 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Chat.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Chat.java @@ -84,7 +84,13 @@ public class Chat { @Expose @ConfigOption(name = "Hide Far Deaths", desc = "Hide the death messages of other players, " + - "except for players who are close to the player, inside dungeon or doing a Kuudra fight.") + "except for players who are close to the player, inside dungeon or during a Kuudra fight.") @ConfigEditorBoolean public boolean hideFarDeathMessages = false; + + @Expose + @ConfigOption(name = "Hide Far Deaths 2", desc = "Hide the death messages of other players, " + + "except for players who are close to the player, inside dungeon or during a Kuudra fight.") + @ConfigEditorBoolean + public boolean hideFarDeathMessages2 = false; } diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Inventory.java b/src/main/java/at/hannibal2/skyhanni/config/features/Inventory.java index 8f8d6e5e3..75b0831ab 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Inventory.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Inventory.java @@ -82,7 +82,7 @@ public class Inventory { public boolean rngMeterNoDrop = false; @Expose - @ConfigOption(name = "Selected Drop", desc = "Highlight the selected drop in the catacombs oder slayer rng meter inventory") + @ConfigOption(name = "Selected Drop", desc = "Highlight the selected drop in the catacombs or slayer rng meter inventory") @ConfigEditorBoolean @ConfigAccordionId(id = 1) public boolean rngMeterSelectedDrop = false; diff --git a/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java b/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java index d8ad7886e..4c58a5118 100644 --- a/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java +++ b/src/main/java/at/hannibal2/skyhanni/config/features/Misc.java @@ -24,12 +24,6 @@ public class Misc { public boolean hideExpBottles = false; @Expose - @ConfigOption(name = "Summon Soul Display", desc = "Shows the name above summoning souls that ready to pick up. " + - "§cNot working in Dungeon if Skytils' 'Hide Non-Starred Mobs Nametags' feature is enabled!") - @ConfigEditorBoolean - public boolean summonSoulDisplay = false; - - @Expose @ConfigOption(name = "Skytils Damage Splash", desc = "Fixing the custom damage splash feature from skytils.") @ConfigEditorBoolean public boolean fixSkytilsDamageSplash = true; diff --git a/src/main/java/at/hannibal2/skyhanni/data/EntityMovementHelper.kt b/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt index 908aae388..1e07a6eaa 100644 --- a/src/main/java/at/hannibal2/skyhanni/data/EntityMovementHelper.kt +++ b/src/main/java/at/hannibal2/skyhanni/data/EntityMovementData.kt @@ -9,7 +9,7 @@ import net.minecraftforge.event.world.WorldEvent import net.minecraftforge.fml.common.eventhandler.SubscribeEvent import net.minecraftforge.fml.common.gameevent.TickEvent -class EntityMovementHelper { +class EntityMovementData { companion object { private val entityLocation = mutableMapOf<Entity, LorenzVec>() diff --git a/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt b/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt new file mode 100644 index 000000000..e359c619e --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/data/ItemClickData.kt @@ -0,0 +1,32 @@ +package at.hannibal2.skyhanni.data + +import at.hannibal2.skyhanni.events.ItemClickInHandEvent +import net.minecraft.client.Minecraft +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import net.minecraftforge.fml.common.gameevent.InputEvent +import org.lwjgl.input.Mouse + +class ItemClickData { + + @SubscribeEvent + fun onClick(event: InputEvent.MouseInputEvent) { + if (!Mouse.getEventButtonState()) return + + val clickType = when (Mouse.getEventButton()) { + 0 -> { + ItemClickInHandEvent.ClickType.LEFT_CLICK + } + + 1 -> { + ItemClickInHandEvent.ClickType.RIGHT_CLICK + } + + else -> { + return + } + } + + val itemStack = Minecraft.getMinecraft().thePlayer.heldItem + ItemClickInHandEvent(clickType, itemStack).postAndCatch() + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/events/ItemClickInHandEvent.kt b/src/main/java/at/hannibal2/skyhanni/events/ItemClickInHandEvent.kt new file mode 100644 index 000000000..e1271b0a3 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/events/ItemClickInHandEvent.kt @@ -0,0 +1,10 @@ +package at.hannibal2.skyhanni.events + +import net.minecraft.item.ItemStack + +class ItemClickInHandEvent(val clickType: ClickType, val itemInHand: ItemStack?): LorenzEvent() { + + enum class ClickType { + LEFT_CLICK, RIGHT_CLICK + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/FireVeilWandParticles.kt b/src/main/java/at/hannibal2/skyhanni/features/FireVeilWandParticles.kt new file mode 100644 index 000000000..1205c202b --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/FireVeilWandParticles.kt @@ -0,0 +1,50 @@ +package at.hannibal2.skyhanni.features + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.events.ItemClickInHandEvent +import at.hannibal2.skyhanni.events.PacketEvent +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName +import at.hannibal2.skyhanni.utils.LorenzUtils +import net.minecraft.network.play.server.S2APacketParticles +import net.minecraft.util.EnumParticleTypes +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +class FireVeilWandParticles { + + var lastClick = 0L + + @SubscribeEvent + fun onChatPacket(event: PacketEvent.ReceiveEvent) { + if (!isEnabled()) return + + val packet = event.packet + if (packet !is S2APacketParticles) return + + if (System.currentTimeMillis() > lastClick + 5_500) return + + if (packet.particleType == EnumParticleTypes.FLAME && packet.particleCount == 1 && packet.particleSpeed == 0f && + packet.xOffset == 0f && + packet.yOffset == 0f && + packet.zOffset == 0f + ) { + event.isCanceled = true + } + } + + @SubscribeEvent + fun onItemClick(event: ItemClickInHandEvent) { + if (!isEnabled()) return + if (event.clickType != ItemClickInHandEvent.ClickType.RIGHT_CLICK) return + + val itemInHand = event.itemInHand ?: return + + val internalName = itemInHand.getInternalName() + if (internalName == "FIRE_VEIL_WAND") { + lastClick = System.currentTimeMillis() + } + } + + private fun isEnabled(): Boolean { + return LorenzUtils.inSkyblock && SkyHanniMod.feature.abilities.fireVeilWandHider + } +}
\ No newline at end of file diff --git a/src/main/java/at/hannibal2/skyhanni/features/SummoningMobManager.kt b/src/main/java/at/hannibal2/skyhanni/features/SummoningMobManager.kt index 36dbab9ed..03d9382d1 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/SummoningMobManager.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/SummoningMobManager.kt @@ -36,6 +36,9 @@ class SummoningMobManager { //§a§ohannibal2's Tank Zombie§r §a160k§c❤ private val healthPattern = Pattern.compile("§a§o(.+)'s (.+)§r §[ae]([\\dkm]+)§c❤") + //§cThe Seraph recalled your 3 summoned allies! + private val seraphRecallPattern = Pattern.compile("§cThe Seraph recalled your (\\d) summoned allies!") + @SubscribeEvent fun onChatMessage(event: LorenzChatEvent) { if (!LorenzUtils.isOnHypixel) return @@ -57,6 +60,12 @@ class SummoningMobManager { event.blockedReason = "summoning_soul" } } + if (message == "§cThe Seraph recalled your summoned ally!" || seraphRecallPattern.matcher(message).matches()) { + despawned() + if (SkyHanniMod.feature.abilities.summoningMobDisplay) { + event.blockedReason = "summoning_soul" + } + } } var tick = 0 diff --git a/src/main/java/at/hannibal2/skyhanni/features/SummoningSoulsName.kt b/src/main/java/at/hannibal2/skyhanni/features/SummoningSoulsName.kt index ec813395a..59784f027 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/SummoningSoulsName.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/SummoningSoulsName.kt @@ -127,6 +127,6 @@ class SummoningSoulsName { } private fun isEnabled(): Boolean { - return LorenzUtils.inSkyblock && SkyHanniMod.feature.misc.summonSoulDisplay + return LorenzUtils.inSkyblock && SkyHanniMod.feature.abilities.summoningSoulDisplay } }
\ 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 index 5ae100ac2..c2c8bcb18 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/bazaar/BazaarApi.kt @@ -1,7 +1,9 @@ package at.hannibal2.skyhanni.features.bazaar +import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.LorenzUtils import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import net.minecraft.item.ItemStack class BazaarApi { @@ -44,9 +46,10 @@ class BazaarApi { return null } - fun isBazaarItem(name: String): Boolean { - val bazaarName = getCleanBazaarName(name) - return bazaarMap.containsKey(bazaarName) + fun isBazaarItem(stack: ItemStack): Boolean { + val internalName = stack.getInternalName() + return bazaarMap.any { it.value.apiName == internalName } + } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt index 412114c58..3d9835910 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/chat/ChatFilter.kt @@ -66,13 +66,13 @@ class ChatFilter { message.matchRegex("§aFriend > §r(.*) §r§e(joined|left).") -> { true } + else -> false } - } private fun uselessNotification(message: String): Boolean { - if (message.matchRegex("§aYou tipped (\\d) (player|players)!")) return true + if (message.matchRegex("§aYou tipped (\\d+) (player|players)!")) return true return when (message) { "§eYour previous §r§6Plasmaflux Power Orb §r§ewas removed!" -> true @@ -225,7 +225,9 @@ class ChatFilter { //Bank "§8Depositing coins...", - "§8Withdrawing coins..." -> true + "§8Withdrawing coins...", + -> true + else -> false } @@ -296,7 +298,9 @@ class ChatFilter { "", "§f", - "§c" -> true + "§c", + -> true + else -> false } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/diana/GriffinBurrowFinder.kt b/src/main/java/at/hannibal2/skyhanni/features/diana/GriffinBurrowFinder.kt index d98f46100..524a94259 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/diana/GriffinBurrowFinder.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/diana/GriffinBurrowFinder.kt @@ -71,10 +71,7 @@ class GriffinBurrowFinder { 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()) + val distance = packet.toLorenzVec().distance(LocationUtils.playerLocation()) if (distance < 20) { // LorenzDebug.log("") // LorenzDebug.log("S2APacketParticles close") diff --git a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonHideItems.kt b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonHideItems.kt index faf48e95c..acc0de8a0 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonHideItems.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/dungeon/DungeonHideItems.kt @@ -1,14 +1,14 @@ package at.hannibal2.skyhanni.features.dungeon import at.hannibal2.skyhanni.SkyHanniMod -import at.hannibal2.skyhanni.data.EntityMovementHelper +import at.hannibal2.skyhanni.data.EntityMovementData import at.hannibal2.skyhanni.events.* import at.hannibal2.skyhanni.utils.ItemUtils.cleanName import at.hannibal2.skyhanni.utils.ItemUtils.getSkullTexture import at.hannibal2.skyhanni.utils.LorenzColor import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzVec import at.hannibal2.skyhanni.utils.getLorenzVec +import at.hannibal2.skyhanni.utils.toLorenzVec import net.minecraft.entity.item.EntityArmorStand import net.minecraft.entity.item.EntityItem import net.minecraft.network.play.server.S2APacketParticles @@ -121,7 +121,7 @@ class DungeonHideItems { } if (isSkeletonSkull(entity)) { - EntityMovementHelper.addToTrack(entity) + EntityMovementData.addToTrack(entity) if (SkyHanniMod.feature.dungeon.hideSkeletonSkull) { val lastMove = movingSkeletonSkulls.getOrDefault(entity, 0) if (lastMove + 100 > System.currentTimeMillis()) { @@ -139,7 +139,7 @@ class DungeonHideItems { val packet = event.packet if (packet is S2APacketParticles) { - val packetLocation = LorenzVec(packet.xCoordinate, packet.yCoordinate, packet.zCoordinate) + val packetLocation = packet.toLorenzVec() for (armorStand in hideParticles.filter { it.value + 100 > System.currentTimeMillis() }.map { it.key }) { val distance = packetLocation.distance(armorStand.getLorenzVec()) if (distance < 2) { diff --git a/src/main/java/at/hannibal2/skyhanni/features/items/HideNotClickableItems.kt b/src/main/java/at/hannibal2/skyhanni/features/items/HideNotClickableItems.kt index 549d347eb..2829742dc 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/items/HideNotClickableItems.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/items/HideNotClickableItems.kt @@ -384,8 +384,7 @@ class HideNotClickableItems { return true } - val displayName = stack.displayName - if (bazaarInventory != BazaarApi.isBazaarItem(displayName)) { + if (bazaarInventory != BazaarApi.isBazaarItem(stack)) { if (bazaarInventory) hideReason = "This item is not a Bazaar Product!" if (auctionHouseInventory) hideReason = "Bazaar Products cannot be auctioned!" diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemResolutionQuery.java b/src/main/java/at/hannibal2/skyhanni/utils/ItemResolutionQuery.java new file mode 100644 index 000000000..1f8988613 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemResolutionQuery.java @@ -0,0 +1,201 @@ +package at.hannibal2.skyhanni.utils; + +import at.hannibal2.skyhanni.config.ConfigManager; +import com.google.common.collect.Iterables; +import com.google.gson.JsonObject; +import com.google.gson.JsonParseException; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.Gui; +import net.minecraft.client.gui.inventory.GuiChest; +import net.minecraft.init.Items; +import net.minecraft.inventory.ContainerChest; +import net.minecraft.inventory.IInventory; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTTagCompound; + +import javax.annotation.Nullable; +import java.util.Arrays; +import java.util.List; +import java.util.Locale; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class ItemResolutionQuery { + + private static final Pattern ENCHANTED_BOOK_NAME_PATTERN = Pattern.compile("^((?:§.)+)([^§]+) ([IVXL]+)$"); + private static final String EXTRA_ATTRIBUTES = "ExtraAttributes"; + private static final List<String> PET_RARITIES = Arrays.asList( + "COMMON", + "UNCOMMON", + "RARE", + "EPIC", + "LEGENDARY", + "MYTHIC" + ); + private ItemStack stack; + private Item itemType; + private int stackSize = -1; + private Gui guiContext; + private String knownInternalName; + + public ItemResolutionQuery withItemStack(ItemStack stack) { + if (stack == null) return this; + this.itemType = stack.getItem(); + this.stack = stack; + this.stackSize = stack.stackSize; + return this; + } + + public ItemResolutionQuery withGuiContext(Gui gui) { + this.guiContext = gui; + return this; + } + + public ItemResolutionQuery withCurrentGuiContext() { + this.guiContext = Minecraft.getMinecraft().currentScreen; + return this; + } + + public ItemResolutionQuery withKnownInternalName(String knownInternalName) { + this.knownInternalName = knownInternalName; + return this; + } + + @Nullable + public String resolveInternalName() { + if (knownInternalName != null) { + return knownInternalName; + } + String resolvedName = resolveFromSkyblock(); + if (resolvedName == null) { + resolvedName = resolveContextualName(); + } else { + switch (resolvedName.intern()) { + case "PET": + resolvedName = resolvePetName(); + break; + case "RUNE": + resolvedName = resolveRuneName(); + break; + case "ENCHANTED_BOOK": + resolvedName = resolveEnchantedBookNameFromNBT(); + break; + case "PARTY_HAT_CRAB": + resolvedName = resolveCrabHatName(); + break; + } + } + + return resolvedName; + } + + // <editor-fold desc="Resolution Helpers"> + private boolean isBazaar(IInventory chest) { + if (chest.getDisplayName().getFormattedText().startsWith("Bazaar ➜ ")) { + return true; + } + int bazaarSlot = chest.getSizeInventory() - 5; + if (bazaarSlot < 0) return false; + ItemStack stackInSlot = chest.getStackInSlot(bazaarSlot); + if (stackInSlot == null || stackInSlot.stackSize == 0) return false; + // NBT lore, we do not care about rendered lore + List<String> lore = ItemUtils.INSTANCE.getLore(stackInSlot); + return lore.contains("§7To Bazaar"); + } + + private String resolveContextualName() { + if (!(guiContext instanceof GuiChest)) { + return null; + } + GuiChest chest = (GuiChest) guiContext; + ContainerChest inventorySlots = (ContainerChest) chest.inventorySlots; + String guiName = inventorySlots.getLowerChestInventory().getDisplayName().getUnformattedText(); + boolean isOnBazaar = isBazaar(inventorySlots.getLowerChestInventory()); + String displayName = ItemUtils.INSTANCE.getName(stack); + if (displayName == null) return null; + if (itemType == Items.enchanted_book && isOnBazaar) { + return resolveEnchantmentByName(displayName); + } + if (displayName.endsWith("Enchanted Book") && guiName.startsWith("Superpairs")) { + for (String loreLine : ItemUtils.INSTANCE.getLore(stack)) { + String enchantmentIdCandidate = resolveEnchantmentByName(loreLine); + if (enchantmentIdCandidate != null) return enchantmentIdCandidate; + } + return null; + } + return null; + } + + private String getDisplayName(NBTTagCompound compound) { + if (compound == null) return null; + String string = compound.getCompoundTag("display").getString("Name"); + if (string == null || string.isEmpty()) + return null; + return string; + } + + private String resolveEnchantmentByName(String name) { + Matcher matcher = ENCHANTED_BOOK_NAME_PATTERN.matcher(name); + if (!matcher.matches()) return null; + String format = matcher.group(1).toLowerCase(Locale.ROOT); + String enchantmentName = matcher.group(2).trim(); + String romanLevel = matcher.group(3); + boolean ultimate = (format.contains("§l")); + + return (ultimate ? "ULTIMATE_" : "") + + enchantmentName.replace(" ", "_").toUpperCase(Locale.ROOT) + + ";" + NumberUtil.INSTANCE.romanToDecimal(romanLevel); + } + + private String resolveCrabHatName() { + String color = getExtraAttributes().getString("party_hat_color"); + return "PARTY_HAT_CRAB_" + color.toUpperCase(Locale.ROOT); + } + + private String resolveEnchantedBookNameFromNBT() { + NBTTagCompound enchantments = getExtraAttributes().getCompoundTag("enchantments"); + String enchantName = Iterables.getOnlyElement(enchantments.getKeySet(), null); + if (enchantName == null || enchantName.isEmpty()) return null; + return enchantName.toUpperCase(Locale.ROOT) + ";" + enchantments.getInteger(enchantName); + } + + private String resolveRuneName() { + NBTTagCompound runes = getExtraAttributes().getCompoundTag("runes"); + String runeName = Iterables.getOnlyElement(runes.getKeySet(), null); + if (runeName == null || runeName.isEmpty()) return null; + return runeName.toUpperCase(Locale.ROOT) + "_RUNE;" + runes.getInteger(runeName); + } + + private String resolvePetName() { + String petInfo = getExtraAttributes().getString("petInfo"); + if (petInfo == null || petInfo.isEmpty()) return null; + try { + JsonObject petInfoObject = ConfigManager.Companion.getGson().fromJson(petInfo, JsonObject.class); + String petId = petInfoObject.get("type").getAsString(); + String petTier = petInfoObject.get("tier").getAsString(); + int rarityIndex = PET_RARITIES.indexOf(petTier); + return petId.toUpperCase(Locale.ROOT) + ";" + rarityIndex; + } catch (JsonParseException | ClassCastException ex) { + /* This happens if Hypixel changed the pet json format; + I still log this exception, since this case *is* exceptional and cannot easily be recovered from */ + ex.printStackTrace(); + return null; + } + } + + private NBTTagCompound getExtraAttributes() { + NBTTagCompound compound = stack.getTagCompound(); + if (compound == null) return new NBTTagCompound(); + return compound.getCompoundTag(EXTRA_ATTRIBUTES); + } + + private String resolveFromSkyblock() { + String internalName = getExtraAttributes().getString("id"); + if (internalName == null || internalName.isEmpty()) return null; + return internalName.toUpperCase(Locale.ROOT); + } + + // </editor-fold> + +} diff --git a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt index 3b38bd84a..bd373d075 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/ItemUtils.kt @@ -11,7 +11,6 @@ import net.minecraftforge.common.util.Constants import java.util.* object ItemUtils { - private val gson = GsonBuilder().setPrettyPrinting().create() fun ItemStack.cleanName() = this.displayName.removeColor() @@ -113,53 +112,10 @@ object ItemUtils { } fun ItemStack.getInternalName(): String { - val tag = tagCompound - if (tag == null || !tag.hasKey("ExtraAttributes", 10)) return "" - - val extraAttributes = tag.getCompoundTag("ExtraAttributes") - var internalName = if (extraAttributes.hasKey("id", 8)) { - extraAttributes.getString("id").replace(":".toRegex(), "-") - } else { - return "" - } - - if (internalName == "PET") { - val petInfo = extraAttributes.getString("petInfo") - if (petInfo.isNotEmpty()) { - val petInfoObject: JsonObject = gson.fromJson(petInfo, JsonObject::class.java) - internalName = petInfoObject["type"].asString - return when (petInfoObject["tier"].asString) { - "COMMON" -> "$internalName;0" - "UNCOMMON" -> "$internalName;1" - "RARE" -> "$internalName;2" - "EPIC" -> "$internalName;3" - "LEGENDARY" -> "$internalName;4" - "MYTHIC" -> "$internalName;5" - else -> internalName - } - } - } - - if (internalName == "ENCHANTED_BOOK" && extraAttributes.hasKey("enchantments", 10)) { - val enchants = extraAttributes.getCompoundTag("enchantments") - for (enchantment in enchants.keySet) { - return enchantment.uppercase(Locale.getDefault()) + ";" + enchants.getInteger(enchantment) - } - } - - if (internalName == "RUNE" && extraAttributes.hasKey("runes", 10)) { - val rune = extraAttributes.getCompoundTag("runes") - for (enchantment in rune.keySet) { - return enchantment.uppercase(Locale.getDefault()) + "_RUNE" + ";" + rune.getInteger(enchantment) - } - } - - if (internalName == "PARTY_HAT_CRAB" && extraAttributes.getString("party_hat_color") != null) { - val crabHat = extraAttributes.getString("party_hat_color") - return "PARTY_HAT_CRAB" + "_" + crabHat.uppercase(Locale.getDefault()) - } - - return internalName + return ItemResolutionQuery() + .withCurrentGuiContext() + .withItemStack(this) + .resolveInternalName() ?: "" } fun ItemStack.getSkullTexture(): String? { diff --git a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt index 95ab29433..117a35f77 100644 --- a/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt +++ b/src/main/java/at/hannibal2/skyhanni/utils/LorenzVec.kt @@ -1,6 +1,7 @@ package at.hannibal2.skyhanni.utils import net.minecraft.entity.Entity +import net.minecraft.network.play.server.S2APacketParticles import net.minecraft.util.BlockPos import net.minecraft.util.Rotations import net.minecraft.util.Vec3 @@ -107,4 +108,6 @@ fun Entity.getLorenzVec(): LorenzVec = LorenzVec(posX, posY, posZ) fun Vec3.toLorenzVec(): LorenzVec = LorenzVec(xCoord, yCoord, zCoord) -fun Rotations.toLorenzVec(): LorenzVec = LorenzVec(x, y, z)
\ No newline at end of file +fun Rotations.toLorenzVec(): LorenzVec = LorenzVec(x, y, z) + +fun S2APacketParticles.toLorenzVec(): LorenzVec = LorenzVec(xCoordinate, yCoordinate, zCoordinate)
\ No newline at end of file |