- add tile deconstruction (concrete tiles can be removed)

- add @SerialName to all packets
- start implementing Entity prototype
- start implementing Entity updates
- clean up some old commented out code
- refactor how debounced events track the triggering events (now include timestamps per event)
- bump tstl
This commit is contained in:
Adam 2022-05-07 20:29:24 +02:00
parent 5656acd350
commit 688b2c7bcb
30 changed files with 650 additions and 553 deletions

View file

@ -1,15 +1,15 @@
[mod-setting-name]
kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-PlayerUpdate=Player update rate (seconds)
kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-MapChunkUpdate=Map update rate (seconds)
kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-EntityUpdate=Entity update rate (seconds)
kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-PlayerUpdate=Player update rate (seconds)
kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-MapChunkUpdate=Map update rate (seconds)
kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-EntityUpdate=Entity update rate (seconds)
[mod-setting-description]
kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-PlayerUpdate=How frequently Player updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (0.25 seconds) is probably fine!
kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-MapChunkUpdate=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine!
kafkatorio_event-cache_default-expiration-duration-seconds_dev-adamko-kafkatorio-schema-packets-EntityUpdate=How frequently Entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (5 seconds) is probably fine!
kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-PlayerUpdate=How frequently Player updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (0.25 seconds) is probably fine!
kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-MapChunkUpdate=How frequently Map updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (30 seconds) is probably fine!
kafkatorio_event-cache_default-expiration-duration-seconds_kafkatorio-packet-keyed-EntityUpdate=How frequently Entity updates are sent to the Kafkatorio server, in seconds. Lower means updates are sent more frequently, which may cause network congestion or reduce performance. The default (5 seconds) is probably fine!
[string-mod-setting]

View file

@ -6,6 +6,7 @@ import KafkatorioSettings from "./main/settings/KafkatorioSettings";
require("./main/events/registerHandlers")
require("./main/events/onMapChunkEventListeners")
require("./main/events/onPlayerEventListeners")
require("./main/events/EntityEvents")
require("./main/commands/kafkatorioCommands")
require("./main/cache/cacheChecker")

View file

