### Vanilla Minecraft Launcher Java Path (Linux) Source: https://github.com/hannibal002/skyhanni/blob/beta/docs/update_java.md Specify the path to the Java executable for the Vanilla Minecraft Launcher on Linux. Replace '' with your installed Java version. ```plaintext /usr/lib/jvm//bin/java ``` -------------------------------- ### Add Regex Test Cases in KDoc Source: https://github.com/hannibal002/skyhanni/blob/beta/CONTRIBUTING.md Provide regex test examples in KDoc comments above pattern variables using lines starting with `REGEX-TEST: ` to ensure pattern correctness. ```kotlin REGEX-TEST: ``` -------------------------------- ### Vanilla Minecraft Launcher Java Path (macOS) Source: https://github.com/hannibal002/skyhanni/blob/beta/docs/update_java.md Specify the path to the Java executable for the Vanilla Minecraft Launcher on macOS. Replace '' with your installed Java version. ```plaintext /Library/Java/JavaVirtualMachines//Contents/Home/bin/java ``` -------------------------------- ### Look up Hypixel SkyBlock Item Prices Source: https://context7.com/hannibal002/skyhanni/llms.txt Use ItemPriceUtils extension functions to get real-time Bazaar, Auction House (lowest BIN), NPC, or craft-cost prices for items. Prices are retrieved from in-memory caches. ```kotlin import at.hannibal2.skyhanni.utils.ItemPriceUtils.getPrice import at.hannibal2.skyhanni.utils.ItemPriceUtils.getPriceOrNull import at.hannibal2.skyhanni.utils.ItemPriceUtils.isAuctionHouseItem import at.hannibal2.skyhanni.utils.ItemPriceSource import at.hannibal2.skyhanni.utils.NeuInternalName.Companion.toInternalName import at.hannibal2.skyhanni.utils.NumberUtil.shortFormat val enchantedSugarCane = "ENCHANTED_SUGAR_CANE".toInternalName() val hyperion = "HYPERION".toInternalName() // ── Bazaar instant-buy price (default source) ───────────────────────────────── val bzPrice: Double = enchantedSugarCane.getPrice() // e.g. 153600.0 // ── Bazaar instant-sell price ───────────────────────────────────────────────── val sellPrice: Double? = enchantedSugarCane.getPriceOrNull(ItemPriceSource.BAZAAR_INSTANT_SELL) // ── Lowest BIN (auction house) ──────────────────────────────────────────────── val binPrice: Double = hyperion.getPrice(ItemPriceSource.LOWEST_BIN) println(binPrice.shortFormat()) // e.g. "320M" // ── NPC sell price ──────────────────────────────────────────────────────────── val npcPrice: Double? = enchantedSugarCane.getPriceOrNull(ItemPriceSource.NPC_SELL) // ── Check if item is on AH ──────────────────────────────────────────────────── println(hyperion.isAuctionHouseItem()) // true println(enchantedSugarCane.isAuctionHouseItem()) // false (Bazaar item) ``` -------------------------------- ### Get All Items in Player's Inventory Source: https://context7.com/hannibal002/skyhanni/llms.txt Fetches all items present in the player's own inventory (36 slots) and prints their names and internal IDs. Requires InventoryUtils and ItemUtils imports. ```kotlin // ── All items in the player's inventory (9×4 slots, 0..35) ─────────────────── val items = InventoryUtils.getItemsInOwnInventory() items.forEach { stack -> println("${stack.getItemName()} — ${stack.getInternalName()}") } ``` -------------------------------- ### LorenzVec: 3D Vector Construction and Arithmetic Source: https://context7.com/hannibal002/skyhanni/llms.txt Demonstrates creating LorenzVec instances and performing basic arithmetic operations like addition, subtraction, and normalization. Requires importing LorenzVec. ```kotlin import at.hannibal2.skyhanni.utils.LorenzVec val a = LorenzVec(100.0, 64.0, -200.0) val b = LorenzVec(110.5, 64.0, -200.0) ``` ```kotlin val midpoint = (a + b) / 2.0 // LorenzVec(105.25, 64.0, -200.0) val direction = (b - a).normalize() // unit vector pointing from a to b ``` -------------------------------- ### Get Current SkyBlock Time Source: https://context7.com/hannibal002/skyhanni/llms.txt Retrieves the current in-game SkyBlock time and prints the year, month, and day. Requires SkyBlockTime and SimpleTimeMark imports. ```kotlin import at.hannibal2.skyhanni.utils.SkyBlockTime import at.hannibal2.skyhanni.utils.SimpleTimeMark import kotlin.time.Duration.Companion.days // ── Current SkyBlock time ───────────────────────────────────────────────────── val now: SkyBlockTime = SimpleTimeMark.now().toSkyBlockTime() println("Year ${now.year}, ${now.monthName}, Day ${now.day}") // Example output: Year 362, Early Winter, Day 12 ``` -------------------------------- ### Create SkyHanniTracker Instance Source: https://context7.com/hannibal002/skyhanni/llms.txt Instantiates a SkyHanniTracker with a name, data creation logic, storage retrieval, configuration, and a display rendering function. Requires necessary imports. ```kotlin import at.hannibal2.skyhanni.utils.tracker.SkyHanniTracker import at.hannibal2.skyhanni.utils.tracker.TrackerData import at.hannibal2.skyhanni.utils.NeuInternalName import at.hannibal2.skyhanni.utils.renderables.Searchable import at.hannibal2.skyhanni.utils.renderables.toRenderable import at.hannibal2.skyhanni.utils.renderables.primitives.text import at.hannibal2.skyhanni.config.storage.ProfileSpecificStorage import at.hannibal2.skyhanni.SkyHanniMod // ── Create tracker instance ─────────────────────────────────────────────────── val cropTracker = SkyHanniTracker( name = "Crop Tracker", createNewSession = { MyCropData() }, getStorage = { storage: ProfileSpecificStorage -> storage.myCropData }, trackerConfig = { SkyHanniMod.feature.garden.cropTracker }, drawDisplay = { data: MyCropData -> listOf( text("§6Wheat: §f${data.wheatCount}").toRenderable() ) } ) ``` -------------------------------- ### LorenzVec: Spatial Utilities Source: https://context7.com/hannibal002/skyhanni/llms.txt Demonstrates utility functions for LorenzVec, including adding an offset to a specific coordinate, rounding to the nearest block, and creating a bounding box. Requires importing LorenzVec. ```kotlin import at.hannibal2.skyhanni.utils.LorenzVec val a = LorenzVec(100.0, 64.0, -200.0) val up2 = a.add(y = 2.0) // LorenzVec(100.0, 66.0, -200.0) val block = a.roundToBlock() // snaps each coordinate to nearest integer val aabb = a.boundingToOffset(1.0, 1.0, 1.0) // AABB from a to a+(1,1,1) ``` -------------------------------- ### NumberUtil: Compact Number Formatting Source: https://context7.com/hannibal002/skyhanni/llms.txt Provides extension functions for Numbers to format them into compact strings using suffixes like 'k', 'M', and 'B'. Supports precise billions formatting. Requires importing NumberUtil.shortFormat. ```kotlin import at.hannibal2.skyhanni.utils.NumberUtil.shortFormat 1234.shortFormat() // "1.2k" 1_500_000.shortFormat() // "1.5M" 2_300_000_000L.shortFormat() // "2.3B" 2_300_000_000L.shortFormat(preciseBillions = true) // "2.300B" ``` -------------------------------- ### Get Item Currently Held in Main Hand Source: https://context7.com/hannibal002/skyhanni/llms.txt Retrieves the item currently held in the player's main hand using InventoryUtils. Requires InventoryUtils and ItemUtils imports. ```kotlin import at.hannibal2.skyhanni.utils.InventoryUtils import at.hannibal2.skyhanni.utils.ItemUtils.getInternalName import at.hannibal2.skyhanni.utils.ItemUtils.getLore import at.hannibal2.skyhanni.utils.ItemUtils.getItemName // ── Item currently held in main hand ───────────────────────────────────────── val heldItem = InventoryUtils.latestItemInHand val heldName = InventoryUtils.itemInHandId // NeuInternalName ``` -------------------------------- ### Launch Mutex-Guarded Coroutine Source: https://context7.com/hannibal002/skyhanni/llms.txt Launches a coroutine that is protected by a Mutex, ensuring only one instance runs at a time. Requires importing kotlinx.coroutines.sync.Mutex. ```kotlin import at.hannibal2.skyhanni.utils.coroutines.CoroutineSettings import at.hannibal2.skyhanni.SkyHanniMod.launch // the mod-scoped CoroutineManager import kotlin.time.Duration.Companion.seconds import kotlinx.coroutines.sync.Mutex val updateMutex = Mutex() CoroutineSettings("updateDisplay") .withMutex(updateMutex) .launchUnScopedCoroutine { recalculateDisplay() } ``` -------------------------------- ### SkyHanni Module Registration Source: https://context7.com/hannibal002/skyhanni/llms.txt Demonstrates how to register modules using the `@SkyHanniModule` annotation. This annotation automatically discovers and wires modules, including options for development-only modules. ```kotlin import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule // ── Production module ───────────────────────────────────────────────────────── @SkyHanniModule object FarmingTrackerModule { // @HandleEvent methods are automatically registered at mod init } // ── Development-only module (not loaded in production builds) ───────────────── @SkyHanniModule(devOnly = true) object DebugOverlay { // Only active during development } ``` -------------------------------- ### Get Items in Currently Open Container Source: https://context7.com/hannibal002/skyhanni/llms.txt Retrieves the name of the currently open inventory container (e.g., chest) and lists items within it. It specifically checks for items related to coins. Requires InventoryUtils and ItemUtils imports. ```kotlin // ── Currently open container (chest/GUI) ───────────────────────────────────── val containerName = InventoryUtils.openInventoryName() // e.g. "Large Chest" val containerItems = InventoryUtils.getItemsInOpenChest() containerItems.forEachIndexed { slot, stack -> if (stack == null) return@forEachIndexed val lore = stack.getLore() if (lore.any { it.contains("§6Coins") }) { println("Found coin-related item at slot $slot: ${stack.getItemName()}") } } ``` -------------------------------- ### Launch Coroutine with IO Context and Timeout Source: https://context7.com/hannibal002/skyhanni/llms.txt Launches a coroutine using the IO dispatcher with a 30-second timeout. Useful for network operations or disk I/O. ```kotlin import at.hannibal2.skyhanni.utils.coroutines.CoroutineSettings import at.hannibal2.skyhanni.SkyHanniMod.launch // the mod-scoped CoroutineManager import kotlin.time.Duration.Companion.seconds // ── IO dispatcher + 30-second timeout ──────────────────────────────────────── CoroutineSettings("downloadRepo", timeout = 30.seconds) .withIOContext() .launchCoroutine { val bytes = downloadFile("https://example.com/repo.zip") processRepo(bytes) } ``` -------------------------------- ### Create Hoverable Chat Message with Tooltip and Command Source: https://context7.com/hannibal002/skyhanni/llms.txt Generate a chat message that shows a tooltip when hovered over and can execute a command. The hover parameter accepts a list of strings for multi-line tooltips. ```kotlin import at.hannibal2.skyhanni.utils.ChatUtils // ── Hoverable message with tooltip lines ───────────────────────────────────── ChatUtils.hoverableChat( message = "Crop summary ready", hover = listOf("§7Wheat: 5,000", "§7Carrot: 3,200", "§7Potato: 8,100"), command = "/sh cropoverview", ) ``` -------------------------------- ### Vanilla Minecraft Launcher Java Path Source: https://github.com/hannibal002/skyhanni/blob/beta/docs/update_java.md Specify the path to the Java executable for the Vanilla Minecraft Launcher on Windows. Ensure 'xxx' is replaced with your specific Java 8 update number. ```plaintext C:\Program Files\Java\jre1.8.0_xxx\bin\javaw.exe ``` -------------------------------- ### Render 2D HUD Overlays with GuiRenderEvent Source: https://context7.com/hannibal002/skyhanni/llms.txt Use GuiRenderEvent subclasses to render 2D elements on the HUD. GuiOverlayRenderEvent renders at all times, while ChestGuiOverlayRenderEvent is specific to inventory screens. ```kotlin import at.hannibal2.skyhanni.api.event.HandleEvent import at.hannibal2.skyhanni.events.GuiRenderEvent import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule import at.hannibal2.skyhanni.utils.RenderUtils.renderRenderables import at.hannibal2.skyhanni.utils.renderables.Renderable import at.hannibal2.skyhanni.utils.renderables.primitives.text import at.hannibal2.skyhanni.config.core.config.Position @SkyHanniModule object MyHudModule { // Position stored in config (drag-to-reposition in GUI editor) private val displayPosition = Position(10, 10) private val display: List = listOf( text("§aSkyHanni HUD"), text("§7Coins: §64,200,000"), ) // Renders outside inventory screens (full brightness) @HandleEvent fun onGuiOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { displayPosition.renderRenderables(display, posLabel = "My HUD") } // Renders only while a chest/container inventory is open @HandleEvent fun onChestGui(event: GuiRenderEvent.ChestGuiOverlayRenderEvent) { // draw inventory-specific overlays here } } ``` -------------------------------- ### StringUtils: String Manipulation Extensions Source: https://context7.com/hannibal002/skyhanni/llms.txt Provides utility functions for cleaning and manipulating strings, including removing Minecraft color codes, trimming whitespace, cleaning for comparisons, and capitalizing the first letter. Ensure the correct import for each function. ```kotlin import at.hannibal2.skyhanni.utils.StringUtils.removeColor import at.hannibal2.skyhanni.utils.StringUtils.trimWhiteSpaceAndResets import at.hannibal2.skyhanni.utils.StringUtils.cleanString import at.hannibal2.skyhanni.utils.StringUtils.firstLetterUppercase import at.hannibal2.skyhanni.utils.StringUtils.removeAllNonLettersAndNumbers // ── Strip color codes ──────────────────────────────────────────────────────── "§aHello §bWorld§r".removeColor() // → "Hello World" "§aHello §bWorld§r".removeColor(keepFormatting = true) // → "Hello World" (formatting chars stripped too) // ── Clean for fuzzy matching ────────────────────────────────────────────────── "§6[VIP+] §bPlayer Name".cleanString() // → "vip player name" (lowercase, no color, no symbols except spaces) // ── Trim whitespace and reset codes ────────────────────────────────────────── " §rSome text §r ".trimWhiteSpaceAndResets() // → "Some text" // ── Remove non-alphanumeric characters ─────────────────────────────────────── "Hello, World! §aTest §r123.".removeAllNonLettersAndNumbers() // → "Hello World Test123" // ── Capitalize first letter ─────────────────────────────────────────────────── "WHEAT".firstLetterUppercase() // "Wheat" "farmING".firstLetterUppercase() // "Farming" ``` -------------------------------- ### Launch Coroutine with Name and Default Timeout Source: https://context7.com/hannibal002/skyhanni/llms.txt Launches a coroutine with a specified name and a default 10-second timeout. Ensure CoroutineManager is available in the scope. ```kotlin import at.hannibal2.skyhanni.utils.coroutines.CoroutineSettings import at.hannibal2.skyhanni.SkyHanniMod.launch // the mod-scoped CoroutineManager import kotlin.time.Duration.Companion.seconds // ── Basic coroutine with a name and 10-second default timeout ───────────────── CoroutineSettings("fetchPrices").launchCoroutine { val data = fetchDataFromApi() // suspend call println("Got data: $data") } ``` -------------------------------- ### Construct Specific SkyBlock Date and Calculate Time Until Source: https://context7.com/hannibal002/skyhanni/llms.txt Creates a specific SkyBlock date and converts it to a SimpleTimeMark to calculate the time remaining until that date. Requires SkyBlockTime and SimpleTimeMark imports. ```kotlin val newYear = SkyBlockTime(year = 363, month = 1, day = 1, hour = 0) val newYearMark: SimpleTimeMark = newYear.toTimeMark() println("New Year in: ${newYearMark.timeUntil()}") ``` -------------------------------- ### Create Clickable Chat Message with Action and Hover Source: https://context7.com/hannibal002/skyhanni/llms.txt Construct a chat message that is clickable and displays a hoverable tooltip. The onClick lambda defines the action to perform when the message is clicked, such as sending a server command. ```kotlin import at.hannibal2.skyhanni.utils.ChatUtils import at.hannibal2.skyhanni.utils.SimpleTimeMark // ── Clickable message with lambda action ────────────────────────────────────── ChatUtils.clickableChat( message = "Click here to warp to hub!", onClick = { ChatUtils.sendMessageToServer("/warp hub") }, hover = "§eClick to warp to Hub", expireAt = SimpleTimeMark.farFuture(), ) ``` -------------------------------- ### Send Server Message with Rate-Limiting Source: https://context7.com/hannibal002/skyhanni/llms.txt Send a message to the server, such as a command, with built-in rate-limiting. This prevents the mod from being kicked for spamming the server. ```kotlin import at.hannibal2.skyhanni.utils.ChatUtils // ── Rate-limited server message (queued to avoid spam kicks) ────────────────── ChatUtils.sendMessageToServer("/bz") ``` -------------------------------- ### Group Repo Patterns with a Prefix Source: https://github.com/hannibal002/skyhanni/blob/beta/CONTRIBUTING.md When a file contains multiple patterns, use `RepoPattern.group(prefix)` to group them under a shared key prefix for better organization. ```kotlin RepoPattern.group(prefix) ``` -------------------------------- ### SimpleTimeMark: SkyBlock Time Conversion and Formatting Source: https://context7.com/hannibal002/skyhanni/llms.txt Convert SimpleTimeMark instances to SkyBlock time components or format them into human-readable date strings. ```kotlin // ── Convert to SkyBlock time ────────────────────────────────────────────────── val sbTime = SimpleTimeMark.now().toSkyBlockTime() println("SkyBlock Year ${sbTime.year}, Month ${sbTime.monthName}, Day ${sbTime.day}") // Example output: SkyBlock Year 362, Month Early Winter, Day 12 ``` ```kotlin // ── Format for display ──────────────────────────────────────────────────────── val mark = SimpleTimeMark.now() println(mark.formattedDate("MMMM d, yyyy h:mm a")) // Example output: June 7, 2025 3:45 PM ``` -------------------------------- ### SkyHanni Event System and Listeners Source: https://context7.com/hannibal002/skyhanni/llms.txt Defines a custom event and demonstrates how to dispatch and listen to events within SkyHanni modules. Supports filtering by game state and island type, and allows for custom event priorities. ```kotlin import at.hannibal2.skyhanni.api.event.HandleEvent import at.hannibal2.skyhanni.api.event.SkyHanniEvent import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.events.chat.SkyHanniChatEvent import at.hannibal2.skyhanni.events.minecraft.SkyHanniTickEvent import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule // ── Define a custom event ───────────────────────────────────────────────────── class MyCustomEvent(val value: Int) : SkyHanniEvent() // ── Dispatch the event anywhere ─────────────────────────────────────────────── MyCustomEvent(42).post() // ── Listen in a module ──────────────────────────────────────────────────────── @SkyHanniModule object MyFeatureModule { // Basic listener – fires every game tick @HandleEvent fun onTick(event: SkyHanniTickEvent) { // runs every tick regardless of island } // Filtered listener – only fires on the Garden island while on SkyBlock @HandleEvent(onlyOnSkyblock = true, onlyOnIsland = IslandType.GARDEN) fun onGardenTick(event: SkyHanniTickEvent) { // only runs while in the Garden } // High-priority cancellable chat listener @HandleEvent(priority = HandleEvent.HIGH) fun onChat(event: SkyHanniChatEvent.Allow) { if (event.message.contains("bad word")) { event.blockedReason = "blocked by MyFeatureModule" } } // Listen to a custom event @HandleEvent fun onMyCustom(event: MyCustomEvent) { println("Received value: ${event.value}") // Expected output: Received value: 42 } } ``` -------------------------------- ### LorenzVec: Conversion to Minecraft Types Source: https://context7.com/hannibal002/skyhanni/llms.txt Illustrates converting a LorenzVec instance to Minecraft's BlockPos and Vec3 types. Requires importing LorenzVec. ```kotlin import at.hannibal2.skyhanni.utils.LorenzVec val a = LorenzVec(100.0, 64.0, -200.0) val blockPos = a.toBlockPos() // BlockPos(100, 64, -200) val vec3 = a.toVec3() // net.minecraft.world.phys.Vec3 ``` -------------------------------- ### CollectionUtils: Map and Collection Extensions Source: https://context7.com/hannibal002/skyhanni/llms.txt Provides extensions for common collection operations like adding/updating map entries, sorting maps by value, checking for multiple values, draining queues, and summing map values. Ensure the necessary imports are present. ```kotlin import at.hannibal2.skyhanni.utils.collection.CollectionUtils.addOrPut import at.hannibal2.skyhanni.utils.collection.CollectionUtils.sortedDesc import at.hannibal2.skyhanni.utils.collection.CollectionUtils.equalsOneOf import at.hannibal2.skyhanni.utils.collection.CollectionUtils.drainForEach import at.hannibal2.skyhanni.utils.collection.CollectionUtils.sumAllValues import java.util.LinkedList // ── addOrPut: increment a counter map ──────────────────────────────────────── val counts = mutableMapOf() counts.addOrPut("wheat", 5) // {"wheat": 5} counts.addOrPut("wheat", 3) // {"wheat": 8} counts.addOrPut("carrot", 10) // {"wheat": 8, "carrot": 10} // ── sortedDesc: sort map by value descending ────────────────────────────────── val sorted = counts.sortedDesc() // [("carrot", 10), ("wheat", 8)] // ── equalsOneOf: multi-value equality check ──────────────────────────────────── val island = "GARDEN" println(island.equalsOneOf("GARDEN", "FARMING_ISLAND", "BARN")) // true println(island.equalsOneOf("HUB", "DUNGEON")) // false // ── drainForEach: consume all items from a queue ───────────────────────────── val queue = LinkedList(listOf(1, 2, 3, 4, 5)) queue.drainForEach { println("Processing $it") } // Output: Processing 1, 2, 3, 4, 5 (queue is empty after) // ── sumAllValues: total up a Map ──────────────────────────────────── val itemCounts = mapOf("wheat" to 500L, "carrot" to 300L, "potato" to 800L) val total = itemCounts.sumAllValues() // 1600L ```