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"
version = "0.1.5"
version = "0.1.6"
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-gradle-plugin:$kotlinVersion")
val kotlinXSerializationVersion = "1.3.1"
val kotlinXSerializationVersion = "1.3.2"
implementation(enforcedPlatform("org.jetbrains.kotlinx:kotlinx-serialization-bom:$kotlinXSerializationVersion"))
implementation("org.jetbrains.kotlinx:kotlinx-serialization-core")
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json")
@ -24,6 +24,9 @@ dependencies {
implementation("com.github.node-gradle:gradle-node-plugin:3.1.1")
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"

View file

@ -32,13 +32,13 @@ val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class)
val nodePath: Directory by extra {
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()
}
val nodeModulesDir: Directory by extra {
val file = nodePath.dir(NpmProject.NODE_MODULES)
logger.lifecycle("Kotlin/JS NODE_MODULES: $file")
logger.info("Kotlin/JS NODE_MODULES: $file")
file
}

View file

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

View file

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

View file

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

View file

@ -138,7 +138,7 @@ distributions {
filter<ReplaceTokens>("tokens" to projectTokens)
includeEmptyDirs = false
exclude {
// exclude empty files
// exclude empty files
it.file.run {
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 {
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) {
let player: LuaPlayer = game.players[playerIndex]
let table = Serdes.Player.playerToTable(player)
let table = Serdes.playerToTable(player)
emitEvent(table, tick, 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) {
let table = Serdes.Entity.entityToTable(entity)
let table = Serdes.entityToTable(entity)
emitEvent(table, tick, eventType)
}
function surfaceEvent(tick: uint, surface: LuaSurface, eventType: string) {
let table = Serdes.Surface.surfaceToTable(surface)
let table = Serdes.surfaceToTable(surface)
emitEvent(table, tick, eventType)
}

View file

@ -1,6 +1,6 @@
{
"name": "kafkatorio-events-mod",
"version": "0.1.5",
"version": "0.1.6",
"private": true,
"scripts": {
"build": "tstl",
@ -9,7 +9,8 @@
"engines": {
"node": ">=10.13.0"
},
"devDependencies": {},
"devDependencies": {
},
"dependencies": {
"lua-types": "^2.11.0",
"@types/node": "^12.0.8",
@ -18,7 +19,10 @@
"typescript": "4.5.4"
},
"license": "UNLICENSED",
"peerDependencies": {},
"optionalDependencies": {},
"bundledDependencies": []
"peerDependencies": {
},
"optionalDependencies": {
},
"bundledDependencies": [
]
}

View file

@ -1,79 +1,65 @@
export namespace Serdes {
export namespace Player {
export function playerToTable(player: LuaPlayer): PlayerData {
let charIds = Entity.entitiesToUnitNumbers(player.get_associated_characters())
return {
object_name: player.object_name,
export function playerToTable(player: LuaPlayer): PlayerData {
let charIds = entitiesToUnitNumbers(player.get_associated_characters())
return {
object_name: player.object_name,
name: player.name,
character_unit_number: player.character?.unit_number ?? null,
associated_characters_unit_numbers: charIds,
position: DataClasses.positionTableToTable(player.position),
}
name: player.name,
character_unit_number: player.character?.unit_number ?? null,
associated_characters_unit_numbers: charIds,
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
return {
object_name: entity.object_name,
return {
object_name: entity.object_name,
// entity data
name: entity.name,
type: entity.type,
active: entity.active,
health: entity.health ?? null,
health_ratio: entity.get_health_ratio(),
surface_index: entity.surface.index,
unit_number: entity.unit_number ?? null,
position: positionTableToTable(entity.position),
// entity data
name: entity.name,
type: entity.type,
active: entity.active,
health: entity.health ?? null,
health_ratio: entity.get_health_ratio(),
surface_index: entity.surface.index,
unit_number: entity.unit_number ?? null,
position: DataClasses.positionTableToTable(entity.position),
// player data
player_index: player?.index ?? null
}
// player data
player_index: player?.index ?? null
}
export function entitiesToUnitNumbers(entities: LuaEntity[]): uint[] {
let result: (uint) [] = []
for (let entity of entities) {
if (entity.unit_number != null) {
result[result.length] = entity.unit_number
}
}
return result
}
}
export namespace Surface {
export function surfaceToTable(surface: LuaSurface): SurfaceData {
return {
object_name: surface.object_name,
name: surface.name,
index: surface.index,
daytime: surface.daytime,
export function entitiesToUnitNumbers(entities: LuaEntity[]): uint[] {
let result: (uint) [] = []
for (let entity of entities) {
if (entity.unit_number != null) {
result[result.length] = entity.unit_number
}
}
return result
}
export namespace DataClasses {
export function surfaceToTable(surface: LuaSurface): SurfaceData {
return {
object_name: surface.object_name,
export function positionTableToTable(positionTable: PositionTable): PositionData {
return {
x: positionTable.x,
y: positionTable.y,
}
name: surface.name,
index: surface.index,
daytime: surface.daytime,
}
}
export function positionTableToTable(positionTable: PositionTable): PositionData {
return {
x: positionTable.x,
y: positionTable.y,
}
}
}

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
class FactorioEventsTopology(
val websocketServer: WebsocketServer,
val builder: StreamsBuilder = StreamsBuilder(),
private val websocketServer: WebsocketServer,
private val builder: StreamsBuilder = StreamsBuilder(),
) {
private val sourceTopic = "factorio-server-log"

View file

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

View file

@ -1,19 +1,11 @@
package dev.adamko.kafkatorio.processor.config
import com.fasterxml.jackson.databind.JsonNode
import dev.adamko.kafkatorio.processor.config.PortVal.Companion.portVal
import java.io.StringReader
import java.time.Clock
import java.util.Properties
import org.http4k.cloudnative.env.Environment
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.uri
/**
* Load properties, in descending priority order, from

View file

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

View file

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

View file

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

View file

@ -48,46 +48,3 @@ tasks.dockerEnv {
}
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,
// )
//}
//