tidying up

This commit is contained in:
Adam 2021-12-28 17:05:52 +01:00
parent 7813756c69
commit 08ab1c582c
24 changed files with 105 additions and 324 deletions

View file

@ -6,7 +6,7 @@ plugins {
} }
group = "dev.adamko.kafkatorio" group = "dev.adamko.kafkatorio"
version = "0.1.5" version = "0.1.6"
val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE")) val licenseFile: RegularFile by extra(layout.projectDirectory.file("LICENSE"))

View file

@ -15,7 +15,7 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-reflect") implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion") implementation("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion")
val kotlinXSerializationVersion = "1.3.1" val kotlinXSerializationVersion = "1.3.2"
implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-serialization-bom:$kotlinXSerializationVersion")) implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-serialization-bom:$kotlinXSerializationVersion"))
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core") implementation("org.jetbrains.kotlinx:kotlinx-serialization-core")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json") implementation("org.jetbrains.kotlinx:kotlinx-serialization-json")
@ -24,6 +24,9 @@ dependencies {
implementation("com.github.node-gradle:gradle-node-plugin:3.1.1") implementation("com.github.node-gradle:gradle-node-plugin:3.1.1")
implementation("net.swiftzer.semver:semver:1.1.2") implementation("net.swiftzer.semver:semver:1.1.2")
// https://github.com/avast/gradle-docker-compose-plugin
implementation("com.avast.gradle:gradle-docker-compose-plugin:0.14.12")
} }
val projectJvmTarget = "11" val projectJvmTarget = "11"

View file

@ -32,13 +32,13 @@ val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class)
val nodePath: Directory by extra { val nodePath: Directory by extra {
val file = rootPackageJson.rootPackageJson.parentFile.normalize() val file = rootPackageJson.rootPackageJson.parentFile.normalize()
logger.lifecycle("Kotlin/JS NODE_PATH: $file") logger.info("Kotlin/JS NODE_PATH: $file")
project.layout.dir(project.provider { file }).get() project.layout.dir(project.provider { file }).get()
} }
val nodeModulesDir: Directory by extra { val nodeModulesDir: Directory by extra {
val file = nodePath.dir(NpmProject.NODE_MODULES) val file = nodePath.dir(NpmProject.NODE_MODULES)
logger.lifecycle("Kotlin/JS NODE_MODULES: $file") logger.info("Kotlin/JS NODE_MODULES: $file")
file file
} }

View file

@ -19,7 +19,6 @@ dependencies {
//<editor-fold desc="Main"> //<editor-fold desc="Main">
implementation(platform("org.jetbrains.kotlin:kotlin-bom")) implementation(platform("org.jetbrains.kotlin:kotlin-bom"))
// implementation(kotlin("stdlib"))
//</editor-fold> //</editor-fold>

View file

@ -1,6 +1,7 @@
package dev.adamko.kafkatorio.lang package dev.adamko.kafkatorio.lang
import com.github.gradle.node.NodePlugin import com.github.gradle.node.NodePlugin
import com.github.gradle.node.npm.task.NpmTask
import dev.adamko.kafkatorio.gradle.areJsonPropertiesUpToDate 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.jsonMapper
@ -55,3 +56,6 @@ val updatePackageJson by tasks.registering(UpdatePackageJson::class) {
} }
tasks.assemble { dependsOn(updatePackageJson) } tasks.assemble { dependsOn(updatePackageJson) }
tasks.withType<NpmTask> {
dependsOn(updatePackageJson)
}

View file

@ -12,7 +12,7 @@ kotlin = "1.6.10"
camel-kafkaConnectors = "0.11.0" camel-kafkaConnectors = "0.11.0"
http4k = "4.17.6.0" http4k = "4.17.6.0"
kafka = "3.0.0" kafka = "3.0.0"
kotlinx-serialization = "1.3.1" kotlinx-serialization = "1.3.2"
kvision = "5.6.1" kvision = "5.6.1"
log4j2 = "2.14.1" log4j2 = "2.14.1"
qosLogback = "1.2.5" qosLogback = "1.2.5"

View file

