diff --git a/Generator/src/main/kotlin/Main.kt b/Generator/src/main/kotlin/Main.kt index 3bfbe5b..0f6b015 100644 --- a/Generator/src/main/kotlin/Main.kt +++ b/Generator/src/main/kotlin/Main.kt @@ -3,7 +3,10 @@ package io.github.flyingpig525 import kotlinx.serialization.json.* import java.io.File import java.io.FileNotFoundException -import kotlin.io.path.* +import kotlin.io.path.Path +import kotlin.io.path.createDirectories +import kotlin.io.path.exists +import kotlin.reflect.KMutableProperty0 // This is not efficient in the slightest :skull: fun main(vararg args: String) { @@ -57,9 +60,18 @@ fun main(vararg args: String) { break } } + if ("noSound" !in args) { + println("processing sounds") + val sounds = actionDump["sounds"]!!.jsonArray + try { + processSounds(sounds) + } catch (e: Throwable) { + println("something went wrong processing sounds") + e.printStackTrace() + } + } - // TODO: Add sound processing - // TODO: Add potion processing + // TODO: Add potion processing (NO!!!!!!! POTIONS DO NOT HAVE A SET STRUCTURE, THEY ALL HAVE THEIR OWN PROPERTIES) } fun blockActions(actions: List) = try { @@ -72,33 +84,65 @@ fun blockActions(actions: List) = try { import io.github.flyingpig525.base.block.subaction.SubAction + @Suppress("unused") enum class ${codeblock.name}SubAction(override val codeblock: String) : SubAction { """.trimIndent() + //language= var file: String = """ package io.github.flyingpig525.base.block.category import io.github.flyingpig525.base.* import io.github.flyingpig525.base.item.* import io.github.flyingpig525.base.item.type.* + import io.github.flyingpig525.base.item.type.tag.* import io.github.flyingpig525.base.block.* import io.github.flyingpig525.base.block.subaction.* import kotlinx.serialization.json.JsonObjectBuilder import kotlinx.serialization.json.put + import kotlin.reflect.full.superclasses + import kotlin.reflect.KClass """.trimIndent() + val tag = object { + //language=kotlin + var tagFile: String = """ + package io.github.flyingpig525.base.item.type.tag + + @Suppress("unused", "RemoveRedundantQualifierName") + object ${codeblock.name}Tags { + """.trimIndent() + } if (!encloses) { + //language=kotlin file += """ + @Suppress("unused") class ${codeblock.name}Category internal constructor(private val template: Template) { private val blocks = template.blocks - private fun block(items: Items, action: String, extra: JsonObjectBuilder.() -> Unit = {}) { - blocks += Block("${codeblock.shortName}", ItemCollection(items).items, action, extra) + private fun block(items: Items, action: String, tagClass: KClass<*>? = null, extra: JsonObjectBuilder.() -> Unit = {}) { + val collection = ItemCollection(items) + tagClass?.nestedClasses?.forEach { klass -> + if (klass.superclasses.any { it.qualifiedName == "kotlin.Enum" }) { + @Suppress("UNCHECKED_CAST") + val entries = klass.java.enumConstants as Array> + entries.forEach { entry -> + if (entry is TagItem) { + if (!entry.default) return@forEach + if (collection.items.none { it is TagItem && it.tag == entry.tag }) + collection += entry + } + } + } + } + blocks += Block("${codeblock.shortName}", collection.items, action, extra) } """.trimIndent() } else { + //language=kotlin file += """ + @Suppress("unused") class ${codeblock.name}Category internal constructor(private val template: Template) { private val blocks = template.blocks @@ -107,16 +151,31 @@ fun blockActions(actions: List) = try { action: String, wrappedCode: Template.() -> Unit, not: Boolean = false, + tagClass: KClass<*>? = null, extra: JsonObjectBuilder.() -> Unit = {} ) { - blocks += Block("${codeblock.shortName}", ItemCollection(items).items, action) { + val collection = ItemCollection(items) + tagClass?.nestedClasses?.forEach { klass -> + if (klass.superclasses.any { it.qualifiedName == "kotlin.Enum" }) { + @Suppress("UNCHECKED_CAST") + val entries = klass.java.enumConstants as Array> + entries.forEach { entry -> + if (entry is TagItem) { + if (!entry.default) return@forEach + if (collection.items.none { it is TagItem && it.tag == entry.tag }) + collection += entry + } + } + } + } + blocks += Block("${codeblock.shortName}", collection.items, action) { if (not) put("attribute", "NOT") extra() } blocks += BracketBlock(type = "${if (codeblock.name == "Repeat") "repeat" else "norm"}") blocks += io.github.flyingpig525.base.Template( io.github.flyingpig525.base.Template.Type.NONE, - a = wrappedCode + code = wrappedCode ).blocks blocks += BracketBlock(false, "${if (codeblock.name == "Repeat") "repeat" else "norm"}") } @@ -126,12 +185,17 @@ fun blockActions(actions: List) = try { val name = action["name"]!!.jsonPrimitive.content val funcName = removeClutter(actionNameToFunction(name)) if (funcName in alreadyDone) continue + if (funcName == "sendMessage") { + println(getActionTagContainerName(action)) + } alreadyDone += funcName + val hasTags = action["tags"]?.jsonArray?.isNotEmpty() == true + if (hasTags) processTags(action, tag::tagFile) val icon = action["icon"]!!.jsonObject val description: List = icon["description"]!!.jsonArray.map { it.jsonPrimitive.content } var comment = "\t/**\n" description.forEach { - comment += "\t * *${removeClutter(it)}*\n" + comment += "\t * ${removeClutter(it)}\n" } val subAction = hasSubAction(action) if (subAction) { @@ -154,7 +218,13 @@ fun blockActions(actions: List) = try { arguments.forEach { arg -> val unprocessed = arg["type"]!!.jsonPrimitive.content if (unprocessed == "NONE") return@forEach - val type = typeToKType(unprocessed) + val type: String + try { + type = typeToKType(unprocessed) + } catch (e: Throwable) { + println(Json { prettyPrint = true }.encodeToString(action)) + throw e + } val description = arg["description"]?.jsonArray?.map { it.jsonPrimitive.content } val optional = arg["optional"]!!.jsonPrimitive.boolean comment += "\t * [$type]" @@ -163,15 +233,24 @@ fun blockActions(actions: List) = try { } comment += "\n\t *\n" description?.forEach { - comment += "\t * ${if (optional) "(*) " else ""}*${removeClutter(it)}*\n" + comment += "\t * ${if (optional) "(*) " else ""}${removeClutter(it)}\n" + } + val notes = arg["notes"]?.jsonArray?.map { it.jsonArray.joinToString(" ") { it.jsonPrimitive.content } } + if (notes != null && notes.isNotEmpty()) { + comment += "\t *\n" + for (note in notes) { + comment += "\t * *$note*\n" + } } comment += "\t *\n" } comment += "\t * (*) = optional\n" + if (hasTags) comment += "\n\t * @see [${getActionTagContainerName(action)}]\n" } comment += "\t */\n" file += "\n$comment" val negatable = negatable(codeblock.name, funcName) + val elseOp = codeblock.name.startsWith("if", true) file += "\tfun $funcName(items: Items${ if (subAction) ", subAction: SubAction" else "" @@ -179,11 +258,17 @@ fun blockActions(actions: List) = try { if (negatable) ", not: Boolean = false" else "" }${ if (encloses) ", wrappedCode: Template.() -> Unit" else "" - }): ElseOperation {\n\t\tblock(items, \"$name\"${if (encloses) ", wrappedCode" else ""}${if (negatable) ", not" else ""})${ + })${ + if (elseOp) ": ElseOperation" else "" + } {\n\t\tblock(items, \"$name\"${if (encloses) ", wrappedCode" else ""}${if (negatable) ", not" else ""}${ + if (hasTags) ", tagClass = ${getActionTagContainerName(action)}::class" else "" + })${ if (subAction) """ { put("subAction", subAction.codeblock) }""" else "" - }\n\t\treturn ElseOperation()\n\t}\n\n" + }${ + if (elseOp) "\n\t\treturn ElseOperation()" else "" + }\n\t}\n\n" } catch (e: Exception) { println(Json.encodeToString(action)) e.printStackTrace() @@ -207,15 +292,59 @@ fun blockActions(actions: List) = try { } file += "}" writeToDirFile("gen/categories", "${codeblock.name}Category.kt", file) + tag.tagFile += "}" + writeToDirFile("gen/tags", "${codeblock.name}Tags.kt", tag.tagFile) +// println(tag.tagFile) } catch (e: Exception) { e.printStackTrace() } +fun processTags(action: JsonObject, tagFile: KMutableProperty0) { + var tagFile by tagFile + + val tags = action["tags"]!!.jsonArray.map { it.jsonObject } + val actionName = action["name"]!!.jsonPrimitive.content + val actionClassName = removeClutter(actionName).noSpace.replaceFirstChar { it.uppercaseChar() } + if (actionClassName == "mod") println(action) + val codeblock = CodeBlock.of(action["codeblockName"]!!.jsonPrimitive.content) + tagFile += "\n\tobject $actionClassName {\n" + for (tag in tags) { + val unprocessedName = tag["name"]!!.jsonPrimitive.content + val name = tag["name"]!!.jsonPrimitive.content.transformedSymbols.noSpace + println(name) + // type has to be kotlin.String because SetVariable has a codeblock named "String" + //language=kotlin + tagFile += "\t\tenum class $name(override val option: kotlin.String, override val default: Boolean) : TagItem {\n" + val options = tag["options"]!!.jsonArray.map { it.jsonObject } + for (option in options) { + val optionName = option["name"]!!.jsonPrimitive.content + val isDefault = tag["defaultOption"]!!.jsonPrimitive.content == optionName + val ordinalName = optionName.transformedSymbols.capitalWords.noSpace + if (isDefault) { + tagFile += "\t\t\t/** **Default** */\n" + } + tagFile += "\t\t\t$ordinalName(\"$optionName\", $isDefault),\n" + } + tagFile = tagFile.dropLast(2) + tagFile += ";\n\n" + // type has to be kotlin.String because SetVariable has a codeblock named "String" + tagFile += "\t\t\toverride val action: kotlin.String = \"$actionName\"\n" + // type has to be kotlin.String because SetVariable has a codeblock named "String" + tagFile += "\t\t\toverride val block: kotlin.String = \"${codeblock.shortName}\"\n" + tagFile += "\t\t\toverride var slot: Int = 26\n" + // type has to be kotlin.String because SetVariable has a codeblock named "String" + tagFile += "\t\t\toverride val tag: kotlin.String = \"$unprocessedName\"\n" + tagFile += "\t\t}\n" + } + tagFile += "\t}\n" +} + fun processEvents(codeblock: CodeBlock, events: List) = try { - if (codeblock != CodeBlock.PlayerEvent && codeblock != CodeBlock.EntityEvent) throw IllegalArgumentException("codeblock cannot be a non-event block") + if (codeblock != CodeBlock.PlayerEvent && codeblock != CodeBlock.EntityEvent && codeblock != CodeBlock.GameEvent) throw IllegalArgumentException("codeblock cannot be a non-event block") var file = """ package io.github.flyingpig525.base.block + @Suppress("unused") enum class ${codeblock.name}(val type: EventBlock.Type, val event: String) { """.trimIndent() for (event in events) { @@ -250,6 +379,7 @@ fun processGameValueCategory(category: String, values: List) { import io.github.flyingpig525.base.item.* import io.github.flyingpig525.base.item.type.* + @Suppress("unused") object $className { """.trimIndent() @@ -289,10 +419,32 @@ fun processGameValueCategory(category: String, values: List) { e.printStackTrace() } file += "}" - println(file) +// println(file) writeToDirFile("gen/gamevalue", "$className.kt", file) } +fun processSounds(sounds: JsonArray) { + var file = """ + @file:Suppress("Unused") + package io.github.flyingpig525.base.item + + import io.github.flyingpig525.base.item.type.SoundItem + + object Sounds { + """.trimIndent() + file += "\n" + for (sound in sounds.map { it.jsonObject }) { + val icon = sound["icon"]?.jsonObject ?: continue + val name = icon["name"]?.jsonPrimitive?.content ?: continue + val decluttered = removeClutter(name.replace("(", "").replace(")", "").replace("-", "").noSpace) + println(decluttered) + file += "\tval $decluttered get() = SoundItem(\"$name\")\n" + } + file += "}" + println(file) + writeToDirFile("gen/sound", "Sounds.kt", file) +} + enum class CodeBlock(val block: String, val shortName: String) { PlayerAction("PLAYER ACTION", "player_action"), EntityAction("ENTITY ACTION", "entity_action"), @@ -306,6 +458,7 @@ enum class CodeBlock(val block: String, val shortName: String) { SetVariable("SET VARIABLE", "set_var"), PlayerEvent("PLAYER EVENT", "player_event"), EntityEvent("ENTITY EVENT", "entity_event"), + GameEvent("GAME EVENT", "game_event"), SelectObject("SELECT OBJECT", "select"); override fun toString(): String = name @@ -328,6 +481,7 @@ fun isSubActionCategory(codeblock: CodeBlock): Boolean = fun typeToKType(type: String): String = when (type) { "NUMBER" -> "NumItem" + "BYTE" -> "NumItem" "VARIABLE" -> "VarItem" "ITEM" -> "MinecraftItem" "BLOCK" -> "MinecraftItem" @@ -353,6 +507,12 @@ fun actionNameToFunction(name: String): String { return name.replace(" ", "").replaceFirstChar { it.lowercase() } } +fun getActionTagContainerName(action: JsonObject): String { + val codeblock = CodeBlock.of(action["codeblockName"]!!.jsonPrimitive.content) + val name = action["name"]!!.jsonPrimitive.content + return "${codeblock.name}Tags.${removeClutter(name).noSpace.replaceFirstChar { it.uppercaseChar() }}" +} + fun removeClutter(str: String): String { return when (str) { "+" -> "plus" @@ -379,6 +539,58 @@ fun removeClutter(str: String): String { } } +val String.noSpace: String get() = replace(" ", "") + +val String.capitalWords: String get() { + var lastWasSpace = true + return map { + if (it.isWhitespace()) { + lastWasSpace = true + return@map it + } + if (!lastWasSpace) return@map it.lowercaseChar() + lastWasSpace = false + it.uppercaseChar() + }.joinToString("") +} + +val String.transformedSymbols: String get() = this + .replace("2020/08/17 17:20:54", " yyyy mm dd hh mm ss ") + .replace("2020/08/17", " yyy mm dd ") + .replace("Mon, August 17", " day month date ") + .replace("Monday", " day ") + .replace("17:20:54", " hh mm ss ") + .replace("5:20 PM", " hh mm am or pm ") + .replace("17h20m54s", " hh h mm m ss s") + .replace("54.229 seconds", " seconds") + .replace("/", " or ") + .replace("(", " ") + .replace(")", " ") + .replace("10", " ten ") + .replace("12", " twelve ") + .replace("20", " twenty ") + .replace("1", " one ") + .replace("2", " two ") + .replace("3", " three ") + .replace("4", " four ") + .replace("5", " five ") + .replace("6", " six ") + .replace("7", " seven ") + .replace("8", " eight ") + .replace("9", " nine ") + .replace("-", " ") + .replace("'", "") + .replace(",", " ") + .replace("|", " or ") + .replace("&", " and ") + .replace("~", " not ") + .replace("<<", " shift left ") + .replace(">>>", " unsigned shift right") + .replace(">>", " shift right ") + .replace("^", " XOR ") + .replace("+", " ") + .replace("⇄", " not equal ") + fun enclosesCode(codeblock: CodeBlock): Boolean = when (codeblock) { CodeBlock.IfEntity -> true CodeBlock.IfPlayer -> true diff --git a/KotlinFire/build.gradle.kts b/KotlinFire/build.gradle.kts index 81330e7..5945dbe 100644 --- a/KotlinFire/build.gradle.kts +++ b/KotlinFire/build.gradle.kts @@ -1,65 +1,17 @@ -import com.vanniktech.maven.publish.JavadocJar -import com.vanniktech.maven.publish.KotlinJvm -import com.vanniktech.maven.publish.SonatypeHost - -/* - * This file was generated by the Gradle 'init' task. - * - * This generated file contains a sample Kotlin library project to get you started. - * For more details on building Java & JVM projects, please refer to https://docs.gradle.org/8.7/userguide/building_java_projects.html in the Gradle documentation. - */ +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile plugins { - // Apply the org.jetbrains.kotlin.jvm Plugin to add support for Kotlin. kotlin("jvm") apply true kotlin("plugin.serialization") apply true - id("com.vanniktech.maven.publish") version "0.31.0-rc2" + id("com.vanniktech.maven.publish") version "0.34.0" id("org.jetbrains.dokka") version "2.0.0" } -version = "1.6.4" +version = "1.7.0-SNAPSHOT" group = "io.github.flyingpig525" -//publishing { -// publications { -// create("gpr") { -// from(components["java"]) -// this.artifactId = "KotlinFire" -// -// pom { -// name = "KotlinFire" -// description = -// "KotlinFire is a Kotlin library used to manipulate code templates from the Minecraft server DiamondFire." -// url = "https://github.com/FlyingPig525/KotlinFire" -// licenses { -// license { -// name = "The Apache License, Version 2.0" -// url = "https://www.apache.org/licenses/LICENSE-2.0.txt" -// } -// } -// developers { -// developer { -// id = "flyingpig525" -// name = "FlyingPig525" -// } -// } -// scm { -// connection = "scm:git:git://github.com/FlyingPig525/KotlinFire.git" -// developerConnection = "scm:git:ssh://github.com/FlyingPig525/KotlinFire.git" -// url = "https://github.com/FlyingPig525/KotlinFire" -// } -// } -// } -// } -//} - mavenPublishing { -// configure(KotlinJvm( -// javadocJar = JavadocJar.Dokka( ), -// sourcesJar = false -// )) - coordinates( "io.github.flyingpig525", "kotlinfire", @@ -93,42 +45,28 @@ mavenPublishing { } signAllPublications() - publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL) + publishToMavenCentral(automaticRelease = true) } -//signing { -// useGpgCmd() -// sign(publishing.publications) -// this.ext { -// -// } -//} repositories { - // Use Maven Central for resolving dependencies. mavenCentral() } dependencies { testImplementation(kotlin("test")) - val ktor_version = "3.1.2" + val ktor_version = "3.5.0" implementation("io.ktor:ktor-client-websockets:$ktor_version") implementation("io.ktor:ktor-client-java:$ktor_version") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1") - -// testRuntimeOnly("org.junit.platform:junit-platform-launcher") -// implementation(kotlin("stdlib-jdk8")) + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.11.0") + implementation(kotlin("reflect")) } -// Apply a specific Java toolchain to ease working on different environments. -//java { -// toolchain { -// languageVersion = JavaLanguageVersion.of(17) -// } -// withSourcesJar() -// withJavadocJar() -//} kotlin { - jvmToolchain(17) + jvmToolchain(21) +} +val compileKotlin: KotlinCompile by tasks +compileKotlin.compilerOptions { + freeCompilerArgs.set(listOf("-Xcontext-parameters")) } \ No newline at end of file diff --git a/KotlinFire/src/main/kotlin/io/github/flyingpig525/annotation/RequiredRank.kt b/KotlinFire/src/main/kotlin/io/github/flyingpig525/annotation/RequiredRank.kt deleted file mode 100644 index 764e62f..0000000 --- a/KotlinFire/src/main/kotlin/io/github/flyingpig525/annotation/RequiredRank.kt +++ /dev/null @@ -1,21 +0,0 @@ -package io.github.flyingpig525.annotation - -@Target(AnnotationTarget.FUNCTION) -@Retention(AnnotationRetention.RUNTIME) -@MustBeDocumented -annotation class Noble - -@Target(AnnotationTarget.FUNCTION) -@Retention(AnnotationRetention.RUNTIME) -@MustBeDocumented -annotation class Emperor - -@Target(AnnotationTarget.FUNCTION) -@Retention(AnnotationRetention.RUNTIME) -@MustBeDocumented -annotation class Mythic - -@Target(AnnotationTarget.FUNCTION) -@Retention(AnnotationRetention.RUNTIME) -@MustBeDocumented -annotation class Overlord \ No newline at end of file diff --git a/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/EventTemplate.kt b/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/EventTemplate.kt index a07813a..a15cbe9 100644 --- a/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/EventTemplate.kt +++ b/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/EventTemplate.kt @@ -3,7 +3,6 @@ package io.github.flyingpig525.base import io.github.flyingpig525.base.block.EntityEvent import io.github.flyingpig525.base.block.EventBlock import io.github.flyingpig525.base.block.PlayerEvent -import io.github.flyingpig525.base.item.Item /** * A DiamondFire event. @@ -12,23 +11,29 @@ import io.github.flyingpig525.base.item.Item */ class EventTemplate private constructor( event: EventBlock, - a: Template.() -> Unit + code: Template.() -> Unit ) : Template( - Type.EVENT, "", a = a + Type.EVENT, "", code = code ) { - constructor(event: PlayerEvent, a: Template.() -> Unit) : this( + /** + * Creates a player event codeline + */ + constructor(event: PlayerEvent, code: Template.() -> Unit) : this( EventBlock( event.type, event.event - ), a + ), code ) - constructor(event: EntityEvent, a: Template.() -> Unit) : this( + /** + * Creates an entity event codeline + */ + constructor(event: EntityEvent, code: Template.() -> Unit) : this( EventBlock( event.type, event.event - ), a + ), code ) init { diff --git a/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/GlobalActionDump.kt b/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/GlobalActionDump.kt deleted file mode 100644 index 6068d19..0000000 --- a/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/GlobalActionDump.kt +++ /dev/null @@ -1,62 +0,0 @@ -package io.github.flyingpig525.base - -import io.github.flyingpig525.base.block.Block -import io.github.flyingpig525.base.item.Item -import io.ktor.client.* -import io.ktor.client.call.* -import io.ktor.client.engine.* -import io.ktor.client.engine.java.* -import io.ktor.client.request.* -import io.ktor.http.* -import kotlinx.coroutines.runBlocking -import kotlinx.serialization.json.* - -object GlobalActionDump { - private var actionDumpBlocks: JsonArray? = null - - const val ACTIONDUMP_URL = "https://raw.githubusercontent.com/FlyingPig525/KotlinFire/refs/heads/master/dbc.json" - - init { - runBlocking { - try { - val get = HttpClient(Java) { - engine { - protocolVersion = java.net.http.HttpClient.Version.HTTP_2 - } - }.get(ACTIONDUMP_URL) { - headers { - append(HttpHeaders.Accept, "text/json") - } - }.body() - actionDumpBlocks = Json.parseToJsonElement(get).jsonObject["actions"]?.jsonArray - } catch (e: Exception) { - - } - } - } - - fun getTags(block: Block): List { - return buildList { - val tags = actionDumpBlocks?.find { - it.jsonObject["name"]?.jsonPrimitive?.content == block.action - }?.jsonObject?.get("tags")?.jsonArray - if (tags != null) { - for ((i, el) in tags.withIndex()) { - this += buildJsonObject { - putJsonObject("item") { - put("id", "bl_tag") - putJsonObject("data") { - put("tag", el.jsonObject["name"]?.jsonPrimitive?.content) - put("option", el.jsonObject["defaultOption"]?.jsonPrimitive?.content) - put("action", block.action) - put("block", block.codeBlock) - } - } - put("slot", 26 - i) - } - } - } - } - } - -} \ No newline at end of file diff --git a/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/Template.kt b/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/Template.kt index 8c95f93..a10a1c6 100644 --- a/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/Template.kt +++ b/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/Template.kt @@ -1,19 +1,11 @@ package io.github.flyingpig525.base -import io.github.flyingpig525.base.block.category.* import io.github.flyingpig525.base.block.* -import io.github.flyingpig525.base.item.Insertable -import io.github.flyingpig525.base.item.Item +import io.github.flyingpig525.base.block.category.* import io.github.flyingpig525.base.item.ItemCollection import io.github.flyingpig525.base.item.ItemComparison -import io.github.flyingpig525.base.item.type.* -import io.github.flyingpig525.base.item.type.NumItem.Companion.numItem -import io.github.flyingpig525.base.item.type.StringItem.Companion.stringItem -import io.github.flyingpig525.base.item.type.TextItem.Companion.textItem -import io.github.flyingpig525.base.item.type.VarItem.Companion.lineVar -import io.github.flyingpig525.base.item.type.VarItem.Companion.toVarItem +import io.github.flyingpig525.base.item.type.ParameterItem import io.github.flyingpig525.encoding.TemplateEncoder -import io.github.flyingpig525.serialization.DiamondFireClass import io.github.flyingpig525.serialization.DiamondFireClassOptIn import io.ktor.client.* import io.ktor.client.engine.java.* @@ -40,7 +32,7 @@ open class Template( type: Type = Type.FUNCTION, val name: String = "PutNameHere", vararg args: ParameterItem, - a: Template.() -> Unit + code: Template.() -> Unit ) : JsonData { val blocks: MutableList = mutableListOf() val SetVariable = SetVariableCategory(this) @@ -77,19 +69,8 @@ open class Template( throw Error("Cannot invoke Event template!") } - operator fun invoke(thisValue: Template, items: Items = {}) = thisValue.invokeTemplate(this, items) - - infix fun ElseOperation.Else(wrappedCode: Template.() -> Unit) { - blocks += ElseBlock() - blocks += BracketBlock(type = "norm") - blocks += Template( - Type.NONE, - a = wrappedCode - ).blocks - blocks += BracketBlock(false, "norm") - } - - + context(t: Template) + operator fun invoke(items: Items = {}) = t.invokeTemplate(this, items) init { if (type != Type.NONE) { @@ -103,7 +84,7 @@ open class Template( } } TemplateContext.push(this) - apply(a) + apply(code) TemplateContext.pop() } @@ -117,474 +98,9 @@ open class Template( } } - fun getTemplateString(): String = TemplateEncoder.encode(this) - - // Extension operator functions - // All VarClass implementations - infix fun VarClass.set(value: T) { - VarClass.assertInsertable(value) - SetVariable.equalTo { - +item - +value - } - } - // bullshit - infix fun VarClass.set(value: GameValue<*>) { - SetVariable.equalTo { - +item - +value - } - } - infix fun VarClass<*>.set(value: VarItem) { - SetVariable.equalTo { - +item - +value - } - } - - // NumVariable - // += - inline operator fun NumVariable.plusAssign(other: Number) = plusAssign(other.numItem) - inline operator fun NumVariable.plusAssign(other: String) = plusAssign(other.numItem) - inline operator fun NumVariable.plusAssign(other: NumVariable) = plusAssign(other.item) - inline operator fun NumVariable.plusAssign(other: NumItem) { - SetVariable.increment { - +item - +other - } - } - inline operator fun NumVariable.plusAssign(other: VarItem) { - SetVariable.increment { - +item - +other - } - } - // -= - inline operator fun NumVariable.minusAssign(other: Number) = minusAssign(other.numItem) - inline operator fun NumVariable.minusAssign(other: String) = minusAssign(other.numItem) - inline operator fun NumVariable.minusAssign(other: NumVariable) = minusAssign(other.item) - inline operator fun NumVariable.minusAssign(other: NumItem) { - SetVariable.decrement { - +item - +other - } - } - inline operator fun NumVariable.minusAssign(other: VarItem) { - SetVariable.decrement { - +item - +other - } - } - // /= - inline operator fun NumVariable.divAssign(other: Number) = divAssign(other.numItem) - inline operator fun NumVariable.divAssign(other: String) = divAssign(other.numItem) - inline operator fun NumVariable.divAssign(other: NumVariable) = divAssign(other.item) - inline operator fun NumVariable.divAssign(other: NumItem) { - SetVariable.divide { - +item - +item - +other - } - } - inline operator fun NumVariable.divAssign(other: VarItem) { - SetVariable.divide { - +item - +item - +other - } - } - // *= - inline operator fun NumVariable.timesAssign(other: Number) = timesAssign(other.numItem) - inline operator fun NumVariable.timesAssign(other: String) = timesAssign(other.numItem) - inline operator fun NumVariable.timesAssign(other: NumVariable) = timesAssign(other.item) - inline operator fun NumVariable.timesAssign(other: NumItem) { - SetVariable.x { - +item - +item - +other - } - } - inline operator fun NumVariable.timesAssign(other: VarItem) { - SetVariable.x { - +item - +item - +other - } - } - // %= - inline operator fun NumVariable.remAssign(other: Number) = remAssign(other.numItem) - inline operator fun NumVariable.remAssign(other: String) = remAssign(other.numItem) - inline operator fun NumVariable.remAssign(other: NumVariable) = remAssign(other.item) - inline operator fun NumVariable.remAssign(other: NumItem) { - SetVariable.mod { - +item - +item - +other - } - } - inline operator fun NumVariable.remAssign(other: VarItem) { - SetVariable.mod { - +item - +item - +other - } - } - inline operator fun NumVariable.unaryMinus() = "-%var($name)".numItem - // TextVariable - // += - inline operator fun TextVariable.plusAssign(other: String) = plusAssign(other.textItem) - inline operator fun TextVariable.plusAssign(other: VarClass<*>) { plusAssign(other.item) } - inline operator fun TextVariable.plusAssign(other: TextItem) { - SetVariable.styledText { - +item - +item - +other - } - } - inline operator fun TextVariable.plusAssign(other: VarItem) { - SetVariable.styledText { - +item - +item - +other - } - } - // Trim - /** - * Trims the content of a styled text - */ - inline fun TextVariable.trim(from: Number, to: Number? = null) = trim(from.numItem, to?.numItem) - /** - * Trims the content of a styled text - * - * [from] and [to] must be [NumItem] parsable strings - */ - inline fun TextVariable.trim(from: String, to: String? = null) = trim(from.numItem, to?.numItem) - /** - * Trims the content of a styled text - * - * @param [to] - Can be an uninitialized variable - */ - inline fun TextVariable.trim(from: VarItem, to: VarItem? = null) { - SetVariable.trimStyledText { - +item - +from - if (to != null) { - +to - } - } - } - /** - * Trims the content of a styled text - */ - inline fun TextVariable.trim(from: NumItem, to: NumItem? = null) { - SetVariable.trimStyledText { - +item - +from - if (to != null) { - +to - } - } - } - // Replace - /** - * @param [replace] - A regex used to find replacement targets - */ - inline fun TextVariable.replace(replace: String, with: String) = replace(replace.textItem, with.textItem) - /** - * @param [replace] - A regex used to find replacement targets - */ - inline fun TextVariable.replace(replace: VarClass<*>, with: VarClass<*>) = replace(replace.item, with.item) - /** - * @param [replace] - A regex used to find replacement targets - */ - inline fun TextVariable.replace(replace: TextItem, with: TextItem) { - SetVariable.rmText { - +item - +item - +replace - +with - } - } - /** - * @param [replace] - A regex used to find replacement targets - */ - inline fun TextVariable.replace(replace: VarItem, with: VarItem) { - SetVariable.rmText { - +item - +item - +replace - +with - } - } - // VecVariable - // Length - inline fun VecVariable.setLength(length: Number) = setLength(length.numItem) - inline fun VecVariable.setLength(length: NumVariable) { - SetVariable.setVectorLength { - +item - +length - } - } - inline fun VecVariable.setLength(length: NumItem) { - SetVariable.setVectorLength { - +item - +length - } - } - // DictionaryVariable - inline operator fun DictionaryVariable.set(key: StringItem, value: Insertable) { - SetVariable.setDictValue { - +key - +value - } - } - inline operator fun DictionaryVariable.set(key: String, value: Insertable) = set(key.stringItem, value) - inline operator fun DictionaryVariable.set(key: String, value: String) = set(key, value.textItem) - inline operator fun DictionaryVariable.set(key: String, value: Number) = set(key, value.numItem) - inline operator fun DictionaryVariable.set(key: StringVariable, value: Insertable) = set(key.stringItem, value) - inline operator fun DictionaryVariable.set(key: StringVariable, value: String) = set(key.stringItem, value.textItem) - inline operator fun DictionaryVariable.set(key: StringVariable, value: Number) = set(key.stringItem, value.numItem) - - /** - * Should only be used when the type expected is string, text, or number. - */ - inline operator fun DictionaryVariable.get(key: String): String = "%entry($name,$key)" - inline operator fun DictionaryVariable.get(key: StringVariable): String = "%entry($name,%var(${key.name})" - inline operator fun DictionaryVariable.get(key: StringItem): String = "%entry($name,${key.text})" - inline fun DictionaryVariable.getAsVariable(key: String, scope: VarItem.Scope = VarItem.Scope.LINE): VarItem { - val i = VarItem("$name-$key-GeneratedGet-oajwkfnvsiuh", scope) - SetVariable.getDictValue { - +i - +item - +key.stringItem - } - return i - } - inline fun DictionaryVariable.getAsVariable(key: StringVariable, scope: VarItem.Scope = VarItem.Scope.LINE): VarItem { - val i = VarItem("$name-%var(${key.name})-GeneratedGet-oajwkfnvsiuh", scope) - SetVariable.getDictValue { - +i - +item - +key - } - return i - } - inline fun DictionaryVariable.getAsVariable(key: StringItem, scope: VarItem.Scope = VarItem.Scope.LINE): VarItem { - val i = VarItem("$name-${key.text}-GeneratedGet-oajwkfnvsiuh", scope) - SetVariable.getDictValue { - +i - +item - +key - } - return i - } - - inline operator fun ListVariable.set(index: NumItem, value: Insertable) { - SetVariable.setListValue { - +item - +index - +value - } - } - inline operator fun ListVariable.set(index: Int, value: Insertable) = set(index.numItem, value) - inline operator fun ListVariable.set(index: Int, value: String) = set(index, value.textItem) - inline operator fun ListVariable.set(index: Int, value: Number) = set(index, value.numItem) - inline operator fun ListVariable.set(index: NumItem, value: String) = set(index, value.textItem) - inline operator fun ListVariable.set(index: NumItem, value: Number) = set(index, value.numItem) - inline operator fun ListVariable.set(index: NumVariable, value: String) = set(index.numItem, value.textItem) - inline operator fun ListVariable.set(index: NumVariable, value: Number) = set(index.numItem, value.numItem) - - inline operator fun ListVariable.get(index: NumVariable): String = "%index($name,%var(${index.name})" - inline operator fun ListVariable.get(index: NumItem): String = "%index($name,${index.value})" - inline operator fun ListVariable.get(index: Int): String = get(index.numItem) - - inline operator fun ListVariable.plusAssign(value: Insertable) { - SetVariable.appendValue { - +item - +value - } - } - - inline operator fun ListVariable.minusAssign(value: Insertable) { - SetVariable.removeListValue { - +item - +value - } - } - - inline fun ListVariable.getAsVariable(index: NumItem, scope: VarItem.Scope = VarItem.Scope.LINE): VarItem { - val i = VarItem("$name-GeneratedGet-${index.value}-aiwhdoaiuhdioa", scope) - SetVariable.getListValue { - +i - +item - +index - } - return i - } - inline fun ListVariable.getAsVariable(index: Int, scope: VarItem.Scope = VarItem.Scope.LINE): VarItem { - val i = VarItem("$name-GeneratedGet-$index-aiwhdoaiuhdioa", scope) - SetVariable.getListValue { - +i - +item - +index.numItem - } - return i - } - inline fun ListVariable.getAsVariable(index: NumVariable, scope: VarItem.Scope = VarItem.Scope.LINE): VarItem { - val i = VarItem("$name-GeneratedGet-%var(${index.name})-aiwhdoaiuhdioa", scope) - SetVariable.getListValue { - +i - +item - +index - } - return i - } - - inline fun ListVariable.flatten() = apply { - SetVariable.flattenList { - +item - } - } - inline fun ListVariable.flatten(out: ListVariable) { - SetVariable.flattenList { - +out - +item - } - } - - // TODO: separate into multiple appends if [values] is too long - inline fun ListVariable.append(vararg values: Insertable) = apply { - SetVariable.appendValue { - +item - for (i in values) { - +i - } - } - } - - inline fun ListVariable.appendAll(value: ListVariable) = apply { - SetVariable.appendList { - +item - +value - } - } - - inline fun ListVariable.dedup() = apply { - SetVariable.dedupList { - +item - } - } - inline fun ListVariable.dedup(out: ListVariable) { - SetVariable.dedupList { - +out - +item - } - } - - inline fun ListVariable.reverse() = apply { - SetVariable.reverseList { - +item - } - } - inline fun ListVariable.reverse(out: ListVariable) { - SetVariable.reverseList { - +out - +item - } - } - - inline fun ListVariable.randomize() = apply { - SetVariable.randomizeList { - +item - +item - } - } - inline fun ListVariable.randomize(out: ListVariable) { - SetVariable.randomizeList { - +out - +item - } - } - - inline fun ListVariable.trim(startIndex: NumItem, endIndex: NumItem) = apply { - SetVariable.trimList { - +item - +startIndex - +endIndex - } - } - inline fun ListVariable.trim(startIndex: Int, endIndex: Int) = - trim(startIndex.numItem, endIndex.numItem) - inline fun ListVariable.trim(startIndex: NumVariable, endIndex: NumVariable) = - trim(startIndex.numItem, endIndex.numItem) - inline fun ListVariable.trim(startIndex: NumItem, endIndex: NumItem, out: ListVariable) = apply { - SetVariable.trimList { - +out - +item - +startIndex - +endIndex - } - } - inline fun ListVariable.trim(startIndex: Int, endIndex: Int, out: ListVariable) = - trim(startIndex.numItem, endIndex.numItem, out) - inline fun ListVariable.trim(startIndex: NumVariable, endIndex: NumVariable, out: ListVariable) = - trim(startIndex.numItem, endIndex.numItem, out) - - inline fun ListVariable.sort() = apply { - SetVariable.sortList { - +item - } - } - inline fun ListVariable.sort(out: ListVariable) { - SetVariable.sortList { - +out - +item - } - } - - inline fun ListVariable.removeIndex(index: NumItem) = apply { - SetVariable.removeListIndex { - +item - +index - } - } - inline fun ListVariable.removeIndex(index: Int) = removeIndex(index.numItem) - inline fun ListVariable.removeIndex(index: NumVariable) = removeIndex(index.numItem) - - inline fun ListVariable.removeValue(value: Insertable) = apply { - SetVariable.removeListValue { - +item - +value - } - } - - inline fun ListVariable.pop( - index: NumItem, - out: VarItem = VarItem("$name-${index.value}-PopValue", VarItem.Scope.LINE) - ): VarItem { - SetVariable.popListValue { - +out - +item - +index - } - return out - } - inline fun ListVariable.pop( - index: Int, - out: VarItem = VarItem("$name-$index-PopValue", VarItem.Scope.LINE) - ) = pop(index.numItem, out) - inline fun ListVariable.pop( - index: NumVariable, - out: VarItem = VarItem("$name-%var(${index.name})-PopValue", VarItem.Scope.LINE) - ) = pop(index.numItem, out) - - inline val ListVariable.size: NumItem get() { - val i = VarItem("$name-ListLength-auhdoiwauhisd", VarItem.Scope.LINE) - SetVariable.listLength { - +i - +item - } - return "%var(${i.name})".numItem + fun getTemplateString(): String { + println("Getting template string for $name") + return TemplateEncoder.encode(this) } fun ifVal(comp: ItemComparison, wrappedCode: Template.() -> Unit): ElseOperation { @@ -592,29 +108,6 @@ open class Template( return ElseOperation() } - @OptIn(DiamondFireClassOptIn::class) - fun DiamondFireClass.init() { - // TODO: add appending if toInitialize is too long for one chest - SetVariable.createList { - +"${name}-KeyList-ajowdoiwajdpowd".lineVar - for (prop in toInitialize.keys) { - +prop.name.stringItem - } - } - SetVariable.createList { - +"${name}-ValueList-ajowdoiwajdpowd".lineVar - for (default in toInitialize.values) { - +default - } - } - SetVariable.createDict { - +name.toVarItem(scope) - +"${name}-KeyList-ajowdoiwajdpowd".lineVar - +"${name}-ValueList-ajowdoiwajdpowd".lineVar - } - } - - companion object { @Deprecated("Recode is no longer being worked on") fun recodeSendTemplate(template: Template) { @@ -656,13 +149,18 @@ open class Template( port = 31375 ) { send("scopes read_plot write_code") + + println("Sent auth request to codeclient") if ("auth" !in String(incoming.receive().data)) { close() return@webSocket } + println("Authed successfully") + send("size") + println("Sent size request to codeclient") val size = String(incoming.receive().data) val sizeNum = when(size) { @@ -672,12 +170,15 @@ open class Template( "MEGA" -> 300 else -> 0 } + + println("Received size $sizeNum") if (sizeNum == 0) { close() return@webSocket } - + + for (temp in templates) { if (temp.blocks.size*2 > sizeNum && !ignoreSizeWarning) { println("TEMPLATE PLACE ERROR\n" @@ -689,15 +190,19 @@ open class Template( } } + println("Sending templates to codeclient") send("place swap") for (temp in templates) { send("place ${temp.getTemplateString()}") + println("Sent ${temp.name}") } - + + println("Sent place request to codeclient") send("place go") incoming.receive() - + + println("Done, closing websocket") close(CloseReason(CloseReason.Codes.NORMAL, "Function done.")) } } diff --git a/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/TemplateCollection.kt b/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/TemplateCollection.kt index b9505ca..60609e2 100644 --- a/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/TemplateCollection.kt +++ b/KotlinFire/src/main/kotlin/io/github/flyingpig525/base/TemplateCollection.kt @@ -2,47 +2,71 @@ package io.github.flyingpig525.base import io.github.flyingpig525.base.block.EntityEvent import io.github.flyingpig525.base.block.PlayerEvent -import io.github.flyingpig525.base.item.Item import io.github.flyingpig525.base.item.type.ParameterItem /** * A helper class providing easy definition and sending of multiple [Template]s. */ -class TemplateCollection(a: TemplateCollection.() -> Unit) { +class TemplateCollection(a: TemplateCollection.() -> Unit) : Iterable