@ -20,14 +20,14 @@ export type KafkatorioPacketData =
export namespace KafkatorioPacketData {
export enum Type {
ConfigurationUpdate = "dev.adamko.kafkatorio.schema.packets.ConfigurationUpdate",
ConsoleChatUpdate = "dev.adamko.kafkatorio.schema.packets.ConsoleChatUpdate",
ConsoleCommandUpdate = "dev.adamko.kafkatorio.schema.packets.ConsoleCommandUpdate",
PrototypesUpdate = "dev.adamko.kafkatorio.schema.packets.PrototypesUpdate",
SurfaceUpdate = "dev.adamko.kafkatorio.schema.packets.SurfaceUpdate",
EntityUpdate = "dev.adamko.kafkatorio.schema.packets.EntityUpdate",
MapChunkUpdate = "dev.adamko.kafkatorio.schema.packets.MapChunkUpdate",
PlayerUpdate = "dev.adamko.kafkatorio.schema.packets.PlayerUpdate",
ConfigurationUpdate = "kafkatorio.packet.instant.ConfigurationUpdate",
ConsoleChatUpdate = "kafkatorio.packet.instant.ConsoleChatUpdate",
ConsoleCommandUpdate = "kafkatorio.packet.instant.ConsoleCommandUpdate",
PrototypesUpdate = "kafkatorio.packet.instant.PrototypesUpdate",
SurfaceUpdate = "kafkatorio.packet.instant.SurfaceUpdate",
EntityUpdate = "kafkatorio.packet.keyed.EntityUpdate",
MapChunkUpdate = "kafkatorio.packet.keyed.MapChunkUpdate",
PlayerUpdate = "kafkatorio.packet.keyed.PlayerUpdate",
}
export interface ConfigurationUpdate {
@ -66,7 +66,7 @@ export namespace KafkatorioPacketData {
export interface EntityUpdate {
type: KafkatorioPacketData.Type.EntityUpdate;
key: EntityUpdateKey;
eventCounts?: { [key: string]: UInt } | null;
events?: { [key: EventName]: Tick[] } | null;
chunkPosition?: MapChunkPosition | null;
graphicsVariation?: UByte | null;
health?: Float | null;
@ -81,7 +81,7 @@ export namespace KafkatorioPacketData {
export interface MapChunkUpdate {
type: KafkatorioPacketData.Type.MapChunkUpdate;
key: MapChunkUpdateKey;
eventCounts?: { [key: string]: UInt } | null;
events?: { [key: EventName]: Tick[] } | null;
player?: PlayerIndex | null;
robot?: EntityIdentifiersData | null;
force?: ForceIndex | null;
@ -92,7 +92,7 @@ export namespace KafkatorioPacketData {
export interface PlayerUpdate {
type: KafkatorioPacketData.Type.PlayerUpdate;
key: PlayerUpdateKey;
eventCounts?: { [key: string]: UInt } | null;
events?: { [key: EventName]: Tick[] } | null;
characterUnitNumber?: UnitNumber | null;
chatColour?: Colour | null;
colour?: Colour | null;
@ -196,7 +196,7 @@ export type FactorioPrototype =
export namespace FactorioPrototype {
export enum Type {
MapTile = "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
MapTile = "kafkatorio.prototype.MapTile",
}
export interface MapTile {
@ -210,6 +210,8 @@ export namespace FactorioPrototype {
}
}
export type EventName = string;
export type Byte = int8;
export type List = any;

View file

@ -181,55 +181,13 @@ export namespace EventUpdates {
return game.encode_string(game.table_to_json(key))!!
}
// function isKeyInstanceOf<TYPE extends FactorioEventUpdateType>(
// key: CacheKey<any> | undefined,
// updateType: TYPE,
// ): key is CacheKey<TYPE> {
// return key != undefined && key.updateType == updateType
// }
}
// export type KeyedPacketType = Exclude<KafkatorioPacketDataType,
// "CONFIG" | "CONSOLE_CHAT" | "CONSOLE_COMMAND" | "PROTOTYPES" | "SURFACE">
// /** Map a {@link KeyedPacketType} to a {@link KafkatorioPacketData} DTO */
// type ConvertToUpdate<TYPE extends KafkatorioKeyedPacketData> =
// TYPE extends "PLAYER" ? PlayerUpdate :
// TYPE extends "MAP_CHUNK" ? MapChunkUpdate :
// TYPE extends "ENTITY" ? EntityUpdate :
// never
// /** Map a {@link KeyedPacketType} to a {@link KafkatorioKeyedPacketKey} */
// type ConvertToUpdateKey<TYPE extends KafkatorioKeyedPacketData> =
// TYPE extends "PLAYER" ? PlayerUpdateKey :
// TYPE extends "MAP_CHUNK" ? MapChunkUpdateKey :
// TYPE extends "ENTITY" ? EntityUpdateKey :
// never
// /** Make `updateType` specific */
export type PacketKey<PACKET extends KafkatorioKeyedPacketData> = PACKET["key"]
export type PacketType<PACKET extends KafkatorioKeyedPacketData> = PACKET["type"]
//
//
// /** Make `updateType` specific */
// export type CacheData<TYPE extends KafkatorioKeyedPacketData> =
// CacheTyped<TYPE>
// & Omit<ConvertToUpdate<TYPE>, "updateType">
//
//
// export type CacheTyped<TYPE extends KafkatorioKeyedPacketData> = {
// readonly updateType: TYPE
// }
export type CacheDataMutator<PACKET extends KafkatorioKeyedPacketData> = (packet: PACKET) => void
class CacheEntry<PACKET extends KafkatorioKeyedPacketData> {
lastUpdatedTick: uint = game.tick
expirationDurationTicks?: uint
@ -245,8 +203,6 @@ export namespace EventUpdates {
this.expirationDurationTicks = expirationDurationTicks
}
}
}
const EventUpdatesManager = new EventUpdates.Manager()

View file

@ -43,6 +43,24 @@ function getMapTilePrototypes(): FactorioPrototype.MapTile[] {
return tiles
}
// function getEntityPrototypes(): FactorioPrototype.MapTile[] {
// let tiles: FactorioPrototype.MapTile[] = []
// for (let [, tile] of game.tile_prototypes) {
// tiles.push({
// type: FactorioPrototype.Type.MapTile,
//
// name: tile.name,
// order: tile.order,
// layer: tile.layer,
// collisionMasks: convertCollisionMaskToNames(tile.collision_mask),
// mapColour: Converters.mapColour(tile.map_color),
// canBeMined: tile.mineable_properties.minable,
// })
// }
// return tiles
// }
function convertCollisionMaskToNames(cm: CollisionMask): string[] {
let masks: string[] = []
for (let [name] of pairs(cm)) {

View file

@ -0,0 +1,97 @@
import {Converters} from "./converters";
import EventDataCache from "../cache/EventDataCache";
import {
EntityUpdateKey,
KafkatorioPacketData
} from "../../generated/kafkatorio-schema/kafkatorio-schema";
script.on_event(defines.events.on_built_entity, (e: OnBuiltEntityEvent) => {
log(`on_built_entity ${e.tick}`)
handleBuiltEntityEvent(e)
})
script.on_event(defines.events.on_robot_built_entity, (e: OnRobotBuiltEntityEvent) => {
log(`on_robot_built_entity ${e.tick}`)
handleBuiltEntityEvent(e)
})
function handleBuiltEntityEvent(event: OnBuiltEntityEvent | OnRobotBuiltEntityEvent) {
const eventName = Converters.eventNameString(event.name)
if (event.created_entity.unit_number == undefined) {
return
}
const key: EntityUpdateKey = {
name: event.created_entity.name,
protoType: event.created_entity.prototype.name,
unitNumber: event.created_entity.unit_number
}
EventDataCache.debounce<KafkatorioPacketData.EntityUpdate>(
key,
KafkatorioPacketData.Type.EntityUpdate,
data => {
data.events ??= {}
data.events[eventName] ??= []
data.events[eventName].push(event.tick)
data.chunkPosition = Converters.convertMapTablePosition(event.created_entity.position)
data.graphicsVariation = event.created_entity.graphics_variation
data.health = event.created_entity.health
data.isActive = event.created_entity.active
data.isRotatable = event.created_entity.rotatable
data.lastUser = event.created_entity.last_user?.index
data.prototype = event.created_entity.prototype.name
}
)
}
script.on_event(defines.events.on_player_mined_entity, (e: OnPlayerMinedEntityEvent) => {
log(`on_player_mined_entity ${e.tick}`)
handleMinedEntityEvent(e)
})
script.on_event(defines.events.on_robot_mined_entity, (e: OnRobotMinedEntityEvent) => {
log(`on_robot_mined_entity ${e.tick}`)
handleMinedEntityEvent(e)
})
function handleMinedEntityEvent(event: OnPlayerMinedEntityEvent | OnRobotMinedEntityEvent) {
const eventName = Converters.eventNameString(event.name)
if (event.entity.unit_number == undefined) {
return
}
const key: EntityUpdateKey = {
name: event.entity.name,
protoType: event.entity.prototype.name,
unitNumber: event.entity.unit_number
}
EventDataCache.debounce<KafkatorioPacketData.EntityUpdate>(
key,
KafkatorioPacketData.Type.EntityUpdate,
data => {
data.events ??= {}
data.events[eventName] ??= []
data.events[eventName].push(event.tick)
data.chunkPosition = Converters.convertMapTablePosition(event.entity.position)
data.graphicsVariation = event.entity.graphics_variation
data.health = event.entity.health
data.isActive = event.entity.active
data.isRotatable = event.entity.rotatable
data.lastUser = event.entity.last_user?.index
data.prototype = event.entity.prototype.name
}
)
}

View file

@ -1,24 +1,8 @@
import {EventName} from "../types";
import {Colour} from "../../generated/kafkatorio-schema/kafkatorio-schema";
import {Colour, MapChunkPosition} from "../../generated/kafkatorio-schema/kafkatorio-schema";
export namespace Converters {
// export function playerToTable(player: LuaPlayer): PlayerData {
// let charIds = entitiesToUnitNumbers(player.get_associated_characters())
// return {
// objectName: player.object_name,
//
// name: player.name,
// characterUnitNumber: player.character?.unit_number ?? null,
// associatedCharactersUnitNumbers: charIds,
// position: mapEntityPosition(player.position),
// colour: mapColour(player.color),
// chatColour: mapColour(player.chat_color),
// lastOnline: player.last_online
// }
// }
const mapEventIdToName = new LuaTable<defines.Events, EventName>()
for (const [eventName, eventId] of pairs(defines.events)) {
mapEventIdToName.set(eventId, eventName)
@ -30,61 +14,6 @@ export namespace Converters {
}
// export function entityToTable(entity: LuaEntity): EntityData {
//
// let player: LuaPlayer | null = entity.is_player() ? entity.player!! : null
//
// return {
// objectName: entity.object_name,
//
// // entity data
// name: entity.name,
// type: entity.type,
// active: entity.active,
// health: entity.health ?? null,
// healthRatio: entity.get_health_ratio() ?? null,
// surface: entity.surface.index,
// unitNumber: entity.unit_number ?? null,
// position: mapEntityPosition(entity.position),
// force: entity.force.index,
//
// // player data
// playerIndex: player?.index ?? null
// }
// }
//
// 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 function mapEntityPosition(mapPos: MapPositionTable): MapEntityPosition {
// return {
// x: mapPos.x,
// y: mapPos.y,
// }
// }
// export function mapTilePosition(mapPos: MapPositionTable): MapTilePosition {
// return {
// x: mapPos.x,
// y: mapPos.y,
// }
// }
// export function mapChunkPosition(mapPos: ChunkPositionTable): MapChunkPosition {
// return {
// x: mapPos.x,
// y: mapPos.y,
// }
// }
export function mapColour(color: ColorTable): Colour {
return [
color.r ?? 0,
@ -95,23 +24,37 @@ export namespace Converters {
}
// export function convertTile(tile: LuaTile): MapTile {
// return {
// x: tile.position.x,
// y: tile.position.y,
// proto: tile.prototype.name,
// }
// }
//
// export function convertTiles(tiles: LuaTile[]): MapTile[] {
// return tiles.map((tile: LuaTile) => convertTile(tile))
// }
export function convertPlacedTiles(
placedTile: LuaTilePrototype,
oldTiles: OldTileAndPosition[],
): TileRead[] {
const converted: TileRead[] = []
for (const [, tile] of ipairs(oldTiles)) {
converted[converted.length] = {
position: {x: tile.position.x, y: tile.position.y},
name: placedTile.name,
}
}
return converted
}
// export function convertBoundingBox(bb: BoundingBoxRead): MapBoundingBox {
// return {
// topLeft: mapTilePosition(bb.left_top),
// bottomRight: mapTilePosition(bb.right_bottom),
// }
// }
export function convertRemovedTiles(
surface: LuaSurface,
oldTiles: OldTileAndPosition[],
): TileRead[] {
const converted: TileRead[] = []
for (const [, tile] of ipairs(oldTiles)) {
converted[converted.length] = surface.get_tile(tile.position.x, tile.position.y)
}
return converted
}
export function convertMapTablePosition(
position: MapPositionTable,
): MapChunkPosition {
return [position.x, position.y]
}
}

View file

@ -2,34 +2,6 @@ import PacketEmitter from "../PacketEmitter";
import {KafkatorioPacketData} from "../../generated/kafkatorio-schema/kafkatorio-schema";
import Type = KafkatorioPacketData.Type;
// export function handlePlayerUpdate(tick: uint, eventType: string, playerIndex: uint) {
// let player: LuaPlayer = game.players[playerIndex]
// let table = Converters.playerToTable(player)
//
// emitEvent(table, tick, eventType)
//
// handleCharactersEvent(tick, eventType, playerIndex)
// }
// export function handleCharactersEvent(tick: uint, eventType: string, playerIndex: uint) {
//
// let player: LuaPlayer = game.players[playerIndex]
//
// if (player.character != undefined) {
// handleEntityUpdate(tick, eventType, player.character)
// }
// for (const character of player.get_associated_characters()) {
// if (character != undefined) {
// handleEntityUpdate(tick, eventType, character)
// }
// }
// }
// export function handleEntityUpdate(tick: uint, eventType: string, entity: LuaEntity) {
// let table = Converters.entityToTable(entity)
// emitEvent(table, tick, eventType)
// }
export function handleSurfaceUpdate(
event: OnTickEvent,
@ -46,71 +18,3 @@ export function handleSurfaceUpdate(
PacketEmitter.emitInstantPacket(update)
}
// export function handleChunkUpdate(
// tick: uint,
// eventType: string,
// surfaceIndex: uint,
// position: ChunkPositionTable,
// area: BoundingBoxRead,
// ) {
//
// let surface = game.get_surface(surfaceIndex)
//
// let tiles: LuaTile[] = surface?.find_tiles_filtered({
// area: area,
// collision_mask: ["ground-tile", "water-tile"]
// }
// ) ?? []
//
// let convertedTiles: MapTile[] = tiles.map((tile: LuaTile) => {
// return Converters.convertTile(tile)
// })
//
// let mapChunk: MapChunk = {
// objectName: "MapChunk",
// tiles: createMapTiles(surfaceIndex, convertedTiles),
// position: Converters.mapChunkPosition(position),
// area: Converters.convertBoundingBox(area),
// }
//
// emitEvent(mapChunk, tick, eventType)
// }
// export function handleTilesUpdate(
// tick: uint,
// eventType: string,
// surfaceIndex: uint,
// newTileType: LuaTilePrototype,
// updatedTiles: OldTileAndPosition[],
// ) {
//
// if (!newTileType.collision_mask["ground-tile"] && !newTileType.collision_mask["water-tile"]) {
// return
// } else {
//
// let convertedTiles: MapTile[] = updatedTiles.map((it) => {
// return {
// x: it.position.x,
// y: it.position.y,
// proto: newTileType.name
// }
// })
//
// let mapTiles: MapTiles = createMapTiles(surfaceIndex, convertedTiles)
//
// emitEvent(mapTiles, tick, eventType)
// }
// }
// function createMapTiles(
// surfaceIndex: uint,
// tiles: MapTile[],
// ): MapTiles {
// return {
// objectName: "LuaTiles",
// surfaceIndex: surfaceIndex,
// tiles: tiles,
// }
// }

View file

@ -12,11 +12,22 @@ import Type = KafkatorioPacketData.Type;
type MapChunkUpdater = (data: KafkatorioPacketData.MapChunkUpdate) => void
type MapTileUpdateEvent =
| OnChunkGeneratedEvent
| OnPlayerBuiltTileEvent
| OnPlayerMinedEntityEvent
| OnPlayerMinedTileEvent
| OnRobotBuiltTileEvent
| OnRobotMinedEntityEvent
| OnRobotMinedTileEvent
| ScriptRaisedSetTilesEvent
function mapTilesUpdateDebounce(
surface: LuaSurface | undefined,
chunkPosition: MapChunkPosition,
tiles: TileRead[],
eventName: string,
event: MapTileUpdateEvent,
updater?: MapChunkUpdater,
expirationDurationTicks?: uint,
) {
@ -25,6 +36,8 @@ function mapTilesUpdateDebounce(
return
}
const eventName = Converters.eventNameString(event.name)
const key: KafkatorioPacketData.MapChunkUpdate["key"] = {
surfaceIndex: surface.index,
chunkPosition: chunkPosition,
@ -60,9 +73,9 @@ function mapTilesUpdateDebounce(
}
// events count update
data.eventCounts ??= {}
data.eventCounts[eventName] ??= 0
data.eventCounts[eventName]++
data.events ??= {}
data.events[eventName] ??= []
data.events[eventName].push(event.tick)
// apply mutator
if (updater != undefined) {
@ -101,15 +114,15 @@ script.on_event(
export function handleChunkGeneratedEvent(
e: OnChunkGeneratedEvent,
event: OnChunkGeneratedEvent,
expirationDurationTicks?: uint,
) {
let tiles = getTiles(e.surface, e.area)
let tiles = getTiles(event.surface, event.area)
mapTilesUpdateDebounce(
e.surface,
[e.position.x, e.position.y],
event.surface,
Converters.convertMapTablePosition(event.position),
tiles,
Converters.eventNameString(e.name),
event,
undefined,
expirationDurationTicks,
)
@ -136,18 +149,18 @@ export function handleChunkGeneratedEvent(
script.on_event(
defines.events.script_raised_set_tiles,
(e: ScriptRaisedSetTilesEvent) => {
log(`script_raised_set_tiles ${e.tick}`)
(event: ScriptRaisedSetTilesEvent) => {
log(`script_raised_set_tiles ${event.tick}`)
const surface = getSurface(e.surface_index)
const surface = getSurface(event.surface_index)
if (surface == undefined) {
return
}
const groupedTiles = groupTiles(e.tiles)
const groupedTiles = groupTiles(event.tiles)
for (const [chunkPos, tiles] of groupedTiles) {
mapTilesUpdateDebounce(surface, chunkPos, tiles, Converters.eventNameString(e.name))
mapTilesUpdateDebounce(surface, chunkPos, tiles, event)
}
}
)
@ -165,41 +178,35 @@ function groupTiles(tiles: TileRead[]): Map<MapChunkPosition, TileRead[]> {
mapChunkPositionToTiles.set(chunkPosition, [])
}
// https://github.com/TypeScriptToLua/TypeScriptToLua/issues/1256
// mapChunkPositionToTiles.get(chunkPosition)?.push(tile)
const tiles = mapChunkPositionToTiles.get(chunkPosition)
if (tiles != null) {
tiles.push(tile)
}
mapChunkPositionToTiles.get(chunkPosition)?.push(tile)
// const tiles = mapChunkPositionToTiles.get(chunkPosition)
// if (tiles != null) {
// tiles.push(tile)
// }
}
return mapChunkPositionToTiles
}
function convertOldPosition(
oldTiles: OldTileAndPosition[],
placedTile: LuaTilePrototype,
): TileRead[] {
return oldTiles.map((tile) => {
return {
position: {x: tile.position.x, y: tile.position.y},
name: placedTile.name,
}
}
)
}
script.on_event(defines.events.on_player_built_tile, (e: OnPlayerBuiltTileEvent) => {
log(`on_player_built_tile ${e.tick}`)
handleBuiltTileEvent(e)
})
script.on_event(defines.events.on_robot_built_tile, (e: OnRobotBuiltTileEvent) => {
log(`on_robot_built_tile ${e.tick}`)
handleBuiltTileEvent(e)
})
function handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEvent) {
const eventName = Converters.eventNameString(event.name)
const surface = getSurface(event.surface_index)
if (surface == undefined) {
const eventName = Converters.eventNameString(event.name)
log(`[handleBuiltTileEvent] undefined surface ${eventName}`)
return
}
const tiles: TileRead[] = convertOldPosition(event.tiles, event.tile)
const tiles: TileRead[] = Converters.convertPlacedTiles(event.tile, event.tiles)
const groupedTiles = groupTiles(tiles)
for (const [chunkPos, tiles] of groupedTiles) {
@ -207,7 +214,7 @@ function handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEv
surface,
chunkPos,
tiles,
eventName,
event,
(data => {
if (isEventType(event, defines.events.on_player_built_tile)) {
data.player = event.player_index
@ -231,27 +238,54 @@ function handleBuiltTileEvent(event: OnPlayerBuiltTileEvent | OnRobotBuiltTileEv
}
script.on_event(defines.events.on_player_built_tile, (e: OnPlayerBuiltTileEvent) => {
log(`on_player_built_tile ${e.tick}`)
handleBuiltTileEvent(e)
})
script.on_event(defines.events.on_robot_built_tile, (e: OnRobotBuiltTileEvent) => {
log(`on_robot_built_tile ${e.tick}`)
handleBuiltTileEvent(e)
script.on_event(defines.events.on_player_mined_tile, (e: OnPlayerMinedTileEvent) => {
log(`on_player_mined_tile ${e.tick}`)
handleMinedTileEvent(e)
})
script.on_event(defines.events.on_robot_mined_tile, (e: OnRobotMinedTileEvent) => {
log(`on_robot_mined_tile ${e.tick}`)
handleMinedTileEvent(e)
})
// function handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) {
// }
//
// script.on_event(defines.events.on_player_mined_tile, (e: OnPlayerMinedTileEvent) => {
// log(`on_player_mined_tile ${e.tick}`)
// handleMinedTileEvent(e)
// })
// script.on_event(defines.events.on_robot_mined_tile, (e: OnRobotMinedTileEvent) => {
// log(`on_robot_mined_tile ${e.tick}`)
// handleMinedTileEvent(e)
// })
function handleMinedTileEvent(event: OnPlayerMinedTileEvent | OnRobotMinedTileEvent) {
const surface = getSurface(event.surface_index)
if (surface == undefined) {
const eventName = Converters.eventNameString(event.name)
log(`[handleMinedTileEvent] undefined surface ${eventName}`)
return
}
const tiles: TileRead[] = Converters.convertRemovedTiles(surface, event.tiles)
const groupedTiles = groupTiles(tiles)
for (const [chunkPos, tiles] of groupedTiles) {
mapTilesUpdateDebounce(
surface,
chunkPos,
tiles,
event,
(data => {
if (isEventType(event, defines.events.on_player_mined_tile)) {
data.player = event.player_index
return
}
if (isEventType(event, defines.events.on_robot_mined_tile)) {
data.robot = {
unitNumber: event.robot?.unit_number ?? null,
name: event.robot.name,
protoType: event.robot.type,
}
return
}
// this line will not compile if the previous 'if' statements are not exhaustive
// noinspection UnnecessaryLocalVariableJS,JSUnusedLocalSymbols
const exhaustiveCheck: never = event
}
)
)
}
}
script.on_event(

View file

@ -6,11 +6,29 @@ import Type = KafkatorioPacketData.Type;
type PlayerUpdater = (player: LuaPlayer, data: KafkatorioPacketData.PlayerUpdate) => void
type PlayerUpdateEvent =
| OnPlayerJoinedGameEvent
| OnPlayerChangedPositionEvent
| OnPlayerChangedSurfaceEvent
| OnPlayerDiedEvent
| OnPlayerBannedEvent
| OnPlayerUnbannedEvent
| OnPlayerKickedEvent
| OnPrePlayerLeftGameEvent
| OnPlayerRemovedEvent
function playerUpdateThrottle(
playerIndex: uint,
eventName: string,
event: PlayerUpdateEvent,
mutate: PlayerUpdater,
) {
const playerIndex = event.player_index
if (playerIndex == undefined) {
return
}
const eventName = Converters.eventNameString(event.name)
EventUpdatesManager.throttle<KafkatorioPacketData.PlayerUpdate>(
{index: playerIndex},
@ -21,10 +39,9 @@ function playerUpdateThrottle(
mutate(player, data)
}
if (data.eventCounts == undefined) {
data.eventCounts = {}
}
data.eventCounts[eventName] = ((data.eventCounts ?? {}) [eventName] ?? 0) + 1
data.events ??= {}
data.events[eventName] ??= []
data.events[eventName].push(event.tick)
}
)
}
@ -50,8 +67,7 @@ script.on_event(
defines.events.on_player_joined_game,
(e: OnPlayerJoinedGameEvent) => {
playerUpdateThrottle(
e.player_index,
Converters.eventNameString(e.name),
e,
(player, data) => {
data.isAdmin = player.admin
data.characterUnitNumber = player.character?.unit_number ?? null
@ -69,12 +85,12 @@ script.on_event(
}
)
script.on_event(
defines.events.on_player_changed_position,
(e: OnPlayerChangedPositionEvent) => {
playerUpdateThrottle(
e.player_index,
Converters.eventNameString(e.name),
e,
(player, data) => {
data.position = [player.position.x, player.position.y]
}
@ -82,12 +98,12 @@ script.on_event(
}
)
script.on_event(
defines.events.on_player_changed_surface,
(e: OnPlayerChangedSurfaceEvent) => {
playerUpdateThrottle(
e.player_index,
Converters.eventNameString(e.name),
e,
(player, data) => {
data.position = [player.position.x, player.position.y]
data.surfaceIndex = player.surface.index
@ -96,12 +112,12 @@ script.on_event(
}
)
script.on_event(
defines.events.on_player_died,
(e: OnPlayerDiedEvent) => {
playerUpdateThrottle(
e.player_index,
Converters.eventNameString(e.name),
e,
(player, data) => {
data.ticksToRespawn = player.ticks_to_respawn ?? null
playerOnlineInfo(player, data)
@ -117,31 +133,28 @@ script.on_event(
}
)
script.on_event(defines.events.on_player_banned, handleBannedEvent)
script.on_event(defines.events.on_player_unbanned, handleBannedEvent)
function handleBannedEvent(e: OnPlayerBannedEvent | OnPlayerUnbannedEvent) {
if (e.player_index != undefined) {
playerUpdateThrottle(
e.player_index,
Converters.eventNameString(e.name),
(player, data) => {
data.bannedReason = e.reason ?? null
playerOnlineInfo(player, data)
}
)
}
function handleBannedEvent(event: OnPlayerBannedEvent | OnPlayerUnbannedEvent) {
playerUpdateThrottle(
event,
(player, data) => {
data.bannedReason = event.reason ?? null
playerOnlineInfo(player, data)
}
)
}
script.on_event(
defines.events.on_player_kicked,
(e: OnPlayerKickedEvent) => {
(event: OnPlayerKickedEvent) => {
playerUpdateThrottle(
e.player_index,
Converters.eventNameString(e.name),
event,
(player, data) => {
data.kickedReason = e.reason ?? null
data.kickedReason = event.reason ?? null
playerOnlineInfo(player, data)
}
)
@ -156,12 +169,11 @@ for (const [name, disconnectId] of pairs(defines.disconnect_reason)) {
script.on_event(
defines.events.on_pre_player_left_game,
(e: OnPrePlayerLeftGameEvent) => {
(event: OnPrePlayerLeftGameEvent) => {
playerUpdateThrottle(
e.player_index,
Converters.eventNameString(e.name),
event,
(player, data) => {
data.disconnectReason = disconnectReasons.get(e.reason)
data.disconnectReason = disconnectReasons.get(event.reason)
playerOnlineInfo(player, data)
}
)
@ -170,10 +182,9 @@ script.on_event(
script.on_event(
defines.events.on_player_removed,
(e: OnPlayerRemovedEvent) => {
(event: OnPlayerRemovedEvent) => {
playerUpdateThrottle(
e.player_index,
Converters.eventNameString(e.name),
event,
(player, data) => {
data.isRemoved = true
playerOnlineInfo(player, data)

View file

@ -31,25 +31,25 @@ import {handleSurfaceUpdate} from "./handlers";
script.on_event(
defines.events.on_tick,
(e: OnTickEvent) => {
if (e.tick % 1000 == 0) {
(event: OnTickEvent) => {
if (event.tick % 1000 == 0) {
for (const [, surface] of game.surfaces) {
handleSurfaceUpdate(e, Converters.eventNameString(e.name), surface)
handleSurfaceUpdate(event, Converters.eventNameString(event.name), surface)
}
}
if (e.tick % 7 == 0) {
if (event.tick % 7 == 0) {
const events: EventData[] = Queue.dequeueValues(1)
if (events.length > 0) {
log(`[${e.tick}] dequed ${events.length} events, current size: ${Queue.size()}`)
log(`[${event.tick}] dequed ${events.length} events, current size: ${Queue.size()}`)
let i = 100
for (const event of events) {
if (isEventType(event, defines.events.on_chunk_generated)) {
let eName = Converters.eventNameString(event.name)
log(`[${e.tick}] dequed event ${eName}`)
log(`[${event.tick}] dequed event ${eName}`)
handleChunkGeneratedEvent(event, i)
i += 10
}

View file

@ -6,18 +6,18 @@ export class KafkatorioSettingsConfig {
private static eventCacheExpirationDefaultSeconds: Record<KafkatorioKeyedPacketTypes, double> = {
"dev.adamko.kafkatorio.schema.packets.PlayerUpdate": 0.5,
"dev.adamko.kafkatorio.schema.packets.MapChunkUpdate": 30,
"dev.adamko.kafkatorio.schema.packets.EntityUpdate": 5,
"kafkatorio.packet.keyed.PlayerUpdate": 0.5,
"kafkatorio.packet.keyed.MapChunkUpdate": 30,
"kafkatorio.packet.keyed.EntityUpdate": 5,
}
private eventCacheExpirationTicks: Record<KafkatorioKeyedPacketTypes, double> = {
"dev.adamko.kafkatorio.schema.packets.PlayerUpdate":
"kafkatorio.packet.keyed.PlayerUpdate":
KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.PlayerUpdate],
"dev.adamko.kafkatorio.schema.packets.MapChunkUpdate":
"kafkatorio.packet.keyed.MapChunkUpdate":
KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.MapChunkUpdate],
"dev.adamko.kafkatorio.schema.packets.EntityUpdate":
"kafkatorio.packet.keyed.EntityUpdate":
KafkatorioSettingsConfig.eventCacheExpirationDefaultSeconds[KafkatorioPacketData.Type.EntityUpdate],
}

View file

@ -24,3 +24,6 @@ type KafkatorioKeyedPacketData = Extract<KafkatorioPacketData, { key: object }>
type KafkatorioKeyedPacketTypes = KafkatorioKeyedPacketData["type"];
type KafkatorioKeyedPacketKeys = KafkatorioKeyedPacketData["key"];
type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] }

View file

@ -32,9 +32,9 @@
}
},
"is-core-module": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.8.1.tgz",
"integrity": "sha512-SdNCUs284hr40hFTFP6l0IfZ/RSrMXF3qgoRHd3/79unUTvrFO/JoXwkGm+5J/Oe3E/b5GsnG330uUNgRpu1PA==",
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.9.0.tgz",
"integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
"requires": {
"has": "^1.0.3"
}
@ -85,9 +85,9 @@
"integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw=="
},
"typescript-to-lua": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.4.3.tgz",
"integrity": "sha512-oGJO1BqXKSxdfwavfOzthelxaQVAc7ykJ4Z/BF96nAWz35nmuLyv9FOSS132TgzLmV02859ndMuTYZtiVnN6jQ==",
"version": "1.4.4",
"resolved": "https://registry.npmjs.org/typescript-to-lua/-/typescript-to-lua-1.4.4.tgz",
"integrity": "sha512-HqXDi0rjYANvVeOJlYAyjwCvLtpXV+RRp9GiknCJrd8+0D9G/2yZ5rO+LsDlY1y09sZ4xmufwsiZ6iNFm+o1GQ==",
"requires": {
"enhanced-resolve": "^5.8.2",
"resolve": "^1.15.1",

View file

@ -9,16 +9,19 @@
"engines": {
"node": "~14.19.1"
},
"devDependencies": {},
"devDependencies": {
},
"dependencies": {
"lua-types": "^2.11.0",
"typescript-to-lua": "1.4.3",
"typescript-to-lua": "1.4.4",
"typed-factorio": "1.0.0",
"typescript": "4.6.3"
},
"// @types/node": "^12.0.8",
"license": "UNLICENSED",
"peerDependencies": {},
"optionalDependencies": {},
"bundledDependencies": []
"peerDependencies": {
},
"optionalDependencies": {
},
"bundledDependencies": [
]
}

View file

@ -2,6 +2,7 @@ package dev.adamko.kafkatorio.schema.common
import dev.adamko.kxstsgen.core.experiments.TupleSerializer
import kotlin.math.roundToInt
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
@ -11,6 +12,7 @@ import kotlinx.serialization.Serializable
* All values here are optional. Colour channels default to `0`, the alpha channel defaults to `1`.
*/
@Serializable(with = Colour.Serializer::class)
@SerialName("kafkatorio.common.Colour")
data class Colour(
val red: Float = 0f,
val green: Float = 0f,
@ -40,6 +42,7 @@ data class Colour(
/** Size-efficient version of [Colour] (`4*4` bytes vs `4*1` bytes) */
@Serializable
@SerialName("kafkatorio.common.ColourHex")
data class ColourHex(
val red: UByte = UByte.MIN_VALUE,
val green: UByte = UByte.MIN_VALUE,

View file

@ -8,6 +8,8 @@ import kotlinx.serialization.Serializable
@JvmInline
value class Tick(val value: UInt)
val UInt.tick
get() = Tick(this)
/**
* Unique ID associated with this surface
@ -51,6 +53,13 @@ value class PrototypeName(private val id: String) {
}
@Serializable
@JvmInline
value class EventName(private val name: String) {
override fun toString(): String = name
}
interface EntityIdentifiers {
val unitNumber: UnitNumber?
val name: String

View file

@ -0,0 +1,27 @@
package dev.adamko.kafkatorio.schema.common
import kotlinx.serialization.Contextual
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
@SerialName("kafkatorio.prototype.FactorioPrototype")
sealed interface FactorioPrototype {
val name: PrototypeName
val mapColour: Colour
@SerialName("kafkatorio.prototype.MapTile")
@Serializable
data class MapTile(
override val name: PrototypeName,
override val mapColour: Colour,
val layer: UInt,
@Contextual
val collisionMasks: List<String>,
val order: String,
/** Can the tile be mined for resources? */
val canBeMined: Boolean,
) : FactorioPrototype
}

View file

@ -0,0 +1,40 @@
package dev.adamko.kafkatorio.schema.common
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
data class MinedProduct(
/** `item` or `fluid`. */
val type: Type,
/** Prototype name of the result. */
@SerialName("name")
val resultPrototype: PrototypeName,
//Amount of the item or fluid to give. If not specified, amount_min, amount_max and probability must all be specified.
val amount: Double?,
//Minimal amount of the item or fluid to give. Has no effect when amount is specified.
//amount_min : Uint or double?,
//Maximum amount of the item or fluid to give. Has no effect when amount is specified.
//amount_max : Uint or double?,
//A value in range [0, 1]. Item or fluid is only given with this probability; otherwise no product is produced.
//probability : Double?,
//How much of this product is a catalyst.
//catalyst_amount : Uint or double?,
) {
@Serializable
enum class Type {
@SerialName("item")
ITEM,
@SerialName("fluid")
FLUID,
}
}

View file

@ -1,10 +1,12 @@
package dev.adamko.kafkatorio.schema.packets
import dev.adamko.kafkatorio.schema.common.Tick
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@Serializable
@SerialName("kafkatorio.packet.KafkatorioPacket")
data class KafkatorioPacket(
val modVersion: String,
val tick: Tick,
@ -13,4 +15,5 @@ data class KafkatorioPacket(
@Serializable
@SerialName("kafkatorio.packet.KafkatorioPacketData")
sealed class KafkatorioPacketData

View file

@ -1,13 +1,15 @@
package dev.adamko.kafkatorio.schema.packets
import dev.adamko.kafkatorio.schema.common.FactorioPrototype
import dev.adamko.kafkatorio.schema.common.PlayerIndex
import dev.adamko.kafkatorio.schema.common.SurfaceIndex
import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/** No key, no caching. Must be sent instantly. */
@Serializable
@SerialName("kafkatorio.packet.KafkatorioPacket")
sealed class KafkatorioInstantPacketData : KafkatorioPacketData()
@ -15,6 +17,7 @@ sealed class KafkatorioInstantPacketData : KafkatorioPacketData()
@Serializable
@SerialName("kafkatorio.packet.instant.ConfigurationUpdate")
data class ConfigurationUpdate(
val factorioData: ConfigurationUpdateGameData,
val allMods: List<ConfigurationUpdateModData>,
@ -23,12 +26,14 @@ data class ConfigurationUpdate(
) : KafkatorioInstantPacketData() {
@Serializable
@SerialName("kafkatorio.packet.instant.ConfigurationUpdate.ConfigurationUpdateGameData")
data class ConfigurationUpdateGameData(
val oldVersion: String? = null,
val newVersion: String? = null,
)
@Serializable
@SerialName("kafkatorio.packet.instant.ConfigurationUpdate.ConfigurationUpdateModData")
data class ConfigurationUpdateModData(
val modName: String,
val currentVersion: String? = null,
@ -38,6 +43,7 @@ data class ConfigurationUpdate(
@Serializable
@SerialName("kafkatorio.packet.instant.ConsoleChatUpdate")
data class ConsoleChatUpdate(
val authorPlayerIndex: PlayerIndex?,
val content: String,
@ -45,6 +51,7 @@ data class ConsoleChatUpdate(
@Serializable
@SerialName("kafkatorio.packet.instant.ConsoleCommandUpdate")
data class ConsoleCommandUpdate(
val authorPlayerIndex: PlayerIndex?,
val command: String,
@ -53,12 +60,14 @@ data class ConsoleCommandUpdate(
@Serializable
@SerialName("kafkatorio.packet.instant.PrototypesUpdate")
data class PrototypesUpdate(
val prototypes: List<FactorioPrototype>,
) : KafkatorioInstantPacketData()
@Serializable
@SerialName("kafkatorio.packet.instant.SurfaceUpdate")
data class SurfaceUpdate(
val index: SurfaceIndex,
val daytime: Double,

View file

@ -3,6 +3,7 @@ package dev.adamko.kafkatorio.schema.packets
import dev.adamko.kafkatorio.schema.common.Colour
import dev.adamko.kafkatorio.schema.common.EntityIdentifiers
import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData
import dev.adamko.kafkatorio.schema.common.EventName
import dev.adamko.kafkatorio.schema.common.ForceIndex
import dev.adamko.kafkatorio.schema.common.MapChunkPosition
import dev.adamko.kafkatorio.schema.common.MapEntityPosition
@ -12,40 +13,46 @@ import dev.adamko.kafkatorio.schema.common.PrototypeName
import dev.adamko.kafkatorio.schema.common.SurfaceIndex
import dev.adamko.kafkatorio.schema.common.Tick
import dev.adamko.kafkatorio.schema.common.UnitNumber
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/** Has a key, so it can be debounced */
@Serializable
@SerialName("kafkatorio.packet.keyed.KafkatorioKeyedPacketData")
sealed class KafkatorioKeyedPacketData : KafkatorioPacketData() {
/** Count how many events this packet is aggregating data from */
abstract val key: KafkatorioKeyedPacketKey2
abstract val eventCounts: Map<String, UInt>?
abstract val key: KafkatorioKeyedPacketKey
/** A list of all events that have been aggregated into this packet. */
abstract val events: Map<EventName, List<Tick>>?
}
@Serializable
sealed class KafkatorioKeyedPacketKey2
@SerialName("kafkatorio.packet.keyed.KafkatorioKeyedPacketKey")
sealed class KafkatorioKeyedPacketKey
/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
@Serializable
@SerialName("kafkatorio.packet.keyed.EntityUpdateKey")
data class EntityUpdateKey(
/** While normally optional, here a [unitNumber] is required for caching */
override val unitNumber: UnitNumber,
override val name: String,
override val protoType: String,
) : EntityIdentifiers, KafkatorioKeyedPacketKey2()
) : EntityIdentifiers, KafkatorioKeyedPacketKey()
@Serializable
@SerialName("kafkatorio.packet.keyed.EntityUpdate")
data class EntityUpdate(
override val key: EntityUpdateKey,
override val eventCounts: Map<String, UInt>? = null,
override val events: Map<EventName, List<Tick>>? = null,
val chunkPosition: MapChunkPosition? = null,
val chunkPosition: MapEntityPosition? = null,
val graphicsVariation: UByte? = null,
val health: Float? = null,
val isActive: Boolean? = null,
@ -61,17 +68,19 @@ data class EntityUpdate(
@Serializable
@SerialName("kafkatorio.packet.keyed.MapChunkUpdateKey")
data class MapChunkUpdateKey(
val chunkPosition: MapChunkPosition,
val surfaceIndex: SurfaceIndex,
) : KafkatorioKeyedPacketKey2()
) : KafkatorioKeyedPacketKey()
@Serializable
@SerialName("kafkatorio.packet.keyed.MapChunkUpdate")
data class MapChunkUpdate(
override val key: MapChunkUpdateKey,
override val eventCounts: Map<String, UInt>? = null,
override val events: Map<EventName, List<Tick>>? = null,
val player: PlayerIndex? = null,
val robot: EntityIdentifiersData? = null,
@ -85,16 +94,18 @@ data class MapChunkUpdate(
/* *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** *** */
@Serializable
@SerialName("kafkatorio.packet.keyed.PlayerUpdateKey")
data class PlayerUpdateKey(
val index: PlayerIndex,
) : KafkatorioKeyedPacketKey2()
) : KafkatorioKeyedPacketKey()
@Serializable
@SerialName("kafkatorio.packet.keyed.PlayerUpdate")
data class PlayerUpdate(
override val key: PlayerUpdateKey,
override val eventCounts: Map<String, UInt>? = null,
override val events: Map<EventName, List<Tick>>? = null,
val characterUnitNumber: UnitNumber? = null,
val chatColour: Colour? = null,

View file

@ -1,23 +0,0 @@
package dev.adamko.kafkatorio.schema.prototypes
import dev.adamko.kafkatorio.schema.common.Colour
import dev.adamko.kafkatorio.schema.common.PrototypeName
import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
@Serializable
sealed class FactorioPrototype {
@Serializable
data class MapTile(
val name: PrototypeName,
val layer: UInt,
val mapColour: Colour,
@Contextual
val collisionMasks: List<String>,
val order: String,
/** Can the tile be mined for resources? */
val canBeMined: Boolean,
) : FactorioPrototype()
}

View file

@ -1,10 +1,11 @@
package dev.adamko.kafkatorio.events.schema
import dev.adamko.kafkatorio.schema.common.EventName
import dev.adamko.kafkatorio.schema.common.MapChunkPosition
import dev.adamko.kafkatorio.schema.common.MapTileDictionary
import dev.adamko.kafkatorio.schema.common.PrototypeName
import dev.adamko.kafkatorio.schema.common.SurfaceIndex
import dev.adamko.kafkatorio.schema.common.Tick
import dev.adamko.kafkatorio.schema.common.tick
import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket
import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate
@ -20,7 +21,7 @@ class MapChunkUpdateTest : FunSpec({
val json = """
{
"data": {
"type": "dev.adamko.kafkatorio.schema.packets.MapChunkUpdate",
"type": "kafkatorio.packet.keyed.MapChunkUpdate",
"key": {
"surfaceIndex": 1,
"chunkPosition": [
@ -46,8 +47,8 @@ class MapChunkUpdateTest : FunSpec({
"grass-3": 32
}
},
"eventCounts": {
"on_chunk_generated": 1
"events": {
"on_chunk_generated": [1]
}
},
"modVersion": "0.4.0",
@ -56,14 +57,16 @@ class MapChunkUpdateTest : FunSpec({
""".trimIndent()
val expected = KafkatorioPacket(
tick = Tick(36u),
tick = 36u.tick,
modVersion = "0.4.0",
data = MapChunkUpdate(
key = MapChunkUpdateKey(
MapChunkPosition(-6, -3),
SurfaceIndex(1u),
),
eventCounts = mapOf("on_chunk_generated" to 1u),
events = mapOf(
EventName("on_chunk_generated") to listOf(1u.tick)
),
tileDictionary = MapTileDictionary(
tilesXY = mapOf(
"-192" to mapOf("-65" to MapTileDictionary.PrototypeKey(2)),

View file

@ -1,9 +1,9 @@
package dev.adamko.kafkatorio.events.schema
import dev.adamko.kafkatorio.schema.common.Colour
import dev.adamko.kafkatorio.schema.common.FactorioPrototype
import dev.adamko.kafkatorio.schema.common.PrototypeName
import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio
import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket
import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate
import io.kotest.core.spec.style.BehaviorSpec
@ -20,10 +20,10 @@ class PrototypesTest : BehaviorSpec({
"modVersion": "0.2.4",
"tick": 534,
"data": {
"type": "dev.adamko.kafkatorio.schema.packets.PrototypesUpdate",
"type": "kafkatorio.packet.instant.PrototypesUpdate",
"prototypes": [
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "tile-unknown",
"order": "z-a",
"layer": 0,
@ -50,10 +50,10 @@ class PrototypesTest : BehaviorSpec({
"modVersion": "0.3.2",
"tick": 534,
"data": {
"type": "dev.adamko.kafkatorio.schema.packets.PrototypesUpdate",
"type": "kafkatorio.packet.instant.PrototypesUpdate",
"prototypes": [
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "stone-path",
"order": "a[artificial]-a[tier-1]-a[stone-path]",
"layer": 60,
@ -64,7 +64,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "concrete",
"order": "a[artificial]-b[tier-2]-a[concrete]",
"layer": 61,
@ -75,7 +75,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "hazard-concrete-left",
"order": "a[artificial]-b[tier-2]-b[hazard-concrete-left]",
"layer": 62,
@ -86,7 +86,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "hazard-concrete-right",
"order": "a[artificial]-b[tier-2]-c[hazard-concrete-right]",
"layer": 62,
@ -97,7 +97,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "refined-concrete",
"order": "a[artificial]-c[tier-3]-a[refined-concrete]",
"layer": 64,
@ -108,7 +108,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "refined-hazard-concrete-left",
"order": "a[artificial]-c[tier-3]-b[refined-hazard-concrete-left]",
"layer": 65,
@ -119,7 +119,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "refined-hazard-concrete-right",
"order": "a[artificial]-c[tier-3]-c[refined-hazard-concrete-right]",
"layer": 65,
@ -130,7 +130,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "landfill",
"order": "a[artificial]-d[utility]-a[landfill]",
"layer": 57,
@ -141,7 +141,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "acid-refined-concrete",
"order": "a[artificial]-e[color-concrete]-acid",
"layer": 97,
@ -152,7 +152,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "black-refined-concrete",
"order": "a[artificial]-e[color-concrete]-black",
"layer": 88,
@ -163,7 +163,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "blue-refined-concrete",
"order": "a[artificial]-e[color-concrete]-blue",
"layer": 73,
@ -174,7 +174,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "brown-refined-concrete",
"order": "a[artificial]-e[color-concrete]-brown",
"layer": 91,
@ -185,7 +185,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "cyan-refined-concrete",
"order": "a[artificial]-e[color-concrete]-cyan",
"layer": 94,
@ -196,7 +196,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "green-refined-concrete",
"order": "a[artificial]-e[color-concrete]-green",
"layer": 70,
@ -207,7 +207,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "orange-refined-concrete",
"order": "a[artificial]-e[color-concrete]-orange",
"layer": 76,
@ -218,7 +218,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "pink-refined-concrete",
"order": "a[artificial]-e[color-concrete]-pink",
"layer": 82,
@ -229,7 +229,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "purple-refined-concrete",
"order": "a[artificial]-e[color-concrete]-purple",
"layer": 85,
@ -240,7 +240,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "red-refined-concrete",
"order": "a[artificial]-e[color-concrete]-red",
"layer": 67,
@ -251,7 +251,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "yellow-refined-concrete",
"order": "a[artificial]-e[color-concrete]-yellow",
"layer": 79,
@ -262,7 +262,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "grass-1",
"order": "b[natural]-a[grass]-a[grass-1]",
"layer": 26,
@ -273,7 +273,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "grass-2",
"order": "b[natural]-a[grass]-b[grass-2]",
"layer": 28,
@ -284,7 +284,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "grass-3",
"order": "b[natural]-a[grass]-c[grass-3]",
"layer": 29,
@ -295,7 +295,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "grass-4",
"order": "b[natural]-a[grass]-d[grass-4]",
"layer": 30,
@ -306,7 +306,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dry-dirt",
"order": "b[natural]-b[dirt]-a[dry-dirt]",
"layer": 18,
@ -317,7 +317,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-1",
"order": "b[natural]-b[dirt]-b[dirt-1]",
"layer": 19,
@ -328,7 +328,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-2",
"order": "b[natural]-b[dirt]-c[dirt-2]",
"layer": 20,
@ -339,7 +339,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-3",
"order": "b[natural]-b[dirt]-d[dirt-3]",
"layer": 21,
@ -350,7 +350,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-4",
"order": "b[natural]-b[dirt]-e[dirt-4]",
"layer": 22,
@ -361,7 +361,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-5",
"order": "b[natural]-b[dirt]-f[dirt-5]",
"layer": 23,
@ -372,7 +372,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-6",
"order": "b[natural]-b[dirt]-g[dirt-6]",
"layer": 24,
@ -383,7 +383,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-7",
"order": "b[natural]-b[dirt]-h[dirt-7]",
"layer": 25,
@ -394,7 +394,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "sand-1",
"order": "b[natural]-c[sand]-a[sand-1]",
"layer": 8,
@ -405,7 +405,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "sand-2",
"order": "b[natural]-c[sand]-b[sand-2]",
"layer": 9,
@ -416,7 +416,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "sand-3",
"order": "b[natural]-c[sand]-c[sand-3]",
"layer": 10,
@ -427,7 +427,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "red-desert-0",
"order": "b[natural]-d[red-desert]-a[red-desert-0]",
"layer": 31,
@ -438,7 +438,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "red-desert-1",
"order": "b[natural]-d[red-desert]-b[red-desert-1]",
"layer": 14,
@ -449,7 +449,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "red-desert-2",
"order": "b[natural]-d[red-desert]-c[red-desert-2]",
"layer": 15,
@ -460,7 +460,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "red-desert-3",
"order": "b[natural]-d[red-desert]-d[red-desert-3]",
"layer": 16,
@ -471,7 +471,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "water",
"order": "c[water]-a[water]",
"layer": 3,
@ -486,7 +486,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "deepwater",
"order": "c[water]-b[deep-water]",
"layer": 3,
@ -501,7 +501,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "water-green",
"order": "c[water]-c[water-green]",
"layer": 3,
@ -516,7 +516,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "deepwater-green",
"order": "c[water]-d[deepwater-green]",
"layer": 3,
@ -531,7 +531,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "water-shallow",
"order": "c[water]-e[water-shallow]",
"layer": 6,
@ -545,7 +545,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "water-mud",
"order": "c[water]-g[water-mud]",
"layer": 7,
@ -559,7 +559,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "nuclear-ground",
"order": "d[destruction]-a[nuclear]-a[nuclear-ground]",
"layer": 33,
@ -570,7 +570,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "water-wube",
"order": "x[wube]-a[water-wube]",
"layer": 2,
@ -585,7 +585,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "tile-unknown",
"order": "z-a",
"layer": 0,
@ -595,7 +595,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "out-of-map",
"order": "z[other]-a[out-of-map]",
"layer": 0,
@ -613,7 +613,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "lab-dark-1",
"order": "z[other]-b[lab]-a[lab-dark-1]",
"layer": 70,
@ -624,7 +624,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "lab-dark-2",
"order": "z[other]-b[lab]-b[lab-dark-2]",
"layer": 70,
@ -635,7 +635,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "lab-white",
"order": "z[other]-b[lab]-c[lab-white]",
"layer": 70,
@ -646,7 +646,7 @@ class PrototypesTest : BehaviorSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "tutorial-grid",
"order": "z[other]-c[tutorial]-a[tutorial-grid]",
"layer": 55,

View file

@ -2,13 +2,16 @@ package dev.adamko.kafkatorio.events.schema
import dev.adamko.kafkatorio.schema.common.Colour
import dev.adamko.kafkatorio.schema.common.EntityIdentifiersData
import dev.adamko.kafkatorio.schema.common.EventName
import dev.adamko.kafkatorio.schema.common.ForceIndex
import dev.adamko.kafkatorio.schema.common.MapEntityPosition
import dev.adamko.kafkatorio.schema.common.PlayerIndex
import dev.adamko.kafkatorio.schema.common.SurfaceIndex
import dev.adamko.kafkatorio.schema.common.Tick
import dev.adamko.kafkatorio.schema.common.UnitNumber
import dev.adamko.kafkatorio.schema.common.tick
import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio
import dev.adamko.kafkatorio.schema.packets.KafkatorioKeyedPacketData
import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket
import dev.adamko.kafkatorio.schema.packets.PlayerUpdate
import dev.adamko.kafkatorio.schema.packets.PlayerUpdateKey
@ -27,14 +30,14 @@ class UpdatePacketsTest : FunSpec({
"tick": 66,
"modVersion": "0.3.2",
"data": {
"type": "dev.adamko.kafkatorio.schema.packets.PlayerUpdate",
"type": "kafkatorio.packet.keyed.PlayerUpdate",
"key": {"index": 1},
"afkTime": 0,
"chatColour": [1, 0.4, 0.6, 1],
"colour": [0.8, 0.5, 0.2, 0.5],
"eventCounts": {
"on_player_changed_position": 7,
"on_player_joined_game": 1
"events": {
"on_player_changed_position": [7, 99],
"on_player_joined_game": [14]
},
"forceIndex": 1,
"isAdmin": true,
@ -68,7 +71,10 @@ class UpdatePacketsTest : FunSpec({
colour = Colour(red = 0.8f, green = 0.5f, blue = 0.2f, alpha = 0.5f),
diedCause = null,
disconnectReason = null,
eventCounts = mapOf("on_player_changed_position" to 7u, "on_player_joined_game" to 1u),
events = mapOf(
EventName("on_player_changed_position") to listOf(7u.tick, 99u.tick),
EventName("on_player_joined_game") to listOf(14u.tick),
),
forceIndex = ForceIndex(1u),
isAdmin = true,
isConnected = true,
@ -124,7 +130,7 @@ class UpdatePacketsTest : FunSpec({
"modVersion": "0.3.2",
"tick": 66,
"data": {
"type": "dev.adamko.kafkatorio.schema.packets.PlayerUpdate",
"type": "kafkatorio.packet.keyed.PlayerUpdate",
"key": {
"index": 1
},
@ -151,7 +157,7 @@ class UpdatePacketsTest : FunSpec({
"tick": 227934,
"modVersion": "0.3.2",
"data": {
"type": "dev.adamko.kafkatorio.schema.packets.PlayerUpdate",
"type": "kafkatorio.packet.keyed.PlayerUpdate",
"key": {
"index": 1
},
@ -164,8 +170,8 @@ class UpdatePacketsTest : FunSpec({
"name": "small-biter",
"protoType": "unit"
},
"eventCounts": {
"on_player_died": 2
"events": {
"on_player_died": [2]
}
}
}
@ -176,9 +182,9 @@ class UpdatePacketsTest : FunSpec({
packet shouldBe KafkatorioPacket(
modVersion = "0.3.2",
tick = Tick(227934u),
tick = 227934u.tick,
data = PlayerUpdate(
afkTime = Tick(324u),
afkTime = 324u.tick,
bannedReason = null,
characterUnitNumber = null,
chatColour = null,
@ -189,7 +195,9 @@ class UpdatePacketsTest : FunSpec({
protoType = "unit",
),
disconnectReason = null,
eventCounts = mapOf("on_player_died" to 2u),
events = mapOf(
EventName("on_player_died") to listOf(2u.tick),
),
forceIndex = null,
key = PlayerUpdateKey(PlayerIndex(1u)),
isAdmin = null,
@ -198,9 +206,9 @@ class UpdatePacketsTest : FunSpec({
isShowOnMap = null,
isSpectator = null,
kickedReason = null,
lastOnline = Tick(227932u),
lastOnline = 227932u.tick,
name = null,
onlineTime = Tick(227888u),
onlineTime = 227888u.tick,
position = null,
surfaceIndex = null,
tag = null,
@ -215,7 +223,7 @@ class UpdatePacketsTest : FunSpec({
val json = """
{
"data": {
"type": "dev.adamko.kafkatorio.schema.packets.SurfaceUpdate",
"type": "kafkatorio.packet.instant.SurfaceUpdate",
"name": "nauvis",
"index": 1,
"daytime": 0.73

View file

@ -0,0 +1,50 @@
package dev.adamko.kafkatorio.schema.packets
import dev.adamko.kafkatorio.schema.jsonMapperKafkatorio
import io.kotest.core.spec.style.FunSpec
import io.kotest.matchers.types.shouldBeInstanceOf
import kotlinx.serialization.decodeFromString
class EntityUpdateTest : FunSpec({
context("EntityUpdate packet") {
/*language=json*/
val json = """
{
"data": {
"type": "kafkatorio.packet.keyed.EntityUpdate",
"key": {
"name": "assembling-machine-2",
"protoType": "assembling-machine-2",
"unitNumber": 4622
},
"events": {
"on_built_entity": [
38023
]
},
"chunkPosition": [
-13.5,
4.5
],
"health": 350,
"isActive": true,
"isRotatable": true,
"lastUser": 1,
"prototype": "assembling-machine-2"
},
"modVersion": "0.4.0",
"tick": 38388
}
""".trimIndent()
test("decode") {
val entityUpdate: KafkatorioPacket = jsonMapperKafkatorio.decodeFromString(json)
entityUpdate.data
.shouldBeInstanceOf<EntityUpdate>()
// entityUpdate.health.shouldNotBeNull().shouldBeExactly(350f)
}
}
})

View file

@ -2,10 +2,10 @@ package dev.adamko.kafkatorio.processor.topology
import dev.adamko.kafkatorio.processor.serdes.kxsBinary
import dev.adamko.kafkatorio.schema.common.ColourHex
import dev.adamko.kafkatorio.schema.common.FactorioPrototype
import dev.adamko.kafkatorio.schema.common.MapTile
import dev.adamko.kafkatorio.schema.common.toHex
import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate
import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype
import dev.adamko.kotka.extensions.materializedAs
import dev.adamko.kotka.extensions.repartitionedAs
import dev.adamko.kotka.extensions.streams.filter

View file

@ -17,7 +17,7 @@ import dev.adamko.kafkatorio.schema.packets.KafkatorioPacket
import dev.adamko.kafkatorio.schema.packets.MapChunkUpdate
import dev.adamko.kafkatorio.schema.packets.MapChunkUpdateKey
import dev.adamko.kafkatorio.schema.packets.PrototypesUpdate
import dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype
import dev.adamko.kafkatorio.schema.common.FactorioPrototype
import dev.adamko.kotka.kxs.serde
import io.kotest.assertions.withClue
import io.kotest.core.spec.style.FunSpec
@ -289,7 +289,7 @@ class GroupMapChunksTest : FunSpec({
"modVersion": "0.4.0",
"tick": 36,
"data": {
"type": "dev.adamko.kafkatorio.schema.packets.MapChunkUpdate",
"type": "kafkatorio.packet.keyed.MapChunkUpdate",
"key": {
"chunkPosition": [
-7,
@ -297,8 +297,8 @@ class GroupMapChunksTest : FunSpec({
],
"surfaceIndex": 1
},
"eventCounts": {
"on_chunk_generated": 1
"events": {
"on_chunk_generated": [1]
},
"tileDictionary": {
"tilesXY": {
@ -1407,10 +1407,10 @@ class GroupMapChunksTest : FunSpec({
"modVersion": "0.4.0",
"tick": 4352,
"data": {
"type": "dev.adamko.kafkatorio.schema.packets.PrototypesUpdate",
"type": "kafkatorio.packet.instant.PrototypesUpdate",
"prototypes": [
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "stone-path",
"layer": 60,
"mapColour": [
@ -1426,7 +1426,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "concrete",
"layer": 61,
"mapColour": [
@ -1442,7 +1442,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "hazard-concrete-left",
"layer": 62,
"mapColour": [
@ -1458,7 +1458,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "hazard-concrete-right",
"layer": 62,
"mapColour": [
@ -1474,7 +1474,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "refined-concrete",
"layer": 64,
"mapColour": [
@ -1490,7 +1490,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "refined-hazard-concrete-left",
"layer": 65,
"mapColour": [
@ -1506,7 +1506,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "refined-hazard-concrete-right",
"layer": 65,
"mapColour": [
@ -1522,7 +1522,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": true
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "landfill",
"layer": 57,
"mapColour": [
@ -1538,7 +1538,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "acid-refined-concrete",
"layer": 97,
"mapColour": [
@ -1554,7 +1554,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "black-refined-concrete",
"layer": 88,
"mapColour": [
@ -1570,7 +1570,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "blue-refined-concrete",
"layer": 73,
"mapColour": [
@ -1586,7 +1586,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "brown-refined-concrete",
"layer": 91,
"mapColour": [
@ -1602,7 +1602,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "cyan-refined-concrete",
"layer": 94,
"mapColour": [
@ -1618,7 +1618,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "green-refined-concrete",
"layer": 70,
"mapColour": [
@ -1634,7 +1634,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "orange-refined-concrete",
"layer": 76,
"mapColour": [
@ -1650,7 +1650,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "pink-refined-concrete",
"layer": 82,
"mapColour": [
@ -1666,7 +1666,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "purple-refined-concrete",
"layer": 85,
"mapColour": [
@ -1682,7 +1682,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "red-refined-concrete",
"layer": 67,
"mapColour": [
@ -1698,7 +1698,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "yellow-refined-concrete",
"layer": 79,
"mapColour": [
@ -1714,7 +1714,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "grass-1",
"layer": 26,
"mapColour": [
@ -1730,7 +1730,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "grass-2",
"layer": 28,
"mapColour": [
@ -1746,7 +1746,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "grass-3",
"layer": 29,
"mapColour": [
@ -1762,7 +1762,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "grass-4",
"layer": 30,
"mapColour": [
@ -1778,7 +1778,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dry-dirt",
"layer": 18,
"mapColour": [
@ -1794,7 +1794,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-1",
"layer": 19,
"mapColour": [
@ -1810,7 +1810,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-2",
"layer": 20,
"mapColour": [
@ -1826,7 +1826,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-3",
"layer": 21,
"mapColour": [
@ -1842,7 +1842,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-4",
"layer": 22,
"mapColour": [
@ -1858,7 +1858,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-5",
"layer": 23,
"mapColour": [
@ -1874,7 +1874,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-6",
"layer": 24,
"mapColour": [
@ -1890,7 +1890,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "dirt-7",
"layer": 25,
"mapColour": [
@ -1906,7 +1906,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "sand-1",
"layer": 8,
"mapColour": [
@ -1922,7 +1922,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "sand-2",
"layer": 9,
"mapColour": [
@ -1938,7 +1938,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "sand-3",
"layer": 10,
"mapColour": [
@ -1954,7 +1954,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "red-desert-0",
"layer": 31,
"mapColour": [
@ -1970,7 +1970,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "red-desert-1",
"layer": 14,
"mapColour": [
@ -1986,7 +1986,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "red-desert-2",
"layer": 15,
"mapColour": [
@ -2002,7 +2002,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "red-desert-3",
"layer": 16,
"mapColour": [
@ -2018,7 +2018,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "water",
"layer": 3,
"mapColour": [
@ -2038,7 +2038,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "deepwater",
"layer": 3,
"mapColour": [
@ -2058,7 +2058,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "water-green",
"layer": 3,
"mapColour": [
@ -2078,7 +2078,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "deepwater-green",
"layer": 3,
"mapColour": [
@ -2098,7 +2098,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "water-shallow",
"layer": 6,
"mapColour": [
@ -2117,7 +2117,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "water-mud",
"layer": 7,
"mapColour": [
@ -2136,7 +2136,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "nuclear-ground",
"layer": 33,
"mapColour": [
@ -2152,7 +2152,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "water-wube",
"layer": 2,
"mapColour": [
@ -2172,7 +2172,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "tile-unknown",
"layer": 0,
"mapColour": [
@ -2186,7 +2186,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "out-of-map",
"layer": 0,
"mapColour": [
@ -2209,7 +2209,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "lab-dark-1",
"layer": 70,
"mapColour": [
@ -2225,7 +2225,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "lab-dark-2",
"layer": 70,
"mapColour": [
@ -2241,7 +2241,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "lab-white",
"layer": 70,
"mapColour": [
@ -2257,7 +2257,7 @@ class GroupMapChunksTest : FunSpec({
"canBeMined": false
},
{
"type": "dev.adamko.kafkatorio.schema.prototypes.FactorioPrototype.MapTile",
"type": "kafkatorio.prototype.MapTile",
"name": "tutorial-grid",
"layer": 55,
"mapColour": [

View file

@ -35,7 +35,6 @@ class SaveMapChunksTest : FunSpec({
test("save tile") {
Scenario().use { scenario ->
val chunkTilesArb = serverMapChunkTilesArb(scenario.serverId)
@ -79,7 +78,7 @@ class SaveMapChunksTest : FunSpec({
Path("build/test/save-map-chunks-${now}")
}
private val topology = saveMapTiles(streamsBuilder, outputDir)
val testDriver: TopologyTestDriver = TopologyTestDriver(topology)
private val testDriver: TopologyTestDriver = TopologyTestDriver(topology)
val groupedMapChunksInputTopic: TestInputTopic<ServerMapChunkId, ServerMapChunkTiles<ColourHex>> =
testDriver.createInputTopic(
@ -99,21 +98,14 @@ class SaveMapChunksTest : FunSpec({
companion object {
fun mapTilePositionArb(
xArb: Arb<Int> = Arb.int(),
yArb: Arb<Int> = Arb.int(),
): Arb<MapTilePosition> = arbitrary {
MapTilePosition(xArb.bind(), yArb.bind())
}
fun mapChunkPositionArb(
private fun mapChunkPositionArb(
xArb: Arb<Int> = Arb.int(-10..10),
yArb: Arb<Int> = Arb.int(-10..10),
): Arb<MapChunkPosition> = arbitrary {
MapChunkPosition(xArb.bind(), yArb.bind())
}
fun colourHexArb(
private fun colourHexArb(
redArb: Arb<UByte> = Arb.uByte(),
greenArb: Arb<UByte> = Arb.uByte(),
blueArb: Arb<UByte> = Arb.uByte(),
@ -123,18 +115,11 @@ class SaveMapChunksTest : FunSpec({
redArb.bind(),
greenArb.bind(),
blueArb.bind(),
// alphaArb.bind(),
255u,
alphaArb.bind(),
)
// ColourHex(
// 255u,
// 0u,
// 0u,
// 255u,
// )
}
fun serverMapChunkIdArb(
private fun serverMapChunkIdArb(
serverId: FactorioServerId,
chunkPosition: Arb<MapChunkPosition> = mapChunkPositionArb(),
surfaceIndex: SurfaceIndex = SurfaceIndex(1u),
@ -148,7 +133,7 @@ class SaveMapChunksTest : FunSpec({
)
}
fun tilesInChunkArb(
private fun tilesInChunkArb(
chunkId: ServerMapChunkId
): Arb<Map<MapTilePosition, ColourHex>> = arbitrary {