diff options
author | CalMWolfs <94038482+CalMWolfs@users.noreply.github.com> | 2024-03-10 23:27:31 +1100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-10 13:27:31 +0100 |
commit | 498afd58e3405d473107e08a3b1891f93f76a96a (patch) | |
tree | 9eabf6a6642cfa9d8939f5f4572c3a5cf00a3a6d /src/main/java/at/hannibal2/skyhanni/features/mining | |
parent | cb62e10474ac7c5aacb52d6cd04095e65051c060 (diff) | |
download | skyhanni-498afd58e3405d473107e08a3b1891f93f76a96a.tar.gz skyhanni-498afd58e3405d473107e08a3b1891f93f76a96a.tar.bz2 skyhanni-498afd58e3405d473107e08a3b1891f93f76a96a.zip |
Feature: Display current and upcoming mining events (#1040)
Co-authored-by: Thunderblade73 <85900443+Thunderblade73@users.noreply.github.com>
Co-authored-by: hannibal2 <24389977+hannibal00212@users.noreply.github.com>
Diffstat (limited to 'src/main/java/at/hannibal2/skyhanni/features/mining')
5 files changed, 207 insertions, 50 deletions
diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEvent.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEvent.kt deleted file mode 100644 index f5d8e26d8..000000000 --- a/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEvent.kt +++ /dev/null @@ -1,26 +0,0 @@ -package at.hannibal2.skyhanni.features.mining.eventtracker - -import at.hannibal2.skyhanni.utils.StringUtils.removeColor -import kotlin.time.Duration -import kotlin.time.Duration.Companion.minutes -import kotlin.time.Duration.Companion.seconds - -enum class MiningEvent(val eventName: String, val defaultLength: Duration, private val colourCode: Char) { - GONE_WITH_THE_WIND("GONE WITH THE WIND", 18.minutes, '9'), - DOUBLE_POWDER("2X POWDER", 15.minutes, 'b'), - GOBLIN_RAID("GOBLIN RAID", 5.minutes, 'c'), - BETTER_TOGETHER("BETTER TOGETHER", 18.minutes, 'd'), - RAFFLE("RAFFLE", 160.seconds, '6'), - MITHRIL_GOURMAND("MITHRIL GOURMAND", 10.minutes, 'b'), - ; - - override fun toString(): String { - return "§$colourCode$eventName" - } - - companion object { - fun fromBossbarName(bossbarName: String): MiningEvent? { - return MiningEvent.entries.find { it.eventName == bossbarName.removeColor() } - } - } -} diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventData.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventData.kt index ee2033ed4..9ce3d3c49 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventData.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventData.kt @@ -4,10 +4,39 @@ import at.hannibal2.skyhanni.data.IslandType import com.google.gson.annotations.Expose import com.google.gson.annotations.SerializedName -data class MiningEventData( +data class MiningEventDataSend( @Expose @SerializedName("server_type") val serverType: IslandType, @Expose @SerializedName("server_id") val serverId: String, - @Expose val event: MiningEvent, + @Expose val event: MiningEventType, @Expose @SerializedName("time_left") val timeRemaining: Long, @Expose @SerializedName("reporter_uuid") val uuid: String ) + +data class MiningEventDataReceive( + @Expose val success: Boolean, + @Expose val data: MiningEventData, + @Expose val cause: String +) + +data class MiningEventData( + @Expose @SerializedName("event_datas") val eventData: Map<IslandType, Map<MiningEventType, EventData>>, + @Expose @SerializedName("running_events") val runningEvents: Map<IslandType, List<RunningEventType>>, + @Expose @SerializedName("total_lobbys") val totalLobbies: Map<IslandType, Int>, + @Expose @SerializedName("update_in") val updateIn: Long, + @Expose @SerializedName("curr_time") val currentTime: Long +) + +data class EventData( + @Expose @SerializedName("starts_at_min") val startMin: Long, + @Expose @SerializedName("starts_at_max") val startMax: Long, + @Expose @SerializedName("ends_at_min") val endMin: Long, + @Expose @SerializedName("ends_at_max") val endMax: Long, + @Expose @SerializedName("lobby_count") val lobbyCount: Int +) + +data class RunningEventType( + @Expose val event: MiningEventType, + @Expose @SerializedName("ends_at") val endsAt: Long, + @Expose @SerializedName("lobby_count") val lobbyCount: Int, + @Expose @SerializedName("is_double") val isDoubleEvent: Boolean +) diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventDisplay.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventDisplay.kt new file mode 100644 index 000000000..7281da5a3 --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventDisplay.kt @@ -0,0 +1,91 @@ +package at.hannibal2.skyhanni.features.mining.eventtracker + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.config.features.mining.MiningEventConfig +import at.hannibal2.skyhanni.data.IslandType +import at.hannibal2.skyhanni.events.GuiRenderEvent +import at.hannibal2.skyhanni.events.LorenzTickEvent +import at.hannibal2.skyhanni.features.fame.ReminderUtils +import at.hannibal2.skyhanni.utils.LorenzUtils +import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland +import at.hannibal2.skyhanni.utils.RenderUtils.renderStrings +import at.hannibal2.skyhanni.utils.SimpleTimeMark.Companion.asTimeMark +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent + +object MiningEventDisplay { + private val config get() = SkyHanniMod.feature.mining.miningEvent + private var display = mutableListOf<String>() + + private var dwarvenEvents = listOf<RunningEventType>() + private var crystalEvents = listOf<RunningEventType>() + private var lastDwarvenEvent: MiningEventType? = null + private var lastCrystalEvent: MiningEventType? = null + + @SubscribeEvent + fun onTick(event: LorenzTickEvent) { + if (!event.repeatSeconds(1)) return + updateDisplay() + } + + @SubscribeEvent + fun onRenderOverlay(event: GuiRenderEvent.GuiOverlayRenderEvent) { + if (!shouldDisplay()) return + config.position.renderStrings(display, posLabel = "Upcoming Events Display") + } + + private fun updateDisplay() { + display.clear() + updateEvents(IslandType.DWARVEN_MINES, dwarvenEvents, lastDwarvenEvent) + updateEvents(IslandType.CRYSTAL_HOLLOWS, crystalEvents, lastCrystalEvent) + } + + private fun updateEvents(islandType: IslandType, events: List<RunningEventType>, lastEvent: MiningEventType?) { + val shouldShow = when (config.showType) { + MiningEventConfig.ShowType.DWARVEN -> islandType == IslandType.DWARVEN_MINES + MiningEventConfig.ShowType.CRYSTAL -> islandType == IslandType.CRYSTAL_HOLLOWS + MiningEventConfig.ShowType.CURRENT -> islandType.isInIsland() + else -> true + } + + events.firstOrNull()?.let { firstEvent -> + if (firstEvent.endsAt.asTimeMark().isInPast()) { + when (islandType) { + IslandType.DWARVEN_MINES -> lastDwarvenEvent = firstEvent.event + IslandType.CRYSTAL_HOLLOWS -> lastCrystalEvent = firstEvent.event + else -> Unit + } + } + } + + if (shouldShow) { + val upcomingEvents = formatUpcomingEvents(events, lastEvent) + display.add("§a${islandType.displayName}§8: $upcomingEvents") + } + } + + private fun formatUpcomingEvents(events: List<RunningEventType>, lastEvent: MiningEventType?): String { + val upcoming = events.filter { !it.endsAt.asTimeMark().isInPast() } + .map { if (it.isDoubleEvent) "${it.event} §8-> ${it.event}" else it.event.toString() } + .toMutableList() + + if (upcoming.isEmpty()) upcoming.add("§7???") + if (config.passedEvents && upcoming.size < 4) lastEvent?.let { upcoming.add(0, it.toPastString()) } + return upcoming.joinToString(" §8-> ") + } + + fun updateData(eventData: MiningEventData) { + eventData.runningEvents.forEach { (islandType, events) -> + when (islandType) { + IslandType.DWARVEN_MINES -> dwarvenEvents = + (events.sortedBy { it.endsAt - it.event.defaultLength.inWholeMilliseconds }) + + IslandType.CRYSTAL_HOLLOWS -> crystalEvents = + (events.sortedBy { it.endsAt - it.event.defaultLength.inWholeMilliseconds }) + else -> Unit + } + } + } + + private fun shouldDisplay() = LorenzUtils.inSkyBlock && config.enabled && !ReminderUtils.isBusy() && + !(!config.outsideMining && !LorenzUtils.inAdvancedMiningIsland()) +} diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventTracker.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventTracker.kt index 010c62615..137aecec2 100644 --- a/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventTracker.kt +++ b/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventTracker.kt @@ -4,24 +4,24 @@ import at.hannibal2.skyhanni.SkyHanniMod import at.hannibal2.skyhanni.config.ConfigManager import at.hannibal2.skyhanni.data.BossbarData import at.hannibal2.skyhanni.data.HypixelData -import at.hannibal2.skyhanni.data.IslandType import at.hannibal2.skyhanni.data.ScoreboardData import at.hannibal2.skyhanni.events.BossbarUpdateEvent import at.hannibal2.skyhanni.events.LorenzChatEvent +import at.hannibal2.skyhanni.events.LorenzTickEvent import at.hannibal2.skyhanni.events.LorenzWorldChangeEvent import at.hannibal2.skyhanni.test.command.ErrorManager import at.hannibal2.skyhanni.utils.APIUtil import at.hannibal2.skyhanni.utils.LorenzUtils -import at.hannibal2.skyhanni.utils.LorenzUtils.isInIsland import at.hannibal2.skyhanni.utils.SimpleTimeMark import at.hannibal2.skyhanni.utils.StringUtils.matchMatcher import at.hannibal2.skyhanni.utils.TabListData import at.hannibal2.skyhanni.utils.TimeUtils -import at.hannibal2.skyhanni.utils.getBoolean -import at.hannibal2.skyhanni.utils.getStringOrValue +import at.hannibal2.skyhanni.utils.fromJson import at.hannibal2.skyhanni.utils.repopatterns.RepoPattern import kotlinx.coroutines.launch import net.minecraftforge.fml.common.eventhandler.SubscribeEvent +import kotlin.time.Duration.Companion.milliseconds +import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds class MiningEventTracker { @@ -45,24 +45,24 @@ class MiningEventTracker { "(?:§.)*\\s+(?:§.)+§l(?<event>.+) ENDED!" ) - private var lastRequestSent = SimpleTimeMark.farPast() + private val defaultCooldown = 1.minutes + private var lastWorldSwitch = SimpleTimeMark.farPast() private var eventEndTime = SimpleTimeMark.farPast() + private var lastSentEvent: MiningEventType? = null - private var lastSentEvent: MiningEvent? = null + private var canRequestAt = SimpleTimeMark.farPast() @SubscribeEvent fun onWorldChange(event: LorenzWorldChangeEvent) { - lastRequestSent = SimpleTimeMark.now() lastWorldSwitch = SimpleTimeMark.farPast() eventEndTime = SimpleTimeMark.farPast() - lastSentEvent = null } @SubscribeEvent fun onBossbarChange(event: BossbarUpdateEvent) { - if (!isEnabled()) return + if (!LorenzUtils.inAdvancedMiningIsland()) return if (lastWorldSwitch.passedSince() < 2.seconds) return if (!eventEndTime.isInPast()) { return @@ -78,7 +78,7 @@ class MiningEventTracker { @SubscribeEvent fun onChat(event: LorenzChatEvent) { - if (!isEnabled()) return + if (!LorenzUtils.inAdvancedMiningIsland()) return eventStartedPattern.matchMatcher(event.message) { sendData(group("event"), null) @@ -88,10 +88,21 @@ class MiningEventTracker { } } + @SubscribeEvent + fun onTick(event: LorenzTickEvent) { + if (!event.repeatSeconds(1)) return + if (!config.enabled) return + if (!LorenzUtils.inSkyBlock || (!config.outsideMining && !LorenzUtils.inAdvancedMiningIsland())) return + if (!canRequestAt.isInPast()) return + + fetchData() + } + private fun sendData(eventName: String, time: String?) { - val eventType = MiningEvent.fromBossbarName(eventName) + val eventType = MiningEventType.fromBossbarName(eventName) if (lastSentEvent == eventType) return if (eventType == null) { + if (!config.enabled) return ErrorManager.logErrorWithData( Exception("UnknownMiningEvent"), "Unknown mining event detected from string $eventName", "eventName" to eventName, @@ -121,7 +132,7 @@ class MiningEventTracker { return } - val miningEventData = MiningEventData( + val miningEventData = MiningEventDataSend( LorenzUtils.skyBlockIsland, serverId, eventType, @@ -129,28 +140,44 @@ class MiningEventTracker { LorenzUtils.getPlayerUuid() ) val miningEventJson = ConfigManager.gson.toJson(miningEventData) -// //todo remove -// println("\n```json$miningEventJson```") SkyHanniMod.coroutineScope.launch { sendData(miningEventJson) } } - private fun isEnabled() = (IslandType.DWARVEN_MINES.isInIsland() || IslandType.CRYSTAL_HOLLOWS.isInIsland()) - && config.sendData -// && config.enabled - private fun sendData(json: String) { val response = APIUtil.postJSON("https://api.soopy.dev/skyblock/chevents/set", json) if (!response.success) return - val success = response.data.getBoolean("success") - if (!success) { - val cause = response.data.getStringOrValue("cause", "unknown") + + val formattedResponse = ConfigManager.gson.fromJson<MiningEventDataReceive>(response.data) + if (!formattedResponse.success) { + if (!config.enabled) return ErrorManager.logErrorWithData( Exception("PostFailure"), "Sending mining event data was unsuccessful", - "cause" to cause, + "cause" to formattedResponse.cause, "sentData" to json ) } } + + private fun fetchData() { + canRequestAt = SimpleTimeMark.now() + defaultCooldown + SkyHanniMod.coroutineScope.launch { + val data = APIUtil.getJSONResponse("https://api.soopy.dev/skyblock/chevents/get") + val miningEventData = ConfigManager.gson.fromJson(data, MiningEventDataReceive::class.java) + + if (!miningEventData.success) { + ErrorManager.logErrorWithData( + Exception("PostFailure"), "Sending mining event data was unsuccessful", + "cause" to miningEventData.cause, + "recievedData" to data + ) + return@launch + } + + canRequestAt = SimpleTimeMark.now() + miningEventData.data.updateIn.milliseconds + + MiningEventDisplay.updateData(miningEventData.data) + } + } } diff --git a/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventType.kt b/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventType.kt new file mode 100644 index 000000000..b8fb1d35a --- /dev/null +++ b/src/main/java/at/hannibal2/skyhanni/features/mining/eventtracker/MiningEventType.kt @@ -0,0 +1,36 @@ +package at.hannibal2.skyhanni.features.mining.eventtracker + +import at.hannibal2.skyhanni.SkyHanniMod +import at.hannibal2.skyhanni.utils.StringUtils.removeColor +import kotlin.time.Duration +import kotlin.time.Duration.Companion.minutes +import kotlin.time.Duration.Companion.seconds + +enum class MiningEventType( + val eventName: String, + private val shortName: String, + val defaultLength: Duration, + private val colourCode: Char +) { + GONE_WITH_THE_WIND("GONE WITH THE WIND", "Wind", 18.minutes, '9'), + DOUBLE_POWDER("2X POWDER", "2x", 15.minutes, 'b'), + GOBLIN_RAID("GOBLIN RAID", "Raid", 5.minutes, 'c'), + BETTER_TOGETHER("BETTER TOGETHER", "Better", 18.minutes, 'd'), + RAFFLE("RAFFLE", "Raffle", 160.seconds, '6'), + MITHRIL_GOURMAND("MITHRIL GOURMAND", "Gourmand", 10.minutes, 'b'), + ; + + override fun toString() = + if (config.compressedFormat) "§$colourCode$shortName" else "§$colourCode$eventName" + + fun toPastString() = + if (config.compressedFormat) "§7$shortName" else "§7$eventName" + + companion object { + private val config get() = SkyHanniMod.feature.mining.miningEvent + + fun fromBossbarName(bossbarName: String): MiningEventType? { + return MiningEventType.entries.find { it.eventName == bossbarName.removeColor() } + } + } +} |