factorio -> event -> mod -> console -> kafka pipe -> kafka -> event processor working!!!!!!!!!!!!!!!!!!
This commit is contained in:
parent
7091f7648d
commit
42b60ac0c3
19 changed files with 152 additions and 87 deletions
25
README.md
25
README.md
|
|
@ -9,11 +9,11 @@
|
||||||
## todo
|
## todo
|
||||||
|
|
||||||
* add settings
|
* add settings
|
||||||
* is active - whether files are exported or not
|
* is active - whether files are exported or not
|
||||||
* delete files - clean up all files
|
* delete files - clean up all files
|
||||||
* tick-rate - how often reports are generated (
|
* tick-rate - how often reports are generated (
|
||||||
* requires on some sort of in-mod cache of map<entity-id, event>)
|
* requires on some sort of in-mod cache of map<entity-id, event>)
|
||||||
* also divide by game-speed? to keep ratio the same
|
* also divide by game-speed? to keep ratio the same
|
||||||
|
|
||||||
### to investigate:
|
### to investigate:
|
||||||
|
|
||||||
|
|
@ -21,6 +21,11 @@
|
||||||
* https://github.com/grafi-tt/lunajson
|
* https://github.com/grafi-tt/lunajson
|
||||||
* http://lua-users.org/wiki/CompressionAndArchiving
|
* http://lua-users.org/wiki/CompressionAndArchiving
|
||||||
* https://luapower.com/zlib
|
* https://luapower.com/zlib
|
||||||
|
* https://github.com/appgurueu/modlib#bluon
|
||||||
|
* https://github.com/dingyi222666/lua-table-serialize
|
||||||
|
* https://github.com/uriid1/lua-serialize
|
||||||
|
* https://github.com/rxi/lume#lumeserializex
|
||||||
|
* https://github.com/SwadicalRag/bON
|
||||||
|
|
||||||
* https://square.github.io/okio/#communicate-on-a-socket-javakotlin
|
* https://square.github.io/okio/#communicate-on-a-socket-javakotlin
|
||||||
|
|
||||||
|
|
@ -30,6 +35,16 @@
|
||||||
|
|
||||||
* https://jbrandhorst.com/post/go-protobuf-tips/
|
* https://jbrandhorst.com/post/go-protobuf-tips/
|
||||||
|
|
||||||
|
##### flatbuffers
|
||||||
|
|
||||||
|
https://github.com/dvidelabs/flatcc
|
||||||
|
|
||||||
|
|
||||||
|
##### z85 encoding
|
||||||
|
|
||||||
|
* Kotlin https://gist.github.com/ischumacher/b4929f26341ebef62cbce35c65543eda
|
||||||
|
* Lua https://web-eworks.github.io/lZ85/
|
||||||
|
|
||||||
#### CBOR
|
#### CBOR
|
||||||
|
|
||||||
https://www.zash.se/lua-cbor.html
|
https://www.zash.se/lua-cbor.html
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "dev.adamko"
|
group = "dev.adamko"
|
||||||
version = "0.0.7"
|
version = "0.1.1"
|
||||||
|
|
||||||
tasks.wrapper {
|
tasks.wrapper {
|
||||||
gradleVersion = "7.3"
|
gradleVersion = "7.3"
|
||||||
|
|
@ -26,7 +26,7 @@ val runKafkatorio by tasks.registering {
|
||||||
group = project.name
|
group = project.name
|
||||||
|
|
||||||
dependsOn(
|
dependsOn(
|
||||||
":modules:infra-factorio-client:processRun",
|
":modules:infra-factorio-client:processRestart",
|
||||||
":modules:infra-factorio-server:processRun",
|
":modules:infra-factorio-server:processRestart",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
9
buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt
Normal file
9
buildSrc/src/main/kotlin/dev/adamko/kafkatorio/common.kt
Normal file
|
|
@ -0,0 +1,9 @@
|
||||||
|
package dev.adamko.kafkatorio
|
||||||
|
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
|
||||||
|
|
||||||
|
val jsonMapper = Json {
|
||||||
|
prettyPrint = true
|
||||||
|
prettyPrintIndent = " "
|
||||||
|
}
|
||||||
|
|
@ -1,8 +1,13 @@
|
||||||
package dev.adamko.kafkatorio.gradle
|
package dev.adamko.kafkatorio.gradle
|
||||||
|
|
||||||
|
import dev.adamko.kafkatorio.jsonMapper
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
|
import kotlinx.serialization.json.jsonObject
|
||||||
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.Task
|
import org.gradle.api.Task
|
||||||
|
import org.gradle.api.file.RegularFileProperty
|
||||||
|
import org.gradle.api.logging.LogLevel
|
||||||
import org.gradle.api.specs.Spec
|
import org.gradle.api.specs.Spec
|
||||||
import org.gradle.kotlin.dsl.invoke
|
import org.gradle.kotlin.dsl.invoke
|
||||||
|
|
||||||
|
|
@ -12,10 +17,28 @@ fun Project.isProcessRunning(process: String, ignoreCase: Boolean = true): Spec<
|
||||||
Spec<Task> {
|
Spec<Task> {
|
||||||
ByteArrayOutputStream().use { outputStream ->
|
ByteArrayOutputStream().use { outputStream ->
|
||||||
project.exec {
|
project.exec {
|
||||||
commandLine("tasklist")
|
commandLine("tasklist") // Windows only for now...
|
||||||
standardOutput = outputStream
|
standardOutput = outputStream
|
||||||
}
|
}
|
||||||
outputStream.toString()
|
outputStream.toString()
|
||||||
.contains(process, ignoreCase)
|
.contains(process, ignoreCase)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Project.areJsonPropertiesUpToDate(
|
||||||
|
packageJsonFile: RegularFileProperty,
|
||||||
|
properties: () -> Map<String, String>
|
||||||
|
): Spec<Task> = Spec<Task> {
|
||||||
|
val packageJsonContent = packageJsonFile.get().asFile.readText()
|
||||||
|
val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject
|
||||||
|
|
||||||
|
properties().all { (key, expectedVal) ->
|
||||||
|
val actualVal = packageJson[key]?.jsonPrimitive?.content
|
||||||
|
(expectedVal == actualVal).also {
|
||||||
|
logger.log(
|
||||||
|
if (it) LogLevel.LIFECYCLE else LogLevel.INFO,
|
||||||
|
"package.json has outdated property '$key' (expected: $expectedVal, actual: $actualVal)"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,17 @@
|
||||||
package dev.adamko.kafkatorio.lang
|
package dev.adamko.kafkatorio.lang
|
||||||
|
|
||||||
import com.github.gradle.node.NodePlugin
|
import com.github.gradle.node.NodePlugin
|
||||||
import dev.adamko.kafkatorio.task.UpdatePackageJson
|
import dev.adamko.kafkatorio.gradle.areJsonPropertiesUpToDate
|
||||||
import dev.adamko.kafkatorio.gradle.not
|
import dev.adamko.kafkatorio.gradle.not
|
||||||
|
import dev.adamko.kafkatorio.jsonMapper
|
||||||
|
import dev.adamko.kafkatorio.task.UpdatePackageJson
|
||||||
import kotlinx.serialization.encodeToString
|
import kotlinx.serialization.encodeToString
|
||||||
import kotlinx.serialization.json.Json
|
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
import kotlinx.serialization.json.JsonPrimitive
|
import kotlinx.serialization.json.JsonPrimitive
|
||||||
import kotlinx.serialization.json.jsonObject
|
import kotlinx.serialization.json.jsonObject
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
|
||||||
import org.gradle.kotlin.dsl.support.useToRun
|
import org.gradle.kotlin.dsl.support.useToRun
|
||||||
import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMultiplatformPlugin
|
|
||||||
import org.jetbrains.kotlin.gradle.targets.js.KotlinJsPlugin
|
|
||||||
import org.jetbrains.kotlin.util.suffixIfNot
|
import org.jetbrains.kotlin.util.suffixIfNot
|
||||||
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("com.github.node-gradle.node")
|
id("com.github.node-gradle.node")
|
||||||
id("dev.adamko.kafkatorio.base")
|
id("dev.adamko.kafkatorio.base")
|
||||||
|
|
@ -27,32 +24,6 @@ node {
|
||||||
distBaseUrl.set(null as String?) // set by dependencyResolutionManagement
|
distBaseUrl.set(null as String?) // set by dependencyResolutionManagement
|
||||||
}
|
}
|
||||||
|
|
||||||
project.plugins.withType<KotlinJsPlugin>()
|
|
||||||
project.plugins.withType<KotlinMultiplatformPlugin>()
|
|
||||||
|
|
||||||
|
|
||||||
val jsonMapper = Json {
|
|
||||||
prettyPrint = true
|
|
||||||
prettyPrintIndent = " "
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
fun arePropertiesUpToDate(
|
|
||||||
packageJsonFile: RegularFileProperty,
|
|
||||||
properties: () -> Map<String, String>
|
|
||||||
): Spec<Task> = Spec<Task> {
|
|
||||||
val packageJsonContent = packageJsonFile.get().asFile.readText()
|
|
||||||
val packageJson = jsonMapper.parseToJsonElement(packageJsonContent).jsonObject
|
|
||||||
|
|
||||||
properties().all { (key, expectedVal) ->
|
|
||||||
val actualVal = packageJson[key]?.jsonPrimitive?.content
|
|
||||||
(expectedVal == actualVal).also {
|
|
||||||
if (!it)
|
|
||||||
logger.lifecycle("package.json has outdated property '$key' (expected: $expectedVal, actual: $actualVal)")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val updatePackageJson by tasks.registering(UpdatePackageJson::class) {
|
val updatePackageJson by tasks.registering(UpdatePackageJson::class) {
|
||||||
group = NodePlugin.NODE_GROUP
|
group = NodePlugin.NODE_GROUP
|
||||||
description = "Read the package.json file and update the version and name, based on the project."
|
description = "Read the package.json file and update the version and name, based on the project."
|
||||||
|
|
@ -60,7 +31,7 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) {
|
||||||
propertiesToCheck["version"] = "${project.version}"
|
propertiesToCheck["version"] = "${project.version}"
|
||||||
|
|
||||||
// check to see if the properties are already up-to-date
|
// check to see if the properties are already up-to-date
|
||||||
onlyIf(!arePropertiesUpToDate(packageJsonFile) { propertiesToCheck })
|
onlyIf(!areJsonPropertiesUpToDate(packageJsonFile) { propertiesToCheck })
|
||||||
|
|
||||||
doLast {
|
doLast {
|
||||||
val packageJsonContent = packageJsonFile.get().asFile.readText()
|
val packageJsonContent = packageJsonFile.get().asFile.readText()
|
||||||
|
|
@ -74,7 +45,7 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) {
|
||||||
.encodeToString(packageJsonUpdate)
|
.encodeToString(packageJsonUpdate)
|
||||||
.suffixIfNot("\n")
|
.suffixIfNot("\n")
|
||||||
|
|
||||||
logger.lifecycle(packageJsonContentUpdated)
|
logger.debug(packageJsonContentUpdated)
|
||||||
|
|
||||||
packageJsonFile.get().asFile.writer().useToRun {
|
packageJsonFile.get().asFile.writer().useToRun {
|
||||||
write(packageJsonContentUpdated)
|
write(packageJsonContentUpdated)
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ val typescriptToLua by tasks.registering(NpmTask::class) {
|
||||||
description = "Convert Typescript To Lua"
|
description = "Convert Typescript To Lua"
|
||||||
group = project.name
|
group = project.name
|
||||||
|
|
||||||
dependsOn(tasks.npmInstall)
|
dependsOn(tasks.npmInstall, fetchEventsSchema)
|
||||||
|
|
||||||
execOverrides { standardOutput = System.out }
|
execOverrides { standardOutput = System.out }
|
||||||
|
|
||||||
|
|
@ -121,12 +121,13 @@ distributions {
|
||||||
contents {
|
contents {
|
||||||
from(layout.projectDirectory.dir("src/main/resources/mod-data")) {
|
from(layout.projectDirectory.dir("src/main/resources/mod-data")) {
|
||||||
include("**/**")
|
include("**/**")
|
||||||
filter<ReplaceTokens>("tokens" to tokens)
|
|
||||||
}
|
}
|
||||||
from(licenseFile)
|
from(licenseFile)
|
||||||
from(typescriptToLua.map { it.outputs })
|
from(typescriptToLua.map { it.outputs })
|
||||||
|
filter<ReplaceTokens>("tokens" to tokens)
|
||||||
includeEmptyDirs = false
|
includeEmptyDirs = false
|
||||||
exclude {
|
exclude {
|
||||||
|
// exclude empty lines
|
||||||
it.file.run {
|
it.file.run {
|
||||||
isFile && useLines { lines -> lines.all { line -> line.isBlank() } }
|
isFile && useLines { lines -> lines.all { line -> line.isBlank() } }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
import {Serdes} from "./serdes/serdes"
|
import {Serdes} from "./serdes/serdes"
|
||||||
|
|
||||||
const MOD_VERSION = script.active_mods["factorio-web-map"]
|
const MOD_VERSION = script.active_mods["@mod.name@"] ?? "UNKNOWN"
|
||||||
|
const FACTORIO_VERSION = script.active_mods["base"] ?? "UNKNOWN"
|
||||||
|
|
||||||
const mapEventIdToName = new LuaTable<defines.Events, keyof typeof defines.events>()
|
const mapEventIdToName = new LuaTable<defines.Events, keyof typeof defines.events>()
|
||||||
for (const [k, v] of pairs(defines.events)) {
|
for (const [k, v] of pairs(defines.events)) {
|
||||||
|
|
@ -48,6 +49,7 @@ function emitEvent<T extends FactorioObjectData>(eventData: T, tick: uint, event
|
||||||
data: eventData,
|
data: eventData,
|
||||||
event_type: eventType,
|
event_type: eventType,
|
||||||
mod_version: MOD_VERSION,
|
mod_version: MOD_VERSION,
|
||||||
|
factorio_version: FACTORIO_VERSION,
|
||||||
tick: tick
|
tick: tick
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "kafkatorio-events-mod",
|
"name": "kafkatorio-events-mod",
|
||||||
"version": "0.0.7",
|
"version": "0.1.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "kafkatorio-events-mod",
|
"name": "kafkatorio-events-mod",
|
||||||
"version": "0.0.7",
|
"version": "0.1.1",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tstl",
|
"build": "tstl",
|
||||||
|
|
@ -9,7 +9,8 @@
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.13.0"
|
"node": ">=10.13.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {},
|
"devDependencies": {
|
||||||
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"lua-types": "^2.11.0",
|
"lua-types": "^2.11.0",
|
||||||
"@types/node": "^12.0.8",
|
"@types/node": "^12.0.8",
|
||||||
|
|
@ -20,7 +21,10 @@
|
||||||
"//": {
|
"//": {
|
||||||
"typed-factorio": "0.10.0"
|
"typed-factorio": "0.10.0"
|
||||||
},
|
},
|
||||||
"peerDependencies": {},
|
"peerDependencies": {
|
||||||
"optionalDependencies": {},
|
},
|
||||||
"bundledDependencies": []
|
"optionalDependencies": {
|
||||||
|
},
|
||||||
|
"bundledDependencies": [
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ interface FactorioObjectData {
|
||||||
interface FactorioEvent<T extends FactorioObjectData> {
|
interface FactorioEvent<T extends FactorioObjectData> {
|
||||||
data: T;
|
data: T;
|
||||||
event_type: string;
|
event_type: string;
|
||||||
|
factorio_version: string;
|
||||||
mod_version: string;
|
mod_version: string;
|
||||||
tick: uint;
|
tick: uint;
|
||||||
}
|
}
|
||||||
|
|
@ -21,7 +22,6 @@ interface PlayerData extends FactorioObjectData {
|
||||||
associated_characters_unit_numbers: uint[];
|
associated_characters_unit_numbers: uint[];
|
||||||
character_unit_number: uint | null;
|
character_unit_number: uint | null;
|
||||||
name: string;
|
name: string;
|
||||||
object_name: string;
|
|
||||||
position: PositionData;
|
position: PositionData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,7 +30,6 @@ interface EntityData extends FactorioObjectData {
|
||||||
health: double | null;
|
health: double | null;
|
||||||
health_ratio: double;
|
health_ratio: double;
|
||||||
name: string;
|
name: string;
|
||||||
object_name: string;
|
|
||||||
player_index: uint | null;
|
player_index: uint | null;
|
||||||
position: PositionData;
|
position: PositionData;
|
||||||
surface_index: int;
|
surface_index: int;
|
||||||
|
|
@ -42,5 +41,4 @@ interface SurfaceData extends FactorioObjectData {
|
||||||
daytime: double;
|
daytime: double;
|
||||||
index: uint;
|
index: uint;
|
||||||
name: string;
|
name: string;
|
||||||
object_name: string;
|
|
||||||
}
|
}
|
||||||
|
|
@ -5,13 +5,40 @@ import dev.adamko.kafkatorio.events.schema.FactorioObjectData
|
||||||
import dev.adamko.kafkatorio.events.schema.jsonMapper
|
import dev.adamko.kafkatorio.events.schema.jsonMapper
|
||||||
import dev.adamko.kafkatorio.processor.config.ApplicationProperties
|
import dev.adamko.kafkatorio.processor.config.ApplicationProperties
|
||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
|
import kotlinx.serialization.decodeFromString
|
||||||
|
import kotlinx.serialization.encodeToString
|
||||||
|
import kotlinx.serialization.modules.SerializersModule
|
||||||
|
import org.apache.kafka.common.serialization.Deserializer
|
||||||
|
import org.apache.kafka.common.serialization.Serde
|
||||||
import org.apache.kafka.common.serialization.Serdes
|
import org.apache.kafka.common.serialization.Serdes
|
||||||
|
import org.apache.kafka.common.serialization.Serializer
|
||||||
import org.apache.kafka.streams.KafkaStreams
|
import org.apache.kafka.streams.KafkaStreams
|
||||||
import org.apache.kafka.streams.StreamsBuilder
|
import org.apache.kafka.streams.StreamsBuilder
|
||||||
import org.apache.kafka.streams.TopologyDescription
|
import org.apache.kafka.streams.TopologyDescription
|
||||||
import org.apache.kafka.streams.kstream.Consumed
|
import org.apache.kafka.streams.kstream.Consumed
|
||||||
import org.apache.kafka.streams.processor.TopicNameExtractor
|
import org.apache.kafka.streams.kstream.Produced
|
||||||
import org.http4k.format.KotlinxSerialization
|
import org.http4k.format.ConfigurableKotlinxSerialization
|
||||||
|
import org.http4k.format.asConfigurable
|
||||||
|
import org.http4k.format.withStandardMappings
|
||||||
|
|
||||||
|
object KSX : ConfigurableKotlinxSerialization({
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
prettyPrint = true
|
||||||
|
prettyPrintIndent = " "
|
||||||
|
asConfigurable().withStandardMappings().done()
|
||||||
|
serializersModule = SerializersModule { }
|
||||||
|
})
|
||||||
|
|
||||||
|
object JsonSerdes : Serde<FactorioEvent<FactorioObjectData>> {
|
||||||
|
override fun serializer() = Serializer<FactorioEvent<FactorioObjectData>> { _, message ->
|
||||||
|
jsonMapper.encodeToString<FactorioEvent<FactorioObjectData>>(message).encodeToByteArray()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun deserializer() = Deserializer<FactorioEvent<FactorioObjectData>> { _, bytes ->
|
||||||
|
jsonMapper.decodeFromString(bytes.decodeToString())
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
|
|
||||||
|
|
@ -25,16 +52,18 @@ fun main() {
|
||||||
)
|
)
|
||||||
.mapValues { readOnlyKey, value ->
|
.mapValues { readOnlyKey, value ->
|
||||||
println("Mapping $readOnlyKey:$value")
|
println("Mapping $readOnlyKey:$value")
|
||||||
// jsonMapper.decodeFromString<FactorioEvent<*>>(value)
|
jsonMapper.decodeFromString<FactorioEvent<FactorioObjectData>>(value)
|
||||||
KotlinxSerialization.asA<FactorioEvent<FactorioObjectData>>(value)
|
// KSX.asA<FactorioEvent<FactorioObjectData>>(value)
|
||||||
}
|
}
|
||||||
.to(TopicNameExtractor { key, value, recordContext ->
|
.to(
|
||||||
value.data.objectName
|
{ key, value, recordContext -> value.data.objectName },
|
||||||
})
|
Produced.with(Serdes.String(), JsonSerdes)
|
||||||
|
)
|
||||||
|
|
||||||
val topology = builder.build()
|
val topology = builder.build()
|
||||||
val properties = appProps.kafkaConfig
|
val properties = appProps.kafkaConfig
|
||||||
|
|
||||||
|
|
||||||
val streams = KafkaStreams(topology, properties)
|
val streams = KafkaStreams(topology, properties)
|
||||||
|
|
||||||
streams.setUncaughtExceptionHandler(StreamsExceptionHandler())
|
streams.setUncaughtExceptionHandler(StreamsExceptionHandler())
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,8 @@ dependencies {
|
||||||
|
|
||||||
implementation("com.github.ntrrgc:ts-generator:1.1.2")
|
implementation("com.github.ntrrgc:ts-generator:1.1.2")
|
||||||
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
implementation("org.jetbrains.kotlin:kotlin-reflect")
|
||||||
|
|
||||||
|
testImplementation(libs.kotest.datatest)
|
||||||
}
|
}
|
||||||
|
|
||||||
val generateTypescript by tasks.registering(JavaExec::class) {
|
val generateTypescript by tasks.registering(JavaExec::class) {
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,11 @@
|
||||||
package dev.adamko.kafkatorio.events.schema
|
package dev.adamko.kafkatorio.events.schema
|
||||||
|
|
||||||
|
|
||||||
|
import kotlin.reflect.full.findAnnotation
|
||||||
|
import kotlin.reflect.full.findAnnotations
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.Transient
|
||||||
import kotlinx.serialization.json.JsonClassDiscriminator
|
import kotlinx.serialization.json.JsonClassDiscriminator
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -15,6 +18,8 @@ data class FactorioEvent<out T : FactorioObjectData>(
|
||||||
/** Schema versioning */
|
/** Schema versioning */
|
||||||
@SerialName("mod_version")
|
@SerialName("mod_version")
|
||||||
val modVersion: String,
|
val modVersion: String,
|
||||||
|
@SerialName("factorio_version")
|
||||||
|
val factorioVersion: String,
|
||||||
/** game time */
|
/** game time */
|
||||||
@SerialName("tick")
|
@SerialName("tick")
|
||||||
val tick: UInt,
|
val tick: UInt,
|
||||||
|
|
@ -29,17 +34,19 @@ const val FactorioObjectDataDiscriminatorKey: String = "object_name"
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@JsonClassDiscriminator(FactorioObjectDataDiscriminatorKey)
|
@JsonClassDiscriminator(FactorioObjectDataDiscriminatorKey)
|
||||||
sealed class FactorioObjectData {
|
sealed class FactorioObjectData private constructor() {
|
||||||
@SerialName(FactorioObjectDataDiscriminatorKey)
|
|
||||||
abstract val objectName: String
|
// workaround - https://github.com/Kotlin/kotlinx.serialization/issues/1664
|
||||||
|
val objectName : String by lazy {
|
||||||
|
requireNotNull(this::class.findAnnotation<SerialName>()?.value) {
|
||||||
|
"Couldn't find @SerialName for ${this::class}!"
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("LuaPlayer")
|
@SerialName("LuaPlayer")
|
||||||
data class PlayerData(
|
data class PlayerData(
|
||||||
@SerialName(FactorioObjectDataDiscriminatorKey)
|
|
||||||
override val objectName: String,
|
|
||||||
|
|
||||||
@Serializable(with = ListAsObjectSerializer::class)
|
@Serializable(with = ListAsObjectSerializer::class)
|
||||||
@SerialName("associated_characters_unit_numbers")
|
@SerialName("associated_characters_unit_numbers")
|
||||||
val associatedCharactersUnitNumbers: List<UInt>,
|
val associatedCharactersUnitNumbers: List<UInt>,
|
||||||
|
|
@ -54,9 +61,6 @@ data class PlayerData(
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("LuaEntity")
|
@SerialName("LuaEntity")
|
||||||
data class EntityData(
|
data class EntityData(
|
||||||
@SerialName(FactorioObjectDataDiscriminatorKey)
|
|
||||||
override val objectName: String,
|
|
||||||
|
|
||||||
@SerialName("active")
|
@SerialName("active")
|
||||||
val active: Boolean,
|
val active: Boolean,
|
||||||
@SerialName("health")
|
@SerialName("health")
|
||||||
|
|
@ -72,7 +76,7 @@ data class EntityData(
|
||||||
@SerialName("type")
|
@SerialName("type")
|
||||||
val type: String,
|
val type: String,
|
||||||
@SerialName("unit_number")
|
@SerialName("unit_number")
|
||||||
val unitNumber: UInt?,
|
val unitNumber: UInt? = null,
|
||||||
|
|
||||||
@SerialName("player_index")
|
@SerialName("player_index")
|
||||||
val playerIndex: UInt? = null,
|
val playerIndex: UInt? = null,
|
||||||
|
|
@ -81,9 +85,6 @@ data class EntityData(
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("LuaSurface")
|
@SerialName("LuaSurface")
|
||||||
data class SurfaceData(
|
data class SurfaceData(
|
||||||
@SerialName(FactorioObjectDataDiscriminatorKey)
|
|
||||||
override val objectName: String,
|
|
||||||
|
|
||||||
@SerialName("daytime")
|
@SerialName("daytime")
|
||||||
val daytime: Double,
|
val daytime: Double,
|
||||||
@SerialName("index")
|
@SerialName("index")
|
||||||
|
|
|
||||||
|
|
@ -1,14 +1,8 @@
|
||||||
package dev.adamko.kafkatorio.events.schema
|
package dev.adamko.kafkatorio.events.schema
|
||||||
|
|
||||||
import dev.adamko.kafkatorio.events.schema.EntityData
|
|
||||||
import dev.adamko.kafkatorio.events.schema.FactorioEvent
|
|
||||||
import dev.adamko.kafkatorio.events.schema.FactorioObjectData
|
|
||||||
import dev.adamko.kafkatorio.events.schema.PlayerData
|
|
||||||
import dev.adamko.kafkatorio.events.schema.PositionData
|
|
||||||
import dev.adamko.kafkatorio.events.schema.SurfaceData
|
|
||||||
import dev.adamko.kafkatorio.events.schema.jsonMapper
|
|
||||||
import io.kotest.core.spec.style.BehaviorSpec
|
import io.kotest.core.spec.style.BehaviorSpec
|
||||||
import io.kotest.matchers.equality.shouldBeEqualToComparingFields
|
import io.kotest.matchers.equality.shouldBeEqualToComparingFields
|
||||||
|
import io.kotest.matchers.shouldBe
|
||||||
import kotlinx.serialization.decodeFromString
|
import kotlinx.serialization.decodeFromString
|
||||||
import org.intellij.lang.annotations.Language
|
import org.intellij.lang.annotations.Language
|
||||||
|
|
||||||
|
|
@ -31,6 +25,7 @@ class FactorioEventTest : BehaviorSpec({
|
||||||
},
|
},
|
||||||
"event_type": "on_player_joined_game",
|
"event_type": "on_player_joined_game",
|
||||||
"mod_version": "0.0.4",
|
"mod_version": "0.0.4",
|
||||||
|
"factorio_version": "1.1.48",
|
||||||
"tick": 1278458
|
"tick": 1278458
|
||||||
}
|
}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
@ -40,7 +35,6 @@ class FactorioEventTest : BehaviorSpec({
|
||||||
|
|
||||||
val expected = FactorioEvent(
|
val expected = FactorioEvent(
|
||||||
data = PlayerData(
|
data = PlayerData(
|
||||||
objectName = "LuaPlayer",
|
|
||||||
name = "fredthedeadhead",
|
name = "fredthedeadhead",
|
||||||
characterUnitNumber = 1u,
|
characterUnitNumber = 1u,
|
||||||
associatedCharactersUnitNumbers = emptyList(),
|
associatedCharactersUnitNumbers = emptyList(),
|
||||||
|
|
@ -51,10 +45,13 @@ class FactorioEventTest : BehaviorSpec({
|
||||||
),
|
),
|
||||||
eventType = "on_player_joined_game",
|
eventType = "on_player_joined_game",
|
||||||
modVersion = "0.0.4",
|
modVersion = "0.0.4",
|
||||||
|
factorioVersion = "1.1.48",
|
||||||
tick = 1278458u
|
tick = 1278458u
|
||||||
)
|
)
|
||||||
|
|
||||||
actual shouldBeEqualToComparingFields expected
|
actual shouldBeEqualToComparingFields expected
|
||||||
|
|
||||||
|
expected.data.objectName shouldBe "LuaPlayer"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -70,6 +67,7 @@ class FactorioEventTest : BehaviorSpec({
|
||||||
},
|
},
|
||||||
"event_type": "on_tick",
|
"event_type": "on_tick",
|
||||||
"mod_version": "0.0.4",
|
"mod_version": "0.0.4",
|
||||||
|
"factorio_version": "1.1.48",
|
||||||
"tick": 1278480
|
"tick": 1278480
|
||||||
}
|
}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
@ -78,17 +76,19 @@ class FactorioEventTest : BehaviorSpec({
|
||||||
|
|
||||||
val expected = FactorioEvent(
|
val expected = FactorioEvent(
|
||||||
data = SurfaceData(
|
data = SurfaceData(
|
||||||
objectName = "LuaSurface",
|
|
||||||
name = "nauvis",
|
name = "nauvis",
|
||||||
index = 1u,
|
index = 1u,
|
||||||
daytime = 0.8390800000511436707029133685864508152008056640625
|
daytime = 0.8390800000511436707029133685864508152008056640625
|
||||||
),
|
),
|
||||||
eventType = "on_tick",
|
eventType = "on_tick",
|
||||||
modVersion = "0.0.4",
|
modVersion = "0.0.4",
|
||||||
|
factorioVersion = "1.1.48",
|
||||||
tick = 1278480u
|
tick = 1278480u
|
||||||
)
|
)
|
||||||
|
|
||||||
actual shouldBeEqualToComparingFields expected
|
actual shouldBeEqualToComparingFields expected
|
||||||
|
|
||||||
|
expected.data.objectName shouldBe "LuaSurface"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,6 +112,7 @@ class FactorioEventTest : BehaviorSpec({
|
||||||
},
|
},
|
||||||
"event_type": "on_player_changed_position",
|
"event_type": "on_player_changed_position",
|
||||||
"mod_version": "0.0.6",
|
"mod_version": "0.0.6",
|
||||||
|
"factorio_version": "1.1.48",
|
||||||
"tick": 1384507
|
"tick": 1384507
|
||||||
}
|
}
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
@ -120,7 +121,6 @@ class FactorioEventTest : BehaviorSpec({
|
||||||
|
|
||||||
val expected = FactorioEvent(
|
val expected = FactorioEvent(
|
||||||
data = EntityData(
|
data = EntityData(
|
||||||
objectName = "LuaEntity",
|
|
||||||
name = "character",
|
name = "character",
|
||||||
type = "character",
|
type = "character",
|
||||||
active = true,
|
active = true,
|
||||||
|
|
@ -136,10 +136,13 @@ class FactorioEventTest : BehaviorSpec({
|
||||||
),
|
),
|
||||||
eventType = "on_player_changed_position",
|
eventType = "on_player_changed_position",
|
||||||
modVersion = "0.0.6",
|
modVersion = "0.0.6",
|
||||||
|
factorioVersion = "1.1.48",
|
||||||
tick = 1384507u
|
tick = 1384507u
|
||||||
)
|
)
|
||||||
|
|
||||||
actual shouldBeEqualToComparingFields expected
|
actual shouldBeEqualToComparingFields expected
|
||||||
|
|
||||||
|
expected.data.objectName shouldBe "LuaEntity"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ val clientLaunch by tasks.registering(Exec::class) {
|
||||||
onlyIf(!isFactorioRunning())
|
onlyIf(!isFactorioRunning())
|
||||||
|
|
||||||
dependsOn(deployModToClient)
|
dependsOn(deployModToClient)
|
||||||
mustRunAfter(clientKill)
|
mustRunAfter(clientKill, ":modules:infra-factorio-server:processRun")
|
||||||
|
|
||||||
commandLine = parseSpaceSeparatedArgs(
|
commandLine = parseSpaceSeparatedArgs(
|
||||||
// """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working
|
// """explorer "steam://rungameid/$factorioGameId// --mp-connect localhost/" """ // not working
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import dev.adamko.kafkatorio.gradle.asConsumer
|
import dev.adamko.kafkatorio.gradle.asConsumer
|
||||||
import dev.adamko.kafkatorio.gradle.factorioModAttributes
|
import dev.adamko.kafkatorio.gradle.factorioModAttributes
|
||||||
|
import org.jetbrains.kotlin.util.parseSpaceSeparatedArgs
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("dev.adamko.kafkatorio.infra.docker-compose")
|
id("dev.adamko.kafkatorio.infra.docker-compose")
|
||||||
|
|
@ -29,6 +30,10 @@ val deployModToServer by tasks.registering(Copy::class) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tasks.dockerDown {
|
||||||
|
commandLine = parseSpaceSeparatedArgs(""" docker-compose stop """)
|
||||||
|
}
|
||||||
|
|
||||||
tasks.dockerUp {
|
tasks.dockerUp {
|
||||||
dependsOn(
|
dependsOn(
|
||||||
deployModToServer,
|
deployModToServer,
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ services:
|
||||||
restart: "unless-stopped"
|
restart: "unless-stopped"
|
||||||
build:
|
build:
|
||||||
dockerfile: "kafka.Dockerfile"
|
dockerfile: "kafka.Dockerfile"
|
||||||
|
context: "."
|
||||||
target: "kafka-kraft"
|
target: "kafka-kraft"
|
||||||
args:
|
args:
|
||||||
KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz"
|
KAFKA_DL_URL: "https://dlcdn.apache.org/kafka/3.0.0/kafka_2.13-3.0.0.tgz"
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ services:
|
||||||
container_name: "kafka-pipe"
|
container_name: "kafka-pipe"
|
||||||
build:
|
build:
|
||||||
dockerfile: "kafka-pipe.Dockerfile"
|
dockerfile: "kafka-pipe.Dockerfile"
|
||||||
|
context: "."
|
||||||
restart: "unless-stopped"
|
restart: "unless-stopped"
|
||||||
privileged: true
|
privileged: true
|
||||||
networks:
|
networks:
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue