feat: Add bazaar/ah search hotkey

This commit is contained in:
Linnea Gräf
2024-11-17 17:29:15 +01:00
parent 915ab96b24
commit 970dfddaf9
11 changed files with 196 additions and 78 deletions

View File

@@ -1,5 +1,3 @@
package moe.nea.firmament.repo
import io.ktor.client.call.body
@@ -21,87 +19,93 @@ import moe.nea.firmament.util.SkyblockId
import moe.nea.firmament.util.async.waitForInput
object HypixelStaticData {
private val logger = LogManager.getLogger("Firmament.HypixelStaticData")
private val moulberryBaseUrl = "https://moulberry.codes"
private val hypixelApiBaseUrl = "https://api.hypixel.net"
var lowestBin: Map<SkyblockId, Double> = mapOf()
private set
var bazaarData: Map<SkyblockId, BazaarData> = mapOf()
private set
var collectionData: Map<String, CollectionSkillData> = mapOf()
private set
private val logger = LogManager.getLogger("Firmament.HypixelStaticData")
private val moulberryBaseUrl = "https://moulberry.codes"
private val hypixelApiBaseUrl = "https://api.hypixel.net"
var lowestBin: Map<SkyblockId, Double> = mapOf()
private set
var bazaarData: Map<SkyblockId, BazaarData> = mapOf()
private set
var collectionData: Map<String, CollectionSkillData> = mapOf()
private set
@Serializable
data class BazaarData(
@SerialName("product_id")
val productId: SkyblockId.BazaarStock,
@SerialName("quick_status")
val quickStatus: BazaarStatus,
)
@Serializable
data class BazaarData(
@SerialName("product_id")
val productId: SkyblockId.BazaarStock,
@SerialName("quick_status")
val quickStatus: BazaarStatus,
)
@Serializable
data class BazaarStatus(
val sellPrice: Double,
val sellVolume: Long,
val sellMovingWeek: Long,
val sellOrders: Long,
val buyPrice: Double,
val buyVolume: Long,
val buyMovingWeek: Long,
val buyOrders: Long
)
@Serializable
data class BazaarStatus(
val sellPrice: Double,
val sellVolume: Long,
val sellMovingWeek: Long,
val sellOrders: Long,
val buyPrice: Double,
val buyVolume: Long,
val buyMovingWeek: Long,
val buyOrders: Long
)
@Serializable
private data class BazaarResponse(
val success: Boolean,
val products: Map<SkyblockId.BazaarStock, BazaarData> = mapOf(),
)
@Serializable
private data class BazaarResponse(
val success: Boolean,
val products: Map<SkyblockId.BazaarStock, BazaarData> = mapOf(),
)
fun getPriceOfItem(item: SkyblockId): Double? = bazaarData[item]?.quickStatus?.buyPrice ?: lowestBin[item]
fun getPriceOfItem(item: SkyblockId): Double? = bazaarData[item]?.quickStatus?.buyPrice ?: lowestBin[item]
fun hasBazaarStock(item: SkyblockId): Boolean {
return item in bazaarData
}
fun spawnDataCollectionLoop() {
Firmament.coroutineScope.launch {
logger.info("Updating collection data")
updateCollectionData()
}
Firmament.coroutineScope.launch {
while (true) {
logger.info("Updating NEU prices")
updatePrices()
withTimeoutOrNull(10.minutes) { waitForInput(IKeyBinding.ofKeyCode(GLFW.GLFW_KEY_U)) }
}
}
}
fun hasAuctionHouseOffers(item: SkyblockId): Boolean {
return (item in lowestBin) // TODO: || (item in biddableAuctionPrices)
}
private suspend fun updatePrices() {
awaitAll(
Firmament.coroutineScope.async { fetchBazaarPrices() },
Firmament.coroutineScope.async { fetchPricesFromMoulberry() },
)
}
fun spawnDataCollectionLoop() {
Firmament.coroutineScope.launch {
logger.info("Updating collection data")
updateCollectionData()
}
Firmament.coroutineScope.launch {
while (true) {
logger.info("Updating NEU prices")
updatePrices()
}
}
}
private suspend fun fetchPricesFromMoulberry() {
lowestBin = Firmament.httpClient.get("$moulberryBaseUrl/lowestbin.json")
.body<Map<SkyblockId, Double>>()
}
private suspend fun updatePrices() {
awaitAll(
Firmament.coroutineScope.async { fetchBazaarPrices() },
Firmament.coroutineScope.async { fetchPricesFromMoulberry() },
)
}
private suspend fun fetchBazaarPrices() {
val response = Firmament.httpClient.get("$hypixelApiBaseUrl/skyblock/bazaar").body<BazaarResponse>()
if (!response.success) {
logger.warn("Retrieved unsuccessful bazaar data")
}
bazaarData = response.products.mapKeys { it.key.toRepoId() }
}
private suspend fun fetchPricesFromMoulberry() {
lowestBin = Firmament.httpClient.get("$moulberryBaseUrl/lowestbin.json")
.body<Map<SkyblockId, Double>>()
}
private suspend fun updateCollectionData() {
val response =
Firmament.httpClient.get("$hypixelApiBaseUrl/resources/skyblock/collections").body<CollectionResponse>()
if (!response.success) {
logger.warn("Retrieved unsuccessful collection data")
}
collectionData = response.collections
logger.info("Downloaded ${collectionData.values.sumOf { it.items.values.size }} collections")
}
private suspend fun fetchBazaarPrices() {
val response = Firmament.httpClient.get("$hypixelApiBaseUrl/skyblock/bazaar").body<BazaarResponse>()
if (!response.success) {
logger.warn("Retrieved unsuccessful bazaar data")
}
bazaarData = response.products.mapKeys { it.key.toRepoId() }
}
private suspend fun updateCollectionData() {
val response =
Firmament.httpClient.get("$hypixelApiBaseUrl/resources/skyblock/collections").body<CollectionResponse>()
if (!response.success) {
logger.warn("Retrieved unsuccessful collection data")
}
collectionData = response.collections
logger.info("Downloaded ${collectionData.values.sumOf { it.items.values.size }} collections")
}
}

