- update data model: simplify key/data (by removing data)

This commit is contained in:
Adam 2022-02-23 17:56:56 +01:00
parent b82e3a1bbf
commit 8e7208ba08
8 changed files with 221 additions and 282 deletions

View file

@ -6,11 +6,8 @@ interface FactorioEventUpdateKey {
updateType: FactorioEventUpdateType; updateType: FactorioEventUpdateType;
} }
interface FactorioEventUpdateData { interface FactorioEventUpdate extends FactorioEventUpdateKey {
updateType: FactorioEventUpdateType; events: string[] | null;
}
interface FactorioEventUpdate extends FactorioEventUpdateKey, FactorioEventUpdateData {
updateType: FactorioEventUpdateType; updateType: FactorioEventUpdateType;
} }
@ -25,31 +22,7 @@ interface PlayerUpdateKey extends FactorioEventUpdateKey {
index: uint; index: uint;
} }
interface PlayerUpdateData extends FactorioEventUpdateData { interface PlayerUpdate extends FactorioEventUpdate, PlayerUpdateKey {
afkTime: uint | null;
bannedReason: string | null;
characterUnitNumber: uint | null;
chatColour: Colour | null;
colour: Colour | null;
diedCause: EntityIdentifiers | null;
disconnectReason: string | null;
forceIndex: uint | null;
isAdmin: boolean | null;
isConnected: boolean | null;
isRemoved: boolean | null;
isShowOnMap: boolean | null;
isSpectator: boolean | null;
kickedReason: string | null;
lastOnline: uint | null;
name: string | null;
onlineTime: uint | null;
position: MapEntityPosition | null;
surfaceIndex: uint | null;
tag: string | null;
ticksToRespawn: uint | null;
}
interface PlayerUpdate extends FactorioEventUpdate, PlayerUpdateKey, PlayerUpdateData {
afkTime: uint | null; afkTime: uint | null;
bannedReason: string | null; bannedReason: string | null;
characterUnitNumber: uint | null; characterUnitNumber: uint | null;
@ -57,6 +30,7 @@ interface PlayerUpdate extends FactorioEventUpdate, PlayerUpdateKey, PlayerUpdat
colour: Colour | null; colour: Colour | null;
diedCause: EntityIdentifiers | null; diedCause: EntityIdentifiers | null;
disconnectReason: string | null; disconnectReason: string | null;
events: string[] | null;
forceIndex: uint | null; forceIndex: uint | null;
index: uint; index: uint;
isAdmin: boolean | null; isAdmin: boolean | null;
@ -81,20 +55,9 @@ interface EntityUpdateKey extends EntityIdentifiers, FactorioEventUpdateKey {
unitNumber: uint; unitNumber: uint;
} }
interface EntityUpdateData extends FactorioEventUpdateData { interface EntityUpdate extends FactorioEventUpdate, EntityIdentifiers, EntityUpdateKey {
chunkPosition: MapChunkPosition | null;
graphicsVariation: number | null;
health: float | null;
isActive: boolean | null;
isRotatable: boolean | null;
lastUser: int | null;
localisedDescription: string | null;
localisedName: string | null;
prototype: string | null;
}
interface EntityUpdate extends FactorioEventUpdate, EntityIdentifiers, EntityUpdateKey, EntityUpdateData {
chunkPosition: MapChunkPosition | null; chunkPosition: MapChunkPosition | null;
events: string[] | null;
graphicsVariation: number | null; graphicsVariation: number | null;
health: float | null; health: float | null;
isActive: boolean | null; isActive: boolean | null;
@ -114,16 +77,9 @@ interface MapChunkUpdateKey extends FactorioEventUpdateKey {
surfaceIndex: uint; surfaceIndex: uint;
} }
interface MapChunkUpdateData extends FactorioEventUpdateData { interface MapChunkUpdate extends FactorioEventUpdate, MapChunkUpdateKey {
force: uint | null;
isDeleted: boolean | null;
player: uint | null;
robot: EntityIdentifiers | null;
tiles: MapTile[] | null;
}
interface MapChunkUpdate extends FactorioEventUpdate, MapChunkUpdateKey, MapChunkUpdateData {
chunkPosition: MapChunkPosition; chunkPosition: MapChunkPosition;
events: string[] | null;
force: uint | null; force: uint | null;
isDeleted: boolean | null; isDeleted: boolean | null;
player: uint | null; player: uint | null;

View file

@ -1,5 +1,3 @@
import {NonNullableKeys} from "../types";
export namespace EventDataCache { export namespace EventDataCache {
@ -88,8 +86,7 @@ export namespace EventDataCache {
const expiredData: Array<FactorioEventUpdate> = [] const expiredData: Array<FactorioEventUpdate> = []
for (let [key, entry] of global.cache) { for (let [key, entry] of global.cache) {
if (isExpired(entry)) { if (isExpired(entry)) {
const update: FactorioEventUpdate = {...key, ...entry.data} expiredData.push(entry.data)
expiredData.push(update)
global.cache.delete(key) global.cache.delete(key)
} }
} }
@ -104,7 +101,7 @@ export namespace EventDataCache {
return undefined return undefined
} }
const value: CacheEntry<any> = global.cache.get(key) const value: CacheEntry<any> = global.cache.get(key)
if (isType(value, key.updateType)) { if (isEntryInstanceOf(value, key.updateType)) {
return value return value
} else { } else {
// Type mismatch. This shouldn't happen... // Type mismatch. This shouldn't happen...
@ -117,8 +114,7 @@ export namespace EventDataCache {
key: CacheKey<TYPE>, key: CacheKey<TYPE>,
mutate: CacheDataMutator<TYPE>, mutate: CacheDataMutator<TYPE>,
): CacheEntry<TYPE> { ): CacheEntry<TYPE> {
// @ts-ignore // TODO resolve ts-ignore for "not assignable to type" const data: CacheData<TYPE> = <CacheData<TYPE>>{updateType: key.updateType}
const data: CacheData<TYPE> = {updateType: key.updateType}
mutate(data) mutate(data)
let entry: CacheEntry<TYPE> = new CacheEntry<TYPE>(data) let entry: CacheEntry<TYPE> = new CacheEntry<TYPE>(data)
global.cache.set(key, entry) global.cache.set(key, entry)
@ -127,34 +123,35 @@ export namespace EventDataCache {
// /** Map a {@link FactorioEventUpdateType} to a {@link FactorioEventUpdate} DTO */ // /** Map a {@link FactorioEventUpdateType} to a {@link FactorioEventUpdate} DTO */
// type ConvertUpdateType<TYPE extends FactorioEventUpdateType> = type ConvertToUpdate<TYPE extends FactorioEventUpdateType> =
// TYPE extends "PLAYER" ? PlayerUpdate : TYPE extends "PLAYER" ? PlayerUpdate :
// TYPE extends "MAP_CHUNK" ? MapChunkUpdate : TYPE extends "MAP_CHUNK" ? MapChunkUpdate :
// TYPE extends "ENTITY" ? EntityUpdate : TYPE extends "ENTITY" ? EntityUpdate :
// never never
type ConvertKeyType<TYPE extends FactorioEventUpdateType> = type ConvertToUpdateKey<TYPE extends FactorioEventUpdateType> =
TYPE extends "PLAYER" ? PlayerUpdateKey : TYPE extends "PLAYER" ? PlayerUpdateKey :
TYPE extends "MAP_CHUNK" ? MapChunkUpdateKey : TYPE extends "MAP_CHUNK" ? MapChunkUpdateKey :
TYPE extends "ENTITY" ? EntityUpdateKey : TYPE extends "ENTITY" ? EntityUpdateKey :
never never
type ConvertKeyData<TYPE extends FactorioEventUpdateType> = // type ConvertToUpdateData<TYPE extends FactorioEventUpdateType> =
TYPE extends "PLAYER" ? PlayerUpdateData : // TYPE extends "PLAYER" ? PlayerUpdateData :
TYPE extends "MAP_CHUNK" ? MapChunkUpdateData : // TYPE extends "MAP_CHUNK" ? MapChunkUpdateData :
TYPE extends "ENTITY" ? EntityUpdateData : // TYPE extends "ENTITY" ? EntityUpdateData :
never // never
/** Only include the non-null properties, and make `updateType` specific */ /** Make `updateType` specific */
export type CacheKey<TYPE extends FactorioEventUpdateType> = export type CacheKey<TYPE extends FactorioEventUpdateType> =
CacheTyped<TYPE> CacheTyped<TYPE>
& Omit<ConvertKeyType<TYPE>, "updateType"> & Omit<ConvertToUpdateKey<TYPE>, "updateType">
/** Exclude {@link CacheKey} fields, and make `updateType` specific */ /** Make nullable-fields optional, and `updateType` specific */
export type CacheData<TYPE extends FactorioEventUpdateType> = export type CacheData<TYPE extends FactorioEventUpdateType> =
CacheTyped<TYPE> CacheTyped<TYPE>
& NonNullableKeys<Partial<Omit<ConvertKeyData<TYPE>, "updateType">>> & Omit<ConvertToUpdate<TYPE>, "updateType">
// & NullablePartial<Omit<ConvertToUpdate<TYPE>, "updateType">>
export type CacheTyped<TYPE extends FactorioEventUpdateType> = { export type CacheTyped<TYPE extends FactorioEventUpdateType> = {
@ -189,54 +186,19 @@ export namespace EventDataCache {
} }
function isType<TYPE extends FactorioEventUpdateType>( function isEntryInstanceOf<TYPE extends FactorioEventUpdateType>(
data: CacheEntry<TYPE>, data: CacheEntry<any>,
updateType: TYPE, updateType: TYPE,
): data is CacheEntry<TYPE> { ): data is CacheEntry<TYPE> {
return data.data.updateType == updateType return isDataInstanceOf<TYPE>(data.data, updateType)
}
function isDataInstanceOf<TYPE extends FactorioEventUpdateType>(
data: CacheData<any>,
updateType: TYPE,
): data is CacheData<TYPE> {
return data.updateType == updateType
} }
} }
// interface FactorioEventUpdate {
// type: string
// }
//
// interface Update<TYPE extends FactorioEventUpdateTypeType> {
// type: T
// }
//
// export interface PlayerUpdate extends Update<"PLAYER"> {
// index: uint
//
// unhandledEvents?: string[]
//
// characterUnitNumber?: uint
// chatColour?: Colour
// colour?: Colour
// disconnectReason?: string
// forceIndex?: uint
// isAdmin?: boolean
// isConnected?: boolean
// isShowOnMap?: boolean
// isSpectator?: boolean
// lastOnline?: uint
// afkTime?: uint
// name?: string
// onlineTime?: uint
// position?: MapEntityPosition
// surfaceIndex?: uint
// ticksToRespawn?: uint
// tag?: string
// }
// export type CacheKey<Type> = MapChunkCacheKey | EntityCacheKey | PlayerCacheKey & {
// type: Type
// }
//
// export function isCacheType<CK extends CacheKey>(
// cacheKey: CacheKey,
// type: CacheType
// ): cacheKey is CK {
// return cacheKey.type == type
// }

View file

@ -1,3 +1,5 @@
import {EventName} from "../types";
export namespace Converters { export namespace Converters {
// export function playerToTable(player: LuaPlayer): PlayerData { // export function playerToTable(player: LuaPlayer): PlayerData {
@ -15,6 +17,18 @@ export namespace Converters {
// } // }
// } // }
const mapEventIdToName = new LuaTable<defines.Events, EventName>()
for (const [eventName, eventId] of pairs(defines.events)) {
mapEventIdToName.set(eventId, eventName)
}
export function eventNameString(event: defines.Events): EventName {
return mapEventIdToName.get(event)
}
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

View file

@ -1,5 +1,6 @@
import {EventDataCache} from "../cache/EventDataCache"; import {EventDataCache} from "../cache/EventDataCache";
import {isEventType} from "./eventTypeCheck"; import {isEventType} from "./eventTypeCheck";
import {Converters} from "./converters";
import CacheKey = EventDataCache.CacheKey; import CacheKey = EventDataCache.CacheKey;
import CacheData = EventDataCache.CacheData; import CacheData = EventDataCache.CacheData;
@ -11,8 +12,10 @@ function mapTilesUpdateDebounce(
surface: LuaSurface | undefined, surface: LuaSurface | undefined,
chunkPosition: ChunkPositionTable, chunkPosition: ChunkPositionTable,
tiles: TileRead[], tiles: TileRead[],
updater?: MapChunkUpdater eventName: string,
updater?: MapChunkUpdater,
) { ) {
if (surface == undefined) { if (surface == undefined) {
return return
} }
@ -38,6 +41,13 @@ function mapTilesUpdateDebounce(
) )
} }
if (data.events == null) {
data.events = []
}
if (eventName ! in data.events) {
data.events.push(eventName)
}
if (updater != undefined) { if (updater != undefined) {
updater(data) updater(data)
} }
@ -67,7 +77,7 @@ script.on_event(
log(`on_chunk_generated ${e.tick}`) log(`on_chunk_generated ${e.tick}`)
let tiles = getTiles(e.surface, e.area) let tiles = getTiles(e.surface, e.area)
mapTilesUpdateDebounce(e.surface, e.position, tiles) mapTilesUpdateDebounce(e.surface, e.position, tiles, Converters.eventNameString(e.name))
} }
) )
@ -76,15 +86,15 @@ script.on_event(
(e: OnChunkChartedEvent) => { (e: OnChunkChartedEvent) => {
log(`on_chunk_charted ${e.tick}`) log(`on_chunk_charted ${e.tick}`)
const surface = getSurface(e.surface_index) // const surface = getSurface(e.surface_index)
if (surface == undefined) { // if (surface == undefined) {
return // return
} // }
//
let tiles = getTiles(surface, e.area) // let tiles = getTiles(surface, e.area)
mapTilesUpdateDebounce(surface, e.position, tiles, (data => { // mapTilesUpdateDebounce(surface, e.position, tiles, (data => {
data.force = e.force.index // data.force = e.force.index
})) // }))
} }
) )
@ -101,7 +111,7 @@ script.on_event(
const groupedTiles = groupTiles(e.tiles) const groupedTiles = groupTiles(e.tiles)
for (const [chunkPos, tiles] of groupedTiles) { for (const [chunkPos, tiles] of groupedTiles) {
mapTilesUpdateDebounce(surface, chunkPos, tiles) mapTilesUpdateDebounce(surface, chunkPos, tiles, Converters.eventNameString(e.name))
} }
} }
) )
@ -146,12 +156,14 @@ function onBuildTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent)
const tiles: TileRead[] = convertOldPosition(event.tiles, event.tile) const tiles: TileRead[] = convertOldPosition(event.tiles, event.tile)
const groupedTiles = groupTiles(tiles) const groupedTiles = groupTiles(tiles)
const eventName = Converters.eventNameString(event.name)
for (const [chunkPos, tiles] of groupedTiles) { for (const [chunkPos, tiles] of groupedTiles) {
mapTilesUpdateDebounce( mapTilesUpdateDebounce(
surface, surface,
chunkPos, chunkPos,
tiles, tiles,
eventName,
(data => { (data => {
if (isEventType(event, defines.events.on_player_built_tile)) { if (isEventType(event, defines.events.on_player_built_tile)) {
data.player = event.player_index data.player = event.player_index

View file

@ -6,6 +6,7 @@ type PlayerUpdater = (player: LuaPlayer, data: CacheData<"PLAYER">) => void
function playerUpdateThrottle( function playerUpdateThrottle(
playerIndex: uint, playerIndex: uint,
eventName: string,
mutate: PlayerUpdater, mutate: PlayerUpdater,
) { ) {
EventDataCache.throttle<"PLAYER">( EventDataCache.throttle<"PLAYER">(
@ -15,6 +16,13 @@ function playerUpdateThrottle(
if (player != undefined) { if (player != undefined) {
mutate(player, data) mutate(player, data)
} }
if (data.events == null) {
data.events = []
}
if (eventName ! in data.events) {
data.events.push(eventName)
}
}) })
) )
} }
@ -41,9 +49,10 @@ script.on_event(
(e: OnPlayerJoinedGameEvent) => { (e: OnPlayerJoinedGameEvent) => {
playerUpdateThrottle( playerUpdateThrottle(
e.player_index, e.player_index,
Converters.eventNameString(e.name),
(player, data) => { (player, data) => {
data.isAdmin = player.admin data.isAdmin = player.admin
data.characterUnitNumber = player.character?.unit_number data.characterUnitNumber = player.character?.unit_number ?? null
data.chatColour = Converters.mapColour(player.chat_color) data.chatColour = Converters.mapColour(player.chat_color)
data.colour = Converters.mapColour(player.color) data.colour = Converters.mapColour(player.color)
data.forceIndex = player.force.index data.forceIndex = player.force.index
@ -62,6 +71,7 @@ script.on_event(
(e: OnPlayerChangedPositionEvent) => { (e: OnPlayerChangedPositionEvent) => {
playerUpdateThrottle( playerUpdateThrottle(
e.player_index, e.player_index,
Converters.eventNameString(e.name),
(player, data) => { (player, data) => {
data.position = player.position data.position = player.position
} }
@ -74,6 +84,7 @@ script.on_event(
(e: OnPlayerChangedSurfaceEvent) => { (e: OnPlayerChangedSurfaceEvent) => {
playerUpdateThrottle( playerUpdateThrottle(
e.player_index, e.player_index,
Converters.eventNameString(e.name),
(player, data) => { (player, data) => {
data.position = player.position data.position = player.position
data.surfaceIndex = player.surface.index data.surfaceIndex = player.surface.index
@ -87,8 +98,9 @@ script.on_event(
(e: OnPlayerDiedEvent) => { (e: OnPlayerDiedEvent) => {
playerUpdateThrottle( playerUpdateThrottle(
e.player_index, e.player_index,
Converters.eventNameString(e.name),
(player, data) => { (player, data) => {
data.ticksToRespawn = player.ticks_to_respawn data.ticksToRespawn = player.ticks_to_respawn ?? null
playerOnlineInfo(player, data) playerOnlineInfo(player, data)
if (e.cause != undefined) { if (e.cause != undefined) {
data.diedCause = { data.diedCause = {
@ -102,43 +114,31 @@ script.on_event(
} }
) )
script.on_event( script.on_event(defines.events.on_player_banned, handleBannedEvent)
defines.events.on_player_banned, script.on_event(defines.events.on_player_unbanned, handleBannedEvent)
(e: OnPlayerBannedEvent) => {
if (e.player_index != undefined) { function handleBannedEvent(e: OnPlayerBannedEvent | OnPlayerUnbannedEvent) {
playerUpdateThrottle(
e.player_index,
(player, data) => {
data.bannedReason = e.reason
playerOnlineInfo(player, data)
}
)
}
}
)
script.on_event(
defines.events.on_player_unbanned,
(e: OnPlayerUnbannedEvent) => {
if (e.player_index != undefined) { if (e.player_index != undefined) {
playerUpdateThrottle( playerUpdateThrottle(
e.player_index, e.player_index,
Converters.eventNameString(e.name),
(player, data) => { (player, data) => {
data.bannedReason = e.reason data.bannedReason = e.reason ?? null
playerOnlineInfo(player, data) playerOnlineInfo(player, data)
} }
) )
} }
} }
)
script.on_event( script.on_event(
defines.events.on_player_kicked, defines.events.on_player_kicked,
(e: OnPlayerKickedEvent) => { (e: OnPlayerKickedEvent) => {
playerUpdateThrottle( playerUpdateThrottle(
e.player_index, e.player_index,
Converters.eventNameString(e.name),
(player, data) => { (player, data) => {
data.kickedReason = e.reason data.kickedReason = e.reason ?? null
playerOnlineInfo(player, data) playerOnlineInfo(player, data)
} }
) )
@ -156,6 +156,7 @@ script.on_event(
(e: OnPrePlayerLeftGameEvent) => { (e: OnPrePlayerLeftGameEvent) => {
playerUpdateThrottle( playerUpdateThrottle(
e.player_index, e.player_index,
Converters.eventNameString(e.name),
(player, data) => { (player, data) => {
data.disconnectReason = disconnectReasons.get(e.reason) data.disconnectReason = disconnectReasons.get(e.reason)
playerOnlineInfo(player, data) playerOnlineInfo(player, data)
@ -169,6 +170,7 @@ script.on_event(
(e: OnPlayerRemovedEvent) => { (e: OnPlayerRemovedEvent) => {
playerUpdateThrottle( playerUpdateThrottle(
e.player_index, e.player_index,
Converters.eventNameString(e.name),
(player, data) => { (player, data) => {
data.isRemoved = true data.isRemoved = true
playerOnlineInfo(player, data) playerOnlineInfo(player, data)

View file

@ -3,23 +3,16 @@ import {
handleConsoleChat, handleConsoleChat,
handleEntityUpdate, handleEntityUpdate,
handleSurfaceUpdate, handleSurfaceUpdate,
// handleTilesUpdate
} from "./handlers"; } from "./handlers";
import {Queue} from "../queue/queue"; import {Queue} from "../queue/queue";
import {EventName} from "../types";
import {isEventType} from "./eventTypeCheck"; import {isEventType} from "./eventTypeCheck";
import {Converters} from "./converters";
const mapEventIdToName = new LuaTable<defines.Events, EventName>()
for (const [eventName, eventId] of pairs(defines.events)) {
mapEventIdToName.set(eventId, eventName)
}
script.on_event( script.on_event(
defines.events.on_player_mined_entity, defines.events.on_player_mined_entity,
(e: OnPlayerMinedEntityEvent) => { (e: OnPlayerMinedEntityEvent) => {
let eventName = mapEventIdToName.get(e.name) let eventName = Converters.eventNameString(e.name)
// handlePlayerUpdate(e.tick, eventName, e.player_index) // handlePlayerUpdate(e.tick, eventName, e.player_index)
handleEntityUpdate(e.tick, eventName, e.entity) handleEntityUpdate(e.tick, eventName, e.entity)
} }
@ -44,7 +37,7 @@ script.on_event(
(e: OnTickEvent) => { (e: OnTickEvent) => {
if (e.tick % 1000 == 0) { if (e.tick % 1000 == 0) {
for (const [, surface] of game.surfaces) { for (const [, surface] of game.surfaces) {
handleSurfaceUpdate(e.tick, mapEventIdToName.get(e.name), surface) handleSurfaceUpdate(e.tick, Converters.eventNameString(e.name), surface)
} }
// let packets = new KafkatorioPacketQueue().dequeueValues(1) // let packets = new KafkatorioPacketQueue().dequeueValues(1)
@ -61,7 +54,7 @@ script.on_event(
for (const event of events) { for (const event of events) {
if (isEventType(event, defines.events.on_chunk_generated)) { if (isEventType(event, defines.events.on_chunk_generated)) {
let eName = mapEventIdToName.get(event.name) let eName = Converters.eventNameString(event.name)
log(`[${e.tick}] dequed event ${eName}`) log(`[${e.tick}] dequed event ${eName}`)
handleChunkUpdate(e.tick, eName, event.surface.index, event.position, event.area) handleChunkUpdate(e.tick, eName, event.surface.index, event.position, event.area)
@ -75,29 +68,15 @@ script.on_event(
script.on_event( script.on_event(
defines.events.on_console_chat, defines.events.on_console_chat,
(e: OnConsoleChatEvent) => { (e: OnConsoleChatEvent) => {
handleConsoleChat(e.tick, mapEventIdToName.get(e.name), e.player_index, e.message) handleConsoleChat(e.tick, Converters.eventNameString(e.name), e.player_index, e.message)
} }
) )
// script.on_event( // script.on_event(
// defines.events.on_chunk_generated, // defines.events.on_chunk_generated,
// (e: OnChunkGeneratedEvent) => { // (e: OnChunkGeneratedEvent) => {
// handleChunkUpdate(e.tick, mapEventIdToName.get(e.name), e.surface.index, e.position, e.area) // handleChunkUpdate(e.tick, mapEventIdToName.get(e.name), e.surface.index, e.position,
// } // e.area) } ) script.on_event( [ defines.events.on_player_built_tile,
// ) // defines.events.on_robot_built_tile, ], (builtTilesEvent) => { handleTilesUpdate(
// // builtTilesEvent.tick, mapEventIdToName.get(builtTilesEvent.name), builtTilesEvent.surface_index,
// script.on_event( // builtTilesEvent.tile, builtTilesEvent.tiles, ) } )
// [
// defines.events.on_player_built_tile,
// defines.events.on_robot_built_tile,
// ],
// (builtTilesEvent) => {
// handleTilesUpdate(
// builtTilesEvent.tick,
// mapEventIdToName.get(builtTilesEvent.name),
// builtTilesEvent.surface_index,
// builtTilesEvent.tile,
// builtTilesEvent.tiles,
// )
// }
// )

View file

@ -1,6 +1,7 @@
package dev.adamko.kafkatorio.events.schema package dev.adamko.kafkatorio.events.schema
import dev.adamko.kafkatorio.events.schema.FactorioEventUpdate.FactorioEventUpdateType import dev.adamko.kafkatorio.events.schema.FactorioEventUpdate.FactorioEventUpdateType
import kotlinx.serialization.Contextual
import kotlinx.serialization.DeserializationStrategy import kotlinx.serialization.DeserializationStrategy
import kotlinx.serialization.EncodeDefault import kotlinx.serialization.EncodeDefault
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
@ -31,16 +32,19 @@ sealed interface FactorioEventUpdateKey {
} }
sealed interface FactorioEventUpdateData { //sealed interface FactorioEventUpdateData {
val updateType: FactorioEventUpdateType // val updateType: FactorioEventUpdateType
} // val event: String?
//}
@Serializable(with = FactorioEventUpdate.Companion.JsonSerializer::class) @Serializable(with = FactorioEventUpdate.Companion.JsonSerializer::class)
sealed class FactorioEventUpdate : FactorioEventUpdateKey, FactorioEventUpdateData { sealed class FactorioEventUpdate : FactorioEventUpdateKey {
@EncodeDefault @EncodeDefault
abstract override val updateType: FactorioEventUpdateType abstract override val updateType: FactorioEventUpdateType
@Contextual
abstract val events: List<String>?
@Serializable @Serializable
enum class FactorioEventUpdateType { enum class FactorioEventUpdateType {
@ -93,63 +97,66 @@ sealed interface PlayerUpdateKey : FactorioEventUpdateKey {
} }
sealed interface PlayerUpdateData : FactorioEventUpdateData { //sealed interface PlayerUpdateData : FactorioEventUpdateData {
val characterUnitNumber: UnitNumber? // val characterUnitNumber: UnitNumber?
val chatColour: Colour? // val chatColour: Colour?
val colour: Colour? // val colour: Colour?
val name: String? // val name: String?
//
val afkTime: Tick? // val afkTime: Tick?
val ticksToRespawn: Tick? // val ticksToRespawn: Tick?
val forceIndex: ForceIndex? // val forceIndex: ForceIndex?
val isAdmin: Boolean? // val isAdmin: Boolean?
val isConnected: Boolean? // val isConnected: Boolean?
val isShowOnMap: Boolean? // val isShowOnMap: Boolean?
val isSpectator: Boolean? // val isSpectator: Boolean?
val lastOnline: Tick? // val lastOnline: Tick?
val onlineTime: Tick? // val onlineTime: Tick?
val position: MapEntityPosition? // val position: MapEntityPosition?
val surfaceIndex: SurfaceIndex? // val surfaceIndex: SurfaceIndex?
val tag: String? // val tag: String?
val diedCause: EntityIdentifiers? // val diedCause: EntityIdentifiers?
//
val bannedReason: String? // val bannedReason: String?
val kickedReason: String? // val kickedReason: String?
val disconnectReason: String? // val disconnectReason: String?
/** `true` when a player is removed (deleted) from the game */ // /** `true` when a player is removed (deleted) from the game */
val isRemoved: Boolean? // val isRemoved: Boolean?
} //}
@Serializable @Serializable
data class PlayerUpdate( data class PlayerUpdate(
override val index: PlayerIndex, override val index: PlayerIndex,
override val characterUnitNumber: UnitNumber? = null, @Contextual
override val chatColour: Colour? = null, override val events: List<String>? = null,
override val colour: Colour? = null,
override val name: String? = null,
override val afkTime: Tick? = null, val characterUnitNumber: UnitNumber? = null,
override val ticksToRespawn: Tick? = null, val chatColour: Colour? = null,
override val forceIndex: ForceIndex? = null, val colour: Colour? = null,
override val isAdmin: Boolean? = null, val name: String? = null,
override val isConnected: Boolean? = null,
override val isShowOnMap: Boolean? = null,
override val isSpectator: Boolean? = null,
override val lastOnline: Tick? = null,
override val onlineTime: Tick? = null,
override val position: MapEntityPosition? = null,
override val surfaceIndex: SurfaceIndex? = null,
override val tag: String? = null,
override val diedCause: EntityIdentifiers? = null,
override val bannedReason: String? = null, val afkTime: Tick? = null,
override val kickedReason: String? = null, val ticksToRespawn: Tick? = null,
override val disconnectReason: String? = null, val forceIndex: ForceIndex? = null,
val isAdmin: Boolean? = null,
val isConnected: Boolean? = null,
val isShowOnMap: Boolean? = null,
val isSpectator: Boolean? = null,
val lastOnline: Tick? = null,
val onlineTime: Tick? = null,
val position: MapEntityPosition? = null,
val surfaceIndex: SurfaceIndex? = null,
val tag: String? = null,
val diedCause: EntityIdentifiers? = null,
val bannedReason: String? = null,
val kickedReason: String? = null,
val disconnectReason: String? = null,
/** `true` when a player is removed (deleted) from the game */ /** `true` when a player is removed (deleted) from the game */
override val isRemoved: Boolean? = null, val isRemoved: Boolean? = null,
) : FactorioEventUpdate(), PlayerUpdateKey, PlayerUpdateData { ) : FactorioEventUpdate(), PlayerUpdateKey {
@EncodeDefault @EncodeDefault
override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.PLAYER override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.PLAYER
} }
@ -165,17 +172,17 @@ sealed interface EntityUpdateKey : EntityIdentifiers, FactorioEventUpdateKey {
override val type: String override val type: String
} }
sealed interface EntityUpdateData : FactorioEventUpdateData { //sealed interface EntityUpdateData : FactorioEventUpdateData {
val chunkPosition: MapChunkPosition? // val chunkPosition: MapChunkPosition?
val graphicsVariation: UShort? // val graphicsVariation: UShort?
val health: Float? // val health: Float?
val isActive: Boolean? // val isActive: Boolean?
val isRotatable: Boolean? // val isRotatable: Boolean?
val lastUser: UInt? // val lastUser: UInt?
val localisedDescription: String? // val localisedDescription: String?
val localisedName: String? // val localisedName: String?
val prototype: PrototypeName? // val prototype: PrototypeName?
} //}
@Serializable @Serializable
data class EntityUpdate( data class EntityUpdate(
@ -183,16 +190,19 @@ data class EntityUpdate(
override val name: String, override val name: String,
override val type: String, override val type: String,
override val chunkPosition: MapChunkPosition? = null, @Contextual
override val graphicsVariation: UShort? = null, override val events: List<String>? = null,
override val health: Float? = null,
override val isActive: Boolean? = null, val chunkPosition: MapChunkPosition? = null,
override val isRotatable: Boolean? = null, val graphicsVariation: UShort? = null,
override val lastUser: UInt? = null, val health: Float? = null,
override val localisedDescription: String? = null, val isActive: Boolean? = null,
override val localisedName: String? = null, val isRotatable: Boolean? = null,
override val prototype: PrototypeName? = null, val lastUser: UInt? = null,
) : FactorioEventUpdate(), EntityIdentifiers, EntityUpdateKey, EntityUpdateData { val localisedDescription: String? = null,
val localisedName: String? = null,
val prototype: PrototypeName? = null,
) : FactorioEventUpdate(), EntityIdentifiers, EntityUpdateKey {
@EncodeDefault @EncodeDefault
override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.ENTITY override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.ENTITY
} }
@ -207,14 +217,13 @@ sealed interface MapChunkUpdateKey : FactorioEventUpdateKey {
} }
sealed interface MapChunkUpdateData : FactorioEventUpdateData { //sealed interface MapChunkUpdateData : FactorioEventUpdateData {
val player: PlayerIndex? // val player: PlayerIndex?
val robot: EntityIdentifiers? // val robot: EntityIdentifiers?
val force: ForceIndex? // val force: ForceIndex?
/** updated tiles - might be partial */ // val tiles: List<MapTile>?
val tiles: List<MapTile>? // val isDeleted: Boolean?
val isDeleted: Boolean? //}
}
@Serializable @Serializable
@ -222,14 +231,19 @@ data class MapChunkUpdate(
override val chunkPosition: MapChunkPosition, override val chunkPosition: MapChunkPosition,
override val surfaceIndex: SurfaceIndex, override val surfaceIndex: SurfaceIndex,
override val player: PlayerIndex? = null, @Contextual
override val robot: EntityIdentifiers? = null, override val events: List<String>? = null,
override val force: ForceIndex? = null,
val player: PlayerIndex? = null,
val robot: EntityIdentifiers? = null,
val force: ForceIndex? = null,
/** updated tiles - might be partial */
// note: this must be a List, not a Map<Location, ProtoName> // note: this must be a List, not a Map<Location, ProtoName>
// because JSON can't have non-string keys. // because JSON can't have non-string keys.
override val tiles: List<MapTile>? = null, @Contextual
override val isDeleted: Boolean? = null, val tiles: List<MapTile>? = null,
) : FactorioEventUpdate(), MapChunkUpdateKey, MapChunkUpdateData { val isDeleted: Boolean? = null,
) : FactorioEventUpdate(), MapChunkUpdateKey {
@EncodeDefault @EncodeDefault
override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.MAP_CHUNK override val updateType: FactorioEventUpdateType = FactorioEventUpdateType.MAP_CHUNK
} }

View file

@ -25,7 +25,7 @@ fun main(args: Array<String>) {
add(FactorioEventUpdatePacket::class) add(FactorioEventUpdatePacket::class)
addAll(FactorioEventUpdate::class.sealedSubclasses) addAll(FactorioEventUpdate::class.sealedSubclasses)
addAll(FactorioEventUpdateKey::class.sealedSubclasses) addAll(FactorioEventUpdateKey::class.sealedSubclasses)
addAll(FactorioEventUpdateData::class.sealedSubclasses) // addAll(FactorioEventUpdateData::class.sealedSubclasses)
}, },
mappings = mapOf( mappings = mapOf(