@ -138,7 +138,7 @@ distributions {
filter<ReplaceTokens>("tokens" to projectTokens) filter<ReplaceTokens>("tokens" to projectTokens)
includeEmptyDirs = false includeEmptyDirs = false
exclude { exclude {
// exclude empty files // exclude empty files
it.file.run { it.file.run {
isFile && useLines { lines -> lines.all { line -> line.isBlank() } } isFile && useLines { lines -> lines.all { line -> line.isBlank() } }
} }
@ -148,36 +148,6 @@ distributions {
} }
} }
//val packageMod by tasks.registering(Zip::class) {
// description = "Package mod files into ZIP"
// group = project.name
//
// dependsOn(typescriptToLua)
//
// inputs.properties(tokens)
//
// from(layout.projectDirectory.dir("src/main/resources/mod-data")) {
// include("**/**")
// filter<ReplaceTokens>("tokens" to tokens)
// }
// from(licenseFile)
//
// into(rootProject.name)
//
// // Factorio required format is:
// // - filename: `mod-name_version.zip`
// // - zip contains one directory, `mod-name`
// archiveFileName.set("${rootProject.name}_${project.version}.zip")
// destinationDirectory.set(layout.buildDirectory.dir("dist"))
//
// doLast {
// val outDir = destinationDirectory.asFile.get().toRelativeString(layout.projectDirectory.asFile)
// val outZip = "${archiveFileName.orNull}"
// logger.lifecycle("Packaged mod into $outDir/$outZip")
// }
//}
val downloadFactorioApiDocs by tasks.registering { val downloadFactorioApiDocs by tasks.registering {
group = project.name group = project.name
@ -244,3 +214,5 @@ tasks.assemble { dependsOn(installEventsTsSchema, tasks.updatePackageJson) }
// } // }
// } // }
// } // }
tasks.npmInstall

View file

@ -10,7 +10,7 @@ for (const [k, v] of pairs(defines.events)) {
function handlePlayerUpdate(tick: uint, playerIndex: uint, eventType: string) { function handlePlayerUpdate(tick: uint, playerIndex: uint, eventType: string) {
let player: LuaPlayer = game.players[playerIndex] let player: LuaPlayer = game.players[playerIndex]
let table = Serdes.Player.playerToTable(player) let table = Serdes.playerToTable(player)
emitEvent(table, tick, eventType) emitEvent(table, tick, eventType)
handleCharactersEvent(tick, playerIndex, eventType) handleCharactersEvent(tick, playerIndex, eventType)
@ -31,12 +31,12 @@ function handleCharactersEvent(tick: uint, playerIndex: uint, eventType: string)
} }
function handleEntityUpdate(tick: uint, entity: LuaEntity, eventType: string) { function handleEntityUpdate(tick: uint, entity: LuaEntity, eventType: string) {
let table = Serdes.Entity.entityToTable(entity) let table = Serdes.entityToTable(entity)
emitEvent(table, tick, eventType) emitEvent(table, tick, eventType)
} }
function surfaceEvent(tick: uint, surface: LuaSurface, eventType: string) { function surfaceEvent(tick: uint, surface: LuaSurface, eventType: string) {
let table = Serdes.Surface.surfaceToTable(surface) let table = Serdes.surfaceToTable(surface)
emitEvent(table, tick, eventType) emitEvent(table, tick, eventType)
} }

View file

@ -1,6 +1,6 @@
{ {
"name": "kafkatorio-events-mod", "name": "kafkatorio-events-mod",
"version": "0.1.5", "version": "0.1.6",
"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",
@ -18,7 +19,10 @@
"typescript": "4.5.4" "typescript": "4.5.4"
}, },
"license": "UNLICENSED", "license": "UNLICENSED",
"peerDependencies": {}, "peerDependencies": {
"optionalDependencies": {}, },
"bundledDependencies": [] "optionalDependencies": {
},
"bundledDependencies": [
]
} }

View file

@ -1,23 +1,18 @@
export namespace Serdes { export namespace Serdes {
export namespace Player {
export function playerToTable(player: LuaPlayer): PlayerData { export function playerToTable(player: LuaPlayer): PlayerData {
let charIds = Entity.entitiesToUnitNumbers(player.get_associated_characters()) let charIds = entitiesToUnitNumbers(player.get_associated_characters())
return { return {
object_name: player.object_name, object_name: player.object_name,
name: player.name, name: player.name,
character_unit_number: player.character?.unit_number ?? null, character_unit_number: player.character?.unit_number ?? null,
associated_characters_unit_numbers: charIds, associated_characters_unit_numbers: charIds,
position: DataClasses.positionTableToTable(player.position), position: positionTableToTable(player.position),
} }
} }
}
export namespace Entity {
export function entityToTable(entity: LuaEntity): EntityData { export function entityToTable(entity: LuaEntity): EntityData {
let player: LuaPlayer | null = entity.is_player() ? entity.player!! : null let player: LuaPlayer | null = entity.is_player() ? entity.player!! : null
@ -33,7 +28,7 @@ export namespace Serdes {
health_ratio: entity.get_health_ratio(), health_ratio: entity.get_health_ratio(),
surface_index: entity.surface.index, surface_index: entity.surface.index,
unit_number: entity.unit_number ?? null, unit_number: entity.unit_number ?? null,
position: DataClasses.positionTableToTable(entity.position), position: positionTableToTable(entity.position),
// player data // player data
player_index: player?.index ?? null player_index: player?.index ?? null
@ -50,10 +45,6 @@ export namespace Serdes {
return result return result
} }
}
export namespace Surface {
export function surfaceToTable(surface: LuaSurface): SurfaceData { export function surfaceToTable(surface: LuaSurface): SurfaceData {
return { return {
object_name: surface.object_name, object_name: surface.object_name,
@ -64,10 +55,6 @@ export namespace Serdes {
} }
} }
}
export namespace DataClasses {
export function positionTableToTable(positionTable: PositionTable): PositionData { export function positionTableToTable(positionTable: PositionTable): PositionData {
return { return {
x: positionTable.x, x: positionTable.x,
@ -75,5 +62,4 @@ export namespace Serdes {
} }
} }
}
} }

View file

@ -1,7 +0,0 @@
package dev.adamko.kafkatorio.processor
/**
* Process the raw messages from a server.
*/
class FactorioEventLogConsumer {
}

View file

@ -13,8 +13,8 @@ import org.apache.kafka.streams.kstream.Consumed
import org.apache.kafka.streams.kstream.Produced import org.apache.kafka.streams.kstream.Produced
class FactorioEventsTopology( class FactorioEventsTopology(
val websocketServer: WebsocketServer, private val websocketServer: WebsocketServer,
val builder: StreamsBuilder = StreamsBuilder(), private val builder: StreamsBuilder = StreamsBuilder(),
) { ) {
private val sourceTopic = "factorio-server-log" private val sourceTopic = "factorio-server-log"

View file

@ -47,7 +47,7 @@ class WebsocketServer {
messages.emit(msg) messages.emit(msg)
} }
suspend fun start(): PolyHandler = supervisorScope builder@{ suspend fun build(): PolyHandler = supervisorScope builder@{
coroutineContext.job.invokeOnCompletion { e -> coroutineContext.job.invokeOnCompletion { e ->
e?.let { serverJob.completeExceptionally(it) } ?: serverJob.complete() e?.let { serverJob.completeExceptionally(it) } ?: serverJob.complete()

View file

@ -1,19 +1,11 @@
package dev.adamko.kafkatorio.processor.config package dev.adamko.kafkatorio.processor.config
import com.fasterxml.jackson.databind.JsonNode
import dev.adamko.kafkatorio.processor.config.PortVal.Companion.portVal import dev.adamko.kafkatorio.processor.config.PortVal.Companion.portVal
import java.io.StringReader
import java.time.Clock import java.time.Clock
import java.util.Properties import java.util.Properties
import org.http4k.cloudnative.env.Environment import org.http4k.cloudnative.env.Environment
import org.http4k.cloudnative.env.EnvironmentKey import org.http4k.cloudnative.env.EnvironmentKey
import org.http4k.core.Credentials
import org.http4k.core.Uri
import org.http4k.format.Json
import org.http4k.lens.boolean
import org.http4k.lens.map
import org.http4k.lens.nonEmptyString import org.http4k.lens.nonEmptyString
import org.http4k.lens.uri
/** /**
* Load properties, in descending priority order, from * Load properties, in descending priority order, from

View file

@ -15,18 +15,5 @@ fun main() = runBlocking {
val topology = FactorioEventsTopology(wsServer) val topology = FactorioEventsTopology(wsServer)
topology.build() topology.build()
wsServer.start().asServer(Undertow(9073)).start().block() wsServer.build().asServer(Undertow(9073)).start().block()
} }
//
//
//// a standard websocket app
//val websocketServer = websockets(
// "/lua-objects" bind { ws: Websocket ->
// ws.send(WsMessage("bob"))
// ws.onMessage {
// println("server received: $it")
// ws.send(it)
// }
// }
//).asServer(Undertow(9097)).start()

View file

@ -1,98 +0,0 @@
@file:Suppress("ClassName")
package dev.adamko.kafkatorio.events.schema
import kotlin.jvm.JvmInline
import kotlinx.serialization.Serializable
/*
* The basic types used in the Factorio API. While Lua only supports the `boolean`, `number`,
* `string`, and `table` types (as they relate to the types listed below), the API docs will
* specify what C++ types these are converted to or from internally.
*/
/**
* Tables are enclosed in curly brackets, like this `{}`
*
* [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#table)
*/
typealias F_table = MutableMap<Any, Any>
sealed interface FBuiltInType {
sealed interface FNumber {
/**
* A floating-point number. This is a single-precision floating point number. Whilst Lua only uses double-precision
* numbers, when a function takes a float, the game engine will immediately convert the double-precision number to
* single-precision.
*
* [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#float)
*/
@Serializable
@JvmInline
value class F_float(val float: Float) : FNumber
/**
* A double-precision floating-point number. This is the same data type as all Lua numbers use.
*
* [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#double)
*/
@Serializable
@JvmInline
value class F_double(val double: Double) : FNumber
/**
* 32-bit signed integer. Possible values are -2,147,483,648 to 2,147,483,647.
*
* [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#int)
*/
@Serializable
@JvmInline
value class F_int(val int: Int) : FNumber
/**
* 8-bit signed integer. Possible values are -128 to 127.
*
* [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#int8)
*/
@Serializable
@JvmInline
value class F_int8(val int8: Byte) : FNumber
/**
* 32-bit unsigned integer. Possible values are 0 to 4,294,967,295.
*
* [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint)
*/
@Serializable
@JvmInline
value class F_uint(val uint: UInt) : FNumber
/**
* 8-bit unsigned integer. Possible values are 0 to 255.
*
* [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint8)
*/
@Serializable
@JvmInline
value class F_uint8(val uint8: UByte) : FNumber
/**
* 16-bit unsigned integer. Possible values are 0 to 65535.
*
* [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint16)
*/
@Serializable
@JvmInline
value class F_uint16(val uint16: UShort) : FNumber
/**
* 64-bit unsigned integer. Possible values are 0 to 18,446,744,073,709,551,615.
*
* [View documentation](https://lua-api.factorio.com/next/Builtin-Types.html#uint64)
*/
@Serializable
@JvmInline
value class F_uint64(val uint64: ULong) : FNumber
}
}

View file

@ -11,18 +11,13 @@ import kotlinx.serialization.json.JsonClassDiscriminator
@Serializable @Serializable
data class FactorioEvent<out T : FactorioObjectData>( data class FactorioEvent<out T : FactorioObjectData>(
/** the initial Factorio event ({defines.events}) trigger */ /** the initial Factorio event ({defines.events}) trigger */
@SerialName("event_type") @SerialName("event_type") val eventType: String,
val eventType: String,
/** Schema versioning */ /** Schema versioning */
@SerialName("mod_version") @SerialName("mod_version") val modVersion: String,
val modVersion: String, @SerialName("factorio_version") val factorioVersion: String,
@SerialName("factorio_version")
val factorioVersion: String,
/** game time */ /** game time */
@SerialName("tick") @SerialName("tick") val tick: UInt,
val tick: UInt, @SerialName("data") val data: T
@SerialName("data")
val data: T
) )
@ -58,64 +53,46 @@ sealed class FactorioObjectData {
@SerialName("LuaPlayer") @SerialName("LuaPlayer")
data class PlayerData( data class PlayerData(
@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>, @SerialName("character_unit_number") val characterUnitNumber: UInt?,
@SerialName("character_unit_number") @SerialName("name") val name: String,
val characterUnitNumber: UInt?, @SerialName("position") val position: PositionData,
@SerialName("name")
val name: String,
@SerialName("position")
val position: PositionData,
) : FactorioObjectData() { ) : FactorioObjectData() {
@Transient @Transient
override val objectName: String= "LuaPlayer" override val objectName: String = "LuaPlayer"
} }
@Serializable @Serializable
@SerialName("LuaEntity") @SerialName("LuaEntity")
data class EntityData( data class EntityData(
@SerialName("active") @SerialName("active") val active: Boolean,
val active: Boolean, @SerialName("health") val health: Double?,
@SerialName("health") @SerialName("health_ratio") val healthRatio: Double,
val health: Double?, @SerialName("name") val name: String,
@SerialName("health_ratio") @SerialName("position") val position: PositionData,
val healthRatio: Double, @SerialName("surface_index") val surfaceIndex: Int,
@SerialName("name") @SerialName("type") val type: String,
val name: String, @SerialName("unit_number") val unitNumber: UInt? = null,
@SerialName("position")
val position: PositionData,
@SerialName("surface_index")
val surfaceIndex: Int,
@SerialName("type")
val type: String,
@SerialName("unit_number")
val unitNumber: UInt? = null,
@SerialName("player_index") @SerialName("player_index") val playerIndex: UInt? = null,
val playerIndex: UInt? = null,
) : FactorioObjectData() { ) : FactorioObjectData() {
@Transient @Transient
override val objectName: String= "LuaEntity" override val objectName: String = "LuaEntity"
} }
@Serializable @Serializable
@SerialName("LuaSurface") @SerialName("LuaSurface")
data class SurfaceData( data class SurfaceData(
@SerialName("daytime") @SerialName("daytime") val daytime: Double,
val daytime: Double, @SerialName("index") val index: UInt,
@SerialName("index") @SerialName("name") val name: String,
val index: UInt,
@SerialName("name")
val name: String,
) : FactorioObjectData() { ) : FactorioObjectData() {
@Transient @Transient
override val objectName: String="LuaSurface" override val objectName: String = "LuaSurface"
} }
@Serializable @Serializable
data class PositionData( data class PositionData(
@SerialName("x") @SerialName("x") val x: Double,
val x: Double, @SerialName("y") val y: Double,
@SerialName("y")
val y: Double,
) )

View file

@ -8,6 +8,9 @@ import me.ntrrgc.tsGenerator.TypeScriptGenerator
import me.ntrrgc.tsGenerator.camelCaseToSnakeCase import me.ntrrgc.tsGenerator.camelCaseToSnakeCase
import org.intellij.lang.annotations.Language import org.intellij.lang.annotations.Language
/**
* Convert Kotlin classes to Typescript classes, using [TypeScriptGenerator]
*/
fun main(args: Array<String>) { fun main(args: Array<String>) {
val gen = val gen =

View file

@ -8,6 +8,8 @@ plugins {
id("dev.adamko.kafkatorio.infra.process-runner") id("dev.adamko.kafkatorio.infra.process-runner")
} }
description = "Start the Factorio game client"
val clientModsDirectory = file("""D:\Users\Adam\AppData\Roaming\Factorio\mods""") val clientModsDirectory = file("""D:\Users\Adam\AppData\Roaming\Factorio\mods""")
val factorioGameId = "427520" val factorioGameId = "427520"
val steamExe = """C:\Program Files (x86)\Steam\steam.exe""" val steamExe = """C:\Program Files (x86)\Steam\steam.exe"""

View file

@ -48,46 +48,3 @@ tasks.dockerEnv {
} }
tasks.build { dependsOn(deployModToServer) } tasks.build { dependsOn(deployModToServer) }
//<editor-fold desc="Factorio server lifecycle tasks">
//val factorioServerStop = tasks.register<Exec>("factorioServerStop") {
// group = project.name
//
// mustRunAfter(deployModToServer)
//
// workingDir(modInfraDir)
// commandLine = parseSpaceSeparatedArgs("docker-compose stop factorio-server")
//}
//val factorioServerUp = tasks.register<Exec>("factorioServerUp") {
// group = project.name
//
// mustRunAfter(deployModToServer)
// dependsOn(factorioServerStop)
//
// workingDir(modInfraDir)
// commandLine = parseSpaceSeparatedArgs("docker-compose up -d factorio-server")
//}
//val factorioServerRestart: Task by tasks.creating {
// group = project.name
//
// dependsOn(factorioServerStop, factorioServerUp)
//}
//</editor-fold>
//
//tasks.processRun {
// description = "Build the mod, upload to Server and Client, and start both"
// dependsOn(
// deployModToServer,
// factorioServerRestart,
// )
//}
//
//tasks.processKill {
// dependsOn(
// factorioServerStop,
// )
//}
//