Begin adding a macro system

This commit is contained in:
Username404 2021-05-18 22:14:35 +02:00
parent 8f16eae53b
commit de98500a3a
Signed by: Username404-59
GPG Key ID: 7AB361FBB257A5D1
10 changed files with 70 additions and 12 deletions

View File

@ -11,6 +11,7 @@ buildscript {
plugins { plugins {
kotlin("jvm") version "1.5.0" kotlin("jvm") version "1.5.0"
kotlin("plugin.serialization") version "1.5.0"
id("com.github.johnrengelman.shadow") version "6.1.0" apply false id("com.github.johnrengelman.shadow") version "6.1.0" apply false
id("architectury-plugin") version "[3.0.100, 3.3[" id("architectury-plugin") version "[3.0.100, 3.3["
id("dev.architectury.loom") version "0.7.2.110" apply false id("dev.architectury.loom") version "0.7.2.110" apply false
@ -31,7 +32,6 @@ val kotlinX: String = "org.jetbrains.kotlinx"
subprojects { subprojects {
group = rootProject.group.toString() group = rootProject.group.toString()
lateinit var mappingsDep: Dependency lateinit var mappingsDep: Dependency
apply(plugin = "org.jetbrains.kotlin.jvm")
apply(plugin = "dev.architectury.loom") apply(plugin = "dev.architectury.loom")
apply(plugin = "com.github.johnrengelman.shadow") apply(plugin = "com.github.johnrengelman.shadow")
val shadowC by configurations.creating val shadowC by configurations.creating
@ -46,7 +46,7 @@ subprojects {
keep("class $group.snowygui.fabric.**") keep("class $group.snowygui.fabric.**")
keep("class $group.snowygui.forge.**") keep("class $group.snowygui.forge.**")
keepnames("class $group.snowygui.Snowy") keepnames("class $group.snowygui.Snowy")
keep("class $group.snowygui.gui.feature.** { public static *** INSTANCE; }") keep("class $group.snowygui.gui.feature.* { public static *** INSTANCE; }")
keepclassmembers("class $group.snowygui.** { public protected <methods>; }") keepclassmembers("class $group.snowygui.** { public protected <methods>; }")
keepattributes("*Annotation*, Signature, InnerClasses, EnclosingMethod, MethodParameters, Synthetic, Exceptions") keepattributes("*Annotation*, Signature, InnerClasses, EnclosingMethod, MethodParameters, Synthetic, Exceptions")
obfuscationdictionary("$dictionariesDir/dictionary.txt") obfuscationdictionary("$dictionariesDir/dictionary.txt")
@ -55,8 +55,15 @@ subprojects {
flattenpackagehierarchy("$group.snowygui") flattenpackagehierarchy("$group.snowygui")
allowaccessmodification() allowaccessmodification()
adaptclassstrings() adaptclassstrings()
dontnote("$group.**") "$group.**".also { dontnote(it); dontwarn(it) }
dontwarn("java.**")
// kotlinx-serialization related configuration:
dontnote("kotlinx.serialization.AnnotationsKt")
keepclasseswithmembers("class kotlinx.serialization.json.** { kotlinx.serialization.KSerializer serializer(...); }")
keep(mapOf("includedescriptorclasses" to true), "class $group.snowygui.**$\$serializer { * ; }")
keepclassmembers("class $group.snowygui.** { *** Companion; }")
keepclasseswithmembers("class $group.snowygui.** { kotlinx.serialization.KSerializer serializer(...); }")
val homeDir = System.getProperty("java.home") as String val homeDir = System.getProperty("java.home") as String
libraryjars(configurations.compileClasspath.get().filter { file -> libraryjars(configurations.compileClasspath.get().filter { file ->
listOf( listOf(
@ -111,13 +118,18 @@ allprojects {
} }
**/ **/
apply(plugin = "java") apply(plugin = "java")
apply(plugin = "org.jetbrains.kotlin.jvm")
apply(plugin = "org.jetbrains.kotlin.plugin.serialization")
apply(plugin = "architectury-plugin") apply(plugin = "architectury-plugin")
java { java {
sourceCompatibility = JavaVersion.VERSION_11 sourceCompatibility = JavaVersion.VERSION_11
} }
val serializationVer: String by rootProject
dependencies { dependencies {
implementation(kotlin("stdlib-jdk8", kotlinVer)) implementation(kotlin("stdlib-jdk8", kotlinVer))
implementation(kotlin("reflect", kotlinVer)) implementation(kotlin("reflect", kotlinVer))
implementation("$kotlinX:kotlinx-serialization-core:$serializationVer")
implementation("$kotlinX:kotlinx-serialization-json:$serializationVer")
annotationProcessor("com.github.bsideup.jabel:jabel-javac-plugin:0.3.0") { annotationProcessor("com.github.bsideup.jabel:jabel-javac-plugin:0.3.0") {
listOf("byte-buddy", "byte-buddy-agent").forEach { listOf("byte-buddy", "byte-buddy-agent").forEach {
exclude(module = it) exclude(module = it)

View File

@ -1,6 +1,5 @@
architectury { common(); injectInjectables = false } architectury { common(); injectInjectables = false }
dependencies { dependencies {
modImplementation("net.fabricmc:fabric-loader:${rootProject.property("fabric_loader_version")}") modImplementation("net.fabricmc:fabric-loader:${rootProject.property("fabric_loader_version")}")
implementation(kotlin("reflect"))
} }

View File

@ -8,15 +8,21 @@ import com.typesafe.config.ConfigValueFactory
import fr.username404.snowygui.ClickGui import fr.username404.snowygui.ClickGui
import fr.username404.snowygui.Snowy import fr.username404.snowygui.Snowy
import fr.username404.snowygui.gui.feature.ButtonImpl import fr.username404.snowygui.gui.feature.ButtonImpl
import fr.username404.snowygui.gui.feature.Macro
import io.github.config4k.extract import io.github.config4k.extract
import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import net.minecraft.client.Minecraft import net.minecraft.client.Minecraft
import java.io.File import java.io.File
import java.nio.charset.Charset
object Configuration { object Configuration {
private val file: File = File(Minecraft.getInstance().gameDirectory.absolutePath + File.separator + "snowy.conf") private val file: File = File(Minecraft.getInstance().gameDirectory.absolutePath + File.separator + "snowy.conf")
private val macroFile: File = File(Minecraft.getInstance().gameDirectory.absolutePath + File.separator + "snowy-macros.json")
private suspend fun writeConfig(c: Config) = coroutineScope { private suspend fun writeConfig(c: Config) = coroutineScope {
launch { launch {
file.writeText( file.writeText(
@ -67,6 +73,12 @@ object Configuration {
val enabledFeatures: MutableMap<String, Boolean> = if (obtained.hasPath("enabledFeatures")) { val enabledFeatures: MutableMap<String, Boolean> = if (obtained.hasPath("enabledFeatures")) {
obtained.extract("enabledFeatures") obtained.extract("enabledFeatures")
} else mutableMapOf() } else mutableMapOf()
val macros: MutableSet<Macro> = run {
if (!macroFile.exists()) macroFile.createNewFile()
macroFile.readLines(Charset.forName("UTF-8")).map {
Json.decodeFromString<Macro>(it)
}.toMutableSet()
}
init { init {
Runtime.getRuntime().addShutdownHook( Runtime.getRuntime().addShutdownHook(
Thread { Thread {
@ -80,6 +92,15 @@ object Configuration {
} }
) )
} }
macros.map { Json.encodeToString(it) }.forEachIndexed { index, s ->
with(macroFile) {
"$s\n".let {
if (index == 0) {
writeText(it)
} else appendText(it)
}
}
}
writeConfig(obtained.withValue("enabledFeatures", ConfigValueFactory.fromMap(enabledFeatures))).join() // TODO Fix formatting of enabledFeatures writeConfig(obtained.withValue("enabledFeatures", ConfigValueFactory.fromMap(enabledFeatures))).join() // TODO Fix formatting of enabledFeatures
} }
} }

View File

@ -18,6 +18,11 @@ sealed class ButtonImpl: ColoredElement(0.0, 0.0, 73, 8, opacity = 0.60F) {
fun initialize() { fun initialize() {
done = true done = true
Snowy.annotatedButtons.forEach { // Initializes every button Snowy.annotatedButtons.forEach { // Initializes every button
fun addToButtons(buttonImpl: ButtonImpl) {
ClickGui.components.filterIsInstance<ClickBox>().find { box ->
box.name!!.key == buttonImpl.info.parent.translationKey
}?.buttons!!.add(buttonImpl)
}
((try { ((try {
it.getConstructor().newInstance() it.getConstructor().newInstance()
} catch (e: NoSuchMethodException) { } catch (e: NoSuchMethodException) {
@ -30,9 +35,10 @@ sealed class ButtonImpl: ColoredElement(0.0, 0.0, 73, 8, opacity = 0.60F) {
} }
} }
} }
ClickGui.components.filterIsInstance<ClickBox>().find { box -> addToButtons(impl)
box.name!!.key == impl.info.parent.translationKey }
}?.buttons!!.add(impl) Configuration.macros.forEach { macro ->
addToButtons(macro)
} }
} }
} }

View File

@ -4,6 +4,9 @@ import fr.username404.snowygui.ClickGui
import fr.username404.snowygui.gui.elements.ClickBox import fr.username404.snowygui.gui.elements.ClickBox
import net.minecraft.network.chat.TranslatableComponent import net.minecraft.network.chat.TranslatableComponent
/**
* Should be used on classes/objects extending [ButtonImpl]
**/
@Target(AnnotationTarget.CLASS) @Target(AnnotationTarget.CLASS)
@Retention(AnnotationRetention.RUNTIME) @Retention(AnnotationRetention.RUNTIME)
annotation class ButtonInfo( annotation class ButtonInfo(

View File

@ -0,0 +1,11 @@
package fr.username404.snowygui.gui.feature
import net.minecraft.client.Minecraft
import kotlinx.serialization.*
import fr.username404.snowygui.gui.feature.ButtonInfo.Companion.Type
@Serializable
@ButtonInfo(Category.MACROS, kind = Type.CLICK)
data class Macro(private val command: String): ButtonImpl() {
override fun execAction() = Minecraft.getInstance().player!!.chat("/$command")
}

View File

@ -29,6 +29,6 @@ class FabricInit: Snowy(), ClientModInitializer {
.setUrls(ClasspathHelper.forPackage(FeaturePackage)) .setUrls(ClasspathHelper.forPackage(FeaturePackage))
.setScanners(SubTypesScanner(false), TypeAnnotationsScanner()) .setScanners(SubTypesScanner(false), TypeAnnotationsScanner())
.useParallelExecutor() .useParallelExecutor()
).getTypesAnnotatedWith(ButtonInfo::class.java) ).getTypesAnnotatedWith(ButtonInfo::class.java).filterNot { it.kotlin.isAbstract || it.kotlin.isData; }.toSet()
} }
} }

View File

@ -2,12 +2,15 @@ architectury { platformSetupLoomIde(); forge() }
repositories { repositories {
maven(url = "https://thedarkcolour.github.io/KotlinForForge/") maven(url = "https://thedarkcolour.github.io/KotlinForForge/")
} }
val serializationVer: String by rootProject
dependencies { dependencies {
forge("net.minecraftforge:forge:${rootProject.architectury.minecraft}-${rootProject.property("forge_version")}.+") forge("net.minecraftforge:forge:${rootProject.architectury.minecraft}-${rootProject.property("forge_version")}.+")
implementation("thedarkcolour:kotlinforforge:${rootProject.property("kotlinforforge")}.0") implementation("thedarkcolour:kotlinforforge:${rootProject.property("kotlinforforge")}.0")
implementation(project(path = ":common")) { isTransitive = false } implementation(project(path = ":common")) { isTransitive = false }
add("developmentForge", project(path = ":common")) { isTransitive = false } add("developmentForge", project(path = ":common")) { isTransitive = false }
shadowC("org.jetbrains.kotlinx:kotlinx-serialization-core:1.2.1") { isTransitive = false } shadowC("org.jetbrains.kotlinx:kotlinx-serialization-core:$serializationVer") { isTransitive = false }
shadowC("org.jetbrains.kotlinx:kotlinx-serialization-json:$serializationVer") { isTransitive = false }
shadowC(project(path = ":common", configuration = "transformProductionForge")) { isTransitive = false } shadowC(project(path = ":common", configuration = "transformProductionForge")) { isTransitive = false }
}; loom { }; loom {
useFabricMixin = true useFabricMixin = true

View File

@ -41,12 +41,14 @@ class ForgeInit: Snowy() {
.filter { data: ModFileScanData.ClassData? -> .filter { data: ModFileScanData.ClassData? ->
(data!!.javaClass.getDeclaredField("clazz").apply { isAccessible = true }.get(data) as Type).className.let { classname -> (data!!.javaClass.getDeclaredField("clazz").apply { isAccessible = true }.get(data) as Type).className.let { classname ->
classname.startsWith(FeaturePackage).let { classname.startsWith(FeaturePackage).let {
it && Class.forName(classname).declaredAnnotations.any { annotation -> it && with(Class.forName(classname)) {
!kotlin.isAbstract && !kotlin.isData && declaredAnnotations.any { annotation ->
annotation is ButtonInfo annotation is ButtonInfo
} }
} }
} }
} }
}
.map { Class.forName((it!!.javaClass.getDeclaredField("clazz").apply { isAccessible = true }.get(it) as Type).className) } .map { Class.forName((it!!.javaClass.getDeclaredField("clazz").apply { isAccessible = true }.get(it) as Type).className) }
.collect(Collectors.toSet()) .collect(Collectors.toSet())
with(MOD_BUS) { with(MOD_BUS) {

View File

@ -11,6 +11,7 @@ minecraft=1.16.5
forge_version=36.1 forge_version=36.1
kotlinforforge=1.12 kotlinforforge=1.12
kotlin_stdlib_version=1.5 kotlin_stdlib_version=1.5
serializationVer=1.2.1
fabric_loader_version=0.11.3 fabric_loader_version=0.11.3
fabric_language_kotlin=1.6.0+kotlin.1.5.0 fabric_language_kotlin=1.6.0+kotlin.1.5.0
fabric_resource_loader_version=0.2.5+059ea8667c fabric_resource_loader_version=0.2.5+059ea8667c