events are up and running again, and are produced to Kafka... next step is to consume the messages

This commit is contained in:
Adam 2021-11-27 19:32:19 +01:00
parent 0d85bfca60
commit 51918a2fb2
9 changed files with 112 additions and 129 deletions

View file

@ -4,7 +4,7 @@ plugins {
} }
group = "dev.adamko.factoriowebmap" group = "dev.adamko.factoriowebmap"
version = "0.0.3" version = "0.0.4"
tasks.wrapper { tasks.wrapper {
gradleVersion = "7.3" gradleVersion = "7.3"

View file

@ -6,14 +6,14 @@ import kotlinx.serialization.json.JsonClassDiscriminator
@Serializable @Serializable
data class FactorioEvent( data class FactorioEvent<T : FactorioObjectData>(
/** the initial Factorio event ({defines.events}) trigger */
val eventType: String,
/** Schema versioning */ /** Schema versioning */
val modVersion: String, val modVersion: String,
/** game time */ /** game time */
val tick: UInt, val tick: UInt,
/** the initial Factorio event ({defines.events}) trigger */ val data: T,
val eventType: String,
val data: FactorioObjectData,
) )
@JsonClassDiscriminator("object_name") @JsonClassDiscriminator("object_name")
@ -21,34 +21,40 @@ sealed interface FactorioObjectData {
val objectName: String val objectName: String
} }
@SerialName("player") @SerialName("LuaPlayer")
data class PlayerData( data class PlayerData(
override val objectName: String, override val objectName: String,
val characterUnitNumber: UInt, val associatedCharactersUnitNumbers: List<UInt>,
val associatedCharacterUnitNumbers: List<UInt>, val characterUnitNumber: UInt?,
val positionData: PositionData, val name: String,
val position: PositionData,
) : FactorioObjectData ) : FactorioObjectData
@SerialName("LuaEntity")
data class EntityData( data class EntityData(
override val objectName: String, override val objectName: String,
val name: String,
val type: String,
val active: Boolean, val active: Boolean,
val healthRatio: Float,
val health: Float?, val health: Float?,
val surfaceIndex: Int, val healthRatio: Float,
val unitNumber: UInt?, val name: String,
val position: PositionData, val position: PositionData,
val surfaceIndex: Int,
val type: String,
val unitNumber: UInt?,
val playerIndex: UInt?, val playerIndex: UInt?,
) : FactorioObjectData ) : FactorioObjectData
@SerialName("LuaSurface")
data class SurfaceData( data class SurfaceData(
override val objectName: String, override val objectName: String,
val name: String,
val index: UInt,
val daytime: Float, val daytime: Float,
val index: UInt,
val name: String,
) : FactorioObjectData ) : FactorioObjectData
@Serializable
data class PositionData( data class PositionData(
val x: Int, val x: Int,
val y: Int, val y: Int,

View file

@ -3,7 +3,7 @@ version: "3.9"
services: services:
factorio-server: factorio-server:
image: factoriotools/factorio:1.1.46 image: factoriotools/factorio:1.1.48
# logging: # logging:
# driver: "json-file" # driver: "json-file"
container_name: "factorio-server" container_name: "factorio-server"

View file

@ -6,7 +6,10 @@
import {Serdes} from "./serdes/serdes" import {Serdes} from "./serdes/serdes"
import {FactorioEvent, JsonTable} from "./model/model"; // import {FactorioEvent, JsonTable} from "./model/model";
const MOD_VERSION = script.active_mods["factorio-web-map"]
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)) {
@ -16,8 +19,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.Player.playerToTable(player)
let event = FactorioEvent(tick, eventType, table) emitEvent(table, tick, eventType)
emitEvent(event)
handleCharactersEvent(tick, playerIndex, eventType) handleCharactersEvent(tick, playerIndex, eventType)
} }
@ -38,22 +40,28 @@ 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.Entity.entityToTable(entity)
let event = FactorioEvent(tick, eventType, table) emitEvent(table, tick, eventType)
emitEvent(event)
} }
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.Surface.surfaceToTable(surface)
let event = FactorioEvent(tick, eventType, table) emitEvent(table, tick, eventType)
emitEvent(event)
} }
// const SERVER_ID: uint = 0 // const SERVER_ID: uint = 0
// const EVENT_FILE_DIR: string = "events" // const EVENT_FILE_DIR: string = "events"
/** Emit a serialised event */ /** Emit a serialised event */
function emitEvent(event: JsonTable) { function emitEvent<T extends FactorioObjectData>(eventData: T, tick: uint, eventType: string) {
let event: FactorioEvent<T> = {
data: eventData,
event_type: eventType,
mod_version: MOD_VERSION,
tick: tick
}
let data = game.table_to_json(event) let data = game.table_to_json(event)
// game.write_file(EVENT_FILE_DIR + "/" + filename, data, false, SERVER_ID)
localised_print(`FactorioEvent: ${data}`) localised_print(`FactorioEvent: ${data}`)
} }

