aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/io
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/io')
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/EnforcedConfigValues.kt123
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt3
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt2
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/PetLeveling.kt2
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/Shimmy.kt85
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/hypixelapi/Collection.kt159
-rw-r--r--src/main/kotlin/io/github/moulberry/notenoughupdates/util/kotlin/gson.kt33
7 files changed, 406 insertions, 1 deletions
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/EnforcedConfigValues.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/EnforcedConfigValues.kt
new file mode 100644
index 00000000..7351a4a0
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/EnforcedConfigValues.kt
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2022 Linnea Gräf
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.miscfeatures
+
+import com.google.gson.JsonElement
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
+import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent
+import io.github.moulberry.notenoughupdates.util.NotificationHandler
+import io.github.moulberry.notenoughupdates.util.Shimmy
+import io.github.moulberry.notenoughupdates.util.Utils
+import io.github.moulberry.notenoughupdates.util.kotlin.fromJson
+import net.minecraft.client.Minecraft
+import net.minecraftforge.client.event.GuiOpenEvent
+import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import net.minecraftforge.fml.common.gameevent.TickEvent
+
+@NEUAutoSubscribe
+object EnforcedConfigValues {
+
+ class EnforcedValue {
+ // lateinit var because we use gson (instead of kotlinx.serialization which can handle data classes)
+ lateinit var path: String
+ lateinit var value: JsonElement
+ }
+
+ class EnforcedValueData {
+ var enforcedValues: List<EnforcedValue> = listOf()
+ var notificationPSA: List<String>? = null
+ var chatPSA: List<String>? = null
+ lateinit var affectedVersions: List<Int>
+ }
+
+
+ var enforcedValues: List<EnforcedValueData> = listOf()
+
+ @SubscribeEvent
+ fun onRepoReload(event: RepositoryReloadEvent) {
+ val fixedValues = event.repositoryRoot.resolve("enforced_values")
+ enforcedValues = if (fixedValues.exists()) {
+ fixedValues.listFiles()
+ .filter {
+ it != null && it.isFile && it.canRead()
+ }
+ .map {
+ NotEnoughUpdates.INSTANCE.manager.gson.fromJson<EnforcedValueData>(it.readText())
+ }.filter {
+ NotEnoughUpdates.VERSION_ID in it.affectedVersions
+ }
+ } else {
+ listOf()
+ }
+ if (!event.isFirstLoad)
+ sendPSAs()
+ }
+
+ @SubscribeEvent
+ fun onGuiClose(event: GuiOpenEvent) {
+ enforceOntoConfig(NotEnoughUpdates.INSTANCE.config ?: return)
+ }
+
+ var hasSentPSAsOnce = false
+
+ @SubscribeEvent
+ fun onTick(tickEvent: TickEvent.ClientTickEvent) {
+ if (hasSentPSAsOnce || Minecraft.getMinecraft().thePlayer == null || !NotEnoughUpdates.INSTANCE.isOnSkyblock) return
+ hasSentPSAsOnce = true
+ sendPSAs()
+ enforceOntoConfig(NotEnoughUpdates.INSTANCE.config ?: return)
+ }
+
+ fun sendPSAs() {
+ val notification = enforcedValues.flatMap { it.notificationPSA ?: emptyList() }
+ if (notification.isNotEmpty()) {
+ NotificationHandler.displayNotification(notification, true)
+ }
+ val chat = enforcedValues.flatMap { it.chatPSA ?: emptyList() }
+ if (chat.isNotEmpty()) {
+ for (line in chat) {
+ Utils.addChatMessage(line)
+ }
+ }
+ }
+
+
+ fun enforceOntoConfig(config: Any) {
+ for (enforcedValue in enforcedValues.flatMap { it.enforcedValues }) {
+ val shimmy = Shimmy.makeShimmy(config, enforcedValue.path.split("."))
+ if (shimmy == null) {
+ println("Could not create shimmy for path ${enforcedValue.path}")
+ continue
+ }
+ val currentValue = shimmy.getJson()
+ if (currentValue != enforcedValue.value) {
+ println("Resetting ${enforcedValue.path} to ${enforcedValue.value} from $currentValue")
+ shimmy.setJson(enforcedValue.value)
+ }
+ }
+ }
+
+ fun isBlockedFromEditing(optionPath: String): Boolean {
+ return enforcedValues.flatMap { it.enforcedValues }.any { it.path == optionPath }
+ }
+
+
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt
index 7485f14d..ccaf5ad8 100644
--- a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumCheapestItemOverlay.kt
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures.inventory
import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
import io.github.moulberry.notenoughupdates.core.util.ArrowPagesUtils
import io.github.moulberry.notenoughupdates.mixins.AccessorGuiContainer
import io.github.moulberry.notenoughupdates.util.MuseumUtil
@@ -39,7 +40,7 @@ import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import org.lwjgl.input.Mouse
import org.lwjgl.opengl.GL11
-
+@NEUAutoSubscribe
object MuseumCheapestItemOverlay {
data class MuseumItem(
var name: String,
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt
index b809ee9f..945449ba 100644
--- a/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/miscfeatures/inventory/MuseumItemHighlighter.kt
@@ -20,6 +20,7 @@
package io.github.moulberry.notenoughupdates.miscfeatures.inventory
import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
import io.github.moulberry.notenoughupdates.core.ChromaColour
import io.github.moulberry.notenoughupdates.core.util.StringUtils
import io.github.moulberry.notenoughupdates.events.GuiContainerBackgroundDrawnEvent
@@ -37,6 +38,7 @@ import net.minecraft.item.EnumDyeColor
import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+@NEUAutoSubscribe
object MuseumItemHighlighter {
private val manager get() = NotEnoughUpdates.INSTANCE.manager
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/PetLeveling.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/PetLeveling.kt
index 200aa3fa..99066e52 100644
--- a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/PetLeveling.kt
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/PetLeveling.kt
@@ -23,7 +23,9 @@ import com.google.gson.JsonObject
import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent
import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay.Rarity
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+import io.github.moulberry.notenoughupdates.autosubscribe.NEUAutoSubscribe
+@NEUAutoSubscribe
object PetLeveling {
data class ExpLadder(
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/Shimmy.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/Shimmy.kt
new file mode 100644
index 00000000..37cdd3ac
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/Shimmy.kt
@@ -0,0 +1,85 @@
+/*
+ * Copyright (C) 2022 Linnea Gräf
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util
+
+import com.google.gson.Gson
+import com.google.gson.JsonElement
+import java.lang.reflect.Field
+
+class Shimmy private constructor(
+ val source: Any,
+ val field: Field,
+) {
+ companion object {
+ val gson = Gson()
+ private fun shimmy(source: Any?, fieldName: String): Any? {
+ if (source == null) return null
+ return try {
+ val declaredField = source.javaClass.getDeclaredField(fieldName)
+ declaredField.isAccessible = true
+ declaredField.get(source)
+ } catch (e: NoSuchFieldException) {
+ null
+ }
+ }
+
+ @JvmStatic
+ fun makeShimmy(source: Any?, path: List<String>): Shimmy? {
+ if (path.isEmpty())
+ return null
+ var source = source
+ for (part in path.dropLast(1)) {
+ source = shimmy(source, part)
+ }
+ if (source == null) return null
+ val lastName = path.last()
+ return try {
+ val field = source.javaClass.getDeclaredField(lastName)
+ field.isAccessible = true
+ Shimmy(
+ source,
+ field,
+ )
+ } catch (e: NoSuchFieldException) {
+ null
+ }
+ }
+
+ }
+
+ val clazz: Class<*> = field.type
+ fun get(): Any? {
+ return field.get(source)
+ }
+
+ fun set(value: Any?) {
+ field.set(source, value)
+ }
+
+ fun getJson(): JsonElement {
+ return gson.toJsonTree(get())
+ }
+
+ fun setJson(element: JsonElement) {
+ set(gson.fromJson(element, clazz))
+ }
+
+
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/hypixelapi/Collection.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/hypixelapi/Collection.kt
new file mode 100644
index 00000000..b2c7fcec
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/hypixelapi/Collection.kt
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2023 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util.hypixelapi
+
+import com.google.gson.JsonArray
+import com.google.gson.JsonObject
+import io.github.moulberry.notenoughupdates.NotEnoughUpdates
+import java.math.BigInteger
+import java.util.concurrent.CompletableFuture
+import kotlin.collections.List
+import kotlin.collections.Map
+import kotlin.collections.component1
+import kotlin.collections.component2
+import kotlin.collections.filter
+import kotlin.collections.flatMap
+import kotlin.collections.groupBy
+import kotlin.collections.mapNotNull
+import kotlin.collections.mapValues
+import kotlin.collections.maxOf
+import kotlin.collections.sumOf
+import kotlin.collections.toList
+import kotlin.collections.toMap
+import kotlin.collections.toSet
+
+data class ProfileCollectionInfo(
+ val collections: Map<String, CollectionInfo>,
+ val craftedGenerators: Map<String, Int>,
+) {
+ data class CollectionInfo(
+ val collection: Collection,
+ val totalCollectionCount: BigInteger,
+ val personalCollectionCount: BigInteger,
+ val unlockedTiers: List<CollectionTier>,
+ )
+
+ class CollectionMetadata internal constructor() {
+ lateinit var collections: Map<String, CollectionCategory>
+ private set
+ val allCollections by lazy { collections.values.flatMap { it.items.toList() }.toMap() }
+ }
+
+ class CollectionCategory internal constructor() {
+ lateinit var items: Map<String, Collection>
+ private set
+ }
+
+ class Collection internal constructor() {
+ lateinit var name: String
+ private set
+ var maxTiers: Int = -1
+ private set
+ lateinit var tiers: List<CollectionTier>
+ private set
+
+ override fun toString(): String {
+ return "Collection(name=$name, maxTiers=$maxTiers, tiers=$tiers)"
+ }
+ }
+
+ class CollectionTier internal constructor() {
+ var tier: Int = -1
+ private set
+ var amountRequired: Int = -1
+ private set
+ lateinit var unlocks: List<String>
+ private set
+
+ override fun toString(): String {
+ return "CollectionTier(tier=$tier, amountRequired=$amountRequired, unlocks=$unlocks)"
+ }
+ }
+
+
+ companion object {
+
+
+ val generatorPattern = "^([^0-9]+)_([0-9]+)$".toRegex()
+
+ val hypixelCollectionInfo: CompletableFuture<CollectionMetadata> by lazy {
+ NotEnoughUpdates.INSTANCE.manager.apiUtils
+ .newHypixelApiRequest("resources/skyblock/collections")
+ .requestJson()
+ .thenApply {
+ NotEnoughUpdates.INSTANCE.manager.gson.fromJson(it, CollectionMetadata::class.java)
+ }
+ }
+
+ fun getCollectionData(
+ profileData: JsonObject,
+ mainPlayer: String,
+ collectionData: CollectionMetadata
+ ): ProfileCollectionInfo? {
+ val mainPlayerUUID = mainPlayer.replace("-", "")
+ val members = profileData["members"] as? JsonObject ?: return null
+ val mainPlayerData =
+ (members[mainPlayerUUID] as? JsonObject ?: return null)
+ val mainPlayerCollection = mainPlayerData["collection"] as? JsonObject ?: return null
+ val memberCollections = members.entrySet().mapNotNull { (uuid, data) ->
+ if (data !is JsonObject) return null
+ data["collection"] as? JsonObject
+ }
+ val generators = members.entrySet().mapNotNull { (uuid, data) ->
+ if (data !is JsonObject) return null
+ data["crafted_generators"] as? JsonArray
+ }.flatMap { it.toList() }
+ return ProfileCollectionInfo(
+ collectionData.allCollections.mapValues { (name, collection) ->
+ val totalCollection = memberCollections.sumOf { it[name]?.asBigInteger ?: BigInteger.ZERO }
+ val personalCollection = mainPlayerCollection[name]?.asBigInteger ?: BigInteger.ZERO
+ CollectionInfo(
+ collection,
+ totalCollection,
+ personalCollection,
+ collection.tiers.filter { BigInteger.valueOf(it.amountRequired.toLong()) <= totalCollection }
+ )
+ },
+ generators.toSet()
+ .mapNotNull {
+ val pattern = generatorPattern.matchEntire(it.asString) ?: return@mapNotNull null
+ pattern.groupValues[1] to pattern.groupValues[2].toInt()
+ }
+ .groupBy { it.first }
+ .mapValues {
+ it.value.maxOf { it.second }
+ }
+ .toMap()
+ )
+ }
+
+ /**
+ * This should be the json object returned by /skyblock/profiles at profiles.<somenumber>. (aka the root tag
+ * should contain profile_id, members, cute_name, etc.)
+ */
+ @JvmStatic
+ fun getCollectionData(profileData: JsonObject, mainPlayer: String): CompletableFuture<ProfileCollectionInfo?> {
+ return hypixelCollectionInfo.thenApply {
+ getCollectionData(profileData, mainPlayer, it)
+ }
+ }
+ }
+
+}
diff --git a/src/main/kotlin/io/github/moulberry/notenoughupdates/util/kotlin/gson.kt b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/kotlin/gson.kt
new file mode 100644
index 00000000..00c3d729
--- /dev/null
+++ b/src/main/kotlin/io/github/moulberry/notenoughupdates/util/kotlin/gson.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2022 NotEnoughUpdates contributors
+ *
+ * This file is part of NotEnoughUpdates.
+ *
+ * NotEnoughUpdates is free software: you can redistribute it
+ * and/or modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation, either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * NotEnoughUpdates is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with NotEnoughUpdates. If not, see <https://www.gnu.org/licenses/>.
+ */
+
+package io.github.moulberry.notenoughupdates.util.kotlin
+
+import com.google.gson.Gson
+import com.google.gson.reflect.TypeToken
+import java.lang.reflect.Type
+
+
+inline fun <reified T : Any> typeToken(): Type {
+ return (object : TypeToken<T>() {}).type
+}
+
+inline fun <reified T : Any> Gson.fromJson(string: String): T {
+ return fromJson(string, typeToken<T>())
+}