readme, convert factorio objects to tables, other refactors
This commit is contained in:
parent
9238140a4c
commit
2e15f83c90
10 changed files with 215 additions and 47 deletions
22
README.md
22
README.md
|
|
@ -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
|
||||
|
||||
|
|
@ -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 =
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
|
|||
16
modules/mod/src/main/typescript/ext/LuaArray.ts
Normal file
16
modules/mod/src/main/typescript/ext/LuaArray.ts
Normal 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>
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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": {},
|
||||
|
|
|
|||
86
modules/mod/src/main/typescript/serdes/serdes.ts
Normal file
86
modules/mod/src/main/typescript/serdes/serdes.ts
Normal 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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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",
|
||||
},
|
||||
"//": {
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue