diff options
Diffstat (limited to 'src/main/kotlin/moe/nea/firmament/util')
62 files changed, 0 insertions, 3138 deletions
diff --git a/src/main/kotlin/moe/nea/firmament/util/Base64Util.kt b/src/main/kotlin/moe/nea/firmament/util/Base64Util.kt deleted file mode 100644 index 44bcdfd..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/Base64Util.kt +++ /dev/null @@ -1,10 +0,0 @@ - -package moe.nea.firmament.util - -object Base64Util { - fun String.padToValidBase64(): String { - val align = this.length % 4 - if (align == 0) return this - return this + "=".repeat(4 - align) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/BazaarPriceStrategy.kt b/src/main/kotlin/moe/nea/firmament/util/BazaarPriceStrategy.kt deleted file mode 100644 index 002eedb..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/BazaarPriceStrategy.kt +++ /dev/null @@ -1,19 +0,0 @@ - -package moe.nea.firmament.util - -import moe.nea.firmament.repo.HypixelStaticData - -enum class BazaarPriceStrategy { - BUY_ORDER, - SELL_ORDER, - NPC_SELL; - - fun getSellPrice(skyblockId: SkyblockId): Double { - val bazaarEntry = HypixelStaticData.bazaarData[skyblockId] ?: return 0.0 - return when (this) { - BUY_ORDER -> bazaarEntry.quickStatus.sellPrice - SELL_ORDER -> bazaarEntry.quickStatus.buyPrice - NPC_SELL -> TODO() - } - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/ClipboardUtils.kt b/src/main/kotlin/moe/nea/firmament/util/ClipboardUtils.kt deleted file mode 100644 index 7b9b836..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/ClipboardUtils.kt +++ /dev/null @@ -1,24 +0,0 @@ - - -package moe.nea.firmament.util - -import moe.nea.firmament.Firmament - -object ClipboardUtils { - fun setTextContent(string: String) { - try { - MC.keyboard.clipboard = string.ifEmpty { " " } - } catch (e: Exception) { - Firmament.logger.error("Could not write clipboard", e) - } - } - - fun getTextContents(): String { - try { - return MC.keyboard.clipboard ?: "" - } catch (e: Exception) { - Firmament.logger.error("Could not read clipboard", e) - return "" - } - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/CommonSoundEffects.kt b/src/main/kotlin/moe/nea/firmament/util/CommonSoundEffects.kt deleted file mode 100644 index a97a2cb..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/CommonSoundEffects.kt +++ /dev/null @@ -1,26 +0,0 @@ - - -package moe.nea.firmament.util - -import net.minecraft.client.sound.PositionedSoundInstance -import net.minecraft.sound.SoundEvent -import net.minecraft.util.Identifier - -// TODO: Replace these with custom sound events that just re use the vanilla ogg s -object CommonSoundEffects { - fun playSound(identifier: Identifier) { - MC.soundManager.play(PositionedSoundInstance.master(SoundEvent.of(identifier), 1F)) - } - - fun playFailure() { - playSound(Identifier.of("minecraft", "block.anvil.place")) - } - - fun playSuccess() { - playDing() - } - - fun playDing() { - playSound(Identifier.of("minecraft", "entity.arrow.hit_player")) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/DurabilityBarEvent.kt b/src/main/kotlin/moe/nea/firmament/util/DurabilityBarEvent.kt deleted file mode 100644 index 993462c..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/DurabilityBarEvent.kt +++ /dev/null @@ -1,20 +0,0 @@ - -package moe.nea.firmament.util - -import me.shedaniel.math.Color -import net.minecraft.item.ItemStack -import moe.nea.firmament.events.FirmamentEvent -import moe.nea.firmament.events.FirmamentEventBus - -data class DurabilityBarEvent( - val item: ItemStack, -) : FirmamentEvent() { - data class DurabilityBar( - val color: Color, - val percentage: Float, - ) - - var barOverride: DurabilityBar? = null - - companion object : FirmamentEventBus<DurabilityBarEvent>() -} diff --git a/src/main/kotlin/moe/nea/firmament/util/ErrorBoundary.kt b/src/main/kotlin/moe/nea/firmament/util/ErrorBoundary.kt deleted file mode 100644 index fbc5b37..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/ErrorBoundary.kt +++ /dev/null @@ -1,10 +0,0 @@ - - -package moe.nea.firmament.util - - -fun <T> errorBoundary(block: () -> T): T? { - // TODO: implement a proper error boundary here to avoid crashing minecraft code - return block() -} - diff --git a/src/main/kotlin/moe/nea/firmament/util/FirmFormatters.kt b/src/main/kotlin/moe/nea/firmament/util/FirmFormatters.kt deleted file mode 100644 index c3bdd16..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/FirmFormatters.kt +++ /dev/null @@ -1,59 +0,0 @@ - - -package moe.nea.firmament.util - -import com.google.common.math.IntMath.pow -import kotlin.math.absoluteValue -import kotlin.time.Duration - -object FirmFormatters { - fun formatCommas(int: Int, segments: Int = 3): String = formatCommas(int.toLong(), segments) - fun formatCommas(long: Long, segments: Int = 3): String { - val α = long / 1000 - if (α != 0L) { - return formatCommas(α, segments) + "," + (long - α * 1000).toString().padStart(3, '0') - } - return long.toString() - } - - fun formatCommas(float: Float, fractionalDigits: Int): String = formatCommas(float.toDouble(), fractionalDigits) - fun formatCommas(double: Double, fractionalDigits: Int): String { - val long = double.toLong() - val δ = (double - long).absoluteValue - val μ = pow(10, fractionalDigits) - val digits = (μ * δ).toInt().toString().padStart(fractionalDigits, '0').trimEnd('0') - return formatCommas(long) + (if (digits.isEmpty()) "" else ".$digits") - } - - fun formatDistance(distance: Double): String { - if (distance < 10) - return "%.1fm".format(distance) - return "%dm".format(distance.toInt()) - } - - fun formatTimespan(duration: Duration, millis: Boolean = false): String { - if (duration.isInfinite()) { - return if (duration.isPositive()) "∞" - else "-∞" - } - val sb = StringBuilder() - if (duration.isNegative()) sb.append("-") - duration.toComponents { days, hours, minutes, seconds, nanoseconds -> - if (days > 0) { - sb.append(days).append("d") - } - if (hours > 0) { - sb.append(hours).append("h") - } - if (minutes > 0) { - sb.append(minutes).append("m") - } - sb.append(seconds).append("s") - if (millis) { - sb.append(nanoseconds / 1_000_000).append("ms") - } - } - return sb.toString() - } - -} diff --git a/src/main/kotlin/moe/nea/firmament/util/FragmentGuiScreen.kt b/src/main/kotlin/moe/nea/firmament/util/FragmentGuiScreen.kt deleted file mode 100644 index 5e13d51..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/FragmentGuiScreen.kt +++ /dev/null @@ -1,93 +0,0 @@ - - -package moe.nea.firmament.util - -import io.github.notenoughupdates.moulconfig.gui.GuiContext -import me.shedaniel.math.Dimension -import me.shedaniel.math.Point -import me.shedaniel.math.Rectangle -import net.minecraft.client.gui.DrawContext -import net.minecraft.client.gui.screen.Screen -import net.minecraft.text.Text - -abstract class FragmentGuiScreen( - val dismissOnOutOfBounds: Boolean = true -) : Screen(Text.literal("")) { - var popup: MoulConfigFragment? = null - - fun createPopup(context: GuiContext, position: Point) { - popup = MoulConfigFragment(context, position) { popup = null } - } - - override fun render(context: DrawContext, mouseX: Int, mouseY: Int, delta: Float) { - super.render(context, mouseX, mouseY, delta) - context.matrices.push() - context.matrices.translate(0f, 0f, 1000f) - popup?.render(context, mouseX, mouseY, delta) - context.matrices.pop() - } - - private inline fun ifPopup(ifYes: (MoulConfigFragment) -> Unit): Boolean { - val p = popup ?: return false - ifYes(p) - return true - } - - override fun keyPressed(keyCode: Int, scanCode: Int, modifiers: Int): Boolean { - return ifPopup { - it.keyPressed(keyCode, scanCode, modifiers) - } - } - - override fun keyReleased(keyCode: Int, scanCode: Int, modifiers: Int): Boolean { - return ifPopup { - it.keyReleased(keyCode, scanCode, modifiers) - } - } - - override fun mouseMoved(mouseX: Double, mouseY: Double) { - ifPopup { it.mouseMoved(mouseX, mouseY) } - } - - override fun mouseReleased(mouseX: Double, mouseY: Double, button: Int): Boolean { - return ifPopup { - it.mouseReleased(mouseX, mouseY, button) - } - } - - override fun mouseDragged(mouseX: Double, mouseY: Double, button: Int, deltaX: Double, deltaY: Double): Boolean { - return ifPopup { - it.mouseDragged(mouseX, mouseY, button, deltaX, deltaY) - } - } - - override fun mouseClicked(mouseX: Double, mouseY: Double, button: Int): Boolean { - return ifPopup { - if (!Rectangle( - it.position, - Dimension(it.context.root.width, it.context.root.height) - ).contains(Point(mouseX, mouseY)) - && dismissOnOutOfBounds - ) { - popup = null - } else { - it.mouseClicked(mouseX, mouseY, button) - } - }|| super.mouseClicked(mouseX, mouseY, button) - } - - override fun charTyped(chr: Char, modifiers: Int): Boolean { - return ifPopup { it.charTyped(chr, modifiers) } - } - - override fun mouseScrolled( - mouseX: Double, - mouseY: Double, - horizontalAmount: Double, - verticalAmount: Double - ): Boolean { - return ifPopup { - it.mouseScrolled(mouseX, mouseY, horizontalAmount, verticalAmount) - } - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/GetRectangle.kt b/src/main/kotlin/moe/nea/firmament/util/GetRectangle.kt deleted file mode 100644 index ec64f31..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/GetRectangle.kt +++ /dev/null @@ -1,17 +0,0 @@ - - -package moe.nea.firmament.util - -import me.shedaniel.math.Rectangle -import moe.nea.firmament.mixins.accessor.AccessorHandledScreen -import net.minecraft.client.gui.screen.ingame.HandledScreen - -fun HandledScreen<*>.getRectangle(): Rectangle { - this as AccessorHandledScreen - return Rectangle( - getX_Firmament(), - getY_Firmament(), - getBackgroundWidth_Firmament(), - getBackgroundHeight_Firmament() - ) -} diff --git a/src/main/kotlin/moe/nea/firmament/util/HoveredItemStack.kt b/src/main/kotlin/moe/nea/firmament/util/HoveredItemStack.kt deleted file mode 100644 index 47a59d0..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/HoveredItemStack.kt +++ /dev/null @@ -1,31 +0,0 @@ - - -package moe.nea.firmament.util - -import me.shedaniel.math.impl.PointHelper -import me.shedaniel.rei.api.client.REIRuntime -import me.shedaniel.rei.api.client.gui.widgets.Slot -import me.shedaniel.rei.api.client.registry.screen.ScreenRegistry -import net.minecraft.client.gui.Element -import net.minecraft.client.gui.ParentElement -import net.minecraft.client.gui.screen.ingame.HandledScreen -import net.minecraft.item.ItemStack -import moe.nea.firmament.mixins.accessor.AccessorHandledScreen - - -val HandledScreen<*>.focusedItemStack: ItemStack? - get() { - this as AccessorHandledScreen - val vanillaSlot = this.focusedSlot_Firmament?.stack - if (vanillaSlot != null) return vanillaSlot - val focusedSlot = ScreenRegistry.getInstance().getFocusedStack(this, PointHelper.ofMouse()) - if (focusedSlot != null) return focusedSlot.cheatsAs().value - var baseElement: Element? = REIRuntime.getInstance().overlay.orElse(null) - val mx = PointHelper.getMouseFloatingX() - val my = PointHelper.getMouseFloatingY() - while (true) { - if (baseElement is Slot) return baseElement.currentEntry.cheatsAs().value - if (baseElement !is ParentElement) return null - baseElement = baseElement.hoveredElement(mx, my).orElse(null) - } - } diff --git a/src/main/kotlin/moe/nea/firmament/util/IdentifierSerializer.kt b/src/main/kotlin/moe/nea/firmament/util/IdentifierSerializer.kt deleted file mode 100644 index 65c5b1c..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/IdentifierSerializer.kt +++ /dev/null @@ -1,25 +0,0 @@ - -package moe.nea.firmament.util - -import kotlinx.serialization.KSerializer -import kotlinx.serialization.builtins.serializer -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder -import net.minecraft.util.Identifier - -object IdentifierSerializer : KSerializer<Identifier> { - val delegateSerializer = String.serializer() - override val descriptor: SerialDescriptor - get() = PrimitiveSerialDescriptor("Identifier", PrimitiveKind.STRING) - - override fun deserialize(decoder: Decoder): Identifier { - return Identifier.of(decoder.decodeSerializableValue(delegateSerializer)) - } - - override fun serialize(encoder: Encoder, value: Identifier) { - encoder.encodeSerializableValue(delegateSerializer, value.toString()) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/IdentityCharacteristics.kt b/src/main/kotlin/moe/nea/firmament/util/IdentityCharacteristics.kt deleted file mode 100644 index f6054c4..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/IdentityCharacteristics.kt +++ /dev/null @@ -1,15 +0,0 @@ - - -package moe.nea.firmament.util - -class IdentityCharacteristics<T>(val value: T) { - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (other !is IdentityCharacteristics<*>) return false - return value === other.value - } - - override fun hashCode(): Int { - return System.identityHashCode(value) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/ItemUtil.kt b/src/main/kotlin/moe/nea/firmament/util/ItemUtil.kt deleted file mode 100644 index 40d6198..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/ItemUtil.kt +++ /dev/null @@ -1,26 +0,0 @@ - - -package moe.nea.firmament.util - -import net.minecraft.item.ItemStack -import net.minecraft.nbt.NbtCompound -import net.minecraft.nbt.NbtList -import net.minecraft.text.Text -import moe.nea.firmament.util.item.loreAccordingToNbt - - -fun ItemStack.appendLore(args: List<Text>) { - if (args.isEmpty()) return - modifyLore { - val loreList = loreAccordingToNbt.toMutableList() - for (arg in args) { - loreList.add(arg) - } - loreList - } -} - -fun ItemStack.modifyLore(update: (List<Text>) -> List<Text>) { - val loreList = loreAccordingToNbt - loreAccordingToNbt = update(loreList) -} diff --git a/src/main/kotlin/moe/nea/firmament/util/LegacyFormattingCode.kt b/src/main/kotlin/moe/nea/firmament/util/LegacyFormattingCode.kt deleted file mode 100644 index 44bacfc..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/LegacyFormattingCode.kt +++ /dev/null @@ -1,35 +0,0 @@ - - -package moe.nea.firmament.util - -import net.minecraft.util.Formatting - -enum class LegacyFormattingCode(val label: String, val char: Char, val index: Int) { - BLACK("BLACK", '0', 0), - DARK_BLUE("DARK_BLUE", '1', 1), - DARK_GREEN("DARK_GREEN", '2', 2), - DARK_AQUA("DARK_AQUA", '3', 3), - DARK_RED("DARK_RED", '4', 4), - DARK_PURPLE("DARK_PURPLE", '5', 5), - GOLD("GOLD", '6', 6), - GRAY("GRAY", '7', 7), - DARK_GRAY("DARK_GRAY", '8', 8), - BLUE("BLUE", '9', 9), - GREEN("GREEN", 'a', 10), - AQUA("AQUA", 'b', 11), - RED("RED", 'c', 12), - LIGHT_PURPLE("LIGHT_PURPLE", 'd', 13), - YELLOW("YELLOW", 'e', 14), - WHITE("WHITE", 'f', 15), - OBFUSCATED("OBFUSCATED", 'k', -1), - BOLD("BOLD", 'l', -1), - STRIKETHROUGH("STRIKETHROUGH", 'm', -1), - UNDERLINE("UNDERLINE", 'n', -1), - ITALIC("ITALIC", 'o', -1), - RESET("RESET", 'r', -1); - - val modern = Formatting.byCode(char)!! - - val formattingCode = "§$char" - -} diff --git a/src/main/kotlin/moe/nea/firmament/util/LegacyTagParser.kt b/src/main/kotlin/moe/nea/firmament/util/LegacyTagParser.kt deleted file mode 100644 index 4e08da1..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/LegacyTagParser.kt +++ /dev/null @@ -1,245 +0,0 @@ - - -package moe.nea.firmament.util - -import java.util.* -import net.minecraft.nbt.AbstractNbtNumber -import net.minecraft.nbt.NbtByte -import net.minecraft.nbt.NbtCompound -import net.minecraft.nbt.NbtDouble -import net.minecraft.nbt.NbtElement -import net.minecraft.nbt.NbtFloat -import net.minecraft.nbt.NbtInt -import net.minecraft.nbt.NbtList -import net.minecraft.nbt.NbtLong -import net.minecraft.nbt.NbtShort -import net.minecraft.nbt.NbtString - -class LegacyTagParser private constructor(string: String) { - data class TagParsingException(val baseString: String, val offset: Int, val mes0: String) : - Exception("$mes0 at $offset in `$baseString`.") - - class StringRacer(val backing: String) { - var idx = 0 - val stack = Stack<Int>() - - fun pushState() { - stack.push(idx) - } - - fun popState() { - idx = stack.pop() - } - - fun discardState() { - stack.pop() - } - - fun peek(count: Int): String { - return backing.substring(minOf(idx, backing.length), minOf(idx + count, backing.length)) - } - - fun finished(): Boolean { - return peek(1).isEmpty() - } - - fun peekReq(count: Int): String? { - val p = peek(count) - if (p.length != count) - return null - return p - } - - fun consumeCountReq(count: Int): String? { - val p = peekReq(count) - if (p != null) - idx += count - return p - } - - fun tryConsume(string: String): Boolean { - val p = peek(string.length) - if (p != string) - return false - idx += p.length - return true - } - - fun consumeWhile(shouldConsumeThisString: (String) -> Boolean): String { - var lastString: String = "" - while (true) { - val nextString = lastString + peek(1) - if (!shouldConsumeThisString(nextString)) { - return lastString - } - idx++ - lastString = nextString - } - } - - fun expect(search: String, errorMessage: String) { - if (!tryConsume(search)) - error(errorMessage) - } - - fun error(errorMessage: String): Nothing { - throw TagParsingException(backing, idx, errorMessage) - } - - } - - val racer = StringRacer(string) - val baseTag = parseTag() - - companion object { - val digitRange = "0123456789-" - fun parse(string: String): NbtCompound { - return LegacyTagParser(string).baseTag - } - } - - fun skipWhitespace() { - racer.consumeWhile { Character.isWhitespace(it.last()) } // Only check last since other chars are always checked before. - } - - fun parseTag(): NbtCompound { - skipWhitespace() - racer.expect("{", "Expected '{’ at start of tag") - skipWhitespace() - val tag = NbtCompound() - while (!racer.tryConsume("}")) { - skipWhitespace() - val lhs = parseIdentifier() - skipWhitespace() - racer.expect(":", "Expected ':' after identifier in tag") - skipWhitespace() - val rhs = parseAny() - tag.put(lhs, rhs) - racer.tryConsume(",") - skipWhitespace() - } - return tag - } - - private fun parseAny(): NbtElement { - skipWhitespace() - val nextChar = racer.peekReq(1) ?: racer.error("Expected new object, found EOF") - return when { - nextChar == "{" -> parseTag() - nextChar == "[" -> parseList() - nextChar == "\"" -> parseStringTag() - nextChar.first() in (digitRange) -> parseNumericTag() - else -> racer.error("Unexpected token found. Expected start of new element") - } - } - - fun parseList(): NbtList { - skipWhitespace() - racer.expect("[", "Expected '[' at start of tag") - skipWhitespace() - val list = NbtList() - while (!racer.tryConsume("]")) { - skipWhitespace() - racer.pushState() - val lhs = racer.consumeWhile { it.all { it in digitRange } } - skipWhitespace() - if (!racer.tryConsume(":") || lhs.isEmpty()) { // No prefixed 0: - racer.popState() - list.add(parseAny()) // Reparse our number (or not a number) as actual tag - } else { - racer.discardState() - skipWhitespace() - list.add(parseAny()) // Ignore prefix indexes. They should not be generated out of order by any vanilla implementation (which is what NEU should export). Instead append where it appears in order. - } - skipWhitespace() - racer.tryConsume(",") - } - return list - } - - fun parseQuotedString(): String { - skipWhitespace() - racer.expect("\"", "Expected '\"' at string start") - val sb = StringBuilder() - while (true) { - when (val peek = racer.consumeCountReq(1)) { - "\"" -> break - "\\" -> { - val escaped = racer.consumeCountReq(1) ?: racer.error("Unfinished backslash escape") - if (escaped != "\"" && escaped != "\\") { - // Surprisingly i couldn't find unicode escapes to be generated by the original minecraft 1.8.9 implementation - racer.idx-- - racer.error("Invalid backslash escape '$escaped'") - } - sb.append(escaped) - } - - null -> racer.error("Unfinished string") - else -> { - sb.append(peek) - } - } - } - return sb.toString() - } - - fun parseStringTag(): NbtString { - return NbtString.of(parseQuotedString()) - } - - object Patterns { - val DOUBLE = "([-+]?[0-9]*\\.?[0-9]+)[d|D]".toRegex() - val FLOAT = "([-+]?[0-9]*\\.?[0-9]+)[f|F]".toRegex() - val BYTE = "([-+]?[0-9]+)[b|B]".toRegex() - val LONG = "([-+]?[0-9]+)[l|L]".toRegex() - val SHORT = "([-+]?[0-9]+)[s|S]".toRegex() - val INTEGER = "([-+]?[0-9]+)".toRegex() - val DOUBLE_UNTYPED = "([-+]?[0-9]*\\.?[0-9]+)".toRegex() - val ROUGH_PATTERN = "[-+]?[0-9]*\\.?[0-9]*[dDbBfFlLsS]?".toRegex() - } - - fun parseNumericTag(): AbstractNbtNumber { - skipWhitespace() - val textForm = racer.consumeWhile { Patterns.ROUGH_PATTERN.matchEntire(it) != null } - if (textForm.isEmpty()) { - racer.error("Expected numeric tag (starting with either -, +, . or a digit") - } - val floatMatch = Patterns.FLOAT.matchEntire(textForm) - if (floatMatch != null) { - return NbtFloat.of(floatMatch.groups[1]!!.value.toFloat()) - } - val byteMatch = Patterns.BYTE.matchEntire(textForm) - if (byteMatch != null) { - return NbtByte.of(byteMatch.groups[1]!!.value.toByte()) - } - val longMatch = Patterns.LONG.matchEntire(textForm) - if (longMatch != null) { - return NbtLong.of(longMatch.groups[1]!!.value.toLong()) - } - val shortMatch = Patterns.SHORT.matchEntire(textForm) - if (shortMatch != null) { - return NbtShort.of(shortMatch.groups[1]!!.value.toShort()) - } - val integerMatch = Patterns.INTEGER.matchEntire(textForm) - if (integerMatch != null) { - return NbtInt.of(integerMatch.groups[1]!!.value.toInt()) - } - val doubleMatch = Patterns.DOUBLE.matchEntire(textForm) ?: Patterns.DOUBLE_UNTYPED.matchEntire(textForm) - if (doubleMatch != null) { - return NbtDouble.of(doubleMatch.groups[1]!!.value.toDouble()) - } - throw IllegalStateException("Could not properly parse numeric tag '$textForm', despite passing rough verification. This is a bug in the LegacyTagParser") - } - - private fun parseIdentifier(): String { - skipWhitespace() - if (racer.peek(1) == "\"") { - return parseQuotedString() - } - return racer.consumeWhile { - val x = it.last() - x != ':' && !Character.isWhitespace(x) - } - } - -} diff --git a/src/main/kotlin/moe/nea/firmament/util/LoadResource.kt b/src/main/kotlin/moe/nea/firmament/util/LoadResource.kt deleted file mode 100644 index 4bc8704..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/LoadResource.kt +++ /dev/null @@ -1,20 +0,0 @@ - -package moe.nea.firmament.util - -import java.io.InputStream -import kotlin.io.path.inputStream -import kotlin.jvm.optionals.getOrNull -import net.minecraft.util.Identifier -import moe.nea.firmament.repo.RepoDownloadManager - - -fun Identifier.openFirmamentResource(): InputStream { - val resource = MC.resourceManager.getResource(this).getOrNull() - if (resource == null) { - if (namespace == "neurepo") - return RepoDownloadManager.repoSavedLocation.resolve(path).inputStream() - error("Could not read resource $this") - } - return resource.inputStream -} - diff --git a/src/main/kotlin/moe/nea/firmament/util/Locraw.kt b/src/main/kotlin/moe/nea/firmament/util/Locraw.kt deleted file mode 100644 index 9778bc7..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/Locraw.kt +++ /dev/null @@ -1,12 +0,0 @@ - - -package moe.nea.firmament.util - -import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient - -@Serializable -data class Locraw(val server: String, val gametype: String? = null, val mode: String? = null, val map: String? = null) { - @Transient - val skyblockLocation = if (gametype == "SKYBLOCK") mode?.let(SkyBlockIsland::forMode) else null -} diff --git a/src/main/kotlin/moe/nea/firmament/util/LogIfNull.kt b/src/main/kotlin/moe/nea/firmament/util/LogIfNull.kt deleted file mode 100644 index 600c5e6..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/LogIfNull.kt +++ /dev/null @@ -1,8 +0,0 @@ - -package moe.nea.firmament.util - - -fun runNull(block: () -> Unit): Nothing? { - block() - return null -} diff --git a/src/main/kotlin/moe/nea/firmament/util/MC.kt b/src/main/kotlin/moe/nea/firmament/util/MC.kt deleted file mode 100644 index b0d3056..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/MC.kt +++ /dev/null @@ -1,94 +0,0 @@ -package moe.nea.firmament.util - -import io.github.moulberry.repo.data.Coordinate -import java.util.concurrent.ConcurrentLinkedQueue -import net.minecraft.client.MinecraftClient -import net.minecraft.client.gui.screen.ingame.HandledScreen -import net.minecraft.client.render.WorldRenderer -import net.minecraft.network.packet.c2s.play.CommandExecutionC2SPacket -import net.minecraft.registry.BuiltinRegistries -import net.minecraft.registry.RegistryKeys -import net.minecraft.registry.RegistryWrapper -import net.minecraft.resource.ReloadableResourceManagerImpl -import net.minecraft.text.Text -import net.minecraft.util.math.BlockPos -import moe.nea.firmament.events.TickEvent - -object MC { - - private val messageQueue = ConcurrentLinkedQueue<Text>() - - init { - TickEvent.subscribe { - while (true) { - inGameHud.chatHud.addMessage(messageQueue.poll() ?: break) - } - while (true) { - (nextTickTodos.poll() ?: break).invoke() - } - } - } - - fun sendChat(text: Text) { - if (instance.isOnThread) - inGameHud.chatHud.addMessage(text) - else - messageQueue.add(text) - } - - fun sendServerCommand(command: String) { - val nh = player?.networkHandler ?: return - nh.sendPacket( - CommandExecutionC2SPacket( - command, - ) - ) - } - - fun sendServerChat(text: String) { - player?.networkHandler?.sendChatMessage(text) - } - - fun sendCommand(command: String) { - player?.networkHandler?.sendCommand(command) - } - - fun onMainThread(block: () -> Unit) { - if (instance.isOnThread) - block() - else - instance.send(block) - } - - private val nextTickTodos = ConcurrentLinkedQueue<() -> Unit>() - fun nextTick(function: () -> Unit) { - nextTickTodos.add(function) - } - - - inline val resourceManager get() = (instance.resourceManager as ReloadableResourceManagerImpl) - inline val worldRenderer: WorldRenderer get() = instance.worldRenderer - inline val networkHandler get() = player?.networkHandler - inline val instance get() = MinecraftClient.getInstance() - inline val keyboard get() = instance.keyboard - inline val textureManager get() = instance.textureManager - inline val inGameHud get() = instance.inGameHud - inline val font get() = instance.textRenderer - inline val soundManager get() = instance.soundManager - inline val player get() = instance.player - inline val camera get() = instance.cameraEntity - inline val guiAtlasManager get() = instance.guiAtlasManager - inline val world get() = instance.world - inline var screen - get() = instance.currentScreen - set(value) = instance.setScreen(value) - inline val handledScreen: HandledScreen<*>? get() = instance.currentScreen as? HandledScreen<*> - inline val window get() = instance.window - inline val currentRegistries: RegistryWrapper.WrapperLookup? get() = world?.registryManager - val defaultRegistries: RegistryWrapper.WrapperLookup = BuiltinRegistries.createWrapperLookup() - val defaultItems = defaultRegistries.getWrapperOrThrow(RegistryKeys.ITEM) -} - - -val Coordinate.blockPos: BlockPos - get() = BlockPos(x, y, z) diff --git a/src/main/kotlin/moe/nea/firmament/util/MinecraftDispatcher.kt b/src/main/kotlin/moe/nea/firmament/util/MinecraftDispatcher.kt deleted file mode 100644 index d1f22a9..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/MinecraftDispatcher.kt +++ /dev/null @@ -1,8 +0,0 @@ - - -package moe.nea.firmament.util - -import kotlinx.coroutines.asCoroutineDispatcher -import net.minecraft.client.MinecraftClient - -val MinecraftDispatcher by lazy { MinecraftClient.getInstance().asCoroutineDispatcher() } diff --git a/src/main/kotlin/moe/nea/firmament/util/MoulConfigFragment.kt b/src/main/kotlin/moe/nea/firmament/util/MoulConfigFragment.kt deleted file mode 100644 index 36132cd..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/MoulConfigFragment.kt +++ /dev/null @@ -1,44 +0,0 @@ - - -package moe.nea.firmament.util - -import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper -import io.github.notenoughupdates.moulconfig.gui.GuiContext -import io.github.notenoughupdates.moulconfig.gui.GuiImmediateContext -import me.shedaniel.math.Point -import net.minecraft.client.gui.DrawContext - -class MoulConfigFragment( - context: GuiContext, - val position: Point, - val dismiss: () -> Unit -) : GuiComponentWrapper(context) { - init { - this.init(MC.instance, MC.screen!!.width, MC.screen!!.height) - } - - override fun createContext(drawContext: DrawContext?): GuiImmediateContext { - val oldContext = super.createContext(drawContext) - return oldContext.translated( - position.x, - position.y, - context.root.width, - context.root.height, - ) - } - - - override fun render(drawContext: DrawContext?, i: Int, j: Int, f: Float) { - val ctx = createContext(drawContext) - val m = drawContext!!.matrices - m.push() - m.translate(position.x.toFloat(), position.y.toFloat(), 0F) - context.root.render(ctx) - m.pop() - ctx.renderContext.doDrawTooltip() - } - - override fun close() { - dismiss() - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/MoulConfigUtils.kt b/src/main/kotlin/moe/nea/firmament/util/MoulConfigUtils.kt deleted file mode 100644 index 00561d1..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/MoulConfigUtils.kt +++ /dev/null @@ -1,230 +0,0 @@ - - -package moe.nea.firmament.util - -import io.github.notenoughupdates.moulconfig.common.MyResourceLocation -import io.github.notenoughupdates.moulconfig.gui.CloseEventListener -import io.github.notenoughupdates.moulconfig.gui.GuiComponentWrapper -import io.github.notenoughupdates.moulconfig.gui.GuiContext -import io.github.notenoughupdates.moulconfig.observer.GetSetter -import io.github.notenoughupdates.moulconfig.xml.ChildCount -import io.github.notenoughupdates.moulconfig.xml.XMLContext -import io.github.notenoughupdates.moulconfig.xml.XMLGuiLoader -import io.github.notenoughupdates.moulconfig.xml.XMLUniverse -import io.github.notenoughupdates.moulconfig.xml.XSDGenerator -import java.io.File -import java.util.function.Supplier -import javax.xml.namespace.QName -import me.shedaniel.math.Color -import org.w3c.dom.Element -import kotlin.time.Duration -import kotlin.time.Duration.Companion.seconds -import net.minecraft.client.gui.screen.Screen -import moe.nea.firmament.gui.BarComponent -import moe.nea.firmament.gui.FirmButtonComponent -import moe.nea.firmament.gui.FirmHoverComponent -import moe.nea.firmament.gui.FixedComponent -import moe.nea.firmament.gui.ImageComponent -import moe.nea.firmament.gui.TickComponent - -object MoulConfigUtils { - val firmUrl = "http://firmament.nea.moe/moulconfig" - val universe = XMLUniverse.getDefaultUniverse().also { uni -> - uni.registerMapper(java.awt.Color::class.java) { - if (it.startsWith("#")) { - val hexString = it.substring(1) - val hex = hexString.toInt(16) - if (hexString.length == 6) { - return@registerMapper java.awt.Color(hex) - } - if (hexString.length == 8) { - return@registerMapper java.awt.Color(hex, true) - } - error("Hexcolor $it needs to be exactly 6 or 8 hex digits long") - } - return@registerMapper java.awt.Color(it.toInt(), true) - } - uni.registerMapper(Color::class.java) { - val color = uni.mapXMLObject(it, java.awt.Color::class.java) - Color.ofRGBA(color.red, color.green, color.blue, color.alpha) - } - uni.registerLoader(object : XMLGuiLoader.Basic<BarComponent> { - override fun getName(): QName { - return QName(firmUrl, "Bar") - } - - override fun createInstance(context: XMLContext<*>, element: Element): BarComponent { - return BarComponent( - context.getPropertyFromAttribute(element, QName("progress"), Double::class.java)!!, - context.getPropertyFromAttribute(element, QName("total"), Double::class.java)!!, - context.getPropertyFromAttribute(element, QName("fillColor"), Color::class.java)!!.get(), - context.getPropertyFromAttribute(element, QName("emptyColor"), Color::class.java)!!.get(), - ) - } - - override fun getChildCount(): ChildCount { - return ChildCount.NONE - } - - override fun getAttributeNames(): Map<String, Boolean> { - return mapOf("progress" to true, "total" to true, "emptyColor" to true, "fillColor" to true) - } - }) - uni.registerLoader(object : XMLGuiLoader.Basic<FirmHoverComponent> { - override fun createInstance(context: XMLContext<*>, element: Element): FirmHoverComponent { - return FirmHoverComponent( - context.getChildFragment(element), - context.getPropertyFromAttribute(element, QName("lines"), List::class.java) as Supplier<List<String>>, - context.getPropertyFromAttribute(element, QName("delay"), Duration::class.java, 0.6.seconds), - ) - } - - override fun getName(): QName { - return QName(firmUrl, "Hover") - } - - override fun getChildCount(): ChildCount { - return ChildCount.ONE - } - - override fun getAttributeNames(): Map<String, Boolean> { - return mapOf( - "lines" to true, - "delay" to false, - ) - } - - }) - uni.registerLoader(object : XMLGuiLoader.Basic<FirmButtonComponent> { - override fun getName(): QName { - return QName(firmUrl, "Button") - } - - override fun createInstance(context: XMLContext<*>, element: Element): FirmButtonComponent { - return FirmButtonComponent( - context.getChildFragment(element), - context.getPropertyFromAttribute(element, QName("enabled"), Boolean::class.java) - ?: GetSetter.constant(true), - context.getPropertyFromAttribute(element, QName("noBackground"), Boolean::class.java, false), - context.getMethodFromAttribute(element, QName("onClick")), - ) - } - - override fun getChildCount(): ChildCount { - return ChildCount.ONE - } - - override fun getAttributeNames(): Map<String, Boolean> { - return mapOf("onClick" to true, "enabled" to false, "noBackground" to false) - } - }) - uni.registerLoader(object : XMLGuiLoader.Basic<ImageComponent> { - override fun createInstance(context: XMLContext<*>, element: Element): ImageComponent { - return ImageComponent( - context.getPropertyFromAttribute(element, QName("width"), Int::class.java)!!.get(), - context.getPropertyFromAttribute(element, QName("height"), Int::class.java)!!.get(), - context.getPropertyFromAttribute(element, QName("resource"), MyResourceLocation::class.java)!!, - context.getPropertyFromAttribute(element, QName("u1"), Float::class.java, 0f), - context.getPropertyFromAttribute(element, QName("u2"), Float::class.java, 1f), - context.getPropertyFromAttribute(element, QName("v1"), Float::class.java, 0f), - context.getPropertyFromAttribute(element, QName("v2"), Float::class.java, 1f), - ) - } - - override fun getName(): QName { - return QName(firmUrl, "Image") - } - - override fun getChildCount(): ChildCount { - return ChildCount.NONE - } - - override fun getAttributeNames(): Map<String, Boolean> { - return mapOf( - "width" to true, "height" to true, - "resource" to true, - "u1" to false, - "u2" to false, - "v1" to false, - "v2" to false, - ) - } - }) - uni.registerLoader(object : XMLGuiLoader.Basic<TickComponent> { - override fun createInstance(context: XMLContext<*>, element: Element): TickComponent { - return TickComponent(context.getMethodFromAttribute(element, QName("tick"))) - } - - override fun getName(): QName { - return QName(firmUrl, "Tick") - } - - override fun getChildCount(): ChildCount { - return ChildCount.NONE - } - - override fun getAttributeNames(): Map<String, Boolean> { - return mapOf("tick" to true) - } - }) - uni.registerLoader(object : XMLGuiLoader.Basic<FixedComponent> { - override fun createInstance(context: XMLContext<*>, element: Element): FixedComponent { - return FixedComponent( - context.getPropertyFromAttribute(element, QName("width"), Int::class.java) - ?: error("Requires width specified"), - context.getPropertyFromAttribute(element, QName("height"), Int::class.java) - ?: error("Requires height specified"), - context.getChildFragment(element) - ) - } - - override fun getName(): QName { - return QName(firmUrl, "Fixed") - } - - override fun getChildCount(): ChildCount { - return ChildCount.ONE - } - - override fun getAttributeNames(): Map<String, Boolean> { - return mapOf("width" to true, "height" to true) - } - }) - } - - fun generateXSD( - file: File, - namespace: String - ) { - val generator = XSDGenerator(universe, namespace) - generator.writeAll() - generator.dumpToFile(file) - } - - @JvmStatic - fun main(args: Array<out String>) { - generateXSD(File("MoulConfig.xsd"), XMLUniverse.MOULCONFIG_XML_NS) - generateXSD(File("MoulConfig.Firmament.xsd"), firmUrl) - File("wrapper.xsd").writeText(""" -<?xml version="1.0" encoding="UTF-8" ?> -<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"> - <xs:import namespace="http://notenoughupdates.org/moulconfig" schemaLocation="MoulConfig.xsd"/> - <xs:import namespace="http://firmament.nea.moe/moulconfig" schemaLocation="MoulConfig.Firmament.xsd"/> -</xs:schema> - """.trimIndent()) - } - - fun loadScreen(name: String, bindTo: Any, parent: Screen?): Screen { - return object : GuiComponentWrapper(loadGui(name, bindTo)) { - override fun close() { - if (context.onBeforeClose() == CloseEventListener.CloseAction.NO_OBJECTIONS_TO_CLOSE) { - client!!.setScreen(parent) - } - } - } - } - - fun loadGui(name: String, bindTo: Any): GuiContext { - return GuiContext(universe.load(bindTo, MyResourceLocation("firmament", "gui/$name.xml"))) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/MutableMapWithMaxSize.kt b/src/main/kotlin/moe/nea/firmament/util/MutableMapWithMaxSize.kt deleted file mode 100644 index 067e652..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/MutableMapWithMaxSize.kt +++ /dev/null @@ -1,38 +0,0 @@ - -package moe.nea.firmament.util - -fun <K, V> mutableMapWithMaxSize(maxSize: Int): MutableMap<K, V> = object : LinkedHashMap<K, V>() { - override fun removeEldestEntry(eldest: MutableMap.MutableEntry<K, V>): Boolean { - return size > maxSize - } -} - -fun <T, R> ((T) -> R).memoizeIdentity(maxCacheSize: Int): (T) -> R { - val memoized = { it: IdentityCharacteristics<T> -> - this(it.value) - }.memoize(maxCacheSize) - return { memoized(IdentityCharacteristics(it)) } -} - -@PublishedApi -internal val SENTINEL_NULL = java.lang.Object() - -/** - * Requires the map to only contain values of type [R] or [SENTINEL_NULL]. This is ensured if the map is only ever - * accessed via this function. - */ -inline fun <T, R> MutableMap<T, Any>.computeNullableFunction(key: T, crossinline func: () -> R): R { - val value = this.getOrPut(key) { - func() ?: SENTINEL_NULL - } - @Suppress("UNCHECKED_CAST") - return if (value === SENTINEL_NULL) null as R - else value as R -} - -fun <T, R> ((T) -> R).memoize(maxCacheSize: Int): (T) -> R { - val map = mutableMapWithMaxSize<T, Any>(maxCacheSize) - return { - map.computeNullableFunction(it) { this@memoize(it) } - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/SBData.kt b/src/main/kotlin/moe/nea/firmament/util/SBData.kt deleted file mode 100644 index b30c6fb..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/SBData.kt +++ /dev/null @@ -1,66 +0,0 @@ -package moe.nea.firmament.util - -import java.util.UUID -import net.hypixel.modapi.HypixelModAPI -import net.hypixel.modapi.packet.impl.clientbound.event.ClientboundLocationPacket -import kotlin.jvm.optionals.getOrNull -import kotlin.time.Duration.Companion.seconds -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 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 lastProfileIdRequest = TimeMark.farPast() - fun init() { - ServerConnectedEvent.subscribe { - 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)) - } - } - SkyblockServerUpdateEvent.subscribe { - if (!hasReceivedProfile && isOnSkyblock && lastProfileIdRequest.passedTime() > 30.seconds) { - lastProfileIdRequest = TimeMark.now() - MC.sendServerCommand("profileid") - } - } - AllowChatEvent.subscribe { event -> - if (event.unformattedString in profileSuggestTexts && lastProfileIdRequest.passedTime() < 5.seconds) { - event.cancel() - } - } - ProcessChatEvent.subscribe(receivesCancelled = true) { 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/moe/nea/firmament/util/ScoreboardUtil.kt b/src/main/kotlin/moe/nea/firmament/util/ScoreboardUtil.kt deleted file mode 100644 index 4311971..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/ScoreboardUtil.kt +++ /dev/null @@ -1,45 +0,0 @@ - - -package moe.nea.firmament.util - -import java.util.* -import net.minecraft.client.gui.hud.InGameHud -import net.minecraft.scoreboard.ScoreboardDisplaySlot -import net.minecraft.scoreboard.Team -import net.minecraft.text.StringVisitable -import net.minecraft.text.Style -import net.minecraft.text.Text -import net.minecraft.util.Formatting - -fun getScoreboardLines(): List<Text> { - val scoreboard = MC.player?.scoreboard ?: return listOf() - val activeObjective = scoreboard.getObjectiveForSlot(ScoreboardDisplaySlot.SIDEBAR) ?: return listOf() - return scoreboard.getScoreboardEntries(activeObjective) - .filter { !it.hidden() } - .sortedWith(InGameHud.SCOREBOARD_ENTRY_COMPARATOR) - .take(15).map { - val team = scoreboard.getScoreHolderTeam(it.owner) - val text = it.name() - Team.decorateName(team, text) - } -} - - -fun Text.formattedString(): String { - val sb = StringBuilder() - visit(StringVisitable.StyledVisitor<Unit> { style, string -> - val c = Formatting.byName(style.color?.name) - if (c != null) { - sb.append("§${c.code}") - } - if (style.isUnderlined) { - sb.append("§n") - } - if (style.isBold) { - sb.append("§l") - } - sb.append(string) - Optional.empty() - }, Style.EMPTY) - return sb.toString().replace("§[^a-f0-9]".toRegex(), "") -} diff --git a/src/main/kotlin/moe/nea/firmament/util/ScreenUtil.kt b/src/main/kotlin/moe/nea/firmament/util/ScreenUtil.kt deleted file mode 100644 index 99d77fb..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/ScreenUtil.kt +++ /dev/null @@ -1,38 +0,0 @@ - - -package moe.nea.firmament.util - -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents -import net.minecraft.client.MinecraftClient -import net.minecraft.client.gui.screen.Screen -import moe.nea.firmament.Firmament - -object ScreenUtil { - init { - ClientTickEvents.START_CLIENT_TICK.register(::onTick) - } - - private fun onTick(minecraft: MinecraftClient) { - if (nextOpenedGui != null) { - val p = minecraft.player - if (p?.currentScreenHandler != null) { - p.closeHandledScreen() - } - minecraft.setScreen(nextOpenedGui) - nextOpenedGui = null - } - } - - private var nextOpenedGui: Screen? = null - - fun setScreenLater(nextScreen: Screen?) { - val nog = nextOpenedGui - if (nog != null) { - Firmament.logger.warn("Setting screen ${if (nextScreen == null) "null" else nextScreen::class.qualifiedName} to be opened later, but ${nog::class.qualifiedName} is already queued.") - return - } - nextOpenedGui = nextScreen - } - - -} diff --git a/src/main/kotlin/moe/nea/firmament/util/SequenceUtil.kt b/src/main/kotlin/moe/nea/firmament/util/SequenceUtil.kt deleted file mode 100644 index 7b5bad0..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/SequenceUtil.kt +++ /dev/null @@ -1,11 +0,0 @@ - - -package moe.nea.firmament.util - -fun <T : Any> T.iterate(iterator: (T) -> T?): Sequence<T> = sequence { - var x: T? = this@iterate - while (x != null) { - yield(x) - x = iterator(x) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/SkyBlockIsland.kt b/src/main/kotlin/moe/nea/firmament/util/SkyBlockIsland.kt deleted file mode 100644 index bd0567d..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/SkyBlockIsland.kt +++ /dev/null @@ -1,42 +0,0 @@ - -package moe.nea.firmament.util - -import kotlinx.serialization.KSerializer -import kotlinx.serialization.Serializable -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder -import moe.nea.firmament.repo.RepoManager - -@Serializable(with = SkyBlockIsland.Serializer::class) -class SkyBlockIsland -private constructor( - val locrawMode: String, -) { - - object Serializer : KSerializer<SkyBlockIsland> { - override val descriptor: SerialDescriptor - get() = PrimitiveSerialDescriptor("SkyBlockIsland", PrimitiveKind.STRING) - - override fun deserialize(decoder: Decoder): SkyBlockIsland { - return forMode(decoder.decodeString()) - } - - override fun serialize(encoder: Encoder, value: SkyBlockIsland) { - encoder.encodeString(value.locrawMode) - } - } - companion object { - private val allIslands = mutableMapOf<String, SkyBlockIsland>() - fun forMode(mode: String): SkyBlockIsland = allIslands.computeIfAbsent(mode, ::SkyBlockIsland) - val HUB = forMode("hub") - val PRIVATE_ISLAND = forMode("dynamic") - val RIFT = forMode("rift") - } - - val userFriendlyName - get() = RepoManager.neuRepo.constants.islands.areaNames - .getOrDefault(locrawMode, locrawMode) -} diff --git a/src/main/kotlin/moe/nea/firmament/util/SkyblockId.kt b/src/main/kotlin/moe/nea/firmament/util/SkyblockId.kt deleted file mode 100644 index 59b1d2c..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/SkyblockId.kt +++ /dev/null @@ -1,149 +0,0 @@ - - -@file:UseSerializers(DashlessUUIDSerializer::class) - -package moe.nea.firmament.util - -import io.github.moulberry.repo.data.NEUItem -import io.github.moulberry.repo.data.Rarity -import java.util.UUID -import kotlinx.serialization.Serializable -import kotlinx.serialization.UseSerializers -import kotlinx.serialization.json.Json -import net.minecraft.component.DataComponentTypes -import net.minecraft.component.type.NbtComponent -import net.minecraft.item.ItemStack -import net.minecraft.nbt.NbtCompound -import net.minecraft.util.Identifier -import moe.nea.firmament.repo.set -import moe.nea.firmament.util.json.DashlessUUIDSerializer - -/** - * A skyblock item id, as used by the NEU repo. - * This is not exactly the format used by HyPixel, but is mostly the same. - * Usually this id splits an id used by HyPixel into more sub items. For example `PET` becomes `$PET_ID;$PET_RARITY`, - * with those values extracted from other metadata. - */ -@JvmInline -@Serializable -value class SkyblockId(val neuItem: String) { - val identifier - get() = Identifier.of("skyblockitem", - neuItem.lowercase().replace(";", "__") - .replace(":", "___") - .replace(illlegalPathRegex) { - it.value.toCharArray() - .joinToString("") { "__" + it.code.toString(16).padStart(4, '0') } - }) - - override fun toString(): String { - return neuItem - } - - /** - * A bazaar stock item id, as returned by the HyPixel bazaar api endpoint. - * These are not equivalent to the in-game ids, or the NEU repo ids, and in fact, do not refer to items, but instead - * to bazaar stocks. The main difference from [SkyblockId]s is concerning enchanted books. There are probably more, - * but for now this holds. - */ - @JvmInline - @Serializable - value class BazaarStock(val bazaarId: String) { - fun toRepoId(): SkyblockId { - bazaarEnchantmentRegex.matchEntire(bazaarId)?.let { - return SkyblockId("${it.groupValues[1]};${it.groupValues[2]}") - } - return SkyblockId(bazaarId.replace(":", "-")) - } - } - - companion object { - val COINS: SkyblockId = SkyblockId("SKYBLOCK_COIN") - private val bazaarEnchantmentRegex = "ENCHANTMENT_(\\D*)_(\\d+)".toRegex() - val NULL: SkyblockId = SkyblockId("null") - val PET_NULL: SkyblockId = SkyblockId("null_pet") - private val illlegalPathRegex = "[^a-z0-9_.-/]".toRegex() - } -} - -val NEUItem.skyblockId get() = SkyblockId(skyblockItemId) - -@Serializable -data class HypixelPetInfo( - val type: String, - val tier: Rarity, - val exp: Double = 0.0, - val candyUsed: Int = 0, - val uuid: UUID? = null, -) { - val skyblockId get() = SkyblockId("${type.uppercase()};${tier.ordinal}") -} - -private val jsonparser = Json { ignoreUnknownKeys = true } - -val ItemStack.extraAttributes: NbtCompound - get() { - val customData = get(DataComponentTypes.CUSTOM_DATA) ?: run { - val component = NbtComponent.of(NbtCompound()) - set(DataComponentTypes.CUSTOM_DATA, component) - component - } - return customData.nbt - } - -val ItemStack.skyblockUUIDString: String? - get() = extraAttributes.getString("uuid")?.takeIf { it.isNotBlank() } - -val ItemStack.skyblockUUID: UUID? - get() = skyblockUUIDString?.let { UUID.fromString(it) } - -val ItemStack.petData: HypixelPetInfo? - get() { - val jsonString = extraAttributes.getString("petInfo") - if (jsonString.isNullOrBlank()) return null - return runCatching { jsonparser.decodeFromString<HypixelPetInfo>(jsonString) } - .getOrElse { return null } - } - -fun ItemStack.setSkyBlockFirmamentUiId(uiId: String) = setSkyBlockId(SkyblockId("FIRMAMENT_UI_$uiId")) -fun ItemStack.setSkyBlockId(skyblockId: SkyblockId): ItemStack { - this.extraAttributes["id"] = skyblockId.neuItem - return this -} - -val ItemStack.skyBlockId: SkyblockId? - get() { - return when (val id = extraAttributes.getString("id")) { - "" -> { - null - } - - "PET" -> { - petData?.skyblockId ?: SkyblockId.PET_NULL - } - - "RUNE", "UNIQUE_RUNE" -> { - val runeData = extraAttributes.getCompound("runes") - val runeKind = runeData.keys.singleOrNull() - if (runeKind == null) SkyblockId("RUNE") - else SkyblockId("${runeKind.uppercase()}_RUNE;${runeData.getInt(runeKind)}") - } - - "ABICASE" -> { - SkyblockId("ABICASE_${extraAttributes.getString("model").uppercase()}") - } - - "ENCHANTED_BOOK" -> { - val enchantmentData = extraAttributes.getCompound("enchantments") - val enchantName = enchantmentData.keys.singleOrNull() - if (enchantName == null) SkyblockId("ENCHANTED_BOOK") - else SkyblockId("${enchantName.uppercase()};${enchantmentData.getInt(enchantName)}") - } - - // TODO: PARTY_HAT_CRAB{,_ANIMATED,_SLOTH},POTION - else -> { - SkyblockId(id) - } - } - } - diff --git a/src/main/kotlin/moe/nea/firmament/util/SortedMapSerializer.kt b/src/main/kotlin/moe/nea/firmament/util/SortedMapSerializer.kt deleted file mode 100644 index baa10ad..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/SortedMapSerializer.kt +++ /dev/null @@ -1,25 +0,0 @@ - - -package moe.nea.firmament.util - -import java.util.SortedMap -import kotlinx.serialization.KSerializer -import kotlinx.serialization.builtins.MapSerializer -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder - -class SortedMapSerializer<K : Comparable<K>, V>(val keyDelegate: KSerializer<K>, val valueDelegate: KSerializer<V>) : - KSerializer<SortedMap<K, V>> { - val mapSerializer = MapSerializer(keyDelegate, valueDelegate) - override val descriptor: SerialDescriptor - get() = mapSerializer.descriptor - - override fun deserialize(decoder: Decoder): SortedMap<K, V> { - return (mapSerializer.deserialize(decoder).toSortedMap(Comparator.naturalOrder())) - } - - override fun serialize(encoder: Encoder, value: SortedMap<K, V>) { - mapSerializer.serialize(encoder, value) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/TemplateUtil.kt b/src/main/kotlin/moe/nea/firmament/util/TemplateUtil.kt deleted file mode 100644 index 11100e9..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/TemplateUtil.kt +++ /dev/null @@ -1,85 +0,0 @@ - - -package moe.nea.firmament.util - -import java.util.* -import kotlinx.serialization.DeserializationStrategy -import kotlinx.serialization.SerializationStrategy -import kotlinx.serialization.serializer -import moe.nea.firmament.Firmament - -object TemplateUtil { - - @JvmStatic - fun getTemplatePrefix(data: String): String? { - val decoded = maybeFromBase64Encoded(data) ?: return null - return decoded.replaceAfter("/", "", "").ifBlank { null } - } - - @JvmStatic - fun intoBase64Encoded(raw: String): String { - return Base64.getEncoder().encodeToString(raw.encodeToByteArray()) - } - - private val base64Alphabet = charArrayOf( - 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', - 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', - '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '=' - ) - - @JvmStatic - fun maybeFromBase64Encoded(raw: String): String? { - val raw = raw.trim() - if (raw.any { it !in base64Alphabet }) { - return null - } - return try { - Base64.getDecoder().decode(raw).decodeToString() - } catch (ex: Exception) { - null - } - } - - - /** - * Returns a base64 encoded string, truncated such that for all `x`, `x.startsWith(prefix)` implies - * `base64Encoded(x).startsWith(getPrefixComparisonSafeBase64Encoding(prefix))` - * (however, the inverse may not always be true). - */ - @JvmStatic - fun getPrefixComparisonSafeBase64Encoding(prefix: String): String { - val rawEncoded = - Base64.getEncoder().encodeToString(prefix.encodeToByteArray()) - .replace("=", "") - return rawEncoded.substring(0, rawEncoded.length - rawEncoded.length % 4) - } - - inline fun <reified T> encodeTemplate(sharePrefix: String, data: T): String = - encodeTemplate(sharePrefix, data, serializer()) - - fun <T> encodeTemplate(sharePrefix: String, data: T, serializer: SerializationStrategy<T>): String { - require(sharePrefix.endsWith("/")) - return intoBase64Encoded(sharePrefix + Firmament.json.encodeToString(serializer, data)) - } - - inline fun <reified T : Any> maybeDecodeTemplate(sharePrefix: String, data: String): T? = - maybeDecodeTemplate(sharePrefix, data, serializer()) - - fun <T : Any> maybeDecodeTemplate(sharePrefix: String, data: String, serializer: DeserializationStrategy<T>): T? { - require(sharePrefix.endsWith("/")) - val data = data.trim() - if (!data.startsWith(getPrefixComparisonSafeBase64Encoding(sharePrefix))) - return null - val decoded = maybeFromBase64Encoded(data) ?: return null - if (!decoded.startsWith(sharePrefix)) - return null - return try { - Firmament.json.decodeFromString<T>(serializer, decoded.substring(sharePrefix.length)) - } catch (e: Exception) { - null - } - } - -} diff --git a/src/main/kotlin/moe/nea/firmament/util/TimeMark.kt b/src/main/kotlin/moe/nea/firmament/util/TimeMark.kt deleted file mode 100644 index 1264212..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/TimeMark.kt +++ /dev/null @@ -1,44 +0,0 @@ - - -package moe.nea.firmament.util - -import kotlin.time.Duration -import kotlin.time.Duration.Companion.milliseconds - -class TimeMark private constructor(private val timeMark: Long) : Comparable<TimeMark> { - fun passedTime() = if (timeMark == 0L) Duration.INFINITE else (System.currentTimeMillis() - timeMark).milliseconds - - operator fun minus(other: TimeMark): Duration { - if (other.timeMark == timeMark) - return 0.milliseconds - if (other.timeMark == 0L) - return Duration.INFINITE - if (timeMark == 0L) - return -Duration.INFINITE - return (timeMark - other.timeMark).milliseconds - } - - companion object { - fun now() = TimeMark(System.currentTimeMillis()) - fun farPast() = TimeMark(0L) - fun ago(timeDelta: Duration): TimeMark { - if (timeDelta.isFinite()) { - return TimeMark(System.currentTimeMillis() - timeDelta.inWholeMilliseconds) - } - require(timeDelta.isPositive()) - return farPast() - } - } - - override fun hashCode(): Int { - return timeMark.hashCode() - } - - override fun equals(other: Any?): Boolean { - return other is TimeMark && other.timeMark == timeMark - } - - override fun compareTo(other: TimeMark): Int { - return this.timeMark.compareTo(other.timeMark) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/Timer.kt b/src/main/kotlin/moe/nea/firmament/util/Timer.kt deleted file mode 100644 index 6e9b467..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/Timer.kt +++ /dev/null @@ -1,25 +0,0 @@ - - -package moe.nea.firmament.util - -import kotlin.time.Duration -import kotlin.time.ExperimentalTime -import kotlin.time.TimeSource - -@OptIn(ExperimentalTime::class) -class Timer { - private var mark: TimeSource.Monotonic.ValueTimeMark? = null - - fun timePassed(): Duration { - return mark?.elapsedNow() ?: Duration.INFINITE - } - - fun markNow() { - mark = TimeSource.Monotonic.markNow() - } - - fun markFarPast() { - mark = null - } - -} diff --git a/src/main/kotlin/moe/nea/firmament/util/WarpUtil.kt b/src/main/kotlin/moe/nea/firmament/util/WarpUtil.kt deleted file mode 100644 index 8fca6f3..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/WarpUtil.kt +++ /dev/null @@ -1,75 +0,0 @@ - -package moe.nea.firmament.util - -import io.github.moulberry.repo.constants.Islands -import io.github.moulberry.repo.constants.Islands.Warp -import kotlinx.serialization.Serializable -import kotlinx.serialization.serializer -import kotlin.math.sqrt -import kotlin.time.Duration.Companion.seconds -import net.minecraft.text.Text -import net.minecraft.util.math.Position -import moe.nea.firmament.events.ProcessChatEvent -import moe.nea.firmament.repo.RepoManager -import moe.nea.firmament.util.data.ProfileSpecificDataHolder - -object WarpUtil { - val warps: List<Islands.Warp> get() = RepoManager.neuRepo.constants.islands.warps - - @Serializable - data class Data( - val excludedWarps: MutableSet<String> = mutableSetOf(), - ) - - object DConfig : ProfileSpecificDataHolder<Data>(serializer(), "warp-util", ::Data) - - private var lastAttemptedWarp = "" - private var lastWarpAttempt = TimeMark.farPast() - fun findNearestWarp(island: SkyBlockIsland, pos: Position): Islands.Warp? { - return warps.asSequence().filter { it.mode == island.locrawMode }.minByOrNull { - if (DConfig.data?.excludedWarps?.contains(it.warp) == true) { - return@minByOrNull Double.MAX_VALUE - } else { - return@minByOrNull squaredDist(pos, it) - } - } - } - - private fun squaredDist(pos: Position, warp: Warp): Double { - val dx = pos.x - warp.x - val dy = pos.y - warp.y - val dz = pos.z - warp.z - return dx * dx + dy * dy + dz * dz - } - - fun teleportToNearestWarp(island: SkyBlockIsland, pos: Position) { - val nearestWarp = findNearestWarp(island, pos) - if (nearestWarp == null) { - MC.sendChat(Text.literal("Could not find an unlocked warp in ${island.userFriendlyName}")) - return - } - if (island == SBData.skyblockLocation - && sqrt(squaredDist(pos, nearestWarp)) > 1.1 * sqrt(squaredDist((MC.player ?: return).pos, nearestWarp)) - ) { - return - } - MC.sendServerCommand("warp ${nearestWarp.warp}") - } - - init { - ProcessChatEvent.subscribe { - if (it.unformattedString == "You haven't unlocked this fast travel destination!" - && lastWarpAttempt.passedTime() < 2.seconds - ) { - DConfig.data?.excludedWarps?.add(lastAttemptedWarp) - DConfig.markDirty() - MC.sendChat(Text.stringifiedTranslatable("firmament.warp-util.mark-excluded", lastAttemptedWarp)) - lastWarpAttempt = TimeMark.farPast() - } - if (it.unformattedString == "You may now fast travel to") { - DConfig.data?.excludedWarps?.clear() - DConfig.markDirty() - } - } - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/assertions.kt b/src/main/kotlin/moe/nea/firmament/util/assertions.kt deleted file mode 100644 index 6f2ed19..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/assertions.kt +++ /dev/null @@ -1,25 +0,0 @@ - - -package moe.nea.firmament.util - -/** - * Less aggressive version of `require(obj != null)`, which fails in devenv but continues at runtime. - */ -inline fun <T : Any> assertNotNullOr(obj: T?, message: String? = null, block: () -> T): T { - if (message == null) - assert(obj != null) - else - assert(obj != null) { message } - return obj ?: block() -} - - -/** - * Less aggressive version of `require(condition)`, which fails in devenv but continues at runtime. - */ -inline fun assertTrueOr(condition: Boolean, block: () -> Unit) { - assert(condition) - if (!condition) block() -} - - diff --git a/src/main/kotlin/moe/nea/firmament/util/async/input.kt b/src/main/kotlin/moe/nea/firmament/util/async/input.kt deleted file mode 100644 index 9aab5cf..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/async/input.kt +++ /dev/null @@ -1,47 +0,0 @@ - - -package moe.nea.firmament.util.async - -import kotlinx.coroutines.suspendCancellableCoroutine -import kotlin.coroutines.resume -import moe.nea.firmament.events.HandledScreenKeyPressedEvent -import moe.nea.firmament.keybindings.IKeyBinding - -private object InputHandler { - data class KeyInputContinuation(val keybind: IKeyBinding, val onContinue: () -> Unit) - - private val activeContinuations = mutableListOf<KeyInputContinuation>() - - fun registerContinuation(keyInputContinuation: KeyInputContinuation): () -> Unit { - synchronized(InputHandler) { - activeContinuations.add(keyInputContinuation) - } - return { - synchronized(this) { - activeContinuations.remove(keyInputContinuation) - } - } - } - - init { - HandledScreenKeyPressedEvent.subscribe { event -> - synchronized(InputHandler) { - val toRemove = activeContinuations.filter { - event.matches(it.keybind) - } - toRemove.forEach { it.onContinue() } - activeContinuations.removeAll(toRemove) - } - } - } -} - -suspend fun waitForInput(keybind: IKeyBinding): Unit = suspendCancellableCoroutine { cont -> - val unregister = - InputHandler.registerContinuation(InputHandler.KeyInputContinuation(keybind) { cont.resume(Unit) }) - cont.invokeOnCancellation { - unregister() - } -} - - diff --git a/src/main/kotlin/moe/nea/firmament/util/colorconversion.kt b/src/main/kotlin/moe/nea/firmament/util/colorconversion.kt deleted file mode 100644 index d7a5dad..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/colorconversion.kt +++ /dev/null @@ -1,13 +0,0 @@ - - -package moe.nea.firmament.util - -import net.minecraft.text.TextColor -import net.minecraft.util.DyeColor - -fun DyeColor.toShedaniel(): me.shedaniel.math.Color = - me.shedaniel.math.Color.ofOpaque(this.signColor) - -fun DyeColor.toTextColor(): TextColor = - TextColor.fromRgb(this.signColor) - diff --git a/src/main/kotlin/moe/nea/firmament/util/customgui/CoordRememberingSlot.kt b/src/main/kotlin/moe/nea/firmament/util/customgui/CoordRememberingSlot.kt deleted file mode 100644 index c61c711..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/customgui/CoordRememberingSlot.kt +++ /dev/null @@ -1,14 +0,0 @@ - -package moe.nea.firmament.util.customgui - -import net.minecraft.screen.slot.Slot - -interface CoordRememberingSlot { - fun rememberCoords_firmament() - fun restoreCoords_firmament() - fun getOriginalX_firmament(): Int - fun getOriginalY_firmament(): Int -} - -val Slot.originalX get() = (this as CoordRememberingSlot).getOriginalX_firmament() -val Slot.originalY get() = (this as CoordRememberingSlot).getOriginalY_firmament() diff --git a/src/main/kotlin/moe/nea/firmament/util/customgui/CustomGui.kt b/src/main/kotlin/moe/nea/firmament/util/customgui/CustomGui.kt deleted file mode 100644 index f9094b2..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/customgui/CustomGui.kt +++ /dev/null @@ -1,72 +0,0 @@ - -package moe.nea.firmament.util.customgui - -import me.shedaniel.math.Rectangle -import net.minecraft.client.gui.DrawContext -import net.minecraft.screen.slot.Slot -import moe.nea.firmament.annotations.Subscribe -import moe.nea.firmament.events.HandledScreenPushREIEvent - -abstract class CustomGui { - - abstract fun getBounds(): List<Rectangle> - - open fun moveSlot(slot: Slot) { - // TODO: return a Pair maybe? worth an investigation - } - - companion object { - @Subscribe - fun onExclusionZone(event: HandledScreenPushREIEvent) { - val customGui = event.screen.customGui ?: return - event.rectangles.addAll(customGui.getBounds()) - } - } - - open fun render( - drawContext: DrawContext, - delta: Float, - mouseX: Int, - mouseY: Int - ) { - } - - open fun mouseClick(mouseX: Double, mouseY: Double, button: Int): Boolean { - return false - } - - open fun afterSlotRender(context: DrawContext, slot: Slot) {} - open fun beforeSlotRender(context: DrawContext, slot: Slot) {} - open fun mouseScrolled(mouseX: Double, mouseY: Double, horizontalAmount: Double, verticalAmount: Double): Boolean { - return false - } - - open fun isClickOutsideBounds(mouseX: Double, mouseY: Double): Boolean { - return getBounds().none { it.contains(mouseX, mouseY) } - } - - open fun isPointWithinBounds( - x: Int, - y: Int, - width: Int, - height: Int, - pointX: Double, - pointY: Double, - ): Boolean { - return getBounds().any { it.contains(pointX, pointY) } && - Rectangle(x, y, width, height).contains(pointX, pointY) - } - - open fun isPointOverSlot(slot: Slot, xOffset: Int, yOffset: Int, pointX: Double, pointY: Double): Boolean { - return isPointWithinBounds(slot.x + xOffset, slot.y + yOffset, 16, 16, pointX, pointY) - } - - open fun onInit() {} - open fun shouldDrawForeground(): Boolean { - return true - } - - open fun onVoluntaryExit(): Boolean { - return true - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/customgui/HasCustomGui.kt b/src/main/kotlin/moe/nea/firmament/util/customgui/HasCustomGui.kt deleted file mode 100644 index edead2e..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/customgui/HasCustomGui.kt +++ /dev/null @@ -1,17 +0,0 @@ - -package moe.nea.firmament.util.customgui - -import net.minecraft.client.gui.screen.ingame.HandledScreen - -@Suppress("FunctionName") -interface HasCustomGui { - fun getCustomGui_Firmament(): CustomGui? - fun setCustomGui_Firmament(gui: CustomGui?) -} - -var <T : HandledScreen<*>> T.customGui: CustomGui? - get() = (this as HasCustomGui).getCustomGui_Firmament() - set(value) { - (this as HasCustomGui).setCustomGui_Firmament(value) - } - diff --git a/src/main/kotlin/moe/nea/firmament/util/data/DataHolder.kt b/src/main/kotlin/moe/nea/firmament/util/data/DataHolder.kt deleted file mode 100644 index 21a6014..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/data/DataHolder.kt +++ /dev/null @@ -1,62 +0,0 @@ - - -package moe.nea.firmament.util.data - -import java.nio.file.Path -import kotlinx.serialization.KSerializer -import kotlin.io.path.exists -import kotlin.io.path.readText -import kotlin.io.path.writeText -import moe.nea.firmament.Firmament - -abstract class DataHolder<T>( - val serializer: KSerializer<T>, - val name: String, - val default: () -> T -) : IDataHolder<T> { - - - final override var data: T - private set - - init { - data = readValueOrDefault() - IDataHolder.putDataHolder(this::class, this) - } - - private val file: Path get() = Firmament.CONFIG_DIR.resolve("$name.json") - - protected fun readValueOrDefault(): T { - if (file.exists()) - try { - return Firmament.json.decodeFromString( - serializer, - file.readText() - ) - } catch (e: Exception) {/* Expecting IOException and SerializationException, but Kotlin doesn't allow multi catches*/ - IDataHolder.badLoads.add(name) - Firmament.logger.error( - "Exception during loading of config file $name. This will reset this config.", - e - ) - } - return default() - } - - private fun writeValue(t: T) { - file.writeText(Firmament.json.encodeToString(serializer, t)) - } - - override fun save() { - writeValue(data) - } - - override fun load() { - data = readValueOrDefault() - } - - override fun markDirty() { - IDataHolder.markDirty(this::class) - } - -} diff --git a/src/main/kotlin/moe/nea/firmament/util/data/IDataHolder.kt b/src/main/kotlin/moe/nea/firmament/util/data/IDataHolder.kt deleted file mode 100644 index 5d09bcd..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/data/IDataHolder.kt +++ /dev/null @@ -1,77 +0,0 @@ - - -package moe.nea.firmament.util.data - -import java.util.concurrent.CopyOnWriteArrayList -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientLifecycleEvents -import kotlin.reflect.KClass -import net.minecraft.client.MinecraftClient -import net.minecraft.server.command.CommandOutput -import net.minecraft.text.Text -import moe.nea.firmament.Firmament -import moe.nea.firmament.events.ScreenChangeEvent - -interface IDataHolder<T> { - companion object { - internal var badLoads: MutableList<String> = CopyOnWriteArrayList() - private val allConfigs: MutableMap<KClass<out IDataHolder<*>>, IDataHolder<*>> = mutableMapOf() - private val dirty: MutableSet<KClass<out IDataHolder<*>>> = mutableSetOf() - - internal fun <T : IDataHolder<K>, K> putDataHolder(kClass: KClass<T>, inst: IDataHolder<K>) { - allConfigs[kClass] = inst - } - - fun <T : IDataHolder<K>, K> markDirty(kClass: KClass<T>) { - if (kClass !in allConfigs) { - Firmament.logger.error("Tried to markDirty '${kClass.qualifiedName}', which isn't registered as 'IConfigHolder'") - return - } - dirty.add(kClass) - } - - private fun performSaves() { - val toSave = dirty.toList().also { - dirty.clear() - } - for (it in toSave) { - val obj = allConfigs[it] - if (obj == null) { - Firmament.logger.error("Tried to save '${it}', which isn't registered as 'ConfigHolder'") - continue - } - obj.save() - } - } - - private fun warnForResetConfigs(player: CommandOutput) { - if (badLoads.isNotEmpty()) { - player.sendMessage( - Text.literal( - "The following configs have been reset: ${badLoads.joinToString(", ")}. " + - "This can be intentional, but probably isn't." - ) - ) - badLoads.clear() - } - } - - fun registerEvents() { - ScreenChangeEvent.subscribe { event -> - performSaves() - val p = MinecraftClient.getInstance().player - if (p != null) { - warnForResetConfigs(p) - } - } - ClientLifecycleEvents.CLIENT_STOPPING.register(ClientLifecycleEvents.ClientStopping { - performSaves() - }) - } - - } - - val data: T - fun save() - fun markDirty() - fun load() -} diff --git a/src/main/kotlin/moe/nea/firmament/util/data/ProfileSpecificDataHolder.kt b/src/main/kotlin/moe/nea/firmament/util/data/ProfileSpecificDataHolder.kt deleted file mode 100644 index 1cd4f22..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/data/ProfileSpecificDataHolder.kt +++ /dev/null @@ -1,84 +0,0 @@ - - -package moe.nea.firmament.util.data - -import java.nio.file.Path -import java.util.UUID -import kotlinx.serialization.KSerializer -import kotlin.io.path.createDirectories -import kotlin.io.path.deleteExisting -import kotlin.io.path.exists -import kotlin.io.path.extension -import kotlin.io.path.listDirectoryEntries -import kotlin.io.path.nameWithoutExtension -import kotlin.io.path.readText -import kotlin.io.path.writeText -import moe.nea.firmament.Firmament -import moe.nea.firmament.util.SBData - -abstract class ProfileSpecificDataHolder<S>( - private val dataSerializer: KSerializer<S>, - val configName: String, - private val configDefault: () -> S -) : IDataHolder<S?> { - - var allConfigs: MutableMap<UUID, S> - - override val data: S? - get() = SBData.profileId?.let { - allConfigs.computeIfAbsent(it) { configDefault() } - } - - init { - allConfigs = readValues() - IDataHolder.putDataHolder(this::class, this) - } - - private val configDirectory: Path get() = Firmament.CONFIG_DIR.resolve("profiles").resolve(configName) - - private fun readValues(): MutableMap<UUID, S> { - if (!configDirectory.exists()) { - configDirectory.createDirectories() - } - val profileFiles = configDirectory.listDirectoryEntries() - return profileFiles - .filter { it.extension == "json" } - .mapNotNull { - try { - UUID.fromString(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( - "Exception during loading of profile specific config file $it ($configName). This will reset that profiles config.", - e - ) - null - } - }.toMap().toMutableMap() - } - - override fun save() { - if (!configDirectory.exists()) { - configDirectory.createDirectories() - } - val c = allConfigs - configDirectory.listDirectoryEntries().forEach { - if (it.nameWithoutExtension !in c.mapKeys { it.toString() }) { - it.deleteExisting() - } - } - c.forEach { (name, value) -> - val f = configDirectory.resolve("$name.json") - f.writeText(Firmament.json.encodeToString(dataSerializer, value)) - } - } - - override fun markDirty() { - IDataHolder.markDirty(this::class) - } - - override fun load() { - allConfigs = readValues() - } - -} diff --git a/src/main/kotlin/moe/nea/firmament/util/filter/IteratorFilterSet.kt b/src/main/kotlin/moe/nea/firmament/util/filter/IteratorFilterSet.kt deleted file mode 100644 index 483b8d9..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/filter/IteratorFilterSet.kt +++ /dev/null @@ -1,33 +0,0 @@ - -package moe.nea.firmament.util.filter - -abstract class IteratorFilterSet<K>(val original: java.util.Set<K>) : java.util.Set<K> by original { - abstract fun shouldKeepElement(element: K): Boolean - - override fun iterator(): MutableIterator<K> { - val parentIterator = original.iterator() - return object : MutableIterator<K> { - var lastEntry: K? = null - override fun hasNext(): Boolean { - while (lastEntry == null) { - if (!parentIterator.hasNext()) - break - val element = parentIterator.next() - if (!shouldKeepElement(element)) continue - lastEntry = element - } - return lastEntry != null - } - - override fun next(): K { - if (!hasNext()) throw NoSuchElementException() - return lastEntry ?: throw NoSuchElementException() - } - - override fun remove() { - TODO("Not yet implemented") - } - } - } -} - diff --git a/src/main/kotlin/moe/nea/firmament/util/item/NbtItemData.kt b/src/main/kotlin/moe/nea/firmament/util/item/NbtItemData.kt deleted file mode 100644 index f7f259d..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/item/NbtItemData.kt +++ /dev/null @@ -1,24 +0,0 @@ - - -package moe.nea.firmament.util.item - -import net.minecraft.component.DataComponentTypes -import net.minecraft.component.type.LoreComponent -import net.minecraft.item.ItemStack -import net.minecraft.text.Text - -var ItemStack.loreAccordingToNbt - get() = get(DataComponentTypes.LORE)?.lines ?: listOf() - set(value) { - set(DataComponentTypes.LORE, LoreComponent(value)) - } - -var ItemStack.displayNameAccordingToNbt: Text - get() = get(DataComponentTypes.CUSTOM_NAME) ?: get(DataComponentTypes.ITEM_NAME) ?: item.name - set(value) { - set(DataComponentTypes.CUSTOM_NAME, value) - } - -fun ItemStack.setCustomName(text: Text) { - set(DataComponentTypes.CUSTOM_NAME, text) -} diff --git a/src/main/kotlin/moe/nea/firmament/util/item/SkullItemData.kt b/src/main/kotlin/moe/nea/firmament/util/item/SkullItemData.kt deleted file mode 100644 index ddab88e..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/item/SkullItemData.kt +++ /dev/null @@ -1,90 +0,0 @@ - - -@file:UseSerializers(DashlessUUIDSerializer::class, InstantAsLongSerializer::class) - -package moe.nea.firmament.util.item - -import com.mojang.authlib.GameProfile -import com.mojang.authlib.minecraft.MinecraftProfileTexture -import com.mojang.authlib.properties.Property -import java.util.UUID -import kotlinx.datetime.Clock -import kotlinx.datetime.Instant -import kotlinx.serialization.Serializable -import kotlinx.serialization.UseSerializers -import kotlinx.serialization.encodeToString -import net.minecraft.component.DataComponentTypes -import net.minecraft.component.type.ProfileComponent -import net.minecraft.item.ItemStack -import net.minecraft.item.Items -import moe.nea.firmament.Firmament -import moe.nea.firmament.util.Base64Util.padToValidBase64 -import moe.nea.firmament.util.assertTrueOr -import moe.nea.firmament.util.json.DashlessUUIDSerializer -import moe.nea.firmament.util.json.InstantAsLongSerializer - -@Serializable -data class MinecraftProfileTextureKt( - val url: String, - val metadata: Map<String, String> = mapOf(), -) - -@Serializable -data class MinecraftTexturesPayloadKt( - val textures: Map<MinecraftProfileTexture.Type, MinecraftProfileTextureKt> = mapOf(), - val profileId: UUID? = null, - val profileName: String? = null, - val isPublic: Boolean = true, - val timestamp: Instant = Clock.System.now(), -) - -fun GameProfile.setTextures(textures: MinecraftTexturesPayloadKt) { - val json = Firmament.json.encodeToString(textures) - val encoded = java.util.Base64.getEncoder().encodeToString(json.encodeToByteArray()) - properties.put(propertyTextures, Property(propertyTextures, encoded)) -} - -private val propertyTextures = "textures" - -fun ItemStack.setEncodedSkullOwner(uuid: UUID, encodedData: String) { - assert(this.item == Items.PLAYER_HEAD) - val gameProfile = GameProfile(uuid, "LameGuy123") - gameProfile.properties.put(propertyTextures, Property(propertyTextures, encodedData.padToValidBase64())) - this.set(DataComponentTypes.PROFILE, ProfileComponent(gameProfile)) -} - -val zeroUUID = UUID.fromString("d3cb85e2-3075-48a1-b213-a9bfb62360c1") -fun createSkullItem(uuid: UUID, url: String) = ItemStack(Items.PLAYER_HEAD) - .also { it.setSkullOwner(uuid, url) } - -fun ItemStack.setSkullOwner(uuid: UUID, url: String) { - assert(this.item == Items.PLAYER_HEAD) - val gameProfile = GameProfile(uuid, "nea89") - gameProfile.setTextures( - MinecraftTexturesPayloadKt( - textures = mapOf(MinecraftProfileTexture.Type.SKIN to MinecraftProfileTextureKt(url)), - profileId = uuid, - profileName = "nea89", - ) - ) - this.set(DataComponentTypes.PROFILE, ProfileComponent(gameProfile)) -} - - -fun decodeProfileTextureProperty(property: Property): MinecraftTexturesPayloadKt? { - assertTrueOr(property.name == propertyTextures) { return null } - return try { - var encodedF: String = property.value - while (encodedF.length % 4 != 0 && encodedF.last() == '=') { - encodedF = encodedF.substring(0, encodedF.length - 1) - } - val json = java.util.Base64.getDecoder().decode(encodedF).decodeToString() - Firmament.json.decodeFromString<MinecraftTexturesPayloadKt>(json) - } catch (e: Exception) { - // Malformed profile data - if (Firmament.DEBUG) - e.printStackTrace() - null - } -} - diff --git a/src/main/kotlin/moe/nea/firmament/util/json/BlockPosSerializer.kt b/src/main/kotlin/moe/nea/firmament/util/json/BlockPosSerializer.kt deleted file mode 100644 index 144b0a0..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/json/BlockPosSerializer.kt +++ /dev/null @@ -1,25 +0,0 @@ -package moe.nea.firmament.util.json - -import kotlinx.serialization.KSerializer -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder -import kotlinx.serialization.serializer -import net.minecraft.util.math.BlockPos - -object BlockPosSerializer : KSerializer<BlockPos> { - val delegate = serializer<List<Int>>() - - override val descriptor: SerialDescriptor - get() = SerialDescriptor("BlockPos", delegate.descriptor) - - override fun deserialize(decoder: Decoder): BlockPos { - val list = decoder.decodeSerializableValue(delegate) - require(list.size == 3) - return BlockPos(list[0], list[1], list[2]) - } - - override fun serialize(encoder: Encoder, value: BlockPos) { - encoder.encodeSerializableValue(delegate, listOf(value.x, value.y, value.z)) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/json/DashlessUUIDSerializer.kt b/src/main/kotlin/moe/nea/firmament/util/json/DashlessUUIDSerializer.kt deleted file mode 100644 index acb1dc8..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/json/DashlessUUIDSerializer.kt +++ /dev/null @@ -1,29 +0,0 @@ - - -package moe.nea.firmament.util.json - -import java.util.UUID -import kotlinx.serialization.KSerializer -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder -import moe.nea.firmament.util.parseDashlessUUID - -object DashlessUUIDSerializer : KSerializer<UUID> { - override val descriptor: SerialDescriptor = - PrimitiveSerialDescriptor("DashlessUUIDSerializer", PrimitiveKind.STRING) - - override fun deserialize(decoder: Decoder): UUID { - val str = decoder.decodeString() - if ("-" in str) { - return UUID.fromString(str) - } - return parseDashlessUUID(str) - } - - override fun serialize(encoder: Encoder, value: UUID) { - encoder.encodeString(value.toString().replace("-", "")) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/json/InstantAsLongSerializer.kt b/src/main/kotlin/moe/nea/firmament/util/json/InstantAsLongSerializer.kt deleted file mode 100644 index ad738dc..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/json/InstantAsLongSerializer.kt +++ /dev/null @@ -1,22 +0,0 @@ - - -package moe.nea.firmament.util.json - -import kotlinx.datetime.Instant -import kotlinx.serialization.KSerializer -import kotlinx.serialization.descriptors.PrimitiveKind -import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder - -object InstantAsLongSerializer : KSerializer<Instant> { - override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("InstantAsLongSerializer", PrimitiveKind.LONG) - override fun deserialize(decoder: Decoder): Instant { - return Instant.fromEpochMilliseconds(decoder.decodeLong()) - } - - override fun serialize(encoder: Encoder, value: Instant) { - encoder.encodeLong(value.toEpochMilliseconds()) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/json/SingletonSerializableList.kt b/src/main/kotlin/moe/nea/firmament/util/json/SingletonSerializableList.kt deleted file mode 100644 index aa543d6..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/json/SingletonSerializableList.kt +++ /dev/null @@ -1,31 +0,0 @@ - -package moe.nea.firmament.util.json - -import kotlinx.serialization.KSerializer -import kotlinx.serialization.builtins.ListSerializer -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder -import kotlinx.serialization.json.JsonArray -import kotlinx.serialization.json.JsonDecoder -import kotlinx.serialization.json.JsonElement - -class SingletonSerializableList<T>(val child: KSerializer<T>) : KSerializer<List<T>> { - override val descriptor: SerialDescriptor - get() = JsonElement.serializer().descriptor - - override fun deserialize(decoder: Decoder): List<T> { - decoder as JsonDecoder - val list = JsonElement.serializer().deserialize(decoder) - if (list is JsonArray) { - return list.map { - decoder.json.decodeFromJsonElement(child, it) - } - } - return listOf(decoder.json.decodeFromJsonElement(child, list)) - } - - override fun serialize(encoder: Encoder, value: List<T>) { - ListSerializer(child).serialize(encoder, value) - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/listutil.kt b/src/main/kotlin/moe/nea/firmament/util/listutil.kt deleted file mode 100644 index 73cb23e..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/listutil.kt +++ /dev/null @@ -1,9 +0,0 @@ - -package moe.nea.firmament.util - -fun <T, R> List<T>.lastNotNullOfOrNull(func: (T) -> R?): R? { - for (i in indices.reversed()) { - return func(this[i]) ?: continue - } - return null -} diff --git a/src/main/kotlin/moe/nea/firmament/util/propertyutil.kt b/src/main/kotlin/moe/nea/firmament/util/propertyutil.kt deleted file mode 100644 index 795a0d2..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/propertyutil.kt +++ /dev/null @@ -1,9 +0,0 @@ - - -package moe.nea.firmament.util - -import kotlin.properties.ReadOnlyProperty - -fun <T, V, M> ReadOnlyProperty<T, V>.map(mapper: (V) -> M): ReadOnlyProperty<T, M> { - return ReadOnlyProperty { thisRef, property -> mapper(this@map.getValue(thisRef, property)) } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/regex.kt b/src/main/kotlin/moe/nea/firmament/util/regex.kt deleted file mode 100644 index 3ce5bd8..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/regex.kt +++ /dev/null @@ -1,55 +0,0 @@ - - -package moe.nea.firmament.util - -import java.util.regex.Matcher -import java.util.regex.Pattern -import org.intellij.lang.annotations.Language -import kotlin.time.Duration -import kotlin.time.Duration.Companion.minutes -import kotlin.time.Duration.Companion.seconds - -inline fun <T> String.ifMatches(regex: Regex, block: (MatchResult) -> T): T? = - regex.matchEntire(this)?.let(block) - -inline fun <T> Pattern.useMatch(string: String, block: Matcher.() -> T): T? = - matcher(string) - .takeIf(Matcher::matches) - ?.let(block) - -@Language("RegExp") -val TIME_PATTERN = "[0-9]+[ms]" - -@Language("RegExp") -val SHORT_NUMBER_FORMAT = "[0-9]+(?:,[0-9]+)*(?:\\.[0-9]+)?[kKmMbB]?" - - -val siScalars = mapOf( - 'k' to 1_000.0, - 'K' to 1_000.0, - 'm' to 1_000_000.0, - 'M' to 1_000_000.0, - 'b' to 1_000_000_000.0, - 'B' to 1_000_000_000.0, -) - -fun parseTimePattern(text: String): Duration { - val length = text.dropLast(1).toInt() - return when (text.last()) { - 'm' -> length.minutes - 's' -> length.seconds - else -> error("Invalid pattern for time $text") - } -} - -fun parseShortNumber(string: String): Double { - var k = string.replace(",", "") - val scalar = k.last() - var scalarMultiplier = siScalars[scalar] - if (scalarMultiplier == null) { - scalarMultiplier = 1.0 - } else { - k = k.dropLast(1) - } - return k.toDouble() * scalarMultiplier -} diff --git a/src/main/kotlin/moe/nea/firmament/util/render/FacingThePlayerContext.kt b/src/main/kotlin/moe/nea/firmament/util/render/FacingThePlayerContext.kt deleted file mode 100644 index eb37e35..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/render/FacingThePlayerContext.kt +++ /dev/null @@ -1,101 +0,0 @@ - -package moe.nea.firmament.util.render - -import com.mojang.blaze3d.systems.RenderSystem -import io.github.notenoughupdates.moulconfig.platform.next -import org.joml.Matrix4f -import net.minecraft.client.font.TextRenderer -import net.minecraft.client.render.BufferRenderer -import net.minecraft.client.render.GameRenderer -import net.minecraft.client.render.LightmapTextureManager -import net.minecraft.client.render.RenderLayer -import net.minecraft.client.render.Tessellator -import net.minecraft.client.render.VertexConsumer -import net.minecraft.client.render.VertexFormat -import net.minecraft.client.render.VertexFormats -import net.minecraft.text.Text -import net.minecraft.util.Identifier -import net.minecraft.util.math.BlockPos -import moe.nea.firmament.util.FirmFormatters -import moe.nea.firmament.util.MC -import moe.nea.firmament.util.assertTrueOr - -@RenderContextDSL -class FacingThePlayerContext(val worldContext: RenderInWorldContext) { - val matrixStack by worldContext::matrixStack - fun waypoint(position: BlockPos, label: Text) { - text( - label, - Text.literal("§e${FirmFormatters.formatDistance(MC.player?.pos?.distanceTo(position.toCenterPos()) ?: 42069.0)}") - ) - } - - fun text( - vararg texts: Text, - verticalAlign: RenderInWorldContext.VerticalAlign = RenderInWorldContext.VerticalAlign.CENTER, - background: Int = 0x70808080, - ) { - assertTrueOr(texts.isNotEmpty()) { return@text } - for ((index, text) in texts.withIndex()) { - worldContext.matrixStack.push() - val width = MC.font.getWidth(text) - worldContext.matrixStack.translate(-width / 2F, verticalAlign.align(index, texts.size), 0F) - val vertexConsumer: VertexConsumer = - worldContext.vertexConsumers.getBuffer(RenderLayer.getTextBackgroundSeeThrough()) - val matrix4f = worldContext.matrixStack.peek().positionMatrix - vertexConsumer.vertex(matrix4f, -1.0f, -1.0f, 0.0f).color(background) - .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() - vertexConsumer.vertex(matrix4f, -1.0f, MC.font.fontHeight.toFloat(), 0.0f).color(background) - .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() - vertexConsumer.vertex(matrix4f, width.toFloat(), MC.font.fontHeight.toFloat(), 0.0f) - .color(background) - .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() - vertexConsumer.vertex(matrix4f, width.toFloat(), -1.0f, 0.0f).color(background) - .light(LightmapTextureManager.MAX_BLOCK_LIGHT_COORDINATE).next() - worldContext.matrixStack.translate(0F, 0F, 0.01F) - - MC.font.draw( - text, - 0F, - 0F, - -1, - false, - worldContext.matrixStack.peek().positionMatrix, - worldContext.vertexConsumers, - TextRenderer.TextLayerType.SEE_THROUGH, - 0, - LightmapTextureManager.MAX_LIGHT_COORDINATE - ) - worldContext.matrixStack.pop() - } - } - - - fun texture( - texture: Identifier, width: Int, height: Int, - u1: Float, v1: Float, - u2: Float, v2: Float, - ) { - RenderSystem.setShaderTexture(0, texture) - RenderSystem.setShader(GameRenderer::getPositionTexColorProgram) - val hw = width / 2F - val hh = height / 2F - val matrix4f: Matrix4f = worldContext.matrixStack.peek().positionMatrix - val buf = Tessellator.getInstance() - .begin(VertexFormat.DrawMode.QUADS, VertexFormats.POSITION_TEXTURE_COLOR) - buf.vertex(matrix4f, -hw, -hh, 0F) - .color(-1) - .texture(u1, v1).next() - buf.vertex(matrix4f, -hw, +hh, 0F) - .color(-1) - .texture(u1, v2).next() - buf.vertex(matrix4f, +hw, +hh, 0F) - .color(-1) - .texture(u2, v2).next() - buf.vertex(matrix4f, +hw, -hh, 0F) - .color(-1) - .texture(u2, v1).next() - BufferRenderer.drawWithGlobalProgram(buf.end()) - } - -} diff --git a/src/main/kotlin/moe/nea/firmament/util/render/LerpUtils.kt b/src/main/kotlin/moe/nea/firmament/util/render/LerpUtils.kt deleted file mode 100644 index f2c2f25..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/render/LerpUtils.kt +++ /dev/null @@ -1,33 +0,0 @@ - -package moe.nea.firmament.util.render - -import me.shedaniel.math.Color - -val pi = Math.PI -val tau = Math.PI * 2 -fun lerpAngle(a: Float, b: Float, progress: Float): Float { - // TODO: there is at least 10 mods to many in here lol - val shortestAngle = ((((b.mod(tau) - a.mod(tau)).mod(tau)) + tau + pi).mod(tau)) - pi - return ((a + (shortestAngle) * progress).mod(tau)).toFloat() -} - -fun lerp(a: Float, b: Float, progress: Float): Float { - return a + (b - a) * progress -} -fun lerp(a: Int, b: Int, progress: Float): Int { - return (a + (b - a) * progress).toInt() -} - -fun ilerp(a: Float, b: Float, value: Float): Float { - return (value - a) / (b - a) -} - -fun lerp(a: Color, b: Color, progress: Float): Color { - return Color.ofRGBA( - lerp(a.red, b.red, progress), - lerp(a.green, b.green, progress), - lerp(a.blue, b.blue, progress), - lerp(a.alpha, b.alpha, progress), - ) -} - diff --git a/src/main/kotlin/moe/nea/firmament/util/render/RenderCircleProgress.kt b/src/main/kotlin/moe/nea/firmament/util/render/RenderCircleProgress.kt deleted file mode 100644 index a2f42b5..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/render/RenderCircleProgress.kt +++ /dev/null @@ -1,95 +0,0 @@ - -package moe.nea.firmament.util.render - -import com.mojang.blaze3d.systems.RenderSystem -import io.github.notenoughupdates.moulconfig.platform.next -import org.joml.Matrix4f -import org.joml.Vector2f -import kotlin.math.atan2 -import kotlin.math.tan -import net.minecraft.client.gui.DrawContext -import net.minecraft.client.render.BufferRenderer -import net.minecraft.client.render.GameRenderer -import net.minecraft.client.render.Tessellator -import net.minecraft.client.render.VertexFormat.DrawMode -import net.minecraft.client.render.VertexFormats -import net.minecraft.util.Identifier - -object RenderCircleProgress { - - fun renderCircle( - drawContext: DrawContext, - texture: Identifier, - progress: Float, - u1: Float, - u2: Float, - v1: Float, - v2: Float, - ) { - RenderSystem.setShaderTexture(0, texture) - RenderSystem.setShader(GameRenderer::getPositionTexColorProgram) - RenderSystem.enableBlend() - val matrix: Matrix4f = drawContext.matrices.peek().positionMatrix - val bufferBuilder = Tessellator.getInstance().begin(DrawMode.TRIANGLES, VertexFormats.POSITION_TEXTURE_COLOR) - - val corners = listOf( - Vector2f(0F, -1F), - Vector2f(1F, -1F), - Vector2f(1F, 0F), - Vector2f(1F, 1F), - Vector2f(0F, 1F), - Vector2f(-1F, 1F), - Vector2f(-1F, 0F), - Vector2f(-1F, -1F), - ) - - for (i in (0 until 8)) { - if (progress < i / 8F) { - break - } - val second = corners[(i + 1) % 8] - val first = corners[i] - if (progress <= (i + 1) / 8F) { - val internalProgress = 1 - (progress - i / 8F) * 8F - val angle = lerpAngle( - atan2(second.y, second.x), - atan2(first.y, first.x), - internalProgress - ) - if (angle < tau / 8 || angle >= tau * 7 / 8) { - second.set(1F, tan(angle)) - } else if (angle < tau * 3 / 8) { - second.set(1 / tan(angle), 1F) - } else if (angle < tau * 5 / 8) { - second.set(-1F, -tan(angle)) - } else { - second.set(-1 / tan(angle), -1F) - } - } - - fun ilerp(f: Float): Float = - ilerp(-1f, 1f, f) - - bufferBuilder - .vertex(matrix, second.x, second.y, 0F) - .texture(lerp(u1, u2, ilerp(second.x)), lerp(v1, v2, ilerp(second.y))) - .color(-1) - .next() - bufferBuilder - .vertex(matrix, first.x, first.y, 0F) - .texture(lerp(u1, u2, ilerp(first.x)), lerp(v1, v2, ilerp(first.y))) - .color(-1) - .next() - bufferBuilder - .vertex(matrix, 0F, 0F, 0F) - .texture(lerp(u1, u2, ilerp(0F)), lerp(v1, v2, ilerp(0F))) - .color(-1) - .next() - } - BufferRenderer.drawWithGlobalProgram(bufferBuilder.end()) - RenderSystem.disableBlend() - } - - - -} diff --git a/src/main/kotlin/moe/nea/firmament/util/render/RenderContextDSL.kt b/src/main/kotlin/moe/nea/firmament/util/render/RenderContextDSL.kt deleted file mode 100644 index 9bb4431..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/render/RenderContextDSL.kt +++ /dev/null @@ -1,6 +0,0 @@ - -package moe.nea.firmament.util.render - -@DslMarker -annotation class RenderContextDSL { -} diff --git a/src/main/kotlin/moe/nea/firmament/util/render/RenderInWorldContext.kt b/src/main/kotlin/moe/nea/firmament/util/render/RenderInWorldContext.kt deleted file mode 100644 index 7faa499..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/render/RenderInWorldContext.kt +++ /dev/null @@ -1,294 +0,0 @@ - - -package moe.nea.firmament.util.render - -import com.mojang.blaze3d.systems.RenderSystem -import io.github.notenoughupdates.moulconfig.platform.next -import java.lang.Math.pow -import org.joml.Matrix4f -import org.joml.Vector3f -import net.minecraft.client.gl.VertexBuffer -import net.minecraft.client.render.BufferBuilder -import net.minecraft.client.render.BufferRenderer -import net.minecraft.client.render.Camera -import net.minecraft.client.render.GameRenderer -import net.minecraft.client.render.RenderLayer -import net.minecraft.client.render.RenderPhase -import net.minecraft.client.render.RenderTickCounter -import net.minecraft.client.render.Tessellator -import net.minecraft.client.render.VertexConsumerProvider -import net.minecraft.client.render.VertexFormat -import net.minecraft.client.render.VertexFormats -import net.minecraft.client.texture.Sprite -import net.minecraft.client.util.math.MatrixStack -import net.minecraft.text.Text -import net.minecraft.util.Identifier -import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Vec3d -import moe.nea.firmament.events.WorldRenderLastEvent -import moe.nea.firmament.util.FirmFormatters -import moe.nea.firmament.util.MC - -@RenderContextDSL -class RenderInWorldContext private constructor( - private val tesselator: Tessellator, - val matrixStack: MatrixStack, - private val camera: Camera, - private val tickCounter: RenderTickCounter, - val vertexConsumers: VertexConsumerProvider.Immediate, -) { - - object RenderLayers { - val TRANSLUCENT_TRIS = RenderLayer.of("firmament_translucent_tris", - VertexFormats.POSITION_COLOR, - VertexFormat.DrawMode.TRIANGLES, - RenderLayer.DEFAULT_BUFFER_SIZE, - false, true, - RenderLayer.MultiPhaseParameters.builder() - .depthTest(RenderPhase.ALWAYS_DEPTH_TEST) - .transparency(RenderPhase.TRANSLUCENT_TRANSPARENCY) - .program(RenderPhase.COLOR_PROGRAM) - .build(false)) - } - - fun color(color: me.shedaniel.math.Color) { - color(color.red / 255F, color.green / 255f, color.blue / 255f, color.alpha / 255f) - } - - fun color(red: Float, green: Float, blue: Float, alpha: Float) { - RenderSystem.setShaderColor(red, green, blue, alpha) - } - - fun block(blockPos: BlockPos) { - matrixStack.push() - matrixStack.translate(blockPos.x.toFloat(), blockPos.y.toFloat(), blockPos.z.toFloat()) - buildCube(matrixStack.peek().positionMatrix, tesselator) - matrixStack.pop() - } - - enum class VerticalAlign { - TOP, BOTTOM, CENTER; - - fun align(index: Int, count: Int): Float { - return when (this) { - CENTER -> (index - count / 2F) * (1 + MC.font.fontHeight.toFloat()) - BOTTOM -> (index - count) * (1 + MC.font.fontHeight.toFloat()) - TOP -> (index) * (1 + MC.font.fontHeight.toFloat()) - } - } - } - - fun waypoint(position: BlockPos, vararg label: Text) { - text( - position.toCenterPos(), - *label, - Text.literal("§e${FirmFormatters.formatDistance(MC.player?.pos?.distanceTo(position.toCenterPos()) ?: 42069.0)}"), - background = 0xAA202020.toInt() - ) - } - - fun withFacingThePlayer(position: Vec3d, block: FacingThePlayerContext.() -> Unit) { - matrixStack.push() - matrixStack.translate(position.x, position.y, position.z) - val actualCameraDistance = position.distanceTo(camera.pos) - val distanceToMoveTowardsCamera = if (actualCameraDistance < 10) 0.0 else -(actualCameraDistance - 10.0) - val vec = position.subtract(camera.pos).multiply(distanceToMoveTowardsCamera / actualCameraDistance) - matrixStack.translate(vec.x, vec.y, vec.z) - matrixStack.multiply(camera.rotation) - matrixStack.scale(0.025F, -0.025F, 1F) - - FacingThePlayerContext(this).run(block) - - matrixStack.pop() - vertexConsumers.drawCurrentLayer() - } - - fun sprite(position: Vec3d, sprite: Sprite, width: Int, height: Int) { - texture( - position, sprite.atlasId, width, height, sprite.minU, sprite.minV, sprite.maxU, sprite.maxV - ) - } - - fun texture( - position: Vec3d, texture: Identifier, width: Int, height: Int, - u1: Float, v1: Float, - u2: Float, v2: Float, - ) { - withFacingThePlayer(position) { - texture(texture, width, height, u1, v1, u2, v2) - } - } - - fun text(position: Vec3d, vararg texts: Text, verticalAlign: VerticalAlign = VerticalAlign.CENTER, background: Int = 0x70808080) { - withFacingThePlayer(position) { - text(*texts, verticalAlign = verticalAlign, background = background) - } - } - - fun tinyBlock(vec3d: Vec3d, size: Float) { - RenderSystem.setShader(GameRenderer::getPositionColorProgram) - matrixStack.push() - matrixStack.translate(vec3d.x, vec3d.y, vec3d.z) - matrixStack.scale(size, size, size) - matrixStack.translate(-.5, -.5, -.5) - buildCube(matrixStack.peek().positionMatrix, tesselator) - matrixStack.pop() - } - - fun wireframeCube(blockPos: BlockPos, lineWidth: Float = 10F) { - RenderSystem.setShader(GameRenderer::getRenderTypeLinesProgram) - matrixStack.push() - RenderSystem.lineWidth(lineWidth / pow(camera.pos.squaredDistanceTo(blockPos.toCenterPos()), 0.25).toFloat()) - matrixStack.translate(blockPos.x.toFloat(), blockPos.y.toFloat(), blockPos.z.toFloat()) - buildWireFrameCube(matrixStack.peek(), tesselator) - matrixStack.pop() - } - - fun line(vararg points: Vec3d, lineWidth: Float = 10F) { - line(points.toList(), lineWidth) - } - - fun tracer(toWhere: Vec3d, lineWidth: Float = 3f) { - val cameraForward = Vector3f(0f, 0f, 1f).rotate(camera.rotation) - line(camera.pos.add(Vec3d(cameraForward)), toWhere, lineWidth = lineWidth) - } - - fun line(points: List<Vec3d>, lineWidth: Float = 10F) { - RenderSystem.setShader(GameRenderer::getRenderTypeLinesProgram) - RenderSystem.lineWidth(lineWidth) - val buffer = tesselator.begin(VertexFormat.DrawMode.LINES, VertexFormats.LINES) - - val matrix = matrixStack.peek() - var lastNormal: Vector3f? = null - points.zipWithNext().forEach { (a, b) -> - val normal = Vector3f(b.x.toFloat(), b.y.toFloat(), b.z.toFloat()) - .sub(a.x.toFloat(), a.y.toFloat(), a.z.toFloat()) - .normalize() - val lastNormal0 = lastNormal ?: normal - lastNormal = normal - buffer.vertex(matrix.positionMatrix, a.x.toFloat(), a.y.toFloat(), a.z.toFloat()) - .color(-1) - .normal(matrix, lastNormal0.x, lastNormal0.y, lastNormal0.z) - .next() - buffer.vertex(matrix.positionMatrix, b.x.toFloat(), b.y.toFloat(), b.z.toFloat()) - .color(-1) - .normal(matrix, normal.x, normal.y, normal.z) - .next() - } - - BufferRenderer.drawWithGlobalProgram(buffer.end()) - } - - companion object { - private fun doLine( - matrix: MatrixStack.Entry, - buf: BufferBuilder, - i: Float, - j: Float, - k: Float, - x: Float, - y: Float, - z: Float - ) { - val normal = Vector3f(x, y, z) - .sub(i, j, k) - .normalize() - buf.vertex(matrix.positionMatrix, i, j, k) - .normal(matrix, normal.x, normal.y, normal.z) - .color(-1) - .next() - buf.vertex(matrix.positionMatrix, x, y, z) - .normal(matrix, normal.x, normal.y, normal.z) - .color(-1) - .next() - } - - - private fun buildWireFrameCube(matrix: MatrixStack.Entry, tessellator: Tessellator) { - val buf = tessellator.begin(VertexFormat.DrawMode.LINES, VertexFormats.LINES) - - for (i in 0..1) { - for (j in 0..1) { - val i = i.toFloat() - val j = j.toFloat() - doLine(matrix, buf, 0F, i, j, 1F, i, j) - doLine(matrix, buf, i, 0F, j, i, 1F, j) - doLine(matrix, buf, i, j, 0F, i, j, 1F) - } - } - BufferRenderer.drawWithGlobalProgram(buf.end()) - } - - private fun buildCube(matrix: Matrix4f, tessellator: Tessellator) { - val buf = tessellator.begin(VertexFormat.DrawMode.TRIANGLES, VertexFormats.POSITION_COLOR) - buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 0.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 1.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 1.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 0.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 1.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 0.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 1.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 0.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 0.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 0.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 0.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 1.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 0.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 1.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 1.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 1.0F, 0.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 1.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 0.0F, 1.0F, 1.0F).color(-1).next() - buf.vertex(matrix, 1.0F, 0.0F, 1.0F).color(-1).next() - RenderLayers.TRANSLUCENT_TRIS.draw(buf.end()) - } - - - fun renderInWorld(event: WorldRenderLastEvent, block: RenderInWorldContext. () -> Unit) { - RenderSystem.disableDepthTest() - RenderSystem.enableBlend() - RenderSystem.defaultBlendFunc() - RenderSystem.disableCull() - - event.matrices.push() - event.matrices.translate(-event.camera.pos.x, -event.camera.pos.y, -event.camera.pos.z) - - val ctx = RenderInWorldContext( - RenderSystem.renderThreadTesselator(), - event.matrices, - event.camera, - event.tickCounter, - event.vertexConsumers - ) - - block(ctx) - - event.matrices.pop() - - RenderSystem.setShaderColor(1F, 1F, 1F, 1F) - VertexBuffer.unbind() - RenderSystem.enableDepthTest() - RenderSystem.enableCull() - RenderSystem.disableBlend() - } - } -} - - diff --git a/src/main/kotlin/moe/nea/firmament/util/render/TranslatedScissors.kt b/src/main/kotlin/moe/nea/firmament/util/render/TranslatedScissors.kt deleted file mode 100644 index c1e6544..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/render/TranslatedScissors.kt +++ /dev/null @@ -1,22 +0,0 @@ - -package moe.nea.firmament.util.render - -import org.joml.Vector4f -import net.minecraft.client.gui.DrawContext - -fun DrawContext.enableScissorWithTranslation(x1: Float, y1: Float, x2: Float, y2: Float) { - val pMat = matrices.peek().positionMatrix - val target = Vector4f() - - target.set(x1, y1, 0f, 1f) - target.mul(pMat) - val scissorX1 = target.x - val scissorY1 = target.y - - target.set(x2, y2, 0f, 1f) - target.mul(pMat) - val scissorX2 = target.x - val scissorY2 = target.y - - enableScissor(scissorX1.toInt(), scissorY1.toInt(), scissorX2.toInt(), scissorY2.toInt()) -} diff --git a/src/main/kotlin/moe/nea/firmament/util/stringutil.kt b/src/main/kotlin/moe/nea/firmament/util/stringutil.kt deleted file mode 100644 index 56f8dbe..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/stringutil.kt +++ /dev/null @@ -1,6 +0,0 @@ - -package moe.nea.firmament.util - -fun parseIntWithComma(string: String): Int { - return string.replace(",", "").toInt() -} diff --git a/src/main/kotlin/moe/nea/firmament/util/textutil.kt b/src/main/kotlin/moe/nea/firmament/util/textutil.kt deleted file mode 100644 index a05733c..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/textutil.kt +++ /dev/null @@ -1,117 +0,0 @@ - - -package moe.nea.firmament.util - -import net.minecraft.text.MutableText -import net.minecraft.text.PlainTextContent -import net.minecraft.text.Style -import net.minecraft.text.Text -import net.minecraft.text.TranslatableTextContent -import net.minecraft.util.Formatting -import moe.nea.firmament.Firmament - - -class TextMatcher(text: Text) { - data class State( - var iterator: MutableList<Text>, - var currentText: Text?, - var offset: Int, - var textContent: String, - ) - - var state = State( - mutableListOf(text), - null, - 0, - "" - ) - - fun pollChunk(): Boolean { - val firstOrNull = state.iterator.removeFirstOrNull() ?: return false - state.offset = 0 - state.currentText = firstOrNull - state.textContent = when (val content = firstOrNull.content) { - is PlainTextContent.Literal -> content.string - else -> { - Firmament.logger.warn("TextContent of type ${content.javaClass} not understood.") - return false - } - } - state.iterator.addAll(0, firstOrNull.siblings) - return true - } - - fun pollChunks(): Boolean { - while (state.offset !in state.textContent.indices) { - if (!pollChunk()) { - return false - } - } - return true - } - - fun pollChar(): Char? { - if (!pollChunks()) return null - return state.textContent[state.offset++] - } - - - fun expectString(string: String): Boolean { - var found = "" - while (found.length < string.length) { - if (!pollChunks()) return false - val takeable = state.textContent.drop(state.offset).take(string.length - found.length) - state.offset += takeable.length - found += takeable - } - return found == string - } -} - -val formattingChars = "kmolnrKMOLNR".toSet() -fun CharSequence.removeColorCodes(keepNonColorCodes: Boolean = false): String { - var nextParagraph = indexOf('§') - if (nextParagraph < 0) return this.toString() - val stringBuffer = StringBuilder(this.length) - var readIndex = 0 - while (nextParagraph >= 0) { - stringBuffer.append(this, readIndex, nextParagraph) - if (keepNonColorCodes && nextParagraph + 1 < length && this[nextParagraph + 1] in formattingChars) { - readIndex = nextParagraph - nextParagraph = indexOf('§', startIndex = readIndex + 1) - } else { - readIndex = nextParagraph + 2 - nextParagraph = indexOf('§', startIndex = readIndex) - } - if (readIndex > this.length) - readIndex = this.length - } - stringBuffer.append(this, readIndex, this.length) - return stringBuffer.toString() -} - -val Text.unformattedString: String - get() = string.removeColorCodes() - - -fun MutableText.withColor(formatting: Formatting) = this.styled { it.withColor(formatting).withItalic(false) } - -fun Text.transformEachRecursively(function: (Text) -> Text): Text { - val c = this.content - if (c is TranslatableTextContent) { - return Text.translatableWithFallback(c.key, c.fallback, *c.args.map { - (if (it is Text) it else Text.literal(it.toString())).transformEachRecursively(function) - }.toTypedArray()).also { new -> - new.style = this.style - new.siblings.clear() - this.siblings.forEach { child -> - new.siblings.add(child.transformEachRecursively(function)) - } - } - } - return function(this.copy().also { it.siblings.clear() }).also { tt -> - this.siblings.forEach { - tt.siblings.add(it.transformEachRecursively(function)) - } - } -} diff --git a/src/main/kotlin/moe/nea/firmament/util/uuid.kt b/src/main/kotlin/moe/nea/firmament/util/uuid.kt deleted file mode 100644 index 4aa0749..0000000 --- a/src/main/kotlin/moe/nea/firmament/util/uuid.kt +++ /dev/null @@ -1,12 +0,0 @@ - - -package moe.nea.firmament.util - -import java.math.BigInteger -import java.util.UUID - -fun parseDashlessUUID(dashlessUuid: String): UUID { - val most = BigInteger(dashlessUuid.substring(0, 16), 16) - val least = BigInteger(dashlessUuid.substring(16, 32), 16) - return UUID(most.toLong(), least.toLong()) -} |