readme, convert factorio objects to tables, other refactors

This commit is contained in:
Adam 2021-10-20 00:51:35 +02:00
parent 9238140a4c
commit 2e15f83c90
10 changed files with 215 additions and 47 deletions

View file

@ -0,0 +1,22 @@
1. output events from Factorio into Kafka.
1. Factorio mod listens to events.
2. For each event, it emits a file.
3. A Kafka Connector consumes each file.
2. Factorio Web Map reads data from Kafka
1. converts data to images
2. hosts a web map
todo
* add settings
* is active - whether files are exported or not
* delete files - clean up all files
* tick-rate - how often reports are generated (
* requires on some sort of in-mod cache of map<entity-id, event>)
* also divide by game-speed? to keep ratio the same
to investigate:
* https://github.com/starwing/lua-protobuf
* https://github.com/grafi-tt/lunajson

View file

@ -19,27 +19,22 @@ plugins {
kotlin {
js(IR) {
binaries.executable()
useCommonJs()
nodejs()
//
//// compilations.all {
// compilations["main"].apply {
// packageJson {
// customField(
// "scripts",
// mapOf(
// "build" to "tstl",
// "dev" to "tstl --watch",
// )
// )
// }
// }
}
}
dependencies {
val kotlinWrappersVersion = "0.0.1-pre.259-kotlin-1.5.31"
implementation(
project.dependencies.enforcedPlatform(
"org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}"
)
)
}
val rootPackageJson by rootProject.tasks.getting(RootPackageJsonTask::class)
//fun NpmTask.setNodeModulesPath(path: String): Unit =

View file

@ -103,7 +103,8 @@ val serverStopTask = tasks.register<Exec>("dockerStop") {
val serverUpTask = tasks.register<Exec>("dockerUp") {
group = "$projectId.factorioServer"
dependsOn(copyModToServerTask, serverStopTask)
mustRunAfter(copyModToServerTask)
dependsOn(serverStopTask)
workingDir = layout.projectDirectory.dir("src/test/resources/server/").asFile
commandLine = parseSpaceSeparatedArgs("docker-compose up -d")

View file

@ -8,39 +8,80 @@
// declare const factorioData: Data
// declare const factorioMods: Mods
// const eventEnum = {
// thingType: Object.values(defines.events)
// }
const SERVER_ID : uint = 0
import {JsonTable, Serdes} from "./serdes/serdes"
function outputEvent(filename: string, event: table) {
let json : string = game.table_to_json(event)
// game.print(`Creating file ${filename}, content: ${json}`)
game.write_file(filename, json, false, SERVER_ID)
// const SERVER_ID: uint = 0
// const EVENT_FILE_DIR: string = "events"
function playerEvent(tick: uint, player_index: uint, eventType: string) {
let player: LuaPlayer = game.players[player_index]
let filename: string = table.concat([player.index, eventType, tick], "_")
let data = Serdes.Player.playerToTable(player)
outputEventFile(player.object_name + "/" + filename, data)
if (player.character != undefined) {
entityEvent(tick, player.character, eventType)
for (const char of player.get_associated_characters()) {
if (char != undefined) {
entityEvent(tick, char, eventType)
}
}
}
}
script.on_event(
[defines.events.on_pre_build, defines.events.on_player_dropped_item],
(e: OnPreBuildEvent | OnPlayerDroppedItemEvent) => {
game.print("player " + e.player_index + " dropped item, tick:" + e.tick)
function entityEvent(tick: uint, entity: LuaEntity, eventType: string) {
if (entity.unit_number != undefined && entity.unit_number != 0) {
let filename: string = table.concat([entity.unit_number, eventType, tick], "_")
let data = Serdes.Entity.entityToTable(entity)
outputEventFile(entity.object_name + "/" + filename, data)
}
);
}
function surfaceEvent(tick: uint, surface: LuaSurface, eventType: string) {
let filename: string =
surface.object_name + "/" + table.concat([surface.index, eventType, tick], "_")
let data = Serdes.Surface.surfaceToTable(surface)
outputEventFile(filename, data)
}
function outputEventFile(filename: string, obj: JsonTable) {
let data = game.table_to_json(obj)
// game.write_file(EVENT_FILE_DIR + "/" + filename, data, false, SERVER_ID)
localised_print(`!===== ${filename} | ${data} =====!`)
}
// script.on_event(
// [defines.events.on_pre_build, defines.events.on_player_dropped_item],
// (e: OnPreBuildEvent | OnPlayerDroppedItemEvent) => {
// game.print("player " + e.player_index + " dropped item, tick:" + e.tick)
// }
// );
script.on_event(
defines.events.on_player_mined_entity,
(e: OnPlayerMinedEntityEvent) => {
entityEvent(e.tick, e.entity, "on_player_mined_entity")
playerEvent(e.tick, e.player_index, "on_player_mined_entity")
}
)
script.on_event(
defines.events.on_player_joined_game,
(e: OnPlayerJoinedGameEvent) => {
let filename : string = `${e.name}/${e.tick}_${e.player_index}`
outputEvent(filename, e)
playerEvent(e.tick, e.player_index, "on_player_joined_game")
}
)
script.on_event(
defines.events.on_player_changed_position,
(e: OnPlayerJoinedGameEvent) => {
let filename : string = `${e.name}/${e.tick}_${e.player_index}`
outputEvent(filename, e)
(e: OnPlayerChangedPositionEvent) => {
playerEvent(e.tick, e.player_index, "on_player_changed_position")
}
)
@ -48,10 +89,19 @@ script.on_event(
defines.events.on_tick,
(e: OnTickEvent) => {
if (e.tick % 60 == 0) {
let msg = "test mod tick: " + e.tick + "\n"
game.write_file("tick.log", msg, true, SERVER_ID)
let filename : string = `${e.name}/${e.tick}`
outputEvent(filename, e)
game.surfaces
for (const [index,] of pairs(game.surfaces)) {
let surface = game.surfaces[index]
surfaceEvent(e.tick, surface, "on_tick")
}
// let filename: string = table.concat([entity.unit_number, eventType, tick], "_")
// let msg = "test mod tick: " + e.tick + "\n"
// game.write_file("tick.log", msg, true, SERVER_ID)
// let filename: string = `OnTickEvent/${e.tick}`
// outputEvent(filename, e)
}
}
);

View file

@ -0,0 +1,16 @@
// declare interface LuaArray<TValue = any> extends LuaTable<number, TValue> {
// }
// = LuaTable<number, TValue>;
// declare type LuaArrayConstructor = (new <TValue = any>() => LuaArray<TValue>)
// declare const LuaArray: LuaArrayConstructor
// class LuaArray<TValue = any> extends LuaTable<number, TValue> {
// add(val: TValue) {
// this.set(this.length(), val)
// }
// }
// declare type LuaArray<TKey extends AnyNotNil = AnyNotNil, TValue = any> & LuaTable<TKey, TValue>

View file

@ -74,9 +74,9 @@
"integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ=="
},
"typed-factorio": {
"version": "0.7.3",
"resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.7.3.tgz",
"integrity": "sha512-Y0J6dqRy1rg3kPlFUX5Ca5nU7CcQgelcY4nKkk6fox17ZCAoOZx1i2ynj/JPuhQsTRsuMV0kQTS1eQKF8bzdaQ==",
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/typed-factorio/-/typed-factorio-0.7.4.tgz",
"integrity": "sha512-IhvydBF1eNtlV8WRJWuu64ySOoMCbNujLX/kvqNMaWL+tcLmORghuQZggCbhuX2HI4wVL+UgGpTwG4xicOQM9A==",
"requires": {
"lua-types": "^2.10.1",
"typescript-to-lua": "^1.0.0"

View file

@ -14,7 +14,7 @@
"lua-types": "^2.11.0",
"@types/node": "^12.0.8",
"typescript-to-lua": "1.0.1",
"typed-factorio": "0.7.3"
"typed-factorio": "0.7.4"
},
"peerDependencies": {},
"optionalDependencies": {},

View file

@ -0,0 +1,86 @@
export type PrimitiveType = number | string | boolean
export type JsonArray<TValue extends PrimitiveType> = TValue[]
export type JsonTableValueType =
PrimitiveType
| JsonTable
| JsonArray<PrimitiveType>
export type JsonTable = LuaTable<string, JsonTableValueType> // & table
// export type JsonArray = LuaArray<PrimitiveType> // & table
export namespace Serdes {
export namespace Player {
export function playerToTable(player: LuaPlayer): JsonTable {
let table = new LuaTable<string, JsonTableValueType>()
table.set("name", player.name)
let charIds: JsonArray<number> = Entity.entitiesToUnitNumbers(player.get_associated_characters())
table.set("characterIds", charIds)
return table
}
}
export namespace Entity {
export function entityToTable(entity: LuaEntity): JsonTable {
let table = new LuaTable<string, JsonTableValueType>()
if (entity.player?.index != null) {
table.set("playerId", entity.player?.index)
}
table.set("type", entity.type)
table.set("active", entity.active)
if (entity.health != null) {
table.set("health", entity.health)
}
table.set("surfaceId", entity.surface.index)
table.set("position", DataClasses.positionTableToTable(entity.position))
return table
}
export function entitiesToUnitNumbers(entities: LuaEntity[]): JsonArray<number> {
let array: number[] = []
let j: number = 0
for (let i = 0; i < entities.length; i++) {
let unitNum = entities[i].unit_number
if (unitNum != null) {
array[j++] = unitNum
}
}
return array
}
}
export namespace Surface {
export function surfaceToTable(surface: LuaSurface): JsonTable {
let table = new LuaTable<string, JsonTableValueType>()
table.set("name", surface.name)
table.set("index", surface.index)
table.set("daytime", surface.daytime)
return table
}
}
export namespace DataClasses {
export function positionTableToTable(positionTable: PositionTable): JsonTable {
let table = new LuaTable<string, JsonTableValueType>()
table.set("x", positionTable.x)
table.set("y", positionTable.y)
return table
}
}
}

View file

@ -22,12 +22,13 @@
"strict": true,
"strictFunctionTypes": true,
"strictNullChecks": true,
"traceResolution": true,
"traceResolution": true
},
"tstl": {
"luaTarget": "5.2",
"tstlVerbose": true,
"noHeader": true,
"noImplicitSelf": true,
"luaLibImport" : "require",
},
"//": {

View file

@ -62,12 +62,9 @@ kotlin {
}
dependencies {
val kotlinWrappersVersion = "0.0.1-pre.254-kotlin-1.5.31"
implementation(
project.dependencies.enforcedPlatform(
"org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom:${kotlinWrappersVersion}"
)
)
// bom is defined in archetype.kotlin-js
implementation("org.jetbrains.kotlin-wrappers:kotlin-react")
// implementation("org.jetbrains.kotlin-wrappers:kotlin-react-dom")