aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/kotlin/features/chat/AutoGGOnTapCube.kt35
-rw-r--r--src/main/kotlin/features/fixes/CompatibliltyFeatures.kt73
-rw-r--r--src/main/kotlin/features/inventory/ItemRarityCosmetics.kt129
-rw-r--r--src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt1
-rw-r--r--src/main/kotlin/util/SBData.kt107
-rw-r--r--src/main/kotlin/util/data/ProfileSpecificDataHolder.kt8
-rw-r--r--src/main/resources/assets/firmament/lang/en_us.json1
7 files changed, 206 insertions, 148 deletions
diff --git a/src/main/kotlin/features/chat/AutoGGOnTapCube.kt b/src/main/kotlin/features/chat/AutoGGOnTapCube.kt
new file mode 100644
index 0000000..356d40a
--- /dev/null
+++ b/src/main/kotlin/features/chat/AutoGGOnTapCube.kt
@@ -0,0 +1,35 @@
+package moe.nea.firmament.features.chat
+
+import java.util.concurrent.ThreadLocalRandom
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.launch
+import kotlin.time.Duration.Companion.milliseconds
+import net.minecraft.text.Text
+import moe.nea.firmament.Firmament
+import moe.nea.firmament.annotations.Subscribe
+import moe.nea.firmament.events.ProcessChatEvent
+import moe.nea.firmament.features.fixes.CompatibliltyFeatures
+import moe.nea.firmament.util.FirmFormatters
+import moe.nea.firmament.util.MC
+import moe.nea.firmament.util.SBData
+import moe.nea.firmament.util.useMatch
+
+object AutoGGOnTapCube {
+
+ val regex = " *. STORE PURCHASE .".toPattern()
+
+ @Subscribe
+ fun onChat(event: ProcessChatEvent) {
+ if (!SBData.isTabCube) return
+ if (!CompatibliltyFeatures.TConfig.tapCube) return
+ regex.useMatch(event.unformattedString) {
+ val delay = ThreadLocalRandom.current().nextInt(500, 3000).milliseconds
+ MC.sendChat(Text.literal("Sending gg in ${FirmFormatters.formatTimespan(delay, true)}"))
+ Firmament.coroutineScope.launch {
+ delay(delay)
+ MC.sendServerChat("gg")
+ MC.sendChat(Text.literal("Mission accomplished. AutoGG out."))
+ }
+ }
+ }
+}
diff --git a/src/main/kotlin/features/fixes/CompatibliltyFeatures.kt b/src/main/kotlin/features/fixes/CompatibliltyFeatures.kt
index 7c43cf6..0b64b80 100644
--- a/src/main/kotlin/features/fixes/CompatibliltyFeatures.kt
+++ b/src/main/kotlin/features/fixes/CompatibliltyFeatures.kt
@@ -1,5 +1,3 @@
-
-
package moe.nea.firmament.features.fixes
import net.fabricmc.loader.api.FabricLoader
@@ -13,39 +11,40 @@ import moe.nea.firmament.gui.config.ManagedConfig
import moe.nea.firmament.util.MC
object CompatibliltyFeatures : FirmamentFeature {
- override val identifier: String
- get() = "compatibility"
-
- object TConfig : ManagedConfig(identifier) {
- val enhancedExplosions by toggle("explosion-enabled") { false }
- val explosionSize by integer("explosion-power", 10, 50) { 1 }
- }
-
- override val config: ManagedConfig?
- get() = TConfig
-
- interface ExplosiveApiWrapper {
- fun spawnParticle(vec3d: Vec3d, power: Float)
- }
-
- class ExplosiveApiWrapperImpl : ExplosiveApiWrapper {
- override fun spawnParticle(vec3d: Vec3d, power: Float) {
- ExplosiveApi.spawnParticles(MC.world, vec3d.x, vec3d.y, vec3d.z, TConfig.explosionSize / 10F)
- }
- }
-
- val explosiveApiWrapper = if (FabricLoader.getInstance().isModLoaded("explosiveenhancement")) {
- ExplosiveApiWrapperImpl()
- } else null
-
- @Subscribe
- fun onExplosion(it: ParticleSpawnEvent) {
- if (TConfig.enhancedExplosions &&
- it.particleEffect.type == ParticleTypes.EXPLOSION_EMITTER &&
- explosiveApiWrapper != null
- ) {
- it.cancel()
- explosiveApiWrapper.spawnParticle(it.position, 2F)
- }
- }
+ override val identifier: String
+ get() = "compatibility"
+
+ object TConfig : ManagedConfig(identifier) {
+ val enhancedExplosions by toggle("explosion-enabled") { false }
+ val explosionSize by integer("explosion-power", 10, 50) { 1 }
+ val tapCube by toggle("tapcube") { true }
+ }
+
+ override val config: ManagedConfig?
+ get() = TConfig
+
+ interface ExplosiveApiWrapper {
+ fun spawnParticle(vec3d: Vec3d, power: Float)
+ }
+
+ class ExplosiveApiWrapperImpl : ExplosiveApiWrapper {
+ override fun spawnParticle(vec3d: Vec3d, power: Float) {
+ ExplosiveApi.spawnParticles(MC.world, vec3d.x, vec3d.y, vec3d.z, TConfig.explosionSize / 10F)
+ }
+ }
+
+ val explosiveApiWrapper = if (FabricLoader.getInstance().isModLoaded("explosiveenhancement")) {
+ ExplosiveApiWrapperImpl()
+ } else null
+
+ @Subscribe
+ fun onExplosion(it: ParticleSpawnEvent) {
+ if (TConfig.enhancedExplosions &&
+ it.particleEffect.type == ParticleTypes.EXPLOSION_EMITTER &&
+ explosiveApiWrapper != null
+ ) {
+ it.cancel()
+ explosiveApiWrapper.spawnParticle(it.position, 2F)
+ }
+ }
}
diff --git a/src/main/kotlin/features/inventory/ItemRarityCosmetics.kt b/src/main/kotlin/features/inventory/ItemRarityCosmetics.kt
index 424f13b..cc2c003 100644
--- a/src/main/kotlin/features/inventory/ItemRarityCosmetics.kt
+++ b/src/main/kotlin/features/inventory/ItemRarityCosmetics.kt
@@ -1,5 +1,3 @@
-
-
package moe.nea.firmament.features.inventory
import java.awt.Color
@@ -11,74 +9,95 @@ import moe.nea.firmament.annotations.Subscribe
import moe.nea.firmament.events.HotbarItemRenderEvent
import moe.nea.firmament.events.SlotRenderEvents
import moe.nea.firmament.features.FirmamentFeature
+import moe.nea.firmament.features.fixes.CompatibliltyFeatures
import moe.nea.firmament.gui.config.ManagedConfig
import moe.nea.firmament.util.MC
-import moe.nea.firmament.util.mc.loreAccordingToNbt
+import moe.nea.firmament.util.SBData
import moe.nea.firmament.util.collections.lastNotNullOfOrNull
import moe.nea.firmament.util.collections.memoizeIdentity
+import moe.nea.firmament.util.mc.loreAccordingToNbt
import moe.nea.firmament.util.unformattedString
object ItemRarityCosmetics : FirmamentFeature {
- override val identifier: String
- get() = "item-rarity-cosmetics"
+ override val identifier: String
+ get() = "item-rarity-cosmetics"
+
+ object TConfig : ManagedConfig(identifier) {
+ val showItemRarityBackground by toggle("background") { false }
+ val showItemRarityInHotbar by toggle("background-hotbar") { false }
+ }
+
+ override val config: ManagedConfig
+ get() = TConfig
- object TConfig : ManagedConfig(identifier) {
- val showItemRarityBackground by toggle("background") { false }
- val showItemRarityInHotbar by toggle("background-hotbar") { false }
- }
+ private val rarityToColor = mapOf(
+ "UNCOMMON" to Formatting.GREEN,
+ "COMMON" to Formatting.WHITE,
+ "RARE" to Formatting.DARK_BLUE,
+ "EPIC" to Formatting.DARK_PURPLE,
+ "LEGENDARY" to Formatting.GOLD,
+ "LEGENJERRY" to Formatting.GOLD,
+ "MYTHIC" to Formatting.LIGHT_PURPLE,
+ "DIVINE" to Formatting.BLUE,
+ "SPECIAL" to Formatting.DARK_RED,
+ "SUPREME" to Formatting.DARK_RED,
+ ).mapValues {
+ val c = Color(it.value.colorValue!!)
+ Triple(c.red / 255F, c.green / 255F, c.blue / 255F)
+ }
- override val config: ManagedConfig
- get() = TConfig
+ private val tabCubeRarityToColor = mapOf(
+ "COMMON" to Color.WHITE,
+ "RELIC" to Color(255, 23, 130),
+ "BOSS DROP" to Color.YELLOW,
+ "MYTHIC" to Color.ORANGE,
+ "RARE" to Color.BLUE,
+ "UNCOMMON" to Color.GREEN,
+ "LEGENDARY" to Color(250, 240, 130),
+ "EPIC" to Color(180, 30, 180),
+ "ULTIMATE" to Color(255, 130, 0),
+ "ᴠᴏᴜᴄʜᴇʀ" to Color(80, 120, 255)
+ ).mapValues {
+ val c = it.value
+ Triple(c.red / 255F, c.green / 255F, c.blue / 255F)
+ }
- private val rarityToColor = mapOf(
- "UNCOMMON" to Formatting.GREEN,
- "COMMON" to Formatting.WHITE,
- "RARE" to Formatting.DARK_BLUE,
- "EPIC" to Formatting.DARK_PURPLE,
- "LEGENDARY" to Formatting.GOLD,
- "LEGENJERRY" to Formatting.GOLD,
- "MYTHIC" to Formatting.LIGHT_PURPLE,
- "DIVINE" to Formatting.BLUE,
- "SPECIAL" to Formatting.DARK_RED,
- "SUPREME" to Formatting.DARK_RED,
- ).mapValues {
- val c = Color(it.value.colorValue!!)
- Triple(c.red / 255F, c.green / 255F, c.blue / 255F)
- }
+ val currentRarities get() = if (CompatibliltyFeatures.TConfig.tapCube && SBData.isTabCube) tabCubeRarityToColor else rarityToColor
- private fun getSkyblockRarity0(itemStack: ItemStack): Triple<Float, Float, Float>? {
- return itemStack.loreAccordingToNbt.lastNotNullOfOrNull {
- val entry = it.unformattedString
- rarityToColor.entries.find { (k, v) -> k in entry }?.value
- }
- }
+ private fun getSkyblockRarity0(itemStack: ItemStack): Triple<Float, Float, Float>? {
+ return itemStack.loreAccordingToNbt.lastNotNullOfOrNull {
+ val entry = it.unformattedString
+ currentRarities.entries.find { (k, v) -> k in entry }?.value
+ }
+ }
- val getSkyblockRarity = ::getSkyblockRarity0.memoizeIdentity(100)
+ // TODO: replace with weak cache
+ val getSkyblockRarity = ::getSkyblockRarity0.memoizeIdentity(100)
- fun drawItemStackRarity(drawContext: DrawContext, x: Int, y: Int, item: ItemStack) {
- val (r, g, b) = getSkyblockRarity(item) ?: return
- drawContext.drawSprite(
- x, y,
- 0,
- 16, 16,
- MC.guiAtlasManager.getSprite(Identifier.of("firmament:item_rarity_background")),
- r, g, b, 1F
- )
- }
+ fun drawItemStackRarity(drawContext: DrawContext, x: Int, y: Int, item: ItemStack) {
+ val (r, g, b) = getSkyblockRarity(item) ?: return
+ drawContext.drawSprite(
+ x, y,
+ 0,
+ 16, 16,
+ MC.guiAtlasManager.getSprite(Identifier.of("firmament:item_rarity_background")),
+ r, g, b, 1F
+ )
+ }
- @Subscribe
- fun onRenderSlot(it: SlotRenderEvents.Before) {
- if (!TConfig.showItemRarityBackground) return
- val stack = it.slot.stack ?: return
- drawItemStackRarity(it.context, it.slot.x, it.slot.y, stack)
- }
+ @Subscribe
+ fun onRenderSlot(it: SlotRenderEvents.Before) {
+ if (!TConfig.showItemRarityBackground) return
+ val stack = it.slot.stack ?: return
+ drawItemStackRarity(it.context, it.slot.x, it.slot.y, stack)
+ }
- @Subscribe
- fun onRenderHotbarItem(it: HotbarItemRenderEvent) {
- if (!TConfig.showItemRarityInHotbar) return
- val stack = it.item
- drawItemStackRarity(it.context, it.x, it.y, stack)
- }
+ @Subscribe
+ fun onRenderHotbarItem(it: HotbarItemRenderEvent) {
+ if (!TConfig.showItemRarityInHotbar) return
+ val stack = it.item
+ drawItemStackRarity(it.context, it.x, it.y, stack)
+ }
}
diff --git a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt
index b615c73..9ad5636 100644
--- a/src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt
+++ b/src/main/kotlin/features/inventory/storageoverlay/StorageOverlay.kt
@@ -139,6 +139,7 @@ object StorageOverlay : FirmamentFeature {
data: SortedMap<StoragePageSlot, StorageData.StorageInventory>
) {
// TODO: FIXME: FIXME NOW: Definitely don't copy all of this every tick into persistence
+ // This should be easily doable now that inventory update event exists.
val newStacks =
VirtualInventory(handler.handler.stacks.take(handler.handler.rows * 9).drop(9).map { it.copy() })
data.compute(handler.storagePageSlot) { slot, existingInventory ->
diff --git a/src/main/kotlin/util/SBData.kt b/src/main/kotlin/util/SBData.kt
index 353bb06..8b3ad96 100644
--- a/src/main/kotlin/util/SBData.kt
+++ b/src/main/kotlin/util/SBData.kt
@@ -9,59 +9,62 @@ import moe.nea.firmament.events.AllowChatEvent
import moe.nea.firmament.events.ProcessChatEvent
import moe.nea.firmament.events.ServerConnectedEvent
import moe.nea.firmament.events.SkyblockServerUpdateEvent
-import moe.nea.firmament.events.WorldReadyEvent
object SBData {
- private val profileRegex = "Profile ID: ([a-z0-9\\-]+)".toRegex()
- val profileSuggestTexts = listOf(
- "CLICK THIS TO SUGGEST IT IN CHAT [DASHES]",
- "CLICK THIS TO SUGGEST IT IN CHAT [NO DASHES]",
- )
- var profileId: UUID? = null
+ private val profileRegex = "Profile ID: ([a-z0-9\\-]+)".toRegex()
+ val profileSuggestTexts = listOf(
+ "CLICK THIS TO SUGGEST IT IN CHAT [DASHES]",
+ "CLICK THIS TO SUGGEST IT IN CHAT [NO DASHES]",
+ )
+ var profileId: UUID? = null
+ val genericProfileId: String? get() = if (isTabCube) "tabcube-${MC.instance.session.uuidOrNull}" else profileId?.toString()
- private var hasReceivedProfile = false
- var locraw: Locraw? = null
- val skyblockLocation: SkyBlockIsland? get() = locraw?.skyblockLocation
- val hasValidLocraw get() = locraw?.server !in listOf("limbo", null)
- val isOnSkyblock get() = locraw?.gametype == "SKYBLOCK"
- var profileIdCommandDebounce = TimeMark.farPast()
- fun init() {
- ServerConnectedEvent.subscribe("SBData:onServerConnected") {
- HypixelModAPI.getInstance().subscribeToEventPacket(ClientboundLocationPacket::class.java)
- }
- HypixelModAPI.getInstance().createHandler(ClientboundLocationPacket::class.java) {
- MC.onMainThread {
- val lastLocraw = locraw
- locraw = Locraw(it.serverName,
- it.serverType.getOrNull()?.name?.uppercase(),
- it.mode.getOrNull(),
- it.map.getOrNull())
- SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, null))
- profileIdCommandDebounce = TimeMark.now()
- }
- }
- SkyblockServerUpdateEvent.subscribe("SBData:sendProfileId") {
- if (!hasReceivedProfile && isOnSkyblock && profileIdCommandDebounce.passedTime() > 10.seconds) {
- profileIdCommandDebounce = TimeMark.now()
- MC.sendServerCommand("profileid")
- }
- }
- AllowChatEvent.subscribe("SBData:hideProfileSuggest") { event ->
- if (event.unformattedString in profileSuggestTexts && profileIdCommandDebounce.passedTime() < 5.seconds) {
- event.cancel()
- }
- }
- ProcessChatEvent.subscribe(receivesCancelled = true, "SBData:loadProfile") { event ->
- val profileMatch = profileRegex.matchEntire(event.unformattedString)
- if (profileMatch != null) {
- try {
- profileId = UUID.fromString(profileMatch.groupValues[1])
- hasReceivedProfile = true
- } catch (e: IllegalArgumentException) {
- profileId = null
- e.printStackTrace()
- }
- }
- }
- }
+ private var hasReceivedProfile = false
+ var locraw: Locraw? = null
+ val skyblockLocation: SkyBlockIsland? get() = locraw?.skyblockLocation
+ val hasValidLocraw get() = locraw?.server !in listOf("limbo", null)
+ val isOnSkyblock get() = locraw?.gametype == "SKYBLOCK"
+ var profileIdCommandDebounce = TimeMark.farPast()
+ val connectionAddress: String? get() = MC.networkHandler?.serverInfo?.address
+ val isTabCube get() = connectionAddress == "tapcube.minehut.gg"
+
+ fun init() {
+ ServerConnectedEvent.subscribe("SBData:onServerConnected") {
+ HypixelModAPI.getInstance().subscribeToEventPacket(ClientboundLocationPacket::class.java)
+ }
+ HypixelModAPI.getInstance().createHandler(ClientboundLocationPacket::class.java) {
+ MC.onMainThread {
+ val lastLocraw = locraw
+ locraw = Locraw(it.serverName,
+ it.serverType.getOrNull()?.name?.uppercase(),
+ it.mode.getOrNull(),
+ it.map.getOrNull())
+ SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, null))
+ profileIdCommandDebounce = TimeMark.now()
+ }
+ }
+ SkyblockServerUpdateEvent.subscribe("SBData:sendProfileId") {
+ if (!hasReceivedProfile && isOnSkyblock && profileIdCommandDebounce.passedTime() > 10.seconds) {
+ profileIdCommandDebounce = TimeMark.now()
+ MC.sendServerCommand("profileid")
+ }
+ }
+ AllowChatEvent.subscribe("SBData:hideProfileSuggest") { event ->
+ if (event.unformattedString in profileSuggestTexts && profileIdCommandDebounce.passedTime() < 5.seconds) {
+ event.cancel()
+ }
+ }
+ ProcessChatEvent.subscribe(receivesCancelled = true, "SBData:loadProfile") { event ->
+ val profileMatch = profileRegex.matchEntire(event.unformattedString)
+ if (profileMatch != null) {
+ try {
+ profileId = UUID.fromString(profileMatch.groupValues[1])
+ hasReceivedProfile = true
+ } catch (e: IllegalArgumentException) {
+ profileId = null
+ e.printStackTrace()
+ }
+ }
+ }
+ }
}
diff --git a/src/main/kotlin/util/data/ProfileSpecificDataHolder.kt b/src/main/kotlin/util/data/ProfileSpecificDataHolder.kt
index 1cd4f22..2566e4c 100644
--- a/src/main/kotlin/util/data/ProfileSpecificDataHolder.kt
+++ b/src/main/kotlin/util/data/ProfileSpecificDataHolder.kt
@@ -22,10 +22,10 @@ abstract class ProfileSpecificDataHolder<S>(
private val configDefault: () -> S
) : IDataHolder<S?> {
- var allConfigs: MutableMap<UUID, S>
+ var allConfigs: MutableMap<String, S>
override val data: S?
- get() = SBData.profileId?.let {
+ get() = SBData.genericProfileId?.let {
allConfigs.computeIfAbsent(it) { configDefault() }
}
@@ -36,7 +36,7 @@ abstract class ProfileSpecificDataHolder<S>(
private val configDirectory: Path get() = Firmament.CONFIG_DIR.resolve("profiles").resolve(configName)
- private fun readValues(): MutableMap<UUID, S> {
+ private fun readValues(): MutableMap<String, S> {
if (!configDirectory.exists()) {
configDirectory.createDirectories()
}
@@ -45,7 +45,7 @@ abstract class ProfileSpecificDataHolder<S>(
.filter { it.extension == "json" }
.mapNotNull {
try {
- UUID.fromString(it.nameWithoutExtension) to Firmament.json.decodeFromString(dataSerializer, it.readText())
+ (it.nameWithoutExtension) to Firmament.json.decodeFromString(dataSerializer, it.readText())
} catch (e: Exception) { /* Expecting IOException and SerializationException, but Kotlin doesn't allow multi catches*/
IDataHolder.badLoads.add(configName)
Firmament.logger.error(
diff --git a/src/main/resources/assets/firmament/lang/en_us.json b/src/main/resources/assets/firmament/lang/en_us.json
index bc2838b..68c30f9 100644
--- a/src/main/resources/assets/firmament/lang/en_us.json
+++ b/src/main/resources/assets/firmament/lang/en_us.json
@@ -194,6 +194,7 @@
"firmament.tooltip.copied.nbt": "Copied NBT data",
"firmament.config.compatibility": "Intermod Features",
"firmament.config.compatibility.explosion-enabled": "Redirect Enhanced Explosions",
+ "firmament.config.compatibility.tapcube": "Add TapCube features",
"firmament.config.compatibility.explosion-power": "Enhanced Explosion Power",
"firmament.quick-commands.join.unknown": "Could not find instance for %s",
"firmament.quick-commands.join.success": "Joining: %s",