View File

@@ -23,6 +23,7 @@ import net.minecraft.item.Items
import net.minecraft.nbt.NbtCompound
import net.minecraft.nbt.NbtElement
import net.minecraft.nbt.NbtOps
import net.minecraft.nbt.NbtString
import net.minecraft.text.Text
import moe.nea.firmament.Firmament
import moe.nea.firmament.gui.config.HudMeta
@@ -33,11 +34,11 @@ import moe.nea.firmament.util.LegacyTagParser
import moe.nea.firmament.util.MC
import moe.nea.firmament.util.SkyblockId
import moe.nea.firmament.util.TestUtil
import moe.nea.firmament.util.mc.FirmamentDataComponentTypes
import moe.nea.firmament.util.mc.appendLore
import moe.nea.firmament.util.mc.modifyLore
import moe.nea.firmament.util.mc.setCustomName
import moe.nea.firmament.util.mc.setSkullOwner
import moe.nea.firmament.util.skyblockId
object ItemCache : IReloadable {
private val cache: MutableMap<String, ItemStack> = ConcurrentHashMap()
@@ -67,6 +68,8 @@ object ItemCache : IReloadable {
null
}
val ItemStack.isBroken
get() = get(FirmamentDataComponentTypes.IS_BROKEN) ?: false
fun brokenItemStack(neuItem: NEUItem?, idHint: SkyblockId? = null): ItemStack {
return ItemStack(Items.PAINTING).apply {
setCustomName(Text.literal(neuItem?.displayName ?: idHint?.neuItem ?: "null"))
@@ -78,6 +81,10 @@ object ItemCache : IReloadable {
)
)
)
set(DataComponentTypes.CUSTOM_DATA, NbtComponent.of(NbtCompound().apply {
put("ID", NbtString.of(neuItem?.skyblockItemId ?: idHint?.neuItem ?: "null"))
}))
set(FirmamentDataComponentTypes.IS_BROKEN, true)
}
}