diff options
author | nea <nea@nea.moe> | 2023-05-16 01:23:43 +0200 |
---|---|---|
committer | nea <nea@nea.moe> | 2023-05-16 01:23:43 +0200 |
commit | ead6762eb1c005914b05f9d3c29f334989c67513 (patch) | |
tree | cd1409756be2bc4a93195c31d432fef053afe002 /src/main/kotlin/moe/nea/notenoughupdates/util | |
parent | 96c546cc73880a7c502c17aadda6ca84c847692d (diff) | |
download | Firmament-ead6762eb1c005914b05f9d3c29f334989c67513.tar.gz Firmament-ead6762eb1c005914b05f9d3c29f334989c67513.tar.bz2 Firmament-ead6762eb1c005914b05f9d3c29f334989c67513.zip |
Replace references to NEU with Firmament
Diffstat (limited to 'src/main/kotlin/moe/nea/notenoughupdates/util')
17 files changed, 0 insertions, 1103 deletions
diff --git a/src/main/kotlin/moe/nea/notenoughupdates/util/ItemUtil.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/ItemUtil.kt deleted file mode 100644 index 2fbff87..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/ItemUtil.kt +++ /dev/null @@ -1,24 +0,0 @@ -package moe.nea.notenoughupdates.util - -import net.minecraft.item.ItemStack -import net.minecraft.nbt.NbtCompound -import net.minecraft.nbt.NbtList -import net.minecraft.nbt.NbtString -import net.minecraft.text.Text - - -fun ItemStack.appendLore(args: List<Text>) { - val compoundTag = getOrCreateSubNbt("display") - val loreList = compoundTag.getOrCreateList("Lore", NbtString.STRING_TYPE) - for (arg in args) { - loreList.add(NbtString.of(Text.Serializer.toJson(arg))) - } -} - -fun NbtCompound.getOrCreateList(label: String, tag: Byte): NbtList = getList(label, tag.toInt()).also { - put(label, it) -} - -fun NbtCompound.getOrCreateCompoundTag(label: String): NbtCompound = getCompound(label).also { - put(label, it) -} diff --git a/src/main/kotlin/moe/nea/notenoughupdates/util/LegacyTagParser.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/LegacyTagParser.kt deleted file mode 100644 index 9f3379b..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/LegacyTagParser.kt +++ /dev/null @@ -1,243 +0,0 @@ -package moe.nea.notenoughupdates.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 doubleMatch = Patterns.DOUBLE.matchEntire(textForm) ?: Patterns.DOUBLE_UNTYPED.matchEntire(textForm) - if (doubleMatch != null) { - return NbtDouble.of(doubleMatch.groups[1]!!.value.toDouble()) - } - 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()) - } - 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/notenoughupdates/util/Locraw.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/Locraw.kt deleted file mode 100644 index 400842f..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/Locraw.kt +++ /dev/null @@ -1,8 +0,0 @@ -package moe.nea.notenoughupdates.util - -import kotlinx.serialization.Serializable - -@Serializable -data class Locraw(val server: String, val gametype: String? = null, val mode: String? = null, val map: String? = null) { - val skyblockLocation = if (gametype == "SKYBLOCK") mode else null -} diff --git a/src/main/kotlin/moe/nea/notenoughupdates/util/MC.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/MC.kt deleted file mode 100644 index 956a330..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/MC.kt +++ /dev/null @@ -1,13 +0,0 @@ -package moe.nea.notenoughupdates.util - -import io.github.moulberry.repo.data.Coordinate -import net.minecraft.client.MinecraftClient -import net.minecraft.util.math.BlockPos - -object MC { - inline val player get() = MinecraftClient.getInstance().player - inline val world get() = MinecraftClient.getInstance().world -} - -val Coordinate.blockPos: BlockPos - get() = BlockPos(x, y, z) diff --git a/src/main/kotlin/moe/nea/notenoughupdates/util/MinecraftDispatcher.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/MinecraftDispatcher.kt deleted file mode 100644 index 366b81a..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/MinecraftDispatcher.kt +++ /dev/null @@ -1,22 +0,0 @@ -package moe.nea.notenoughupdates.util - -import kotlinx.coroutines.CoroutineDispatcher -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.Runnable -import kotlin.coroutines.CoroutineContext -import net.minecraft.client.MinecraftClient - -object MinecraftDispatcher : CoroutineDispatcher() { - @ExperimentalCoroutinesApi - override fun limitedParallelism(parallelism: Int): CoroutineDispatcher { - throw UnsupportedOperationException("limitedParallelism is not supported for MinecraftDispatcher") - } - - override fun isDispatchNeeded(context: CoroutineContext): Boolean = - !MinecraftClient.getInstance().isOnThread - - - override fun dispatch(context: CoroutineContext, block: Runnable) { - MinecraftClient.getInstance().execute(block) - } -} diff --git a/src/main/kotlin/moe/nea/notenoughupdates/util/SBData.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/SBData.kt deleted file mode 100644 index 393cdbb..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/SBData.kt +++ /dev/null @@ -1,64 +0,0 @@ -package moe.nea.notenoughupdates.util - -import kotlinx.serialization.SerializationException -import kotlinx.serialization.decodeFromString -import kotlin.time.Duration -import kotlin.time.Duration.Companion.seconds -import kotlin.time.ExperimentalTime -import kotlin.time.TimeSource -import moe.nea.notenoughupdates.NotEnoughUpdates -import moe.nea.notenoughupdates.events.ServerChatLineReceivedEvent -import moe.nea.notenoughupdates.events.SkyblockServerUpdateEvent -import moe.nea.notenoughupdates.events.WorldReadyEvent - -object SBData { - val profileRegex = "(?:Your profile was changed to: |You are playing on profile: )(.+)".toRegex() - var profileCuteName: String? = null - - private var lastLocrawSent = Timer() - private val locrawRoundtripTime: Duration = 5.seconds - var locraw: Locraw? = null - val skyblockLocation get() = locraw?.skyblockLocation - - - fun init() { - ServerChatLineReceivedEvent.subscribe { event -> - val profileMatch = profileRegex.matchEntire(event.unformattedString) - if (profileMatch != null) { - profileCuteName = profileMatch.groupValues[1] - } - if (event.unformattedString.startsWith("{")) { - if (tryReceiveLocraw(event.unformattedString) && lastLocrawSent.timePassed() < locrawRoundtripTime) { - lastLocrawSent.markFarPast() - event.cancel() - } - } - } - - WorldReadyEvent.subscribe { - sendLocraw() - locraw = null - } - } - - private fun tryReceiveLocraw(unformattedString: String): Boolean = try { - val lastLocraw = locraw - locraw = NotEnoughUpdates.json.decodeFromString<Locraw>(unformattedString) - SkyblockServerUpdateEvent.publish(SkyblockServerUpdateEvent(lastLocraw, locraw)) - true - } catch (e: SerializationException) { - e.printStackTrace() - false - } catch (e: IllegalArgumentException) { - e.printStackTrace() - false - } - - fun sendLocraw() { - lastLocrawSent.markNow() - val nh = MC.player?.networkHandler ?: return - nh.sendChatCommand("locraw") - } - - -} diff --git a/src/main/kotlin/moe/nea/notenoughupdates/util/ScreenUtil.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/ScreenUtil.kt deleted file mode 100644 index 6c86c41..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/ScreenUtil.kt +++ /dev/null @@ -1,36 +0,0 @@ -package moe.nea.notenoughupdates.util - -import moe.nea.notenoughupdates.NotEnoughUpdates -import net.fabricmc.fabric.api.client.event.lifecycle.v1.ClientTickEvents -import net.minecraft.client.MinecraftClient -import net.minecraft.client.gui.screen.Screen - -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) { - NotEnoughUpdates.logger.warn("Setting screen ${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/notenoughupdates/util/SequenceUtil.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/SequenceUtil.kt deleted file mode 100644 index 3e338bd..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/SequenceUtil.kt +++ /dev/null @@ -1,9 +0,0 @@ -package moe.nea.notenoughupdates.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/notenoughupdates/util/SkyblockId.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/SkyblockId.kt deleted file mode 100644 index 7c6c391..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/SkyblockId.kt +++ /dev/null @@ -1,48 +0,0 @@ -package moe.nea.notenoughupdates.util - -import io.github.moulberry.repo.data.NEUItem -import io.github.moulberry.repo.data.Rarity -import kotlinx.serialization.Serializable -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.json.Json -import net.minecraft.item.ItemStack -import net.minecraft.nbt.NbtCompound -import net.minecraft.util.Identifier - -@JvmInline -value class SkyblockId(val neuItem: String) { - val identifier get() = Identifier("skyblockitem", neuItem.lowercase().replace(";", "__")) -} - -val NEUItem.skyblockId get() = SkyblockId(skyblockItemId) - -@Serializable -data class HypixelPetInfo( - val type: String, - val tier: Rarity, -) { - val skyblockId get() = SkyblockId("${type.uppercase()};${tier.ordinal}") -} - -private val jsonparser = Json { ignoreUnknownKeys = true } - -val ItemStack.extraAttributes: NbtCompound - get() = getOrCreateSubNbt("ExtraAttributes") - -val ItemStack.skyBlockId: SkyblockId? - get() { - when (val id = extraAttributes.getString("id")) { - "PET" -> { - val jsonString = extraAttributes.getString("petInfo") - if (jsonString.isNullOrBlank()) return null - val petInfo = - runCatching { jsonparser.decodeFromString<HypixelPetInfo>(jsonString) } - .getOrElse { return null } - return petInfo.skyblockId - } - // TODO: RUNE, ENCHANTED_BOOK, PARTY_HAT_CRAB{,_ANIMATED}, ABICASE - else -> { - return SkyblockId(id) - } - } - } diff --git a/src/main/kotlin/moe/nea/notenoughupdates/util/TimeMark.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/TimeMark.kt deleted file mode 100644 index 5196606..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/TimeMark.kt +++ /dev/null @@ -1,15 +0,0 @@ -package moe.nea.notenoughupdates.util - -import kotlin.time.Duration -import kotlin.time.ExperimentalTime -import kotlin.time.TimeSource - -@OptIn(ExperimentalTime::class) -class TimeMark private constructor(private val timeMark: TimeSource.Monotonic.ValueTimeMark?) { - fun passedTime() = timeMark?.elapsedNow() ?: Duration.INFINITE - - companion object { - fun now() = TimeMark(TimeSource.Monotonic.markNow()) - fun farPast() = TimeMark(null) - } -} diff --git a/src/main/kotlin/moe/nea/notenoughupdates/util/Timer.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/Timer.kt deleted file mode 100644 index 14f76f7..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/Timer.kt +++ /dev/null @@ -1,23 +0,0 @@ -package moe.nea.notenoughupdates.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/notenoughupdates/util/config/ManagedConfig.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/config/ManagedConfig.kt deleted file mode 100644 index a149bf2..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/config/ManagedConfig.kt +++ /dev/null @@ -1,206 +0,0 @@ -package moe.nea.notenoughupdates.util.config - -import io.github.cottonmc.cotton.gui.client.CottonClientScreen -import io.github.cottonmc.cotton.gui.client.LibGui -import io.github.cottonmc.cotton.gui.client.LightweightGuiDescription -import io.github.cottonmc.cotton.gui.widget.WButton -import io.github.cottonmc.cotton.gui.widget.WLabel -import io.github.cottonmc.cotton.gui.widget.WToggleButton -import io.github.cottonmc.cotton.gui.widget.WWidget -import io.github.cottonmc.cotton.gui.widget.data.Insets -import kotlinx.serialization.decodeFromString -import kotlinx.serialization.encodeToString -import kotlinx.serialization.json.JsonElement -import kotlinx.serialization.json.JsonObject -import kotlinx.serialization.json.JsonPrimitive -import kotlinx.serialization.json.boolean -import kotlinx.serialization.json.jsonPrimitive -import kotlin.io.path.createDirectories -import kotlin.io.path.readText -import kotlin.io.path.writeText -import kotlin.properties.ReadOnlyProperty -import kotlin.reflect.KProperty -import net.minecraft.client.MinecraftClient -import net.minecraft.text.Text -import moe.nea.notenoughupdates.NotEnoughUpdates -import moe.nea.notenoughupdates.gui.WGridPanelWithPadding -import moe.nea.notenoughupdates.util.ScreenUtil.setScreenLater - -abstract class ManagedConfig(val name: String) { - - class GuiAppender(val width: Int) { - private var row = 0 - internal val panel = WGridPanelWithPadding(verticalPadding = 4, horizontalPadding = 4) - internal val reloadables = mutableListOf<(() -> Unit)>() - fun set(x: Int, y: Int, w: Int, h: Int, widget: WWidget) { - panel.add(widget, x, y, w, h) - } - - - fun onReload(reloadable: () -> Unit) { - reloadables.add(reloadable) - } - - fun skipRows(r: Int) { - row += r - } - - fun appendSplitRow(left: WWidget, right: WWidget) { - val lw = width / 2 - set(0, row, lw, 1, left) - set(lw, row, width - lw, 1, right) - skipRows(1) - } - - fun appendFullRow(widget: WWidget) { - set(0, row, width, 1, widget) - skipRows(1) - } - } - - interface OptionHandler<T : Any> { - fun toJson(element: T): JsonElement? - fun fromJson(element: JsonElement): T - fun emitGuiElements(opt: Option<T>, guiAppender: GuiAppender) - } - - inner class Option<T : Any> internal constructor( - val propertyName: String, - val default: () -> T, - val handler: OptionHandler<T> - ) : ReadOnlyProperty<Any?, T> { - - private lateinit var _value: T - private var loaded = false - var value: T - get() { - if (!loaded) - load() - return _value - } - set(value) { - loaded = true - _value = value - } - - override fun getValue(thisRef: Any?, property: KProperty<*>): T { - return value - } - - private fun load() { - if (data.containsKey(propertyName)) { - try { - value = handler.fromJson(data[propertyName]!!) - } catch (e: Exception) { - NotEnoughUpdates.logger.error( - "Exception during loading of config file $name. This will reset this config.", - e - ) - } - } - value = default() - } - - internal fun toJson(): JsonElement? { - return handler.toJson(value) - } - - fun appendToGui(guiapp: GuiAppender) { - handler.emitGuiElements(this, guiapp) - } - } - - val file = NotEnoughUpdates.CONFIG_DIR.resolve("$name.json") - val data: JsonObject by lazy { - try { - NotEnoughUpdates.json.decodeFromString( - file.readText() - ) - } catch (e: Exception) { - NotEnoughUpdates.logger.info("Could not read config $name. Loading empty config.") - JsonObject(mutableMapOf()) - } - } - - fun save() { - val data = JsonObject(allOptions.mapNotNull { (key, value) -> - value.toJson()?.let { - key to it - } - }.toMap()) - file.parent.createDirectories() - file.writeText(NotEnoughUpdates.json.encodeToString(data)) - } - - - val allOptions = mutableMapOf<String, Option<*>>() - val sortedOptions = mutableListOf<Option<*>>() - - protected fun <T : Any> option(propertyName: String, default: () -> T, handler: OptionHandler<T>): Option<T> { - if (propertyName in allOptions) error("Cannot register the same name twice") - return Option(propertyName, default, handler).also { - allOptions[propertyName] = it - sortedOptions.add(it) - } - } - - class BooleanHandler(val config: ManagedConfig) : OptionHandler<Boolean> { - override fun toJson(element: Boolean): JsonElement? { - return JsonPrimitive(element) - } - - override fun fromJson(element: JsonElement): Boolean { - return element.jsonPrimitive.boolean - } - - override fun emitGuiElements(opt: Option<Boolean>, guiAppender: GuiAppender) { - guiAppender.appendFullRow( - WToggleButton(Text.translatable("neu.config.${config.name}.${opt.propertyName}")).apply { - guiAppender.onReload { toggle = opt.value } - setOnToggle { - opt.value = it - config.save() - } - } - ) - } - } - - class ClickHandler(val config: ManagedConfig, val runnable: () -> Unit) : OptionHandler<Unit> { - override fun toJson(element: Unit): JsonElement? { - return null - } - - override fun fromJson(element: JsonElement) {} - - override fun emitGuiElements(opt: Option<Unit>, guiAppender: GuiAppender) { - guiAppender.appendSplitRow( - WLabel(Text.translatable("neu.config.${config.name}.${opt.propertyName}")), - WButton(Text.translatable("neu.config.${config.name}.${opt.propertyName}")).apply { - setOnClick { - runnable() - } - }, - ) - } - } - - protected fun toggle(propertyName: String, default: () -> Boolean): Option<Boolean> { - return option(propertyName, default, BooleanHandler(this)) - } - - fun showConfigEditor() { - val lwgd = LightweightGuiDescription() - val guiapp = GuiAppender(20) - guiapp.panel.insets = Insets.ROOT_PANEL - sortedOptions.forEach { it.appendToGui(guiapp) } - guiapp.reloadables.forEach { it() } - lwgd.setRootPanel(guiapp.panel) - setScreenLater(CottonClientScreen(lwgd)) - } - - protected fun button(propertyName: String, runnable: () -> Unit): Option<Unit> { - return option(propertyName, { }, ClickHandler(this, runnable)) - } - -} diff --git a/src/main/kotlin/moe/nea/notenoughupdates/util/data/DataHolder.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/data/DataHolder.kt deleted file mode 100644 index 6c9d8e8..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/data/DataHolder.kt +++ /dev/null @@ -1,60 +0,0 @@ -package moe.nea.notenoughupdates.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.notenoughupdates.NotEnoughUpdates - -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() = NotEnoughUpdates.CONFIG_DIR.resolve("$name.json") - - protected fun readValueOrDefault(): T { - if (file.exists()) - try { - return NotEnoughUpdates.json.decodeFromString( - serializer, - file.readText() - ) - } catch (e: Exception) {/* Expecting IOException and SerializationException, but Kotlin doesn't allow multi catches*/ - IDataHolder.badLoads.add(name) - NotEnoughUpdates.logger.error( - "Exception during loading of config file $name. This will reset this config.", - e - ) - } - return default() - } - - private fun writeValue(t: T) { - file.writeText(NotEnoughUpdates.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/notenoughupdates/util/data/IDataHolder.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/data/IDataHolder.kt deleted file mode 100644 index ccbf676..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/data/IDataHolder.kt +++ /dev/null @@ -1,75 +0,0 @@ -package moe.nea.notenoughupdates.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.notenoughupdates.NotEnoughUpdates -import moe.nea.notenoughupdates.events.ScreenOpenEvent - -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) { - NotEnoughUpdates.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) { - NotEnoughUpdates.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() { - ScreenOpenEvent.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/notenoughupdates/util/data/ProfileSpecificDataHolder.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/data/ProfileSpecificDataHolder.kt deleted file mode 100644 index a2f78b1..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/data/ProfileSpecificDataHolder.kt +++ /dev/null @@ -1,82 +0,0 @@ -package moe.nea.notenoughupdates.util.data - -import java.nio.file.Path -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.notenoughupdates.NotEnoughUpdates -import moe.nea.notenoughupdates.util.SBData - -abstract class ProfileSpecificDataHolder<S>( - private val dataSerializer: KSerializer<S>, - val configName: String, - private val configDefault: () -> S -) : IDataHolder<S?> { - - var allConfigs: MutableMap<String, S> - - override val data: S? - get() = SBData.profileCuteName?.let { - allConfigs.computeIfAbsent(it) { configDefault() } - } - - init { - allConfigs = readValues() - readValues() - IDataHolder.putDataHolder(this::class, this) - } - - private val configDirectory: Path get() = NotEnoughUpdates.CONFIG_DIR.resolve("profiles").resolve(configName) - - private fun readValues(): MutableMap<String, S> { - if (!configDirectory.exists()) { - configDirectory.createDirectories() - } - val profileFiles = configDirectory.listDirectoryEntries() - return profileFiles - .filter { it.extension == "json" } - .mapNotNull { - try { - it.nameWithoutExtension to NotEnoughUpdates.json.decodeFromString(dataSerializer, it.readText()) - } catch (e: Exception) { /* Expecting IOException and SerializationException, but Kotlin doesn't allow multi catches*/ - IDataHolder.badLoads.add(configName) - NotEnoughUpdates.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) { - it.deleteExisting() - } - } - c.forEach { (name, value) -> - val f = configDirectory.resolve("$name.json") - f.writeText(NotEnoughUpdates.json.encodeToString(dataSerializer, value)) - } - } - - override fun markDirty() { - IDataHolder.markDirty(this::class) - } - - override fun load() { - allConfigs = readValues() - } - -} diff --git a/src/main/kotlin/moe/nea/notenoughupdates/util/render/block.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/render/block.kt deleted file mode 100644 index 0d6c63b..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/render/block.kt +++ /dev/null @@ -1,105 +0,0 @@ -package moe.nea.notenoughupdates.util.render - -import com.mojang.blaze3d.systems.RenderSystem -import org.joml.Matrix4f -import net.minecraft.client.gl.VertexBuffer -import net.minecraft.client.render.BufferBuilder -import net.minecraft.client.render.Camera -import net.minecraft.client.render.GameRenderer -import net.minecraft.client.render.Tessellator -import net.minecraft.client.render.VertexFormat -import net.minecraft.client.render.VertexFormats -import net.minecraft.client.util.math.MatrixStack -import net.minecraft.util.math.BlockPos -import net.minecraft.util.math.Vec3d - -class RenderBlockContext private constructor(private val tesselator: Tessellator, private val matrixStack: MatrixStack) { - private val buffer = tesselator.buffer - 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, buffer) - tesselator.draw() - matrixStack.pop() - } - - fun tinyBlock(vec3d: Vec3d, size: Float) { - matrixStack.push() - matrixStack.translate(vec3d.x, vec3d.y, vec3d.z) - matrixStack.scale(size, size, size) - matrixStack.translate(-.5, -.5, -.5) - buildCube(matrixStack.peek().positionMatrix, buffer) - tesselator.draw() - matrixStack.pop() - } - - companion object { - private fun buildCube(matrix: Matrix4f, buf: BufferBuilder) { - buf.begin(VertexFormat.DrawMode.TRIANGLES, VertexFormats.POSITION_COLOR) - buf.fixedColor(255, 255, 255, 255) - buf.vertex(matrix, 0.0F, 0.0F, 0.0F).next() - buf.vertex(matrix, 0.0F, 0.0F, 1.0F).next() - buf.vertex(matrix, 0.0F, 1.0F, 1.0F).next() - buf.vertex(matrix, 1.0F, 1.0F, 0.0F).next() - buf.vertex(matrix, 0.0F, 0.0F, 0.0F).next() - buf.vertex(matrix, 0.0F, 1.0F, 0.0F).next() - buf.vertex(matrix, 1.0F, 0.0F, 1.0F).next() - buf.vertex(matrix, 0.0F, 0.0F, 0.0F).next() - buf.vertex(matrix, 1.0F, 0.0F, 0.0F).next() - buf.vertex(matrix, 1.0F, 1.0F, 0.0F).next() - buf.vertex(matrix, 1.0F, 0.0F, 0.0F).next() - buf.vertex(matrix, 0.0F, 0.0F, 0.0F).next() - buf.vertex(matrix, 0.0F, 0.0F, 0.0F).next() - buf.vertex(matrix, 0.0F, 1.0F, 1.0F).next() - buf.vertex(matrix, 0.0F, 1.0F, 0.0F).next() - buf.vertex(matrix, 1.0F, 0.0F, 1.0F).next() - buf.vertex(matrix, 0.0F, 0.0F, 1.0F).next() - buf.vertex(matrix, 0.0F, 0.0F, 0.0F).next() - buf.vertex(matrix, 0.0F, 1.0F, 1.0F).next() - buf.vertex(matrix, 0.0F, 0.0F, 1.0F).next() - buf.vertex(matrix, 1.0F, 0.0F, 1.0F).next() - buf.vertex(matrix, 1.0F, 1.0F, 1.0F).next() - buf.vertex(matrix, 1.0F, 0.0F, 0.0F).next() - buf.vertex(matrix, 1.0F, 1.0F, 0.0F).next() - buf.vertex(matrix, 1.0F, 0.0F, 0.0F).next() - buf.vertex(matrix, 1.0F, 1.0F, 1.0F).next() - buf.vertex(matrix, 1.0F, 0.0F, 1.0F).next() - buf.vertex(matrix, 1.0F, 1.0F, 1.0F).next() - buf.vertex(matrix, 1.0F, 1.0F, 0.0F).next() - buf.vertex(matrix, 0.0F, 1.0F, 0.0F).next() - buf.vertex(matrix, 1.0F, 1.0F, 1.0F).next() - buf.vertex(matrix, 0.0F, 1.0F, 0.0F).next() - buf.vertex(matrix, 0.0F, 1.0F, 1.0F).next() - buf.vertex(matrix, 1.0F, 1.0F, 1.0F).next() - buf.vertex(matrix, 0.0F, 1.0F, 1.0F).next() - buf.vertex(matrix, 1.0F, 0.0F, 1.0F).next() - buf.unfixColor() - } - - fun renderBlocks(matrices: MatrixStack, camera: Camera, block: RenderBlockContext. () -> Unit) { - RenderSystem.disableDepthTest() - RenderSystem.enableBlend() - RenderSystem.defaultBlendFunc() - RenderSystem.setShader(GameRenderer::getPositionColorProgram) - - matrices.push() - matrices.translate(-camera.pos.x, -camera.pos.y, -camera.pos.z) - - val ctx = RenderBlockContext(Tessellator.getInstance(), matrices) - block(ctx) - - matrices.pop() - - RenderSystem.setShaderColor(1F,1F,1F,1F) - VertexBuffer.unbind() - RenderSystem.enableDepthTest() - RenderSystem.disableBlend() - } - } -} - - diff --git a/src/main/kotlin/moe/nea/notenoughupdates/util/textutil.kt b/src/main/kotlin/moe/nea/notenoughupdates/util/textutil.kt deleted file mode 100644 index ac640be..0000000 --- a/src/main/kotlin/moe/nea/notenoughupdates/util/textutil.kt +++ /dev/null @@ -1,70 +0,0 @@ -package moe.nea.notenoughupdates.util - -import net.minecraft.text.LiteralTextContent -import net.minecraft.text.Text -import net.minecraft.text.TextContent -import moe.nea.notenoughupdates.NotEnoughUpdates - - -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 LiteralTextContent -> content.string - TextContent.EMPTY -> "" - else -> { - NotEnoughUpdates.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 Text.unformattedString - get() = string.replace("§.".toRegex(), "") - |