summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--build.gradle.kts56
-rw-r--r--buildSrc/build.gradle.kts3
-rw-r--r--root.gradle.kts31
-rw-r--r--settings.gradle.kts1
-rw-r--r--sharedVariables/src/MappingStyle.kt6
-rw-r--r--sharedVariables/src/MinecraftVersion.kt32
-rw-r--r--sharedVariables/src/Versions.kt59
-rw-r--r--src/main/kotlin/AllModules.kt11
-rw-r--r--src/main/kotlin/ChatStore.kt37
-rw-r--r--src/main/kotlin/UltraNotifier.kt8
-rw-r--r--src/main/kotlin/commands/BrigadierPatchbay.kt27
-rw-r--r--src/main/kotlin/commands/Commands.kt6
-rw-r--r--src/main/kotlin/event/SubscriptionTarget.kt5
-rw-r--r--src/main/kotlin/event/UltraNotifierEvents.kt2
-rw-r--r--src/main/kotlin/gui/BaseScreen.kt52
-rw-r--r--src/main/kotlin/gui/MessageUi.kt6
-rw-r--r--src/main/kotlin/util/IdentityCharacteristics.kt15
-rw-r--r--versions/mapping-1.14.4-forge-1.8.9.txt2
18 files changed, 275 insertions, 84 deletions
diff --git a/build.gradle.kts b/build.gradle.kts
index 5feb95d..e95fde4 100644
--- a/build.gradle.kts
+++ b/build.gradle.kts
@@ -1,4 +1,5 @@
import com.replaymod.gradle.preprocess.PreprocessExtension
+import moe.nea.sharedbuild.MinecraftVersion
import moe.nea.sharedbuild.Versions
import moe.nea.sharedbuild.parseEnvFile
import net.fabricmc.loom.api.LoomGradleExtensionAPI
@@ -16,7 +17,7 @@ val version = Versions.values().find { it.projectPath == project.path }!!
if (version.forgeDep != null)
extra.set("loom.platform", "forge")
apply(plugin = "gg.essential.loom")
-apply(plugin = "com.replaymod.preprocess")
+apply(plugin = "dev.deftu.gradle.preprocess")
val loom = the<LoomGradleExtensionAPI>()
val preprocess = the<PreprocessExtension>()
@@ -27,38 +28,14 @@ if (version.needsPack200) {
if (version.forgeDep != null) {
loom.forge.mixinConfig("mixins.ultranotifier.json")
}
-val mcJavaVersion = JavaLanguageVersion.of(
- when {
- version.numericMinecraftVersion >= 12005 -> 21
- version.numericMinecraftVersion >= 11800 -> 17
- version.numericMinecraftVersion >= 11700 -> 16
- else -> 8
- }
-)
-loom.mixin.defaultRefmapName.set("mixins.ultranotifier.refmap.json")
+val mcJavaVersion = version.minecraftVersion.javaLanguageVersion
+//loom.mixin.defaultRefmapName.set("mixins.ultranotifier.refmap.json")
java.toolchain.languageVersion.set(mcJavaVersion)
preprocess.run {
- vars.put("MC", version.numericMinecraftVersion)
+ vars.put("MC", version.minecraftVersion.versionNumber)
vars.put("FORGE", if ((version.forgeDep != null)) 1 else 0)
vars.put("JAVA", mcJavaVersion.asInt())
}
-
-repositories {
- mavenCentral()
- maven("https://maven.minecraftforge.net") {
- metadataSources {
- artifact()
- }
- }
- maven("https://repo.spongepowered.org/maven/")
- maven("https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1")
- maven("https://jitpack.io") {
- content {
- includeGroupByRegex("(io|com)\\.github\\..+")
- }
- }
-}
-
loom.run {
this.runs {
this.removeIf { it.name != "client" }
@@ -86,8 +63,8 @@ val shadowModImpl by configurations.creating {
val include = if (version.forgeDep != null) configurations.getByName("include") else shadowModImpl
val devauthVersion = "1.1.2"
dependencies {
- "minecraft"("com.mojang:minecraft:" + version.minecraftVersion)
- "mappings"(version.mappingDependency)
+ "minecraft"("com.mojang:minecraft:" + version.minecraftVersion.versionName)
+ "mappings"(if(version.mappingDependency=="official") loom.officialMojangMappings() else version.mappingDependency)
if (version.forgeDep != null) {
"forge"(version.forgeDep!!)
runtimeOnly("me.djtheredstoner:DevAuth-forge-legacy:$devauthVersion")
@@ -97,10 +74,11 @@ dependencies {
runtimeOnly("me.djtheredstoner:DevAuth-fabric:$devauthVersion")
}
shadowImpl("com.github.therealbush:eventbus:1.0.2")
- if (version.numericMinecraftVersion < 11300) {
+ include(version.universalCraft)
+ if (version.minecraftVersion.versionNumber < 11300) {
shadowImpl("com.mojang:brigadier:1.0.18")
}
- if (version <= Versions.MC11404F) {
+ if (version.forgeDep != null) {
shadowImpl("org.spongepowered:mixin:0.7.11-SNAPSHOT") {
isTransitive = false
}
@@ -149,7 +127,7 @@ tasks.processResources {
}
if (version.forgeDep != null) {
exclude("fabric.mod.json")
- if (version.numericMinecraftVersion < 11400) {
+ if (version.minecraftVersion < MinecraftVersion.MC1144) {
exclude("META-INF/mods.toml")
} else {
exclude("mcmod.info")
@@ -172,11 +150,9 @@ tasks.named("runClient", RunGameTask::class) {
})
}
-if (version.isBridge) {
- tasks.withType<JavaCompile> {
- onlyIf { false }
- }
- tasks.withType<KotlinCompile> {
- onlyIf { false }
- }
+tasks.withType<JavaCompile> {
+ onlyIf { false }
+}
+tasks.withType<KotlinCompile> {
+ onlyIf { false }
}
diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts
index d54cae9..e118815 100644
--- a/buildSrc/build.gradle.kts
+++ b/buildSrc/build.gradle.kts
@@ -7,4 +7,5 @@ repositories {
}
dependencies {
implementation("com.google.code.gson:gson:2.10.1")
-} \ No newline at end of file
+ implementation("com.google.guava:guava:33.2.1-jre")
+}
diff --git a/root.gradle.kts b/root.gradle.kts
index d7f638d..dc2911a 100644
--- a/root.gradle.kts
+++ b/root.gradle.kts
@@ -2,7 +2,7 @@ import com.replaymod.gradle.preprocess.Node
import moe.nea.sharedbuild.Versions
plugins {
- id("com.replaymod.preprocess") version "b09f534"
+ id("dev.deftu.gradle.preprocess") version "0.7.1"
// id("fabric-loom") version "1.6-SNAPSHOT" apply false
kotlin("jvm") version "1.9.23" apply false
id("gg.essential.loom") version "1.6.+" apply false
@@ -13,15 +13,40 @@ plugins {
allprojects {
version = "1.0.0"
group = "moe.nea.rxcraft"
+ repositories {
+ mavenCentral()
+ maven("https://maven.minecraftforge.net") {
+ metadataSources {
+ artifact()
+ }
+ }
+ maven("https://repo.spongepowered.org/maven/")
+ maven("https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1")
+ maven("https://jitpack.io") {
+ content {
+ includeGroupByRegex("(io|com)\\.github\\..+")
+ }
+ }
+ maven("https://repo.essential.gg/repository/maven-public")
+ }
}
preprocess {
+ strictExtraMappings.set(true)
val nodes = mutableMapOf<Versions, Node>()
Versions.values().forEach { version ->
- nodes[version] = createNode(version.projectName, version.numericMinecraftVersion, version.mappingStyle)
+ nodes[version] =
+ createNode(version.projectName, version.minecraftVersion.versionNumber, version.mappingStyle.identifier)
}
Versions.values().forEach { child ->
val parent = child.parent ?: return@forEach
- nodes[parent]!!.link(nodes[child]!!, file("versions/mapping-${parent.projectName}-${child.projectName}.txt"))
+ val mappingFile = file("versions/mapping-${parent.projectName}-${child.projectName}.txt")
+ if (mappingFile.exists()) {
+ println("Using mapping file $mappingFile")
+ nodes[parent]!!.link(nodes[child]!!, mappingFile)
+ } else {
+ nodes[parent]!!.link(nodes[child]!!)
+ println("Skipping mapping file $mappingFile")
+ }
}
} \ No newline at end of file
diff --git a/settings.gradle.kts b/settings.gradle.kts
index 3f927a5..4a20c6e 100644
--- a/settings.gradle.kts
+++ b/settings.gradle.kts
@@ -14,6 +14,7 @@ pluginManagement {
maven("https://maven.minecraftforge.net/")
maven("https://repo.spongepowered.org/maven/")
maven("https://repo.sk1er.club/repository/maven-releases/")
+ maven("https://maven.deftu.dev/releases")
}
resolutionStrategy {
eachPlugin {
diff --git a/sharedVariables/src/MappingStyle.kt b/sharedVariables/src/MappingStyle.kt
new file mode 100644
index 0000000..deb7fe8
--- /dev/null
+++ b/sharedVariables/src/MappingStyle.kt
@@ -0,0 +1,6 @@
+package moe.nea.sharedbuild
+
+enum class MappingStyle(val identifier: String) {
+ SEARGE("srg"),
+ YARN("yarn"),
+}
diff --git a/sharedVariables/src/MinecraftVersion.kt b/sharedVariables/src/MinecraftVersion.kt
new file mode 100644
index 0000000..a9e8851
--- /dev/null
+++ b/sharedVariables/src/MinecraftVersion.kt
@@ -0,0 +1,32 @@
+package moe.nea.sharedbuild
+
+import org.gradle.jvm.toolchain.JavaLanguageVersion
+
+enum class MinecraftVersion(
+ val versionName: String,
+) {
+ MC189("1.8.9"),
+ MC11200("1.12"),
+ MC11202("1.12.2"),
+ MC1144("1.14.4"),
+ MC11602("1.16.2"),
+ MC11605("1.16.5"),
+ MC12006("1.20.6"),
+ MC121("1.21"),
+ ;
+
+ val versionNumber = run {
+ val parts = versionName.split('.').mapTo(mutableListOf()) { it.toInt() }
+ if (parts.size == 2) parts.add(0)
+ require(parts.size == 3)
+ parts[0] * 10000 + parts[1] * 100 + parts[2]
+ }
+ val javaVersion: Int = when {
+ versionNumber >= 12005 -> 21
+ versionNumber >= 11800 -> 17
+ versionNumber >= 11700 -> 16
+ else -> 8
+ }
+ val javaLanguageVersion = JavaLanguageVersion.of(javaVersion)
+
+}
diff --git a/sharedVariables/src/Versions.kt b/sharedVariables/src/Versions.kt
index bfccd3a..447ac33 100644
--- a/sharedVariables/src/Versions.kt
+++ b/sharedVariables/src/Versions.kt
@@ -5,32 +5,61 @@ private fun yarn(version: String): String =
enum class Versions(
val projectName: String,
- val mappingStyle: String,
- val minecraftVersion: String,
+ val minecraftVersion: MinecraftVersion,
val mappingDependency: String,
- parentName: String?,
+ val mappingStyle: MappingStyle,
val forgeDep: String?,
- val needsPack200: Boolean,
- val isBridge: Boolean,
-
val fabricVersion: String? = null,
+ parentName: String?,
) {
- MC189("1.8.9", "srg", "1.8.9", "de.oceanlabs.mcp:mcp_stable:22-1.8.9@zip", "MC11404F", "net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9", true, false),
- MC11404F("1.14.4-forge", "srg", "1.14.4", "de.oceanlabs.mcp:mcp_stable:58-1.14.4@zip", "MC11404", "net.minecraftforge:forge:1.14.4-28.1.113", false, true),
- MC11404("1.14.4", "yarn", "1.14.4", yarn("1.14.4+build.1"), "MC12006", null, false, true, fabricVersion = "0.23.2+1.14"),
- MC12006("1.20.6", "yarn", "1.20.6", yarn("1.20.6+build.1"), null, null, false, false, fabricVersion = "0.99.0+1.20.6"),
+ MC189("1.8.9",
+ MinecraftVersion.MC189,
+ "de.oceanlabs.mcp:mcp_stable:22-1.8.9@zip",
+ MappingStyle.SEARGE,
+ "net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9",
+ null,
+ "MC11202"),
+ MC11202("1.12.2",
+ MinecraftVersion.MC11202,
+ "de.oceanlabs.mcp:mcp_stable:39-1.12@zip",
+ MappingStyle.SEARGE,
+ "net.minecraftforge:forge:1.12.2-14.23.5.2847",
+ null,
+ "MC116Forge"),
+ MC116Forge("1.16.2-forge",
+ MinecraftVersion.MC11602,
+ "official",
+ MappingStyle.SEARGE,
+ "net.minecraftforge:forge:1.16.2-33.0.61",
+ null,
+ "MC116Fabric"),
+ MC116Fabric("1.16.2-fabric",
+ MinecraftVersion.MC11602,
+ yarn("1.16.2+build.47"),
+ MappingStyle.YARN,
+ null,
+ "0.20.1+build.401-1.16",
+ "MC12006"
+ ),
+ MC12006(
+ "1.20.6",
+ MinecraftVersion.MC12006,
+ yarn("1.20.6+build.1"),
+ MappingStyle.YARN,
+ null,
+ fabricVersion = "0.99.0+1.20.6",
+ null,
+ ),
;
+ val platformName = if (forgeDep == null) "fabric" else "forge"
+ val universalCraft = "gg.essential:universalcraft-${minecraftVersion.versionName}-$platformName:363"
+ val needsPack200 = forgeDep != null && minecraftVersion <= MinecraftVersion.MC11202
val parent: Versions? by lazy {
if (parentName == null) null
else Versions.values().find { it.name == parentName }!!
}
- val numericMinecraftVersion = run {
- require(minecraftVersion.count { it == '.' } == 2)
- val (a, b, c) = minecraftVersion.split(".").map { it.toInt() }
- a * 10000 + b * 100 + c
- }
val projectPath get() = ":$projectName"
companion object {
diff --git a/src/main/kotlin/AllModules.kt b/src/main/kotlin/AllModules.kt
new file mode 100644
index 0000000..9befea9
--- /dev/null
+++ b/src/main/kotlin/AllModules.kt
@@ -0,0 +1,11 @@
+package moe.nea.ultranotifier
+
+import moe.nea.ultranotifier.commands.Commands
+import moe.nea.ultranotifier.event.SubscriptionTarget
+
+object AllModules {
+ val allModules: List<SubscriptionTarget> = listOf(
+ ChatStore,
+ Commands
+ )
+}
diff --git a/src/main/kotlin/ChatStore.kt b/src/main/kotlin/ChatStore.kt
new file mode 100644
index 0000000..2d9ff30
--- /dev/null
+++ b/src/main/kotlin/ChatStore.kt
@@ -0,0 +1,37 @@
+package moe.nea.ultranotifier
+
+import moe.nea.ultranotifier.event.ChatGuiLineEvent
+import moe.nea.ultranotifier.event.PacketChatLineEvent
+import moe.nea.ultranotifier.event.SubscriptionTarget
+import moe.nea.ultranotifier.event.UltraSubscribe
+import moe.nea.ultranotifier.util.IdentityCharacteristics
+import net.minecraft.text.Text
+
+object ChatStore : SubscriptionTarget {
+
+ data class ChatLine(
+ val text: Text,
+ var fromPacket: Boolean = false,
+ var isDisplayed: Boolean = false,
+ )
+
+ val allLines = object : LinkedHashMap<IdentityCharacteristics<Text>, ChatLine>() {
+ override fun removeEldestEntry(eldest: MutableMap.MutableEntry<IdentityCharacteristics<Text>, ChatLine>?): Boolean {
+ return size > 500 // TODO: config
+ }
+ }
+
+ fun insertChatLine(text: Text): ChatLine {
+ return allLines.getOrPut(IdentityCharacteristics(text)) { ChatLine(text) }
+ }
+
+ @UltraSubscribe
+ fun onMessageDisplayed(event: ChatGuiLineEvent) {
+ insertChatLine(event.component).isDisplayed = true
+ }
+
+ @UltraSubscribe
+ fun onMessageReceived(event: PacketChatLineEvent) {
+ insertChatLine(event.component).fromPacket = true
+ }
+}
diff --git a/src/main/kotlin/UltraNotifier.kt b/src/main/kotlin/UltraNotifier.kt
index f1bb8ff..cce83e9 100644
--- a/src/main/kotlin/UltraNotifier.kt
+++ b/src/main/kotlin/UltraNotifier.kt
@@ -1,7 +1,8 @@
package moe.nea.ultranotifier
-import moe.nea.ultranotifier.commands.Commands
import moe.nea.ultranotifier.event.RegistrationFinishedEvent
+import moe.nea.ultranotifier.event.UltraEvent
+import moe.nea.ultranotifier.event.UltraNotifierEvents
import moe.nea.ultranotifier.init.NeaMixinConfig
import java.io.File
@@ -18,7 +19,10 @@ object UltraNotifier {
for (mixinPlugin in NeaMixinConfig.getMixinPlugins()) {
logger.info("Loaded ${mixinPlugin.mixins.size} mixins for ${mixinPlugin.mixinPackage}.")
}
- Commands.init()
+ AllModules.allModules.forEach {
+ UltraNotifierEvents.register(it)
+ it.init()
+ }
RegistrationFinishedEvent().post()
diff --git a/src/main/kotlin/commands/BrigadierPatchbay.kt b/src/main/kotlin/commands/BrigadierPatchbay.kt
index 7396b6c..a6c9f6a 100644
--- a/src/main/kotlin/commands/BrigadierPatchbay.kt
+++ b/src/main/kotlin/commands/BrigadierPatchbay.kt
@@ -1,6 +1,6 @@
package moe.nea.ultranotifier.commands
-//#if FORGE
+//#if MC < 1.16
//$$import com.mojang.brigadier.CommandDispatcher
//$$import com.mojang.brigadier.builder.LiteralArgumentBuilder
//$$import com.mojang.brigadier.tree.CommandNode
@@ -12,8 +12,7 @@ package moe.nea.ultranotifier.commands
//$$import net.minecraft.command.CommandBase
//$$import net.minecraft.command.CommandHandler
//$$import net.minecraft.command.ICommandSender
-//$$import net.minecraft.util.BlockPos
-//$$import net.minecraft.util.ChatComponentText
+//$$import net.minecraft.server.MinecraftServer
//$$import net.minecraft.util.text.ITextComponent
//$$import net.minecraftforge.client.ClientCommandHandler
//$$
@@ -23,7 +22,7 @@ package moe.nea.ultranotifier.commands
//$$ val sender: ICommandSender
//$$) : UltraCommandSource {
//$$ override fun sendFeedback(text: ITextComponent) {
-//$$ sender.addChatMessage(text)
+//$$ sender.sendMessage(text)
//$$ }
//$$}
//$$
@@ -31,37 +30,27 @@ package moe.nea.ultranotifier.commands
//$$ val dispatcher: CommandDispatcher<UltraCommandSource>,
//$$ val node: CommandNode<UltraCommandSource>
//$$) : CommandBase() {
-//$$ override fun addTabCompletionOptions(
-//$$ sender: ICommandSender?,
-//$$ args: Array<out String>?,
-//$$ pos: BlockPos?
-//$$ ): MutableList<String> {
-//$$ return super.addTabCompletionOptions(sender, args, pos)
-//$$ }
-//$$
-//$$ override fun canCommandSenderUseCommand(sender: ICommandSender?): Boolean {
-//$$ // TODO: proper check here maybe?
+//$$ override fun checkPermission(server: MinecraftServer, sender: ICommandSender): Boolean {
//$$ return true
//$$ }
//$$
-//$$ override fun getCommandName(): String {
+//$$ override fun getName(): String {
//$$ return node.name
//$$ }
//$$
-//$$ override fun getCommandUsage(sender: ICommandSender?): String {
+//$$ override fun getUsage(sender: ICommandSender): String {
//$$ return ""
//$$ }
//$$
//$$ private fun getCommandLineText(args: Array<out String>) = "${node.name} ${args.joinToString(" ")}".trim()
-//$$
-//$$ override fun processCommand(sender: ICommandSender, args: Array<out String>) {
+//$$ override fun execute(server: MinecraftServer, sender: ICommandSender, args: Array<out String>) {
//$$ val source = BridgedCommandSource(sender)
//$$ val results = dispatcher.parse(getCommandLineText(args), source)
//$$ kotlin.runCatching {
//$$ dispatcher.execute(results)
//$$ Unit
//$$ }.recoverCatching {
-//$$ source.sendFeedback(ChatComponentText("Could not execute ultra command: ${it.message}"))
+//$$ source.sendFeedback(literalText("Could not execute ultra command: ${it.message}"))
//$$ }
//$$ }
//$$}
diff --git a/src/main/kotlin/commands/Commands.kt b/src/main/kotlin/commands/Commands.kt
index 4509fcf..95e8685 100644
--- a/src/main/kotlin/commands/Commands.kt
+++ b/src/main/kotlin/commands/Commands.kt
@@ -3,6 +3,7 @@ package moe.nea.ultranotifier.commands
import com.mojang.brigadier.builder.LiteralArgumentBuilder
import moe.nea.ultranotifier.UltraNotifier
import moe.nea.ultranotifier.event.CommandRegistrationEvent
+import moe.nea.ultranotifier.event.SubscriptionTarget
import moe.nea.ultranotifier.event.UltraNotifierEvents
import moe.nea.ultranotifier.event.UltraSubscribe
import net.minecraft.text.Text
@@ -35,7 +36,7 @@ fun literalText(string: String): Text =
//$$ net.minecraft.util.ChatComponentText(string)
//#endif
-object Commands {
+object Commands : SubscriptionTarget {
@UltraSubscribe
fun registerTestCommand(event: CommandRegistrationEvent) {
event.dispatcher.register(LiteralArgumentBuilder.literal<UltraCommandSource>("hello")
@@ -45,8 +46,7 @@ object Commands {
})
}
- fun init() {
- UltraNotifierEvents.register(this)
+ override fun init() {
//#if FORGE
//$$ UltraNotifierEvents.register(BrigadierPatchbay)
//#else
diff --git a/src/main/kotlin/event/SubscriptionTarget.kt b/src/main/kotlin/event/SubscriptionTarget.kt
new file mode 100644
index 0000000..e66eb94
--- /dev/null
+++ b/src/main/kotlin/event/SubscriptionTarget.kt
@@ -0,0 +1,5 @@
+package moe.nea.ultranotifier.event
+
+interface SubscriptionTarget {
+ fun init() = Unit
+}
diff --git a/src/main/kotlin/event/UltraNotifierEvents.kt b/src/main/kotlin/event/UltraNotifierEvents.kt
index 34d1769..7190b63 100644
--- a/src/main/kotlin/event/UltraNotifierEvents.kt
+++ b/src/main/kotlin/event/UltraNotifierEvents.kt
@@ -16,7 +16,7 @@ object UltraNotifierEvents {
return event
}
- fun register(obj: Any) {
+ fun register(obj: SubscriptionTarget) {
//#if FORGE
//$$ eventBus.register(obj)
//#else
diff --git a/src/main/kotlin/gui/BaseScreen.kt b/src/main/kotlin/gui/BaseScreen.kt
new file mode 100644
index 0000000..06aafb9
--- /dev/null
+++ b/src/main/kotlin/gui/BaseScreen.kt
@@ -0,0 +1,52 @@
+package moe.nea.ultranotifier.gui
+
+import net.minecraft.client.gui.DrawContext
+import net.minecraft.client.gui.screen.Screen
+import net.minecraft.text.Text
+//#if MC < 1.20.4
+//$$import com.mojang.blaze3d.platform.GlStateManager
+//#endif
+
+class DrawingContext(
+//#if MC > 1.20.4
+ val vanilla: DrawContext,
+//#endif
+) {
+ fun pushMatrix() {
+//#if MC > 1.20.4
+ vanilla.matrices.push()
+//#else
+//$$ GlStateManager.pushMatrix()
+//#endif
+ }
+ fun popMatrix() {
+//#if MC > 1.20.4
+ vanilla.matrices.pop()
+//#else
+//$$ GlStateManager.popMatrix()
+//#endif
+ }
+ fun translate(x: Double, y: Double, z: Double) {
+//#if MC > 1.20.4
+ vanilla.matrices.translate(x, y, z)
+//#else
+//$$ GlStateManager.translate(x, y, z)
+//#endif
+ }
+ fun scale(x: Float, y: Float, z: Float) {
+//#if MC > 1.20.4
+ vanilla.matrices.scale(x, y, z)
+//#else
+//$$ GlStateManager.scale(x, y, z)
+//#endif
+ }
+
+}
+
+abstract class BaseScreen(title: Text) : Screen(
+//#if MC >= 11400
+ title
+//#endif
+) {
+
+}
diff --git a/src/main/kotlin/gui/MessageUi.kt b/src/main/kotlin/gui/MessageUi.kt
new file mode 100644
index 0000000..78965b3
--- /dev/null
+++ b/src/main/kotlin/gui/MessageUi.kt
@@ -0,0 +1,6 @@
+package moe.nea.ultranotifier.gui
+
+import moe.nea.ultranotifier.commands.literalText
+
+class MessageUi : BaseScreen(literalText("Messages")) {
+}
diff --git a/src/main/kotlin/util/IdentityCharacteristics.kt b/src/main/kotlin/util/IdentityCharacteristics.kt
new file mode 100644
index 0000000..d3f5294
--- /dev/null
+++ b/src/main/kotlin/util/IdentityCharacteristics.kt
@@ -0,0 +1,15 @@
+package moe.nea.ultranotifier.util
+
+class IdentityCharacteristics<T>(val value: T) {
+ override fun hashCode(): Int {
+ return System.identityHashCode(value)
+ }
+
+ override fun equals(other: Any?): Boolean {
+ return value === other
+ }
+
+ override fun toString(): String {
+ return "IdentityCharacteristics($value)"
+ }
+}
diff --git a/versions/mapping-1.14.4-forge-1.8.9.txt b/versions/mapping-1.14.4-forge-1.8.9.txt
index cdd8783..2c4adf0 100644
--- a/versions/mapping-1.14.4-forge-1.8.9.txt
+++ b/versions/mapping-1.14.4-forge-1.8.9.txt
@@ -3,3 +3,5 @@ net.minecraft.util.text.ITextComponent net.minecraft.util.IChatComponent
net.minecraft.util.text.ITextComponent getString() getUnformattedText()
net.minecraftforge.eventbus.api.Event net.minecraftforge.fml.common.eventhandler.Event
net.minecraftforge.eventbus.api.SubscribeEvent net.minecraftforge.fml.common.eventhandler.SubscribeEvent
+net.minecraft.client.gui.screen.Screen net.minecraft.client.gui.GuiScreen
+com.mojang.blaze3d.platform.GlStateManager net.minecraft.client.renderer.GlStateManager \ No newline at end of file