View file

@ -5,8 +5,8 @@ interface FactorioObjectData {
object_name: string; object_name: string;
} }
interface FactorioEvent { interface FactorioEvent<T extends FactorioObjectData> {
data: FactorioObjectData; data: T;
event_type: string; event_type: string;
mod_version: string; mod_version: string;
tick: uint; tick: uint;
@ -18,10 +18,11 @@ interface PositionData {
} }
interface PlayerData extends FactorioObjectData { interface PlayerData extends FactorioObjectData {
associated_character_unit_numbers: uint[]; associated_characters_unit_numbers: uint[];
character_unit_number: uint; character_unit_number: uint | null;
name: string;
object_name: string; object_name: string;
position_data: PositionData; position: PositionData;
} }
interface EntityData extends FactorioObjectData { interface EntityData extends FactorioObjectData {

View file

@ -1,47 +1,46 @@
import {Serdes} from "../serdes/serdes"; // import {Serdes} from "../serdes/serdes";
import FactorioObjectData = Serdes.FactorioObjectData; // import FactorioObjectData = Serdes.FactorioObjectData;
//
// export type JsonPrimitiveType = number | string | boolean | undefined | null | void
//
// export type JsonArray<T extends JsonPrimitiveType = void> = T[]
//
// export type JsonTableValueType =
// JsonPrimitiveType
// | JsonTable
// | JsonArray<JsonPrimitiveType>
// | undefined
// | null
//
// export interface JsonTable {
// [key: string]: JsonTableValueType
// }
export type JsonPrimitiveType = number | string | boolean | undefined | null | void
export type JsonArray<T extends JsonPrimitiveType = void> = T[] // export interface FactorioEvent extends JsonTable {
// /** Schema versioning */
export type JsonTableValueType = // mod_version: string,
JsonPrimitiveType // /** game time */
| JsonTable // tick: uint,
| JsonArray<JsonPrimitiveType> // /** the initial Factorio event ({defines.events}) trigger */
| undefined // event_type: string,
| null // data: FactorioObjectData,
// }
export interface JsonTable { //
[key: string]: JsonTableValueType // export const FactorioEvent =
} // (<DataType extends FactorioObjectData>(
// tick: uint,
const MOD_VERSION = script.active_mods["factorio-web-map"] // eventType: string,
// data: DataType
export interface FactorioEvent extends JsonTable { // ) => {
/** Schema versioning */ // return {
mod_version: string, // mod_version: MOD_VERSION,
/** game time */ // tick: tick,
tick: uint, // event_type: eventType,
/** the initial Factorio event ({defines.events}) trigger */ // data: data,
event_type: string, // } as FactorioEvent
data: FactorioObjectData, // }
} // )
export const FactorioEvent =
(<DataType extends FactorioObjectData>(
tick: uint,
eventType: string,
data: DataType
) => {
return {
mod_version: MOD_VERSION,
tick: tick,
event_type: eventType,
data: data,
} as FactorioEvent
}
)
// export type JsonArray<TValue extends JsonPrimitiveType> = TValue[] // export type JsonArray<TValue extends JsonPrimitiveType> = TValue[]

View file

@ -1,6 +1,6 @@
{ {
"name": "factorio-web-map-mod", "name": "factorio-web-map-mod",
"version": "0.0.3", "version": "0.0.4",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -74,18 +74,18 @@
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==" "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="
}, },
"typed-factorio": { "typed-factorio": {
"version": "0.11.0-packagetypes-1", "version": "0.12.0",
"resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.11.0-packagetypes-1.tgz", "resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.12.0.tgz",
"integrity": "sha512-oiN9XjODry434DPcgx3MNyC22/cOrbeU5/q0uM+Tj8BjJ7B42DYH+SR21tEtrHaWHNUJNX5iXD8h1Bk0N3Qvmw==", "integrity": "sha512-7SeZX7TvWjtO+V5buWEgHUbhi7tSNZsHGveh5uPQ6Vvr7BDEhHre9DP3OrdD+L7cpAtvJ2w9OwaMnDm2P5dvng==",
"requires": { "requires": {
"lua-types": "^2.10.1", "lua-types": "^2.10.1",
"typescript-to-lua": "^1.0.0" "typescript-to-lua": "^1.0.0"
} }
}, },
"typescript": { "typescript": {
"version": "4.4.4", "version": "4.5.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.4.4.tgz", "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.5.2.tgz",
"integrity": "sha512-DqGhF5IKoBl8WNf8C1gu8q0xZSInh9j1kJJMqT3a94w1JzVaBU4EXOSMrz9yDqMT0xt3selp83fuFMQ0uzv6qA==" "integrity": "sha512-5BlMof9H1yGt0P8/WF+wPNw6GfctgGjXp5hkblpyT+8rkASSmkUKMXrxR0Xg8ThVCi/JnHQiKXeBaEwCeQwMFw=="
}, },
"typescript-to-lua": { "typescript-to-lua": {
"version": "1.1.1", "version": "1.1.1",

View file

@ -1,6 +1,6 @@
{ {
"name": "factorio-web-map-mod", "name": "factorio-web-map-mod",
"version": "0.0.3", "version": "0.0.4",
"private": true, "private": true,
"scripts": { "scripts": {
"build": "tstl", "build": "tstl",
@ -14,8 +14,8 @@
"lua-types": "^2.11.0", "lua-types": "^2.11.0",
"@types/node": "^12.0.8", "@types/node": "^12.0.8",
"typescript-to-lua": "1.1.1", "typescript-to-lua": "1.1.1",
"typed-factorio": "0.11.0-packagetypes-1", "typed-factorio": "0.12.0",
"typescript": "4.4.4" "typescript": "4.5.2"
}, },
"//": { "//": {
"typed-factorio": "0.10.0" "typed-factorio": "0.10.0"

View file

@ -1,28 +1,20 @@
import {JsonTable, JsonArray} from "../model/model"; // import {JsonTable, JsonArray} from "../model/model";
import PositionData = Serdes.DataClasses.PositionData;
export namespace Serdes { export namespace Serdes {
export interface FactorioObjectData extends JsonTable { // export interface FactorioObjectData extends JsonTable {
object_name: string // object_name: string
} // }
export namespace Player { export namespace Player {
export interface PlayerData extends FactorioObjectData {
name: string
character_unit_number?: uint
associated_characters_unit_numbers: JsonArray<number>
position: PositionData
}
export function playerToTable(player: LuaPlayer): PlayerData { export function playerToTable(player: LuaPlayer): PlayerData {
let charIds = Entity.entitiesToUnitNumbers(player.get_associated_characters()) let charIds = Entity.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, character_unit_number: player.character?.unit_number ?? null,
associated_characters_unit_numbers: charIds, associated_characters_unit_numbers: charIds,
position: DataClasses.positionTableToTable(player.position), position: DataClasses.positionTableToTable(player.position),
} }
@ -32,40 +24,28 @@ export namespace Serdes {
export namespace Entity { export namespace Entity {
interface EntityData extends FactorioObjectData {
name: string
type: string
active: boolean
health?: number
surface_index: int
unit_number?: number
position: PositionData
player_index?: number
}
export function entityToTable(entity: LuaEntity): EntityData { export function entityToTable(entity: LuaEntity): EntityData {
let data: EntityData = { let player: LuaPlayer | null = entity.is_player() ? entity.player!! : null
return {
object_name: entity.object_name, object_name: entity.object_name,
name: entity.name, name: entity.name,
type: entity.type, type: entity.type,
active: entity.active, active: entity.active,
health: entity.health, health: entity.health ?? null,
health_ratio: entity.get_health_ratio(),
surface_index: entity.surface.index, surface_index: entity.surface.index,
unit_number: entity.unit_number, unit_number: entity.unit_number ?? null,
position: DataClasses.positionTableToTable(entity.position), position: DataClasses.positionTableToTable(entity.position),
// player data:
player_index: player?.index ?? null
}
} }
if (entity.is_player()) { export function entitiesToUnitNumbers(entities: LuaEntity[]): uint[] {
let player = entity.player!! let result: (uint) [] = []
data.player_index = player.index
}
return data
}
export function entitiesToUnitNumbers(entities: LuaEntity[]): JsonArray<number> {
let result: (number) [] = []
for (let entity of entities) { for (let entity of entities) {
if (entity.unit_number != null) { if (entity.unit_number != null) {
result[result.length] = entity.unit_number result[result.length] = entity.unit_number
@ -78,12 +58,6 @@ export namespace Serdes {
export namespace Surface { export namespace Surface {
interface SurfaceData extends FactorioObjectData {
name: string
index: uint
daytime: number
}
export function surfaceToTable(surface: LuaSurface): SurfaceData { export function surfaceToTable(surface: LuaSurface): SurfaceData {
return { return {
object_name: surface.object_name, object_name: surface.object_name,
@ -97,11 +71,6 @@ export namespace Serdes {
export namespace DataClasses { export namespace DataClasses {
export interface PositionData extends JsonTable {
x: int
y: int
}
export function positionTableToTable(positionTable: PositionTable): PositionData { export function positionTableToTable(positionTable: PositionTable): PositionData {
return { return {
x: positionTable.x, x: positionTable.x,